if ((entry->flags & IS_LINKAGE) != 0)
entry->canonical = entry->name;
else if (entry->lang == language_ada)
- handle_gnat_encoded_entry (entry, gnat_entries.get (),
- new_gnat_entries);
+ {
+ /* Newer versions of GNAT emit DW_TAG_module and use a
+ hierarchical structure. In this case, we don't need to
+ do any extra work. This can be detected by looking for a
+ GNAT-encoded name. */
+ if (strstr (entry->name, "__") == nullptr)
+ {
+ entry->canonical = entry->name;
+
+ /* If the entry does not have a parent, then there's
+ nothing extra to do here -- the entry itself is
+ sufficient.
+
+ However, if it does have a parent, we have to
+ synthesize an entry with the full name. This is
+ unfortunate, but it's necessary due to how some of
+ the Ada name-lookup code currently works. For
+ example, without this, ada_get_tsd_type will
+ fail.
+
+ Eventually it would be good to change the Ada lookup
+ code, and then remove these entries (and supporting
+ code in cooked_index_entry::full_name). */
+ if (entry->get_parent () != nullptr)
+ {
+ const char *fullname = entry->full_name (&m_storage, false,
+ true);
+ cooked_index_entry *linkage = create (entry->die_offset,
+ entry->tag,
+ (entry->flags
+ | IS_LINKAGE
+ | IS_SYNTHESIZED),
+ language_ada,
+ fullname,
+ nullptr,
+ entry->per_cu);
+ linkage->canonical = fullname;
+ new_gnat_entries.push_back (linkage);
+ }
+ }
+ else
+ handle_gnat_encoded_entry (entry, gnat_entries.get (),
+ new_gnat_entries);
+ }
else if (entry->lang == language_cplus || entry->lang == language_c)
{
void **slot = htab_find_slot (seen_names.get (), entry,
#include "dwarf2/read-gdb-index.h"
#include "dwarf2/sect-names.h"
#include "dwarf2/stringify.h"
+#include "dwarf2/tag.h"
#include "dwarf2/public.h"
#include "bfd.h"
#include "elf-bfd.h"
{
struct attribute *attr;
+ if (tag_is_type (die->tag) && die->tag != DW_TAG_template_type_param)
+ {
+ /* Historically GNAT emitted some types in funny scopes. For
+ example, in one test case, where the first use of Natural was
+ as the type of a field in a record, GNAT emitted:
+
+ <2>: DW_TAG_structure_type
+ ... variant parts and whatnot
+ <5>: DW_TAG_subrange_type
+ . DW_AT_name: natural
+
+ To detect this, we look up the DIE tree for a node that has
+ a name; and if that name is fully qualified, we return 0
+ here. */
+ if (cu->lang () == language_ada)
+ {
+ for (die_info *iter = die->parent;
+ iter != nullptr;
+ iter = iter->parent)
+ {
+ if (tag_is_type (iter->tag))
+ {
+ const char *name = dwarf2_name (iter, cu);
+ if (name != nullptr)
+ return strstr (name, "__") == nullptr;
+ }
+ }
+ }
+ return 1;
+ }
+
switch (die->tag)
{
- case DW_TAG_namespace:
- case DW_TAG_typedef:
- case DW_TAG_class_type:
- case DW_TAG_interface_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_enumeration_type:
case DW_TAG_enumerator:
case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
case DW_TAG_imported_declaration:
return 1;
+ case DW_TAG_module:
+ /* We don't need the namespace for Fortran modules, but we do
+ for Ada packages. */
+ return cu->lang () == language_ada;
+
case DW_TAG_variable:
case DW_TAG_constant:
/* We only need to prefix "globally" visible variables. These include
Fortran names because there is no mangling standard. So new_symbol
will set the demangled name to the result of dwarf2_full_name, and it is
the demangled name that GDB uses if it exists. */
- if (lang == language_ada
- || (lang == language_fortran && physname))
+ if ((lang == language_ada || lang == language_fortran) && physname)
{
/* For Ada unit, we prefer the linkage name over the name, as
the former contains the exported name, which the user expects
return linkage_name;
}
+ /* Some versions of GNAT emit fully-qualified names already. These
+ have "__" separating the components -- something ordinary names
+ will never have. */
+ if (lang == language_ada
+ && name != nullptr
+ && strstr (name, "__") != nullptr)
+ return name;
+
/* These are the only languages we know how to qualify names in. */
if (name != NULL
&& (lang == language_cplus
- || lang == language_fortran || lang == language_d
- || lang == language_rust))
+ || lang == language_fortran
+ || lang == language_d
+ || lang == language_rust
+ || lang == language_ada))
{
if (die_needs_namespace (die, cu))
{
canonical_name = imported_name_prefix;
}
else if (strlen (imported_name_prefix) > 0)
- canonical_name = obconcat (&objfile->objfile_obstack,
- imported_name_prefix,
- (cu->lang () == language_d
- ? "."
- : "::"),
- imported_name, (char *) NULL);
+ {
+ gdb::unique_xmalloc_ptr<char> temp;
+ temp = typename_concat (imported_name_prefix, imported_name, 0, cu);
+ canonical_name = obstack_strdup (&objfile->objfile_obstack, temp.get ());
+ }
else
canonical_name = imported_name;
static bool
check_ada_pragma_import (struct die_info *die, struct dwarf2_cu *cu)
{
- /* A Pragma Import will have both a name and a linkage name. */
- const char *name = dwarf2_name (die, cu);
+ if (cu->lang () != language_ada)
+ return false;
+
+ /* A Pragma Import will have both a name and a linkage name. With a
+ newer version of GNAT, we have to examine the full name, because
+ the compiler might decide to emit a linkage name matching the
+ full name in some scenario. */
+ const char *name = dwarf2_full_name (nullptr, die, cu);
if (name == nullptr)
return false;
if (!for_specification)
{
+ /* Older versions of GNAT emit full-qualified encoded names. In
+ this case, also use this name as the linkage name. */
if (m_language == language_ada
- && *linkage_name == nullptr)
+ && *linkage_name == nullptr
+ && *name != nullptr
+ && strstr (*name, "__") != nullptr)
*linkage_name = *name;
if (!scanning_per_cu->addresses_seen && low_pc.has_value ()
/* 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_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 || cu->lang () == language_ada)
+ if (linkagename == nullptr)
sym->set_linkage_name (physname);
+ else if (cu->lang () == language_ada)
+ sym->set_linkage_name (linkagename);
else
{
if (physname == linkagename)
list_to_add = cu->list_in_scope;
}
- if (is_ada_import_or_export (cu, name, linkagename))
+ if (is_ada_import_or_export (cu, physname, linkagename))
{
/* This is either a Pragma Import or Export. They can
be distinguished by the declaration flag. */
- sym->set_linkage_name (name);
+ sym->set_linkage_name (physname);
if (die_is_declaration (die, cu))
{
/* For Import, create a symbol using the source
/* 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, name, cu,
+ add_ada_export_symbol (sym, linkagename, physname, cu,
list_to_add);
}
}
list_to_add = cu->list_in_scope;
if (list_to_add != nullptr
- && is_ada_import_or_export (cu, name, linkagename))
+ && 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, name, linkagename, cu,
+ add_ada_export_symbol (sym, physname, linkagename, cu,
list_to_add);
}
}
if (!suppress_add)
list_to_add = cu->list_in_scope;
}
- else if (is_ada_import_or_export (cu, name, linkagename))
+ 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 (name);
+ sym->set_linkage_name (physname);
list_to_add
= ((cu->list_in_scope
== cu->get_builder ()->get_file_symbols ())
if (cu->lang () != language_cplus
&& cu->lang () != language_fortran
&& cu->lang () != language_d
- && cu->lang () != language_rust)
+ && cu->lang () != language_rust
+ && cu->lang () != language_ada)
return "";
retval = anonymous_struct_prefix (die, cu);
else if (die->tag == DW_TAG_entry_point)
return determine_prefix (parent, cu);
}
+ else if (cu->lang () == language_ada
+ && (die->tag == DW_TAG_subprogram
+ || die->tag == DW_TAG_inlined_subroutine
+ || die->tag == DW_TAG_lexical_block))
+ return dwarf2_full_name (nullptr, parent, cu);
return "";
case DW_TAG_enumeration_type:
parent_type = read_type_die (parent, cu);
lead = "__";
sep = "_MOD_";
}
+ else if (cu->lang () == language_ada)
+ sep = "__";
else
sep = "::";
&& die->tag != DW_TAG_namelist
&& die->tag != DW_TAG_union_type
&& die->tag != DW_TAG_template_type_param
- && die->tag != DW_TAG_template_value_param)
+ && die->tag != DW_TAG_template_value_param
+ && die->tag != DW_TAG_module)
return NULL;
switch (die->tag)