binutils-gdb/gdb/namespace.h
Pierre-Marie de Rodat 22cee43f9a [Ada] Add support for subprogram renamings
Consider the following declaration:

    function Foo (I : Integer) return Integer renames Pack.Bar;

As Foo is not materialized as a routine whose name is derived from Foo,
GDB currently cannot use it:

    (gdb) print foo(0)
    No definition of "foo" in current context.

However, compilers can emit DW_TAG_imported_declaration in order to
materialize the fact that Foo is actually another name for Pack.Bar.
This commit enhances the DWARF reader to record global renamings (it
used to put global ones in a static block) and enhances the Ada engine
to leverage this information during symbol lookup.

gdb/ChangeLog:

	* ada-lang.c: Include namespace.h
	(aux_add_nonlocal_symbols): Fix a function name in comment.
	(ada_add_block_renamings): New.
	(add_nonlocal_symbols): Add global renamings handling.
	(ada_lookup_symbol_list_worker): Move the symbol lookup part
	to...
	(ada_add_all_symbols): ... this new function.
	(ada_add_block_symbols): Try to match the input name against the
	"using directives list", perform a recursive symbol lookup on
	the matched declarations.
	* block.h (struct block): Move the_namespace to top-level as
	namespace_info. Remove the language_specific field.
	(BLOCK_NAMESPACE): Update access to the namespace_info field.
	* buildsym.h (using_directives): Rename into...
	(local_using_directives): ... this.
	(global_using_directives): New.
	(struct context_stack): Rename the using_directives field into
	local_using_directives.
	* buildsym.c (finish_block_internal): Deal with the proper
	using directives repository (local or global).
	(prepare_for_building): Reset local_using_directives. Assert
	that there is no pending global using directive.
	(reset_symtab_globals): Reset global_using_directives and
	local_using_directives.
	(end_symtab_get_static_block): Don't ignore symtabs that have
	only using directives.
	(push_context): Update references to local_using_directives.
	(buildsym_init): Do not reset using_directives.
	* cp-support.c: Include namespace.h.
	* cp-support.h (struct using_direct): Move to namespace.h.
	(cp_add_using_directives): Move to namespace.h.
	* cp-namespace.c: Include namespace.h
	(cp_add_using_directive): Move to namespace.c, rename it to
	add_using_directive, add a "using_directives" argument and use
	it as the pending using directives repository.  All callers
	updated.
	* dwarf2read.c (using_directives): New.
	(read_import_statement): Call using_directives.
	(read_func_scope): Update references to local_using_directives.
	(read_lexical_block_scope): Likewise.
	(read_namespace): Update the heading comment, call
	using_directives.
	* namespace.h: New file.
	* namespace.c: New file.
	* Makefile.in (SFILES): Add namespace.c.
	(COMMON_OBS): Add namespace.o

gdb/testsuite/ChangeLog:

	* gdb.ada/fun_renaming.exp: New testcase.
	* gdb.ada/fun_renaming/fun_renaming.adb: New file.
	* gdb.ada/fun_renaming/pack.adb: New file.
	* gdb.ada/fun_renaming/pack.ads: New file.

Tested on x86_64-linux.  Support for this in GCC is in the pipeline: see
<https://gcc.gnu.org/ml/gcc-patches/2015-07/msg02166.html>.
2015-08-13 09:33:42 +02:00

119 lines
3.8 KiB
C++

/* Code dealing with "using" directives for GDB.
Copyright (C) 2003-2015 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef NAMESPACE_H
#define NAMESPACE_H
#include "vec.h"
#include "gdb_vecs.h"
#include "gdb_obstack.h"
/* This struct is designed to store data from using directives. It
says that names from namespace IMPORT_SRC should be visible within
namespace IMPORT_DEST. These form a linked list; NEXT is the next
element of the list. If the imported namespace or declaration has
been aliased within the IMPORT_DEST namespace, ALIAS is set to a
string representing the alias. Otherwise, ALIAS is NULL.
DECLARATION is the name of the imported declaration, if this import
statement represents one. Otherwise DECLARATION is NULL and this
import statement represents a namespace.
C++: using namespace A;
Fortran: use A
import_src = "A"
import_dest = local scope of the import statement even such as ""
alias = NULL
declaration = NULL
excludes = NULL
C++: using A::x;
Fortran: use A, only: x
import_src = "A"
import_dest = local scope of the import statement even such as ""
alias = NULL
declaration = "x"
excludes = NULL
The declaration will get imported as import_dest::x.
C++ has no way to import all names except those listed ones.
Fortran: use A, localname => x
import_src = "A"
import_dest = local scope of the import statement even such as ""
alias = "localname"
declaration = "x"
excludes = NULL
+
import_src = "A"
import_dest = local scope of the import statement even such as ""
alias = NULL
declaration = NULL
excludes = ["x"]
All the entries of A get imported except of "x". "x" gets imported as
"localname". "x" is not defined as a local name by this statement.
C++: namespace LOCALNS = A;
Fortran has no way to address non-local namespace/module.
import_src = "A"
import_dest = local scope of the import statement even such as ""
alias = "LOCALNS"
declaration = NULL
excludes = NULL
The namespace will get imported as the import_dest::LOCALNS
namespace.
C++ cannot express it, it would be something like: using localname
= A::x;
Fortran: use A, only localname => x
import_src = "A"
import_dest = local scope of the import statement even such as ""
alias = "localname"
declaration = "x"
excludes = NULL
The declaration will get imported as localname or
`import_dest`localname. */
struct using_direct
{
const char *import_src;
const char *import_dest;
const char *alias;
const char *declaration;
struct using_direct *next;
/* Used during import search to temporarily mark this node as
searched. */
int searched;
/* USING_DIRECT has variable allocation size according to the number of
EXCLUDES entries, the last entry is NULL. */
const char *excludes[1];
};
extern void add_using_directive (struct using_direct **using_directives,
const char *dest,
const char *src,
const char *alias,
const char *declaration,
VEC (const_char_ptr) *excludes,
int copy_names,
struct obstack *obstack);
#endif /* NAMESPACE_H */