+Mon Nov 15 11:38:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * gdbtypes.h: Add TYPE_FLAG_TARGET_STUB.
+ * gdbtypes.c (check_stub_type): On TYPE_FLAG_TARGET_STUB, do
+ what cleanup_undefined_types does for arrays, except we clear
+ TYPE_FLAG_TARGET_STUB if we fix up the type.
+ * stabsread.c (cleanup_undefined_types): Add comments about how
+ doing arrays here is no longer the clean way to do it.
+ (read_array_type): Set TYPE_FLAG_TARGET_STUB as well as calling
+ add_undefined_type.
+ * c-typeprint.c, ch-typeprint.c: Move call to check_stub_type
+ outside switch so it happens for all type codes.
+ * cp-valprint.c (cp_print_value_fields): Recurse to val_print,
+ instead of c_val_print, so that check_stub_type gets called.
+
+ * gdbtypes.h, gdbtypes.c, m2-lang.c, ch-lang.c, c-lang.c: Remove
+ TYPE_FLAG_SIGNED. It was inconsistently set, never checked
+ (except in recursive_dump_type), and is pointless.
+
Mon Nov 15 00:40:38 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
* paread.c (pa_symfile_init): Look for the $TEXT$ section rather
case FT_SIGNED_CHAR:
type = init_type (TYPE_CODE_INT,
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_SIGNED, "signed char", objfile);
+ 0, "signed char", objfile);
break;
case FT_UNSIGNED_CHAR:
type = init_type (TYPE_CODE_INT,
case FT_SIGNED_SHORT:
type = init_type (TYPE_CODE_INT,
TARGET_SHORT_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_SIGNED, "short", objfile); /* FIXME-fnf */
+ 0, "short", objfile); /* FIXME-fnf */
break;
case FT_UNSIGNED_SHORT:
type = init_type (TYPE_CODE_INT,
case FT_SIGNED_INTEGER:
type = init_type (TYPE_CODE_INT,
TARGET_INT_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_SIGNED, "int", objfile); /* FIXME -fnf */
+ 0, "int", objfile); /* FIXME -fnf */
break;
case FT_UNSIGNED_INTEGER:
type = init_type (TYPE_CODE_INT,
case FT_SIGNED_LONG:
type = init_type (TYPE_CODE_INT,
TARGET_LONG_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_SIGNED, "long", objfile); /* FIXME -fnf */
+ 0, "long", objfile); /* FIXME -fnf */
break;
case FT_UNSIGNED_LONG:
type = init_type (TYPE_CODE_INT,
case FT_SIGNED_LONG_LONG:
type = init_type (TYPE_CODE_INT,
TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_SIGNED, "signed long long", objfile);
+ 0, "signed long long", objfile);
break;
case FT_UNSIGNED_LONG_LONG:
type = init_type (TYPE_CODE_INT,
return;
}
+ check_stub_type (type);
+
switch (TYPE_CODE (type))
{
case TYPE_CODE_ARRAY:
}
else if (show > 0)
{
- check_stub_type (type);
-
cp_type_print_derivation_info (stream, type);
fprintf_filtered (stream, "{\n");
type = init_type (TYPE_CODE_CHAR, 1, TYPE_FLAG_UNSIGNED, "CHAR", objfile);
break;
case FT_SIGNED_CHAR:
- type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_SIGNED, "BYTE", objfile);
+ type = init_type (TYPE_CODE_INT, 1, 0, "BYTE", objfile);
break;
case FT_UNSIGNED_CHAR:
type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, "UBYTE", objfile);
break;
case FT_SHORT: /* Chill ints are 2 bytes */
- type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_SIGNED, "INT", objfile);
+ type = init_type (TYPE_CODE_INT, 2, 0, "INT", objfile);
break;
case FT_UNSIGNED_SHORT: /* Chill ints are 2 bytes */
type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED, "UINT", objfile);
case FT_SIGNED_INTEGER: /* FIXME? */
case FT_LONG: /* Chill longs are 4 bytes */
case FT_SIGNED_LONG: /* Chill longs are 4 bytes */
- type = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_SIGNED, "LONG", objfile);
+ type = init_type (TYPE_CODE_INT, 4, 0, "LONG", objfile);
break;
case FT_UNSIGNED_INTEGER: /* FIXME? */
case FT_UNSIGNED_LONG: /* Chill longs are 4 bytes */
return;
}
+ check_stub_type (type);
+
switch (TYPE_CODE (type))
{
case TYPE_CODE_PTR:
}
else
{
- check_stub_type (type);
fprintf_filtered (stream, "(\n");
if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
{
/* END-FIXME */
-
-/* BEGIN-FIXME: Hooks into c-valprint.c */
-
-extern int
-c_val_print PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *, int, int, int,
- enum val_prettyprint));
-/* END-FIXME */
-
-
void
cp_print_class_method (valaddr, type, stream)
char *valaddr;
v = value_from_longest (TYPE_FIELD_TYPE (type, i),
unpack_field_as_long (type, valaddr, i));
- c_val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0,
- stream, format, 0, recurse + 1, pretty);
+ val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0,
+ stream, format, 0, recurse + 1, pretty);
}
}
else
}
else
{
- c_val_print (TYPE_FIELD_TYPE (type, i),
- valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
- 0, stream, format, 0, recurse + 1, pretty);
+ val_print (TYPE_FIELD_TYPE (type, i),
+ valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
+ 0, stream, format, 0, recurse + 1, pretty);
}
}
}
If this is a stubbed struct (i.e. declared as struct foo *), see if
we can find a full definition in some other file. If so, copy this
- definition, so we can use it in future. If not, set a flag so we
- don't waste too much time in future. (FIXME, this doesn't seem
- to be happening...)
+ definition, so we can use it in future. There used to be a comment (but
+ not any code) that if we don't find a full definition, we'd set a flag
+ so we don't spend time in the future checking the same type. That would
+ be a mistake, though--we might load in more symbols which contain a
+ full definition for the type.
This used to be coded as a macro, but I don't think it is called
- often enough to merit such treatment.
-*/
+ often enough to merit such treatment. */
struct complaint stub_noname_complaint =
{"stub type has NULL name", 0, 0};
(struct symtab **) NULL);
if (sym)
{
- memcpy ((char *)type, (char *)SYMBOL_TYPE(sym), sizeof (struct type));
+ memcpy ((char *)type,
+ (char *)SYMBOL_TYPE(sym),
+ sizeof (struct type));
+ }
+ }
+
+ if (TYPE_FLAGS (type) & TYPE_FLAG_TARGET_STUB)
+ {
+ struct type *range_type;
+
+ check_stub_type (TYPE_TARGET_TYPE (type));
+ if (!(TYPE_FLAGS (TYPE_TARGET_TYPE (type)) & TYPE_FLAG_STUB)
+ && TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_NFIELDS (type) == 1
+ && (TYPE_CODE (range_type = TYPE_FIELD_TYPE (type, 0))
+ == TYPE_CODE_RANGE))
+ {
+ /* Now recompute the length of the array type, based on its
+ number of elements and the target type's length. */
+ TYPE_LENGTH (type) =
+ ((TYPE_FIELD_BITPOS (range_type, 1)
+ - TYPE_FIELD_BITPOS (range_type, 0)
+ + 1)
+ * TYPE_LENGTH (TYPE_TARGET_TYPE (type)));
+ TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB;
}
}
}
{
puts_filtered (" TYPE_FLAG_UNSIGNED");
}
- if (TYPE_FLAGS (type) & TYPE_FLAG_SIGNED)
- {
- puts_filtered (" TYPE_FLAG_SIGNED");
- }
if (TYPE_FLAGS (type) & TYPE_FLAG_STUB)
{
puts_filtered (" TYPE_FLAG_STUB");
"char", (struct objfile *) NULL);
builtin_type_signed_char =
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_SIGNED,
+ 0,
"signed char", (struct objfile *) NULL);
builtin_type_unsigned_char =
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
#if !defined (GDBTYPES_H)
#define GDBTYPES_H 1
-/* When gdb creates fundamental types, it uses one of the following
- type identifiers. The identifiers are used to index a vector of
- pointers to any types that are created. */
+/* Codes for `fundamental types'. This is a monstrosity based on the
+ bogus notion that there are certain compiler-independent
+ `fundamental types'. None of these is well-defined (how big is
+ FT_SHORT? Does it depend on the language? How does the
+ language-specific code know which type to correlate to FT_SHORT?) */
#define FT_VOID 0
#define FT_BOOLEAN 1
/* Some bits for the type's flags word. */
-/* Explicitly unsigned integer type */
+/* Unsigned integer type. If this is not set for a TYPE_CODE_INT, the
+ type is signed. */
#define TYPE_FLAG_UNSIGNED (1 << 0)
-/* Explicitly signed integer type */
-
-#define TYPE_FLAG_SIGNED (1 << 1)
-
/* This appears in a type's flags word if it is a stub type (e.g., if
someone referenced a type that wasn't defined in a source file
via (struct sir_not_appearing_in_this_film *)). */
#define TYPE_FLAG_STUB (1 << 2)
+/* The target type of this type is a stub type, and this type needs to
+ be updated if it gets un-stubbed in check_stub_type. Currently only
+ used for arrays, in which TYPE_LENGTH of the array gets set based
+ on the TYPE_LENGTH of the target type. */
+
+#define TYPE_FLAG_TARGET_STUB (1 << 3)
struct type
{
case FT_SIGNED_CHAR:
type = init_type (TYPE_CODE_INT,
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_SIGNED, "signed char", objfile);
+ 0, "signed char", objfile);
break;
case FT_UNSIGNED_CHAR:
type = init_type (TYPE_CODE_INT,
case FT_SIGNED_SHORT:
type = init_type (TYPE_CODE_INT,
TARGET_SHORT_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_SIGNED, "short", objfile); /* FIXME-fnf */
+ 0, "short", objfile); /* FIXME-fnf */
break;
case FT_UNSIGNED_SHORT:
type = init_type (TYPE_CODE_INT,
case FT_SIGNED_INTEGER:
type = init_type (TYPE_CODE_INT,
TARGET_INT_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_SIGNED, "int", objfile); /* FIXME -fnf */
+ 0, "int", objfile); /* FIXME -fnf */
break;
case FT_UNSIGNED_INTEGER:
type = init_type (TYPE_CODE_INT,
case FT_SIGNED_LONG:
type = init_type (TYPE_CODE_INT,
TARGET_LONG_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_SIGNED, "long", objfile); /* FIXME -fnf */
+ 0, "long", objfile); /* FIXME -fnf */
break;
case FT_UNSIGNED_LONG:
type = init_type (TYPE_CODE_INT,
case FT_SIGNED_LONG_LONG:
type = init_type (TYPE_CODE_INT,
TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_SIGNED, "signed long long", objfile);
+ 0, "signed long long", objfile);
break;
case FT_UNSIGNED_LONG_LONG:
type = init_type (TYPE_CODE_INT,
*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
/* 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);
}
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;
}