/* Initialize anonymous_namespace_name if necessary, and return it. */
static tree
-get_anonymous_namespace_name(void)
+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");
+ 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");
+ /* 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;
}
/* The datatype used to implement the mapping from names to types at
a given scope. */
-struct binding_table_s GTY(())
-{
+struct GTY(()) binding_table_s {
/* Array of chains of "binding_entry"s */
binding_entry * GTY((length ("%h.chain_count"))) chain;
/* If declaring a type as a typedef, copy the type (unless we're
at line 0), and install this TYPE_DECL as the new type's typedef
- name. See the extensive comment in ../c-decl.c (pushdecl). */
+ name. See the extensive comment of set_underlying_type (). */
if (TREE_CODE (x) == TYPE_DECL)
{
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
- /* 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_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
- TYPE_NAME (type) = x;
- TREE_TYPE (x) = type;
- }
+
+ if (DECL_IS_BUILTIN (x)
+ || (TREE_TYPE (x) != 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))))
+ set_underlying_type (x);
if (type != error_mark_node
&& TYPE_NAME (type)
&& TREE_PUBLIC (x))
TREE_PUBLIC (name) = 1;
+ /* Don't complain about the parms we push and then pop
+ while tentatively parsing a function declarator. */
+ if (TREE_CODE (x) == PARM_DECL && DECL_CONTEXT (x) == NULL_TREE)
+ /* Ignore. */;
+
/* Warn if shadowing an argument at the top level of the body. */
- if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
- /* Inline decls shadow nothing. */
- && !DECL_FROM_INLINE (x)
- && TREE_CODE (oldlocal) == PARM_DECL
- /* Don't check the `this' parameter. */
- && !DECL_ARTIFICIAL (oldlocal))
+ else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
+ /* Inline decls shadow nothing. */
+ && !DECL_FROM_INLINE (x)
+ && TREE_CODE (oldlocal) == PARM_DECL
+ /* Don't check the `this' parameter. */
+ && !DECL_ARTIFICIAL (oldlocal))
{
bool err = false;
}
}
- if (warn_shadow && !err
- /* Don't complain about the parms we push and then pop
- while tentatively parsing a function declarator. */
- && !(TREE_CODE (x) == PARM_DECL && DECL_CONTEXT (x) == NULL_TREE))
+ if (warn_shadow && !err)
{
- warning (OPT_Wshadow, "declaration of %q#D shadows a parameter", x);
- warning (OPT_Wshadow, "%Jshadowed declaration is here", oldlocal);
+ warning_at (input_location, OPT_Wshadow,
+ "declaration of %q#D shadows a parameter", x);
+ warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
+ "shadowed declaration is here");
}
}
else if (oldlocal != NULL_TREE
&& TREE_CODE (oldlocal) == VAR_DECL)
{
- warning (OPT_Wshadow, "declaration of %qD shadows a previous local", x);
- warning (OPT_Wshadow, "%Jshadowed declaration is here", oldlocal);
+ warning_at (input_location, OPT_Wshadow,
+ "declaration of %qD shadows a previous local", x);
+ warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
+ "shadowed declaration is here");
}
else if (oldglobal != NULL_TREE
&& TREE_CODE (oldglobal) == VAR_DECL)
/* XXX shadow warnings in outer-more namespaces */
{
- warning (OPT_Wshadow, "declaration of %qD shadows a global declaration",
- x);
- warning (OPT_Wshadow, "%Jshadowed declaration is here", oldglobal);
+ warning_at (input_location, OPT_Wshadow,
+ "declaration of %qD shadows a global declaration", x);
+ warning_at (DECL_SOURCE_LOCATION (oldglobal), OPT_Wshadow,
+ "shadowed declaration is here");
}
}
}
static bool keep_next_level_flag;
static int binding_depth = 0;
-static int is_class_level = 0;
static void
indent (int depth)
scope->binding_depth = binding_depth;
indent (binding_depth);
cxx_scope_debug (scope, input_line, "push");
- is_class_level = 0;
binding_depth++;
}
}
{
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");
- }
- is_class_level = 0;
}
/* Move one nesting level up. */
b->binding_depth = binding_depth;
indent (binding_depth);
cxx_scope_debug (b, input_line, "resume");
- is_class_level = 0;
binding_depth++;
}
}
return get_identifier (buf);
}
+/* This code is practically identical to that for creating
+ anonymous names, but is just used for lambdas instead. This is necessary
+ because anonymous names are recognized and cannot be passed to template
+ functions. */
+/* FIXME is this still necessary? */
+
+static GTY(()) int lambda_cnt = 0;
+
+tree
+make_lambda_name (void)
+{
+ char buf[32];
+
+ sprintf (buf, LAMBDANAME_FORMAT, lambda_cnt++);
+ return get_identifier (buf);
+}
+
/* Return (from the stack of) the BINDING, if any, established at SCOPE. */
static inline cxx_binding *
void
pushlevel_class (void)
{
- if (ENABLE_SCOPE_CHECKING)
- is_class_level = 1;
-
class_binding_level = begin_scope (sk_class, current_class_type);
}
/* Now, pop out of the binding level which we created up in the
`pushlevel_class' routine. */
- if (ENABLE_SCOPE_CHECKING)
- is_class_level = 1;
-
+ gcc_assert (current_binding_level == level);
leave_scope ();
timevar_pop (TV_NAME_LOOKUP);
}
tree name;
bool is_valid = true;
+ /* Do nothing if we're adding to an outer lambda closure type,
+ outer_binding will add it later if it's needed. */
+ if (current_class_type != class_binding_level->this_entity)
+ return true;
+
timevar_push (TV_NAME_LOOKUP);
/* Get the name of X. */
if (TREE_CODE (x) == OVERLOAD)
/* Check for invalid member names. */
gcc_assert (TYPE_BEING_DEFINED (current_class_type));
+ /* Check that we're pushing into the right binding level. */
+ gcc_assert (current_class_type == class_binding_level->this_entity);
+
/* 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. */
void
set_decl_namespace (tree decl, tree scope, bool friendp)
{
- tree old, fn;
+ tree old;
/* Get rid of namespace aliases. */
scope = ORIGINAL_NAMESPACE (scope);
if (old == error_mark_node)
/* No old declaration at all. */
goto complain;
+ /* If it's a TREE_LIST, the result of the lookup was ambiguous. */
+ if (TREE_CODE (old) == TREE_LIST)
+ {
+ error ("reference to %qD is ambiguous", decl);
+ print_candidates (old);
+ 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
- point. pushdecl will find those errors later. */
- return;
+ {
+ /* We might have found OLD in an inline namespace inside SCOPE. */
+ DECL_CONTEXT (decl) = DECL_CONTEXT (old);
+ /* Don't compare non-function decls with decls_match here, since
+ it can't check for the correct constness at this
+ point. pushdecl will find those errors later. */
+ return;
+ }
/* 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;
return;
if (is_overloaded_fn (old))
{
- for (; old; old = OVL_NEXT (old))
- if (decls_match (decl, OVL_CURRENT (old)))
+ tree found = NULL_TREE;
+ tree elt = old;
+ for (; elt; elt = OVL_NEXT (elt))
+ {
+ tree ofn = OVL_CURRENT (elt);
+ /* Adjust DECL_CONTEXT first so decls_match will return true
+ if DECL will match a declaration in an inline namespace. */
+ DECL_CONTEXT (decl) = DECL_CONTEXT (ofn);
+ if (decls_match (decl, ofn))
+ {
+ if (found && !decls_match (found, ofn))
+ {
+ DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
+ error ("reference to %qD is ambiguous", decl);
+ print_candidates (old);
+ return;
+ }
+ found = ofn;
+ }
+ }
+ if (found)
+ {
+ if (!is_associated_namespace (scope, CP_DECL_CONTEXT (found)))
+ goto complain;
+ DECL_CONTEXT (decl) = DECL_CONTEXT (found);
return;
+ }
}
- else if (decls_match (decl, old))
- return;
+ else
+ {
+ DECL_CONTEXT (decl) = DECL_CONTEXT (old);
+ if (decls_match (decl, old))
+ return;
+ }
+
+ /* It didn't work, go back to the explicit scope. */
+ DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
complain:
error ("%qD should have been declared inside %qD", decl, scope);
}
"%qD attribute is meaningless since members of the "
"anonymous namespace get local symbols", name);
- push_visibility (TREE_STRING_POINTER (x));
+ push_visibility (TREE_STRING_POINTER (x), 1);
saw_vis = true;
}
else
gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
if (building_stmt_tree ())
- add_stmt (build_stmt (USING_STMT, name_space));
+ add_stmt (build_stmt (input_location, USING_STMT, name_space));
name_space = ORIGINAL_NAMESPACE (name_space);
if (!toplevel_bindings_p ())
push_to_top_level ();
x = pushdecl_namespace_level (x, is_friend);
if (init)
- finish_decl (x, *init, NULL_TREE);
+ cp_finish_decl (x, *init, false, NULL_TREE, 0);
pop_from_top_level ();
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
}
/* If the function from S2 is already in S1, there is no
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
- || (DECL_EXTERN_C_P (fn1) && DECL_EXTERN_C_P (fn2)
- && DECL_NAME (fn1) == DECL_NAME (fn2)))
+ different namespaces, but let's leave them in in case
+ they have different default arguments. */
+ if (fn1 == fn2)
break;
}
return true;
if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
return false;
+ /* In unevaluated context, look past normal capture fields. */
+ if (cp_unevaluated_operand && TREE_CODE (val) == FIELD_DECL
+ && DECL_NORMAL_CAPTURE_P (val))
+ return false;
return true;
}
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
}
+/* Returns true iff VEC contains TARGET. */
+
+static bool
+tree_vec_contains (VEC(tree,gc)* vec, tree target)
+{
+ unsigned int i;
+ tree elt;
+ for (i = 0; VEC_iterate(tree,vec,i,elt); ++i)
+ if (elt == target)
+ return true;
+ return false;
+}
+
/* [namespace.qual]
Accepts the NAME to lookup and its qualifying SCOPE.
Returns the name/type pair found into the cxx_binding *RESULT,
struct scope_binding *result, int flags)
{
/* Maintain a list of namespaces visited... */
- tree seen = NULL_TREE;
+ VEC(tree,gc) *seen = NULL;
+ VEC(tree,gc) *seen_inline = NULL;
/* ... and a list of namespace yet to see. */
- tree todo = NULL_TREE;
- tree todo_maybe = NULL_TREE;
+ VEC(tree,gc) *todo = NULL;
+ VEC(tree,gc) *todo_maybe = NULL;
+ VEC(tree,gc) *todo_inline = NULL;
tree usings;
timevar_push (TV_NAME_LOOKUP);
/* Look through namespace aliases. */
scope = ORIGINAL_NAMESPACE (scope);
- while (scope && result->value != error_mark_node)
+
+ /* Algorithm: Starting with SCOPE, walk through the the set of used
+ namespaces. For each used namespace, look through its inline
+ namespace set for any bindings and usings. If no bindings are found,
+ add any usings seen to the set of used namespaces. */
+ VEC_safe_push (tree, gc, todo, scope);
+
+ while (VEC_length (tree, todo))
{
- cxx_binding *binding =
- cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
- seen = tree_cons (scope, NULL_TREE, seen);
- if (binding)
- 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
- non-strong ones if the initial RESULT is non-NULL, but the
- binding in the given namespace is? */
- for (usings = DECL_NAMESPACE_USING (scope); usings;
- usings = TREE_CHAIN (usings))
- /* If this was a real directive, and we have not seen it. */
- if (!TREE_INDIRECT_USING (usings))
- {
- /* Try to avoid queuing the same namespace more than once,
- the exception being when a namespace was already
- enqueued for todo_maybe and then a strong using is
- found for it. We could try to remove it from
- todo_maybe, but it's probably not worth the effort. */
- if (is_associated_namespace (scope, TREE_PURPOSE (usings))
- && !purpose_member (TREE_PURPOSE (usings), seen)
- && !purpose_member (TREE_PURPOSE (usings), todo))
- todo = tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo);
- else if ((!result->value && !result->type)
- && !purpose_member (TREE_PURPOSE (usings), seen)
- && !purpose_member (TREE_PURPOSE (usings), todo)
- && !purpose_member (TREE_PURPOSE (usings), todo_maybe))
- todo_maybe = tree_cons (TREE_PURPOSE (usings), NULL_TREE,
- todo_maybe);
- }
- if (todo)
- {
- scope = TREE_PURPOSE (todo);
- todo = TREE_CHAIN (todo);
- }
- else if (todo_maybe
- && (!result->value && !result->type))
+ bool found_here;
+ scope = VEC_pop (tree, todo);
+ if (tree_vec_contains (seen, scope))
+ continue;
+ VEC_safe_push (tree, gc, seen, scope);
+ VEC_safe_push (tree, gc, todo_inline, scope);
+
+ found_here = false;
+ while (VEC_length (tree, todo_inline))
{
- scope = TREE_PURPOSE (todo_maybe);
- todo = TREE_CHAIN (todo_maybe);
- todo_maybe = NULL_TREE;
+ cxx_binding *binding;
+
+ scope = VEC_pop (tree, todo_inline);
+ if (tree_vec_contains (seen_inline, scope))
+ continue;
+ VEC_safe_push (tree, gc, seen_inline, scope);
+
+ binding =
+ cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+ if (binding)
+ {
+ found_here = true;
+ ambiguous_decl (result, binding, flags);
+ }
+
+ for (usings = DECL_NAMESPACE_USING (scope); usings;
+ usings = TREE_CHAIN (usings))
+ if (!TREE_INDIRECT_USING (usings))
+ {
+ if (is_associated_namespace (scope, TREE_PURPOSE (usings)))
+ VEC_safe_push (tree, gc, todo_inline, TREE_PURPOSE (usings));
+ else
+ VEC_safe_push (tree, gc, todo_maybe, TREE_PURPOSE (usings));
+ }
}
+
+ if (found_here)
+ VEC_truncate (tree, todo_maybe, 0);
else
- scope = NULL_TREE; /* If there never was a todo list. */
+ while (VEC_length (tree, todo_maybe))
+ VEC_safe_push (tree, gc, todo, VEC_pop (tree, todo_maybe));
}
+ VEC_free (tree,gc,todo);
+ VEC_free (tree,gc,todo_maybe);
+ VEC_free (tree,gc,todo_inline);
+ VEC_free (tree,gc,seen);
+ VEC_free (tree,gc,seen_inline);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
}
}
tree
-lookup_function_nonclass (tree name, tree args, bool block_p)
+lookup_function_nonclass (tree name, VEC(tree,gc) *args, bool block_p)
{
return
lookup_arg_dependent (name,
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
+/* Returns true iff DECL is a block-scope extern declaration of a function
+ or variable. */
+
+bool
+is_local_extern (tree decl)
+{
+ cxx_binding *binding;
+
+ /* For functions, this is easy. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ return DECL_LOCAL_FUNCTION_P (decl);
+
+ if (TREE_CODE (decl) != VAR_DECL)
+ return false;
+ if (!current_function_decl)
+ return false;
+
+ /* For variables, this is not easy. We need to look at the binding stack
+ for the identifier to see whether the decl we have is a local. */
+ for (binding = IDENTIFIER_BINDING (DECL_NAME (decl));
+ binding && binding->scope->kind != sk_namespace;
+ binding = binding->previous)
+ if (binding->value == decl)
+ return LOCAL_BINDING_P (binding);
+
+ return false;
+}
+
/* Like lookup_name_innermost_nonclass_level, but for types. */
static tree
struct arg_lookup
{
tree name;
- tree args;
+ VEC(tree,gc) *args;
tree namespaces;
tree classes;
tree functions;
static bool arg_assoc (struct arg_lookup*, tree);
static bool arg_assoc_args (struct arg_lookup*, tree);
+static bool arg_assoc_args_vec (struct arg_lookup*, VEC(tree,gc) *);
static bool arg_assoc_type (struct arg_lookup*, tree);
static bool add_function (struct arg_lookup *, tree);
static bool arg_assoc_namespace (struct arg_lookup *, tree);
total number of functions being compared, which should usually be the
case. */
- /* We must find only functions, or exactly one non-function. */
- if (!k->functions)
+ if (!is_overloaded_fn (fn))
+ /* All names except those of (possibly overloaded) functions and
+ function templates are ignored. */;
+ else if (!k->functions)
k->functions = fn;
else if (fn == k->functions)
;
- else if (is_overloaded_fn (k->functions) && is_overloaded_fn (fn))
- k->functions = build_overload (fn, k->functions);
else
- {
- tree f1 = OVL_CURRENT (k->functions);
- tree f2 = fn;
- if (is_overloaded_fn (f1))
- {
- fn = f1; f1 = f2; f2 = fn;
- }
- error ("%q+D is not a function,", f1);
- error (" conflict with %q+D", f2);
- error (" in call to %qD", k->name);
- return true;
- }
+ k->functions = build_overload (fn, k->functions);
return false;
}
classes. */
if (hidden_name_p (OVL_CURRENT (value)))
{
- tree args;
+ unsigned int ix;
+ tree arg;
- for (args = k->args; args; args = TREE_CHAIN (args))
- if (friend_of_associated_class_p (TREE_VALUE (args),
- OVL_CURRENT (value)))
+ for (ix = 0; VEC_iterate (tree, k->args, ix, arg); ++ix)
+ if (friend_of_associated_class_p (arg, OVL_CURRENT (value)))
break;
- if (!args)
+ if (ix >= VEC_length (tree, k->args))
continue;
}
if (arg_assoc_namespace (k, context))
return true;
+ complete_type (type);
+
if (TYPE_BINFO (type))
{
/* Process baseclasses. */
return false;
}
+/* Adds everything associated with an argument vector. Returns true
+ on error. */
+
+static bool
+arg_assoc_args_vec (struct arg_lookup *k, VEC(tree,gc) *args)
+{
+ unsigned int ix;
+ tree arg;
+
+ for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
+ if (arg_assoc (k, arg))
+ return true;
+ return false;
+}
+
/* Adds everything associated with a given tree_node. Returns 1 on error. */
static bool
are the functions found in normal lookup. */
tree
-lookup_arg_dependent (tree name, tree fns, tree args)
+lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args)
{
struct arg_lookup k;
picking up later definitions) in the second stage. */
k.namespaces = NULL_TREE;
- arg_assoc_args (&k, args);
+ arg_assoc_args_vec (&k, args);
fns = k.functions;
{
tree cs = current_scope ();
- if (scope == ts_current)
+ if (scope == ts_current
+ || (cs && TREE_CODE (cs) == FUNCTION_DECL))
context = cs;
else if (cs != NULL_TREE && TYPE_P (cs))
/* When declaring a friend class of a local class, we want
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;
s->bindings = b;
s->need_pop_function_context = need_pop;
s->function_decl = current_function_decl;
- s->skip_evaluation = skip_evaluation;
+ s->unevaluated_operand = cp_unevaluated_operand;
+ s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
scope_chain = s;
current_function_decl = NULL_TREE;
current_lang_name = lang_name_cplusplus;
current_namespace = global_namespace;
push_class_stack ();
- skip_evaluation = 0;
+ cp_unevaluated_operand = 0;
+ c_inhibit_evaluation_warnings = 0;
timevar_pop (TV_NAME_LOOKUP);
}
if (s->need_pop_function_context)
pop_function_context ();
current_function_decl = s->function_decl;
- skip_evaluation = s->skip_evaluation;
+ cp_unevaluated_operand = s->unevaluated_operand;
+ c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings;
timevar_pop (TV_NAME_LOOKUP);
}
if (TREE_CODE (t) != TEMPLATE_DECL)
{
if (building_stmt_tree ())
- add_stmt (build_stmt (USING_STMT, t));
+ add_stmt (build_stmt (input_location, USING_STMT, t));
else
(*debug_hooks->imported_module_or_decl) (t, NULL_TREE, context, false);
}