daily update
[external/binutils.git] / gdb / stabsread.c
index 624a4c0..7fc77d0 100644 (file)
@@ -2,7 +2,7 @@
 
    Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
    1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008, 2009 Free Software Foundation, Inc.
+   2008, 2009, 2010 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -673,18 +673,14 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       switch (string[1])
        {
        case 't':
-         SYMBOL_SET_LINKAGE_NAME
-           (sym, obsavestring ("this", strlen ("this"),
-                               &objfile->objfile_obstack));
+         SYMBOL_SET_LINKAGE_NAME (sym, "this");
          break;
 
        case 'v':               /* $vtbl_ptr_type */
          goto normal;
 
        case 'e':
-         SYMBOL_SET_LINKAGE_NAME
-           (sym, obsavestring ("eh_throw", strlen ("eh_throw"),
-                               &objfile->objfile_obstack));
+         SYMBOL_SET_LINKAGE_NAME (sym, "eh_throw");
          break;
 
        case '_':
@@ -717,11 +713,11 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
        }
       if (new_name != NULL)
        {
-         SYMBOL_SET_NAMES (sym, new_name, strlen (new_name), objfile);
+         SYMBOL_SET_NAMES (sym, new_name, strlen (new_name), 1, objfile);
          xfree (new_name);
        }
       else
-       SYMBOL_SET_NAMES (sym, string, p - string, objfile);
+       SYMBOL_SET_NAMES (sym, string, p - string, 1, objfile);
     }
   p++;
 
@@ -797,6 +793,75 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
            SYMBOL_CLASS (sym) = LOC_CONST;
          }
          break;
+
+       case 'c':
+         {
+           SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_char;
+           SYMBOL_VALUE (sym) = atoi (p);
+           SYMBOL_CLASS (sym) = LOC_CONST;
+         }
+         break;
+
+       case 's':
+         {
+           struct type *range_type;
+           int ind = 0;
+           char quote = *p++;
+           char *startp = p;
+           gdb_byte *string_local = (gdb_byte *) alloca (strlen (p));
+           gdb_byte *string_value;
+
+           if (quote != '\'' && quote != '"')
+             {
+               SYMBOL_CLASS (sym) = LOC_CONST;
+               SYMBOL_TYPE (sym) = error_type (&p, objfile);
+               SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+               add_symbol_to_list (sym, &file_symbols);
+               return sym;
+             }
+
+           /* Find matching quote, rejecting escaped quotes.  */
+           while (*p && *p != quote)
+             {
+               if (*p == '\\' && p[1] == quote)
+                 {
+                   string_local[ind] = (gdb_byte) quote;
+                   ind++;
+                   p += 2;
+                 }
+               else if (*p) 
+                 {
+                   string_local[ind] = (gdb_byte) (*p);
+                   ind++;
+                   p++;
+                 }
+             }
+           if (*p != quote)
+             {
+               SYMBOL_CLASS (sym) = LOC_CONST;
+               SYMBOL_TYPE (sym) = error_type (&p, objfile);
+               SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+               add_symbol_to_list (sym, &file_symbols);
+               return sym;
+             }
+
+           /* NULL terminate the string.  */
+           string_local[ind] = 0;
+           range_type = create_range_type (NULL,
+                                           objfile_type (objfile)->builtin_int,
+                                           0, ind);
+           SYMBOL_TYPE (sym) = create_array_type (NULL,
+                                 objfile_type (objfile)->builtin_char,
+                                 range_type);
+           string_value = obstack_alloc (&objfile->objfile_obstack, ind + 1);
+           memcpy (string_value, string_local, ind + 1);
+           p++;
+
+           SYMBOL_VALUE_BYTES (sym) = string_value;
+           SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+         }
+         break;
+
        case 'e':
          /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value
             can be represented as integral.
@@ -1682,8 +1747,7 @@ again:
 
     case 'f':                  /* Function returning another type */
       type1 = read_type (pp, objfile);
-      type = make_function_type (type1, dbx_lookup_type (typenums, objfile),
-                                objfile);
+      type = make_function_type (type1, dbx_lookup_type (typenums, objfile));
       break;
 
     case 'g':                   /* Prototyped function.  (Sun)  */
@@ -1707,7 +1771,7 @@ again:
         struct type *return_type = read_type (pp, objfile);
         struct type *func_type
           = make_function_type (return_type,
-                               dbx_lookup_type (typenums, objfile), objfile);
+                               dbx_lookup_type (typenums, objfile));
         struct type_list {
           struct type *type;
           struct type_list *next;
@@ -3329,6 +3393,42 @@ complain_about_struct_wipeout (struct type *type)
             _("struct/union type gets multiply defined: %s%s"), kind, name);
 }
 
+/* Set the length for all variants of a same main_type, which are
+   connected in the closed chain.
+   
+   This is something that needs to be done when a type is defined *after*
+   some cross references to this type have already been read.  Consider
+   for instance the following scenario where we have the following two
+   stabs entries:
+
+        .stabs  "t:p(0,21)=*(0,22)=k(0,23)=xsdummy:",160,0,28,-24
+        .stabs  "dummy:T(0,23)=s16x:(0,1),0,3[...]"
+
+   A stubbed version of type dummy is created while processing the first
+   stabs entry.  The length of that type is initially set to zero, since
+   it is unknown at this point.  Also, a "constant" variation of type
+   "dummy" is created as well (this is the "(0,22)=k(0,23)" section of
+   the stabs line).
+
+   The second stabs entry allows us to replace the stubbed definition
+   with the real definition.  However, we still need to adjust the length
+   of the "constant" variation of that type, as its length was left
+   untouched during the main type replacement...  */
+
+static void
+set_length_in_type_chain (struct type *type)
+{
+  struct type *ntype = TYPE_CHAIN (type);
+
+  while (ntype != type)
+    {
+      if (TYPE_LENGTH(ntype) == 0)
+       TYPE_LENGTH (ntype) = TYPE_LENGTH (type);
+      else
+        complain_about_struct_wipeout (ntype);
+      ntype = TYPE_CHAIN (ntype);
+    }
+}
 
 /* Read the description of a structure (or union type) and return an object
    describing the type.
@@ -3387,6 +3487,7 @@ read_struct_type (char **pp, struct type *type, enum type_code type_code,
     TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits, 0);
     if (nbits != 0)
       return error_type (pp, objfile);
+    set_length_in_type_chain (type);
   }
 
   /* Now read the baseclasses, if any, read the regular C struct or C++
@@ -3551,6 +3652,7 @@ read_enum_type (char **pp, struct type *type,
   /* Now fill in the fields of the type-structure.  */
 
   TYPE_LENGTH (type) = gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT;
+  set_length_in_type_chain (type);
   TYPE_CODE (type) = TYPE_CODE_ENUM;
   TYPE_STUB (type) = 0;
   if (unsigned_enum)
@@ -4116,7 +4218,17 @@ read_args (char **pp, int end, struct objfile *objfile, int *nargsp,
     }
   (*pp)++;                     /* get past `end' (the ':' character) */
 
-  if (TYPE_CODE (types[n - 1]) != TYPE_CODE_VOID)
+  if (n == 0)
+    {
+      /* We should read at least the THIS parameter here.  Some broken stabs
+        output contained `(0,41),(0,42)=@s8;-16;,(0,43),(0,1);' where should
+        have been present ";-16,(0,43)" reference instead.  This way the
+        excessive ";" marker prematurely stops the parameters parsing.  */
+
+      complaint (&symfile_complaints, _("Invalid (empty) method arguments"));
+      *varargsp = 0;
+    }
+  else if (TYPE_CODE (types[n - 1]) != TYPE_CODE_VOID)
     *varargsp = 1;
   else
     {