#endif
/* end-sanitize-chill */
-#define STREQ(a,b) (strcmp(a,b)==0)
-#define STREQN(a,b,n) (strncmp(a,b,n)==0)
-
/* Flags to target_to_host() that tell whether or not the data object is
expected to be signed. Used, for example, when fetching a signed
integer in the target environment which is used as a signed integer
static void
read_tag_pointer_type PARAMS ((struct dieinfo *dip));
+static void
+read_tag_string_type PARAMS ((struct dieinfo *dip));
+
static void
read_subroutine_type PARAMS ((struct dieinfo *, char *, char *));
case LANG_FORTRAN77:
case LANG_FORTRAN90:
case LANG_PASCAL83:
- default:
+ /* We don't know anything special about these yet. */
cu_language = language_unknown;
break;
+ default:
+ /* If no at_language, try to deduce one from the filename */
+ cu_language = deduce_language_from_filename (dip -> at_name);
+ break;
}
cu_language_defn = language_def (cu_language);
}
char *tpart1;
struct dieinfo mbr;
char *nextdie;
+#if !BITS_BIG_ENDIAN
int anonymous_size;
+#endif
if ((type = lookup_utype (dip -> die_ref)) == NULL)
{
struct type *typep = NULL; /* Array type we are building */
struct type *nexttype; /* Type of each element (may be array) */
struct type *indextype; /* Type of this index */
+ struct type *rangetype;
unsigned int format;
unsigned short fundtype;
unsigned long lowbound;
complain (&subscript_data_items, DIE_ID, DIE_NAME);
nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
}
- typep = create_array_type ((struct type *) NULL, nexttype, indextype,
- lowbound, highbound);
+ rangetype = create_range_type ((struct type *) NULL, indextype,
+ lowbound, highbound);
+ typep = create_array_type ((struct type *) NULL, nexttype, rangetype);
break;
case FMT_FT_C_X:
case FMT_FT_X_C:
case FMT_UT_X_C:
case FMT_UT_X_X:
complain (&unhandled_array_subscript_format, DIE_ID, DIE_NAME, format);
- typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
- typep = create_array_type ((struct type *) NULL, typep, typep, 0, 1);
+ nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0);
+ typep = create_array_type ((struct type *) NULL, nexttype, rangetype);
break;
default:
complain (&unknown_array_subscript_format, DIE_ID, DIE_NAME, format);
- typep = dwarf_fundamental_type (current_objfile, FT_INTEGER);
- typep = create_array_type ((struct type *) NULL, typep, typep, 0, 1);
+ nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0);
+ typep = create_array_type ((struct type *) NULL, nexttype, rangetype);
break;
}
return (typep);
/*
+LOCAL FUNCTION
+
+ read_tag_string_type -- read TAG_string_type DIE
+
+SYNOPSIS
+
+ static void read_tag_string_type (struct dieinfo *dip)
+
+DESCRIPTION
+
+ Extract all information from a TAG_string_type DIE and add to
+ the user defined type vector. It isn't really a user defined
+ type, but it behaves like one, with other DIE's using an
+ AT_user_def_type attribute to reference it.
+ */
+
+static void
+read_tag_string_type (dip)
+ struct dieinfo *dip;
+{
+ struct type *utype;
+ struct type *indextype;
+ struct type *rangetype;
+ unsigned long lowbound = 0;
+ unsigned long highbound;
+
+ if ((utype = lookup_utype (dip -> die_ref)) != NULL)
+ {
+ /* Ack, someone has stuck a type in the slot we want. Complain
+ about it. */
+ complain (&dup_user_type_definition, DIE_ID, DIE_NAME);
+ }
+ else
+ {
+ if (dip -> has_at_byte_size)
+ {
+ /* A fixed bounds string */
+ highbound = dip -> at_byte_size - 1;
+ }
+ else
+ {
+ /* A varying length string. Stub for now. (FIXME) */
+ highbound = 1;
+ }
+ indextype = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+ rangetype = create_range_type ((struct type *) NULL, indextype,
+ lowbound, highbound);
+ utype = create_string_type ((struct type *) NULL, rangetype);
+ alloc_utype (dip -> die_ref, utype);
+ }
+}
+
+/*
+
LOCAL FUNCTION
read_subroutine_type -- process TAG_subroutine_type dies
memset (sym, 0, sizeof (struct symbol));
SYMBOL_NAME (sym) = create_name (list -> field.name,
&objfile->symbol_obstack);
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language);
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
SYMBOL_CLASS (sym) = LOC_CONST;
SYMBOL_TYPE (sym) = type;
case TAG_pointer_type:
read_tag_pointer_type (&di);
break;
+ case TAG_string_type:
+ read_tag_string_type (&di);
+ break;
default:
new_symbol (&di, objfile);
break;
{
scan += TARGET_FT_LONG_SIZE (objfile);
ADD_PSYMBOL_TO_LIST (scan, strlen (scan), VAR_NAMESPACE, LOC_CONST,
- objfile -> static_psymbols, 0);
+ objfile -> static_psymbols, 0, cu_language,
+ objfile);
scan += strlen (scan) + 1;
}
}
ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
VAR_NAMESPACE, LOC_BLOCK,
objfile -> global_psymbols,
- dip -> at_low_pc);
+ dip -> at_low_pc, cu_language, objfile);
break;
case TAG_global_variable:
record_minimal_symbol (dip -> at_name, locval (dip -> at_location),
ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
VAR_NAMESPACE, LOC_STATIC,
objfile -> global_psymbols,
- 0);
+ 0, cu_language, objfile);
break;
case TAG_subroutine:
ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
VAR_NAMESPACE, LOC_BLOCK,
objfile -> static_psymbols,
- dip -> at_low_pc);
+ dip -> at_low_pc, cu_language, objfile);
break;
case TAG_local_variable:
ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
VAR_NAMESPACE, LOC_STATIC,
objfile -> static_psymbols,
- 0);
+ 0, cu_language, objfile);
break;
case TAG_typedef:
ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
VAR_NAMESPACE, LOC_TYPEDEF,
objfile -> static_psymbols,
- 0);
+ 0, cu_language, objfile);
break;
case TAG_class_type:
case TAG_structure_type:
ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
STRUCT_NAMESPACE, LOC_TYPEDEF,
objfile -> static_psymbols,
- 0);
+ 0, cu_language, objfile);
if (cu_language == language_cplus)
{
/* For C++, these implicitly act as typedefs as well. */
ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
VAR_NAMESPACE, LOC_TYPEDEF,
objfile -> static_psymbols,
- 0);
+ 0, cu_language, objfile);
}
break;
}
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_TYPE (sym) = decode_die_type (dip);
+
+ /* If this symbol is from a C++ compilation, then attempt to cache the
+ demangled form for future reference. This is a typical time versus
+ space tradeoff, that was decided in favor of time because it sped up
+ C++ symbol lookups by a factor of about 20. */
+
+ SYMBOL_LANGUAGE (sym) = cu_language;
+ SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile -> symbol_obstack);
switch (dip -> die_tag)
{
case TAG_label:
memset (sym, 0, sizeof (struct symbol));
SYMBOL_NAME (sym) = create_name (dip -> at_name,
&objfile->symbol_obstack);
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language);
SYMBOL_TYPE (sym) = type;
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;