/* Helper routines for C++ support in GDB.
- Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2003-2004, 2007-2012 Free Software Foundation, Inc.
Contributed by David Carlton and by Kealia, Inc.
/* Check to see if SYMBOL refers to an object contained within an
anonymous namespace; if so, add an appropriate using directive. */
-/* Optimize away strlen ("(anonymous namespace)"). */
-
-#define ANONYMOUS_NAMESPACE_LEN 21
-
void
-cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
+cp_scan_for_anonymous_namespaces (const struct symbol *const symbol,
+ struct objfile *const objfile)
{
if (SYMBOL_DEMANGLED_NAME (symbol) != NULL)
{
while (name[next_component] == ':')
{
- if ((next_component - previous_component) == ANONYMOUS_NAMESPACE_LEN
+ if (((next_component - previous_component)
+ == CP_ANONYMOUS_NAMESPACE_LEN)
&& strncmp (name + previous_component,
- "(anonymous namespace)",
- ANONYMOUS_NAMESPACE_LEN) == 0)
+ CP_ANONYMOUS_NAMESPACE_STR,
+ CP_ANONYMOUS_NAMESPACE_LEN) == 0)
{
int dest_len = (previous_component == 0
? 0 : previous_component - 2);
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,
- &SYMBOL_SYMTAB (symbol)->objfile->objfile_obstack);
+ cp_add_using_directive (dest, src, NULL, NULL, NULL,
+ &objfile->objfile_obstack);
}
/* The "+ 2" is for the "::". */
previous_component = next_component + 2;
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. The arguments are copied into newly allocated memory
- so they can be temporaries. */
+ it is NULL. EXCLUDES is a list of names not to import from an imported
+ module or NULL. 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,
struct obstack *obstack)
{
struct using_direct *current;
for (current = using_directives; current != NULL; current = current->next)
{
- if (strcmp (current->import_src, src) == 0
- && strcmp (current->import_dest, dest) == 0
- && ((alias == NULL && current->alias == NULL)
- || (alias != NULL && current->alias != NULL
- && strcmp (alias, current->alias) == 0))
- && ((declaration == NULL && current->declaration == NULL)
- || (declaration != NULL && current->declaration != NULL
- && strcmp (declaration, current->declaration) == 0)))
- return;
+ 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;
}
- new = OBSTACK_ZALLOC (obstack, struct using_direct);
+ new = obstack_alloc (obstack, (sizeof (*new)
+ + (VEC_length (const_char_ptr, excludes)
+ * sizeof (*new->excludes))));
+ memset (new, 0, sizeof (*new));
new->import_src = obsavestring (src, strlen (src), obstack);
new->import_dest = obsavestring (dest, strlen (dest), obstack);
new->declaration = obsavestring (declaration, strlen (declaration),
obstack);
+ memcpy (new->excludes, VEC_address (const_char_ptr, excludes),
+ VEC_length (const_char_ptr, excludes) * sizeof (*new->excludes));
+ new->excludes[VEC_length (const_char_ptr, excludes)] = NULL;
+
new->next = using_directives;
using_directives = new;
}
int
cp_is_anonymous (const char *namespace)
{
- return (strstr (namespace, "(anonymous namespace)")
+ return (strstr (namespace, CP_ANONYMOUS_NAMESPACE_STR)
!= NULL);
}
current != NULL;
current = current->next)
{
+ const char **excludep;
+
len = strlen (current->import_dest);
directive_match = (search_parents
? (strncmp (scope, current->import_dest,
ancestors then it is applicable. */
if (directive_match && !current->searched)
{
- /* Mark this import as searched so that the recursive call
- does not search it again. */
- current->searched = 1;
- searched_cleanup = make_cleanup (reset_directive_searched,
- current);
-
- /* If there is an import of a single declaration, compare the
- imported declaration (after optional renaming by its alias)
- with the sought out name. If there is a match pass
- current->import_src as NAMESPACE to direct the search
- towards the imported namespace. */
- if (current->declaration
- && strcmp (name, current->alias
- ? current->alias : current->declaration) == 0)
- sym = cp_lookup_symbol_in_namespace (current->import_src,
- current->declaration,
- block, domain);
-
- /* If this is a DECLARATION_ONLY search or a symbol was found
- or this import statement was an import declaration, the
- search of this import is complete. */
- if (declaration_only || sym != NULL || current->declaration)
- {
- current->searched = 0;
- discard_cleanups (searched_cleanup);
-
- if (sym != NULL)
- return sym;
-
- continue;
- }
-
- if (current->alias != NULL
- && strcmp (name, current->alias) == 0)
- /* If the import is creating an alias and the alias matches
- the sought name. Pass current->import_src as the NAME to
- direct the search towards the aliased namespace. */
- {
- sym = cp_lookup_symbol_in_namespace (scope,
- current->import_src,
+ /* Mark this import as searched so that the recursive call
+ does not search it again. */
+ current->searched = 1;
+ searched_cleanup = make_cleanup (reset_directive_searched,
+ current);
+
+ /* If there is an import of a single declaration, compare the
+ imported declaration (after optional renaming by its alias)
+ with the sought out name. If there is a match pass
+ current->import_src as NAMESPACE to direct the search
+ towards the imported namespace. */
+ if (current->declaration
+ && strcmp (name, current->alias
+ ? current->alias : current->declaration) == 0)
+ sym = cp_lookup_symbol_in_namespace (current->import_src,
+ current->declaration,
block, domain);
- }
- else if (current->alias == NULL)
- {
- /* If this import statement creates no alias, pass
- current->inner as NAMESPACE to direct the search
- towards the imported namespace. */
- sym = cp_lookup_symbol_imports (current->import_src,
- name, block,
- domain, 0, 0);
- }
- current->searched = 0;
- discard_cleanups (searched_cleanup);
-
- if (sym != NULL)
- return sym;
+
+ /* If this is a DECLARATION_ONLY search or a symbol was found
+ or this import statement was an import declaration, the
+ search of this import is complete. */
+ if (declaration_only || sym != NULL || current->declaration)
+ {
+ current->searched = 0;
+ discard_cleanups (searched_cleanup);
+
+ if (sym != NULL)
+ return sym;
+
+ continue;
+ }
+
+ /* Do not follow CURRENT if NAME matches its EXCLUDES. */
+ for (excludep = current->excludes; *excludep; excludep++)
+ if (strcmp (name, *excludep) == 0)
+ break;
+ if (*excludep)
+ {
+ discard_cleanups (searched_cleanup);
+ continue;
+ }
+
+ if (current->alias != NULL
+ && strcmp (name, current->alias) == 0)
+ /* If the import is creating an alias and the alias matches
+ the sought name. Pass current->import_src as the NAME to
+ direct the search towards the aliased namespace. */
+ {
+ sym = cp_lookup_symbol_in_namespace (scope,
+ current->import_src,
+ block, domain);
+ }
+ else if (current->alias == NULL)
+ {
+ /* If this import statement creates no alias, pass
+ current->inner as NAMESPACE to direct the search
+ towards the imported namespace. */
+ sym = cp_lookup_symbol_imports (current->import_src,
+ name, block,
+ domain, 0, 0);
+ }
+ current->searched = 0;
+ discard_cleanups (searched_cleanup);
+
+ if (sym != NULL)
+ return sym;
}
}
const char *nested_name,
const struct block *block)
{
+ /* type_name_no_tag_required provides better error reporting using the
+ original type. */
+ struct type *saved_parent_type = parent_type;
+
+ CHECK_TYPEDEF (parent_type);
+
switch (TYPE_CODE (parent_type))
{
case TYPE_CODE_STRUCT:
just like members of namespaces; in particular,
lookup_symbol_namespace works when looking them up. */
- const char *parent_name = TYPE_TAG_NAME (parent_type);
+ const char *parent_name = type_name_no_tag_or_error (saved_parent_type);
struct symbol *sym
= cp_lookup_symbol_in_namespace (parent_name, nested_name,
block, VAR_DOMAIN);