aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c809
1 files changed, 470 insertions, 339 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e68c06447e1..794317fa63f 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1,6 +1,6 @@
/* Process declarations and variables for C compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@@ -49,6 +49,7 @@ Boston, MA 02111-1307, USA. */
#include "c-pragma.h"
#include "diagnostic.h"
#include "debug.h"
+#include "timevar.h"
static tree grokparms PARAMS ((tree));
static const char *redeclaration_error_message PARAMS ((tree, tree));
@@ -65,7 +66,7 @@ static void storedecls PARAMS ((tree));
static void require_complete_types_for_parms PARAMS ((tree));
static int ambi_op_p PARAMS ((enum tree_code));
static int unary_op_p PARAMS ((enum tree_code));
-static tree store_bindings PARAMS ((tree, tree));
+static cxx_saved_binding *store_bindings (tree, cxx_saved_binding *);
static tree lookup_tag_reverse PARAMS ((tree, tree));
static tree lookup_name_real PARAMS ((tree, int, int, int));
static void push_local_name PARAMS ((tree));
@@ -96,8 +97,8 @@ static void push_binding PARAMS ((tree, tree, struct cp_binding_level*));
static int add_binding PARAMS ((tree, tree));
static void pop_binding PARAMS ((tree, tree));
static tree local_variable_p_walkfn PARAMS ((tree *, int *, void *));
-static tree find_binding PARAMS ((tree, tree));
-static tree select_decl PARAMS ((tree, int));
+static cxx_binding *find_binding (tree, tree, cxx_binding *);
+static tree select_decl (cxx_binding *, int);
static int lookup_flags PARAMS ((int, int));
static tree qualify_lookup PARAMS ((tree, int));
static tree record_builtin_java_type PARAMS ((const char *, int));
@@ -328,6 +329,9 @@ struct cp_binding_level GTY(())
/* A chain of NAMESPACE_DECL nodes. */
tree namespaces;
+ /* An array of static functions and variables (for namespaces only) */
+ varray_type static_decls;
+
/* A chain of VTABLE_DECL nodes. */
tree vtables;
@@ -899,13 +903,11 @@ note_level_for_catch ()
/* For a binding between a name and an entity at a block scope,
this is the `struct cp_binding_level' for the block. */
-#define BINDING_LEVEL(NODE) \
- (((struct tree_binding*)(NODE))->scope.level)
+#define BINDING_LEVEL(NODE) ((NODE)->scope.level)
-/* A free list of CPLUS_BINDING nodes, connected by their
- TREE_CHAINs. */
+/* A free list of "cxx_binding"s, connected by their PREVIOUS. */
-static GTY((deletable (""))) tree free_bindings;
+static GTY((deletable (""))) cxx_binding *free_bindings;
/* Make DECL the innermost binding for ID. The LEVEL is the binding
level at which this declaration is being bound. */
@@ -916,15 +918,15 @@ push_binding (id, decl, level)
tree decl;
struct cp_binding_level* level;
{
- tree binding;
+ cxx_binding *binding;
if (free_bindings)
{
binding = free_bindings;
- free_bindings = TREE_CHAIN (binding);
+ free_bindings = binding->previous;
}
else
- binding = make_node (CPLUS_BINDING);
+ binding = cxx_binding_make ();
/* Now, fill in the binding information. */
BINDING_VALUE (binding) = decl;
@@ -935,7 +937,7 @@ push_binding (id, decl, level)
BINDING_HAS_LEVEL_P (binding) = 1;
/* And put it on the front of the list of bindings for ID. */
- TREE_CHAIN (binding) = IDENTIFIER_BINDING (id);
+ binding->previous = IDENTIFIER_BINDING (id);
IDENTIFIER_BINDING (id) = binding;
}
@@ -950,9 +952,10 @@ add_binding (id, decl)
tree id;
tree decl;
{
- tree binding = IDENTIFIER_BINDING (id);
+ cxx_binding *binding = IDENTIFIER_BINDING (id);
int ok = 1;
+ timevar_push (TV_NAME_LOOKUP);
if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
/* The new name is the type name. */
BINDING_TYPE (binding) = decl;
@@ -1009,7 +1012,7 @@ add_binding (id, decl)
ok = 0;
}
- return ok;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
}
/* Add DECL to the list of things declared in B. */
@@ -1037,6 +1040,13 @@ add_decl_to_level (decl, b)
TREE_CHAIN (decl) = b->names;
b->names = decl;
b->names_size++;
+
+ /* If appropriate, add decl to separate list of statics */
+ if (b->namespace_p)
+ if ((TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
+ || (TREE_CODE (decl) == FUNCTION_DECL
+ && (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl))))
+ VARRAY_PUSH_TREE (b->static_decls, decl);
}
}
@@ -1092,9 +1102,10 @@ push_class_binding (id, decl)
tree decl;
{
int result = 1;
- tree binding = IDENTIFIER_BINDING (id);
+ cxx_binding *binding = IDENTIFIER_BINDING (id);
tree context;
+ timevar_push (TV_NAME_LOOKUP);
/* Note that we declared this value so that we can issue an error if
this is an invalid redeclaration of a name already used for some
other purpose. */
@@ -1146,7 +1157,7 @@ push_class_binding (id, decl)
in this class. */
INHERITED_VALUE_BINDING_P (binding) = 1;
- return result;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result);
}
/* Remove the binding for DECL which should be the innermost binding
@@ -1157,7 +1168,7 @@ pop_binding (id, decl)
tree id;
tree decl;
{
- tree binding;
+ cxx_binding *binding;
if (id == NULL_TREE)
/* It's easiest to write the loops that call this function without
@@ -1169,7 +1180,7 @@ pop_binding (id, decl)
binding = IDENTIFIER_BINDING (id);
/* The name should be bound. */
- my_friendly_assert (binding != NULL_TREE, 0);
+ my_friendly_assert (binding != NULL, 0);
/* The DECL will be either the ordinary binding or the type
binding for this identifier. Remove that binding. */
@@ -1184,10 +1195,10 @@ pop_binding (id, decl)
{
/* We're completely done with the innermost binding for this
identifier. Unhook it from the list of bindings. */
- IDENTIFIER_BINDING (id) = TREE_CHAIN (binding);
+ IDENTIFIER_BINDING (id) = binding->previous;
/* Add it to the free list. */
- TREE_CHAIN (binding) = free_bindings;
+ binding->previous = free_bindings;
free_bindings = binding;
/* Clear the BINDING_LEVEL so the garbage collector doesn't walk
@@ -1276,8 +1287,10 @@ poplevel (keep, reverse, functionbody)
tree decl;
int leaving_for_scope;
+ timevar_push (TV_NAME_LOOKUP);
+
if (cfun && !doing_semantic_analysis_p ())
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
my_friendly_assert (current_binding_level->parm_flag != 2,
19990916);
@@ -1404,8 +1417,8 @@ poplevel (keep, reverse, functionbody)
if (leaving_for_scope && TREE_CODE (link) == VAR_DECL
&& DECL_NAME (link))
{
- tree outer_binding
- = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (link)));
+ cxx_binding *outer_binding
+ = IDENTIFIER_BINDING (DECL_NAME (link))->previous;
tree ns_binding;
if (!outer_binding)
@@ -1460,7 +1473,7 @@ poplevel (keep, reverse, functionbody)
current_binding_level->level_chain->
dead_vars_from_for);
- /* Although we don't pop the CPLUS_BINDING, we do clear
+ /* Although we don't pop the cxx_binding, we do clear
its BINDING_LEVEL since the level is going away now. */
BINDING_LEVEL (IDENTIFIER_BINDING (DECL_NAME (link)))
= 0;
@@ -1568,7 +1581,7 @@ poplevel (keep, reverse, functionbody)
block = poplevel (keep, reverse, functionbody);
}
- return block;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, block);
}
/* Delete the node BLOCK from the current binding level.
@@ -1659,6 +1672,8 @@ poplevel_class ()
register struct cp_binding_level *level = class_binding_level;
tree shadowed;
+ timevar_push (TV_NAME_LOOKUP);
+
my_friendly_assert (level != 0, 354);
/* If we're leaving a toplevel class, don't bother to do the setting
@@ -1687,15 +1702,15 @@ poplevel_class ()
shadowed;
shadowed = TREE_CHAIN (shadowed))
{
- tree t;
+ cxx_binding *binding;
- t = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
- while (t && BINDING_LEVEL (t) != b)
- t = TREE_CHAIN (t);
+ binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
+ while (binding && BINDING_LEVEL (binding) != b)
+ binding = binding->previous;
- if (t)
+ if (binding)
IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed))
- = BINDING_VALUE (t);
+ = BINDING_VALUE (binding);
}
}
else
@@ -1723,6 +1738,8 @@ poplevel_class ()
#endif /* defined(DEBUG_BINDING_LEVELS) */
pop_binding_level ();
+
+ timevar_pop (TV_NAME_LOOKUP);
}
/* We are entering the scope of a class. Clear IDENTIFIER_CLASS_VALUE
@@ -1910,23 +1927,12 @@ wrapup_globals_for_namespace (namespace, data)
tree namespace;
void *data;
{
- tree globals = cp_namespace_decls (namespace);
- int len = NAMESPACE_LEVEL (namespace)->names_size;
- tree *vec = (tree *) alloca (sizeof (tree) * len);
- int i;
- int result;
- tree decl;
+ struct cp_binding_level *level = NAMESPACE_LEVEL (namespace);
+ varray_type statics = level->static_decls;
+ tree *vec = &VARRAY_TREE (statics, 0);
+ int len = VARRAY_ACTIVE_SIZE (statics);
int last_time = (data != 0);
- if (last_time && namespace == global_namespace)
- /* Let compile_file handle the global namespace. */
- return 0;
-
- /* Process the decls in reverse order--earliest first.
- Put them into VEC from back to front, then take out from front. */
- for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
- vec[len - i - 1] = decl;
-
if (last_time)
{
check_global_declarations (vec, len);
@@ -1934,9 +1940,7 @@ wrapup_globals_for_namespace (namespace, data)
}
/* Write out any globals that need to be output. */
- result = wrapup_global_declarations (vec, len);
-
- return result;
+ return wrapup_global_declarations (vec, len);
}
@@ -2087,101 +2091,92 @@ print_binding_stack ()
print_binding_level (global_binding_level);
}
-/* Namespace binding access routines: The namespace_bindings field of
- the identifier is polymorphic, with three possible values:
- NULL_TREE, a list of CPLUS_BINDINGS, or any other tree_node
- indicating the BINDING_VALUE of global_namespace. */
+/* Namespace binding access routines. */
/* Check whether the a binding for the name to scope is known.
- Assumes that the bindings of the name are already a list
- of bindings. Returns the binding found, or NULL_TREE. */
+ Returns the binding found, or NULL. */
-static tree
-find_binding (name, scope)
- tree name;
- tree scope;
+static inline cxx_binding *
+find_binding (tree name, tree scope, cxx_binding *front)
{
- tree iter, prev = NULL_TREE;
+ cxx_binding *iter;
+ cxx_binding *prev = NULL;
- scope = ORIGINAL_NAMESPACE (scope);
+ timevar_push (TV_NAME_LOOKUP);
- for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter;
- iter = TREE_CHAIN (iter))
+ for (iter = front; iter; iter = iter->previous)
{
- my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374);
if (BINDING_SCOPE (iter) == scope)
{
/* Move binding found to the front of the list, so
subsequent lookups will find it faster. */
if (prev)
{
- TREE_CHAIN (prev) = TREE_CHAIN (iter);
- TREE_CHAIN (iter) = IDENTIFIER_NAMESPACE_BINDINGS (name);
+ prev->previous = iter->previous;
+ iter->previous = front;
IDENTIFIER_NAMESPACE_BINDINGS (name) = iter;
}
- return iter;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, iter);
}
prev = iter;
}
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL);
}
-/* Always returns a binding for name in scope. If the
- namespace_bindings is not a list, convert it to one first.
+/* Return the binding for NAME in SCOPE, if any. Otherwise, return NULL. */
+cxx_binding *
+cxx_scope_find_binding_for_name (tree scope, tree name)
+{
+ cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
+ if (b)
+ {
+ scope = ORIGINAL_NAMESPACE (scope);
+ /* Fold-in case where NAME is used only once. */
+ if (scope == BINDING_SCOPE (b) && b->previous == NULL)
+ return b;
+ return find_binding (name, scope, b);
+ }
+ return b;
+}
+
+
+/* Always returns a binding for name in scope.
If no binding is found, make a new one. */
-tree
-binding_for_name (name, scope)
- tree name;
- tree scope;
+cxx_binding *
+binding_for_name (tree name, tree scope)
{
- tree b = IDENTIFIER_NAMESPACE_BINDINGS (name);
- tree result;
+ cxx_binding *result;
scope = ORIGINAL_NAMESPACE (scope);
-
- if (b && TREE_CODE (b) != CPLUS_BINDING)
- {
- /* Get rid of optimization for global scope. */
- IDENTIFIER_NAMESPACE_BINDINGS (name) = NULL_TREE;
- BINDING_VALUE (binding_for_name (name, global_namespace)) = b;
- b = IDENTIFIER_NAMESPACE_BINDINGS (name);
- }
- if (b && (result = find_binding (name, scope)))
+ result = cxx_scope_find_binding_for_name (scope, name);
+ if (result)
return result;
/* Not found, make a new one. */
- result = make_node (CPLUS_BINDING);
- TREE_CHAIN (result) = b;
- IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
- BINDING_SCOPE (result) = scope;
+ result = cxx_binding_make ();
+ result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
BINDING_TYPE (result) = NULL_TREE;
BINDING_VALUE (result) = NULL_TREE;
+ BINDING_SCOPE (result) = scope;
+ result->is_local = false;
+ result->value_is_inherited = false;
+ result->has_level = false;
+ IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
return result;
}
-/* Return the binding value for name in scope, considering that
- namespace_binding may or may not be a list of CPLUS_BINDINGS. */
+/* Return the binding value for name in scope. */
tree
-namespace_binding (name, scope)
- tree name;
- tree scope;
+namespace_binding (tree name, tree scope)
{
- tree b = IDENTIFIER_NAMESPACE_BINDINGS (name);
- if (b == NULL_TREE)
- return NULL_TREE;
- if (scope == NULL_TREE)
- scope = global_namespace;
- if (TREE_CODE (b) != CPLUS_BINDING)
- return (scope == global_namespace) ? b : NULL_TREE;
- name = find_binding (name,scope);
- if (name == NULL_TREE)
- return name;
- return BINDING_VALUE (name);
+ cxx_binding *b =
+ cxx_scope_find_binding_for_name (scope ? scope : global_namespace, name);
+
+ return b ? b->value : NULL_TREE;
}
-/* Set the binding value for name in scope. If modifying the binding
- of global_namespace is attempted, try to optimize it. */
+/* Set the binding value for name in scope. */
void
set_namespace_binding (name, scope, val)
@@ -2189,22 +2184,15 @@ set_namespace_binding (name, scope, val)
tree scope;
tree val;
{
- tree b;
+ cxx_binding *b;
+ timevar_push (TV_NAME_LOOKUP);
if (scope == NULL_TREE)
scope = global_namespace;
- if (scope == global_namespace)
- {
- b = IDENTIFIER_NAMESPACE_BINDINGS (name);
- if (b == NULL_TREE || TREE_CODE (b) != CPLUS_BINDING)
- {
- IDENTIFIER_NAMESPACE_BINDINGS (name) = val;
- return;
- }
- }
b = binding_for_name (name, scope);
BINDING_VALUE (b) = val;
+ timevar_pop (TV_NAME_LOOKUP);
}
/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we
@@ -2218,6 +2206,9 @@ push_namespace (name)
int need_new = 1;
int implicit_use = 0;
int global = 0;
+
+ timevar_push (TV_NAME_LOOKUP);
+
if (!global_namespace)
{
/* This must be ::. */
@@ -2266,6 +2257,9 @@ push_namespace (name)
pushlevel (0);
declare_namespace_level ();
NAMESPACE_LEVEL (d) = current_binding_level;
+ VARRAY_TREE_INIT (current_binding_level->static_decls,
+ name != std_identifier ? 10 : 200,
+ "Static declarations");
}
}
else
@@ -2275,6 +2269,8 @@ push_namespace (name)
do_using_directive (d);
/* Enter the name space. */
current_namespace = d;
+
+ timevar_pop (TV_NAME_LOOKUP);
}
/* Pop from the scope of the current namespace. */
@@ -2311,6 +2307,7 @@ void
pop_nested_namespace (ns)
tree ns;
{
+ timevar_push (TV_NAME_LOOKUP);
while (ns != global_namespace)
{
pop_namespace ();
@@ -2318,9 +2315,26 @@ pop_nested_namespace (ns)
}
pop_from_top_level ();
+ timevar_pop (TV_NAME_LOOKUP);
}
+/* Allocate storage for saving a C++ binding. */
+#define cxx_saved_binding_make() \
+ (ggc_alloc (sizeof (cxx_saved_binding)))
+
+struct cxx_saved_binding GTY(())
+{
+ /* Link that chains saved C++ bindings for a given name into a stack. */
+ cxx_saved_binding *previous;
+ /* The name of the current binding. */
+ tree identifier;
+ /* The binding we're saving. */
+ cxx_binding *binding;
+ tree class_value;
+ tree real_type_value;
+};
+
/* Subroutines for reverting temporarily to top-level for instantiation
of templates and such. We actually need to clear out the class- and
local-value slots of all identifiers, so that only the global values
@@ -2328,16 +2342,18 @@ pop_nested_namespace (ns)
scope isn't enough, because more binding levels may be pushed. */
struct saved_scope *scope_chain;
-static tree
-store_bindings (names, old_bindings)
- tree names, old_bindings;
+static cxx_saved_binding *
+store_bindings (tree names, cxx_saved_binding *old_bindings)
{
tree t;
- tree search_bindings = old_bindings;
+ cxx_saved_binding *search_bindings = old_bindings;
+ timevar_push (TV_NAME_LOOKUP);
for (t = names; t; t = TREE_CHAIN (t))
{
- tree binding, t1, id;
+ tree id;
+ cxx_saved_binding *saved;
+ cxx_saved_binding *t1;
if (TREE_CODE (t) == TREE_LIST)
id = TREE_PURPOSE (t);
@@ -2351,24 +2367,24 @@ store_bindings (names, old_bindings)
|| !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
continue;
- for (t1 = search_bindings; t1; t1 = TREE_CHAIN (t1))
- if (TREE_VEC_ELT (t1, 0) == id)
+ for (t1 = search_bindings; t1; t1 = t1->previous)
+ if (t1->identifier == id)
goto skip_it;
my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
- binding = make_tree_vec (4);
- TREE_VEC_ELT (binding, 0) = id;
- TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id);
- TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id);
- TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id);
- IDENTIFIER_BINDING (id) = NULL_TREE;
+ saved = cxx_saved_binding_make ();
+ saved->previous = old_bindings;
+ saved->identifier = id;
+ saved->binding = IDENTIFIER_BINDING (id);
+ saved->class_value = IDENTIFIER_CLASS_VALUE (id);;
+ saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
+ IDENTIFIER_BINDING (id) = NULL;
IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
- TREE_CHAIN (binding) = old_bindings;
- old_bindings = binding;
+ old_bindings = saved;
skip_it:
;
}
- return old_bindings;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings);
}
void
@@ -2377,9 +2393,11 @@ maybe_push_to_top_level (pseudo)
{
struct saved_scope *s;
struct cp_binding_level *b;
- tree old_bindings;
+ cxx_saved_binding *old_bindings;
int need_pop;
+ timevar_push (TV_NAME_LOOKUP);
+
s = (struct saved_scope *) ggc_alloc_cleared (sizeof (struct saved_scope));
b = scope_chain ? current_binding_level : 0;
@@ -2393,7 +2411,7 @@ maybe_push_to_top_level (pseudo)
else
need_pop = 0;
- old_bindings = NULL_TREE;
+ old_bindings = NULL;
if (scope_chain && previous_class_type)
old_bindings = store_bindings (previous_class_values, old_bindings);
@@ -2432,6 +2450,7 @@ maybe_push_to_top_level (pseudo)
VARRAY_TREE_INIT (current_lang_base, 10, "current_lang_base");
current_lang_name = lang_name_cplusplus;
current_namespace = global_namespace;
+ timevar_pop (TV_NAME_LOOKUP);
}
void
@@ -2444,7 +2463,9 @@ void
pop_from_top_level ()
{
struct saved_scope *s = scope_chain;
- tree t;
+ cxx_saved_binding *saved;
+
+ timevar_push (TV_NAME_LOOKUP);
/* Clear out class-level bindings cache. */
if (previous_class_type)
@@ -2453,13 +2474,13 @@ pop_from_top_level ()
current_lang_base = 0;
scope_chain = s->prev;
- for (t = s->old_bindings; t; t = TREE_CHAIN (t))
+ for (saved = s->old_bindings; saved; saved = saved->previous)
{
- tree id = TREE_VEC_ELT (t, 0);
+ tree id = saved->identifier;
- SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1));
- IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2);
- IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);
+ IDENTIFIER_BINDING (id) = saved->binding;
+ IDENTIFIER_CLASS_VALUE (id) = saved->class_value;
+ SET_IDENTIFIER_TYPE_VALUE (id, saved->real_type_value);
}
/* If we were in the middle of compiling a function, restore our
@@ -2468,6 +2489,8 @@ pop_from_top_level ()
pop_function_context_from (NULL_TREE);
current_function_decl = s->function_decl;
last_function_parms = s->last_parms;
+
+ timevar_pop (TV_NAME_LOOKUP);
}
/* Push a definition of struct, union or enum tag "name".
@@ -2499,7 +2522,7 @@ set_identifier_type_value_with_scope (id, type, b)
}
else
{
- tree binding = binding_for_name (id, current_namespace);
+ cxx_binding *binding = binding_for_name (id, current_namespace);
BINDING_TYPE (binding) = type;
/* Store marker instead of real type. */
type = global_type_node;
@@ -2523,18 +2546,19 @@ tree
identifier_type_value (id)
tree id;
{
+ timevar_push (TV_NAME_LOOKUP);
/* There is no type with that name, anywhere. */
if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
/* This is not the type marker, but the real thing. */
if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
- return REAL_IDENTIFIER_TYPE_VALUE (id);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, 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, 0);
if (id)
- return TREE_TYPE (id);
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_TYPE (id));
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
}
/* Pop off extraneous binding levels left over due to syntax errors.
@@ -2661,6 +2685,8 @@ push_local_name (decl)
size_t i, nelts;
tree t, name;
+ timevar_push (TV_NAME_LOOKUP);
+
if (!local_names)
VARRAY_TREE_INIT (local_names, 8, "local_names");
@@ -2681,11 +2707,12 @@ push_local_name (decl)
DECL_DISCRIMINATOR (decl) = 1;
VARRAY_TREE (local_names, i) = decl;
- return;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0);
}
}
VARRAY_PUSH_TREE (local_names, decl);
+ timevar_pop (TV_NAME_LOOKUP);
}
/* Push a tag name NAME for struct/class/union/enum type TYPE.
@@ -2700,6 +2727,8 @@ pushtag (name, type, globalize)
{
register struct cp_binding_level *b;
+ timevar_push (TV_NAME_LOOKUP);
+
b = current_binding_level;
while (b->tag_transparent
|| (b->parm_flag == 2
@@ -2809,6 +2838,8 @@ pushtag (name, type, globalize)
tree d = build_decl (TYPE_DECL, NULL_TREE, type);
TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b);
}
+
+ timevar_pop (TV_NAME_LOOKUP);
}
/* Counter used to create anonymous type names. */
@@ -3135,6 +3166,10 @@ duplicate_decls (newdecl, olddecl)
/* Replace the old RTL to avoid problems with inlining. */
SET_DECL_RTL (olddecl, DECL_RTL (newdecl));
}
+ /* Even if the types match, prefer the new declarations type
+ for anitipated built-ins, for exception lists, etc... */
+ else if (DECL_ANTICIPATED (olddecl))
+ TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl))
{
@@ -3210,7 +3245,11 @@ duplicate_decls (newdecl, olddecl)
&& compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))),
TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))))
&& comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
- DECL_TEMPLATE_PARMS (olddecl)))
+ DECL_TEMPLATE_PARMS (olddecl))
+ /* Template functions can be disambiguated by
+ return type. */
+ && same_type_p (TREE_TYPE (TREE_TYPE (newdecl)),
+ TREE_TYPE (TREE_TYPE (olddecl))))
{
error ("new declaration `%#D'", newdecl);
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
@@ -3601,7 +3640,10 @@ duplicate_decls (newdecl, olddecl)
DECL_BEFRIENDING_CLASSES (newdecl)
= chainon (DECL_BEFRIENDING_CLASSES (newdecl),
DECL_BEFRIENDING_CLASSES (olddecl));
- DECL_THUNKS (newdecl) = DECL_THUNKS (olddecl);
+ /* DECL_THUNKS is only valid for virtual functions,
+ otherwise it is a DECL_FRIEND_CONTEXT. */
+ if (DECL_VIRTUAL_P (newdecl))
+ DECL_THUNKS (newdecl) = DECL_THUNKS (olddecl);
}
}
@@ -3778,6 +3820,8 @@ pushdecl (x)
register tree name;
int need_new_binding;
+ timevar_push (TV_NAME_LOOKUP);
+
/* We shouldn't be calling pushdecl when we're generating RTL for a
function that we already did semantic analysis on previously. */
my_friendly_assert (!cfun || doing_semantic_analysis_p (),
@@ -3901,7 +3945,7 @@ pushdecl (x)
/* Check for duplicate params. */
if (duplicate_decls (x, t))
- return t;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
else if ((DECL_EXTERN_C_FUNCTION_P (x)
|| DECL_FUNCTION_TEMPLATE_P (x))
@@ -3914,12 +3958,12 @@ pushdecl (x)
TREE_TYPE (x));
/* Throw away the redeclaration. */
- return t;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
else if (TREE_CODE (t) != TREE_CODE (x))
{
if (duplicate_decls (x, t))
- return t;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
else if (duplicate_decls (x, t))
{
@@ -3928,7 +3972,7 @@ pushdecl (x)
else if (TREE_CODE (t) == FUNCTION_DECL)
check_default_args (t);
- return t;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
else if (DECL_MAIN_P (x))
{
@@ -3942,7 +3986,7 @@ pushdecl (x)
error ("as `%D'", x);
/* We don't try to push this declaration since that
causes a crash. */
- return x;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
}
}
@@ -3960,7 +4004,7 @@ pushdecl (x)
{
t = push_overloaded_decl (x, PUSH_LOCAL);
if (t != x)
- return t;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
if (!namespace_bindings_p ())
/* We do not need to create a binding for this name;
push_overloaded_decl will have already done so if
@@ -3972,7 +4016,7 @@ pushdecl (x)
t = push_overloaded_decl (x, PUSH_GLOBAL);
if (t == x)
add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t)));
- return t;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
/* If declaring a type as a typedef, copy the type (unless we're
@@ -4147,7 +4191,9 @@ pushdecl (x)
if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
/* Inline decls shadow nothing. */
&& !DECL_FROM_INLINE (x)
- && TREE_CODE (oldlocal) == PARM_DECL)
+ && TREE_CODE (oldlocal) == PARM_DECL
+ /* Don't check the `this' parameter. */
+ && !DECL_ARTIFICIAL (oldlocal))
{
bool err = false;
@@ -4207,7 +4253,7 @@ pushdecl (x)
? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
: current_binding_level);
- return x;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
}
/* Same as pushdecl, but define X in binding-level LEVEL. We rely on the
@@ -4221,6 +4267,8 @@ pushdecl_with_scope (x, level)
register struct cp_binding_level *b;
tree function_decl = current_function_decl;
+ timevar_push (TV_NAME_LOOKUP);
+
current_function_decl = NULL_TREE;
if (level->parm_flag == 2)
{
@@ -4237,7 +4285,7 @@ pushdecl_with_scope (x, level)
current_binding_level = b;
}
current_function_decl = function_decl;
- return x;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
}
/* Like pushdecl, only it places X in the current namespace,
@@ -4250,6 +4298,7 @@ pushdecl_namespace_level (x)
register struct cp_binding_level *b = current_binding_level;
register tree t;
+ timevar_push (TV_NAME_LOOKUP);
t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace));
/* Now, the type_shadowed stack may screw us. Munge it so it does
@@ -4283,7 +4332,7 @@ pushdecl_namespace_level (x)
*ptr = newval;
}
}
- return t;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL,
@@ -4293,10 +4342,11 @@ tree
pushdecl_top_level (x)
tree x;
{
+ timevar_push (TV_NAME_LOOKUP);
push_to_top_level ();
x = pushdecl_namespace_level (x);
pop_from_top_level ();
- return x;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
}
/* Make the declaration of X appear in CLASS scope. */
@@ -4307,6 +4357,7 @@ pushdecl_class_level (x)
{
tree name;
+ timevar_push (TV_NAME_LOOKUP);
/* Get the name of X. */
if (TREE_CODE (x) == OVERLOAD)
name = DECL_NAME (get_first_fn (x));
@@ -4329,6 +4380,7 @@ pushdecl_class_level (x)
for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f))
pushdecl_class_level (f);
}
+ timevar_pop (TV_NAME_LOOKUP);
}
/* Enter DECL into the symbol table, if that's appropriate. Returns
@@ -4369,11 +4421,13 @@ push_class_level_binding (name, x)
tree name;
tree x;
{
- tree binding;
+ cxx_binding *binding;
+
+ 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)
- return;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0);
/* Make sure that this new member does not have the same name
as a template parameter. */
@@ -4423,7 +4477,7 @@ push_class_level_binding (name, x)
INHERITED_VALUE_BINDING_P (binding) = 0;
TREE_TYPE (shadow) = x;
IDENTIFIER_CLASS_VALUE (name) = x;
- return;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0);
}
}
@@ -4438,6 +4492,7 @@ push_class_level_binding (name, x)
what to pop later. */
TREE_TYPE (class_binding_level->class_shadowed) = x;
}
+ timevar_pop (TV_NAME_LOOKUP);
}
/* Insert another USING_DECL into the current binding level, returning
@@ -4452,18 +4507,21 @@ push_using_decl (scope, name)
{
tree decl;
+ timevar_push (TV_NAME_LOOKUP);
+
my_friendly_assert (TREE_CODE (scope) == NAMESPACE_DECL, 383);
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 384);
for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name)
break;
if (decl)
- return namespace_bindings_p () ? decl : NULL_TREE;
+ 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;
TREE_CHAIN (decl) = current_binding_level->usings;
current_binding_level->usings = decl;
- return decl;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
}
/* Add namespace to using_directives. Return NULL_TREE if nothing was
@@ -4477,19 +4535,22 @@ push_using_directive (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)
- return NULL_TREE;
-
- /* Recursively add all namespaces 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, NULL_TREE);
ancestor = namespace_ancestor (current_decl_namespace (), used);
ud = current_binding_level->using_directives;
ud = tree_cons (used, ancestor, ud);
current_binding_level->using_directives = ud;
- return ud;
+
+ /* Recursively add all namespaces 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);
}
/* DECL is a FUNCTION_DECL for a non-member function, which may have
@@ -4521,6 +4582,8 @@ push_overloaded_decl (decl, flags)
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
@@ -4553,7 +4616,7 @@ push_overloaded_decl (decl, flags)
decl, fn);
if (duplicate_decls (decl, fn))
- return fn;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fn);
}
}
else if (old == error_mark_node)
@@ -4563,7 +4626,7 @@ push_overloaded_decl (decl, flags)
{
cp_error_at ("previous non-function declaration `%#D'", old);
error ("conflicts with function declaration `%#D'", decl);
- return decl;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
}
}
@@ -4609,10 +4672,10 @@ push_overloaded_decl (decl, flags)
*d = tree_cons (NULL_TREE, new_binding,
TREE_CHAIN (*d));
- /* And update the CPLUS_BINDING node. */
+ /* And update the cxx_binding node. */
BINDING_VALUE (IDENTIFIER_BINDING (name))
= new_binding;
- return decl;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
}
/* We should always find a previous binding in this case. */
@@ -4623,7 +4686,7 @@ push_overloaded_decl (decl, flags)
push_local_binding (name, new_binding, flags);
}
- return decl;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
}
/* Generate an implicit declaration for identifier FUNCTIONID
@@ -4807,18 +4870,20 @@ lookup_label (id)
tree decl;
struct named_label_list *ent;
+ timevar_push (TV_NAME_LOOKUP);
+
/* You can't use labels at global scope. */
if (current_function_decl == NULL_TREE)
{
error ("label `%s' referenced outside of any function",
IDENTIFIER_POINTER (id));
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
}
/* See if we've already got this label. */
decl = IDENTIFIER_LABEL_VALUE (id);
if (decl != NULL_TREE && DECL_CONTEXT (decl) == current_function_decl)
- return decl;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
/* Record this label on the list of labels used in this function.
We do this before calling make_label_decl so that we get the
@@ -4835,7 +4900,7 @@ lookup_label (id)
/* Now fill in the information we didn't have before. */
ent->label_decl = decl;
- return decl;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
}
/* Declare a local label named ID. */
@@ -5069,6 +5134,8 @@ define_label (filename, line, name)
struct named_label_list *ent;
register struct cp_binding_level *p;
+ timevar_push (TV_NAME_LOOKUP);
+
for (ent = named_labels; ent; ent = ent->next)
if (ent->label_decl == decl)
break;
@@ -5084,7 +5151,7 @@ define_label (filename, line, name)
if (DECL_INITIAL (decl) != NULL_TREE)
{
error ("duplicate label `%D'", decl);
- return 0;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
}
else
{
@@ -5099,8 +5166,9 @@ define_label (filename, line, name)
ent->binding_level = current_binding_level;
}
check_previous_gotos (decl);
- return decl;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
}
+ timevar_pop (TV_NAME_LOOKUP);
}
struct cp_switch
@@ -5307,6 +5375,8 @@ lookup_tag (form, name, binding_level, thislevel_only)
if THISLEVEL_ONLY. */
int allow_template_parms_p = 1;
+ timevar_push (TV_NAME_LOOKUP);
+
for (level = binding_level; level; level = level->level_chain)
{
register tree tail;
@@ -5316,24 +5386,28 @@ lookup_tag (form, name, binding_level, thislevel_only)
/* There's no need for error checking here, because
anon names are unique throughout the compilation. */
if (TYPE_IDENTIFIER (TREE_VALUE (tail)) == name)
- return TREE_VALUE (tail);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_VALUE (tail));
}
else if (level->namespace_p)
/* Do namespace lookup. */
for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
{
- tree old = binding_for_name (name, tail);
+ cxx_binding *binding =
+ cxx_scope_find_binding_for_name (tail, name);
+ tree old;
/* If we just skipped past a template parameter level,
even though THISLEVEL_ONLY, and we find a template
class declaration, then we use the _TYPE node for the
template. See the example below. */
if (thislevel_only && !allow_template_parms_p
- && old && BINDING_VALUE (old)
- && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (old)))
- old = TREE_TYPE (BINDING_VALUE (old));
- else
- old = BINDING_TYPE (old);
+ && binding && BINDING_VALUE (binding)
+ && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (binding)))
+ old = TREE_TYPE (BINDING_VALUE (binding));
+ else if (binding)
+ old = BINDING_TYPE (binding);
+ else
+ old = NULL;
if (old)
{
@@ -5342,18 +5416,18 @@ lookup_tag (form, name, binding_level, thislevel_only)
if the typedef doesn't refer to a taggable type. */
old = follow_tag_typedef (old);
if (!old)
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
if (TREE_CODE (old) != form
&& (form == ENUMERAL_TYPE
|| TREE_CODE (old) == ENUMERAL_TYPE))
{
error ("`%#D' redeclared as %C", old, form);
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
}
- return old;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old);
}
if (thislevel_only || tail == global_namespace)
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
}
else
for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
@@ -5367,9 +5441,9 @@ lookup_tag (form, name, binding_level, thislevel_only)
{
/* Definition isn't the kind we were looking for. */
error ("`%#D' redeclared as %C", TREE_VALUE (tail), form);
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
}
- return TREE_VALUE (tail);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_VALUE (tail));
}
}
if (thislevel_only && ! level->tag_transparent)
@@ -5391,10 +5465,10 @@ lookup_tag (form, name, binding_level, thislevel_only)
continue;
}
else
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
}
}
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
}
#if 0
@@ -5420,6 +5494,8 @@ lookup_tag_reverse (type, name)
{
register struct cp_binding_level *level;
+ timevar_push (TV_NAME_LOOKUP);
+
for (level = current_binding_level; level; level = level->level_chain)
{
register tree tail;
@@ -5429,11 +5505,11 @@ lookup_tag_reverse (type, name)
{
if (name)
TREE_PURPOSE (tail) = name;
- return TREE_PURPOSE (tail);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_PURPOSE (tail));
}
}
}
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
}
/* Look up NAME in the NAMESPACE. */
@@ -5444,18 +5520,21 @@ lookup_namespace_name (namespace, name)
{
tree val;
tree template_id = NULL_TREE;
+ cxx_binding binding;
+
+ timevar_push (TV_NAME_LOOKUP);
my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370);
if (TREE_CODE (name) == NAMESPACE_DECL)
/* This happens for A::B<int> when B is a namespace. */
- return name;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, name);
else if (TREE_CODE (name) == TEMPLATE_DECL)
{
/* This happens for A::B where B is a template, and there are no
template arguments. */
error ("invalid use of `%D'", name);
- return error_mark_node;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
namespace = ORIGINAL_NAMESPACE (namespace);
@@ -5472,13 +5551,13 @@ lookup_namespace_name (namespace, name)
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
- val = make_node (CPLUS_BINDING);
- if (!qualified_lookup_using_namespace (name, namespace, val, 0))
- return error_mark_node;
+ cxx_binding_clear (&binding);
+ if (!qualified_lookup_using_namespace (name, namespace, &binding, 0))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- if (BINDING_VALUE (val))
+ if (binding.value)
{
- val = BINDING_VALUE (val);
+ val = binding.value;
if (template_id)
{
@@ -5497,7 +5576,7 @@ lookup_namespace_name (namespace, name)
{
error ("`%D::%D' is not a template",
namespace, name);
- return error_mark_node;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
}
@@ -5509,11 +5588,11 @@ lookup_namespace_name (namespace, name)
if (!val || !DECL_P(val)
|| !DECL_LANG_SPECIFIC(val)
|| !DECL_ANTICIPATED (val))
- return val;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
}
error ("`%D' undeclared in namespace `%D'", name, namespace);
- return error_mark_node;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
/* Hash a TYPENAME_TYPE. K is really of type `tree'. */
@@ -5677,10 +5756,13 @@ make_typename_type (context, name, complain)
return error_mark_node;
}
- if (complain & tf_parsing)
- type_access_control (context, tmpl);
- else
- enforce_access (context, tmpl);
+ if (complain & tf_error)
+ {
+ if (complain & tf_parsing)
+ type_access_control (context, tmpl);
+ else
+ enforce_access (context, tmpl);
+ }
return lookup_template_class (tmpl,
TREE_OPERAND (fullname, 1),
@@ -5709,10 +5791,13 @@ make_typename_type (context, name, complain)
return error_mark_node;
}
- if (complain & tf_parsing)
- type_access_control (context, t);
- else
- enforce_access (context, t);
+ if (complain & tf_error)
+ {
+ if (complain & tf_parsing)
+ type_access_control (context, t);
+ else
+ enforce_access (context, t);
+ }
if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
t = TREE_TYPE (t);
@@ -5753,7 +5838,7 @@ make_typename_type (context, name, complain)
tree
make_unbound_class_template (context, name, complain)
tree context, name;
- int complain;
+ tsubst_flags_t complain;
{
tree t;
tree d;
@@ -5775,15 +5860,18 @@ make_unbound_class_template (context, name, complain)
if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
{
- if (complain)
+ if (complain & tf_error)
error ("no class template named `%#T' in `%#T'", name, context);
return error_mark_node;
}
- if (complain & tf_parsing)
- type_access_control (context, tmpl);
- else
- enforce_access (context, tmpl);
+ if (complain & tf_error)
+ {
+ if (complain & tf_parsing)
+ type_access_control (context, tmpl);
+ else
+ enforce_access (context, tmpl);
+ }
return tmpl;
}
@@ -5806,19 +5894,20 @@ make_unbound_class_template (context, name, complain)
/* Select the right _DECL from multiple choices. */
static tree
-select_decl (binding, flags)
- tree binding;
- int flags;
+select_decl (cxx_binding *binding, int flags)
{
tree val;
+
+ timevar_push (TV_NAME_LOOKUP);
+
val = BINDING_VALUE (binding);
if (LOOKUP_NAMESPACES_ONLY (flags))
{
/* We are not interested in types. */
if (val && TREE_CODE (val) == NAMESPACE_DECL)
- return val;
- return NULL_TREE;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
}
/* If we could have a type and
@@ -5833,7 +5922,7 @@ select_decl (binding, flags)
|| !DECL_CLASS_TEMPLATE_P (val)))
val = NULL_TREE;
- return val;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
}
/* Unscoped lookup of a global: iterate over current namespaces,
@@ -5846,65 +5935,65 @@ unqualified_namespace_lookup (name, flags, spacesp)
int flags;
tree *spacesp;
{
- tree b = make_node (CPLUS_BINDING);
tree initial = current_decl_namespace ();
tree scope = initial;
tree siter;
struct cp_binding_level *level;
tree val = NULL_TREE;
+ cxx_binding binding;
+ timevar_push (TV_NAME_LOOKUP);
+ cxx_binding_clear (&binding);
if (spacesp)
*spacesp = NULL_TREE;
for (; !val; scope = CP_DECL_CONTEXT (scope))
{
+ cxx_binding *b;
if (spacesp)
*spacesp = tree_cons (scope, NULL_TREE, *spacesp);
- val = binding_for_name (name, scope);
+ b = cxx_scope_find_binding_for_name (scope, name);
/* Ignore anticipated built-in functions. */
- if (val && BINDING_VALUE (val)
- && DECL_P (BINDING_VALUE (val))
- && DECL_LANG_SPECIFIC (BINDING_VALUE (val))
- && DECL_ANTICIPATED (BINDING_VALUE (val)))
- {
- BINDING_VALUE (b) = NULL_TREE;
- BINDING_TYPE (b) = NULL_TREE;
- }
- else
+ if (b && BINDING_VALUE (b) && DECL_P (BINDING_VALUE (b))
+ && DECL_LANG_SPECIFIC (BINDING_VALUE (b))
+ && DECL_ANTICIPATED (BINDING_VALUE (b)))
+ /* Keep binding cleared. */;
+ else if (b)
{
/* Initialize binding for this context. */
- BINDING_VALUE (b) = BINDING_VALUE (val);
- BINDING_TYPE (b) = BINDING_TYPE (val);
+ binding.value = BINDING_VALUE (b);
+ binding.type = BINDING_TYPE (b);
}
/* Add all _DECLs seen through local using-directives. */
for (level = current_binding_level;
!level->namespace_p;
level = level->level_chain)
- if (!lookup_using_namespace (name, b, level->using_directives,
+ if (!lookup_using_namespace (name, &binding, level->using_directives,
scope, flags, spacesp))
/* Give up because of error. */
- return error_mark_node;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
/* Add all _DECLs seen through global using-directives. */
/* XXX local and global using lists should work equally. */
siter = initial;
while (1)
{
- if (!lookup_using_namespace (name, b, DECL_NAMESPACE_USING (siter),
+ if (!lookup_using_namespace (name, &binding,
+ DECL_NAMESPACE_USING (siter),
scope, flags, spacesp))
/* Give up because of error. */
- return error_mark_node;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
if (siter == scope) break;
siter = CP_DECL_CONTEXT (siter);
}
- val = select_decl (b, flags);
+ val = select_decl (&binding, flags);
if (scope == global_namespace)
break;
}
- return val;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
}
/* Combine prefer_type and namespaces_only into flags. */
@@ -5956,6 +6045,7 @@ warn_about_implicit_typename_lookup (typename, binding)
tree name = DECL_NAME (typename);
if (! (TREE_CODE (binding) == TEMPLATE_DECL
+ && CLASS_TYPE_P (subtype)
&& CLASSTYPE_TEMPLATE_INFO (subtype)
&& CLASSTYPE_TI_TEMPLATE (subtype) == binding)
&& ! (TREE_CODE (binding) == TYPE_DECL
@@ -6054,6 +6144,9 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
tree from_obj = NULL_TREE;
int flags;
int val_is_implicit_typename = 0;
+ cxx_binding *iter;
+
+ timevar_push (TV_NAME_LOOKUP);
/* Hack: copy flag set by parser, if set. */
if (only_namespace_names)
@@ -6080,8 +6173,8 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
if (type)
{
if (type == error_mark_node)
- return error_mark_node;
- if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ if (IMPLICIT_TYPENAME_P (type))
type = TREE_TYPE (type);
if (TYPE_P (type))
@@ -6091,11 +6184,12 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
type = global_namespace;
if (TREE_CODE (type) == NAMESPACE_DECL)
{
- val = make_node (CPLUS_BINDING);
+ cxx_binding b;
+ cxx_binding_clear (&b);
flags |= LOOKUP_COMPLAIN;
- if (!qualified_lookup_using_namespace (name, type, val, flags))
- return NULL_TREE;
- val = select_decl (val, flags);
+ if (!qualified_lookup_using_namespace (name, type, &b, flags))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ val = select_decl (&b, flags);
}
else if (! IS_AGGR_TYPE (type)
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM
@@ -6148,27 +6242,27 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
if (current_class_type == NULL_TREE)
nonclass = 1;
- for (t = IDENTIFIER_BINDING (name); t; t = TREE_CHAIN (t))
+ for (iter = IDENTIFIER_BINDING (name); iter; iter = iter->previous)
{
tree binding;
- if (!LOCAL_BINDING_P (t) && nonclass)
+ if (!LOCAL_BINDING_P (iter) && nonclass)
/* We're not looking for class-scoped bindings, so keep going. */
continue;
/* If this is the kind of thing we're looking for, we're done. */
- if (qualify_lookup (BINDING_VALUE (t), flags))
- binding = BINDING_VALUE (t);
+ if (qualify_lookup (BINDING_VALUE (iter), flags))
+ binding = BINDING_VALUE (iter);
else if ((flags & LOOKUP_PREFER_TYPES)
- && qualify_lookup (BINDING_TYPE (t), flags))
- binding = BINDING_TYPE (t);
+ && qualify_lookup (BINDING_TYPE (iter), flags))
+ binding = BINDING_TYPE (iter);
else
binding = NULL_TREE;
/* Handle access control on types from enclosing or base classes. */
if (binding && ! yylex
- && BINDING_LEVEL (t) && BINDING_LEVEL (t)->parm_flag == 2)
- type_access_control (BINDING_LEVEL (t)->this_class, binding);
+ && BINDING_LEVEL (iter) && BINDING_LEVEL (iter)->parm_flag == 2)
+ type_access_control (BINDING_LEVEL (iter)->this_class, binding);
if (binding
&& (!val || !IMPLICIT_TYPENAME_TYPE_DECL_P (binding)))
@@ -6183,6 +6277,10 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
}
}
+ /* The name might be from an enclosing class of the current scope. */
+ if (!val && !nonclass && current_class_type)
+ val = qualify_lookup (lookup_nested_field (name, !yylex), flags);
+
/* Now lookup in namespace scopes. */
if (!val || val_is_implicit_typename)
{
@@ -6223,7 +6321,7 @@ does not match lookup in the current scope (`%#D')",
else if (from_obj)
val = from_obj;
- return val;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
}
tree
@@ -6267,6 +6365,8 @@ lookup_name_current_level (name)
struct cp_binding_level *b;
tree t = NULL_TREE;
+ timevar_push (TV_NAME_LOOKUP);
+
b = current_binding_level;
while (b->parm_flag == 2)
b = b->level_chain;
@@ -6285,7 +6385,7 @@ lookup_name_current_level (name)
while (1)
{
if (BINDING_LEVEL (IDENTIFIER_BINDING (name)) == b)
- return IDENTIFIER_VALUE (name);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name));
if (b->keep == 2)
b = b->level_chain;
@@ -6294,7 +6394,7 @@ lookup_name_current_level (name)
}
}
- return t;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
/* Like lookup_name_current_level, but for types. */
@@ -6304,6 +6404,8 @@ lookup_type_current_level (name)
tree name;
{
register tree t = NULL_TREE;
+
+ timevar_push (TV_NAME_LOOKUP);
my_friendly_assert (! current_binding_level->namespace_p, 980716);
@@ -6314,7 +6416,8 @@ lookup_type_current_level (name)
while (1)
{
if (purpose_member (name, b->type_shadowed))
- return REAL_IDENTIFIER_TYPE_VALUE (name);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
+ REAL_IDENTIFIER_TYPE_VALUE (name));
if (b->keep == 2)
b = b->level_chain;
else
@@ -6322,7 +6425,7 @@ lookup_type_current_level (name)
}
}
- return t;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
void
@@ -6550,6 +6653,10 @@ cxx_init_decl_processing ()
NAMESPACE_LEVEL (global_namespace) = global_binding_level;
declare_namespace_level ();
+ VARRAY_TREE_INIT (global_binding_level->static_decls,
+ 200,
+ "Static declarations");
+
/* Create the `std' namespace. */
push_namespace (std_identifier);
std_node = current_namespace;
@@ -7417,7 +7524,9 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
wrong semantics. If we say -fno-conserve-space, we want this to
produce errors about redefs; to do this we force variables into the
data segment. */
- DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem);
+ DECL_COMMON (tem) = ((TREE_CODE (tem) != VAR_DECL
+ || !DECL_THREAD_LOCAL (tem))
+ && (flag_conserve_space || ! TREE_PUBLIC (tem)));
#endif
if (! processing_template_decl)
@@ -7545,10 +7654,7 @@ grok_reference_init (decl, type, init)
DECL_INITIAL for local references (instead assigning to them
explicitly); we need to allow the temporary to be initialized
first. */
- tmp = convert_to_reference
- (type, init, CONV_IMPLICIT,
- LOOKUP_ONLYCONVERTING|LOOKUP_SPECULATIVELY|LOOKUP_NORMAL|DIRECT_BIND,
- decl);
+ tmp = initialize_reference (type, init, decl);
if (tmp == error_mark_node)
return NULL_TREE;
@@ -7900,6 +8006,7 @@ reshape_init (tree type, tree *initp)
{
/* Loop through the initializable fields, gathering
initializers. */
+ /* FIXME support non-trivial labeled initializers. */
while (*initp && field)
{
tree field_init;
@@ -7914,8 +8021,6 @@ reshape_init (tree type, tree *initp)
initializer for the first member of the union. */
if (TREE_CODE (type) == UNION_TYPE)
break;
- if (TREE_PURPOSE (field_init))
- field = TREE_PURPOSE (field_init);
field = next_initializable_field (TREE_CHAIN (field));
}
}
@@ -8204,14 +8309,16 @@ void
maybe_inject_for_scope_var (decl)
tree decl;
{
+ timevar_push (TV_NAME_LOOKUP);
+
if (!DECL_NAME (decl))
- return;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0);
/* Declarations of __FUNCTION__ and its ilk appear magically when
the variable is first used. If that happens to be inside a
for-loop, we don't want to do anything special. */
if (DECL_PRETTY_FUNCTION_P (decl))
- return;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0);
if (current_binding_level->is_for_scope)
{
@@ -8227,8 +8334,8 @@ maybe_inject_for_scope_var (decl)
Otherwise, we need to preserve the temp slot for decl to last
into the outer binding level. */
- tree outer_binding
- = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (decl)));
+ cxx_binding *outer_binding
+ = IDENTIFIER_BINDING (DECL_NAME (decl))->previous;
if (outer_binding && BINDING_LEVEL (outer_binding) == outer
&& (TREE_CODE (BINDING_VALUE (outer_binding))
@@ -8242,6 +8349,8 @@ maybe_inject_for_scope_var (decl)
else if (DECL_IN_MEMORY_P (decl))
preserve_temp_slots (DECL_RTL (decl));
}
+
+ timevar_pop (TV_NAME_LOOKUP);
}
/* Generate code to initialize DECL (a local variable). */
@@ -8481,6 +8590,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
necessary zero-initialization has already been performed. */
if (TREE_STATIC (decl) && !DECL_INITIAL (decl))
DECL_INITIAL (decl) = build_zero_init (TREE_TYPE (decl),
+ /*nelts=*/NULL_TREE,
/*static_storage_p=*/true);
/* Remember that the initialization for this variable has
taken place. */
@@ -9233,13 +9343,19 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
DECL_NOT_REALLY_EXTERN (decl) = 1;
}
+ DID_INLINE_FUNC (decl) = 0;
/* If the declaration was declared inline, mark it as such. */
if (inlinep)
DECL_DECLARED_INLINE_P (decl) = 1;
/* We inline functions that are explicitly declared inline, or, when
the user explicitly asks us to, all functions. */
- if (DECL_DECLARED_INLINE_P (decl) || flag_inline_trees == 2)
+ if (DECL_DECLARED_INLINE_P (decl))
DECL_INLINE (decl) = 1;
+ if (flag_inline_trees == 2 && !DECL_INLINE (decl))
+ {
+ DID_INLINE_FUNC (decl) = 1;
+ DECL_INLINE (decl) = 1;
+ }
DECL_EXTERNAL (decl) = 1;
if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE)
@@ -9532,8 +9648,7 @@ grokvardecl (type, name, specbits_in, initialized, constp, scope)
TYPE, which is a POINTER_TYPE to a METHOD_TYPE. */
tree
-build_ptrmemfunc_type (type)
- tree type;
+build_ptrmemfunc_type (tree type)
{
tree fields[4];
tree t;
@@ -10236,6 +10351,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
ctype = cname;
}
+ /* If the parser sees something like "void a::b" where
+ "a::b" is a namespace, it will build a SCOPE_REF with
+ a NAMESPACE_DECL, rather than an IDENTIFIER_NODE, as
+ the second operand. Since the SCOPE_REF is being
+ used as a declarator, we recover from that here. */
+ if (TREE_CODE (TREE_OPERAND (decl, 1)) == NAMESPACE_DECL)
+ TREE_OPERAND (decl, 1) = DECL_NAME (TREE_OPERAND (decl, 1));
+
if (ctype && TREE_CODE (TREE_OPERAND (decl, 1)) == TYPE_DECL
&& constructor_name_p (DECL_NAME (TREE_OPERAND (decl, 1)),
ctype))
@@ -11449,11 +11572,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
type = error_mark_node;
}
- if (decl_context == FIELD
+ if ((decl_context == FIELD || decl_context == PARM)
&& !processing_template_decl
&& variably_modified_type_p (type))
{
- error ("data member may not have variably modified type `%T'", type);
+ if (decl_context == FIELD)
+ error ("data member may not have variably modified type `%T'", type);
+ else
+ error ("parameter may not have variably modified type `%T'", type);
type = error_mark_node;
}
@@ -12211,7 +12337,10 @@ require_complete_types_for_parms (parms)
/* grokparms will have already issued an error */
TREE_TYPE (parms) = error_mark_node;
else if (complete_type_or_else (TREE_TYPE (parms), parms))
- layout_decl (parms, 0);
+ {
+ layout_decl (parms, 0);
+ DECL_ARG_TYPE (parms) = type_passed_as (TREE_TYPE (parms));
+ }
else
TREE_TYPE (parms) = error_mark_node;
}
@@ -13013,6 +13142,8 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
struct cp_binding_level *b = current_binding_level;
tree context = NULL_TREE;
+ timevar_push (TV_NAME_LOOKUP);
+
switch (tag_code)
{
case record_type:
@@ -13215,7 +13346,7 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
TYPE_ATTRIBUTES (ref) = attributes;
- return ref;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ref);
}
tree
@@ -13468,44 +13599,56 @@ finish_enum (enumtype)
/* We built up the VALUES in reverse order. */
TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
- /* [dcl.enum]
-
- Following the closing brace of an enum-specifier, each
- enumerator has the type of its enumeration. Prior to the
- closing brace, the type of each enumerator is the type of
- its initializing value. */
- for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
- TREE_TYPE (TREE_VALUE (pair)) = enumtype;
-
- /* For an enum defined in a template, all further processing is
- postponed until the template is instantiated. */
+ /* For an enum defined in a template, just set the type of the values;
+ all further processing is postponed until the template is
+ instantiated. We need to set the type so that tsubst of a CONST_DECL
+ works. */
if (processing_template_decl)
{
+ for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
+ TREE_TYPE (TREE_VALUE (pair)) = enumtype;
if (at_function_scope_p ())
add_stmt (build_min (TAG_DEFN, enumtype));
return;
}
- /* Figure out what the minimum and maximum values of the enumerators
- are. */
if (TYPE_VALUES (enumtype))
{
minnode = maxnode = NULL_TREE;
- for (pair = TYPE_VALUES (enumtype);
- pair;
- pair = TREE_CHAIN (pair))
+ for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
{
- tree value;
+ tree decl = TREE_VALUE (pair);
+ tree value = DECL_INITIAL (decl);
- value = DECL_INITIAL (TREE_VALUE (pair));
+ /* [dcl.enum]: Following the closing brace of an enum-specifier,
+ each enumerator has the type of its enumeration. Prior to the
+ closing brace, the type of each enumerator is the type of its
+ initializing value. */
+ TREE_TYPE (decl) = enumtype;
+ /* Figure out what the minimum and maximum values of the
+ enumerators are. */
if (!minnode)
minnode = maxnode = value;
else if (tree_int_cst_lt (maxnode, value))
maxnode = value;
else if (tree_int_cst_lt (value, minnode))
minnode = value;
+
+ /* Set the TREE_TYPE for the values as well. That's so that when
+ we call decl_constant_value we get an entity of the right type
+ (but with the constant value). But first make a copy so we
+ don't clobber shared INTEGER_CSTs. */
+ if (TREE_TYPE (value) != enumtype)
+ {
+ value = DECL_INITIAL (decl) = copy_node (value);
+ TREE_TYPE (value) = enumtype;
+ }
+
+ /* In addition, transform the TYPE_VALUES list to contain the
+ values, rather than the CONST_DECLs for them. */
+ TREE_VALUE (pair) = value;
}
}
else
@@ -13520,18 +13663,6 @@ finish_enum (enumtype)
highprec = min_precision (maxnode, unsignedp);
precision = MAX (lowprec, highprec);
- /* Set the TREE_TYPE for the values as well. That's so that when we
- call decl_constant_value we get an entity of the right type (but
- with the constant value). In addition, transform the TYPE_VALUES
- list to contain the values, rather than the CONST_DECLs for them. */
- for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
- {
- tree value = DECL_INITIAL (TREE_VALUE (pair));
-
- TREE_TYPE (value) = enumtype;
- TREE_VALUE (pair) = value;
- }
-
/* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */
TYPE_SIZE (enumtype) = NULL_TREE;
TYPE_PRECISION (enumtype) = precision;
@@ -13583,7 +13714,6 @@ build_enumerator (name, value, enumtype)
tree decl;
tree context;
tree type;
- tree values;
/* Remove no-op casts from the value. */
if (value)
@@ -13630,26 +13760,9 @@ build_enumerator (name, value, enumtype)
}
/* Remove no-op casts from the value. */
- if (value)
- STRIP_TYPE_NOPS (value);
-#if 0
- /* To fix MAX_VAL enum consts. (bkoz) */
- TREE_TYPE (value) = integer_type_node;
-#endif
+ STRIP_TYPE_NOPS (value);
}
- /* We always have to copy here; not all INTEGER_CSTs are unshared.
- Even in other cases, we will later (in finish_enum) be setting
- the type of VALUE. But, we don't need to make a copy if this
- VALUE is one of the enumeration constants for this same
- enumeration type. */
- for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
- if (TREE_VALUE (values) == value)
- break;
- /* If we didn't break out of the loop, then we do need a copy. */
- if (!values && value)
- value = copy_node (value);
-
/* C++ associates enums with global, function, or class declarations. */
context = current_scope ();
@@ -14416,6 +14529,15 @@ finish_function (flags)
if (fndecl == NULL_TREE)
return error_mark_node;
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
+ && DECL_VIRTUAL_P (fndecl)
+ && !processing_template_decl)
+ {
+ tree fnclass = DECL_CONTEXT (fndecl);
+ if (fndecl == CLASSTYPE_KEY_METHOD (fnclass))
+ keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes);
+ }
+
nested = function_depth > 1;
fntype = TREE_TYPE (fndecl);
@@ -14487,11 +14609,20 @@ finish_function (flags)
if (current_function_return_value)
{
tree r = current_function_return_value;
- /* This is only worth doing for fns that return in memory--and
- simpler, since we don't have to worry about promoted modes. */
+ tree outer;
+
if (r != error_mark_node
- && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
+ /* This is only worth doing for fns that return in memory--and
+ simpler, since we don't have to worry about promoted modes. */
+ && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)))
+ /* Only allow this for variables declared in the outer scope of
+ the function so we know that their lifetime always ends with a
+ return; see g++.dg/opt/nrv6.C. We could be more flexible if
+ we were to do this optimization in tree-ssa. */
+ && (outer = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl)),
+ chain_member (r, BLOCK_VARS (outer))))
{
+
DECL_ALIGN (r) = DECL_ALIGN (DECL_RESULT (fndecl));
walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
nullify_returns_r, r);
@@ -14631,6 +14762,7 @@ start_method (declspecs, declarator, attrlist)
DECL_DECLARED_INLINE_P (fndecl) = 1;
+ DID_INLINE_FUNC (fndecl) = 0;
if (flag_default_inline)
DECL_INLINE (fndecl) = 1;
@@ -14894,7 +15026,6 @@ cp_tree_node_structure (t)
{
case DEFAULT_ARG: return TS_CP_IDENTIFIER;
case IDENTIFIER_NODE: return TS_CP_IDENTIFIER;
- case CPLUS_BINDING: return TS_CP_BINDING;
case OVERLOAD: return TS_CP_OVERLOAD;
case TEMPLATE_PARM_INDEX: return TS_CP_TPI;
case PTRMEM_CST: return TS_CP_PTRMEM;