struct nextfield
{
struct nextfield *next;
+
+ /* This is the raw visibility from the stab. It is not checked
+ for being one of the visibilities we recognize, so code which
+ examines this field better be able to deal. */
int visibility;
+
struct field field;
} *list;
struct next_fnfieldlist
#define BELIEVE_PCC_PROMOTION 0
#endif
-#if 0
-/* I think this can go away, all current uses have been removed.
- GCC emits a few crazy types which can only be distinguished by the
- name (complex, long long on some machines), but I'd say fix GCC. */
-
-/* During some calls to read_type (and thus to read_range_type), this
- contains the name of the type being defined. Range types are only
- used in C as basic types. We use the name to distinguish the otherwise
- identical basic types "int" and "long" and their unsigned versions.
- FIXME, this should disappear with better type management. */
-
-static char *long_kludge_name;
-#endif
-
-#if 0
-struct complaint dbx_class_complaint =
-{
- "encountered DBX-style class variable debugging information.\n\
-You seem to have compiled your program with \
-\"g++ -g0\" instead of \"g++ -g\".\n\
-Therefore GDB will not know about your class variables", 0, 0
-};
-#endif
-
struct complaint invalid_cpp_abbrev_complaint =
{"invalid C++ abbreviation `%s'", 0, 0};
/* Check for and handle cretinous stabs symbol name continuation! */
#define STABS_CONTINUE(pp) \
do { \
- if (**(pp) == '\\') *(pp) = next_symbol_text (); \
+ if (**(pp) == '\\' || (**(pp) == '?' && (*(pp))[1] == '\0')) \
+ *(pp) = next_symbol_text (); \
} while (0)
\f
{
name = stabs->stab[ii];
pp = (char*) strchr (name, ':');
+ while (pp[1] == ':')
+ {
+ pp += 2;
+ pp = (char *)strchr(pp, ':');
+ }
sym = find_symbol_in_list (symbols, name, pp-name);
if (!sym)
{
static char *type_synonym_name;
+#if !defined (REG_STRUCT_HAS_ADDR)
+#define REG_STRUCT_HAS_ADDR(gcc_p) 0
+#endif
+
/* ARGSUSED */
struct symbol *
define_symbol (valu, string, desc, type, objfile)
if (p == 0)
return 0;
+ while (p[1] == ':')
+ {
+ p += 2;
+ p = strchr(p, ':');
+ }
+
/* If a nameless stab entry, all we need is the type, not the symbol.
e.g. ":t10=*2" or a nameless enum like " :T16=ered:0,green:1,blue:2,;" */
nameless = (p == string || ((string[0] == ' ') && (string[1] == ':')));
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.
+
+ But we only do this in the REG_STRUCT_HAS_ADDR case, so that
+ we can still get information about what is going on with the
+ stack (VAX for computing args_printed, using stack slots instead
+ of saved registers in backtraces, etc.).
+
Note that this code illegally combines
- main(argc) int argc; { register int argc = 1; }
+ main(argc) struct foo argc; { register struct foo argc; }
but this case is considered pathological and causes a warning
from a decent compiler. */
+
if (local_symbols
- && local_symbols->nsyms > 0)
+ && local_symbols->nsyms > 0
+ && REG_STRUCT_HAS_ADDR (processing_gcc_compilation)
+ && (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT
+ || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION))
{
struct symbol *prev_sym;
prev_sym = local_symbols->symbol[local_symbols->nsyms - 1];
break;
case 't':
-#if 0
- /* See comment where long_kludge_name is declared. */
- /* Here we save the name of the symbol for read_range_type, which
- ends up reading in the basic types. In stabs, unfortunately there
- is no distinction between "int" and "long" types except their
- names. Until we work out a saner type policy (eliminating most
- builtin types and using the names specified in the files), we
- save away the name so that far away from here in read_range_type,
- we can examine it to decide between "int" and "long". FIXME. */
- long_kludge_name = SYMBOL_NAME (sym);
-#endif
SYMBOL_TYPE (sym) = read_type (&p, objfile);
/* For a nameless type, we don't want a create a symbol, thus we
strlen (SYMBOL_NAME (sym)),
&objfile -> symbol_obstack);
}
+ /* The semantics of C++ state that "struct foo { ... }" also defines
+ a typedef for "foo". Unfortunately, cfront never makes the typedef
+ when translating C++ into C. We make the typedef here so that
+ "ptype foo" works as expected for cfront translated code. */
+ else if (current_subfile->language == language_cplus)
+ {
+ synonym = 1;
+ type_synonym_name = obsavestring (SYMBOL_NAME (sym),
+ strlen (SYMBOL_NAME (sym)),
+ &objfile -> symbol_obstack);
+ }
SYMBOL_TYPE (sym) = read_type (&p, objfile);
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_STRUCT)
|| (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)))
SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
}
/* Check for and handle cretinous dbx symbol name continuation! */
- if ((*pp)[-1] == '\\')
+ if ((*pp)[-1] == '\\' || (*pp)[-1] == '?')
{
*pp = next_symbol_text ();
}
there is no size attribute. */
int type_size = -1;
+ /* Used to distinguish string and bitstring from char-array and set. */
+ int is_string = 0;
+
/* Read type number if present. The type number may be omitted.
for instance in a two-dimensional array declared with type
"ar1;1;10;ar1;1;10;4". */
if (type_size <= 0)
type_size = -1;
break;
+
+ case 'S':
+ is_string = 1;
+ break;
+
default:
/* Ignore unrecognized type attributes, so future compilers
can invent new ones. */
char *type_name;
{
- char *from, *to;
+ char *from, *to, *p, *q1, *q2;
/* Set the type code according to the following letter. */
switch ((*pp)[0])
code = TYPE_CODE_ENUM;
break;
default:
- return error_type (pp);
+ {
+ /* Complain and keep going, so compilers can invent new
+ cross-reference types. */
+ static struct complaint msg =
+ {"Unrecognized cross-reference type `%c'", 0, 0};
+ complain (&msg, (*pp)[0]);
+ code = TYPE_CODE_STRUCT;
+ break;
+ }
}
-
- to = type_name = (char *)
- obstack_alloc (&objfile -> type_obstack,
- (((char *) strchr (*pp, ':') - (*pp)) + 1));
+
+ q1 = strchr(*pp, '<');
+ p = strchr(*pp, ':');
+ if (p == NULL)
+ return error_type (pp);
+ while (q1 && p > q1 && p[1] == ':')
+ {
+ q2 = strchr(q1, '>');
+ if (!q2 || q2 < p)
+ break;
+ p += 2;
+ p = strchr(p, ':');
+ if (p == NULL)
+ return error_type (pp);
+ }
+ to = type_name =
+ (char *)obstack_alloc (&objfile->type_obstack, p - *pp + 1);
/* Copy the name. */
from = *pp + 1;
- while ((*to++ = *from++) != ':')
- ;
- *--to = '\0';
+ while (from < p)
+ *to++ = *from++;
+ *to = '\0';
- /* Set the pointer ahead of the name which we just read. */
- *pp = from;
+ /* Set the pointer ahead of the name which we just read, and
+ the colon. */
+ *pp = from + 1;
}
- /* Now check to see whether the type has already been declared. */
- /* This is necessary at least in the case where the
- program says something like
- struct foo bar[5];
- The compiler puts out a cross-reference; we better find
- set the length of the structure correctly so we can
- set the length of the array. */
+ /* Now check to see whether the type has already been
+ declared. This was written for arrays of cross-referenced
+ types before we had TYPE_CODE_TARGET_STUBBED, so I'm pretty
+ sure it is not necessary anymore. But it might be a good
+ idea, to save a little memory. */
+
for (ppt = file_symbols; ppt; ppt = ppt->next)
for (i = 0; i < ppt->nsyms; i++)
{
return type;
}
}
-
+
/* Didn't find the type to which this refers, so we must
be dealing with a forward reference. Allocate a type
structure for it, and keep track of it so we can
case '9':
case '(':
- (*pp)--;
- if (read_type_number (pp, xtypenums) != 0)
- return error_type (pp);
+ {
+ char *pp_saved;
- if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
- /* It's being defined as itself. That means it is "void". */
- type = init_type (TYPE_CODE_VOID, 0, 0, NULL, objfile);
- else
- {
- struct type *xtype = *dbx_lookup_type (xtypenums);
+ (*pp)--;
+ pp_saved = *pp;
- /* This can happen if we had '-' followed by a garbage character,
- for example. */
- if (xtype == NULL)
- return error_type (pp);
+ /* Peek ahead at the number to detect void. */
+ if (read_type_number (pp, xtypenums) != 0)
+ return error_type (pp);
- /* The type is being defined to another type. So we copy the type.
- This loses if we copy a C++ class and so we lose track of how
- the names are mangled (but g++ doesn't output stabs like this
- now anyway). */
-
- type = alloc_type (objfile);
- memcpy (type, xtype, sizeof (struct type));
-
- /* The idea behind clearing the names is that the only purpose
- for defining a type to another type is so that the name of
- one can be different. So we probably don't need to worry much
- about the case where the compiler doesn't give a name to the
- new type. */
- TYPE_NAME (type) = NULL;
- TYPE_TAG_NAME (type) = NULL;
- }
- if (typenums[0] != -1)
- *dbx_lookup_type (typenums) = type;
- break;
+ if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
+ /* It's being defined as itself. That means it is "void". */
+ type = init_type (TYPE_CODE_VOID, 0, 0, NULL, objfile);
+ else
+ {
+ struct type *xtype;
+
+ /* Go back to the number and have read_type get it. This means
+ that we can deal with something like t(1,2)=(3,4)=... which
+ the Lucid compiler uses. */
+ *pp = pp_saved;
+ xtype = read_type (pp, objfile);
+
+ /* The type is being defined to another type. So we copy the type.
+ This loses if we copy a C++ class and so we lose track of how
+ the names are mangled (but g++ doesn't output stabs like this
+ now anyway). */
+
+ type = alloc_type (objfile);
+ memcpy (type, xtype, sizeof (struct type));
+
+ /* The idea behind clearing the names is that the only purpose
+ for defining a type to another type is so that the name of
+ one can be different. So we probably don't need to worry much
+ about the case where the compiler doesn't give a name to the
+ new type. */
+ TYPE_NAME (type) = NULL;
+ TYPE_TAG_NAME (type) = NULL;
+ }
+ if (typenums[0] != -1)
+ *dbx_lookup_type (typenums) = type;
+ break;
+ }
/* In the following types, we must be sure to overwrite any existing
type that the typenums refer to, rather than allocating a new one
type = dbx_alloc_type (typenums, objfile);
type = read_array_type (pp, type, objfile);
+ if (is_string)
+ TYPE_CODE (type) = TYPE_CODE_STRING;
+ break;
+
+ case 'S':
+ type1 = read_type (pp, objfile);
+ type = create_set_type ((struct type*) NULL, type1);
+ if (is_string)
+ TYPE_CODE (type) = TYPE_CODE_BITSTRING;
+ if (typenums[0] != -1)
+ *dbx_lookup_type (typenums) = type;
break;
default:
#define VISIBILITY_PRIVATE '0' /* Stabs character for private field */
#define VISIBILITY_PROTECTED '1' /* Stabs character for protected fld */
#define VISIBILITY_PUBLIC '2' /* Stabs character for public field */
-#define VISIBILITY_IGNORE '9' /* artificial character for ignore the field */
+#define VISIBILITY_IGNORE '9' /* Optimized out or zero length */
/* Read member function stabs info for C++ classes. The form of each member
function data is:
fip -> list -> field.name =
obsavestring (*pp, p - *pp, &objfile -> type_obstack);
*pp = p + 1;
-
+
/* This means we have a visibility for a field coming. */
if (**pp == '/')
{
(*pp)++;
fip -> list -> visibility = *(*pp)++;
- switch (fip -> list -> visibility)
- {
- case VISIBILITY_PRIVATE:
- case VISIBILITY_PROTECTED:
- break;
-
- case VISIBILITY_PUBLIC:
- /* Nothing to do */
- break;
-
- default:
- /* Unknown visibility specifier. */
- complain (&stabs_general_complaint,
- "unknown visibility specifier");
- return;
- break;
- }
}
else
{
/* normal dbx-style format, no explicit visibility */
fip -> list -> visibility = VISIBILITY_PUBLIC;
}
-
+
fip -> list -> field.type = read_type (pp, objfile);
if (**pp == ':')
{
return;
}
}
- /* kung: I add a new visibility type VISIBILITY_IGNORE, so that
- when printing value, this field will print <no value>. ptype
- will still print the type info of the field. */
- /* FIXME-tiemann: Can't the compiler put out something which
- lets us distinguish these? (or maybe just not put out anything
- for the field). What is the story here? What does the compiler
- really do? Also, patch gdb.texinfo for this case; I document
- it as a possible problem there. Search for "DBX-style". */
-
- /* This is wrong because this is identical to the symbols
- produced for GCC 0-size arrays. For example:
- typedef union {
- int num;
- char str[0];
- } foo;
- The code which dumped core in such circumstances should be
- fixed not to dump core. */
-
- /* g++ -g0 can put out bitpos & bitsize zero for a static
- field. This does not give us any way of getting its
- class, so we can't know its name. But we can just
- ignore the field so we don't dump core and other nasty
- stuff. */
+
if (fip -> list -> field.bitpos == 0 && fip -> list -> field.bitsize == 0)
{
- /* complain (&dbx_class_complaint); */
+ /* This can happen in two cases: (1) at least for gcc 2.4.5 or so,
+ it is a field which has been optimized out. The correct stab for
+ this case is to use VISIBILITY_IGNORE, but that is a recent
+ invention. (2) It is a 0-size array. For example
+ union { int num; char str[0]; } foo. Printing "<no value>" for
+ str in "p foo" is OK, since foo.str (and thus foo.str[3])
+ will continue to work, and a 0-size array as a whole doesn't
+ have any contents to print.
+
+ I suspect this probably could also happen with gcc -gstabs (not
+ -gstabs+) for static fields, and perhaps other C++ extensions.
+ Hopefully few people use -gstabs with gdb, since it is intended
+ for dbx compatibility. */
+
/* Ignore this field. */
fip -> list-> visibility = VISIBILITY_IGNORE;
}
dbx gives a bit size for all fields.
Note that forward refs cannot be packed,
and treat enums as if they had the width of ints. */
-
+
if (TYPE_CODE (fip -> list -> field.type) != TYPE_CODE_INT
&& TYPE_CODE (fip -> list -> field.type) != TYPE_CODE_ENUM)
{
'/0' (VISIBILITY_PRIVATE)
'/1' (VISIBILITY_PROTECTED)
'/2' (VISIBILITY_PUBLIC)
+ '/9' (VISIBILITY_IGNORE)
or nothing, for C style fields with public visibility.
Returns 1 for success, 0 for failure. */
-
+
static int
read_struct_fields (fip, pp, type, objfile)
struct field_info *fip;
}
read_one_struct_field (fip, pp, p, type, objfile);
}
- if (p[1] == ':')
+ if (p[0] == ':' && p[1] == ':')
{
/* chill the list of fields: the last entry (at the head) is a
partially constructed entry which we now scrub. */
new -> field.bitsize = 0; /* this should be an unpacked field! */
STABS_CONTINUE (pp);
- switch (*(*pp)++)
+ switch (**pp)
{
case '0':
/* Nothing to do. */
SET_TYPE_FIELD_VIRTUAL (type, i);
break;
default:
- /* Bad visibility format. */
- return 0;
+ /* Unknown character. Complain and treat it as non-virtual. */
+ {
+ static struct complaint msg = {
+ "Unknown virtual character `%c' for baseclass", 0, 0};
+ complain (&msg, **pp);
+ }
}
+ ++(*pp);
new -> visibility = *(*pp)++;
switch (new -> visibility)
case VISIBILITY_PUBLIC:
break;
default:
- /* Bad visibility format. */
- return 0;
+ /* Bad visibility format. Complain and treat it as
+ public. */
+ {
+ static struct complaint msg = {
+ "Unknown visibility `%c' for baseclass", 0, 0};
+ complain (&msg, new -> visibility);
+ new -> visibility = VISIBILITY_PUBLIC;
+ }
}
{
case VISIBILITY_IGNORE:
SET_TYPE_FIELD_IGNORE (type, nfields);
+ break;
case VISIBILITY_PUBLIC:
break;
default:
- /* Should warn about this unknown visibility? */
+ /* Unknown visibility. Complain and treat it as public. */
+ {
+ static struct complaint msg = {
+ "Unknown visibility `%c' for field", 0, 0};
+ complain (&msg, fip -> list -> visibility);
+ }
break;
}
fip -> list = fip -> list -> next;
return error_type (pp);
++*pp;
- if (!(**pp >= '0' && **pp <= '9'))
+ if (!(**pp >= '0' && **pp <= '9') && **pp != '-')
{
(*pp)++;
adjustable = 1;
if (nbits != 0)
return error_type (pp);
- if (!(**pp >= '0' && **pp <= '9'))
+ if (!(**pp >= '0' && **pp <= '9') && **pp != '-')
{
(*pp)++;
adjustable = 1;
/* If we have an array whose element type is not yet known, but whose
bounds *are* known, record it to be adjusted at the end of the file. */
+ /* FIXME: Why check for zero length rather than TYPE_FLAG_STUB? I think
+ the two have the same effect except that the latter is cleaner and the
+ former would be wrong for types which really are zero-length (if we
+ have any). */
if (TYPE_LENGTH (element_type) == 0 && !adjustable)
{
+ TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
add_undefined_type (type);
}
/* Now fill in the fields of the type-structure. */
- TYPE_LENGTH (type) = sizeof (int);
+ TYPE_LENGTH (type) = TARGET_INT_BIT / HOST_CHAR_BIT;
TYPE_CODE (type) = TYPE_CODE_ENUM;
TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
TYPE_NFIELDS (type) = nsyms;
if (nbits != 0)
return error_type (pp);
-#if 0
- /* FIXME. Here we should just be able to make a type of the right
- number of bits and signedness. FIXME. */
-
- if (type_bits == TARGET_LONG_LONG_BIT)
- return (lookup_fundamental_type (objfile,
- signed_type? FT_LONG_LONG: FT_UNSIGNED_LONG_LONG));
-
- if (type_bits == TARGET_INT_BIT)
- {
- /* FIXME -- the only way to distinguish `int' from `long'
- is to look at its name! */
- if (signed_type)
- {
- if (long_kludge_name && long_kludge_name[0] == 'l' /* long */)
- return lookup_fundamental_type (objfile, FT_LONG);
- else
- return lookup_fundamental_type (objfile, FT_INTEGER);
- }
- else
- {
- if (long_kludge_name
- && ((long_kludge_name[0] == 'u' /* unsigned */ &&
- long_kludge_name[9] == 'l' /* long */)
- || (long_kludge_name[0] == 'l' /* long unsigned */)))
- return lookup_fundamental_type (objfile, FT_UNSIGNED_LONG);
- else
- return lookup_fundamental_type (objfile, FT_UNSIGNED_INTEGER);
- }
- }
-
- if (type_bits == TARGET_SHORT_BIT)
- return (lookup_fundamental_type (objfile,
- signed_type? FT_SHORT: FT_UNSIGNED_SHORT));
-
- if (type_bits == TARGET_CHAR_BIT)
- return (lookup_fundamental_type (objfile,
- signed_type? FT_CHAR: FT_UNSIGNED_CHAR));
-
- if (type_bits == 0)
- return lookup_fundamental_type (objfile, FT_VOID);
-
- return error_type (pp);
-#else
return init_type (type_bits == 0 ? TYPE_CODE_VOID : TYPE_CODE_INT,
type_bits / TARGET_CHAR_BIT,
signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
objfile);
-#endif
}
static struct type *
case TYPE_CODE_UNION:
case TYPE_CODE_ENUM:
{
- /* Check if it has been defined since. */
+ /* Check if it has been defined since. Need to do this here
+ as well as in check_stub_type to deal with the (legitimate in
+ C though not C++) case of several types with the same name
+ in different source files. */
if (TYPE_FLAGS (*type) & TYPE_FLAG_STUB)
{
struct pending *ppt;
}
break;
- case TYPE_CODE_ARRAY:
+ case TYPE_CODE_ARRAY:
{
+ /* This is a kludge which is here for historical reasons
+ because I suspect that check_stub_type does not get
+ called everywhere it needs to be called for arrays. Even
+ with this kludge, those places are broken for the case
+ where the stub type is defined in another compilation
+ unit, but this kludge at least deals with it for the case
+ in which it is the same compilation unit.
+
+ Don't try to do this by calling check_stub_type; it might
+ cause symbols to be read in lookup_symbol, and the symbol
+ reader is not reentrant. */
+
struct type *range_type;
int lower, upper;
upper = TYPE_FIELD_BITPOS (range_type, 1);
TYPE_LENGTH (*type) = (upper - lower + 1)
* TYPE_LENGTH (TYPE_TARGET_TYPE (*type));
+
+ /* If the target type is not a stub, we could be clearing
+ TYPE_FLAG_TARGET_STUB for *type. */
}
break;
break;
}
}
+
undef_types_length = 0;
}