X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fname-lookup.c;h=06726da74ea8ea14a382f62b6b35949e6803a2be;hb=221024763ee5ab708e44a54e3514cd209ce5b686;hp=41feb57898e8d40b55df08caa7c8efb18a0c59f0;hpb=9dd72ec43737ca9d1ec49315d4a5e0fdd3d578f2;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 41feb57898e..06726da74ea 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1,5 +1,5 @@ /* Definitions for C++ name lookup routines. - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis @@ -28,10 +28,12 @@ along with GCC; see the file COPYING3. If not see #include "cp-tree.h" #include "name-lookup.h" #include "timevar.h" -#include "toplev.h" #include "diagnostic-core.h" +#include "intl.h" #include "debug.h" #include "c-family/c-pragma.h" +#include "params.h" +#include "pointer-set.h" /* The bindings for a particular name in a particular scope. */ @@ -318,33 +320,11 @@ new_class_binding (tree name, tree value, tree type, cxx_scope *scope) cp_class_binding *cb; cxx_binding *binding; - if (VEC_length (cp_class_binding, scope->class_shadowed)) - { - cp_class_binding *old_base; - old_base = VEC_index (cp_class_binding, scope->class_shadowed, 0); - if (VEC_reserve (cp_class_binding, gc, scope->class_shadowed, 1)) - { - /* Fixup the current bindings, as they might have moved. */ - size_t i; - - FOR_EACH_VEC_ELT (cp_class_binding, scope->class_shadowed, i, cb) - { - cxx_binding **b; - b = &IDENTIFIER_BINDING (cb->identifier); - while (*b != &old_base[i].base) - b = &((*b)->previous); - *b = &cb->base; - } - } - cb = VEC_quick_push (cp_class_binding, scope->class_shadowed, NULL); - } - else cb = VEC_safe_push (cp_class_binding, gc, scope->class_shadowed, NULL); cb->identifier = name; - binding = &cb->base; + cb->base = binding = cxx_binding_make (value, type); binding->scope = scope; - cxx_binding_init (binding, value, type); return binding; } @@ -433,12 +413,11 @@ pop_binding (tree id, tree decl) was successful. */ static bool -supplement_binding (cxx_binding *binding, tree decl) +supplement_binding_1 (cxx_binding *binding, tree decl) { tree bval = binding->value; bool ok = true; - timevar_push (TV_NAME_LOOKUP); if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) /* The new name is the type name. */ binding->type = decl; @@ -458,7 +437,9 @@ supplement_binding (cxx_binding *binding, tree decl) && DECL_ANTICIPATED (bval) && !DECL_HIDDEN_FRIEND_P (bval))) binding->value = decl; - else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)) + else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval) + && (TREE_CODE (decl) != TYPE_DECL + || same_type_p (TREE_TYPE (decl), TREE_TYPE (bval)))) { /* The old binding was a type name. It was placed in VALUE field because it was thought, at the point it was @@ -525,7 +506,19 @@ supplement_binding (cxx_binding *binding, tree decl) ok = false; } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok); + return ok; +} + +/* Wrapper for supplement_binding_1. */ + +static bool +supplement_binding (cxx_binding *binding, tree decl) +{ + bool ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = supplement_binding_1 (binding, decl); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Add DECL to the list of things declared in B. */ @@ -549,7 +542,6 @@ add_decl_to_level (tree decl, cxx_scope *b) 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 @@ -573,17 +565,15 @@ add_decl_to_level (tree decl, cxx_scope *b) If an old decl is returned, it may have been smashed to agree with what X says. */ -tree -pushdecl_maybe_friend (tree x, bool is_friend) +static tree +pushdecl_maybe_friend_1 (tree x, bool is_friend) { tree t; tree name; int need_new_binding; - timevar_push (TV_NAME_LOOKUP); - if (x == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; need_new_binding = 1; @@ -719,7 +709,7 @@ pushdecl_maybe_friend (tree x, bool is_friend) /* Check for duplicate params. */ tree d = duplicate_decls (x, t, is_friend); if (d) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, d); + return d; } else if ((DECL_EXTERN_C_FUNCTION_P (x) || DECL_FUNCTION_TEMPLATE_P (x)) @@ -732,7 +722,7 @@ pushdecl_maybe_friend (tree x, bool is_friend) TREE_TYPE (x)); /* Throw away the redeclaration. */ - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + return t; } else { @@ -741,14 +731,14 @@ pushdecl_maybe_friend (tree x, bool is_friend) /* If the redeclaration failed, we can stop at this point. */ if (olddecl == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; if (olddecl) { if (TREE_CODE (t) == TYPE_DECL) SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t)); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + return t; } else if (DECL_MAIN_P (x) && TREE_CODE (t) == FUNCTION_DECL) { @@ -762,7 +752,7 @@ pushdecl_maybe_friend (tree x, bool is_friend) error ("as %qD", x); /* We don't try to push this declaration since that causes a crash. */ - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); + return x; } } } @@ -805,12 +795,15 @@ pushdecl_maybe_friend (tree x, bool is_friend) x_exception_spec, ce_normal)) { - pedwarn (input_location, 0, "declaration of %q#D with C language linkage", + pedwarn (input_location, 0, + "declaration of %q#D with C language linkage", x); - pedwarn (input_location, 0, "conflicts with previous declaration %q+#D", + pedwarn (input_location, 0, + "conflicts with previous declaration %q+#D", previous); - pedwarn (input_location, 0, "due to different exception specifications"); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + pedwarn (input_location, 0, + "due to different exception specifications"); + return error_mark_node; } } else @@ -855,7 +848,7 @@ pushdecl_maybe_friend (tree x, bool is_friend) check_default_args (t); if (t != x || DECL_FUNCTION_TEMPLATE_P (t)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + return t; /* 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 @@ -872,7 +865,7 @@ pushdecl_maybe_friend (tree x, bool is_friend) inlining. */ && (!TYPE_NAME (type) || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x)))) - cp_set_underlying_type (x); + set_underlying_type (x); if (type != error_mark_node && TYPE_NAME (type) @@ -944,8 +937,15 @@ pushdecl_maybe_friend (tree x, bool is_friend) else { /* Here to install a non-global value. */ - tree oldlocal = innermost_non_namespace_value (name); tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name); + tree oldlocal = NULL_TREE; + cxx_scope *oldscope = NULL; + cxx_binding *oldbinding = outer_binding (name, NULL, true); + if (oldbinding) + { + oldlocal = oldbinding->value; + oldscope = oldbinding->scope; + } if (need_new_binding) { @@ -992,7 +992,7 @@ pushdecl_maybe_friend (tree x, bool is_friend) /* OK */; else { - warning (0, "extern declaration of %q#D doesn't match", x); + warning (0, "extern declaration of %q#D doesn%'t match", x); warning (0, "global declaration %q+#D", oldglobal); } } @@ -1022,11 +1022,6 @@ pushdecl_maybe_friend (tree x, bool is_friend) || (TREE_CODE (oldlocal) == TYPE_DECL && (!DECL_ARTIFICIAL (oldlocal) || TREE_CODE (x) == TYPE_DECL))) - /* Don't check the `this' parameter or internally generated - vars unless it's an implicit typedef (see - create_implicit_typedef in decl.c). */ - && (!DECL_ARTIFICIAL (oldlocal) - || DECL_IMPLICIT_TYPEDEF_P (oldlocal)) /* Don't check for internally generated vars unless it's an implicit typedef (see create_implicit_typedef in decl.c). */ @@ -1074,12 +1069,30 @@ pushdecl_maybe_friend (tree x, bool is_friend) } } } + /* Error if redeclaring a local declared in a + for-init-statement or in the condition of an if or + switch statement when the new declaration is in the + outermost block of the controlled statement. + Redeclaring a variable from a for or while condition is + detected elsewhere. */ + else if (TREE_CODE (oldlocal) == VAR_DECL + && oldscope == current_binding_level->level_chain + && (oldscope->kind == sk_cond + || oldscope->kind == sk_for)) + { + error ("redeclaration of %q#D", x); + error ("%q+#D previously declared here", oldlocal); + } if (warn_shadow && !nowarn) { if (TREE_CODE (oldlocal) == PARM_DECL) warning_at (input_location, OPT_Wshadow, "declaration of %q#D shadows a parameter", x); + else if (is_capture_proxy (oldlocal)) + warning_at (input_location, OPT_Wshadow, + "declaration of %qD shadows a lambda capture", + x); else warning_at (input_location, OPT_Wshadow, "declaration of %qD shadows a previous local", @@ -1142,7 +1155,19 @@ pushdecl_maybe_friend (tree x, bool is_friend) ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x)) : current_binding_level); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); + return x; +} + +/* Wrapper for pushdecl_maybe_friend_1. */ + +tree +pushdecl_maybe_friend (tree x, bool is_friend) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = pushdecl_maybe_friend_1 (x, is_friend); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Record a decl-node X as belonging to the current lexical scope. */ @@ -1169,7 +1194,7 @@ maybe_push_decl (tree decl) && DECL_CONTEXT (decl) != NULL_TREE /* Definitions of namespace members outside their namespace are possible. */ - && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL) + && !DECL_NAMESPACE_SCOPE_P (decl)) || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ()) || type == unknown_type_node /* The declaration of a template specialization does not affect @@ -1421,6 +1446,7 @@ begin_scope (scope_kind kind, tree entity) case sk_try: case sk_catch: case sk_for: + case sk_cond: case sk_class: case sk_scoped_enum: case sk_function_parms: @@ -1551,9 +1577,9 @@ maybe_push_cleanup_level (tree type) } } -/* Nonzero if we are currently in the global binding level. */ +/* Return true if we are in the global binding level. */ -int +bool global_bindings_p (void) { return global_scope_p (current_binding_level); @@ -1634,6 +1660,22 @@ getdecls (void) return current_binding_level->names; } +/* Return how many function prototypes we are currently nested inside. */ + +int +function_parm_depth (void) +{ + int level = 0; + struct cp_binding_level *b; + + for (b = current_binding_level; + b->kind == sk_function_parms; + b = b->level_chain) + ++level; + + return level; +} + /* For debugging. */ static int no_print_functions = 0; static int no_print_builtins = 0; @@ -1737,26 +1779,38 @@ print_binding_stack (void) print_binding_level (NAMESPACE_LEVEL (global_namespace)); } -/* Return the type associated with id. */ +/* Return the type associated with ID. */ -tree -identifier_type_value (tree id) +static tree +identifier_type_value_1 (tree id) { - timevar_push (TV_NAME_LOOKUP); /* There is no type with that name, anywhere. */ if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + return NULL_TREE; /* This is not the type marker, but the real thing. */ if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, REAL_IDENTIFIER_TYPE_VALUE (id)); + return REAL_IDENTIFIER_TYPE_VALUE (id); /* Have to search for it. It must be on the global level, now. Ask lookup_name not to return non-types. */ id = lookup_name_real (id, 2, 1, /*block_p=*/true, 0, LOOKUP_COMPLAIN); if (id) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_TYPE (id)); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + return TREE_TYPE (id); + return NULL_TREE; +} + +/* Wrapper for identifier_type_value_1. */ + +tree +identifier_type_value (tree id) +{ + tree ret; + timevar_start (TV_NAME_LOOKUP); + ret = identifier_type_value_1 (id); + timevar_stop (TV_NAME_LOOKUP); + return ret; } + /* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++. */ @@ -1897,13 +1951,11 @@ make_lambda_name (void) static inline cxx_binding * find_binding (cxx_scope *scope, cxx_binding *binding) { - timevar_push (TV_NAME_LOOKUP); - for (; binding != NULL; binding = binding->previous) if (binding->scope == scope) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding); + return binding; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (cxx_binding *)0); + return (cxx_binding *)0; } /* Return the binding for NAME in SCOPE, if any. Otherwise, return NULL. */ @@ -1982,36 +2034,50 @@ lookup_extern_c_fun_binding_in_all_ns (tree function) scope, a using decl might extend any previous bindings). */ static tree -push_using_decl (tree scope, tree name) +push_using_decl_1 (tree scope, tree name) { tree decl; - timevar_push (TV_NAME_LOOKUP); gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL); gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); for (decl = current_binding_level->usings; decl; decl = DECL_CHAIN (decl)) 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); + return namespace_bindings_p () ? decl : NULL_TREE; decl = build_lang_decl (USING_DECL, name, NULL_TREE); USING_DECL_SCOPE (decl) = scope; DECL_CHAIN (decl) = current_binding_level->usings; current_binding_level->usings = decl; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; +} + +/* Wrapper for push_using_decl_1. */ + +static tree +push_using_decl (tree scope, tree name) +{ + tree ret; + timevar_start (TV_NAME_LOOKUP); + ret = push_using_decl_1 (scope, name); + timevar_stop (TV_NAME_LOOKUP); + return ret; } /* Same as pushdecl, but define X in binding-level LEVEL. We rely on the - caller to set DECL_CONTEXT properly. */ + caller to set DECL_CONTEXT properly. -tree -pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend) + Note that this must only be used when X will be the new innermost + binding for its name, as we tack it onto the front of IDENTIFIER_BINDING + without checking to see if the current IDENTIFIER_BINDING comes from a + closer binding level than LEVEL. */ + +static tree +pushdecl_with_scope_1 (tree x, cxx_scope *level, bool is_friend) { struct cp_binding_level *b; tree function_decl = current_function_decl; - timevar_push (TV_NAME_LOOKUP); current_function_decl = NULL_TREE; if (level->kind == sk_class) { @@ -2028,8 +2094,21 @@ pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend) current_binding_level = b; } current_function_decl = function_decl; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); + return x; } + +/* Wrapper for pushdecl_with_scope_1. */ + +tree +pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = pushdecl_with_scope_1 (x, level, is_friend); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; +} + /* DECL is a FUNCTION_DECL for a non-member function, which may have other definitions already in place. We get around this by making @@ -2053,14 +2132,13 @@ pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend) it's always DECL (and never something that's not a _DECL). */ static tree -push_overloaded_decl (tree decl, int flags, bool is_friend) +push_overloaded_decl_1 (tree decl, int flags, bool is_friend) { tree name = DECL_NAME (decl); tree old; tree new_binding; int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL)); - timevar_push (TV_NAME_LOOKUP); if (doing_global) old = namespace_binding (name, DECL_CONTEXT (decl)); else @@ -2098,7 +2176,7 @@ push_overloaded_decl (tree decl, int flags, bool 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); + return dup; } /* We don't overload implicit built-ins. duplicate_decls() @@ -2116,7 +2194,7 @@ push_overloaded_decl (tree decl, int flags, bool is_friend) { error ("previous non-function declaration %q+#D", old); error ("conflicts with function declaration %q#D", decl); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; } } @@ -2168,7 +2246,7 @@ push_overloaded_decl (tree decl, int flags, bool is_friend) /* And update the cxx_binding node. */ IDENTIFIER_BINDING (name)->value = new_binding; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; } /* We should always find a previous binding in this case. */ @@ -2179,7 +2257,19 @@ push_overloaded_decl (tree decl, int flags, bool is_friend) push_local_binding (name, new_binding, flags); } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; +} + +/* Wrapper for push_overloaded_decl_1. */ + +static tree +push_overloaded_decl (tree decl, int flags, bool is_friend) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = push_overloaded_decl_1 (decl, flags, is_friend); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Check a non-member using-declaration. Return the name and scope @@ -2391,7 +2481,7 @@ do_local_using_decl (tree decl, tree scope, tree name) if (decl == NULL_TREE) return; - if (building_stmt_tree () + if (building_stmt_list_p () && at_function_scope_p ()) add_decl_expr (decl); @@ -2626,7 +2716,7 @@ poplevel_class (void) size_t i; tree shadowed; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); gcc_assert (level != 0); /* If we're leaving a toplevel class, cache its binding level. */ @@ -2641,7 +2731,10 @@ poplevel_class (void) if (level->class_shadowed) { FOR_EACH_VEC_ELT (cp_class_binding, level->class_shadowed, i, cb) - IDENTIFIER_BINDING (cb->identifier) = cb->base.previous; + { + IDENTIFIER_BINDING (cb->identifier) = cb->base->previous; + cxx_binding_free (cb->base); + } ggc_free (level->class_shadowed); level->class_shadowed = NULL; } @@ -2650,7 +2743,7 @@ poplevel_class (void) `pushlevel_class' routine. */ gcc_assert (current_binding_level == level); leave_scope (); - timevar_pop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } /* Set INHERITED_VALUE_BINDING_P on BINDING to true or false, as @@ -2694,13 +2787,14 @@ pushdecl_class_level (tree x) { tree name; bool is_valid = true; + bool subtime; /* 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); + subtime = timevar_cond_start (TV_NAME_LOOKUP); /* Get the name of X. */ if (TREE_CODE (x) == OVERLOAD) name = DECL_NAME (get_first_fn (x)); @@ -2729,7 +2823,8 @@ pushdecl_class_level (tree x) input_location = save_location; } } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, is_valid); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return is_valid; } /* Return the BINDING (if any) for NAME in SCOPE, which is a class @@ -2796,21 +2891,20 @@ get_class_binding (tree name, cxx_scope *scope) /* Make the declaration(s) of X appear in CLASS scope under the name NAME. Returns true if the binding is valid. */ -bool -push_class_level_binding (tree name, tree x) +static bool +push_class_level_binding_1 (tree name, tree x) { cxx_binding *binding; tree decl = x; bool ok; - timevar_push (TV_NAME_LOOKUP); /* The class_binding_level will be NULL if x is a template parameter name in a member template. */ if (!class_binding_level) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + return true; if (name == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false); + return false; /* Check for invalid member names. */ gcc_assert (TYPE_BEING_DEFINED (current_class_type)); @@ -2825,7 +2919,7 @@ push_class_level_binding (tree name, tree x) decl = TREE_VALUE (decl); if (!check_template_shadow (decl)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false); + return false; /* [class.mem] @@ -2859,7 +2953,7 @@ push_class_level_binding (tree name, tree x) error ("%qD has the same name as the class in which it is " "declared", x); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false); + return false; } } @@ -2910,11 +3004,11 @@ push_class_level_binding (tree name, tree x) else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval)) old_decl = bval; else if (TREE_CODE (x) == USING_DECL && TREE_CODE (bval) == USING_DECL) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + return true; else if (TREE_CODE (x) == USING_DECL && is_overloaded_fn (bval)) old_decl = bval; else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + return true; if (old_decl && binding->scope == class_binding_level) { @@ -2923,7 +3017,7 @@ push_class_level_binding (tree name, tree x) here. This function is only used to register bindings from with the class definition itself. */ INHERITED_VALUE_BINDING_P (binding) = 0; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + return true; } } @@ -2945,7 +3039,19 @@ push_class_level_binding (tree name, tree x) ok = true; } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok); + return ok; +} + +/* Wrapper for push_class_level_binding_1. */ + +bool +push_class_level_binding (tree name, tree x) +{ + bool ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = push_class_level_binding_1 (name, x); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Process "using SCOPE::NAME" in a class scope. Return the @@ -3063,12 +3169,13 @@ do_class_using_decl (tree scope, tree name) /* Return the binding value for name in scope. */ -tree -namespace_binding (tree name, tree scope) + +static tree +namespace_binding_1 (tree name, tree scope) { cxx_binding *binding; - if (scope == NULL) + if (SCOPE_FILE_SCOPE_P (scope)) scope = global_namespace; else /* Unnecessary for the global namespace because it can't be an alias. */ @@ -3079,14 +3186,23 @@ namespace_binding (tree name, tree scope) return binding ? binding->value : NULL_TREE; } +tree +namespace_binding (tree name, tree scope) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = namespace_binding_1 (name, scope); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; +} + /* Set the binding value for name in scope. */ -void -set_namespace_binding (tree name, tree scope, tree val) +static void +set_namespace_binding_1 (tree name, tree scope, tree val) { cxx_binding *b; - timevar_push (TV_NAME_LOOKUP); if (scope == NULL_TREE) scope = global_namespace; b = binding_for_name (NAMESPACE_LEVEL (scope), name); @@ -3094,7 +3210,16 @@ set_namespace_binding (tree name, tree scope, tree val) b->value = val; else supplement_binding (b, val); - timevar_pop (TV_NAME_LOOKUP); +} + +/* Wrapper for set_namespace_binding_1. */ + +void +set_namespace_binding (tree name, tree scope, tree val) +{ + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + set_namespace_binding_1 (name, scope, val); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } /* Set the context of a declaration to scope. Complain if we are not @@ -3239,7 +3364,6 @@ handle_namespace_attrs (tree ns, tree attributes) 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; @@ -3260,7 +3384,6 @@ handle_namespace_attrs (tree ns, tree attributes) saw_vis = true; } else -#endif { warning (OPT_Wattributes, "%qD attribute directive ignored", name); @@ -3282,7 +3405,7 @@ push_namespace (tree name) int implicit_use = 0; bool anon = !name; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (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 @@ -3342,7 +3465,7 @@ push_namespace (tree name) /* Enter the name space. */ current_namespace = d; - timevar_pop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } /* Pop from the scope of the current namespace. */ @@ -3377,7 +3500,7 @@ push_nested_namespace (tree ns) void pop_nested_namespace (tree ns) { - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); gcc_assert (current_namespace == ns); while (ns != global_namespace) { @@ -3386,7 +3509,7 @@ pop_nested_namespace (tree ns) } pop_from_top_level (); - timevar_pop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } /* Temporarily set the namespace for the current declaration. */ @@ -3411,13 +3534,26 @@ pop_decl_namespace (void) of two given namespaces. */ static tree -namespace_ancestor (tree ns1, tree ns2) +namespace_ancestor_1 (tree ns1, tree ns2) { - timevar_push (TV_NAME_LOOKUP); + tree nsr; 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)); + nsr = ns1; + else + nsr = namespace_ancestor_1 (CP_DECL_CONTEXT (ns1), ns2); + return nsr; +} + +/* Wrapper for namespace_ancestor_1. */ + +static tree +namespace_ancestor (tree ns1, tree ns2) +{ + tree nsr; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + nsr = namespace_ancestor_1 (ns1, ns2); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return nsr; } /* Process a namespace-alias declaration. */ @@ -3440,7 +3576,7 @@ do_namespace_alias (tree alias, tree name_space) pushdecl (alias); /* Emit debug info for namespace alias. */ - if (!building_stmt_tree ()) + if (!building_stmt_list_p ()) (*debug_hooks->global_decl) (alias); } @@ -3453,7 +3589,7 @@ pushdecl_namespace_level (tree x, bool is_friend) struct cp_binding_level *b = current_binding_level; tree t; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace), is_friend); /* Now, the type_shadowed stack may screw us. Munge it so it does @@ -3487,23 +3623,21 @@ pushdecl_namespace_level (tree x, bool is_friend) *ptr = newval; } } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return 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 -add_using_namespace (tree user, tree used, bool indirect) +add_using_namespace_1 (tree user, tree used, bool indirect) { tree t; - timevar_push (TV_NAME_LOOKUP); /* Using oneself is a no-op. */ if (user == used) - { - timevar_pop (TV_NAME_LOOKUP); - return; - } + return; gcc_assert (TREE_CODE (user) == NAMESPACE_DECL); gcc_assert (TREE_CODE (used) == NAMESPACE_DECL); /* Check if we already have this. */ @@ -3513,7 +3647,6 @@ add_using_namespace (tree user, tree used, bool indirect) if (!indirect) /* Promote to direct usage. */ TREE_INDIRECT_USING (t) = 0; - timevar_pop (TV_NAME_LOOKUP); return; } @@ -3531,12 +3664,21 @@ add_using_namespace (tree user, tree used, bool indirect) /* Recursively add all namespaces used. */ for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t)) /* indirect usage */ - add_using_namespace (user, TREE_PURPOSE (t), 1); + add_using_namespace_1 (user, TREE_PURPOSE (t), 1); /* Tell everyone using us about the new used namespaces. */ for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t)) - add_using_namespace (TREE_PURPOSE (t), used, 1); - timevar_pop (TV_NAME_LOOKUP); + add_using_namespace_1 (TREE_PURPOSE (t), used, 1); +} + +/* Wrapper for add_using_namespace_1. */ + +static void +add_using_namespace (tree user, tree used, bool indirect) +{ + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + add_using_namespace_1 (user, used, indirect); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } /* Process a using-declaration not appearing in class or local scope. */ @@ -3582,7 +3724,7 @@ do_using_directive (tree name_space) gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL); - if (building_stmt_tree ()) + if (building_stmt_list_p ()) add_stmt (build_stmt (input_location, USING_STMT, name_space)); name_space = ORIGINAL_NAMESPACE (name_space); @@ -3643,13 +3785,14 @@ parse_using_directive (tree name_space, tree attribs) static tree pushdecl_top_level_1 (tree x, tree *init, bool is_friend) { - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); push_to_top_level (); x = pushdecl_namespace_level (x, is_friend); if (init) cp_finish_decl (x, *init, false, NULL_TREE, 0); pop_from_top_level (); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return x; } /* Like pushdecl, only it places X in the global scope if appropriate. */ @@ -3863,13 +4006,8 @@ qualify_lookup (tree val, int flags) 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; - /* None of the lookups that use qualify_lookup want the op() from the - lambda; they want the one from the enclosing class. */ - if (TREE_CODE (val) == FUNCTION_DECL && LAMBDA_FUNCTION_P (val)) + /* Look through lambda things that we shouldn't be able to see. */ + if (is_lambda_ignored_entity (val)) return false; return true; } @@ -3919,11 +4057,73 @@ remove_hidden_names (tree fns) return fns; } +/* Suggest alternatives for NAME, an IDENTIFIER_NODE for which name + lookup failed. Search through all available namespaces and print out + possible candidates. */ + +void +suggest_alternatives_for (location_t location, tree name) +{ + VEC(tree,heap) *candidates = NULL; + VEC(tree,heap) *namespaces_to_search = NULL; + int max_to_search = PARAM_VALUE (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP); + int n_searched = 0; + tree t; + unsigned ix; + + VEC_safe_push (tree, heap, namespaces_to_search, global_namespace); + + while (!VEC_empty (tree, namespaces_to_search) + && n_searched < max_to_search) + { + tree scope = VEC_pop (tree, namespaces_to_search); + struct scope_binding binding = EMPTY_SCOPE_BINDING; + struct cp_binding_level *level = NAMESPACE_LEVEL (scope); + + /* Look in this namespace. */ + qualified_lookup_using_namespace (name, scope, &binding, 0); + + n_searched++; + + if (binding.value) + VEC_safe_push (tree, heap, candidates, binding.value); + + /* Add child namespaces. */ + for (t = level->namespaces; t; t = DECL_CHAIN (t)) + VEC_safe_push (tree, heap, namespaces_to_search, t); + } + + /* If we stopped before we could examine all namespaces, inform the + user. Do this even if we don't have any candidates, since there + might be more candidates further down that we weren't able to + find. */ + if (n_searched >= max_to_search + && !VEC_empty (tree, namespaces_to_search)) + inform (location, + "maximum limit of %d namespaces searched for %qE", + max_to_search, name); + + VEC_free (tree, heap, namespaces_to_search); + + /* Nothing useful to report. */ + if (VEC_empty (tree, candidates)) + return; + + inform_n (location, VEC_length (tree, candidates), + "suggested alternative:", + "suggested alternatives:"); + + FOR_EACH_VEC_ELT (tree, candidates, ix, t) + inform (location_of (t), " %qE", t); + + VEC_free (tree, heap, candidates); +} + /* Unscoped lookup of a global: iterate over current namespaces, considering using-directives. */ static tree -unqualified_namespace_lookup (tree name, int flags) +unqualified_namespace_lookup_1 (tree name, int flags) { tree initial = current_decl_namespace (); tree scope = initial; @@ -3931,8 +4131,6 @@ unqualified_namespace_lookup (tree name, int flags) struct cp_binding_level *level; tree val = NULL_TREE; - timevar_push (TV_NAME_LOOKUP); - for (; !val; scope = CP_DECL_CONTEXT (scope)) { struct scope_binding binding = EMPTY_SCOPE_BINDING; @@ -3949,7 +4147,7 @@ unqualified_namespace_lookup (tree name, int flags) if (!lookup_using_namespace (name, &binding, level->using_directives, scope, flags)) /* Give up because of error. */ - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; /* Add all _DECLs seen through global using-directives. */ /* XXX local and global using lists should work equally. */ @@ -3960,7 +4158,7 @@ unqualified_namespace_lookup (tree name, int flags) DECL_NAMESPACE_USING (siter), scope, flags)) /* Give up because of error. */ - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; if (siter == scope) break; siter = CP_DECL_CONTEXT (siter); } @@ -3969,7 +4167,19 @@ unqualified_namespace_lookup (tree name, int flags) if (scope == global_namespace) break; } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); + return val; +} + +/* Wrapper for unqualified_namespace_lookup_1. */ + +static tree +unqualified_namespace_lookup (tree name, int flags) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = unqualified_namespace_lookup_1 (name, flags); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL @@ -4019,7 +4229,7 @@ lookup_using_namespace (tree name, struct scope_binding *val, tree usings, tree scope, int flags) { tree iter; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); /* Iterate over all used namespaces in current, searching for using directives of scope. */ for (iter = usings; iter; iter = TREE_CHAIN (iter)) @@ -4032,7 +4242,8 @@ lookup_using_namespace (tree name, struct scope_binding *val, if (val1) ambiguous_decl (val, val1, flags); } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return val->value != error_mark_node; } /* Returns true iff VEC contains TARGET. */ @@ -4065,14 +4276,14 @@ qualified_lookup_using_namespace (tree name, tree scope, VEC(tree,gc) *todo_maybe = NULL; VEC(tree,gc) *todo_inline = NULL; tree usings; - timevar_push (TV_NAME_LOOKUP); + timevar_start (TV_NAME_LOOKUP); /* Look through namespace aliases. */ scope = ORIGINAL_NAMESPACE (scope); - /* Algorithm: Starting with SCOPE, walk through the the set of used + /* Algorithm: Starting with SCOPE, walk through 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. */ + 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)) @@ -4124,12 +4335,18 @@ qualified_lookup_using_namespace (tree name, tree scope, 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); + timevar_stop (TV_NAME_LOOKUP); + return result->value != error_mark_node; } /* Subroutine of outer_binding. - Returns TRUE if BINDING is a binding to a template parameter of SCOPE, - FALSE otherwise. */ + + Returns TRUE if BINDING is a binding to a template parameter of + SCOPE. In that case SCOPE is the scope of a primary template + parameter -- in the sense of G++, i.e, a template that has its own + template header. + + Returns FALSE otherwise. */ static bool binding_to_template_parms_of_scope_p (cxx_binding *binding, @@ -4145,6 +4362,8 @@ binding_to_template_parms_of_scope_p (cxx_binding *binding, return (scope && scope->this_entity && get_template_info (scope->this_entity) + && PRIMARY_TEMPLATE_P (TI_TEMPLATE + (get_template_info (scope->this_entity))) && parameter_of_template_p (binding_value, TI_TEMPLATE (get_template_info \ (scope->this_entity)))); @@ -4244,14 +4463,13 @@ innermost_non_namespace_value (tree name) If NONCLASS is nonzero, bindings in class scopes are ignored. If BLOCK_P is false, bindings in block scopes are ignored. */ -tree -lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, - int namespaces_only, int flags) +static tree +lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p, + int namespaces_only, int flags) { cxx_binding *iter; tree val = NULL_TREE; - timevar_push (TV_NAME_LOOKUP); /* Conversion operators are handled specially because ordinary unqualified name lookup will not find template conversion operators. */ @@ -4275,10 +4493,10 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, class_type = level->this_entity; operators = lookup_fnfields (class_type, name, /*protect=*/0); if (operators) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators); + return operators; } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + return NULL_TREE; } flags |= lookup_flags (prefer_type, namespaces_only); @@ -4373,7 +4591,21 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, if (val && TREE_CODE (val) == OVERLOAD && !really_overloaded_fn (val)) val = OVL_FUNCTION (val); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); + return val; +} + +/* Wrapper for lookup_name_real_1. */ + +tree +lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, + int namespaces_only, int flags) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = lookup_name_real_1 (name, prefer_type, nonclass, block_p, + namespaces_only, flags); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } tree @@ -4420,14 +4652,12 @@ lookup_name_prefer_type (tree name, int prefer_type) A TYPE_DECL best matching the NAME is returned. Catching error and issuing diagnostics are caller's responsibility. */ -tree -lookup_type_scope (tree name, tag_scope scope) +static tree +lookup_type_scope_1 (tree name, tag_scope scope) { cxx_binding *iter = NULL; tree val = NULL_TREE; - timevar_push (TV_NAME_LOOKUP); - /* Look in non-namespace scope first. */ if (current_binding_level->kind != sk_namespace) iter = outer_binding (name, NULL, /*class_p=*/ true); @@ -4482,7 +4712,7 @@ lookup_type_scope (tree name, tag_scope scope) while (b) { if (iter->scope == b) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); + return val; if (b->kind == sk_cleanup || b->kind == sk_template_parms || b->kind == sk_function_parms) @@ -4495,19 +4725,31 @@ lookup_type_scope (tree name, tag_scope scope) } } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + return NULL_TREE; } + +/* Wrapper for lookup_type_scope_1. */ + +tree +lookup_type_scope (tree name, tag_scope scope) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = lookup_type_scope_1 (name, scope); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; +} + /* Similar to `lookup_name' but look only in the innermost non-class binding level. */ -tree -lookup_name_innermost_nonclass_level (tree name) +static tree +lookup_name_innermost_nonclass_level_1 (tree name) { struct cp_binding_level *b; tree t = NULL_TREE; - timevar_push (TV_NAME_LOOKUP); b = innermost_nonclass_level (); if (b->kind == sk_namespace) @@ -4528,7 +4770,7 @@ lookup_name_innermost_nonclass_level (tree name) if (binding->scope == b && !(TREE_CODE (binding->value) == VAR_DECL && DECL_DEAD_FOR_LOCAL (binding->value))) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding->value); + return binding->value; if (b->kind == sk_cleanup) b = b->level_chain; @@ -4537,9 +4779,22 @@ lookup_name_innermost_nonclass_level (tree name) } } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + return t; } +/* Wrapper for lookup_name_innermost_nonclass_level_1. */ + +tree +lookup_name_innermost_nonclass_level (tree name) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = lookup_name_innermost_nonclass_level_1 (name); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; +} + + /* Returns true iff DECL is a block-scope extern declaration of a function or variable. */ @@ -4575,7 +4830,7 @@ lookup_type_current_level (tree name) { tree t = NULL_TREE; - timevar_push (TV_NAME_LOOKUP); + timevar_start (TV_NAME_LOOKUP); gcc_assert (current_binding_level->kind != sk_namespace); if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE @@ -4585,8 +4840,10 @@ lookup_type_current_level (tree name) while (1) { if (purpose_member (name, b->type_shadowed)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, - REAL_IDENTIFIER_TYPE_VALUE (name)); + { + t = REAL_IDENTIFIER_TYPE_VALUE (name); + break; + } if (b->kind == sk_cleanup) b = b->level_chain; else @@ -4594,7 +4851,8 @@ lookup_type_current_level (tree name) } } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + timevar_stop (TV_NAME_LOOKUP); + return t; } /* [basic.lookup.koenig] */ @@ -4607,6 +4865,7 @@ struct arg_lookup VEC(tree,gc) *namespaces; VEC(tree,gc) *classes; tree functions; + struct pointer_set_t *fn_set; }; static bool arg_assoc (struct arg_lookup*, tree); @@ -4626,22 +4885,21 @@ static bool arg_assoc_template_arg (struct arg_lookup*, tree); static bool add_function (struct arg_lookup *k, tree fn) { - /* We used to check here to see if the function was already in the list, - but that's O(n^2), which is just too expensive for function lookup. - Now we deal with the occasional duplicate in joust. In doing this, we - assume that the number of duplicates will be small compared to the - total number of functions being compared, which should usually be the - case. */ - if (!is_overloaded_fn (fn)) /* All names except those of (possibly overloaded) functions and function templates are ignored. */; + else if (k->fn_set && pointer_set_insert (k->fn_set, fn)) + /* It's already in the list. */; else if (!k->functions) k->functions = fn; else if (fn == k->functions) ; else - k->functions = build_overload (fn, k->functions); + { + k->functions = build_overload (fn, k->functions); + if (TREE_CODE (k->functions) == OVERLOAD) + OVL_ARG_DEPENDENT (k->functions) = true; + } return false; } @@ -4932,6 +5190,7 @@ arg_assoc_type (struct arg_lookup *k, tree type) case BOOLEAN_TYPE: case FIXED_POINT_TYPE: case DECLTYPE_TYPE: + case NULLPTR_TYPE: return false; case RECORD_TYPE: if (TYPE_PTRMEMFUNC_P (type)) @@ -4963,7 +5222,6 @@ arg_assoc_type (struct arg_lookup *k, tree type) return false; case LANG_TYPE: gcc_assert (type == unknown_type_node - || NULLPTR_TYPE_P (type) || type == init_list_type_node); return false; case TYPE_PACK_EXPANSION: @@ -5051,8 +5309,8 @@ arg_assoc (struct arg_lookup *k, tree n) } else if (TREE_CODE (n) == OVERLOAD) { - for (; n; n = OVL_CHAIN (n)) - if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n)))) + for (; n; n = OVL_NEXT (n)) + if (arg_assoc_type (k, TREE_TYPE (OVL_CURRENT (n)))) return true; } @@ -5062,14 +5320,12 @@ arg_assoc (struct arg_lookup *k, tree n) /* Performs Koenig lookup depending on arguments, where fns are the functions found in normal lookup. */ -tree -lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args, - bool include_std) +static tree +lookup_arg_dependent_1 (tree name, tree fns, VEC(tree,gc) *args, + bool include_std) { struct arg_lookup k; - 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. */ @@ -5087,6 +5343,23 @@ lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args, picking up later definitions) in the second stage. */ k.namespaces = make_tree_vector (); + /* We used to allow duplicates and let joust discard them, but + since the above change for DR 164 we end up with duplicates of + all the functions found by unqualified lookup. So keep track + of which ones we've seen. */ + if (fns) + { + tree ovl; + /* We shouldn't be here if lookup found something other than + namespace-scope functions. */ + gcc_assert (DECL_NAMESPACE_SCOPE_P (OVL_CURRENT (fns))); + k.fn_set = pointer_set_create (); + for (ovl = fns; ovl; ovl = OVL_NEXT (ovl)) + pointer_set_insert (k.fn_set, OVL_CURRENT (ovl)); + } + else + k.fn_set = NULL; + if (include_std) arg_assoc_namespace (&k, std_node); arg_assoc_args_vec (&k, args); @@ -5104,24 +5377,39 @@ lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args, release_tree_vector (k.classes); release_tree_vector (k.namespaces); + if (k.fn_set) + pointer_set_destroy (k.fn_set); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fns); + return fns; } +/* Wrapper for lookup_arg_dependent_1. */ + +tree +lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args, + bool include_std) +{ + tree ret; + timevar_start (TV_NAME_LOOKUP); + ret = lookup_arg_dependent_1 (name, fns, args, include_std); + timevar_stop (TV_NAME_LOOKUP); + return ret; +} + + /* Add namespace to using_directives. Return NULL_TREE if nothing was changed (i.e. there was already a directive), or the fresh TREE_LIST otherwise. */ static tree -push_using_directive (tree used) +push_using_directive_1 (tree used) { tree ud = current_binding_level->using_directives; tree iter, ancestor; - timevar_push (TV_NAME_LOOKUP); /* Check if we already have this. */ if (purpose_member (used, ud) != NULL_TREE) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + return NULL_TREE; ancestor = namespace_ancestor (current_decl_namespace (), used); ud = current_binding_level->using_directives; @@ -5132,7 +5420,19 @@ push_using_directive (tree used) for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter)) push_using_directive (TREE_PURPOSE (iter)); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ud); + return ud; +} + +/* Wrapper for push_using_directive_1. */ + +static tree +push_using_directive (tree used) +{ + tree ret; + timevar_start (TV_NAME_LOOKUP); + ret = push_using_directive_1 (used); + timevar_stop (TV_NAME_LOOKUP); + return ret; } /* The type TYPE is being declared. If it is a class template, or a @@ -5225,13 +5525,12 @@ maybe_process_template_type_declaration (tree type, int is_friend, Returns TYPE upon success and ERROR_MARK_NODE otherwise. */ -tree -pushtag (tree name, tree type, tag_scope scope) +static tree +pushtag_1 (tree name, tree type, tag_scope scope) { struct cp_binding_level *b; tree decl; - timevar_push (TV_NAME_LOOKUP); b = current_binding_level; while (/* Cleanup scopes are not scopes from the point of view of the language. */ @@ -5256,7 +5555,7 @@ pushtag (tree name, tree type, tag_scope scope) gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); /* Do C++ gratuitous typedefing. */ - if (IDENTIFIER_TYPE_VALUE (name) != type) + if (identifier_type_value_1 (name) != type) { tree tdef; int in_class = 0; @@ -5302,12 +5601,12 @@ pushtag (tree name, tree type, tag_scope scope) 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); + return decl; if (b->kind == sk_class) { if (!TYPE_BEING_DEFINED (current_class_type)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; if (!PROCESSING_REAL_TEMPLATE_DECL_P ()) /* Put this TYPE_DECL on the TYPE_FIELDS list for the @@ -5320,9 +5619,9 @@ pushtag (tree name, tree type, tag_scope scope) } else if (b->kind != sk_template_parms) { - decl = pushdecl_with_scope (decl, b, /*is_friend=*/false); + decl = pushdecl_with_scope_1 (decl, b, /*is_friend=*/false); if (decl == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; } if (! in_class) @@ -5361,7 +5660,19 @@ pushtag (tree name, tree type, tag_scope scope) TREE_PUBLIC (decl) = 1; determine_visibility (decl); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type); + return type; +} + +/* Wrapper for pushtag_1. */ + +tree +pushtag (tree name, tree type, tag_scope scope) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = pushtag_1 (name, type, scope); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Subroutines for reverting temporarily to top-level for instantiation @@ -5399,7 +5710,7 @@ store_bindings (tree names, VEC(cxx_saved_binding,gc) **old_bindings) { tree t; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); for (t = names; t; t = TREE_CHAIN (t)) { tree id; @@ -5411,7 +5722,7 @@ store_bindings (tree names, VEC(cxx_saved_binding,gc) **old_bindings) store_binding (id, old_bindings); } - timevar_pop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } /* Like store_bindings, but NAMES is a vector of cp_class_binding @@ -5424,10 +5735,10 @@ store_class_bindings (VEC(cp_class_binding,gc) *names, size_t i; cp_class_binding *cb; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); for (i = 0; VEC_iterate(cp_class_binding, names, i, cb); ++i) store_binding (cb->identifier, old_bindings); - timevar_pop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } void @@ -5439,7 +5750,7 @@ push_to_top_level (void) size_t i; bool need_pop; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); s = ggc_alloc_cleared_saved_scope (); b = scope_chain ? current_binding_level : 0; @@ -5499,17 +5810,16 @@ push_to_top_level (void) push_class_stack (); cp_unevaluated_operand = 0; c_inhibit_evaluation_warnings = 0; - timevar_pop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } -void -pop_from_top_level (void) +static void +pop_from_top_level_1 (void) { struct saved_scope *s = scope_chain; cxx_saved_binding *saved; size_t i; - timevar_push (TV_NAME_LOOKUP); /* Clear out class-level bindings cache. */ if (previous_class_level) invalidate_class_lookup_cache (); @@ -5533,9 +5843,19 @@ pop_from_top_level (void) current_function_decl = s->function_decl; cp_unevaluated_operand = s->unevaluated_operand; c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings; - timevar_pop (TV_NAME_LOOKUP); } +/* Wrapper for pop_from_top_level_1. */ + +void +pop_from_top_level (void) +{ + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + pop_from_top_level_1 (); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); +} + + /* Pop off extraneous binding levels left over due to syntax errors. We don't pop past namespaces, as they might be valid. */ @@ -5586,7 +5906,7 @@ cp_emit_debug_info_for_using (tree t, tree context) for (t = OVL_CURRENT (t); t; t = OVL_NEXT (t)) if (TREE_CODE (t) != TEMPLATE_DECL) { - if (building_stmt_tree ()) + if (building_stmt_list_p ()) add_stmt (build_stmt (input_location, USING_STMT, t)); else (*debug_hooks->imported_module_or_decl) (t, NULL_TREE, context, false);