/* Support routines for decoding "stabs" debugging information format.
- Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 1997
+ Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
/* end new functions added for cfront support */
-static void
+static void
add_live_range PARAMS ((struct objfile *, struct symbol *,
CORE_ADDR, CORE_ADDR));
-static int
+static int
resolve_live_range PARAMS ((struct objfile *, struct symbol *, char *));
-static int
+static int
process_reference PARAMS ((char **string));
-static CORE_ADDR
+static CORE_ADDR
ref_search_value PARAMS ((int refnum));
-static void
-ref_init PARAMS ((void));
-
-static char *
-get_substring PARAMS ((char ** p, int c));
+static int
+resolve_symbol_reference PARAMS ((struct objfile *, struct symbol *, char *));
static const char vptr_name[] = { '_','v','p','t','r',CPLUS_MARKER,'\0' };
static const char vb_name[] = { '_','v','b',CPLUS_MARKER,'\0' };
#define BELIEVE_PCC_PROMOTION 0
#endif
-struct complaint invalid_cpp_abbrev_complaint =
+static struct complaint invalid_cpp_abbrev_complaint =
{"invalid C++ abbreviation `%s'", 0, 0};
-struct complaint invalid_cpp_type_complaint =
+static struct complaint invalid_cpp_type_complaint =
{"C++ abbreviated type name unknown at symtab pos %d", 0, 0};
-struct complaint member_fn_complaint =
+static struct complaint member_fn_complaint =
{"member function type missing, got '%c'", 0, 0};
-struct complaint const_vol_complaint =
+static struct complaint const_vol_complaint =
{"const/volatile indicator missing, got '%c'", 0, 0};
-struct complaint error_type_complaint =
+static struct complaint error_type_complaint =
{"debug info mismatch between compiler and debugger", 0, 0};
-struct complaint invalid_member_complaint =
+static struct complaint invalid_member_complaint =
{"invalid (minimal) member type data format at symtab pos %d.", 0, 0};
-struct complaint range_type_base_complaint =
+static struct complaint range_type_base_complaint =
{"base type %d of range type is not defined", 0, 0};
-struct complaint reg_value_complaint =
+static struct complaint reg_value_complaint =
{"register number %d too large (max %d) in symbol %s", 0, 0};
-struct complaint vtbl_notfound_complaint =
+static struct complaint vtbl_notfound_complaint =
{"virtual function table pointer not found when defining class `%s'", 0, 0};
-struct complaint unrecognized_cplus_name_complaint =
+static struct complaint unrecognized_cplus_name_complaint =
{"Unknown C++ symbol name `%s'", 0, 0};
-struct complaint rs6000_builtin_complaint =
+static struct complaint rs6000_builtin_complaint =
{"Unknown builtin type %d", 0, 0};
-struct complaint unresolved_sym_chain_complaint =
+static struct complaint unresolved_sym_chain_complaint =
{"%s: common block `%s' from global_sym_chain unresolved", 0, 0};
-struct complaint stabs_general_complaint =
+static struct complaint stabs_general_complaint =
+ {"%s", 0, 0};
+
+static struct complaint lrs_general_complaint =
{"%s", 0, 0};
/* Make a list of forward references which haven't been defined. */
/* End of code added to support parsing of ARM/Cfront stabs strings */
-/* This routine fixes up symbol references to point to the original
- symbol definition.
- The main need for this function is to add information for supporting
- live range splitting.
- eg: p : "#7=", "#2=z:r(0,1)" "#2:r(0,1);l(#5,#6),l(#7,#4)" */
-int
+/* This routine fixes up symbol references/aliases to point to the original
+ symbol definition. Returns 0 on failure, non-zero on success. */
+
+static int
resolve_symbol_reference (objfile, sym, p)
- struct objfile * objfile;
- struct symbol * sym;
- char * p;
+ struct objfile *objfile;
+ struct symbol *sym;
+ char *p;
{
int refnum;
- struct symbol * ref_sym=0;
- struct cleanup *back_to;
-
- back_to = make_cleanup (null_cleanup, 0);
+ struct symbol *ref_sym=0;
+ struct alias_list *alias;
- if (*p != '#') /* symbol ref id */
+ /* If this is not a symbol reference return now. */
+ if (*p != '#')
return 0;
/* Use "#<num>" as the name; we'll fix the name later.
/*---------------------------------------------------------*/
/* This gets reference name from string. sym may not have a name. */
+
+ /* Get the reference number associated with the reference id in the
+ gdb stab string. From that reference number, get the main/primary
+ symbol for this alias. */
refnum = process_reference (&p);
ref_sym = ref_search (refnum);
if (!ref_sym)
- error ("error: symbol for reference not found.\n");
+ {
+ complain (&lrs_general_complaint, "symbol for reference not found");
+ return 0;
+ }
/* Parse the stab of the referencing symbol
now that we have the referenced symbol.
/*--------------------------------------------------*/
/* Add this symbol to the reference list. */
/*--------------------------------------------------*/
- SYMBOL_ALIASES (sym) = SYMBOL_ALIASES (ref_sym);
- SYMBOL_ALIASES (ref_sym) = sym;
+
+ alias = (struct alias_list *) obstack_alloc (&objfile->type_obstack,
+ sizeof (struct alias_list));
+ if (!alias)
+ {
+ complain (&lrs_general_complaint, "Unable to allocate alias list memory");
+ return 0;
+ }
+
+ alias->next = 0;
+ alias->sym = sym;
+
+ if (!SYMBOL_ALIASES (ref_sym))
+ {
+ SYMBOL_ALIASES (ref_sym) = alias;
+ }
+ else
+ {
+ struct alias_list *temp;
+
+ /* Get to the end of the list. */
+ for (temp = SYMBOL_ALIASES (ref_sym);
+ temp->next;
+ temp = temp->next)
+ ;
+ temp->next = alias;
+ }
/* Want to fix up name so that other functions (eg. valops)
will correctly print the name.
SYMBOL_NAME (sym) = SYMBOL_NAME (ref_sym);
/* Done! */
-
- do_cleanups (back_to);
- return 0;
-}
-
-/* Get range symbol reference. eg. "#2),l(#3,#5)"
- postpone resolve_reference until after we're done reading symbols. */
-struct symbol *
-resolve_reference (p)
- char *p;
-{
- char sym_refid[32];
- struct symbol *sym = 0;
- char *s = p;
- int len;
-
- if (!s || *s != '#')
- return 0;
- p = strchr (s, ')');
- if (!p || p == s)
- return 0;
- len = p - s + 1;
- strncpy (sym_refid, s, len);
- sym_refid[len] = '\0';
- sym = lookup_symbol (sym_refid, 0, VAR_NAMESPACE, 0, 0);
- return sym;
+ return 1;
}
/* Structure for storing pointers to reference definitions for fast lookup
during "process_later". */
-#define MAX_REFS 100 /* FIXME! Change to use heap. */
-static struct ref_map_s
+
+struct ref_map
{
char *stabs;
CORE_ADDR value;
struct symbol *sym;
-} ref_map[MAX_REFS];
-
-/* Initialize our list of references.
- This should be called before any symbol table is read.
- FIXME: Will reference numbers be unique only to objects? If so, we may
- need to add something to disambiguate the refids. Or, it might be OK to
- leave as is, as long as we read and process an object's symbol table all
- at once. */
-static int ref_count = 0; /* Ptr to free cell in linked list. */
-static void
-ref_init ()
-{
- ref_count = 0;
- memset (ref_map, 0, MAX_REFS * sizeof (struct ref_map_s));
-}
+};
+
+#define MAX_CHUNK_REFS 100
+#define REF_CHUNK_SIZE (MAX_CHUNK_REFS * sizeof (struct ref_map))
+#define REF_MAP_SIZE(ref_chunk) ((ref_chunk) * REF_CHUNK_SIZE)
+
+static struct ref_map *ref_map;
+
+/* Ptr to free cell in chunk's linked list. */
+static int ref_count = 0;
+
+/* Number of chunks malloced. */
+static int ref_chunk = 0;
/* Create array of pointers mapping refids to symbols and stab strings.
Add pointers to reference definition symbols and/or their values as we
CORE_ADDR value;
{
if (ref_count == 0)
- ref_init ();
+ ref_chunk = 0;
if (refnum >= ref_count)
ref_count = refnum + 1;
- if (ref_count > MAX_REFS)
- error ("no more free slots in chain\n");
+ if (ref_count > ref_chunk * MAX_CHUNK_REFS)
+ {
+ int new_slots = ref_count - ref_chunk * MAX_CHUNK_REFS;
+ int new_chunks = new_slots / MAX_CHUNK_REFS + 1;
+ ref_map = (struct ref_map *)
+ xrealloc (ref_map, REF_MAP_SIZE (ref_chunk + new_chunks));
+ memset (ref_map + ref_chunk * MAX_CHUNK_REFS, 0, new_chunks * REF_CHUNK_SIZE);
+ ref_chunk += new_chunks;
+ }
ref_map[refnum].stabs = stabs;
ref_map[refnum].sym = sym;
ref_map[refnum].value = value;
}
-/* Return defined sym for the reference "refnum" */
+/* Return defined sym for the reference REFNUM. */
struct symbol *
ref_search (refnum)
int refnum;
return ref_map[refnum].sym;
}
-/* Return value for the reference "refnum" */
+/* Return value for the reference REFNUM. */
+
static CORE_ADDR
ref_search_value (refnum)
int refnum;
return ref_map[refnum].value;
}
-/* Parse reference id and advance string to the next character following
- the string.
- Return the reference number. */
+/* Parse a reference id in STRING and return the resulting
+ reference number. Move STRING beyond the reference id. */
static int
process_reference (string)
if (**string != '#')
return 0;
+ /* Advance beyond the initial '#'. */
+ p = *string + 1;
+
/* Read number as reference id. */
- p = *string + 1; /* Advance beyond '#' */
while (*p && isdigit (*p))
{
refnum = refnum * 10 + *p - '0';
return refnum;
}
-/* If string defines a reference, store away a pointer to the reference
- definition for fast lookup when we "process_later",
- and return the reference number. */
+/* If STRING defines a reference, store away a pointer to the reference
+ definition for later use. Return the reference number. */
+
int
symbol_reference_defined (string)
char **string;
if (*p == '=')
{
/* Symbol is being defined here. */
-
*string = p + 1;
return refnum;
}
{
/* Must be a reference. Either the symbol has already been defined,
or this is a forward reference to it. */
-
*string = p;
- return 0; /* Not defined here */
+ return -1;
}
}
char *s;
int refnum, nlen;
- /* Initialize symbol references and determine if this is
- a definition. If symbol reference is being defined, go
- ahead and add it. Otherwise, just return sym. */
+ /* If STRING defines a new reference id, then add it to the
+ reference map. Else it must be referring to a previously
+ defined symbol, so add it to the alias list of the previously
+ defined symbol. */
s = string;
- if (refnum = symbol_reference_defined (&s), refnum)
- ref_add (refnum, sym, string, SYMBOL_VALUE (sym));
+ refnum = symbol_reference_defined (&s);
+ if (refnum >= 0)
+ ref_add (refnum, sym, string, SYMBOL_VALUE (sym));
else
- process_later (sym, string, resolve_symbol_reference);
+ if (!resolve_symbol_reference (objfile, sym, string))
+ return NULL;
- /* s is after refid... advance string there
- so that the symbol name will not include the refid. */
+ /* S..P contains the name of the symbol. We need to store
+ the correct name into SYMBOL_NAME. */
nlen = p - s;
- if (nlen > 0)
- {
- SYMBOL_NAME (sym) = (char *)
- obstack_alloc (&objfile -> symbol_obstack, nlen);
- strncpy (SYMBOL_NAME (sym), s, nlen);
- SYMBOL_NAME (sym)[nlen] = '\0';
- SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
- }
- else
- /* FIXME! Want SYMBOL_NAME (sym) = 0;
- Get error if leave name 0. So give it something. */
- {
- nlen = p - string;
- SYMBOL_NAME (sym) = (char *)
- obstack_alloc (&objfile -> symbol_obstack, nlen);
- strncpy (SYMBOL_NAME (sym), string, nlen);
- SYMBOL_NAME (sym)[nlen] = '\0';
- SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
- }
+ if (refnum >= 0)
+ {
+ if (nlen > 0)
+ {
+ SYMBOL_NAME (sym) = (char *)
+ obstack_alloc (&objfile -> symbol_obstack, nlen);
+ strncpy (SYMBOL_NAME (sym), s, nlen);
+ SYMBOL_NAME (sym)[nlen] = '\0';
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ }
+ else
+ /* FIXME! Want SYMBOL_NAME (sym) = 0;
+ Get error if leave name 0. So give it something. */
+ {
+ nlen = p - string;
+ SYMBOL_NAME (sym) = (char *)
+ obstack_alloc (&objfile -> symbol_obstack, nlen);
+ strncpy (SYMBOL_NAME (sym), string, nlen);
+ SYMBOL_NAME (sym)[nlen] = '\0';
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ }
+ }
+ /* Advance STRING beyond the reference id. */
string = s;
}
else
in GDB. E.g. "int" is converted to "function returning int". */
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_FUNC)
SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
+
+ /* All functions in C++ have prototypes. */
+ if (SYMBOL_LANGUAGE (sym) == language_cplus)
+ TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
+
/* fall into process_prototype_types */
process_prototype_types:
- /* Sun acc puts declared types of arguments here. We don't care
- about their actual types (FIXME -- we should remember the whole
- function prototype), but the list may define some new types
- that we have to remember, so we must scan it now. */
- while (*p == ';') {
- p++;
- read_type (&p, objfile);
- }
+ /* Sun acc puts declared types of arguments here. */
+ if (*p == ';')
+ {
+ struct type *ftype = SYMBOL_TYPE (sym);
+ int nsemi = 0;
+ int nparams = 0;
+ char *p1 = p;
+
+ /* Obtain a worst case guess for the number of arguments
+ by counting the semicolons. */
+ while (*p1)
+ {
+ if (*p1++ == ';')
+ nsemi++;
+ }
+
+ /* Allocate parameter information fields and fill them in. */
+ TYPE_FIELDS (ftype) = (struct field *)
+ TYPE_ALLOC (ftype, nsemi * sizeof (struct field));
+ while (*p++ == ';')
+ {
+ struct type *ptype;
+
+ /* A type number of zero indicates the start of varargs.
+ FIXME: GDB currently ignores vararg functions. */
+ if (p[0] == '0' && p[1] == '\0')
+ break;
+ ptype = read_type (&p, objfile);
+
+ /* The Sun compilers mark integer arguments, which should
+ be promoted to the width of the calling conventions, with
+ a type which references itself. This type is turned into
+ a TYPE_CODE_VOID type by read_type, and we have to turn
+ it back into builtin_type_int here.
+ FIXME: Do we need a new builtin_type_promoted_int_arg ? */
+ if (TYPE_CODE (ptype) == TYPE_CODE_VOID)
+ ptype = builtin_type_int;
+ TYPE_FIELD_TYPE (ftype, nparams++) = ptype;
+ }
+ TYPE_NFIELDS (ftype) = nparams;
+ TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
+ }
break;
case 'F':
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE_ADDRESS (sym) = valu;
#ifdef STATIC_TRANSFORM_NAME
- if (SYMBOL_NAME (sym)[0] == '$')
+ if (IS_STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)))
{
struct minimal_symbol *msym;
msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE_ADDRESS (sym) = valu;
#ifdef STATIC_TRANSFORM_NAME
- if (SYMBOL_NAME (sym)[0] == '$')
+ if (IS_STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)))
{
struct minimal_symbol *msym;
msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
}
}
- /* Is there more to parse? eg. ";l(#1,#2);l(#3,#5)" */
- while (*p && (*p == ';' || *p == ','))
+ /* Is there more to parse? For example LRS/alias information? */
+ while (*p && *p == ';')
{
p++;
if (*p && *p == 'l')
/* GNU extensions for live range splitting may be appended to
the end of the stab string. eg. "l(#1,#2);l(#3,#5)" */
- /* Fix up ranges later. */
- process_later (sym, p, resolve_live_range);
+ /* Resolve the live range and add it to SYM's live range list. */
+ if (!resolve_live_range (objfile, sym, p))
+ return NULL;
/* Find end of live range info. */
p = strchr (p, ')');
if (!*p || *p != ')')
- error ("Internal error: live range format not recognized.\n");
+ {
+ complain (&lrs_general_complaint, "live range format not recognized");
+ return NULL;
+ }
p++;
}
}
return sym;
}
+/* Add the live range found in P to the symbol SYM in objfile OBJFILE. Returns
+ non-zero on success, zero otherwise. */
-/* Add live range information to symbol. (eg. p is l(#1,#2)...) */
-static int
+static int
resolve_live_range (objfile, sym, p)
- struct objfile * objfile;
- struct symbol *sym;
- char *p;
+ struct objfile *objfile;
+ struct symbol *sym;
+ char *p;
{
- char *s=p;
int refnum;
CORE_ADDR start, end;
-
+
+ /* Sanity check the beginning of the stabs string. */
if (!*p || *p != 'l')
- error ("Internal error: live range string.\n");
+ {
+ complain (&lrs_general_complaint, "live range string 1");
+ return 0;
+ }
p++;
if (!*p || *p != '(')
- error ("Internal error: live range string.\n");
+ {
+ complain (&lrs_general_complaint, "live range string 2");
+ return 0;
+ }
p++;
- /* Get starting value of range symbol reference. eg. "#1,#2),l(#3,#5)"
- and advance p past the refid. */
+ /* Get starting value of range and advance P past the reference id.
+
+ ?!? In theory, the process_reference should never fail, but we should
+ catch that case just in case the compiler scrogged the stabs. */
refnum = process_reference (&p);
start = ref_search_value (refnum);
if (!start)
- error ("Internal error: live range symbol not found.\n");
+ {
+ complain (&lrs_general_complaint, "Live range symbol not found 1");
+ return 0;
+ }
if (!*p || *p != ',')
- error ("Internal error: live range string.\n");
+ {
+ complain (&lrs_general_complaint, "live range string 3");
+ return 0;
+ }
p++;
- /* Get ending value of range symbol reference. eg. "#2),l(#3,#5)" */
+ /* Get ending value of range and advance P past the reference id.
+
+ ?!? In theory, the process_reference should never fail, but we should
+ catch that case just in case the compiler scrogged the stabs. */
refnum = process_reference (&p);
end = ref_search_value (refnum);
if (!end)
- error ("Internal error: live range symbol not found.\n");
+ {
+ complain (&lrs_general_complaint, "Live range symbol not found 2");
+ return 0;
+ }
+ if (!*p || *p != ')')
+ {
+ complain (&lrs_general_complaint, "live range string 4");
+ return 0;
+ }
+
+ /* Now that we know the bounds of the range, add it to the
+ symbol. */
add_live_range (objfile, sym, start, end);
- if (!*p || *p != ')')
- error ("Internal error: live range string.\n");
- p++;
- return 0;
+ return 1;
}
+/* Add a new live range defined by START and END to the symbol SYM
+ in objfile OBJFILE. */
+
static void
add_live_range (objfile, sym, start, end)
- struct objfile *objfile;
- struct symbol *sym;
- CORE_ADDR start, end;
+ struct objfile *objfile;
+ struct symbol *sym;
+ CORE_ADDR start, end;
{
- struct live_range *r, *rs;
+ struct range_list *r, *rs;
if (start >= end)
- error ("Internal error: end of live range follows start.\n");
+ {
+ complain (&lrs_general_complaint, "end of live range follows start");
+ return;
+ }
/* Alloc new live range structure. */
- r = (struct live_range *)
- obstack_alloc (&objfile->type_obstack,
- sizeof (struct live_range));
+ r = (struct range_list *)
+ obstack_alloc (&objfile->type_obstack,
+ sizeof (struct range_list));
r->start = start;
r->end = end;
r->next = 0;
/* Append this range to the symbol's range list. */
- if (!SYMBOL_RANGE (sym))
- {
- SYMBOL_RANGE (sym) = r;
- }
+ if (!SYMBOL_RANGES (sym))
+ SYMBOL_RANGES (sym) = r;
else
{
/* Get the last range for the symbol. */
- for (rs = SYMBOL_RANGE (sym); rs->next; rs = rs->next)
+ for (rs = SYMBOL_RANGES (sym); rs->next; rs = rs->next)
;
rs->next = r;
}
}
-/* Given addr, Search thu alias list to find the one active. */
-struct symbol *
-ref_search_val (sym, addr)
- struct symbol *sym;
- CORE_ADDR addr;
-{
- struct live_range *r;
-
- while (sym)
- {
- if (!SYMBOL_RANGE (sym))
- return sym;
- for (r = SYMBOL_RANGE (sym); r; r = r->next)
- {
- if (r->start <= addr
- && r->end > addr)
- return sym;
- }
- sym = SYMBOL_ALIASES (sym);
- }
- return 0;
-}
-
\f
/* Skip rest of this symbol and return an error type.
break;
case 25:
/* Complex type consisting of two IEEE single precision values. */
- rettype = init_type (TYPE_CODE_ERROR, 8, 0, "complex", NULL);
+ rettype = init_type (TYPE_CODE_COMPLEX, 8, 0, "complex", NULL);
break;
case 26:
/* Complex type consisting of two IEEE double precision values. */
- rettype = init_type (TYPE_CODE_ERROR, 16, 0, "double complex", NULL);
+ rettype = init_type (TYPE_CODE_COMPLEX, 16, 0, "double complex", NULL);
break;
case 27:
rettype = init_type (TYPE_CODE_INT, 1, 0, "integer*1", NULL);
Note that forward refs cannot be packed,
and treat enums as if they had the width of ints. */
- if (TYPE_CODE (FIELD_TYPE (fip->list->field)) != TYPE_CODE_INT
- && TYPE_CODE (FIELD_TYPE (fip->list->field)) != TYPE_CODE_BOOL
- && TYPE_CODE (FIELD_TYPE (fip->list->field)) != TYPE_CODE_ENUM)
+ struct type *field_type = check_typedef (FIELD_TYPE (fip->list->field));
+
+ if (TYPE_CODE (field_type) != TYPE_CODE_INT
+ && TYPE_CODE (field_type) != TYPE_CODE_RANGE
+ && TYPE_CODE (field_type) != TYPE_CODE_BOOL
+ && TYPE_CODE (field_type) != TYPE_CODE_ENUM)
{
FIELD_BITSIZE (fip->list->field) = 0;
}
if ((FIELD_BITSIZE (fip->list->field)
- == TARGET_CHAR_BIT * TYPE_LENGTH (FIELD_TYPE (fip->list->field))
- || (TYPE_CODE (FIELD_TYPE (fip->list->field)) == TYPE_CODE_ENUM
+ == TARGET_CHAR_BIT * TYPE_LENGTH (field_type)
+ || (TYPE_CODE (field_type) == TYPE_CODE_ENUM
&& FIELD_BITSIZE (fip->list->field) == TARGET_INT_BIT )
)
&&
/* Sun's ACC uses a somewhat saner method for specifying the builtin
typedefs in every file (for int, long, etc):
- type = b <signed> <width>; <offset>; <nbits>
- signed = u or s. Possible c in addition to u or s (for char?).
+ type = b <signed> <width> <format type>; <offset>; <nbits>
+ signed = u or s.
+ optional format type = c or b for char or boolean.
offset = offset from high order bit to start bit of type.
width is # bytes in object of this type, nbits is # bits in type.
int type_bits;
int nbits;
int signed_type;
+ enum type_code code = TYPE_CODE_INT;
switch (**pp)
{
/* For some odd reason, all forms of char put a c here. This is strange
because no other type has this honor. We can safely ignore this because
we actually determine 'char'acterness by the number of bits specified in
- the descriptor. */
+ the descriptor.
+ Boolean forms, e.g Fortran logical*X, put a b here. */
if (**pp == 'c')
(*pp)++;
+ else if (**pp == 'b')
+ {
+ code = TYPE_CODE_BOOL;
+ (*pp)++;
+ }
/* The first number appears to be the number of bytes occupied
by this type, except that unsigned short is 4 instead of 2.
signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
objfile);
else
- return init_type (TYPE_CODE_INT,
+ return init_type (code,
type_bits / TARGET_CHAR_BIT,
signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
objfile);
|| details == NF_COMPLEX32)
/* This is a type we can't handle, but we do know the size.
We also will be able to give it a name. */
- return init_type (TYPE_CODE_ERROR, nbytes, 0, NULL, objfile);
+ return init_type (TYPE_CODE_COMPLEX, nbytes, 0, NULL, objfile);
return init_type (TYPE_CODE_FLT, nbytes, 0, NULL, objfile);
}
if (self_subrange && n2 == 0 && n3 == 0)
return init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
- /* If n3 is zero and n2 is positive, we want a floating type,
- and n2 is the width in bytes.
+ /* If n3 is zero and n2 is positive, we want a floating type, and n2
+ is the width in bytes.
- Fortran programs appear to use this for complex types also,
- and they give no way to distinguish between double and single-complex!
+ Fortran programs appear to use this for complex types also. To
+ distinguish between floats and complex, g77 (and others?) seem
+ to use self-subranges for the complexes, and subranges of int for
+ the floats.
- GDB does not have complex types.
-
- Just return the complex as a float of that size. It won't work right
- for the complex values, but at least it makes the file loadable. */
+ Also note that for complexes, g77 sets n2 to the size of one of
+ the member floats, not the whole complex beast. My guess is that
+ this was to work well with pre-COMPLEX versions of gdb. */
if (n3 == 0 && n2 > 0)
{
- return init_type (TYPE_CODE_FLT, n2, 0, NULL, objfile);
+ if (self_subrange)
+ {
+ return init_type (TYPE_CODE_COMPLEX, 2 * n2, 0, NULL, objfile);
+ }
+ else
+ {
+ return init_type (TYPE_CODE_FLT, n2, 0, NULL, objfile);
+ }
}
/* If the upper bound is -1, it must really be an unsigned int. */
if (SYMBOL_NAME (msymbol)[0] == SYMBOL_NAME (sym)[0] &&
STREQ(SYMBOL_NAME (msymbol) + 1, SYMBOL_NAME (sym) + 1))
{
+
+ struct alias_list *aliases;
+
/* Splice this symbol out of the hash chain and
assign the value we have to it. */
if (prev)
/* FIXME: Maybe should have added aliases to the global chain, resolved symbol name, then treated aliases as normal
symbols? Still, we wouldn't want to add_to_list. */
/* Now do the same for each alias of this symbol */
- for (rsym = sym; rsym; rsym = SYMBOL_ALIASES (rsym))
+ rsym = sym;
+ aliases = SYMBOL_ALIASES (sym);
+ while (rsym)
{
if (SYMBOL_CLASS (rsym) == LOC_BLOCK)
- {
- fix_common_block (rsym, SYMBOL_VALUE_ADDRESS (msymbol));
- }
+ {
+ fix_common_block (rsym,
+ SYMBOL_VALUE_ADDRESS (msymbol));
+ }
else
- {
- SYMBOL_VALUE_ADDRESS (rsym)
+ {
+ SYMBOL_VALUE_ADDRESS (rsym)
= SYMBOL_VALUE_ADDRESS (msymbol);
- }
+ }
SYMBOL_SECTION (rsym) = SYMBOL_SECTION (msymbol);
+ if (aliases)
+ {
+ rsym = aliases->sym;
+ aliases = aliases->next;
+ }
+ else
+ rsym = NULL;
}
+
if (prev)
{