/* Definitions for C++ name lookup routines.
- Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
GCC 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 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "toplev.h"
#include "diagnostic.h"
#include "debug.h"
+#include "c-pragma.h"
/* The bindings for a particular name in a particular scope. */
#define EMPTY_SCOPE_BINDING { NULL_TREE, NULL_TREE }
static cxx_scope *innermost_nonclass_level (void);
-static tree select_decl (const struct scope_binding *, int);
static cxx_binding *binding_for_name (cxx_scope *, tree);
-static tree lookup_name_innermost_nonclass_level (tree);
-static tree push_overloaded_decl (tree, int);
+static tree push_overloaded_decl (tree, int, bool);
static bool lookup_using_namespace (tree, struct scope_binding *, tree,
- tree, int);
+ tree, int);
static bool qualified_lookup_using_namespace (tree, tree,
struct scope_binding *, int);
static tree lookup_type_current_level (tree);
static tree push_using_directive (tree);
-static void cp_emit_debug_info_for_using (tree, tree);
/* The :: namespace. */
unit. */
static GTY(()) tree anonymous_namespace_name;
+/* Initialize anonymous_namespace_name if necessary, and return it. */
+
+static tree
+get_anonymous_namespace_name(void)
+{
+ if (!anonymous_namespace_name)
+ {
+ /* The anonymous namespace has to have a unique name
+ if typeinfo objects are being compared by name. */
+ if (! flag_weak || ! SUPPORTS_ONE_ONLY)
+ anonymous_namespace_name = get_file_function_name ("N");
+ else
+ /* The demangler expects anonymous namespaces to be called
+ something starting with '_GLOBAL__N_'. */
+ anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
+ }
+ return anonymous_namespace_name;
+}
/* Compute the chain index of a binding_entry given the HASH value of its
name and the total COUNT of chains. COUNT is assumed to be a power
{
binding_entry temp = table->chain[i];
while (temp != NULL)
- {
- binding_entry entry = temp;
- temp = entry->chain;
- binding_entry_free (entry);
- }
+ {
+ binding_entry entry = temp;
+ temp = entry->chain;
+ binding_entry_free (entry);
+ }
table->chain[i] = NULL;
}
table->entry_count = 0;
{
binding_entry entry = old_chains[i];
for (; entry != NULL; entry = old_chains[i])
- {
- const unsigned int hash = IDENTIFIER_HASH_VALUE (entry->name);
- const size_t j = ENTRY_INDEX (hash, new_chain_count);
-
- old_chains[i] = entry->chain;
- entry->chain = table->chain[j];
- table->chain[j] = entry;
- }
+ {
+ const unsigned int hash = IDENTIFIER_HASH_VALUE (entry->name);
+ const size_t j = ENTRY_INDEX (hash, new_chain_count);
+
+ old_chains[i] = entry->chain;
+ entry->chain = table->chain[j];
+ table->chain[j] = entry;
+ }
}
table->entry_count = old_entry_count;
}
{
binding_entry entry = table->chain[i];
for (; entry != NULL; entry = entry->chain)
- proc (entry, data);
+ proc (entry, data);
}
}
\f
{
cp_class_binding *cb;
cxx_binding *binding;
-
+
if (VEC_length (cp_class_binding, scope->class_shadowed))
{
cp_class_binding *old_base;
{
/* Fixup the current bindings, as they might have moved. */
size_t i;
-
+
for (i = 0;
VEC_iterate (cp_class_binding, scope->class_shadowed, i, cb);
i++)
}
else
cb = VEC_safe_push (cp_class_binding, gc, scope->class_shadowed, NULL);
-
+
cb->identifier = name;
binding = &cb->base;
binding->scope = scope;
}
else
binding = new_class_binding (id, decl, /*type=*/NULL_TREE, level);
-
+
/* Now, fill in the binding information. */
binding->previous = IDENTIFIER_BINDING (id);
INHERITED_VALUE_BINDING_P (binding) = 0;
}
}
-/* BINDING records an existing declaration for a namein the current scope.
+/* BINDING records an existing declaration for a name in the current scope.
But, DECL is another declaration for that same identifier in the
same scope. This is the `struct stat' hack whereby a non-typedef
class name or enum-name can be bound at the same level as some other
else if (/* BVAL is null when push_class_level_binding moves an
inherited type-binding out of the way to make room for a
new value binding. */
- !bval
+ !bval
/* BVAL is error_mark_node when DECL's name has been used
in a non-class scope prior declaration. In that case,
we should have already issued a diagnostic; for graceful
error recovery purpose, pretend this was the intended
declaration for that name. */
|| bval == error_mark_node
- /* If BVAL is a built-in that has not yet been declared,
+ /* If BVAL is anticipated but has not yet been declared,
pretend it is not there at all. */
|| (TREE_CODE (bval) == FUNCTION_DECL
- && DECL_ANTICIPATED (bval)))
+ && DECL_ANTICIPATED (bval)
+ && !DECL_HIDDEN_FRIEND_P (bval)))
binding->value = decl;
else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval))
{
/* We have two typedef-names, both naming the same type to have
the same name. In general, this is OK because of:
- [dcl.typedef]
+ [dcl.typedef]
In a given scope, a typedef specifier can be used to redefine
the name of any type declared in that scope to refer to the
- type to which it already refers.
+ type to which it already refers.
However, in class scopes, this rule does not apply due to the
stricter language in [class.mem] prohibiting redeclarations of
&& DECL_EXTERNAL (decl) && DECL_EXTERNAL (bval)
&& !DECL_CLASS_SCOPE_P (decl))
{
- duplicate_decls (decl, binding->value);
+ duplicate_decls (decl, binding->value, /*newdecl_is_friend=*/false);
ok = false;
}
else if (TREE_CODE (decl) == NAMESPACE_DECL
&& DECL_NAMESPACE_ALIAS (bval)
&& ORIGINAL_NAMESPACE (bval) == ORIGINAL_NAMESPACE (decl))
/* [namespace.alias]
-
+
In a declarative region, a namespace-alias-definition can be
used to redefine a namespace-alias declared in that declarative
region to refer only to the namespace to which it already
else
{
error ("declaration of %q#D", decl);
- cp_error_at ("conflicts with previous declaration %q#D", bval);
+ error ("conflicts with previous declaration %q+#D", bval);
ok = false;
}
static void
add_decl_to_level (tree decl, cxx_scope *b)
{
- if (TREE_CODE (decl) == NAMESPACE_DECL
+ /* We used to record virtual tables as if they were ordinary
+ variables, but no longer do so. */
+ gcc_assert (!(TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl)));
+
+ if (TREE_CODE (decl) == NAMESPACE_DECL
&& !DECL_NAMESPACE_ALIAS (decl))
{
TREE_CHAIN (decl) = b->namespaces;
b->namespaces = decl;
}
- else if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
- {
- TREE_CHAIN (decl) = b->vtables;
- b->vtables = decl;
- }
- else
+ else
{
/* We build up the list in reverse order, and reverse it later if
- necessary. */
+ necessary. */
TREE_CHAIN (decl) = b->names;
b->names = decl;
b->names_size++;
/* If appropriate, add decl to separate list of statics. We
- include extern variables because they might turn out to be
+ include extern variables because they might turn out to be
static later. It's OK for this list to contain a few false
positives. */
if (b->kind == sk_namespace)
/* Record a decl-node X as belonging to the current lexical scope.
Check for errors (such as an incompatible declaration for the same
- name already seen in the same scope).
+ name already seen in the same scope). IS_FRIEND is true if X is
+ declared as a friend.
Returns either X or an old decl for the same name.
If an old decl is returned, it may have been smashed
to agree with what X says. */
tree
-pushdecl (tree x)
+pushdecl_maybe_friend (tree x, bool is_friend)
{
tree t;
tree name;
timevar_push (TV_NAME_LOOKUP);
+ if (x == error_mark_node)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+
need_new_binding = 1;
if (DECL_TEMPLATE_PARM_P (x))
{
if (current_function_decl && x != current_function_decl
/* A local declaration for a function doesn't constitute
- nesting. */
+ nesting. */
&& TREE_CODE (x) != FUNCTION_DECL
/* A local declaration for an `extern' variable is in the
scope of the current namespace, not the current
if (decls_match (x, t))
/* The standard only says that the local extern
inherits linkage from the previous decl; in
- particular, default args are not shared. We must
- also tell cgraph to treat these decls as the same,
- or we may neglect to emit an "unused" static - we
- do this by making the DECL_UIDs equal, which should
- be viewed as a kludge. FIXME. */
+ particular, default args are not shared. Add
+ the decl into a hash table to make sure only
+ the previous decl in this case is seen by the
+ middle end. */
{
+ struct cxx_int_tree_map *h;
+ void **loc;
+
TREE_PUBLIC (x) = TREE_PUBLIC (t);
- DECL_UID (x) = DECL_UID (t);
+
+ if (cp_function_chain->extern_decl_map == NULL)
+ cp_function_chain->extern_decl_map
+ = htab_create_ggc (20, cxx_int_tree_map_hash,
+ cxx_int_tree_map_eq, NULL);
+
+ h = GGC_NEW (struct cxx_int_tree_map);
+ h->uid = DECL_UID (x);
+ h->to = t;
+ loc = htab_find_slot_with_hash
+ (cp_function_chain->extern_decl_map, h,
+ h->uid, INSERT);
+ *(struct cxx_int_tree_map **) loc = h;
}
}
else if (TREE_CODE (t) == PARM_DECL)
gcc_assert (DECL_CONTEXT (t));
/* Check for duplicate params. */
- if (duplicate_decls (x, t))
+ if (duplicate_decls (x, t, is_friend))
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
else if ((DECL_EXTERN_C_FUNCTION_P (x)
{
if (pedantic && ! DECL_IN_SYSTEM_HEADER (x))
pedwarn ("redeclaration of %<wchar_t%> as %qT",
- TREE_TYPE (x));
+ TREE_TYPE (x));
/* Throw away the redeclaration. */
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
else
{
- tree olddecl = duplicate_decls (x, t);
-
+ tree olddecl = duplicate_decls (x, t, is_friend);
+
/* If the redeclaration failed, we can stop at this
point. */
if (olddecl == error_mark_node)
{
if (TREE_CODE (t) == TYPE_DECL)
SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
- else if (TREE_CODE (t) == FUNCTION_DECL)
- check_default_args (t);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
{
/* A redeclaration of main, but not a duplicate of the
previous one.
-
+
[basic.start.main]
-
+
This function shall not be overloaded. */
- cp_error_at ("invalid redeclaration of %qD", t);
+ error ("invalid redeclaration of %q+D", t);
error ("as %qD", x);
/* We don't try to push this declaration since that
causes a crash. */
}
}
+ if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))
+ check_default_args (x);
+
check_template_shadow (x);
- /* If this is a function conjured up by the backend, massage it
+ /* If this is a function conjured up by the back end, massage it
so it looks friendly. */
if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_LANG_SPECIFIC (x))
{
if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_FUNCTION_MEMBER_P (x))
{
- t = push_overloaded_decl (x, PUSH_LOCAL);
+ t = push_overloaded_decl (x, PUSH_LOCAL, is_friend);
if (t != x)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
if (!namespace_bindings_p ())
}
else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x))
{
- t = push_overloaded_decl (x, PUSH_GLOBAL);
+ t = push_overloaded_decl (x, PUSH_GLOBAL, is_friend);
if (t == x)
add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t)));
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
{
tree type = TREE_TYPE (x);
if (DECL_IS_BUILTIN (x))
- {
+ {
if (TYPE_NAME (type) == 0)
- TYPE_NAME (type) = x;
- }
- else if (type != error_mark_node && TYPE_NAME (type) != x
+ TYPE_NAME (type) = x;
+ }
+ else if (type != error_mark_node && TYPE_NAME (type) != x
/* We don't want to copy the type when all we're
doing is making a TYPE_DECL for the purposes of
inlining. */
&& (!TYPE_NAME (type)
|| TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x)))
- {
+ {
DECL_ORIGINAL_TYPE (x) = type;
- type = build_variant_type_copy (type);
+ type = build_variant_type_copy (type);
TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
- TYPE_NAME (type) = x;
- TREE_TYPE (x) = type;
- }
+ TYPE_NAME (type) = x;
+ TREE_TYPE (x) = type;
+ }
if (type != error_mark_node
&& TYPE_NAME (type)
&& TYPE_IDENTIFIER (type))
- set_identifier_type_value (DECL_NAME (x), x);
+ set_identifier_type_value (DECL_NAME (x), x);
}
/* Multiple external decls of the same identifier ought to match.
&& !same_type_p (TREE_TYPE (x), TREE_TYPE (decl)))
{
pedwarn ("type mismatch with previous external decl of %q#D", x);
- cp_pedwarn_at ("previous external decl of %q#D", decl);
+ pedwarn ("previous external decl of %q+#D", decl);
}
}
+ if (TREE_CODE (x) == FUNCTION_DECL
+ && is_friend
+ && !flag_friend_injection)
+ {
+ /* This is a new declaration of a friend function, so hide
+ it from ordinary function lookup. */
+ DECL_ANTICIPATED (x) = 1;
+ DECL_HIDDEN_FRIEND_P (x) = 1;
+ }
+
/* This name is new in its binding level.
Install the new declaration and return it. */
if (namespace_bindings_p ())
if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
TREE_PUBLIC (name) = 1;
- /* Bind the name for the entity. */
- if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
- && t != NULL_TREE)
- && (TREE_CODE (x) == TYPE_DECL
- || TREE_CODE (x) == VAR_DECL
- || TREE_CODE (x) == ALIAS_DECL
- || TREE_CODE (x) == NAMESPACE_DECL
- || TREE_CODE (x) == CONST_DECL
- || TREE_CODE (x) == TEMPLATE_DECL))
- SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
+ /* Bind the name for the entity. */
+ if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
+ && t != NULL_TREE)
+ && (TREE_CODE (x) == TYPE_DECL
+ || TREE_CODE (x) == VAR_DECL
+ || TREE_CODE (x) == NAMESPACE_DECL
+ || TREE_CODE (x) == CONST_DECL
+ || TREE_CODE (x) == TEMPLATE_DECL))
+ SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
/* If new decl is `static' and an `extern' was seen previously,
warn about it. */
else
{
warning (0, "extern declaration of %q#D doesn't match", x);
- cp_warning_at ("global declaration %q#D", oldglobal);
+ warning (0, "global declaration %q+#D", oldglobal);
}
}
/* If we have a local external declaration,
them there. */
struct cp_binding_level *b = current_binding_level->level_chain;
- /* Skip the ctor/dtor cleanup level. */
- b = b->level_chain;
+ if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
+ /* Skip the ctor/dtor cleanup level. */
+ b = b->level_chain;
/* ARM $8.3 */
if (b->kind == sk_function_parms)
if (warn_shadow && !err)
{
- warning (0, "declaration of %q#D shadows a parameter", x);
- warning (0, "%Jshadowed declaration is here", oldlocal);
+ warning (OPT_Wshadow, "declaration of %q#D shadows a parameter", x);
+ warning (OPT_Wshadow, "%Jshadowed declaration is here", oldlocal);
}
}
/*want_type=*/false);
else
member = NULL_TREE;
-
+
if (member && !TREE_STATIC (member))
{
/* Location of previous decl is not useful in this case. */
- warning (0, "declaration of %qD shadows a member of 'this'",
+ warning (OPT_Wshadow, "declaration of %qD shadows a member of 'this'",
x);
}
else if (oldlocal != NULL_TREE
&& TREE_CODE (oldlocal) == VAR_DECL)
{
- warning (0, "declaration of %qD shadows a previous local", x);
- warning (0, "%Jshadowed declaration is here", oldlocal);
+ warning (OPT_Wshadow, "declaration of %qD shadows a previous local", x);
+ warning (OPT_Wshadow, "%Jshadowed declaration is here", oldlocal);
}
else if (oldglobal != NULL_TREE
&& TREE_CODE (oldglobal) == VAR_DECL)
/* XXX shadow warnings in outer-more namespaces */
{
- warning (0, "declaration of %qD shadows a global declaration",
+ warning (OPT_Wshadow, "declaration of %qD shadows a global declaration",
x);
- warning (0, "%Jshadowed declaration is here", oldglobal);
+ warning (OPT_Wshadow, "%Jshadowed declaration is here", oldglobal);
}
}
}
- if (TREE_CODE (x) == FUNCTION_DECL)
- check_default_args (x);
-
if (TREE_CODE (x) == VAR_DECL)
maybe_register_incomplete_var (x);
}
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
}
+/* Record a decl-node X as belonging to the current lexical scope. */
+
+tree
+pushdecl (tree x)
+{
+ return pushdecl_maybe_friend (x, false);
+}
+
/* Enter DECL into the symbol table, if that's appropriate. Returns
DECL, or a modified version thereof. */
if (!(TREE_CODE (decl) == VAR_DECL && DECL_DEAD_FOR_LOCAL (decl)))
return decl;
- shadowed = DECL_SHADOWED_FOR_VAR (decl);
+ shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (decl)
+ ? DECL_SHADOWED_FOR_VAR (decl) : NULL_TREE ;
while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
&& DECL_DEAD_FOR_LOCAL (shadowed))
- shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
+ shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (shadowed)
+ ? DECL_SHADOWED_FOR_VAR (shadowed) : NULL_TREE;
if (!shadowed)
shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (decl));
if (shadowed)
if (!DECL_ERROR_REPORTED (decl))
{
warning (0, "name lookup of %qD changed", DECL_NAME (decl));
- cp_warning_at (" matches this %qD under ISO standard rules",
- shadowed);
- cp_warning_at (" matches this %qD under old rules", decl);
+ warning (0, " matches this %q+D under ISO standard rules",
+ shadowed);
+ warning (0, " matches this %q+D under old rules", decl);
DECL_ERROR_REPORTED (decl) = 1;
}
return shadowed;
{
error ("name lookup of %qD changed for new ISO %<for%> scoping",
DECL_NAME (decl));
- cp_error_at (" cannot use obsolete binding at %qD because "
- "it has a destructor", decl);
+ error (" cannot use obsolete binding at %q+D because "
+ "it has a destructor", decl);
return error_mark_node;
}
else
{
pedwarn ("name lookup of %qD changed for new ISO %<for%> scoping",
DECL_NAME (decl));
- cp_pedwarn_at (" using obsolete binding at %qD", decl);
+ pedwarn (" using obsolete binding at %q+D", decl);
}
return decl;
const char *desc = cxx_scope_descriptor (scope);
if (scope->this_entity)
verbatim ("%s %s(%E) %p %d\n", action, desc,
- scope->this_entity, (void *) scope, line);
+ scope->this_entity, (void *) scope, line);
else
verbatim ("%s %s %p %d\n", action, desc, (void *) scope, line);
}
begin_scope (scope_kind kind, tree entity)
{
cxx_scope *scope;
-
+
/* Reuse or create a struct for this binding level. */
if (!ENABLE_SCOPE_CHECKING && free_binding_level)
{
scope = free_binding_level;
+ memset (scope, 0, sizeof (cxx_scope));
free_binding_level = scope->level_chain;
}
else
- scope = GGC_NEW (cxx_scope);
- memset (scope, 0, sizeof (cxx_scope));
+ scope = GGC_CNEW (cxx_scope);
scope->this_entity = entity;
scope->more_cleanups_ok = true;
case sk_cleanup:
scope->keep = true;
break;
-
+
case sk_template_spec:
scope->explicit_spec_p = true;
kind = sk_template_parms;
case sk_for:
case sk_class:
case sk_function_parms:
+ case sk_omp:
scope->keep = keep_next_level_flag;
break;
/* We cannot leave a scope, if there are none left. */
if (NAMESPACE_LEVEL (global_namespace))
gcc_assert (!global_scope_p (scope));
-
+
if (ENABLE_SCOPE_CHECKING)
{
indent (--binding_depth);
cxx_scope_debug (scope, input_line, "leave");
if (is_class_level != (scope == class_binding_level))
- {
- indent (binding_depth);
- verbatim ("XXX is_class_level != (current_scope == class_scope)\n");
- }
+ {
+ indent (binding_depth);
+ verbatim ("XXX is_class_level != (current_scope == class_scope)\n");
+ }
is_class_level = 0;
}
current_binding_level = scope->level_chain;
/* Namespace-scopes are left most probably temporarily, not
- completely; they can be reopen later, e.g. in namespace-extension
+ completely; they can be reopened later, e.g. in namespace-extension
or any name binding activity that requires us to resume a
namespace. For classes, we cache some binding levels. For other
scopes, we just make the structure available for reuse. */
{
return (current_binding_level->blocks != NULL_TREE
|| current_binding_level->keep
- || current_binding_level->kind == sk_cleanup
+ || current_binding_level->kind == sk_cleanup
|| current_binding_level->names != NULL_TREE);
}
{
tree t;
int i = 0, len;
- fprintf (stderr, " blocks=" HOST_PTR_PRINTF, (void *) lvl->blocks);
+ fprintf (stderr, " blocks=%p", (void *) lvl->blocks);
if (lvl->more_cleanups_ok)
fprintf (stderr, " more-cleanups-ok");
if (lvl->have_cleanups)
break;
}
if (i)
- fprintf (stderr, "\n");
+ fprintf (stderr, "\n");
}
if (VEC_length (cp_class_binding, lvl->class_shadowed))
{
size_t i;
cp_class_binding *b;
fprintf (stderr, " class-shadowed:");
- for (i = 0;
+ for (i = 0;
VEC_iterate(cp_class_binding, lvl->class_shadowed, i, b);
- ++i)
+ ++i)
fprintf (stderr, " %s ", IDENTIFIER_POINTER (b->identifier));
fprintf (stderr, "\n");
}
{
fprintf (stderr, " type-shadowed:");
for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t))
- {
+ {
fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
- }
+ }
fprintf (stderr, "\n");
}
}
struct cp_binding_level *level;
for (level = stack; !global_scope_p (level); level = level->level_chain)
{
- fprintf (stderr, "binding level " HOST_PTR_PRINTF "\n", (void *) level);
+ fprintf (stderr, "binding level %p\n", (void *) level);
print_binding_level (level);
}
}
print_binding_stack (void)
{
struct cp_binding_level *b;
- fprintf (stderr, "current_binding_level=" HOST_PTR_PRINTF
- "\nclass_binding_level=" HOST_PTR_PRINTF
- "\nNAMESPACE_LEVEL (global_namespace)=" HOST_PTR_PRINTF "\n",
+ fprintf (stderr, "current_binding_level=%p\n"
+ "class_binding_level=%p\n"
+ "NAMESPACE_LEVEL (global_namespace)=%p\n",
(void *) current_binding_level, (void *) class_binding_level,
- (void *) NAMESPACE_LEVEL (global_namespace));
+ (void *) NAMESPACE_LEVEL (global_namespace));
if (class_binding_level)
{
for (b = class_binding_level; b; b = b->level_chain)
supplement_binding (binding, decl);
else
binding->value = decl;
-
+
/* Store marker instead of real type. */
type = global_type_node;
}
return name;
}
-/* Returns TRUE if NAME is the name for the constructor for TYPE. */
+/* Returns TRUE if NAME is the name for the constructor for TYPE,
+ which must be a class type. */
bool
constructor_name_p (tree name, tree type)
{
tree ctor_name;
+ gcc_assert (IS_AGGR_TYPE (type));
+
if (!name)
return false;
-
+
if (TREE_CODE (name) != IDENTIFIER_NODE)
return false;
-
+
ctor_name = constructor_name_full (type);
if (name == ctor_name)
return true;
return get_identifier (buf);
}
-/* Return (from the stack of) the BINDING, if any, established at SCOPE. */
+/* Return (from the stack of) the BINDING, if any, established at SCOPE. */
static inline cxx_binding *
find_binding (cxx_scope *scope, cxx_binding *binding)
{
/* Fold-in case where NAME is used only once. */
if (scope == b->scope && b->previous == NULL)
- return b;
+ return b;
return find_binding (scope, b);
}
return NULL;
return NULL_TREE if this not in namespace scope (in namespace
scope, a using decl might extend any previous bindings). */
-tree
+static tree
push_using_decl (tree scope, tree name)
{
tree decl;
gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL);
gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
- if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name)
+ if (USING_DECL_SCOPE (decl) == scope && DECL_NAME (decl) == name)
break;
if (decl)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
- namespace_bindings_p () ? decl : NULL_TREE);
- decl = build_lang_decl (USING_DECL, name, void_type_node);
- DECL_INITIAL (decl) = scope;
+ namespace_bindings_p () ? decl : NULL_TREE);
+ decl = build_lang_decl (USING_DECL, name, NULL_TREE);
+ USING_DECL_SCOPE (decl) = scope;
TREE_CHAIN (decl) = current_binding_level->usings;
current_binding_level->usings = decl;
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
caller to set DECL_CONTEXT properly. */
tree
-pushdecl_with_scope (tree x, cxx_scope *level)
+pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend)
{
struct cp_binding_level *b;
tree function_decl = current_function_decl;
{
b = current_binding_level;
current_binding_level = level;
- x = pushdecl (x);
+ x = pushdecl_maybe_friend (x, is_friend);
current_binding_level = b;
}
current_function_decl = function_decl;
FLAGS is a bitwise-or of the following values:
PUSH_LOCAL: Bind DECL in the current scope, rather than at
- namespace scope.
+ namespace scope.
PUSH_USING: DECL is being pushed as the result of a using
- declaration.
+ declaration.
+
+ IS_FRIEND is true if this is a friend declaration.
The value returned may be a previous declaration if we guessed wrong
about what language DECL should belong to (C or C++). Otherwise,
it's always DECL (and never something that's not a _DECL). */
static tree
-push_overloaded_decl (tree decl, int flags)
+push_overloaded_decl (tree decl, int flags, bool is_friend)
{
tree name = DECL_NAME (decl);
tree old;
old = NULL_TREE;
}
else if (is_overloaded_fn (old))
- {
- tree tmp;
+ {
+ tree tmp;
for (tmp = old; tmp; tmp = OVL_NEXT (tmp))
{
tree fn = OVL_CURRENT (tmp);
+ tree dup;
if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
&& !(flags & PUSH_USING)
TYPE_ARG_TYPES (TREE_TYPE (decl)))
&& ! decls_match (fn, decl))
error ("%q#D conflicts with previous using declaration %q#D",
- decl, fn);
+ decl, fn);
- if (duplicate_decls (decl, fn) == fn)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fn);
+ dup = duplicate_decls (decl, fn, is_friend);
+ /* If DECL was a redeclaration of FN -- even an invalid
+ one -- pass that information along to our caller. */
+ if (dup == fn || dup == error_mark_node)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, dup);
}
/* We don't overload implicit built-ins. duplicate_decls()
may fail to merge the decls if the new decl is e.g. a
template function. */
if (TREE_CODE (old) == FUNCTION_DECL
- && DECL_ANTICIPATED (old))
+ && DECL_ANTICIPATED (old)
+ && !DECL_HIDDEN_FRIEND_P (old))
old = NULL;
}
else if (old == error_mark_node)
old = NULL_TREE;
else
{
- cp_error_at ("previous non-function declaration %q#D", old);
+ error ("previous non-function declaration %q+#D", old);
error ("conflicts with function declaration %q#D", decl);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
}
/* 7.3.3/5
A using-declaration shall not name a template-id. */
error ("a using-declaration cannot specify a template-id. "
- "Try %<using %D%>", name);
+ "Try %<using %D%>", name);
return NULL_TREE;
}
static void
do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
- tree *newval, tree *newtype)
+ tree *newval, tree *newtype)
{
struct scope_binding decls = EMPTY_SCOPE_BINDING;
return;
}
+ /* Shift the old and new bindings around so we're comparing class and
+ enumeration names to each other. */
+ if (oldval && DECL_IMPLICIT_TYPEDEF_P (oldval))
+ {
+ oldtype = oldval;
+ oldval = NULL_TREE;
+ }
+
+ if (decls.value && DECL_IMPLICIT_TYPEDEF_P (decls.value))
+ {
+ decls.type = decls.value;
+ decls.value = NULL_TREE;
+ }
+
/* It is impossible to overload a built-in function; any explicit
declaration eliminates the built-in declaration. So, if OLDVAL
is a built-in, then we can just pretend it isn't there. */
- if (oldval
+ if (oldval
&& TREE_CODE (oldval) == FUNCTION_DECL
- && DECL_ANTICIPATED (oldval))
+ && DECL_ANTICIPATED (oldval)
+ && !DECL_HIDDEN_FRIEND_P (oldval))
oldval = NULL_TREE;
- /* Check for using functions. */
- if (decls.value && is_overloaded_fn (decls.value))
+ if (decls.value)
{
- tree tmp, tmp1;
-
- if (oldval && !is_overloaded_fn (oldval))
+ /* Check for using functions. */
+ if (is_overloaded_fn (decls.value))
{
- if (!DECL_IMPLICIT_TYPEDEF_P (oldval))
- error ("%qD is already declared in this scope", name);
- oldval = NULL_TREE;
- }
+ tree tmp, tmp1;
- *newval = oldval;
- for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
- {
- tree new_fn = OVL_CURRENT (tmp);
-
- /* [namespace.udecl]
+ if (oldval && !is_overloaded_fn (oldval))
+ {
+ error ("%qD is already declared in this scope", name);
+ oldval = NULL_TREE;
+ }
- If a function declaration in namespace scope or block
- scope has the same name and the same parameter types as a
- function introduced by a using declaration the program is
- ill-formed. */
- for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
+ *newval = oldval;
+ for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
{
- tree old_fn = OVL_CURRENT (tmp1);
-
- if (new_fn == old_fn)
- /* The function already exists in the current namespace. */
- break;
- else if (OVL_USED (tmp1))
- continue; /* this is a using decl */
- else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
- TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+ tree new_fn = OVL_CURRENT (tmp);
+
+ /* [namespace.udecl]
+
+ If a function declaration in namespace scope or block
+ scope has the same name and the same parameter types as a
+ function introduced by a using declaration the program is
+ ill-formed. */
+ for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
{
- gcc_assert (!DECL_ANTICIPATED (old_fn));
+ tree old_fn = OVL_CURRENT (tmp1);
- /* There was already a non-using declaration in
- this scope with the same parameter types. If both
- are the same extern "C" functions, that's ok. */
- if (decls_match (new_fn, old_fn))
+ if (new_fn == old_fn)
+ /* The function already exists in the current namespace. */
break;
- else
- {
- error ("%qD is already declared in this scope", name);
- break;
+ else if (OVL_USED (tmp1))
+ continue; /* this is a using decl */
+ else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
+ TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+ {
+ gcc_assert (!DECL_ANTICIPATED (old_fn)
+ || DECL_HIDDEN_FRIEND_P (old_fn));
+
+ /* There was already a non-using declaration in
+ this scope with the same parameter types. If both
+ are the same extern "C" functions, that's ok. */
+ if (decls_match (new_fn, old_fn))
+ break;
+ else
+ {
+ error ("%qD is already declared in this scope", name);
+ break;
+ }
}
}
- }
- /* If we broke out of the loop, there's no reason to add
- this function to the using declarations for this
- scope. */
- if (tmp1)
- continue;
-
- /* If we are adding to an existing OVERLOAD, then we no
- longer know the type of the set of functions. */
- if (*newval && TREE_CODE (*newval) == OVERLOAD)
- TREE_TYPE (*newval) = unknown_type_node;
- /* Add this new function to the set. */
- *newval = build_overload (OVL_CURRENT (tmp), *newval);
- /* If there is only one function, then we use its type. (A
- using-declaration naming a single function can be used in
- contexts where overload resolution cannot be
- performed.) */
- if (TREE_CODE (*newval) != OVERLOAD)
- {
- *newval = ovl_cons (*newval, NULL_TREE);
- TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
+ /* If we broke out of the loop, there's no reason to add
+ this function to the using declarations for this
+ scope. */
+ if (tmp1)
+ continue;
+
+ /* If we are adding to an existing OVERLOAD, then we no
+ longer know the type of the set of functions. */
+ if (*newval && TREE_CODE (*newval) == OVERLOAD)
+ TREE_TYPE (*newval) = unknown_type_node;
+ /* Add this new function to the set. */
+ *newval = build_overload (OVL_CURRENT (tmp), *newval);
+ /* If there is only one function, then we use its type. (A
+ using-declaration naming a single function can be used in
+ contexts where overload resolution cannot be
+ performed.) */
+ if (TREE_CODE (*newval) != OVERLOAD)
+ {
+ *newval = ovl_cons (*newval, NULL_TREE);
+ TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
+ }
+ OVL_USED (*newval) = 1;
}
- OVL_USED (*newval) = 1;
+ }
+ else
+ {
+ *newval = decls.value;
+ if (oldval && !decls_match (*newval, oldval))
+ error ("%qD is already declared in this scope", name);
}
}
- else
+ else
+ *newval = oldval;
+
+ if (decls.type && TREE_CODE (decls.type) == TREE_LIST)
{
- *newval = decls.value;
- if (oldval && !decls_match (*newval, oldval))
- error ("%qD is already declared in this scope", name);
+ error ("reference to %qD is ambiguous", name);
+ print_candidates (decls.type);
}
-
- *newtype = decls.type;
- if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
+ else
{
- error ("using declaration %qD introduced ambiguous type %qT",
- name, oldtype);
- return;
+ *newtype = decls.type;
+ if (oldtype && *newtype && !decls_match (oldtype, *newtype))
+ error ("%qD is already declared in this scope", name);
}
+
+ /* If *newval is empty, shift any class or enumeration name down. */
+ if (!*newval)
+ {
+ *newval = *newtype;
+ *newtype = NULL_TREE;
+ }
}
/* Process a using-declaration at function scope. */
term = OVL_FUNCTION (oldval);
else
term = oldval;
- for (fn = newval; fn && OVL_CURRENT (fn) != term;
+ for (fn = newval; fn && OVL_CURRENT (fn) != term;
fn = OVL_NEXT (fn))
- push_overloaded_decl (OVL_CURRENT (fn),
- PUSH_LOCAL | PUSH_USING);
+ push_overloaded_decl (OVL_CURRENT (fn),
+ PUSH_LOCAL | PUSH_USING,
+ false);
}
else
push_local_binding (name, newval, PUSH_USING);
|| CLASS_TYPE_P (root)));
gcc_assert ((TREE_CODE (child) == NAMESPACE_DECL
|| CLASS_TYPE_P (child)));
-
+
/* The global namespace encloses everything. */
if (root == global_namespace)
return true;
pushing name into scope. In case a template parameter scope is present,
namespace is pushed under the template parameter scope according to
name lookup rule in 14.6.1/6.
-
+
Return the former current scope suitable for pop_inner_scope. */
tree
;
else if (value_binding)
{
- if (TREE_CODE (value_binding) == TREE_LIST
+ if (TREE_CODE (value_binding) == TREE_LIST
&& TREE_TYPE (value_binding) == error_mark_node)
/* NAME is ambiguous. */
;
new binding object. */
if (type_binding || value_binding)
{
- binding = new_class_binding (name,
- value_binding,
+ binding = new_class_binding (name,
+ value_binding,
type_binding,
scope);
/* This is a class-scope binding, not a block-scope binding. */
return binding;
}
-
+
/* Make the declaration(s) of X appear in CLASS scope under the name
NAME. Returns true if the binding is valid. */
if (!class_binding_level)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+ if (name == error_mark_node)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
+
/* Check for invalid member names. */
gcc_assert (TYPE_BEING_DEFINED (current_class_type));
/* We could have been passed a tree list if this is an ambiguous
declaration. If so, pull the declaration out because
check_template_shadow will not handle a TREE_LIST. */
- if (TREE_CODE (decl) == TREE_LIST
+ if (TREE_CODE (decl) == TREE_LIST
&& TREE_TYPE (decl) == error_mark_node)
decl = TREE_VALUE (decl);
if (INHERITED_VALUE_BINDING_P (binding))
{
/* If the old binding was from a base class, and was for a
- tag name, slide it over to make room for the new binding.
- The old binding is still visible if explicitly qualified
- with a class-key. */
+ tag name, slide it over to make room for the new binding.
+ The old binding is still visible if explicitly qualified
+ with a class-key. */
if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
&& !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
{
INHERITED_VALUE_BINDING_P (binding) = 0;
}
else
- old_decl = bval;
+ {
+ old_decl = bval;
+ /* Any inherited type declaration is hidden by the type
+ declaration in the derived class. */
+ if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))
+ binding->type = NULL_TREE;
+ }
}
else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval))
old_decl = bval;
tree
do_class_using_decl (tree scope, tree name)
{
- tree value, type;
-
+ /* The USING_DECL returned by this function. */
+ tree value;
+ /* The declaration (or declarations) name by this using
+ declaration. NULL if we are in a template and cannot figure out
+ what has been named. */
+ tree decl;
+ /* True if SCOPE is a dependent type. */
+ bool scope_dependent_p;
+ /* True if SCOPE::NAME is dependent. */
+ bool name_dependent_p;
+ /* True if any of the bases of CURRENT_CLASS_TYPE are dependent. */
+ bool bases_dependent_p;
+ tree binfo;
+ tree base_binfo;
+ int i;
+
+ if (name == error_mark_node)
+ return NULL_TREE;
+
if (!scope || !TYPE_P (scope))
{
error ("using-declaration for non-member at class scope");
return NULL_TREE;
}
+
+ /* Make sure the name is not invalid */
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
- error ("using-declaration cannot name destructor");
+ error ("%<%T::%D%> names destructor", scope, name);
+ return NULL_TREE;
+ }
+ if (IS_AGGR_TYPE (scope) && constructor_name_p (name, scope))
+ {
+ error ("%<%T::%D%> names constructor", scope, name);
+ return NULL_TREE;
+ }
+ if (constructor_name_p (name, current_class_type))
+ {
+ error ("%<%T::%D%> names constructor in %qT",
+ scope, name, current_class_type);
return NULL_TREE;
}
- gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
+ scope_dependent_p = dependent_type_p (scope);
+ name_dependent_p = (scope_dependent_p
+ || (IDENTIFIER_TYPENAME_P (name)
+ && dependent_type_p (TREE_TYPE (name))));
+
+ bases_dependent_p = false;
+ if (processing_template_decl)
+ for (binfo = TYPE_BINFO (current_class_type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo);
+ i++)
+ if (dependent_type_p (TREE_TYPE (base_binfo)))
+ {
+ bases_dependent_p = true;
+ break;
+ }
+
+ decl = NULL_TREE;
- /* Dependent using decls have a NULL type, non-dependent ones have a
- void type. */
- type = dependent_type_p (scope) ? NULL_TREE : void_type_node;
- value = build_lang_decl (USING_DECL, name, type);
- DECL_INITIAL (value) = scope;
+ /* From [namespace.udecl]:
- if (scope && !processing_template_decl)
+ A using-declaration used as a member-declaration shall refer to a
+ member of a base class of the class being defined.
+
+ In general, we cannot check this constraint in a template because
+ we do not know the entire set of base classes of the current
+ class type. However, if all of the base classes are
+ non-dependent, then we can avoid delaying the check until
+ instantiation. */
+ if (!scope_dependent_p)
{
- tree r;
+ base_kind b_kind;
+ binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
+ if (b_kind < bk_proper_base)
+ {
+ if (!bases_dependent_p)
+ {
+ error_not_base_type (scope, current_class_type);
+ return NULL_TREE;
+ }
+ }
+ else if (!name_dependent_p)
+ {
+ decl = lookup_member (binfo, name, 0, false);
+ if (!decl)
+ {
+ error ("no members matching %<%T::%D%> in %q#T", scope, name,
+ scope);
+ return NULL_TREE;
+ }
+ /* The binfo from which the functions came does not matter. */
+ if (BASELINK_P (decl))
+ decl = BASELINK_FUNCTIONS (decl);
+ }
+ }
+
+ value = build_lang_decl (USING_DECL, name, NULL_TREE);
+ USING_DECL_DECLS (value) = decl;
+ USING_DECL_SCOPE (value) = scope;
+ DECL_DEPENDENT_P (value) = !decl;
- r = lookup_qualified_name (scope, name, false, false);
- if (r && (DECL_P (r) || TREE_CODE (r) == OVERLOAD))
- cp_emit_debug_info_for_using (r, scope);
- }
return value;
}
void
set_decl_namespace (tree decl, tree scope, bool friendp)
{
- tree old;
-
+ tree old, fn;
+
/* Get rid of namespace aliases. */
scope = ORIGINAL_NAMESPACE (scope);
-
+
/* It is ok for friends to be qualified in parallel space. */
if (!friendp && !is_ancestor (current_namespace, scope))
error ("declaration of %qD not in a namespace surrounding %qD",
- decl, scope);
+ decl, scope);
DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
- /* Writing "int N::i" to declare a variable within "N" is invalid. */
- if (scope == current_namespace)
+ /* Writing "int N::i" to declare a variable within "N" is invalid. */
+ if (scope == current_namespace)
{
if (at_namespace_scope_p ())
- error ("explicit qualification in declaration of `%D'",
+ error ("explicit qualification in declaration of %qD",
decl);
return;
}
/* See whether this has been declared in the namespace. */
- old = namespace_binding (DECL_NAME (decl), scope);
- if (!old)
+ old = lookup_qualified_name (scope, DECL_NAME (decl), false, true);
+ if (old == error_mark_node)
/* No old declaration at all. */
goto complain;
- /* A template can be explicitly specialized in any namespace. */
- if (processing_explicit_instantiation)
- return;
if (!is_overloaded_fn (decl))
/* Don't compare non-function decls with decls_match here, since
it can't check for the correct constness at this
/* Since decl is a function, old should contain a function decl. */
if (!is_overloaded_fn (old))
goto complain;
+ fn = OVL_CURRENT (old);
+ if (!is_associated_namespace (scope, CP_DECL_CONTEXT (fn)))
+ goto complain;
+ /* A template can be explicitly specialized in any namespace. */
+ if (processing_explicit_instantiation)
+ return;
if (processing_template_decl || processing_specialization)
/* We have not yet called push_template_decl to turn a
FUNCTION_DECL into a TEMPLATE_DECL, so the declarations won't
match. But, we'll check later, when we construct the
template. */
return;
+ /* Instantiations or specializations of templates may be declared as
+ friends in any namespace. */
+ if (friendp && DECL_USE_TEMPLATE (decl))
+ return;
if (is_overloaded_fn (old))
{
for (; old; old = OVL_NEXT (old))
return;
complain:
error ("%qD should have been declared inside %qD", decl, scope);
-}
+}
/* Return the namespace where the current declaration is declared. */
result = decl_namespace_context (current_class_type);
else if (current_function_decl)
result = decl_namespace_context (current_function_decl);
- else
+ else
result = current_namespace;
return result;
}
+/* Process any ATTRIBUTES on a namespace definition. Currently only
+ attribute visibility is meaningful, which is a property of the syntactic
+ block rather than the namespace as a whole, so we don't touch the
+ NAMESPACE_DECL at all. Returns true if attribute visibility is seen. */
+
+bool
+handle_namespace_attrs (tree ns, tree attributes)
+{
+ tree d;
+ bool saw_vis = false;
+
+ for (d = attributes; d; d = TREE_CHAIN (d))
+ {
+ tree name = TREE_PURPOSE (d);
+ tree args = TREE_VALUE (d);
+
+#ifdef HANDLE_PRAGMA_VISIBILITY
+ if (is_attribute_p ("visibility", name))
+ {
+ tree x = args ? TREE_VALUE (args) : NULL_TREE;
+ if (x == NULL_TREE || TREE_CODE (x) != STRING_CST || TREE_CHAIN (args))
+ {
+ warning (OPT_Wattributes,
+ "%qD attribute requires a single NTBS argument",
+ name);
+ continue;
+ }
+
+ if (!TREE_PUBLIC (ns))
+ warning (OPT_Wattributes,
+ "%qD attribute is meaningless since members of the "
+ "anonymous namespace get local symbols", name);
+
+ push_visibility (TREE_STRING_POINTER (x));
+ saw_vis = true;
+ }
+ else
+#endif
+ {
+ warning (OPT_Wattributes, "%qD attribute directive ignored",
+ name);
+ continue;
+ }
+ }
+
+ return saw_vis;
+}
+
/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we
select a name that is unique to this compilation unit. */
bool anon = !name;
timevar_push (TV_NAME_LOOKUP);
-
+
/* We should not get here if the global_namespace is not yet constructed
nor if NAME designates the global namespace: The global scope is
constructed elsewhere. */
if (anon)
{
- /* The name of anonymous namespace is unique for the translation
- unit. */
- if (!anonymous_namespace_name)
- anonymous_namespace_name = get_file_function_name ('N');
- name = anonymous_namespace_name;
+ name = get_anonymous_namespace_name();
d = IDENTIFIER_NAMESPACE_VALUE (name);
if (d)
- /* Reopening anonymous namespace. */
- need_new = 0;
+ /* Reopening anonymous namespace. */
+ need_new = 0;
implicit_use = 1;
}
else
/* Check whether this is an extended namespace definition. */
d = IDENTIFIER_NAMESPACE_VALUE (name);
if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
- {
- need_new = 0;
- if (DECL_NAMESPACE_ALIAS (d))
- {
- error ("namespace alias %qD not allowed here, assuming %qD",
- d, DECL_NAMESPACE_ALIAS (d));
- d = DECL_NAMESPACE_ALIAS (d);
- }
- }
+ {
+ need_new = 0;
+ if (DECL_NAMESPACE_ALIAS (d))
+ {
+ error ("namespace alias %qD not allowed here, assuming %qD",
+ d, DECL_NAMESPACE_ALIAS (d));
+ d = DECL_NAMESPACE_ALIAS (d);
+ }
+ }
}
if (need_new)
/* Make a new namespace, binding the name to it. */
d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
+ /* The name of this namespace is not visible to other translation
+ units if it is an anonymous namespace or member thereof. */
+ if (anon || decl_anon_ns_mem_p (current_namespace))
+ TREE_PUBLIC (d) = 0;
+ else
+ TREE_PUBLIC (d) = 1;
pushdecl (d);
if (anon)
{
if (TREE_CODE (decl) != NAMESPACE_DECL)
decl = decl_namespace_context (decl);
decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl),
- NULL_TREE, decl_namespace_list);
+ NULL_TREE, decl_namespace_list);
}
/* [namespace.memdef]/2 */
decl_namespace_list = TREE_CHAIN (decl_namespace_list);
}
-/* Return the namespace that is the common ancestor
+/* Return the namespace that is the common ancestor
of two given namespaces. */
static tree
if (is_ancestor (ns1, ns2))
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ns1);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
- namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2));
+ namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2));
}
/* Process a namespace-alias declaration. */
void
do_namespace_alias (tree alias, tree namespace)
{
- if (TREE_CODE (namespace) != NAMESPACE_DECL)
- {
- /* The parser did not find it, so it's not there. */
- error ("unknown namespace %qD", namespace);
- return;
- }
+ if (namespace == error_mark_node)
+ return;
+
+ gcc_assert (TREE_CODE (namespace) == NAMESPACE_DECL);
namespace = ORIGINAL_NAMESPACE (namespace);
/* Build the alias. */
- alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
+ alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
DECL_NAMESPACE_ALIAS (alias) = namespace;
DECL_EXTERNAL (alias) = 1;
DECL_CONTEXT (alias) = FROB_CONTEXT (current_scope ());
if appropriate. */
tree
-pushdecl_namespace_level (tree x)
+pushdecl_namespace_level (tree x, bool is_friend)
{
struct cp_binding_level *b = current_binding_level;
tree t;
timevar_push (TV_NAME_LOOKUP);
- t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace));
+ t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace), is_friend);
/* Now, the type_shadowed stack may screw us. Munge it so it does
what we want. */
tree newval;
tree *ptr = (tree *)0;
for (; !global_scope_p (b); b = b->level_chain)
- {
- tree shadowed = b->type_shadowed;
- for (; shadowed; shadowed = TREE_CHAIN (shadowed))
- if (TREE_PURPOSE (shadowed) == name)
- {
+ {
+ tree shadowed = b->type_shadowed;
+ for (; shadowed; shadowed = TREE_CHAIN (shadowed))
+ if (TREE_PURPOSE (shadowed) == name)
+ {
ptr = &TREE_VALUE (shadowed);
/* Can't break out of the loop here because sometimes
a binding level will have duplicate bindings for
PT names. It's gross, but I haven't time to fix it. */
- }
- }
+ }
+ }
newval = TREE_TYPE (t);
if (ptr == (tree *)0)
- {
- /* @@ This shouldn't be needed. My test case "zstring.cc" trips
- up here if this is changed to an assertion. --KR */
+ {
+ /* @@ This shouldn't be needed. My test case "zstring.cc" trips
+ up here if this is changed to an assertion. --KR */
SET_IDENTIFIER_TYPE_VALUE (name, t);
}
else
- {
+ {
*ptr = newval;
- }
+ }
}
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
/* Insert USED into the using list of USER. Set INDIRECT_flag if this
directive is not directly from the source. Also find the common
ancestor and let our users know about the new namespace */
-static void
+static void
add_using_namespace (tree user, tree used, bool indirect)
{
tree t;
}
/* Add used to the user's using list. */
- DECL_NAMESPACE_USING (user)
- = tree_cons (used, namespace_ancestor (user, used),
+ DECL_NAMESPACE_USING (user)
+ = tree_cons (used, namespace_ancestor (user, used),
DECL_NAMESPACE_USING (user));
TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
decl = validate_nonmember_using_decl (decl, scope, name);
if (decl == NULL_TREE)
return;
-
+
binding = binding_for_name (NAMESPACE_LEVEL (current_namespace), name);
oldval = binding->value;
binding->value = newval;
if (newtype)
binding->type = newtype;
- return;
}
/* Process a using-directive. */
{
tree context = NULL_TREE;
+ if (namespace == error_mark_node)
+ return;
+
+ gcc_assert (TREE_CODE (namespace) == NAMESPACE_DECL);
+
if (building_stmt_tree ())
add_stmt (build_stmt (USING_STMT, namespace));
-
- /* using namespace A::B::C; */
- if (TREE_CODE (namespace) == SCOPE_REF)
- namespace = TREE_OPERAND (namespace, 1);
- if (TREE_CODE (namespace) == IDENTIFIER_NODE)
- {
- /* Lookup in lexer did not find a namespace. */
- if (!processing_template_decl)
- error ("namespace %qT undeclared", namespace);
- return;
- }
- if (TREE_CODE (namespace) != NAMESPACE_DECL)
- {
- if (!processing_template_decl)
- error ("%qT is not a namespace", namespace);
- return;
- }
namespace = ORIGINAL_NAMESPACE (namespace);
+
if (!toplevel_bindings_p ())
{
push_using_directive (namespace);
if (current_namespace != global_namespace)
context = current_namespace;
}
-
+
/* Emit debugging info. */
if (!processing_template_decl)
(*debug_hooks->imported_module_or_decl) (namespace, context);
if (!toplevel_bindings_p ())
error ("strong using only meaningful at namespace scope");
else if (namespace != error_mark_node)
- DECL_NAMESPACE_ASSOCIATIONS (namespace)
- = tree_cons (current_namespace, 0,
- DECL_NAMESPACE_ASSOCIATIONS (namespace));
+ {
+ if (!is_ancestor (current_namespace, namespace))
+ error ("current namespace %qD does not enclose strongly used namespace %qD",
+ current_namespace, namespace);
+ DECL_NAMESPACE_ASSOCIATIONS (namespace)
+ = tree_cons (current_namespace, 0,
+ DECL_NAMESPACE_ASSOCIATIONS (namespace));
+ }
}
else
warning (OPT_Wattributes, "%qD attribute directive ignored", name);
*INIT, if INIT is non-NULL. */
static tree
-pushdecl_top_level_1 (tree x, tree *init)
+pushdecl_top_level_1 (tree x, tree *init, bool is_friend)
{
timevar_push (TV_NAME_LOOKUP);
push_to_top_level ();
- x = pushdecl_namespace_level (x);
+ x = pushdecl_namespace_level (x, is_friend);
if (init)
- cp_finish_decl (x, *init, NULL_TREE, 0);
+ finish_decl (x, *init, NULL_TREE);
pop_from_top_level ();
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
}
tree
pushdecl_top_level (tree x)
{
- return pushdecl_top_level_1 (x, NULL);
+ return pushdecl_top_level_1 (x, NULL, false);
+}
+
+/* Like pushdecl_top_level, but adding the IS_FRIEND parameter. */
+
+tree
+pushdecl_top_level_maybe_friend (tree x, bool is_friend)
+{
+ return pushdecl_top_level_1 (x, NULL, is_friend);
}
/* Like pushdecl, only it places X in the global scope if
tree
pushdecl_top_level_and_finish (tree x, tree init)
{
- return pushdecl_top_level_1 (x, &init);
+ return pushdecl_top_level_1 (x, &init, false);
}
/* Combines two sets of overloaded functions into an OVERLOAD chain, removing
need to add it again. For `extern "C"' functions, we
might have two FUNCTION_DECLs for the same function, in
different namespaces; again, we only need one of them. */
- if (fn1 == fn2
+ if (fn1 == fn2
|| (DECL_EXTERN_C_P (fn1) && DECL_EXTERN_C_P (fn2)
&& DECL_NAME (fn1) == DECL_NAME (fn2)))
break;
}
-
+
/* If we exhausted all of the functions in S1, FN2 is new. */
if (!fns1)
s1 = build_overload (fn2, s1);
XXX I don't want to repeat the entire duplicate_decls here */
static void
-ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
- int flags)
+ambiguous_decl (struct scope_binding *old, cxx_binding *new, int flags)
{
tree val, type;
gcc_assert (old != NULL);
+
+ /* Copy the type. */
+ type = new->type;
+ if (LOOKUP_NAMESPACES_ONLY (flags)
+ || (type && hidden_name_p (type) && !(flags & LOOKUP_HIDDEN)))
+ type = NULL_TREE;
+
/* Copy the value. */
val = new->value;
if (val)
- switch (TREE_CODE (val))
- {
- case TEMPLATE_DECL:
- /* If we expect types or namespaces, and not templates,
- or this is not a template class. */
- if ((LOOKUP_QUALIFIERS_ONLY (flags)
- && !DECL_CLASS_TEMPLATE_P (val))
- || hidden_name_p (val))
- val = NULL_TREE;
- break;
- case TYPE_DECL:
- if (LOOKUP_NAMESPACES_ONLY (flags) || hidden_name_p (val))
- val = NULL_TREE;
- break;
- case NAMESPACE_DECL:
- if (LOOKUP_TYPES_ONLY (flags))
- val = NULL_TREE;
- break;
- case FUNCTION_DECL:
- /* Ignore built-in functions that are still anticipated. */
- if (LOOKUP_QUALIFIERS_ONLY (flags) || hidden_name_p (val))
- val = NULL_TREE;
- break;
- default:
- if (LOOKUP_QUALIFIERS_ONLY (flags))
- val = NULL_TREE;
- }
-
+ {
+ if (hidden_name_p (val) && !(flags & LOOKUP_HIDDEN))
+ val = NULL_TREE;
+ else
+ switch (TREE_CODE (val))
+ {
+ case TEMPLATE_DECL:
+ /* If we expect types or namespaces, and not templates,
+ or this is not a template class. */
+ if ((LOOKUP_QUALIFIERS_ONLY (flags)
+ && !DECL_CLASS_TEMPLATE_P (val)))
+ val = NULL_TREE;
+ break;
+ case TYPE_DECL:
+ if (LOOKUP_NAMESPACES_ONLY (flags)
+ || (type && (flags & LOOKUP_PREFER_TYPES)))
+ val = NULL_TREE;
+ break;
+ case NAMESPACE_DECL:
+ if (LOOKUP_TYPES_ONLY (flags))
+ val = NULL_TREE;
+ break;
+ case FUNCTION_DECL:
+ /* Ignore built-in functions that are still anticipated. */
+ if (LOOKUP_QUALIFIERS_ONLY (flags))
+ val = NULL_TREE;
+ break;
+ default:
+ if (LOOKUP_QUALIFIERS_ONLY (flags))
+ val = NULL_TREE;
+ }
+ }
+
+ /* If val is hidden, shift down any class or enumeration name. */
+ if (!val)
+ {
+ val = type;
+ type = NULL_TREE;
+ }
+
if (!old->value)
old->value = val;
else if (val && val != old->value)
{
if (is_overloaded_fn (old->value) && is_overloaded_fn (val))
- old->value = merge_functions (old->value, val);
+ old->value = merge_functions (old->value, val);
else
{
- /* Some declarations are functions, some are not. */
- if (flags & LOOKUP_COMPLAIN)
- {
- /* If we've already given this error for this lookup,
- old->value is error_mark_node, so let's not
- repeat ourselves. */
- if (old->value != error_mark_node)
- {
- error ("use of %qD is ambiguous", name);
- cp_error_at (" first declared as %q#D here", old->value);
- }
- cp_error_at (" also declared as %q#D here", val);
- }
- old->value = error_mark_node;
+ old->value = tree_cons (NULL_TREE, old->value,
+ build_tree_list (NULL_TREE, val));
+ TREE_TYPE (old->value) = error_mark_node;
}
}
- /* ... and copy the type. */
- type = new->type;
- if (LOOKUP_NAMESPACES_ONLY (flags))
- type = NULL_TREE;
+
if (!old->type)
old->type = type;
else if (type && old->type != type)
{
- if (flags & LOOKUP_COMPLAIN)
- {
- error ("%qD denotes an ambiguous type",name);
- error ("%J first type here", TYPE_MAIN_DECL (old->type));
- error ("%J other type here", TYPE_MAIN_DECL (type));
- }
+ old->type = tree_cons (NULL_TREE, old->type,
+ build_tree_list (NULL_TREE, type));
+ TREE_TYPE (old->type) = error_mark_node;
}
}
return true;
}
-/* Given a lookup that returned VAL, decide if we want to ignore it or
- not based on DECL_ANTICIPATED_P. */
+/* Given a lookup that returned VAL, decide if we want to ignore it or
+ not based on DECL_ANTICIPATED. */
bool
hidden_name_p (tree val)
return false;
}
-/* Look up NAME in the NAMESPACE. */
+/* Remove any hidden friend functions from a possibly overloaded set
+ of functions. */
tree
-lookup_namespace_name (tree namespace, tree name)
+remove_hidden_names (tree fns)
{
- tree val;
- tree template_id = NULL_TREE;
- struct scope_binding binding = EMPTY_SCOPE_BINDING;
-
- timevar_push (TV_NAME_LOOKUP);
- gcc_assert (TREE_CODE (namespace) == NAMESPACE_DECL);
+ if (!fns)
+ return fns;
- if (TREE_CODE (name) == NAMESPACE_DECL)
- /* This happens for A::B<int> when B is a namespace. */
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, name);
- else if (TREE_CODE (name) == TEMPLATE_DECL)
+ if (TREE_CODE (fns) == FUNCTION_DECL && hidden_name_p (fns))
+ fns = NULL_TREE;
+ else if (TREE_CODE (fns) == OVERLOAD)
{
- /* This happens for A::B where B is a template, and there are no
- template arguments. */
- error ("invalid use of %qD", name);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- }
-
- namespace = ORIGINAL_NAMESPACE (namespace);
-
- if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- {
- template_id = name;
- name = TREE_OPERAND (name, 0);
- if (TREE_CODE (name) == OVERLOAD)
- name = DECL_NAME (OVL_CURRENT (name));
- else if (DECL_P (name))
- name = DECL_NAME (name);
- }
-
- gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
-
- if (!qualified_lookup_using_namespace (name, namespace, &binding, 0))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-
- if (binding.value)
- {
- val = binding.value;
+ tree o;
- if (template_id)
+ for (o = fns; o; o = OVL_NEXT (o))
+ if (hidden_name_p (OVL_CURRENT (o)))
+ break;
+ if (o)
{
- if (DECL_CLASS_TEMPLATE_P (val))
- val = lookup_template_class (val,
- TREE_OPERAND (template_id, 1),
- /*in_decl=*/NULL_TREE,
- /*context=*/NULL_TREE,
- /*entering_scope=*/0,
- tf_error | tf_warning);
- else if (DECL_FUNCTION_TEMPLATE_P (val)
- || TREE_CODE (val) == OVERLOAD)
- val = lookup_template_function (val,
- TREE_OPERAND (template_id, 1));
- else
- {
- error ("%<%D::%D%> is not a template", namespace, name);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- }
- }
-
- /* If we have a single function from a using decl, pull it out. */
- if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
- val = OVL_FUNCTION (val);
-
- /* Ignore built-in functions and friends that haven't been declared
- yet. */
- if (!val || !hidden_name_p (val))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
- }
-
- error ("%qD undeclared in namespace %qD", name, namespace);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-}
-
-/* Select the right _DECL from multiple choices. */
-
-static tree
-select_decl (const struct scope_binding *binding, int flags)
-{
- tree val;
- val = binding->value;
+ tree n = NULL_TREE;
- timevar_push (TV_NAME_LOOKUP);
- if (LOOKUP_NAMESPACES_ONLY (flags))
- {
- /* We are not interested in types. */
- if (val && TREE_CODE (val) == NAMESPACE_DECL)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ for (o = fns; o; o = OVL_NEXT (o))
+ if (!hidden_name_p (OVL_CURRENT (o)))
+ n = build_overload (OVL_CURRENT (o), n);
+ fns = n;
+ }
}
- /* If looking for a type, or if there is no non-type binding, select
- the value binding. */
- if (binding->type && (!val || (flags & LOOKUP_PREFER_TYPES)))
- val = binding->type;
- /* Don't return non-types if we really prefer types. */
- else if (val && LOOKUP_TYPES_ONLY (flags)
- && ! DECL_DECLARES_TYPE_P (val))
- val = NULL_TREE;
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+ return fns;
}
/* Unscoped lookup of a global: iterate over current namespaces,
tree siter;
struct cp_binding_level *level;
tree val = NULL_TREE;
- struct scope_binding binding = EMPTY_SCOPE_BINDING;
timevar_push (TV_NAME_LOOKUP);
for (; !val; scope = CP_DECL_CONTEXT (scope))
{
+ struct scope_binding binding = EMPTY_SCOPE_BINDING;
cxx_binding *b =
- cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+ cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
if (b)
- {
- if (b->value && hidden_name_p (b->value))
- /* Ignore anticipated built-in functions and friends. */
- ;
- else
- binding.value = b->value;
- binding.type = b->type;
- }
+ ambiguous_decl (&binding, b, flags);
/* Add all _DECLs seen through local using-directives. */
for (level = current_binding_level;
level->kind != sk_namespace;
level = level->level_chain)
if (!lookup_using_namespace (name, &binding, level->using_directives,
- scope, flags))
+ scope, flags))
/* Give up because of error. */
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
while (1)
{
if (!lookup_using_namespace (name, &binding,
- DECL_NAMESPACE_USING (siter),
+ DECL_NAMESPACE_USING (siter),
scope, flags))
/* Give up because of error. */
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
siter = CP_DECL_CONTEXT (siter);
}
- val = select_decl (&binding, flags);
+ val = binding.value;
if (scope == global_namespace)
break;
}
/* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL
or a class TYPE). If IS_TYPE_P is TRUE, then ignore non-type
- bindings.
+ bindings.
Returns a DECL (or OVERLOAD, or BASELINK) representing the
declaration found. If no suitable declaration can be found,
lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
{
int flags = 0;
+ tree t = NULL_TREE;
if (TREE_CODE (scope) == NAMESPACE_DECL)
{
if (is_type_p)
flags |= LOOKUP_PREFER_TYPES;
if (qualified_lookup_using_namespace (name, scope, &binding, flags))
- return select_decl (&binding, flags);
+ t = binding.value;
}
else if (is_aggr_type (scope, complain))
- {
- tree t;
- t = lookup_member (scope, name, 2, is_type_p);
- if (t)
- return t;
- }
+ t = lookup_member (scope, name, 2, is_type_p);
- return error_mark_node;
+ if (!t)
+ return error_mark_node;
+ return t;
}
/* Subroutine of unqualified_namespace_lookup:
for (iter = usings; iter; iter = TREE_CHAIN (iter))
if (TREE_VALUE (iter) == scope)
{
- tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
- cxx_binding *val1 =
- cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
- /* Resolve ambiguities. */
- if (val1)
- ambiguous_decl (name, val, val1, flags);
+ tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
+ cxx_binding *val1 =
+ cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
+ /* Resolve ambiguities. */
+ if (val1)
+ ambiguous_decl (val, val1, flags);
}
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
}
cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
seen = tree_cons (scope, NULL_TREE, seen);
if (binding)
- ambiguous_decl (name, result, binding, flags);
+ ambiguous_decl (result, binding, flags);
/* Consider strong using directives always, and non-strong ones
if we haven't found a binding yet. ??? Shouldn't we consider
CLASS_P is false, then class bindings are ignored. */
cxx_binding *
-outer_binding (tree name,
+outer_binding (tree name,
cxx_binding *binding,
bool class_p)
{
if (class_p)
while (scope && scope != outer_scope && scope->kind != sk_namespace)
{
- if (scope->kind == sk_class)
+ if (scope->kind == sk_class)
{
cxx_binding *class_binding;
-
+
class_binding = get_class_binding (name, scope);
if (class_binding)
{
/* Conversion operators are handled specially because ordinary
unqualified name lookup will not find template conversion
operators. */
- if (IDENTIFIER_TYPENAME_P (name))
+ if (IDENTIFIER_TYPENAME_P (name))
{
struct cp_binding_level *level;
- for (level = current_binding_level;
+ for (level = current_binding_level;
level && level->kind != sk_namespace;
level = level->level_chain)
{
tree class_type;
tree operators;
-
- /* A conversion operator can only be declared in a class
+
+ /* A conversion operator can only be declared in a class
scope. */
if (level->kind != sk_class)
continue;
-
+
/* Lookup the conversion operator in the class. */
class_type = level->this_entity;
operators = lookup_fnfields (class_type, name, /*protect=*/0);
iter = outer_binding (name, iter, !nonclass))
{
tree binding;
-
+
/* Skip entities we don't want. */
if (LOCAL_BINDING_P (iter) ? !block_p : nonclass)
continue;
-
+
/* If this is the kind of thing we're looking for, we're done. */
- if (qualify_lookup (iter->value, flags)
- && !hidden_name_p (iter->value))
+ if (qualify_lookup (iter->value, flags))
binding = iter->value;
else if ((flags & LOOKUP_PREFER_TYPES)
- && qualify_lookup (iter->type, flags)
- && !hidden_name_p (iter->type))
+ && qualify_lookup (iter->type, flags))
binding = iter->type;
else
binding = NULL_TREE;
-
+
if (binding)
{
+ if (hidden_name_p (binding))
+ {
+ /* A non namespace-scope binding can only be hidden if
+ we are in a local class, due to friend declarations.
+ In particular, consider:
+
+ void f() {
+ struct A {
+ friend struct B;
+ void g() { B* b; } // error: B is hidden
+ }
+ struct B {};
+ }
+
+ The standard says that "B" is a local class in "f"
+ (but not nested within "A") -- but that name lookup
+ for "B" does not find this declaration until it is
+ declared directly with "f".
+
+ In particular:
+
+ [class.friend]
+
+ If a friend declaration appears in a local class and
+ the name specified is an unqualified name, a prior
+ declaration is looked up without considering scopes
+ that are outside the innermost enclosing non-class
+ scope. For a friend class declaration, if there is no
+ prior declaration, the class that is specified
+ belongs to the innermost enclosing non-class scope,
+ but if it is subsequently referenced, its name is not
+ found by name lookup until a matching declaration is
+ provided in the innermost enclosing nonclass scope.
+ */
+ gcc_assert (current_class_type &&
+ LOCAL_CLASS_P (current_class_type));
+
+ /* This binding comes from a friend declaration in the local
+ class. The standard (11.4.8) states that the lookup can
+ only succeed if there is a non-hidden declaration in the
+ current scope, which is not the case here. */
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ }
val = binding;
break;
}
if (!val)
val = unqualified_namespace_lookup (name, flags);
- if (val)
- {
- /* If we have a single function from a using decl, pull it out. */
- if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
- val = OVL_FUNCTION (val);
- }
+ /* If we have a single function from a using decl, pull it out. */
+ if (val && TREE_CODE (val) == OVERLOAD && !really_overloaded_fn (val))
+ val = OVL_FUNCTION (val);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
}
tree
lookup_function_nonclass (tree name, tree args, bool block_p)
{
- return
- lookup_arg_dependent (name,
- lookup_name_real (name, 0, 1, block_p, 0,
+ return
+ lookup_arg_dependent (name,
+ lookup_name_real (name, 0, 1, block_p, 0,
LOOKUP_COMPLAIN),
args);
}
tree
-lookup_name (tree name, int prefer_type)
+lookup_name (tree name)
+{
+ return lookup_name_real (name, 0, 0, /*block_p=*/true, 0, LOOKUP_COMPLAIN);
+}
+
+tree
+lookup_name_prefer_type (tree name, int prefer_type)
{
- return lookup_name_real (name, prefer_type, 0, /*block_p=*/true,
+ return lookup_name_real (name, prefer_type, 0, /*block_p=*/true,
0, LOOKUP_COMPLAIN);
}
Unlike lookup_name_real, we make sure that NAME is actually
declared in the desired scope, not from inheritance, nor using
directive. For using declaration, there is DR138 still waiting
- to be resolved. Hidden name coming from earlier an friend
+ to be resolved. Hidden name coming from an earlier friend
declaration is also returned.
A TYPE_DECL best matching the NAME is returned. Catching error
for (; iter; iter = outer_binding (name, iter, /*class_p=*/ true))
{
/* Check if this is the kind of thing we're looking for.
- If SCOPE is TS_CURRENT, also make sure it doesn't come from
+ If SCOPE is TS_CURRENT, also make sure it doesn't come from
base class. For ITER->VALUE, we can simply use
- INHERITED_VALUE_BINDING_P. For ITER->TYPE, we have to use
+ INHERITED_VALUE_BINDING_P. For ITER->TYPE, we have to use
our own check.
We check ITER->TYPE before ITER->VALUE in order to handle
else if (qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
val = iter->value;
}
-
+
}
/* Type found, check if it is in the allowed scopes, ignoring cleanup
/* Similar to `lookup_name' but look only in the innermost non-class
binding level. */
-static tree
+tree
lookup_name_innermost_nonclass_level (tree name)
{
struct cp_binding_level *b;
{
if (purpose_member (name, b->type_shadowed))
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
- REAL_IDENTIFIER_TYPE_VALUE (name));
+ REAL_IDENTIFIER_TYPE_VALUE (name));
if (b->kind == sk_cleanup)
b = b->level_chain;
else
struct arg_lookup
{
tree name;
+ tree args;
tree namespaces;
tree classes;
tree functions;
case. */
/* We must find only functions, or exactly one non-function. */
- if (!k->functions)
+ if (!k->functions)
k->functions = fn;
else if (fn == k->functions)
;
{
fn = f1; f1 = f2; f2 = fn;
}
- cp_error_at ("%qD is not a function,", f1);
- cp_error_at (" conflict with %qD", f2);
+ error ("%q+D is not a function,", f1);
+ error (" conflict with %q+D", f2);
error (" in call to %qD", k->name);
return true;
}
}
}
+/* Return whether FN is a friend of an associated class of ARG. */
+
+static bool
+friend_of_associated_class_p (tree arg, tree fn)
+{
+ tree type;
+
+ if (TYPE_P (arg))
+ type = arg;
+ else if (type_unknown_p (arg))
+ return false;
+ else
+ type = TREE_TYPE (arg);
+
+ /* If TYPE is a class, the class itself and all base classes are
+ associated classes. */
+ if (CLASS_TYPE_P (type))
+ {
+ if (is_friend (type, fn))
+ return true;
+
+ if (TYPE_BINFO (type))
+ {
+ tree binfo, base_binfo;
+ int i;
+
+ for (binfo = TYPE_BINFO (type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo);
+ i++)
+ if (is_friend (BINFO_TYPE (base_binfo), fn))
+ return true;
+ }
+ }
+
+ /* If TYPE is a class member, the class of which it is a member is
+ an associated class. */
+ if ((CLASS_TYPE_P (type)
+ || TREE_CODE (type) == UNION_TYPE
+ || TREE_CODE (type) == ENUMERAL_TYPE)
+ && TYPE_CONTEXT (type)
+ && CLASS_TYPE_P (TYPE_CONTEXT (type))
+ && is_friend (TYPE_CONTEXT (type), fn))
+ return true;
+
+ return false;
+}
+
/* Add functions of a namespace to the lookup structure.
Returns true on error. */
value = TREE_CHAIN (value))
if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
return true;
-
+
value = namespace_binding (k->name, scope);
if (!value)
return false;
for (; value; value = OVL_NEXT (value))
- if (add_function (k, OVL_CURRENT (value)))
- return true;
-
+ {
+ /* We don't want to find arbitrary hidden functions via argument
+ dependent lookup. We only want to find friends of associated
+ classes. */
+ if (hidden_name_p (OVL_CURRENT (value)))
+ {
+ tree args;
+
+ for (args = k->args; args; args = TREE_CHAIN (args))
+ if (friend_of_associated_class_p (TREE_VALUE (args),
+ OVL_CURRENT (value)))
+ break;
+ if (!args)
+ continue;
+ }
+
+ if (add_function (k, OVL_CURRENT (value)))
+ return true;
+ }
+
return false;
}
/* It's not a member template. */
if (TREE_CODE (ctx) == NAMESPACE_DECL)
- return arg_assoc_namespace (k, ctx);
+ return arg_assoc_namespace (k, ctx);
/* Otherwise, it must be member template. */
- else
- return arg_assoc_class (k, ctx);
+ else
+ return arg_assoc_class (k, ctx);
+ }
+ /* It's an argument pack; handle it recursively. */
+ else if (ARGUMENT_PACK_P (arg))
+ {
+ tree args = ARGUMENT_PACK_ARGS (arg);
+ int i, len = TREE_VEC_LENGTH (args);
+ for (i = 0; i < len; ++i)
+ if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, i)))
+ return true;
+
+ return false;
}
/* It's not a template template argument, but it is a type template
argument. */
{
tree list, friends, context;
int i;
-
+
/* Backend build structures, such as __builtin_va_list, aren't
affected by all this. */
if (!CLASS_TYPE_P (type))
if (purpose_member (type, k->classes))
return false;
k->classes = tree_cons (type, NULL_TREE, k->classes);
-
+
context = decl_namespace_context (type);
if (arg_assoc_namespace (k, context))
return true;
{
/* Process baseclasses. */
tree binfo, base_binfo;
-
+
for (binfo = TYPE_BINFO (type), i = 0;
BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
if (arg_assoc_class (k, BINFO_TYPE (base_binfo)))
return true;
}
-
+
/* Process friends. */
- for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
+ for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
list = TREE_CHAIN (list))
if (k->name == FRIEND_NAME (list))
- for (friends = FRIEND_DECLS (list); friends;
+ for (friends = FRIEND_DECLS (list); friends;
friends = TREE_CHAIN (friends))
{
tree fn = TREE_VALUE (friends);
}
/* Process template arguments. */
- if (CLASSTYPE_TEMPLATE_INFO (type)
+ if (CLASSTYPE_TEMPLATE_INFO (type)
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
{
list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
- for (i = 0; i < TREE_VEC_LENGTH (list); ++i)
- arg_assoc_template_arg (k, TREE_VEC_ELT (list, i));
+ for (i = 0; i < TREE_VEC_LENGTH (list); ++i)
+ arg_assoc_template_arg (k, TREE_VEC_ELT (list, i));
}
return false;
case REAL_TYPE:
case COMPLEX_TYPE:
case VECTOR_TYPE:
- case CHAR_TYPE:
case BOOLEAN_TYPE:
return false;
case RECORD_TYPE:
case LANG_TYPE:
gcc_assert (type == unknown_type_node);
return false;
+ case TYPE_PACK_EXPANSION:
+ return arg_assoc_type (k, PACK_EXPANSION_PATTERN (type));
+
default:
gcc_unreachable ();
}
int ix;
if (TREE_CODE (template) == COMPONENT_REF)
- template = TREE_OPERAND (template, 1);
-
+ template = TREE_OPERAND (template, 1);
+
/* First, the template. There may actually be more than one if
this is an overloaded function template. But, in that case,
we only need the first; all the functions will be in the same
template = OVL_CURRENT (template);
ctx = CP_DECL_CONTEXT (template);
-
+
if (TREE_CODE (ctx) == NAMESPACE_DECL)
{
if (arg_assoc_namespace (k, ctx) == 1)
return true;
/* Now the arguments. */
- for (ix = TREE_VEC_LENGTH (args); ix--;)
- if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
- return true;
+ if (args)
+ for (ix = TREE_VEC_LENGTH (args); ix--;)
+ if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
+ return true;
}
else if (TREE_CODE (n) == OVERLOAD)
{
lookup_arg_dependent (tree name, tree fns, tree args)
{
struct arg_lookup k;
- tree fn = NULL_TREE;
timevar_push (TV_NAME_LOOKUP);
+
+ /* Remove any hidden friend functions from the list of functions
+ found so far. They will be added back by arg_assoc_class as
+ appropriate. */
+ fns = remove_hidden_names (fns);
+
k.name = name;
+ k.args = args;
k.functions = fns;
k.classes = NULL_TREE;
- /* We've already looked at some namespaces during normal unqualified
- lookup -- but we don't know exactly which ones. If the functions
- we found were brought into the current namespace via a using
- declaration, we have not really checked the namespace from which
- they came. Therefore, we check all namespaces here -- unless the
- function we have is from the current namespace. Even then, we
- must check all namespaces if the function is a local
- declaration; any other declarations present at namespace scope
- should be visible during argument-dependent lookup. */
- if (fns)
- fn = OVL_CURRENT (fns);
- if (fn && TREE_CODE (fn) == FUNCTION_DECL
- && (CP_DECL_CONTEXT (fn) != current_decl_namespace ()
- || DECL_LOCAL_FUNCTION_P (fn)))
- k.namespaces = NULL_TREE;
- else
- /* Setting NAMESPACES is purely an optimization; it prevents
- adding functions which are already in FNS. Adding them would
- be safe -- "joust" will eliminate the duplicates -- but
- wasteful. */
- k.namespaces = build_tree_list (current_decl_namespace (), NULL_TREE);
+ /* We previously performed an optimization here by setting
+ NAMESPACES to the current namespace when it was safe. However, DR
+ 164 says that namespaces that were already searched in the first
+ stage of template processing are searched again (potentially
+ picking up later definitions) in the second stage. */
+ k.namespaces = NULL_TREE;
arg_assoc_args (&k, args);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, k.functions);
+
+ fns = k.functions;
+
+ if (fns
+ && TREE_CODE (fns) != VAR_DECL
+ && !is_overloaded_fn (fns))
+ {
+ error ("argument dependent lookup finds %q+D", fns);
+ error (" in call to %qD", name);
+ fns = error_mark_node;
+ }
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fns);
}
/* Add namespace to using_directives. Return NULL_TREE if nothing was
static tree
maybe_process_template_type_declaration (tree type, int is_friend,
- cxx_scope *b)
+ cxx_scope *b)
{
tree decl = TYPE_NAME (type);
/* You can't declare a new template type in a template parameter
list. But, you can declare a non-template type:
- template <class A*> struct S;
+ template <class A*> struct S;
is a forward-declaration of `A'. */
;
+ else if (b->kind == sk_namespace
+ && current_binding_level->kind != sk_namespace)
+ /* If this new type is being injected into a containing scope,
+ then it's not a template type. */
+ ;
else
{
gcc_assert (IS_AGGR_TYPE (type) || TREE_CODE (type) == ENUMERAL_TYPE);
{
maybe_add_class_template_decl_list (current_class_type,
type, /*friend_p=*/0);
- /* Put this UDT in the table of UDTs for the class. */
+ /* Put this UTD in the table of UTDs for the class. */
if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
CLASSTYPE_NESTED_UTDS (current_class_type) =
binding_table_new (SCOPE_DEFAULT_HT_SIZE);
pushtag (tree name, tree type, tag_scope scope)
{
struct cp_binding_level *b;
+ tree decl;
timevar_push (TV_NAME_LOOKUP);
b = current_binding_level;
|| COMPLETE_TYPE_P (b->this_entity))))
b = b->level_chain;
- if (name)
- {
- /* Do C++ gratuitous typedefing. */
- if (IDENTIFIER_TYPE_VALUE (name) != type)
- {
- tree d = NULL_TREE;
- int in_class = 0;
- tree context = TYPE_CONTEXT (type);
-
- if (! context)
- {
- tree cs = current_scope ();
-
- if (scope == ts_current)
- context = cs;
- else if (cs != NULL_TREE && TYPE_P (cs))
- /* When declaring a friend class of a local class, we want
- to inject the newly named class into the scope
- containing the local class, not the namespace scope. */
- context = decl_function_context (get_type_decl (cs));
- }
- if (!context)
- context = current_namespace;
-
- if (b->kind == sk_class
- || (b->kind == sk_template_parms
- && b->level_chain->kind == sk_class))
- in_class = 1;
+ gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
- if (current_lang_name == lang_name_java)
- TYPE_FOR_JAVA (type) = 1;
+ /* Do C++ gratuitous typedefing. */
+ if (IDENTIFIER_TYPE_VALUE (name) != type)
+ {
+ tree tdef;
+ int in_class = 0;
+ tree context = TYPE_CONTEXT (type);
- d = create_implicit_typedef (name, type);
- DECL_CONTEXT (d) = FROB_CONTEXT (context);
- if (scope == ts_within_enclosing_non_class)
- {
- /* This is a friend. Make this TYPE_DECL node hidden from
- ordinary name lookup. Its corresponding TEMPLATE_DECL
- will be marked in push_template_decl_real. */
- retrofit_lang_decl (d);
- DECL_ANTICIPATED (d) = 1;
- DECL_FRIEND_P (d) = 1;
- }
+ if (! context)
+ {
+ tree cs = current_scope ();
+
+ if (scope == ts_current)
+ context = cs;
+ else if (cs != NULL_TREE && TYPE_P (cs))
+ /* When declaring a friend class of a local class, we want
+ to inject the newly named class into the scope
+ containing the local class, not the namespace
+ scope. */
+ context = decl_function_context (get_type_decl (cs));
+ }
+ if (!context)
+ context = current_namespace;
- if (! in_class)
- set_identifier_type_value_with_scope (name, d, b);
+ if (b->kind == sk_class
+ || (b->kind == sk_template_parms
+ && b->level_chain->kind == sk_class))
+ in_class = 1;
- d = maybe_process_template_type_declaration
- (type, scope == ts_within_enclosing_non_class, b);
- if (d == error_mark_node)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ if (current_lang_name == lang_name_java)
+ TYPE_FOR_JAVA (type) = 1;
- if (b->kind == sk_class)
- {
- if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
- /* Put this TYPE_DECL on the TYPE_FIELDS list for the
- class. But if it's a member template class, we
- want the TEMPLATE_DECL, not the TYPE_DECL, so this
- is done later. */
- finish_member_declaration (d);
- else
- pushdecl_class_level (d);
- }
- else if (b->kind != sk_template_parms)
- d = pushdecl_with_scope (d, b);
+ tdef = create_implicit_typedef (name, type);
+ DECL_CONTEXT (tdef) = FROB_CONTEXT (context);
+ if (scope == ts_within_enclosing_non_class)
+ {
+ /* This is a friend. Make this TYPE_DECL node hidden from
+ ordinary name lookup. Its corresponding TEMPLATE_DECL
+ will be marked in push_template_decl_real. */
+ retrofit_lang_decl (tdef);
+ DECL_ANTICIPATED (tdef) = 1;
+ DECL_FRIEND_P (tdef) = 1;
+ }
- if (d == error_mark_node)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ decl = maybe_process_template_type_declaration
+ (type, scope == ts_within_enclosing_non_class, b);
+ if (decl == error_mark_node)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
- /* FIXME what if it gets a name from typedef? */
- if (ANON_AGGRNAME_P (name))
- DECL_IGNORED_P (d) = 1;
-
- TYPE_CONTEXT (type) = DECL_CONTEXT (d);
-
- /* If this is a local class, keep track of it. We need this
- information for name-mangling, and so that it is possible to find
- all function definitions in a translation unit in a convenient
- way. (It's otherwise tricky to find a member function definition
- it's only pointed to from within a local class.) */
- if (TYPE_CONTEXT (type)
- && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL)
- VEC_safe_push (tree, gc, local_classes, type);
- }
- if (b->kind == sk_class
- && !COMPLETE_TYPE_P (current_class_type))
+ if (b->kind == sk_class)
+ {
+ if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
+ /* Put this TYPE_DECL on the TYPE_FIELDS list for the
+ class. But if it's a member template class, we want
+ the TEMPLATE_DECL, not the TYPE_DECL, so this is done
+ later. */
+ finish_member_declaration (decl);
+ else
+ pushdecl_class_level (decl);
+ }
+ else if (b->kind != sk_template_parms)
{
- maybe_add_class_template_decl_list (current_class_type,
- type, /*friend_p=*/0);
+ decl = pushdecl_with_scope (decl, b, /*is_friend=*/false);
+ if (decl == error_mark_node)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+ }
- if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
- CLASSTYPE_NESTED_UTDS (current_class_type)
- = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
+ if (! in_class)
+ set_identifier_type_value_with_scope (name, tdef, b);
- binding_table_insert
- (CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
- }
- }
+ TYPE_CONTEXT (type) = DECL_CONTEXT (decl);
- if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
- /* Use the canonical TYPE_DECL for this node. */
- TYPE_STUB_DECL (type) = TYPE_NAME (type);
- else
+ /* If this is a local class, keep track of it. We need this
+ information for name-mangling, and so that it is possible to
+ find all function definitions in a translation unit in a
+ convenient way. (It's otherwise tricky to find a member
+ function definition it's only pointed to from within a local
+ class.) */
+ if (TYPE_CONTEXT (type)
+ && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL)
+ VEC_safe_push (tree, gc, local_classes, type);
+ }
+ if (b->kind == sk_class
+ && !COMPLETE_TYPE_P (current_class_type))
{
- /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE
- will be the tagged type we just added to the current
- binding level. This fake NULL-named TYPE_DECL node helps
- dwarfout.c to know when it needs to output a
- representation of a tagged type, and it also gives us a
- convenient place to record the "scope start" address for
- the tagged type. */
-
- tree d = build_decl (TYPE_DECL, NULL_TREE, type);
- TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b);
+ maybe_add_class_template_decl_list (current_class_type,
+ type, /*friend_p=*/0);
+
+ if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
+ CLASSTYPE_NESTED_UTDS (current_class_type)
+ = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
+
+ binding_table_insert
+ (CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
}
+
+ decl = TYPE_NAME (type);
+ gcc_assert (TREE_CODE (decl) == TYPE_DECL);
+ TYPE_STUB_DECL (type) = decl;
+
+ /* Set type visibility now if this is a forward declaration. */
+ TREE_PUBLIC (decl) = 1;
+ determine_visibility (decl);
+
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
}
\f
if (IDENTIFIER_MARKED (id))
return;
-
+
IDENTIFIER_MARKED (id) = 1;
saved = VEC_safe_push (cxx_saved_binding, gc, *old_bindings, NULL);
objects, rather than a TREE_LIST. */
static void
-store_class_bindings (VEC(cp_class_binding,gc) *names,
+store_class_bindings (VEC(cp_class_binding,gc) *names,
VEC(cxx_saved_binding,gc) **old_bindings)
{
size_t i;
struct cp_binding_level *b;
cxx_saved_binding *sb;
size_t i;
- int need_pop;
+ bool need_pop;
timevar_push (TV_NAME_LOOKUP);
s = GGC_CNEW (struct saved_scope);
/* If we're in the middle of some function, save our state. */
if (cfun)
{
- need_pop = 1;
+ need_pop = true;
push_function_context_to (NULL_TREE);
}
else
- need_pop = 0;
+ need_pop = false;
if (scope_chain && previous_class_level)
store_class_bindings (previous_class_level->class_shadowed,
s->bindings = b;
s->need_pop_function_context = need_pop;
s->function_decl = current_function_decl;
+ s->skip_evaluation = skip_evaluation;
scope_chain = s;
current_function_decl = NULL_TREE;
current_lang_base = VEC_alloc (tree, gc, 10);
current_lang_name = lang_name_cplusplus;
current_namespace = global_namespace;
+ push_class_stack ();
+ skip_evaluation = 0;
timevar_pop (TV_NAME_LOOKUP);
}
cxx_saved_binding *saved;
size_t i;
- timevar_push (TV_NAME_LOOKUP);
+ timevar_push (TV_NAME_LOOKUP);
/* Clear out class-level bindings cache. */
if (previous_class_level)
invalidate_class_lookup_cache ();
+ pop_class_stack ();
current_lang_base = 0;
if (s->need_pop_function_context)
pop_function_context_from (NULL_TREE);
current_function_decl = s->function_decl;
+ skip_evaluation = s->skip_evaluation;
timevar_pop (TV_NAME_LOOKUP);
}
}
/* Emit debugging information for using declarations and directives.
- If input tree is overloaded fn then emit debug info for all
+ If input tree is overloaded fn then emit debug info for all
candidates. */
-static void
+void
cp_emit_debug_info_for_using (tree t, tree context)
{
- /* Ignore this FUNCTION_DECL if it refers to a builtin declaration
+ /* Don't try to emit any debug information if we have errors. */
+ if (sorrycount || errorcount)
+ return;
+
+ /* Ignore this FUNCTION_DECL if it refers to a builtin declaration
of a builtin function. */
- if (TREE_CODE (t) == FUNCTION_DECL
+ if (TREE_CODE (t) == FUNCTION_DECL
&& DECL_EXTERNAL (t)
&& DECL_BUILT_IN (t))
return;
it is a global namespace. */
if (context == global_namespace)
context = NULL_TREE;
-
+
if (BASELINK_P (t))
t = BASELINK_FUNCTIONS (t);
-
+
/* FIXME: Handle TEMPLATE_DECLs. */
for (t = OVL_CURRENT (t); t; t = OVL_NEXT (t))
if (TREE_CODE (t) != TEMPLATE_DECL)
(*debug_hooks->imported_module_or_decl) (t, context);
- }
+}
#include "gt-cp-name-lookup.h"