]> Git Repo - binutils.git/blobdiff - gdb/stabsread.c
Thu Apr 22 14:50:05 1993 Jim Kingdon ([email protected])
[binutils.git] / gdb / stabsread.c
index b3dd4f04eca7c0a7f3460bbebe98d66031b56986..9b475bd0f31ecc2c9a267de719e9b32b5bb2cbd1 100644 (file)
@@ -87,6 +87,9 @@ read_sun_floating_type PARAMS ((char **, int [2], struct objfile *));
 static struct type *
 read_enum_type PARAMS ((char **, struct type *, struct objfile *));
 
+static struct type *
+rs6000_builtin_type PARAMS ((int));
+
 static int
 read_member_functions PARAMS ((struct field_info *, char **, struct type *,
                               struct objfile *));
@@ -183,6 +186,9 @@ struct complaint vtbl_notfound_complaint =
 struct complaint unrecognized_cplus_name_complaint =
   {"Unknown C++ symbol name `%s'", 0, 0};
 
+struct complaint rs6000_builtin_complaint =
+  {"Unknown builtin type %d", 0, 0};
+
 struct complaint stabs_general_complaint =
   {"%s", 0, 0};
 
@@ -255,6 +261,19 @@ dbx_lookup_type (typenums)
 
   if (filenum == 0)
     {
+      if (index < 0)
+       {
+         /* Caller wants address of address of type.  We think
+            that negative (rs6k builtin) types will never appear as
+            "lvalues", (nor should they), so we stuff the real type
+            pointer into a temp, and return its address.  If referenced,
+            this will do the right thing.  */
+         static struct type *temp_type;
+
+         temp_type = rs6000_builtin_type(index);
+         return &temp_type;
+       }
+
       /* Type is defined outside of header files.
         Find it in this object file's type vector.  */
       if (index >= type_vector_length)
@@ -363,9 +382,32 @@ patch_block_stabs (symbols, stabs, objfile)
          sym = find_symbol_in_list (symbols, name, pp-name);
          if (!sym)
            {
-#ifndef IBM6000_TARGET
-             printf ("ERROR! stab symbol not found!\n");       /* FIXME */
-#endif
+             /* On xcoff, if a global is defined and never referenced,
+                ld will remove it from the executable.  There is then
+                a N_GSYM stab for it, but no regular (C_EXT) symbol.  */
+             sym = (struct symbol *)
+               obstack_alloc (&objfile->symbol_obstack,
+                              sizeof (struct symbol));
+
+             memset (sym, 0, sizeof (struct symbol));
+             SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+             SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+             SYMBOL_NAME (sym) =
+               obstack_copy0 (&objfile->symbol_obstack, name, pp - name);
+             pp += 2;
+             if (*(pp-1) == 'F' || *(pp-1) == 'f')
+               {
+                 /* I don't think the linker does this with functions,
+                    so as far as I know this is never executed.
+                    But it doesn't hurt to check.  */
+                 SYMBOL_TYPE (sym) =
+                   lookup_function_type (read_type (&pp, objfile));
+               }
+             else
+               {
+                 SYMBOL_TYPE (sym) = read_type (&pp, objfile);
+               }
+             add_symbol_to_list (sym, &global_symbols);
            }
          else
            {
@@ -791,6 +833,7 @@ define_symbol (valu, string, desc, type, objfile)
 
 #endif /* no BELIEVE_PCC_PROMOTION_TYPE.  */
 
+    case 'R':
     case 'P':
       /* acc seems to use P to delare the prototypes of functions that
          are referenced by this file.  gdb is not prepared to deal
@@ -810,7 +853,6 @@ define_symbol (valu, string, desc, type, objfile)
       add_symbol_to_list (sym, &local_symbols);
       break;
 
-    case 'R':
     case 'r':
       /* Register variable (either global or local).  */
       SYMBOL_CLASS (sym) = LOC_REGISTER;
@@ -822,7 +864,31 @@ define_symbol (valu, string, desc, type, objfile)
        }
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
       if (within_function)
-        add_symbol_to_list (sym, &local_symbols);
+       {
+         /* Sun cc uses a pair of symbols, one 'p' and one 'r' with the same
+            name to represent an argument passed in a register.
+            GCC uses 'P' for the same case.  So if we find such a symbol pair
+            we combine it into one 'P' symbol.
+            Note that this code illegally combines
+              main(argc) int argc; { register int argc = 1; }
+            but this case is considered pathological and causes a warning
+            from a decent compiler.  */
+         if (local_symbols
+             && local_symbols->nsyms > 0)
+           {
+             struct symbol *prev_sym;
+             prev_sym = local_symbols->symbol[local_symbols->nsyms - 1];
+             if (SYMBOL_CLASS (prev_sym) == LOC_ARG
+                 && STREQ (SYMBOL_NAME (prev_sym), SYMBOL_NAME(sym)))
+               {
+                 SYMBOL_CLASS (prev_sym) = LOC_REGPARM;
+                 SYMBOL_VALUE (prev_sym) = SYMBOL_VALUE (sym);
+                 sym = prev_sym;
+                 break;
+               }
+           }
+          add_symbol_to_list (sym, &local_symbols);
+       }
       else
         add_symbol_to_list (sym, &file_symbols);
       break;
@@ -923,6 +989,23 @@ define_symbol (valu, string, desc, type, objfile)
     default:
       error ("Invalid symbol data: unknown symbol-type code `%c' at symtab pos %d.", deftype, symnum);
     }
+
+  /* When passing structures to a function, some systems sometimes pass
+     the address in a register, not the structure itself. 
+
+     If REG_STRUCT_HAS_ADDR yields non-zero we have to convert LOC_REGPARM
+     to LOC_REGPARM_ADDR for structures and unions.  */
+
+#if !defined (REG_STRUCT_HAS_ADDR)
+#define REG_STRUCT_HAS_ADDR(gcc_p) 0
+#endif
+
+  if (SYMBOL_CLASS (sym) == LOC_REGPARM
+      && REG_STRUCT_HAS_ADDR (processing_gcc_compilation)
+      && (   (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
+         || (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)))
+    SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+
   return sym;
 }
 
@@ -1161,10 +1244,6 @@ read_type (pp, objfile)
       }
 
     case '-':                          /* RS/6000 built-in type */
-      (*pp)--;
-      type = builtin_type (pp);                /* (in xcoffread.c) */
-      goto after_digits;
-
     case '0':
     case '1':
     case '2':
@@ -1179,9 +1258,6 @@ read_type (pp, objfile)
       (*pp)--;
       read_type_number (pp, xtypenums);
       type = *dbx_lookup_type (xtypenums);
-      /* fall through */
-
-    after_digits:
       if (type == 0)
        type = lookup_fundamental_type (objfile, FT_VOID);
       if (typenums[0] != -1)
@@ -1333,6 +1409,60 @@ read_type (pp, objfile)
   return type;
 }
 \f
+/* RS/6000 xlc/dbx combination uses a set of builtin types, starting from -1.
+   Return the proper type node for a given builtin type number. */
+
+static struct type *
+rs6000_builtin_type (typenum)
+  int typenum;
+{
+  /* default types are defined in dbxstclass.h. */
+  switch (-typenum) {
+  case 1: 
+    return lookup_fundamental_type (current_objfile, FT_INTEGER);
+  case 2: 
+    return lookup_fundamental_type (current_objfile, FT_CHAR);
+  case 3: 
+    return lookup_fundamental_type (current_objfile, FT_SHORT);
+  case 4: 
+    return lookup_fundamental_type (current_objfile, FT_LONG);
+  case 5: 
+    return lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);
+  case 6: 
+    return lookup_fundamental_type (current_objfile, FT_SIGNED_CHAR);
+  case 7: 
+    return lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);
+  case 8: 
+    return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
+  case 9: 
+    return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
+  case 10: 
+    return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
+  case 11: 
+    return lookup_fundamental_type (current_objfile, FT_VOID);
+  case 12: 
+    return lookup_fundamental_type (current_objfile, FT_FLOAT);
+  case 13: 
+    return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
+  case 14: 
+    return lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
+  case 15: 
+    /* requires a builtin `integer' */
+    return lookup_fundamental_type (current_objfile, FT_INTEGER);
+  case 16: 
+    return lookup_fundamental_type (current_objfile, FT_BOOLEAN);
+  case 17: 
+    /* requires builtin `short real' */
+    return lookup_fundamental_type (current_objfile, FT_FLOAT);
+  case 18: 
+    /* requires builtin `real' */
+    return lookup_fundamental_type (current_objfile, FT_FLOAT);
+  default:
+    complain (rs6000_builtin_complaint, typenum);
+    return NULL;
+  }
+}
+\f
 /* This page contains subroutines of read_type.  */
 
 #define VISIBILITY_PRIVATE     '0'     /* Stabs character for private field */
@@ -1477,6 +1607,8 @@ read_member_functions (fip, pp, type, objfile)
 
          if (TYPE_FLAGS (new_sublist -> fn_field.type) & TYPE_FLAG_STUB)
            {
+             if (!TYPE_DOMAIN_TYPE (new_sublist -> fn_field.type))
+               TYPE_DOMAIN_TYPE (new_sublist -> fn_field.type) = type;
              new_sublist -> fn_field.is_stub = 1;
            }
          new_sublist -> fn_field.physname = savestring (*pp, p - *pp);
@@ -2279,7 +2411,7 @@ read_struct_type (pp, type, objfile)
   /* Now read the baseclasses, if any, read the regular C struct or C++
      class member fields, attach the fields to the type, read the C++
      member functions, attach them to the type, and then read any tilde
-     fields. */
+     field (baseclass specifier for the class holding the main vtable). */
 
   if (!read_baseclasses (&fi, pp, type, objfile)
       || !read_struct_fields (&fi, pp, type, objfile)
This page took 0.034188 seconds and 4 git commands to generate.