sym->set_symtab (fe->symtab (*file_cu));
}
-/* Given a pointer to a DWARF information entry, figure out if we need
- to make a symbol table entry for it, and if so, create a new entry
- and return a pointer to it.
- If TYPE is NULL, determine symbol type from the die, otherwise
- used the passed type.
- If SPACE is not NULL, use it to hold the new symbol. If it is
- NULL, allocate a new symbol on the objfile's obstack. */
+/* Given a DWARF information entry CU/DIE with LINKAGENAME and PHYSNAME, fill
+ in SYM according to DIE->tag. */
-static struct symbol *
-new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
- struct symbol *space)
+static void
+new_symbol (struct die_info *die, struct dwarf2_cu *cu, struct symbol *sym,
+ const char *linkagename, const char *physname)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct objfile *objfile = per_objfile->objfile;
- struct symbol *sym = NULL;
- const char *name;
- struct attribute *attr = NULL;
- struct attribute *attr2 = NULL;
+ struct attribute *attr = nullptr;
+ struct attribute *attr2 = nullptr;
std::vector<symbol *> *list_to_add = nullptr;
+ bool suppress_add = false;
- name = dwarf2_name (die, cu);
- if (name == nullptr && (die->tag == DW_TAG_subprogram
- || die->tag == DW_TAG_inlined_subroutine
- || die->tag == DW_TAG_entry_point))
- name = dw2_linkage_name (die, cu);
-
- if (name)
+ switch (die->tag)
{
- int suppress_add = 0;
-
- if (space)
- sym = space;
- else
- sym = objfile->new_symbol<symbol> ();
-
- /* Cache this symbol's name and the name's demangled form (if any). */
- sym->set_language (cu->lang (), &objfile->objfile_obstack);
- /* Fortran does not have mangling standard and the mangling does differ
- between gfortran, iFort etc. */
- const char *physname
- = ((cu->lang () == language_fortran || cu->lang () == language_ada)
- ? dwarf2_full_name (name, die, cu)
- : dwarf2_physname (name, die, cu));
- const char *linkagename = dw2_linkage_name (die, cu);
-
- if (linkagename == nullptr)
- sym->set_linkage_name (physname);
- else if (cu->lang () == language_ada)
- sym->set_linkage_name (linkagename);
+ case DW_TAG_label:
+ {
+ attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+ if (attr != nullptr)
+ {
+ CORE_ADDR addr = per_objfile->relocate (attr->as_address ());
+ sym->set_section_index (SECT_OFF_TEXT (objfile));
+ sym->set_value_address (addr);
+ sym->set_loc_class_index (LOC_LABEL);
+ }
+ else
+ sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
+ type_allocator alloc (objfile, cu->lang ());
+ struct type *addr_type
+ = alloc.copy_type (builtin_type (objfile)->builtin_core_addr);
+ sym->set_type (addr_type);
+ sym->set_domain (LABEL_DOMAIN);
+ list_to_add = cu->list_in_scope;
+ }
+ break;
+ case DW_TAG_entry_point:
+ /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
+ finish_block. */
+ sym->set_domain (FUNCTION_DOMAIN);
+ sym->set_loc_class_index (LOC_BLOCK);
+ /* DW_TAG_entry_point provides an additional entry_point to an
+ existing sub_program. Therefore, we inherit the "external"
+ attribute from the sub_program to which the entry_point
+ belongs to. */
+ attr2 = dwarf2_attr (die->parent, DW_AT_external, cu);
+ if (attr2 != nullptr && attr2->as_boolean ())
+ list_to_add = &cu->get_builder ()->get_global_symbols ();
else
+ list_to_add = cu->list_in_scope;
+ break;
+ case DW_TAG_subprogram:
+ /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
+ finish_block. */
+ sym->set_domain (FUNCTION_DOMAIN);
+ sym->set_loc_class_index (LOC_BLOCK);
+ attr2 = dwarf2_attr (die, DW_AT_external, cu);
+ if ((attr2 != nullptr && attr2->as_boolean ())
+ || cu->lang () == language_ada
+ || cu->lang () == language_fortran)
{
- if (physname == linkagename)
- sym->set_demangled_name (name, &objfile->objfile_obstack);
- else
- sym->set_demangled_name (physname, &objfile->objfile_obstack);
-
- sym->set_linkage_name (linkagename);
+ /* Subprograms marked external are stored as a global symbol.
+ Ada and Fortran subprograms, whether marked external or
+ not, are always stored as a global symbol, because we want
+ to be able to access them globally. For instance, we want
+ to be able to break on a nested subprogram without having
+ to specify the context. */
+ list_to_add = &cu->get_builder ()->get_global_symbols ();
}
-
- /* Handle DW_AT_artificial. */
- attr = dwarf2_attr (die, DW_AT_artificial, cu);
- if (attr != nullptr)
- sym->set_is_artificial (attr->as_boolean ());
-
- /* Default assumptions.
- Use the passed type or decode it from the die. */
- sym->set_domain (UNDEF_DOMAIN);
- sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
- if (type != NULL)
- sym->set_type (type);
else
- sym->set_type (die_type (die, cu));
+ list_to_add = cu->list_in_scope;
- /* Handle DW_AT_{call,decl}_{file,line}. */
- new_symbol_file_line (die, cu, sym);
-
- switch (die->tag)
+ if (is_ada_import_or_export (cu, physname, linkagename))
{
- case DW_TAG_label:
- {
- attr = dwarf2_attr (die, DW_AT_low_pc, cu);
- if (attr != nullptr)
- {
- CORE_ADDR addr = per_objfile->relocate (attr->as_address ());
- sym->set_section_index (SECT_OFF_TEXT (objfile));
- sym->set_value_address (addr);
- sym->set_loc_class_index (LOC_LABEL);
- }
- else
- sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
- type_allocator alloc (objfile, cu->lang ());
- struct type *addr_type
- = alloc.copy_type (builtin_type (objfile)->builtin_core_addr);
- sym->set_type (addr_type);
- sym->set_domain (LABEL_DOMAIN);
- list_to_add = cu->list_in_scope;
- }
- break;
- case DW_TAG_entry_point:
- /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
- finish_block. */
- sym->set_domain (FUNCTION_DOMAIN);
- sym->set_loc_class_index (LOC_BLOCK);
- /* DW_TAG_entry_point provides an additional entry_point to an
- existing sub_program. Therefore, we inherit the "external"
- attribute from the sub_program to which the entry_point
- belongs to. */
- attr2 = dwarf2_attr (die->parent, DW_AT_external, cu);
- if (attr2 != nullptr && attr2->as_boolean ())
- list_to_add = &cu->get_builder ()->get_global_symbols ();
- else
- list_to_add = cu->list_in_scope;
- break;
- case DW_TAG_subprogram:
- /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
- finish_block. */
- sym->set_domain (FUNCTION_DOMAIN);
- sym->set_loc_class_index (LOC_BLOCK);
- attr2 = dwarf2_attr (die, DW_AT_external, cu);
- if ((attr2 != nullptr && attr2->as_boolean ())
- || cu->lang () == language_ada
- || cu->lang () == language_fortran)
+ /* This is either a Pragma Import or Export. They can
+ be distinguished by the declaration flag. */
+ sym->set_linkage_name (physname);
+ if (die_is_declaration (die, cu))
{
- /* Subprograms marked external are stored as a global symbol.
- Ada and Fortran subprograms, whether marked external or
- not, are always stored as a global symbol, because we want
- to be able to access them globally. For instance, we want
- to be able to break on a nested subprogram without having
- to specify the context. */
- list_to_add = &cu->get_builder ()->get_global_symbols ();
+ /* For Import, create a symbol using the source
+ name, and have it refer to the linkage name. */
+ SYMBOL_LOCATION_BATON (sym) = (void *) linkagename;
+ sym->set_loc_class_index (ada_block_index);
}
else
{
- list_to_add = cu->list_in_scope;
+ /* For Export, create a symbol using the source
+ name, then create a second symbol that refers
+ back to it. */
+ add_ada_export_symbol (sym, linkagename, physname, cu,
+ *list_to_add);
}
+ }
+ break;
+ case DW_TAG_inlined_subroutine:
+ /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
+ finish_block. */
+ sym->set_domain (FUNCTION_DOMAIN);
+ sym->set_loc_class_index (LOC_BLOCK);
+ sym->set_is_inlined (1);
+ list_to_add = cu->list_in_scope;
+ break;
+ case DW_TAG_template_value_param:
+ suppress_add = true;
+ [[fallthrough]];
+ case DW_TAG_constant:
+ case DW_TAG_variable:
+ case DW_TAG_member:
+ sym->set_domain (VAR_DOMAIN);
+ /* Compilation with minimal debug info may result in
+ variables with missing type entries. Change the
+ misleading `void' type to something sensible. */
+ if (sym->type ()->code () == TYPE_CODE_VOID)
+ {
+ type_allocator alloc (objfile, cu->lang ());
+ struct type *int_type
+ = alloc.copy_type (builtin_type (objfile)->builtin_int);
+ sym->set_type (int_type);
+ }
- if (is_ada_import_or_export (cu, physname, linkagename))
+ attr = dwarf2_attr (die, DW_AT_const_value, cu);
+ /* In the case of DW_TAG_member, we should only be called for
+ static const members. */
+ if (die->tag == DW_TAG_member)
+ {
+ /* dwarf2_add_field uses die_is_declaration,
+ so we do the same. */
+ gdb_assert (die_is_declaration (die, cu));
+ gdb_assert (attr);
+ }
+ if (attr != nullptr)
+ {
+ dwarf2_const_value (attr, sym, cu);
+ attr2 = dwarf2_attr (die, DW_AT_external, cu);
+ if (!suppress_add)
{
- /* This is either a Pragma Import or Export. They can
- be distinguished by the declaration flag. */
- sym->set_linkage_name (physname);
- if (die_is_declaration (die, cu))
- {
- /* For Import, create a symbol using the source
- name, and have it refer to the linkage name. */
- SYMBOL_LOCATION_BATON (sym) = (void *) linkagename;
- sym->set_loc_class_index (ada_block_index);
- }
+ if (attr2 != nullptr && attr2->as_boolean ())
+ list_to_add = &cu->get_builder ()->get_global_symbols ();
else
- {
- /* For Export, create a symbol using the source
- name, then create a second symbol that refers
- back to it. */
- add_ada_export_symbol (sym, linkagename, physname, cu,
- *list_to_add);
- }
+ list_to_add = cu->list_in_scope;
}
break;
- case DW_TAG_inlined_subroutine:
- /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
- finish_block. */
- sym->set_domain (FUNCTION_DOMAIN);
- sym->set_loc_class_index (LOC_BLOCK);
- sym->set_is_inlined (1);
- list_to_add = cu->list_in_scope;
- break;
- case DW_TAG_template_value_param:
- suppress_add = 1;
- [[fallthrough]];
- case DW_TAG_constant:
- case DW_TAG_variable:
- case DW_TAG_member:
- sym->set_domain (VAR_DOMAIN);
- /* Compilation with minimal debug info may result in
- variables with missing type entries. Change the
- misleading `void' type to something sensible. */
- if (sym->type ()->code () == TYPE_CODE_VOID)
- {
- type_allocator alloc (objfile, cu->lang ());
- struct type *int_type
- = alloc.copy_type (builtin_type (objfile)->builtin_int);
- sym->set_type (int_type);
- }
+ }
+ attr = dwarf2_attr (die, DW_AT_location, cu);
+ if (attr != nullptr)
+ {
+ var_decode_location (attr, sym, cu);
+ attr2 = dwarf2_attr (die, DW_AT_external, cu);
- attr = dwarf2_attr (die, DW_AT_const_value, cu);
- /* In the case of DW_TAG_member, we should only be called for
- static const members. */
- if (die->tag == DW_TAG_member)
- {
- /* dwarf2_add_field uses die_is_declaration,
- so we do the same. */
- gdb_assert (die_is_declaration (die, cu));
- gdb_assert (attr);
- }
- if (attr != nullptr)
+ /* Fortran explicitly imports any global symbols to the local
+ scope by DW_TAG_common_block. */
+ if (cu->lang () == language_fortran && die->parent
+ && die->parent->tag == DW_TAG_common_block)
+ attr2 = nullptr;
+
+ if (sym->loc_class () == LOC_STATIC
+ && sym->value_address () == 0
+ && !per_objfile->per_bfd->has_section_at_zero)
{
- dwarf2_const_value (attr, sym, cu);
- attr2 = dwarf2_attr (die, DW_AT_external, cu);
- if (!suppress_add)
- {
- if (attr2 != nullptr && attr2->as_boolean ())
- list_to_add = &cu->get_builder ()->get_global_symbols ();
- else
- list_to_add = cu->list_in_scope;
- }
- break;
+ /* When a static variable is eliminated by the linker,
+ the corresponding debug information is not stripped
+ out, but the variable address is set to null;
+ do not add such variables into symbol table. */
}
- attr = dwarf2_attr (die, DW_AT_location, cu);
- if (attr != nullptr)
+ else if (attr2 != nullptr && attr2->as_boolean ())
{
- var_decode_location (attr, sym, cu);
- attr2 = dwarf2_attr (die, DW_AT_external, cu);
-
- /* Fortran explicitly imports any global symbols to the local
- scope by DW_TAG_common_block. */
- if (cu->lang () == language_fortran && die->parent
- && die->parent->tag == DW_TAG_common_block)
- attr2 = NULL;
-
if (sym->loc_class () == LOC_STATIC
- && sym->value_address () == 0
- && !per_objfile->per_bfd->has_section_at_zero)
- {
- /* When a static variable is eliminated by the linker,
- the corresponding debug information is not stripped
- out, but the variable address is set to null;
- do not add such variables into symbol table. */
- }
- else if (attr2 != nullptr && attr2->as_boolean ())
+ && (objfile->flags & OBJF_MAINLINE) == 0
+ && per_objfile->per_bfd->can_copy)
{
- if (sym->loc_class () == LOC_STATIC
- && (objfile->flags & OBJF_MAINLINE) == 0
- && per_objfile->per_bfd->can_copy)
- {
- /* A global static variable might be subject to
- copy relocation. We first check for a local
- minsym, though, because maybe the symbol was
- marked hidden, in which case this would not
- apply. */
- bound_minimal_symbol found
- = (lookup_minimal_symbol_linkage
- (sym->linkage_name (), objfile, false));
- if (found.minsym != nullptr)
- sym->maybe_copied = 1;
- }
-
- /* A variable with DW_AT_external is never static,
- but it may be block-scoped. */
- list_to_add
- = ((cu->list_in_scope
- == &cu->get_builder ()->get_file_symbols ())
- ? &cu->get_builder ()->get_global_symbols ()
- : cu->list_in_scope);
+ /* A global static variable might be subject to
+ copy relocation. We first check for a local
+ minsym, though, because maybe the symbol was
+ marked hidden, in which case this would not
+ apply. */
+ bound_minimal_symbol found
+ = (lookup_minimal_symbol_linkage
+ (sym->linkage_name (), objfile, false));
+ if (found.minsym != nullptr)
+ sym->maybe_copied = 1;
}
- else
- list_to_add = cu->list_in_scope;
- if (list_to_add != nullptr
- && is_ada_import_or_export (cu, physname, linkagename))
- {
- /* This is a Pragma Export. A Pragma Import won't
- be seen here, because it will not have a location
- and so will be handled below. */
- add_ada_export_symbol (sym, physname, linkagename, cu,
- *list_to_add);
- }
+ /* A variable with DW_AT_external is never static,
+ but it may be block-scoped. */
+ list_to_add
+ = ((cu->list_in_scope
+ == &cu->get_builder ()->get_file_symbols ())
+ ? &cu->get_builder ()->get_global_symbols ()
+ : cu->list_in_scope);
}
else
+ list_to_add = cu->list_in_scope;
+
+ if (list_to_add != nullptr
+ && is_ada_import_or_export (cu, physname, linkagename))
{
- /* We do not know the address of this symbol.
- If it is an external symbol and we have type information
- for it, enter the symbol as a LOC_UNRESOLVED symbol.
- The address of the variable will then be determined from
- the minimal symbol table whenever the variable is
- referenced. */
- attr2 = dwarf2_attr (die, DW_AT_external, cu);
-
- /* Fortran explicitly imports any global symbols to the local
- scope by DW_TAG_common_block. */
- if (cu->lang () == language_fortran && die->parent
- && die->parent->tag == DW_TAG_common_block)
- {
- /* SYMBOL_CLASS doesn't matter here because
- read_common_block is going to reset it. */
- if (!suppress_add)
- list_to_add = cu->list_in_scope;
- }
- else if (is_ada_import_or_export (cu, physname, linkagename))
- {
- /* This is a Pragma Import. A Pragma Export won't
- be seen here, because it will have a location and
- so will be handled above. */
- sym->set_linkage_name (physname);
- list_to_add
- = ((cu->list_in_scope
- == &cu->get_builder ()->get_file_symbols ())
- ? &cu->get_builder ()->get_global_symbols ()
- : cu->list_in_scope);
- SYMBOL_LOCATION_BATON (sym) = (void *) linkagename;
- sym->set_loc_class_index (ada_imported_index);
- }
- else if (attr2 != nullptr && attr2->as_boolean ()
- && dwarf2_attr (die, DW_AT_type, cu) != NULL)
- {
- /* A variable with DW_AT_external is never static, but it
- may be block-scoped. */
- list_to_add
- = ((cu->list_in_scope
- == &cu->get_builder ()->get_file_symbols ())
- ? &cu->get_builder ()->get_global_symbols ()
- : cu->list_in_scope);
-
- sym->set_loc_class_index (LOC_UNRESOLVED);
- }
- else if (!die_is_declaration (die, cu))
- {
- /* Use the default LOC_OPTIMIZED_OUT class. */
- gdb_assert (sym->loc_class () == LOC_OPTIMIZED_OUT);
- if (!suppress_add)
- list_to_add = cu->list_in_scope;
- }
+ /* This is a Pragma Export. A Pragma Import won't
+ be seen here, because it will not have a location
+ and so will be handled below. */
+ add_ada_export_symbol (sym, physname, linkagename, cu,
+ *list_to_add);
}
- break;
- case DW_TAG_formal_parameter:
- {
- /* If we are inside a function, mark this as an argument. If
- not, we might be looking at an argument to an inlined function
- when we do not have enough information to show inlined frames;
- pretend it's a local variable in that case so that the user can
- still see it. */
- sym->set_domain (VAR_DOMAIN);
- if (cu->get_builder ()->current_context_has_function ())
- sym->set_is_argument (true);
- attr = dwarf2_attr (die, DW_AT_location, cu);
- if (attr != nullptr)
- {
- var_decode_location (attr, sym, cu);
- }
- attr = dwarf2_attr (die, DW_AT_const_value, cu);
- if (attr != nullptr)
- {
- dwarf2_const_value (attr, sym, cu);
- }
+ }
+ else
+ {
+ /* We do not know the address of this symbol.
+ If it is an external symbol and we have type information
+ for it, enter the symbol as a LOC_UNRESOLVED symbol.
+ The address of the variable will then be determined from
+ the minimal symbol table whenever the variable is
+ referenced. */
+ attr2 = dwarf2_attr (die, DW_AT_external, cu);
- list_to_add = cu->list_in_scope;
- }
- break;
- case DW_TAG_unspecified_parameters:
- /* From varargs functions; gdb doesn't seem to have any
- interest in this information, so just ignore it for now.
- (FIXME?) */
- break;
- case DW_TAG_template_type_param:
- suppress_add = 1;
- [[fallthrough]];
- case DW_TAG_class_type:
- case DW_TAG_interface_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_set_type:
- case DW_TAG_enumeration_type:
- if (cu->lang () == language_c
- || cu->lang () == language_cplus
- || cu->lang () == language_objc
- || cu->lang () == language_opencl
- || cu->lang () == language_minimal)
+ /* Fortran explicitly imports any global symbols to the local
+ scope by DW_TAG_common_block. */
+ if (cu->lang () == language_fortran && die->parent
+ && die->parent->tag == DW_TAG_common_block)
{
- /* These languages have a tag namespace. Note that
- there's a special hack for C++ in the matching code,
- so we don't need to enter a separate typedef for the
- tag. */
- sym->set_loc_class_index (LOC_TYPEDEF);
- sym->set_domain (STRUCT_DOMAIN);
+ /* SYMBOL_CLASS doesn't matter here because
+ read_common_block is going to reset it. */
+ if (!suppress_add)
+ list_to_add = cu->list_in_scope;
}
- else
+ else if (is_ada_import_or_export (cu, physname, linkagename))
{
- /* Other languages don't have a tag namespace. */
- sym->set_loc_class_index (LOC_TYPEDEF);
- sym->set_domain (TYPE_DOMAIN);
+ /* This is a Pragma Import. A Pragma Export won't
+ be seen here, because it will have a location and
+ so will be handled above. */
+ sym->set_linkage_name (physname);
+ list_to_add
+ = ((cu->list_in_scope
+ == &cu->get_builder ()->get_file_symbols ())
+ ? &cu->get_builder ()->get_global_symbols ()
+ : cu->list_in_scope);
+ SYMBOL_LOCATION_BATON (sym) = (void *) linkagename;
+ sym->set_loc_class_index (ada_imported_index);
}
-
- /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
- really ever be static objects: otherwise, if you try
- to, say, break of a class's method and you're in a file
- which doesn't mention that class, it won't work unless
- the check for all static symbols in lookup_symbol_aux
- saves you. See the OtherFileClass tests in
- gdb.c++/namespace.exp. */
-
- if (!suppress_add)
+ else if (attr2 != nullptr && attr2->as_boolean ()
+ && dwarf2_attr (die, DW_AT_type, cu) != nullptr)
{
- buildsym_compunit *builder = cu->get_builder ();
+ /* A variable with DW_AT_external is never static, but it
+ may be block-scoped. */
list_to_add
- = ((cu->list_in_scope == &builder->get_file_symbols ()
- && cu->lang () == language_cplus)
- ? &builder->get_global_symbols ()
+ = ((cu->list_in_scope
+ == &cu->get_builder ()->get_file_symbols ())
+ ? &cu->get_builder ()->get_global_symbols ()
: cu->list_in_scope);
- /* The semantics of C++ state that "struct foo {
- ... }" also defines a typedef for "foo". */
- if (cu->lang () == language_cplus
- || cu->lang () == language_ada
- || cu->lang () == language_d
- || cu->lang () == language_rust)
- {
- /* The symbol's name is already allocated along
- with this objfile, so we don't need to
- duplicate it for the type. */
- if (sym->type ()->name () == 0)
- sym->type ()->set_name (sym->search_name ());
- }
+ sym->set_loc_class_index (LOC_UNRESOLVED);
}
- break;
- case DW_TAG_unspecified_type:
- if (cu->lang () == language_ada)
- break;
- [[fallthrough]];
- case DW_TAG_typedef:
- case DW_TAG_array_type:
- case DW_TAG_base_type:
- case DW_TAG_subrange_type:
- case DW_TAG_generic_subrange:
- sym->set_loc_class_index (LOC_TYPEDEF);
- sym->set_domain (TYPE_DOMAIN);
- list_to_add = cu->list_in_scope;
- break;
- case DW_TAG_enumerator:
- sym->set_domain (VAR_DOMAIN);
- attr = dwarf2_attr (die, DW_AT_const_value, cu);
- if (attr != nullptr)
+ else if (!die_is_declaration (die, cu))
{
- dwarf2_const_value (attr, sym, cu);
+ /* Use the default LOC_OPTIMIZED_OUT class. */
+ gdb_assert (sym->loc_class () == LOC_OPTIMIZED_OUT);
+ if (!suppress_add)
+ list_to_add = cu->list_in_scope;
}
+ }
+ break;
+ case DW_TAG_formal_parameter:
+ {
+ /* If we are inside a function, mark this as an argument. If
+ not, we might be looking at an argument to an inlined function
+ when we do not have enough information to show inlined frames;
+ pretend it's a local variable in that case so that the user can
+ still see it. */
+ sym->set_domain (VAR_DOMAIN);
+ if (cu->get_builder ()->current_context_has_function ())
+ sym->set_is_argument (true);
+ attr = dwarf2_attr (die, DW_AT_location, cu);
+ if (attr != nullptr)
+ var_decode_location (attr, sym, cu);
+ attr = dwarf2_attr (die, DW_AT_const_value, cu);
+ if (attr != nullptr)
+ dwarf2_const_value (attr, sym, cu);
+
+ list_to_add = cu->list_in_scope;
+ }
+ break;
+ case DW_TAG_unspecified_parameters:
+ /* From varargs functions; gdb doesn't seem to have any
+ interest in this information, so just ignore it for now.
+ (FIXME?) */
+ break;
+ case DW_TAG_template_type_param:
+ suppress_add = true;
+ [[fallthrough]];
+ case DW_TAG_class_type:
+ case DW_TAG_interface_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_set_type:
+ case DW_TAG_enumeration_type:
+ if (cu->lang () == language_c
+ || cu->lang () == language_cplus
+ || cu->lang () == language_objc
+ || cu->lang () == language_opencl
+ || cu->lang () == language_minimal)
+ {
+ /* These languages have a tag namespace. Note that
+ there's a special hack for C++ in the matching code,
+ so we don't need to enter a separate typedef for the
+ tag. */
+ sym->set_loc_class_index (LOC_TYPEDEF);
+ sym->set_domain (STRUCT_DOMAIN);
+ }
+ else
+ {
+ /* Other languages don't have a tag namespace. */
+ sym->set_loc_class_index (LOC_TYPEDEF);
+ sym->set_domain (TYPE_DOMAIN);
+ }
- /* NOTE: carlton/2003-11-10: See comment above in the
- DW_TAG_class_type, etc. block. */
+ /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
+ really ever be static objects: otherwise, if you try
+ to, say, break of a class's method and you're in a file
+ which doesn't mention that class, it won't work unless
+ the check for all static symbols in lookup_symbol_aux
+ saves you. See the OtherFileClass tests in
+ gdb.c++/namespace.exp. */
+ if (!suppress_add)
+ {
+ buildsym_compunit *builder = cu->get_builder ();
list_to_add
- = ((cu->list_in_scope == &cu->get_builder ()->get_file_symbols ()
+ = ((cu->list_in_scope == &builder->get_file_symbols ()
&& cu->lang () == language_cplus)
- ? &cu->get_builder ()->get_global_symbols ()
+ ? &builder->get_global_symbols ()
: cu->list_in_scope);
- break;
- case DW_TAG_imported_declaration:
- case DW_TAG_namespace:
- sym->set_domain (TYPE_DOMAIN);
- sym->set_loc_class_index (LOC_TYPEDEF);
- list_to_add = &cu->get_builder ()->get_global_symbols ();
- break;
- case DW_TAG_module:
- sym->set_loc_class_index (LOC_TYPEDEF);
- sym->set_domain (MODULE_DOMAIN);
- list_to_add = &cu->get_builder ()->get_global_symbols ();
- break;
- case DW_TAG_common_block:
- sym->set_loc_class_index (LOC_COMMON_BLOCK);
- sym->set_domain (COMMON_BLOCK_DOMAIN);
- list_to_add = cu->list_in_scope;
- break;
- case DW_TAG_namelist:
- sym->set_loc_class_index (LOC_STATIC);
- sym->set_domain (VAR_DOMAIN);
- list_to_add = cu->list_in_scope;
- break;
- default:
- /* Not a tag we recognize. Hopefully we aren't processing
- trash data, but since we must specifically ignore things
- we don't recognize, there is nothing else we should do at
- this point. */
- complaint (_("unsupported tag: '%s'"),
- dwarf_tag_name (die->tag));
- break;
- }
- if (suppress_add)
- {
- sym->hash_next = objfile->template_symbols;
- objfile->template_symbols = sym;
- list_to_add = NULL;
+ /* The semantics of C++ state that "struct foo {
+ ... }" also defines a typedef for "foo". */
+ if (cu->lang () == language_cplus
+ || cu->lang () == language_ada
+ || cu->lang () == language_d
+ || cu->lang () == language_rust)
+ {
+ /* The symbol's name is already allocated along
+ with this objfile, so we don't need to
+ duplicate it for the type. */
+ if (sym->type ()->name () == 0)
+ sym->type ()->set_name (sym->search_name ());
+ }
}
+ break;
+ case DW_TAG_unspecified_type:
+ if (cu->lang () == language_ada)
+ break;
+ [[fallthrough]];
+ case DW_TAG_typedef:
+ case DW_TAG_array_type:
+ case DW_TAG_base_type:
+ case DW_TAG_subrange_type:
+ case DW_TAG_generic_subrange:
+ sym->set_loc_class_index (LOC_TYPEDEF);
+ sym->set_domain (TYPE_DOMAIN);
+ list_to_add = cu->list_in_scope;
+ break;
+ case DW_TAG_enumerator:
+ sym->set_domain (VAR_DOMAIN);
+ attr = dwarf2_attr (die, DW_AT_const_value, cu);
+ if (attr != nullptr)
+ dwarf2_const_value (attr, sym, cu);
- if (list_to_add != NULL)
- add_symbol_to_list (sym, *list_to_add);
+ /* NOTE: carlton/2003-11-10: See comment above in the
+ DW_TAG_class_type, etc. block. */
+
+ list_to_add
+ = ((cu->list_in_scope == &cu->get_builder ()->get_file_symbols ()
+ && cu->lang () == language_cplus)
+ ? &cu->get_builder ()->get_global_symbols ()
+ : cu->list_in_scope);
+ break;
+ case DW_TAG_imported_declaration:
+ case DW_TAG_namespace:
+ sym->set_domain (TYPE_DOMAIN);
+ sym->set_loc_class_index (LOC_TYPEDEF);
+ list_to_add = &cu->get_builder ()->get_global_symbols ();
+ break;
+ case DW_TAG_module:
+ sym->set_loc_class_index (LOC_TYPEDEF);
+ sym->set_domain (MODULE_DOMAIN);
+ list_to_add = &cu->get_builder ()->get_global_symbols ();
+ break;
+ case DW_TAG_common_block:
+ sym->set_loc_class_index (LOC_COMMON_BLOCK);
+ sym->set_domain (COMMON_BLOCK_DOMAIN);
+ list_to_add = cu->list_in_scope;
+ break;
+ case DW_TAG_namelist:
+ sym->set_loc_class_index (LOC_STATIC);
+ sym->set_domain (VAR_DOMAIN);
+ list_to_add = cu->list_in_scope;
+ break;
+ default:
+ /* Not a tag we recognize. Hopefully we aren't processing
+ trash data, but since we must specifically ignore things
+ we don't recognize, there is nothing else we should do at
+ this point. */
+ complaint (_("unsupported tag: '%s'"),
+ dwarf_tag_name (die->tag));
+ break;
+ }
- /* For the benefit of old versions of GCC, check for anonymous
- namespaces based on the demangled name. */
- if (!cu->processing_has_namespace_info
- && cu->lang () == language_cplus)
- cp_scan_for_anonymous_namespaces (cu->get_builder (), sym, objfile);
+ if (suppress_add)
+ {
+ sym->hash_next = objfile->template_symbols;
+ objfile->template_symbols = sym;
+ return;
}
- return (sym);
+
+ if (list_to_add != nullptr)
+ add_symbol_to_list (sym, *list_to_add);
+}
+
+/* Given a pointer to a DWARF information entry, figure out if we need
+ to make a symbol table entry for it, and if so, create a new entry
+ and return a pointer to it.
+ If TYPE is nullptr, determine symbol type from the die, otherwise
+ used the passed type.
+ If SPACE is not nullptr, use it to hold the new symbol. If it is
+ nullptr, allocate a new symbol on the objfile's obstack. */
+
+static struct symbol *
+new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
+ struct symbol *space)
+{
+ dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ struct objfile *objfile = per_objfile->objfile;
+
+ const char *name = dwarf2_name (die, cu);
+ if (name == nullptr && (die->tag == DW_TAG_subprogram
+ || die->tag == DW_TAG_inlined_subroutine
+ || die->tag == DW_TAG_entry_point))
+ name = dw2_linkage_name (die, cu);
+ if (name == nullptr)
+ return nullptr;
+
+ struct symbol *sym = space;
+ if (sym == nullptr)
+ sym = objfile->new_symbol<symbol> ();
+
+ sym->set_language (cu->lang (), &objfile->objfile_obstack);
+
+ /* Fortran does not have mangling standard and the mangling does differ
+ between gfortran, iFort etc. */
+ const char *physname
+ = ((cu->lang () == language_fortran || cu->lang () == language_ada)
+ ? dwarf2_full_name (name, die, cu)
+ : dwarf2_physname (name, die, cu));
+ const char *linkagename = dw2_linkage_name (die, cu);
+
+ /* Cache this symbol's name and the name's demangled form (if any). */
+ sym->set_linkage_name (linkagename != nullptr
+ ? linkagename
+ : physname);
+ if (linkagename != nullptr && cu->lang () != language_ada)
+ sym->set_demangled_name (physname == linkagename
+ ? name
+ : physname,
+ &objfile->objfile_obstack);
+
+ /* Handle DW_AT_artificial. */
+ struct attribute *attr = dwarf2_attr (die, DW_AT_artificial, cu);
+ if (attr != nullptr)
+ sym->set_is_artificial (attr->as_boolean ());
+
+ /* Default assumptions.
+ Use the passed type or decode it from the die. */
+ sym->set_domain (UNDEF_DOMAIN);
+ sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
+ sym->set_type (type != nullptr
+ ? type
+ : die_type (die, cu));
+
+ /* Handle DW_AT_{call,decl}_{file,line}. */
+ new_symbol_file_line (die, cu, sym);
+
+ /* Handle TAG-specific part. */
+ new_symbol (die, cu, sym, linkagename, physname);
+
+ /* For the benefit of old versions of GCC, check for anonymous
+ namespaces based on the demangled name. */
+ if (!cu->processing_has_namespace_info
+ && cu->lang () == language_cplus)
+ cp_scan_for_anonymous_namespaces (cu->get_builder (), sym, objfile);
+
+ return sym;
}
/* Read a constant value from an attribute. Either set *VALUE, or if