macrotab.c macroexp.c macrocmd.c macroscope.c main.c maint.c \
mdebugread.c memattr.c mem-break.c minsyms.c mipsread.c memory-map.c \
memrange.c mi/mi-common.c \
+ namespace.c \
objc-lang.c \
objfiles.c osabi.c observer.c osdata.c \
opencl-lang.c \
charset.o continuations.o corelow.o disasm.o dummy-frame.o dfp.o \
source.o value.o eval.o valops.o valarith.o valprint.o printcmd.o \
block.o symtab.o psymtab.o symfile.o symfile-debug.o symmisc.o \
- linespec.o dictionary.o \
+ linespec.o dictionary.o namespace.o \
location.o infcall.o \
infcmd.o infrun.o \
expprint.o environ.o stack.o thread.o \
#include "stack.h"
#include "gdb_vecs.h"
#include "typeprint.h"
+#include "namespace.h"
#include "psymtab.h"
#include "value.h"
const struct block *, const char *,
domain_enum, struct objfile *, int);
+static void ada_add_all_symbols (struct obstack *, const struct block *,
+ const char *, domain_enum, int, int *);
+
static int is_nonfunction (struct block_symbol *, int);
static void add_defn_to_vec (struct obstack *, struct symbol *,
int found_sym;
};
-/* A callback for add_matching_symbols that adds SYM, found in BLOCK,
+/* A callback for add_nonlocal_symbols that adds SYM, found in BLOCK,
to a list of symbols. DATA0 is a pointer to a struct match_data *
containing the obstack that collects the symbol list, the file that SYM
must come from, a flag indicating whether a non-argument symbol has
return 0;
}
+/* Helper for add_nonlocal_symbols. Find symbols in DOMAIN which are targetted
+ by renamings matching NAME in BLOCK. Add these symbols to OBSTACKP. If
+ WILD_MATCH_P is nonzero, perform the naming matching in "wild" mode (see
+ function "wild_match" for more information). Return whether we found such
+ symbols. */
+
+static int
+ada_add_block_renamings (struct obstack *obstackp,
+ const struct block *block,
+ const char *name,
+ domain_enum domain,
+ int wild_match_p)
+{
+ struct using_direct *renaming;
+ int defns_mark = num_defns_collected (obstackp);
+
+ for (renaming = block_using (block);
+ renaming != NULL;
+ renaming = renaming->next)
+ {
+ const char *r_name;
+ int name_match;
+
+ /* Avoid infinite recursions: skip this renaming if we are actually
+ already traversing it.
+
+ Currently, symbol lookup in Ada don't use the namespace machinery from
+ C++/Fortran support: skip namespace imports that use them. */
+ if (renaming->searched
+ || (renaming->import_src != NULL
+ && renaming->import_src[0] != '\0')
+ || (renaming->import_dest != NULL
+ && renaming->import_dest[0] != '\0'))
+ continue;
+ renaming->searched = 1;
+
+ /* TODO: here, we perform another name-based symbol lookup, which can
+ pull its own multiple overloads. In theory, we should be able to do
+ better in this case since, in DWARF, DW_AT_import is a DIE reference,
+ not a simple name. But in order to do this, we would need to enhance
+ the DWARF reader to associate a symbol to this renaming, instead of a
+ name. So, for now, we do something simpler: re-use the C++/Fortran
+ namespace machinery. */
+ r_name = (renaming->alias != NULL
+ ? renaming->alias
+ : renaming->declaration);
+ name_match
+ = wild_match_p ? wild_match (r_name, name) : strcmp (r_name, name);
+ if (name_match == 0)
+ ada_add_all_symbols (obstackp, block, renaming->declaration, domain,
+ 1, NULL);
+ renaming->searched = 0;
+ }
+ return num_defns_collected (obstackp) != defns_mark;
+}
+
/* Implements compare_names, but only applying the comparision using
the given CASING. */
int is_wild_match)
{
struct objfile *objfile;
+ struct compunit_symtab *cu;
struct match_data data;
memset (&data, 0, sizeof data);
objfile->sf->qf->map_matching_symbols (objfile, name, domain, global,
aux_add_nonlocal_symbols, &data,
full_match, compare_names);
+
+ ALL_OBJFILE_COMPUNITS (objfile, cu)
+ {
+ const struct block *global_block
+ = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cu), GLOBAL_BLOCK);
+
+ if (ada_add_block_renamings (obstackp, global_block , name, domain,
+ is_wild_match))
+ data.found_sym = 1;
+ }
}
if (num_defns_collected (obstackp) == 0 && global && !is_wild_match)
}
}
-/* Find symbols in DOMAIN matching NAME0, in BLOCK0 and, if full_search is
+/* Find symbols in DOMAIN matching NAME, in BLOCK and, if FULL_SEARCH is
non-zero, enclosing scope and in global scopes, returning the number of
- matches.
- Sets *RESULTS to point to a vector of (SYM,BLOCK) tuples,
- indicating the symbols found and the blocks and symbol tables (if
- any) in which they were found. This vector is transient---good only to
- the next call of ada_lookup_symbol_list.
+ matches. Add these to OBSTACKP.
- When full_search is non-zero, any non-function/non-enumeral
- symbol match within the nest of blocks whose innermost member is BLOCK0,
+ When FULL_SEARCH is non-zero, any non-function/non-enumeral
+ symbol match within the nest of blocks whose innermost member is BLOCK,
is the one match returned (no other matches in that or
enclosing blocks is returned). If there are any matches in or
- surrounding BLOCK0, then these alone are returned.
+ surrounding BLOCK, then these alone are returned.
Names prefixed with "standard__" are handled specially: "standard__"
- is first stripped off, and only static and global symbols are searched. */
+ is first stripped off, and only static and global symbols are searched.
-static int
-ada_lookup_symbol_list_worker (const char *name0, const struct block *block0,
- domain_enum domain,
- struct block_symbol **results,
- int full_search)
+ If MADE_GLOBAL_LOOKUP_P is non-null, set it before return to whether we had
+ to lookup global symbols. */
+
+static void
+ada_add_all_symbols (struct obstack *obstackp,
+ const struct block *block,
+ const char *name,
+ domain_enum domain,
+ int full_search,
+ int *made_global_lookup_p)
{
struct symbol *sym;
- const struct block *block;
- const char *name;
- const int wild_match_p = should_use_wild_match (name0);
- int syms_from_global_search = 0;
- int ndefns;
-
- obstack_free (&symbol_list_obstack, NULL);
- obstack_init (&symbol_list_obstack);
-
- /* Search specified block and its superiors. */
+ const int wild_match_p = should_use_wild_match (name);
- name = name0;
- block = block0;
+ if (made_global_lookup_p)
+ *made_global_lookup_p = 0;
/* Special case: If the user specifies a symbol name inside package
Standard, do a non-wild matching of the symbol name without
using, for instance, Standard.Constraint_Error when Constraint_Error
is ambiguous (due to the user defining its own Constraint_Error
entity inside its program). */
- if (startswith (name0, "standard__"))
+ if (startswith (name, "standard__"))
{
block = NULL;
- name = name0 + sizeof ("standard__") - 1;
+ name = name + sizeof ("standard__") - 1;
}
/* Check the non-global symbols. If we have ANY match, then we're done. */
if (block != NULL)
{
if (full_search)
- {
- ada_add_local_symbols (&symbol_list_obstack, name, block,
- domain, wild_match_p);
- }
+ ada_add_local_symbols (obstackp, name, block, domain, wild_match_p);
else
{
/* In the !full_search case we're are being called by
ada_iterate_over_symbols, and we don't want to search
superblocks. */
- ada_add_block_symbols (&symbol_list_obstack, block, name,
- domain, NULL, wild_match_p);
+ ada_add_block_symbols (obstackp, block, name, domain, NULL,
+ wild_match_p);
}
- if (num_defns_collected (&symbol_list_obstack) > 0 || !full_search)
- goto done;
+ if (num_defns_collected (obstackp) > 0 || !full_search)
+ return;
}
/* No non-global symbols found. Check our cache to see if we have
already performed this search before. If we have, then return
the same result. */
- if (lookup_cached_symbol (name0, domain, &sym, &block))
+ if (lookup_cached_symbol (name, domain, &sym, &block))
{
if (sym != NULL)
- add_defn_to_vec (&symbol_list_obstack, sym, block);
- goto done;
+ add_defn_to_vec (obstackp, sym, block);
+ return;
}
- syms_from_global_search = 1;
+ if (made_global_lookup_p)
+ *made_global_lookup_p = 1;
/* Search symbols from all global blocks. */
- add_nonlocal_symbols (&symbol_list_obstack, name, domain, 1,
- wild_match_p);
+ add_nonlocal_symbols (obstackp, name, domain, 1, wild_match_p);
/* Now add symbols from all per-file blocks if we've gotten no hits
(not strictly correct, but perhaps better than an error). */
- if (num_defns_collected (&symbol_list_obstack) == 0)
- add_nonlocal_symbols (&symbol_list_obstack, name, domain, 0,
- wild_match_p);
+ if (num_defns_collected (obstackp) == 0)
+ add_nonlocal_symbols (obstackp, name, domain, 0, wild_match_p);
+}
+
+/* Find symbols in DOMAIN matching NAME, in BLOCK and, if full_search is
+ non-zero, enclosing scope and in global scopes, returning the number of
+ matches.
+ Sets *RESULTS to point to a vector of (SYM,BLOCK) tuples,
+ indicating the symbols found and the blocks and symbol tables (if
+ any) in which they were found. This vector is transient---good only to
+ the next call of ada_lookup_symbol_list.
+
+ When full_search is non-zero, any non-function/non-enumeral
+ symbol match within the nest of blocks whose innermost member is BLOCK,
+ is the one match returned (no other matches in that or
+ enclosing blocks is returned). If there are any matches in or
+ surrounding BLOCK, then these alone are returned.
+
+ Names prefixed with "standard__" are handled specially: "standard__"
+ is first stripped off, and only static and global symbols are searched. */
+
+static int
+ada_lookup_symbol_list_worker (const char *name, const struct block *block,
+ domain_enum domain,
+ struct block_symbol **results,
+ int full_search)
+{
+ const int wild_match_p = should_use_wild_match (name);
+ int syms_from_global_search;
+ int ndefns;
+
+ obstack_free (&symbol_list_obstack, NULL);
+ obstack_init (&symbol_list_obstack);
+ ada_add_all_symbols (&symbol_list_obstack, block, name, domain,
+ full_search, &syms_from_global_search);
-done:
ndefns = num_defns_collected (&symbol_list_obstack);
*results = defns_collected (&symbol_list_obstack, 1);
ndefns = remove_extra_symbols (*results, ndefns);
if (ndefns == 0 && full_search && syms_from_global_search)
- cache_symbol (name0, domain, NULL, NULL);
+ cache_symbol (name, domain, NULL, NULL);
if (ndefns == 1 && full_search && syms_from_global_search)
- cache_symbol (name0, domain, (*results)[0].symbol, (*results)[0].block);
-
- ndefns = remove_irrelevant_renamings (*results, ndefns, block0);
+ cache_symbol (name, domain, (*results)[0].symbol, (*results)[0].block);
+ ndefns = remove_irrelevant_renamings (*results, ndefns, block);
return ndefns;
}
}
}
+ /* Handle renamings. */
+
+ if (ada_add_block_renamings (obstackp, block, name, domain, wild))
+ found_sym = 1;
+
if (!found_sym && arg_sym != NULL)
{
add_defn_to_vec (obstackp,
struct dictionary *dict;
- /* Used for language-specific info. */
+ /* Contains information about namespace-related info relevant to this block:
+ using directives and the current namespace scope. */
- union
- {
- struct
- {
- /* Contains information about namespace-related info relevant to
- this block: using directives and the current namespace
- scope. */
-
- struct block_namespace_info *the_namespace;
- }
- cplus_specific;
- }
- language_specific;
+ struct block_namespace_info *namespace_info;
};
/* The global block is singled out so that we can provide a back-link
#define BLOCK_FUNCTION(bl) (bl)->function
#define BLOCK_SUPERBLOCK(bl) (bl)->superblock
#define BLOCK_DICT(bl) (bl)->dict
-#define BLOCK_NAMESPACE(bl) (bl)->language_specific.cplus_specific.the_namespace
+#define BLOCK_NAMESPACE(bl) (bl)->namespace_info
struct blockvector
{
opblock = pblock;
}
- block_set_using (block, using_directives, &objfile->objfile_obstack);
- using_directives = NULL;
+ block_set_using (block,
+ (is_global
+ ? global_using_directives
+ : local_using_directives),
+ &objfile->objfile_obstack);
+ if (is_global)
+ global_using_directives = NULL;
+ else
+ local_using_directives = NULL;
record_pending_block (objfile, block, opblock);
last_source_start_addr = start_addr;
local_symbols = NULL;
+ local_using_directives = NULL;
within_function = 0;
have_line_numbers = 0;
a symtab, or by the really_free_pendings cleanup. */
gdb_assert (file_symbols == NULL);
gdb_assert (global_symbols == NULL);
+ gdb_assert (global_using_directives == NULL);
gdb_assert (pending_macros == NULL);
gdb_assert (pending_addrmap == NULL);
gdb_assert (current_subfile == NULL);
set_last_source_file (NULL);
local_symbols = NULL;
+ local_using_directives = NULL;
file_symbols = NULL;
global_symbols = NULL;
+ global_using_directives = NULL;
/* We don't free pending_macros here because if the symtab was successfully
built then ownership was transferred to the symtab. */
&& file_symbols == NULL
&& global_symbols == NULL
&& have_line_numbers == 0
- && pending_macros == NULL)
+ && pending_macros == NULL
+ && global_using_directives == NULL)
{
/* Ignore symtabs that have no functions with real debugging info. */
return NULL;
newobj->locals = local_symbols;
newobj->old_blocks = pending_blocks;
newobj->start_addr = valu;
- newobj->using_directives = using_directives;
+ newobj->local_using_directives = local_using_directives;
newobj->name = NULL;
local_symbols = NULL;
- using_directives = NULL;
+ local_using_directives = NULL;
return newobj;
}
void
buildsym_init (void)
{
- using_directives = NULL;
subfile_stack = NULL;
pending_addrmap_interesting = 0;
gdb_assert (pending_blocks == NULL);
gdb_assert (file_symbols == NULL);
gdb_assert (global_symbols == NULL);
+ gdb_assert (global_using_directives == NULL);
gdb_assert (pending_macros == NULL);
gdb_assert (pending_addrmap == NULL);
gdb_assert (buildsym_compunit == NULL);
/* "using" directives local to lexical context. */
-EXTERN struct using_direct *using_directives;
+EXTERN struct using_direct *local_using_directives;
+
+/* global "using" directives. */
+
+EXTERN struct using_direct *global_using_directives;
/* Stack representing unclosed lexical contexts (that will become
blocks, eventually). */
/* Pending using directives at the time we entered. */
- struct using_direct *using_directives;
+ struct using_direct *local_using_directives;
/* Pointer into blocklist as of entry */
#include "frame.h"
#include "buildsym.h"
#include "language.h"
+#include "namespace.h"
static struct block_symbol
cp_lookup_nested_symbol_1 (struct type *container_type,
anonymous namespace. So add symbols in it to the
namespace given by the previous component if there is
one, or to the global namespace if there isn't. */
- cp_add_using_directive (dest, src, NULL, NULL, NULL, 1,
- &objfile->objfile_obstack);
+ add_using_directive (&local_using_directives,
+ dest, src, NULL, NULL, NULL, 1,
+ &objfile->objfile_obstack);
}
/* The "+ 2" is for the "::". */
previous_component = next_component + 2;
}
}
-/* Add a using directive to using_directives. If the using directive
- in question has already been added, don't add it twice.
-
- Create a new struct using_direct which imports the namespace SRC
- into the scope DEST. ALIAS is the name of the imported namespace
- in the current scope. If ALIAS is NULL then the namespace is known
- by its original name. DECLARATION is the name if the imported
- varable if this is a declaration import (Eg. using A::x), otherwise
- it is NULL. EXCLUDES is a list of names not to import from an
- imported module or NULL. If COPY_NAMES is non-zero, then the
- arguments are copied into newly allocated memory so they can be
- temporaries. For EXCLUDES the VEC pointers are copied but the
- pointed to characters are not copied. */
-
-void
-cp_add_using_directive (const char *dest,
- const char *src,
- const char *alias,
- const char *declaration,
- VEC (const_char_ptr) *excludes,
- int copy_names,
- struct obstack *obstack)
-{
- struct using_direct *current;
- struct using_direct *newobj;
-
- /* Has it already been added? */
-
- for (current = using_directives; current != NULL; current = current->next)
- {
- int ix;
- const char *param;
-
- if (strcmp (current->import_src, src) != 0)
- continue;
- if (strcmp (current->import_dest, dest) != 0)
- continue;
- if ((alias == NULL && current->alias != NULL)
- || (alias != NULL && current->alias == NULL)
- || (alias != NULL && current->alias != NULL
- && strcmp (alias, current->alias) != 0))
- continue;
- if ((declaration == NULL && current->declaration != NULL)
- || (declaration != NULL && current->declaration == NULL)
- || (declaration != NULL && current->declaration != NULL
- && strcmp (declaration, current->declaration) != 0))
- continue;
-
- /* Compare the contents of EXCLUDES. */
- for (ix = 0; VEC_iterate (const_char_ptr, excludes, ix, param); ix++)
- if (current->excludes[ix] == NULL
- || strcmp (param, current->excludes[ix]) != 0)
- break;
- if (ix < VEC_length (const_char_ptr, excludes)
- || current->excludes[ix] != NULL)
- continue;
-
- /* Parameters exactly match CURRENT. */
- return;
- }
-
- newobj = obstack_alloc (obstack, (sizeof (*newobj)
- + (VEC_length (const_char_ptr, excludes)
- * sizeof (*newobj->excludes))));
- memset (newobj, 0, sizeof (*newobj));
-
- if (copy_names)
- {
- newobj->import_src = obstack_copy0 (obstack, src, strlen (src));
- newobj->import_dest = obstack_copy0 (obstack, dest, strlen (dest));
- }
- else
- {
- newobj->import_src = src;
- newobj->import_dest = dest;
- }
-
- if (alias != NULL && copy_names)
- newobj->alias = obstack_copy0 (obstack, alias, strlen (alias));
- else
- newobj->alias = alias;
-
- if (declaration != NULL && copy_names)
- newobj->declaration = obstack_copy0 (obstack,
- declaration, strlen (declaration));
- else
- newobj->declaration = declaration;
-
- memcpy (newobj->excludes, VEC_address (const_char_ptr, excludes),
- VEC_length (const_char_ptr, excludes) * sizeof (*newobj->excludes));
- newobj->excludes[VEC_length (const_char_ptr, excludes)] = NULL;
-
- newobj->next = using_directives;
- using_directives = newobj;
-}
-
/* Test whether or not NAMESPACE looks like it mentions an anonymous
namespace; return nonzero if so. */
#include "expression.h"
#include "value.h"
#include "cp-abi.h"
+#include "namespace.h"
#include <signal.h>
#include "safe-ctype.h"
struct objfile;
struct type;
struct demangle_component;
+struct using_direct;
/* A string representing the name of the anonymous namespace used in GDB. */
struct obstack obstack;
};
-/* 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];
-};
-
/* Functions from cp-support.c. */
extern int cp_is_in_anonymous (const char *symbol_name);
-extern void cp_add_using_directive (const char *dest,
- const char *src,
- const char *alias,
- const char *declaration,
- VEC (const_char_ptr) *excludes,
- int copy_names,
- struct obstack *obstack);
-
extern void cp_scan_for_anonymous_namespaces (const struct symbol *symbol,
struct objfile *objfile);
#include "source.h"
#include "filestuff.h"
#include "build-id.h"
+#include "namespace.h"
#include <fcntl.h>
#include <sys/types.h>
static void read_module (struct die_info *die, struct dwarf2_cu *cu);
+static struct using_direct **using_directives (enum language);
+
static void read_import_statement (struct die_info *die, struct dwarf2_cu *);
static int read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu);
return 0;
}
+/* Return the using directives repository (global or local?) to use in the
+ current context for LANGUAGE.
+
+ For Ada, imported declarations can materialize renamings, which *may* be
+ global. However it is impossible (for now?) in DWARF to distinguish
+ "external" imported declarations and "static" ones. As all imported
+ declarations seem to be static in all other languages, make them all CU-wide
+ global only in Ada. */
+
+static struct using_direct **
+using_directives (enum language language)
+{
+ if (language == language_ada && context_stack_depth == 0)
+ return &global_using_directives;
+ else
+ return &local_using_directives;
+}
+
/* Read the import statement specified by the given die and record it. */
static void
process_die (child_die, cu);
}
- cp_add_using_directive (import_prefix,
- canonical_name,
- import_alias,
- imported_declaration,
- excludes,
- 0,
- &objfile->objfile_obstack);
+ add_using_directive (using_directives (cu->language),
+ import_prefix,
+ canonical_name,
+ import_alias,
+ imported_declaration,
+ excludes,
+ 0,
+ &objfile->objfile_obstack);
do_cleanups (cleanups);
}
when we finish processing a function scope, we may need to go
back to building a containing block's symbol lists. */
local_symbols = newobj->locals;
- using_directives = newobj->using_directives;
+ local_using_directives = newobj->local_using_directives;
/* If we've finished processing a top-level function, subsequent
symbols go in the file symbol list. */
inherit_abstract_dies (die, cu);
newobj = pop_context ();
- if (local_symbols != NULL || using_directives != NULL)
+ if (local_symbols != NULL || local_using_directives != NULL)
{
struct block *block
= finish_block (0, &local_symbols, newobj->old_blocks,
dwarf2_record_block_ranges (die, block, baseaddr, cu);
}
local_symbols = newobj->locals;
- using_directives = newobj->using_directives;
+ local_using_directives = newobj->local_using_directives;
}
/* Read in DW_TAG_GNU_call_site and insert it to CU->call_site_htab. */
return set_die_type (die, type, cu);
}
-/* Read a C++ namespace. */
+/* Read a namespace scope. */
static void
read_namespace (struct die_info *die, struct dwarf2_cu *cu)
{
const char *previous_prefix = determine_prefix (die, cu);
- cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL,
- NULL, NULL, 0, &objfile->objfile_obstack);
+ add_using_directive (using_directives (cu->language),
+ previous_prefix, TYPE_NAME (type), NULL,
+ NULL, NULL, 0, &objfile->objfile_obstack);
}
}
--- /dev/null
+/* 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/>. */
+
+#include "defs.h"
+#include "namespace.h"
+
+/* Add a using directive to USING_DIRECTIVES. If the using directive
+ in question has already been added, don't add it twice.
+
+ Create a new struct using_direct which imports the namespace SRC
+ into the scope DEST. ALIAS is the name of the imported namespace
+ in the current scope. If ALIAS is NULL then the namespace is known
+ by its original name. DECLARATION is the name if the imported
+ varable if this is a declaration import (Eg. using A::x), otherwise
+ it is NULL. EXCLUDES is a list of names not to import from an
+ imported module or NULL. If COPY_NAMES is non-zero, then the
+ arguments are copied into newly allocated memory so they can be
+ temporaries. For EXCLUDES the VEC pointers are copied but the
+ pointed to characters are not copied. */
+
+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)
+{
+ struct using_direct *current;
+ struct using_direct *newobj;
+
+ /* Has it already been added? */
+
+ for (current = *using_directives; current != NULL; current = current->next)
+ {
+ int ix;
+ const char *param;
+
+ if (strcmp (current->import_src, src) != 0)
+ continue;
+ if (strcmp (current->import_dest, dest) != 0)
+ continue;
+ if ((alias == NULL && current->alias != NULL)
+ || (alias != NULL && current->alias == NULL)
+ || (alias != NULL && current->alias != NULL
+ && strcmp (alias, current->alias) != 0))
+ continue;
+ if ((declaration == NULL && current->declaration != NULL)
+ || (declaration != NULL && current->declaration == NULL)
+ || (declaration != NULL && current->declaration != NULL
+ && strcmp (declaration, current->declaration) != 0))
+ continue;
+
+ /* Compare the contents of EXCLUDES. */
+ for (ix = 0; VEC_iterate (const_char_ptr, excludes, ix, param); ix++)
+ if (current->excludes[ix] == NULL
+ || strcmp (param, current->excludes[ix]) != 0)
+ break;
+ if (ix < VEC_length (const_char_ptr, excludes)
+ || current->excludes[ix] != NULL)
+ continue;
+
+ /* Parameters exactly match CURRENT. */
+ return;
+ }
+
+ newobj = obstack_alloc (obstack, (sizeof (*newobj)
+ + (VEC_length (const_char_ptr, excludes)
+ * sizeof (*newobj->excludes))));
+ memset (newobj, 0, sizeof (*newobj));
+
+ if (copy_names)
+ {
+ newobj->import_src = obstack_copy0 (obstack, src, strlen (src));
+ newobj->import_dest = obstack_copy0 (obstack, dest, strlen (dest));
+ }
+ else
+ {
+ newobj->import_src = src;
+ newobj->import_dest = dest;
+ }
+
+ if (alias != NULL && copy_names)
+ newobj->alias = obstack_copy0 (obstack, alias, strlen (alias));
+ else
+ newobj->alias = alias;
+
+ if (declaration != NULL && copy_names)
+ newobj->declaration = obstack_copy0 (obstack,
+ declaration, strlen (declaration));
+ else
+ newobj->declaration = declaration;
+
+ memcpy (newobj->excludes, VEC_address (const_char_ptr, excludes),
+ VEC_length (const_char_ptr, excludes) * sizeof (*newobj->excludes));
+ newobj->excludes[VEC_length (const_char_ptr, excludes)] = NULL;
+
+ newobj->next = *using_directives;
+ *using_directives = newobj;
+}
--- /dev/null
+/* 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 */
--- /dev/null
+# Copyright 2015 Free Software Foundation, Inc.
+#
+# 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/>.
+
+load_lib "ada.exp"
+
+standard_ada_testfile fun_renaming
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } {
+ return -1
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "BREAK" ${testdir}/fun_renaming.adb]
+runto "fun_renaming.adb:$bp_location"
+
+# Sanity check: make sure we can call a regular global function.
+gdb_test "print next(1)" " = 2"
+
+# Starting with GCC 6, renamed subprograms are materialized in the debugging
+# information: make sure we can call the regular global function using its
+# multiple names.
+
+set test "print n(1)"
+gdb_test_multiple $test $test {
+ -re " = 2\..*$gdb_prompt $" {
+ pass $test
+ }
+ -re "No definition of \"n\" in current context\..*$gdb_prompt $" {
+ if {[test_compiler_info {gcc-6*}]} {
+ fail $test
+ } else {
+ xfail $test
+ }
+ }
+
+}
+set test "print renamed_next(1)"
+gdb_test_multiple $test $test {
+ -re " = 2\..*$gdb_prompt $" {
+ pass $test
+ }
+ -re "No definition of \"renamed_next\" in current context\..*$gdb_prompt $" {
+ if {[test_compiler_info {gcc-6*}]} {
+ fail $test
+ } else {
+ xfail $test
+ }
+ }
+}
+
+set test "print pack.renamed_next(1)"
+gdb_test_multiple $test $test {
+ -re " = 2\..*$gdb_prompt $" {
+ pass $test
+ }
+ -re "No definition of \"pack\.renamed_next\" in current context\..*$gdb_prompt $" {
+ if {[test_compiler_info {gcc-6*}]} {
+ fail $test
+ } else {
+ xfail $test
+ }
+ }
+ -re "Type <data variable, no debug info> is not a structure or union type\..*$gdb_prompt $" {
+ if {[test_compiler_info {gcc-6*}]} {
+ fail $test
+ } else {
+ xfail $test
+ }
+ }
+}
--- /dev/null
+-- Copyright 2015 Free Software Foundation, Inc.
+--
+-- 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/>.
+
+with Pack;
+
+procedure Fun_Renaming is
+ function N (I : Integer) return Integer renames Pack.Next;
+begin
+ Pack.Discard (N (1)); -- BREAK
+ Pack.Discard (Pack.Renamed_Next (1)); -- BREAK
+end Fun_Renaming;
--- /dev/null
+-- Copyright 2015 Free Software Foundation, Inc.
+--
+-- 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/>.
+
+package body Pack is
+ function Next (I : Integer) return Integer is
+ begin
+ return I + 1;
+ end Next;
+
+ procedure Discard (I : Integer) is
+ begin
+ null;
+ end Discard;
+end Pack;
--- /dev/null
+-- Copyright 2015 Free Software Foundation, Inc.
+--
+-- 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/>.
+
+package Pack is
+
+ function Next (I : Integer) return Integer;
+ function Renamed_Next (I : Integer) return Integer renames Next;
+ procedure Discard (I : Integer);
+
+end Pack;