diff options
author | Gabriel Dos Reis <gdr@integrable-solutions.net> | 2003-10-13 10:26:36 +0000 |
---|---|---|
committer | Gabriel Dos Reis <gdr@gcc.gnu.org> | 2003-10-13 10:26:36 +0000 |
commit | 00e8de680e6a5c880ac9aec78b765f6e1d2531dc (patch) | |
tree | b9ede29f76d95815a065186834227685a06326b9 | |
parent | 4f0504d9072cc2ced75e6a1586d95d1f33e4fb37 (diff) | |
download | gcc-00e8de680e6a5c880ac9aec78b765f6e1d2531dc.zip gcc-00e8de680e6a5c880ac9aec78b765f6e1d2531dc.tar.gz gcc-00e8de680e6a5c880ac9aec78b765f6e1d2531dc.tar.bz2 |
Break out decl.c (2/n)
Break out decl.c (2/n)
* name-lookup.c: Include diagnostic.h
(cxx_binding_free): Make static.
(cxx_binding_make): Likewise.
(binding_table_new): Likewise
(binding_table_free): Likewise.
(binding_table_insert): Likewise.
(binding_table_find_anon_type): Likewise.
(binding_table_reverse_maybe_remap): Likewise.
(supplement_binding): Likewise.
* name-lookup.h (global_scope_name): Declare extern.
(global_type_node): Likewise.
(cxx_binding_free): Don't export.
(cxx_binding_make): Likewise.
(binding_table_new): Likewise.
(binding_table_free): Likewise.
(binding_table_insert): Likewise.
(binding_table_find_anon_type): Likewise.
(binding_table_reverse_maybe_remap): Likewise.
* Make-lang.in (cp/name-lookup.o): Depend on $(DIAGNOSTIC_H)
* decl.c (lookup_namespace_name): Move to name-lookup.c
(select_decl): Likewise.
(unqualified_namespace_lookup): Likewise.
(lookup_qualified_name): Likewise.
(lookup_name_real): Likewise.
(lookup_name_nonclass): Likewise.
(lookup_function_nonclass): Likewise.
(lookup_name): Likewise.
(lookup_name_current_level): Likewise.
(lookup_type_current_level): Likewise.
(lookup_flags): Likewise.
(qualify_lookup): Likewise.
(lookup_tag): Likewise.
(lookup_tag_reverse): Likewise.
(getdecls): Likewise.
(storedecls): Remove.
(cxx_remember_type_decls): Likewise.
(global_bindings_p): Likewise.
(innermost_nonclass_level): Likewise.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(kept_level_p): Likewise.
(innermost_scope_kind): Likewise.
(template_parm_scope_p): Likewise.
(push_binding): Likewise.
(push_local_binding): Likewise.
(add_decl_to_level): Likewise. Make extern.
(push_class_binding): Move to name-lookup.c.
(resume_level): Likewise. Rename to resume_scope.
(begin_scope): Likewise.
(indent): Likewise.
(binding_depth): Likewise.
(is_class_level): Likewise.
(cxx_scope_descriptor): Likewise.
(cxx_scope_debug): Likewise.
(namespace_scope_ht_size): Likewise.
(leave_scope): Likewise.
(pushlevel_class): Likewise.
(poplevel_class): Likewise.
(clear_identifier_class_values): Likewise.
(pushdecl_with_scope): Likewise.
(pushdecl_namespace_level): Likewise.
(pushdecl_class_level): Likewise.
(push_class_level_binding): Likewise.
(push_using_directive): Likewise.
(identifier_global_value): Likewise.
(keep_next_level_flag): Likewise.
(keep_next_level): Likewise.
(free_binding_level): Likewise.
(set_class_shadows): Likewise.
(maybe_push_cleanup_level): Likewise.
(cp_namespace_decls): Likewise.
(bt_print_entry): Likewise.
(print_binding_level): Likewise.
(print_other_binding_stack): Likewise.
(print_binding_stack): Likewise.
(push_namespace): Likewise.
(pop_namespace): Likewise.
(push_nested_namespace): Likewise.
(pop_nested_namespace): Likewise.
(cxx_saved_binding_make): Likewise.
(struct cxx_saved_binding_make): Likewise.
(store_bindings): Likewise.
(maybe_push_to_top_level): Likewise.
(push_to_top_level): Likewise.
(pop_from_top_level): Likewise.
(identifier_type_value): Likewise.
(set_identifier_type_value): Likewise.
(set_identifier_type_value_with_scope): Likewise.
(pop_everything): Likewise.
(pushtag): Likewise.
(follow_tag_typedef): Likewise.
(maybe_process_template_type_declaration): Likewise.
(pop_binding): Likewise.
* cp-tree.h: Move corresponding declarations to name-lookup.h
From-SVN: r72426
-rw-r--r-- | gcc/cp/ChangeLog | 98 | ||||
-rw-r--r-- | gcc/cp/Make-lang.in | 3 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 48 | ||||
-rw-r--r-- | gcc/cp/decl.c | 2268 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 2241 | ||||
-rw-r--r-- | gcc/cp/name-lookup.h | 65 |
6 files changed, 2393 insertions, 2330 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9a0735b..be4eba0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,101 @@ +2003-10-13 Gabriel Dos Reis <gdr@integrable-solutions.net> + + Break out decl.c (2/n) + * name-lookup.c: Include diagnostic.h + (cxx_binding_free): Make static. + (cxx_binding_make): Likewise. + (binding_table_new): Likewise + (binding_table_free): Likewise. + (binding_table_insert): Likewise. + (binding_table_find_anon_type): Likewise. + (binding_table_reverse_maybe_remap): Likewise. + (supplement_binding): Likewise. + * name-lookup.h (global_scope_name): Declare extern. + (global_type_node): Likewise. + (cxx_binding_free): Don't export. + (cxx_binding_make): Likewise. + (binding_table_new): Likewise. + (binding_table_free): Likewise. + (binding_table_insert): Likewise. + (binding_table_find_anon_type): Likewise. + (binding_table_reverse_maybe_remap): Likewise. + * Make-lang.in (cp/name-lookup.o): Depend on $(DIAGNOSTIC_H) + * decl.c (lookup_namespace_name): Move to name-lookup.c + (select_decl): Likewise. + (unqualified_namespace_lookup): Likewise. + (lookup_qualified_name): Likewise. + (lookup_name_real): Likewise. + (lookup_name_nonclass): Likewise. + (lookup_function_nonclass): Likewise. + (lookup_name): Likewise. + (lookup_name_current_level): Likewise. + (lookup_type_current_level): Likewise. + (lookup_flags): Likewise. + (qualify_lookup): Likewise. + (lookup_tag): Likewise. + (lookup_tag_reverse): Likewise. + (getdecls): Likewise. + (storedecls): Remove. + (cxx_remember_type_decls): Likewise. + (global_bindings_p): Likewise. + (innermost_nonclass_level): Likewise. + (toplevel_bindings_p): Likewise. + (namespace_bindings_p): Likewise. + (kept_level_p): Likewise. + (innermost_scope_kind): Likewise. + (template_parm_scope_p): Likewise. + (push_binding): Likewise. + (push_local_binding): Likewise. + (add_decl_to_level): Likewise. Make extern. + (push_class_binding): Move to name-lookup.c. + (resume_level): Likewise. Rename to resume_scope. + (begin_scope): Likewise. + (indent): Likewise. + (binding_depth): Likewise. + (is_class_level): Likewise. + (cxx_scope_descriptor): Likewise. + (cxx_scope_debug): Likewise. + (namespace_scope_ht_size): Likewise. + (leave_scope): Likewise. + (pushlevel_class): Likewise. + (poplevel_class): Likewise. + (clear_identifier_class_values): Likewise. + (pushdecl_with_scope): Likewise. + (pushdecl_namespace_level): Likewise. + (pushdecl_class_level): Likewise. + (push_class_level_binding): Likewise. + (push_using_directive): Likewise. + (identifier_global_value): Likewise. + (keep_next_level_flag): Likewise. + (keep_next_level): Likewise. + (free_binding_level): Likewise. + (set_class_shadows): Likewise. + (maybe_push_cleanup_level): Likewise. + (cp_namespace_decls): Likewise. + (bt_print_entry): Likewise. + (print_binding_level): Likewise. + (print_other_binding_stack): Likewise. + (print_binding_stack): Likewise. + (push_namespace): Likewise. + (pop_namespace): Likewise. + (push_nested_namespace): Likewise. + (pop_nested_namespace): Likewise. + (cxx_saved_binding_make): Likewise. + (struct cxx_saved_binding_make): Likewise. + (store_bindings): Likewise. + (maybe_push_to_top_level): Likewise. + (push_to_top_level): Likewise. + (pop_from_top_level): Likewise. + (identifier_type_value): Likewise. + (set_identifier_type_value): Likewise. + (set_identifier_type_value_with_scope): Likewise. + (pop_everything): Likewise. + (pushtag): Likewise. + (follow_tag_typedef): Likewise. + (maybe_process_template_type_declaration): Likewise. + (pop_binding): Likewise. + * cp-tree.h: Move corresponding declarations to name-lookup.h + 2003-10-12 Steven Bosscher <steven@gcc.gnu.org> * cvt.c (ocp_convert): Move warning to C common code. diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index a975273..52a5a0c 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -279,7 +279,8 @@ cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h $( cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) diagnostic.h gt-cp-parser.h output.h cp/name-lookup.o: cp/name-lookup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(CXX_TREE_H) timevar.h gt-cp-name-lookup.h toplev.h + $(TM_H) $(CXX_TREE_H) timevar.h gt-cp-name-lookup.h toplev.h \ + $(DIAGNOSTIC_H) cp/cxx-pretty-print.o: cp/cxx-pretty-print.c $(CXX_PRETTY_PRINT_H) \ $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h $(CXX_TREE_H) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f4582c3..f3286d6 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3584,9 +3584,6 @@ extern void clone_function_decl (tree, int); extern void adjust_clone_args (tree); /* decl.c */ -extern int global_bindings_p (void); -extern int kept_level_p (void); -extern tree getdecls (void); extern void insert_block (tree); extern void set_block (tree); extern tree pushdecl (tree); @@ -3597,34 +3594,12 @@ extern bool cxx_mark_addressable (tree); extern void cxx_push_function_context (struct function *); extern void cxx_pop_function_context (struct function *); extern void cxx_mark_function_context (struct function *); -extern int toplevel_bindings_p (void); -extern int namespace_bindings_p (void); -extern void keep_next_level (bool); -extern scope_kind innermost_scope_kind (void); -extern int template_parm_scope_p (void); -extern void set_class_shadows (tree); -extern void maybe_push_cleanup_level (tree); -extern cxx_scope *begin_scope (scope_kind, tree); +extern void maybe_push_cleanup_level (tree); extern void finish_scope (void); -extern void resume_level (struct cp_binding_level *); extern void delete_block (tree); extern void add_block_current_level (tree); -extern void pushlevel_class (void); -extern void poplevel_class (void); -extern void print_binding_stack (void); -extern void print_binding_level (struct cp_binding_level *); -extern void push_namespace (tree); -extern void pop_namespace (void); -extern void push_nested_namespace (tree); -extern void pop_nested_namespace (tree); -extern void maybe_push_to_top_level (int); -extern void push_to_top_level (void); -extern void pop_from_top_level (void); extern void push_switch (tree); extern void pop_switch (void); -extern tree identifier_type_value (tree); -extern void set_identifier_type_value (tree, tree); -extern void pop_everything (void); extern void pushtag (tree, tree, int); extern tree make_anon_name (void); extern void clear_anon_tags (void); @@ -3632,31 +3607,16 @@ extern int decls_match (tree, tree); extern int duplicate_decls (tree, tree); extern tree pushdecl_top_level (tree); extern tree pushdecl_top_level_and_finish (tree, tree); -extern bool pushdecl_class_level (tree); -extern tree pushdecl_namespace_level (tree); extern tree push_using_decl (tree, tree); -extern tree push_using_directive (tree); -extern bool push_class_level_binding (tree, tree); extern tree implicitly_declare (tree); extern tree declare_local_label (tree); extern tree define_label (location_t, tree); extern void check_goto (tree); extern void define_case_label (void); -extern tree namespace_binding (tree, tree); -extern void set_namespace_binding (tree, tree, tree); -extern tree lookup_namespace_name (tree, tree); extern tree make_typename_type (tree, tree, tsubst_flags_t); extern tree make_unbound_class_template (tree, tree, tsubst_flags_t); -extern tree lookup_name_nonclass (tree); -extern tree lookup_function_nonclass (tree, tree); -extern tree lookup_qualified_name (tree, tree, bool, bool); -extern tree lookup_name (tree, int); -extern tree lookup_name_current_level (tree); -extern tree lookup_type_current_level (tree); -extern tree lookup_name_real (tree, int, int, int, int); extern tree namespace_ancestor (tree, tree); extern bool is_ancestor (tree, tree); -extern tree unqualified_namespace_lookup (tree, int, tree *); extern tree check_for_out_of_scope_variable (tree); extern bool lookup_using_namespace (tree, cxx_binding *, tree, tree, int, tree *); extern bool qualified_lookup_using_namespace (tree, tree, cxx_binding *, int); @@ -3705,12 +3665,8 @@ extern void revert_static_member_fn (tree); extern void fixup_anonymous_aggr (tree); extern int check_static_variable_definition (tree, tree); extern tree compute_array_index_type (tree, tree); -extern void push_local_binding (tree, tree, int); -extern int push_class_binding (tree, tree); extern tree check_default_argument (tree, tree); extern tree push_overloaded_decl (tree, int); -extern void clear_identifier_class_values (void); -extern void storetags (tree); extern int vtable_decl_p (tree, void *); extern int vtype_decl_p (tree, void *); extern int sigtable_decl_p (tree, void *); @@ -3722,7 +3678,6 @@ typedef int (*walk_namespaces_fn) (tree, void *); extern int walk_namespaces (walk_namespaces_fn, void *); extern int wrapup_globals_for_namespace (tree, void *); -extern tree cp_namespace_decls (tree); extern tree create_implicit_typedef (tree, tree); extern tree maybe_push_decl (tree); extern tree build_target_expr_with_type (tree, tree); @@ -3736,6 +3691,7 @@ extern tree check_elaborated_type_specifier (enum tag_types, tree, bool); extern tree cxx_builtin_type_decls (void); extern bool have_extern_spec; +extern GTY(()) tree last_function_parms; /* in decl2.c */ extern bool check_java_method (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 872fed0..bcd0a5f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -55,14 +55,10 @@ Boston, MA 02111-1307, USA. */ static tree grokparms (tree); static const char *redeclaration_error_message (tree, tree); -static void resume_binding_level (struct cp_binding_level *); static int decl_jump_unsafe (tree); -static void storedecls (tree); static void require_complete_types_for_parms (tree); static int ambi_op_p (enum tree_code); static int unary_op_p (enum tree_code); -static cxx_saved_binding *store_bindings (tree, cxx_saved_binding *); -static tree lookup_tag_reverse (tree, tree); static void push_local_name (tree); static void warn_extern_redeclared_static (tree, tree); static tree grok_reference_init (tree, tree, tree, tree *); @@ -70,11 +66,6 @@ static tree grokfndecl (tree, tree, tree, tree, int, enum overload_flags, tree, tree, int, int, int, int, int, int, tree); static tree grokvardecl (tree, tree, RID_BIT_TYPE *, int, int, tree); -static tree follow_tag_typedef (tree); -static tree lookup_tag (enum tree_code, tree, - struct cp_binding_level *, int); -static void set_identifier_type_value_with_scope - (tree, tree, struct cp_binding_level *); static void record_unknown_type (tree, const char *); static tree builtin_function_1 (const char *, tree, tree, int, enum built_in_class, const char *, @@ -83,24 +74,15 @@ static tree build_library_fn_1 (tree, enum tree_code, tree); static int member_function_or_else (tree, tree, enum overload_flags); static void bad_specifiers (tree, const char *, int, int, int, int, int); -static tree maybe_process_template_type_declaration - (tree, int, struct cp_binding_level*); static void check_for_uninitialized_const_var (tree); static hashval_t typename_hash (const void *); static int typename_compare (const void *, const void *); -static void push_binding (tree, tree, struct cp_binding_level*); -static void pop_binding (tree, tree); static tree local_variable_p_walkfn (tree *, int *, void *); -static tree select_decl (cxx_binding *, int); -static int lookup_flags (int, int); -static tree qualify_lookup (tree, int); static tree record_builtin_java_type (const char *, int); static const char *tag_name (enum tag_types code); -static struct cp_binding_level *innermost_nonclass_level (void); static int walk_namespaces_r (tree, walk_namespaces_fn, void *); static int walk_globals_r (tree, void*); static int walk_vtables_r (tree, void*); -static void add_decl_to_level (tree, struct cp_binding_level *); static tree make_label_decl (tree, int); static void use_label (tree); static void check_previous_goto_1 (tree, struct cp_binding_level *, tree, @@ -193,10 +175,10 @@ tree cp_global_trees[CPTI_MAX]; /* Indicates that there is a type value in some namespace, although that is not necessarily in scope at the moment. */ -static GTY(()) tree global_type_node; +tree global_type_node; /* The node that holds the "name" of the global scope. */ -static GTY(()) tree global_scope_name; +tree global_scope_name; /* Used only for jumps to as-yet undefined labels, since jumps to defined labels can have their validity checked immediately. */ @@ -278,331 +260,12 @@ int adding_implicit_members = 0; bool have_extern_spec; -/* A chain of binding_level structures awaiting reuse. */ - -static GTY((deletable (""))) struct cp_binding_level *free_binding_level; - -/* true means unconditionally make a BLOCK for the next level pushed. */ - -static bool keep_next_level_flag; - /* A TREE_LIST of VAR_DECLs. The TREE_PURPOSE is a RECORD_TYPE or UNION_TYPE; the TREE_VALUE is a VAR_DECL with that type. At the time the VAR_DECL was declared, the type was incomplete. */ static GTY(()) tree incomplete_vars; - -#ifndef ENABLE_SCOPE_CHECKING -# define ENABLE_SCOPE_CHECKING 0 -#else -# define ENABLE_SCOPE_CHECKING 1 -#endif - -static int binding_depth = 0; -static int is_class_level = 0; - -static void -indent (int depth) -{ - int i; - - for (i = 0; i < depth * 2; i++) - putc (' ', stderr); -} - -static tree pushdecl_with_scope (tree, struct cp_binding_level *); - -/* Return a string describing the kind of SCOPE we have. */ -static const char * -cxx_scope_descriptor (cxx_scope *scope) -{ - /* The order of this table must match the "scope_kind" - enumerators. */ - static const char* scope_kind_names[] = { - "block-scope", - "cleanup-scope", - "try-scope", - "catch-scope", - "for-scope", - "function-parameter-scope", - "class-scope", - "namespace-scope", - "template-parameter-scope", - "template-explicit-spec-scope" - }; - const scope_kind kind = scope->explicit_spec_p - ? sk_template_spec : scope->kind; - - return scope_kind_names[kind]; -} - -/* Output a debugging information about SCOPE when performning - ACTION at LINE. */ -static void -cxx_scope_debug (cxx_scope *scope, int line, const char *action) -{ - const char *desc = cxx_scope_descriptor (scope); - if (scope->this_entity) - verbatim ("%s %s(%E) %p %d\n", action, desc, - scope->this_entity, (void *) scope, line); - else - verbatim ("%s %s %p %d\n", action, desc, (void *) scope, line); -} - -/* Return the estimated initial size of the hashtable of a NAMESPACE - scope. */ - -static inline size_t -namespace_scope_ht_size (tree ns) -{ - tree name = DECL_NAME (ns); - - return name == std_identifier - ? NAMESPACE_STD_HT_SIZE - : (name == global_scope_name - ? GLOBAL_SCOPE_HT_SIZE - : NAMESPACE_ORDINARY_HT_SIZE); -} - -/* Create a new KIND scope and make it the top of the active scopes stack. - ENTITY is the scope of the associated C++ entity (namespace, class, - function); it is NULL otherwise. */ - -cxx_scope * -begin_scope (scope_kind kind, tree entity) -{ - cxx_scope *scope; - - /* Reuse or create a struct for this binding level. */ - if (!ENABLE_SCOPE_CHECKING && free_binding_level) - { - scope = free_binding_level; - free_binding_level = scope->level_chain; - } - else - scope = ggc_alloc (sizeof (cxx_scope)); - memset (scope, 0, sizeof (cxx_scope)); - - scope->this_entity = entity; - scope->more_cleanups_ok = true; - switch (kind) - { - case sk_cleanup: - scope->keep = true; - break; - - case sk_template_spec: - scope->explicit_spec_p = true; - kind = sk_template_parms; - /* fall through */ - case sk_template_parms: - case sk_block: - case sk_try: - case sk_catch: - case sk_for: - case sk_class: - case sk_function_parms: - scope->keep = keep_next_level_flag; - break; - - case sk_namespace: - scope->type_decls = binding_table_new (namespace_scope_ht_size (entity)); - NAMESPACE_LEVEL (entity) = scope; - VARRAY_TREE_INIT (scope->static_decls, - DECL_NAME (entity) == std_identifier - || DECL_NAME (entity) == global_scope_name - ? 200 : 10, - "Static declarations"); - break; - - default: - /* Should not happen. */ - my_friendly_assert (false, 20030922); - break; - } - scope->kind = kind; - - /* Add it to the front of currently active scopes stack. */ - scope->level_chain = current_binding_level; - current_binding_level = scope; - keep_next_level_flag = false; - - if (ENABLE_SCOPE_CHECKING) - { - scope->binding_depth = binding_depth; - indent (binding_depth); - cxx_scope_debug (scope, input_location.line, "push"); - is_class_level = 0; - binding_depth++; - } - - return scope; -} - -/* We're about to leave current scope. Pop the top of the stack of - currently active scopes. Return the enclosing scope, now active. */ - -static cxx_scope * -leave_scope (void) -{ - cxx_scope *scope = current_binding_level; - - if (scope->kind == sk_namespace && class_binding_level) - current_binding_level = class_binding_level; - - /* We cannot leave a scope, if there are none left. */ - if (NAMESPACE_LEVEL (global_namespace)) - my_friendly_assert (!global_scope_p (scope), 20030527); - - if (ENABLE_SCOPE_CHECKING) - { - indent (--binding_depth); - cxx_scope_debug (scope, input_location.line, "leave"); - if (is_class_level != (scope == class_binding_level)) - { - indent (binding_depth); - verbatim ("XXX is_class_level != (current_scope == class_scope)\n"); - } - is_class_level = 0; - } - - /* Move one nesting level up. */ - current_binding_level = scope->level_chain; - - /* Namespace-scopes are left most probably temporarily, not completely; - they can be reopen later, e.g. in namespace-extension or any name - binding acttivity that requires us to resume a namespace. For other - scopes, we just make the structure available for reuse. */ - if (scope->kind != sk_namespace) - { - scope->level_chain = free_binding_level; - if (scope->kind == sk_class) - scope->type_decls = NULL; - else - binding_table_free (scope->type_decls); - my_friendly_assert (!ENABLE_SCOPE_CHECKING - || scope->binding_depth == binding_depth, - 20030529); - free_binding_level = scope; - } - - /* Find the innermost enclosing class scope, and reset - CLASS_BINDING_LEVEL appropriately. */ - for (scope = current_binding_level; - scope && scope->kind != sk_class; - scope = scope->level_chain) - ; - class_binding_level = scope && scope->kind == sk_class ? scope : NULL; - - return current_binding_level; -} - -static void -resume_binding_level (struct cp_binding_level* b) -{ - /* Resuming binding levels is meant only for namespaces, - and those cannot nest into classes. */ - my_friendly_assert(!class_binding_level, 386); - /* Also, resuming a non-directly nested namespace is a no-no. */ - my_friendly_assert(b->level_chain == current_binding_level, 386); - current_binding_level = b; - if (ENABLE_SCOPE_CHECKING) - { - b->binding_depth = binding_depth; - indent (binding_depth); - cxx_scope_debug (b, input_location.line, "resume"); - is_class_level = 0; - binding_depth++; - } -} -/* Nonzero if we are currently in the global binding level. */ - -int -global_bindings_p (void) -{ - return global_scope_p (current_binding_level); -} - -/* Return the innermost binding level that is not for a class scope. */ - -static struct cp_binding_level * -innermost_nonclass_level (void) -{ - struct cp_binding_level *b; - - b = current_binding_level; - while (b->kind == sk_class) - b = b->level_chain; - - return b; -} - -/* Nonzero if we are currently in a toplevel binding level. This - means either the global binding level or a namespace in a toplevel - binding level. Since there are no non-toplevel namespace levels, - this really means any namespace or template parameter level. We - also include a class whose context is toplevel. */ - -int -toplevel_bindings_p (void) -{ - struct cp_binding_level *b = innermost_nonclass_level (); - - return b->kind == sk_namespace || b->kind == sk_template_parms; -} - -/* Nonzero if this is a namespace scope, or if we are defining a class - which is itself at namespace scope, or whose enclosing class is - such a class, etc. */ - -int -namespace_bindings_p (void) -{ - struct cp_binding_level *b = innermost_nonclass_level (); - - return b->kind == sk_namespace; -} - -/* If KEEP is true, make a BLOCK node for the next binding level, - unconditionally. Otherwise, use the normal logic to decide whether - or not to create a BLOCK. */ - -void -keep_next_level (bool keep) -{ - keep_next_level_flag = keep; -} - -/* Nonzero if the current level needs to have a BLOCK made. */ - -int -kept_level_p (void) -{ - return (current_binding_level->blocks != NULL_TREE - || current_binding_level->keep - || current_binding_level->kind == sk_cleanup - || current_binding_level->names != NULL_TREE - || current_binding_level->type_decls != NULL); -} - -/* Returns the kind of the innermost scope. */ - -scope_kind -innermost_scope_kind (void) -{ - return current_binding_level->kind; -} - -/* Returns nonzero if this scope was created to store template - parameters. */ - -int -template_parm_scope_p (void) -{ - return innermost_scope_kind () == sk_template_parms; -} - /* Returns the kind of template specialization we are currently processing, given that it's declaration contained N_CLASS_SCOPES explicit scope qualifications. */ @@ -693,28 +356,6 @@ current_tmpl_spec_kind (int n_class_scopes) return innermost_specialization_p ? tsk_expl_spec : tsk_template; } -void -set_class_shadows (tree shadows) -{ - class_binding_level->class_shadowed = shadows; -} - -/* We're defining an object of type TYPE. If it needs a cleanup, but - we're not allowed to add any more objects with cleanups to the current - scope, create a new binding level. */ - -void -maybe_push_cleanup_level (tree type) -{ - if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) - && current_binding_level->more_cleanups_ok == 0) - { - begin_scope (sk_cleanup, NULL); - clear_last_expr (); - add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1); - } -} - /* Exit the current scope. */ void @@ -723,192 +364,6 @@ finish_scope (void) poplevel (0, 0, 0); } -/* Make DECL the innermost binding for ID. The LEVEL is the binding - level at which this declaration is being bound. */ - -static void -push_binding (tree id, tree decl, cxx_scope* level) -{ - cxx_binding *binding = cxx_binding_make (decl, NULL); - - /* Now, fill in the binding information. */ - binding->previous = IDENTIFIER_BINDING (id); - binding->scope = level; - INHERITED_VALUE_BINDING_P (binding) = 0; - LOCAL_BINDING_P (binding) = (level != class_binding_level); - - /* And put it on the front of the list of bindings for ID. */ - IDENTIFIER_BINDING (id) = binding; -} - -/* Add DECL to the list of things declared in B. */ - -static void -add_decl_to_level (tree decl, - struct cp_binding_level* b) -{ - if (TREE_CODE (decl) == NAMESPACE_DECL - && !DECL_NAMESPACE_ALIAS (decl)) - { - TREE_CHAIN (decl) = b->namespaces; - b->namespaces = decl; - } - else if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl)) - { - TREE_CHAIN (decl) = b->vtables; - b->vtables = decl; - } - else - { - /* We build up the list in reverse order, and reverse it later if - necessary. */ - TREE_CHAIN (decl) = b->names; - b->names = decl; - b->names_size++; - - /* If appropriate, add decl to separate list of statics */ - if (b->kind == sk_namespace) - 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); - } -} - -/* Bind DECL to ID in the current_binding_level, assumed to be a local - binding level. If PUSH_USING is set in FLAGS, we know that DECL - doesn't really belong to this binding level, that it got here - through a using-declaration. */ - -void -push_local_binding (tree id, tree decl, int flags) -{ - struct cp_binding_level *b; - - /* Skip over any local classes. This makes sense if we call - push_local_binding with a friend decl of a local class. */ - b = innermost_nonclass_level (); - - if (lookup_name_current_level (id)) - { - /* Supplement the existing binding. */ - if (!supplement_binding (IDENTIFIER_BINDING (id), decl)) - /* It didn't work. Something else must be bound at this - level. Do not add DECL to the list of things to pop - later. */ - return; - } - else - /* Create a new binding. */ - push_binding (id, decl, b); - - if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING)) - /* We must put the OVERLOAD into a TREE_LIST since the - TREE_CHAIN of an OVERLOAD is already used. Similarly for - decls that got here through a using-declaration. */ - decl = build_tree_list (NULL_TREE, decl); - - /* And put DECL on the list of things declared by the current - binding level. */ - add_decl_to_level (decl, b); -} - -/* Bind DECL to ID in the class_binding_level. Returns nonzero if the - binding was successful. */ - -int -push_class_binding (tree id, tree decl) -{ - int result = 1; - 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. */ - note_name_declared_in_class (id, decl); - - if (binding && binding->scope == class_binding_level) - /* Supplement the existing binding. */ - result = supplement_binding (IDENTIFIER_BINDING (id), decl); - else - /* Create a new binding. */ - push_binding (id, decl, class_binding_level); - - /* Update the IDENTIFIER_CLASS_VALUE for this ID to be the - class-level declaration. Note that we do not use DECL here - because of the possibility of the `struct stat' hack; if DECL is - a class-name or enum-name we might prefer a field-name, or some - such. */ - IDENTIFIER_CLASS_VALUE (id) = IDENTIFIER_BINDING (id)->value; - - /* If this is a binding from a base class, mark it as such. */ - binding = IDENTIFIER_BINDING (id); - if (binding->value == decl && TREE_CODE (decl) != TREE_LIST) - { - if (TREE_CODE (decl) == OVERLOAD) - context = CP_DECL_CONTEXT (OVL_CURRENT (decl)); - else - { - my_friendly_assert (DECL_P (decl), 0); - context = context_for_name_lookup (decl); - } - - if (is_properly_derived_from (current_class_type, context)) - INHERITED_VALUE_BINDING_P (binding) = 1; - else - INHERITED_VALUE_BINDING_P (binding) = 0; - } - else if (binding->value == decl) - /* We only encounter a TREE_LIST when push_class_decls detects an - ambiguity. Such an ambiguity can be overridden by a definition - in this class. */ - INHERITED_VALUE_BINDING_P (binding) = 1; - - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result); -} - -/* Remove the binding for DECL which should be the innermost binding - for ID. */ - -static void -pop_binding (tree id, tree decl) -{ - cxx_binding *binding; - - if (id == NULL_TREE) - /* It's easiest to write the loops that call this function without - checking whether or not the entities involved have names. We - get here for such an entity. */ - return; - - /* Get the innermost binding for ID. */ - binding = IDENTIFIER_BINDING (id); - - /* The name should be bound. */ - my_friendly_assert (binding != NULL, 0); - - /* The DECL will be either the ordinary binding or the type - binding for this identifier. Remove that binding. */ - if (binding->value == decl) - binding->value = NULL_TREE; - else if (binding->type == decl) - binding->type = NULL_TREE; - else - abort (); - - if (!binding->value && !binding->type) - { - /* We're completely done with the innermost binding for this - identifier. Unhook it from the list of bindings. */ - IDENTIFIER_BINDING (id) = binding->previous; - - /* Add it to the free list. */ - cxx_binding_free (binding); - } -} - /* When a label goes out of scope, check to see if that label was used in a valid manner, and issue any appropriate warnings or errors. */ @@ -1319,109 +774,6 @@ set_block (tree block ATTRIBUTE_UNUSED ) but it is not applicable in function-at-a-time mode. */ } -/* Do a pushlevel for class declarations. */ - -void -pushlevel_class (void) -{ - if (ENABLE_SCOPE_CHECKING) - is_class_level = 1; - - class_binding_level = begin_scope (sk_class, current_class_type); -} - -/* ...and a poplevel for class declarations. */ - -void -poplevel_class (void) -{ - 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 - of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot - shouldn't even be used when current_class_type isn't set, and second, - if we don't touch it here, we're able to use the cache effect if the - next time we're entering a class scope, it is the same class. */ - if (current_class_depth != 1) - { - struct cp_binding_level* b; - - /* Clear out our IDENTIFIER_CLASS_VALUEs. */ - for (shadowed = level->class_shadowed; - shadowed; - shadowed = TREE_CHAIN (shadowed)) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = NULL_TREE; - - /* Find the next enclosing class, and recreate - IDENTIFIER_CLASS_VALUEs appropriate for that class. */ - b = level->level_chain; - while (b && b->kind != sk_class) - b = b->level_chain; - - if (b) - for (shadowed = b->class_shadowed; - shadowed; - shadowed = TREE_CHAIN (shadowed)) - { - cxx_binding *binding; - - binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed)); - while (binding && binding->scope != b) - binding = binding->previous; - - if (binding) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) - = binding->value; - } - } - else - /* Remember to save what IDENTIFIER's were bound in this scope so we - can recover from cache misses. */ - { - previous_class_type = current_class_type; - previous_class_values = class_binding_level->class_shadowed; - } - for (shadowed = level->type_shadowed; - shadowed; - shadowed = TREE_CHAIN (shadowed)) - SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed)); - - /* Remove the bindings for all of the class-level declarations. */ - for (shadowed = level->class_shadowed; - shadowed; - shadowed = TREE_CHAIN (shadowed)) - pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed)); - - /* Now, pop out of the binding level which we created up in the - `pushlevel_class' routine. */ - if (ENABLE_SCOPE_CHECKING) - is_class_level = 1; - - leave_scope (); - timevar_pop (TV_NAME_LOOKUP); -} - -/* We are entering the scope of a class. Clear IDENTIFIER_CLASS_VALUE - for any names in enclosing classes. */ - -void -clear_identifier_class_values (void) -{ - tree t; - - if (!class_binding_level) - return; - - for (t = class_binding_level->class_shadowed; - t; - t = TREE_CHAIN (t)) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; -} - /* Returns nonzero if T is a virtual function table. */ int @@ -1441,14 +793,6 @@ vtype_decl_p (tree t, void *data ATTRIBUTE_UNUSED ) && TYPE_POLYMORPHIC_P (TREE_TYPE (t))); } -/* Return the declarations that are members of the namespace NS. */ - -tree -cp_namespace_decls (tree ns) -{ - return NAMESPACE_LEVEL (ns)->names; -} - struct walk_globals_data { walk_globals_pred p; walk_globals_fn f; @@ -1585,599 +929,6 @@ wrapup_globals_for_namespace (tree namespace, void* data) } -/* For debugging. */ -static int no_print_functions = 0; -static int no_print_builtins = 0; - -/* Called from print_binding_level through binding_table_foreach to - print the content of binding ENTRY. DATA is a pointer to line offset - marker. */ -static void -bt_print_entry (binding_entry entry, void *data) -{ - int *p = (int *) data; - int len; - - if (entry->name == NULL) - len = 3; - else if (entry->name == TYPE_IDENTIFIER (entry->type)) - len = 2; - else - len = 4; - len = 4; - - *p += len; - - if (*p > 5) - { - fprintf (stderr, "\n\t"); - *p = len; - } - if (entry->name == NULL) - { - print_node_brief (stderr, "<unnamed-typedef", entry->type, 0); - fprintf (stderr, ">"); - } - else if (entry->name == TYPE_IDENTIFIER (entry->type)) - print_node_brief (stderr, "", entry->type, 0); - else - { - print_node_brief (stderr, "<typedef", entry->name, 0); - print_node_brief (stderr, "", entry->type, 0); - fprintf (stderr, ">"); - } -} - -void -print_binding_level (struct cp_binding_level* lvl) -{ - tree t; - int i = 0, len; - fprintf (stderr, " blocks=" HOST_PTR_PRINTF, (void *) lvl->blocks); - if (lvl->more_cleanups_ok) - fprintf (stderr, " more-cleanups-ok"); - if (lvl->have_cleanups) - fprintf (stderr, " have-cleanups"); - fprintf (stderr, "\n"); - if (lvl->names) - { - fprintf (stderr, " names:\t"); - /* We can probably fit 3 names to a line? */ - for (t = lvl->names; t; t = TREE_CHAIN (t)) - { - if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL)) - continue; - if (no_print_builtins - && (TREE_CODE (t) == TYPE_DECL) - && (!strcmp (DECL_SOURCE_FILE (t),"<built-in>"))) - continue; - - /* Function decls tend to have longer names. */ - if (TREE_CODE (t) == FUNCTION_DECL) - len = 3; - else - len = 2; - i += len; - if (i > 6) - { - fprintf (stderr, "\n\t"); - i = len; - } - print_node_brief (stderr, "", t, 0); - if (t == error_mark_node) - break; - } - if (i) - fprintf (stderr, "\n"); - } - if (lvl->type_decls) - { - fprintf (stderr, " tags:\t"); - i = 0; - binding_table_foreach (lvl->type_decls, bt_print_entry, &i); - if (i) - fprintf (stderr, "\n"); - } - if (lvl->class_shadowed) - { - fprintf (stderr, " class-shadowed:"); - for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t)) - { - fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); - } - fprintf (stderr, "\n"); - } - if (lvl->type_shadowed) - { - fprintf (stderr, " type-shadowed:"); - for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t)) - { - fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); - } - fprintf (stderr, "\n"); - } -} - -void -print_other_binding_stack (struct cp_binding_level *stack) -{ - struct cp_binding_level *level; - for (level = stack; !global_scope_p (level); level = level->level_chain) - { - fprintf (stderr, "binding level " HOST_PTR_PRINTF "\n", (void *) level); - print_binding_level (level); - } -} - -void -print_binding_stack (void) -{ - struct cp_binding_level *b; - fprintf (stderr, "current_binding_level=" HOST_PTR_PRINTF - "\nclass_binding_level=" HOST_PTR_PRINTF - "\nNAMESPACE_LEVEL (global_namespace)=" HOST_PTR_PRINTF "\n", - (void *) current_binding_level, (void *) class_binding_level, - (void *) NAMESPACE_LEVEL (global_namespace)); - if (class_binding_level) - { - for (b = class_binding_level; b; b = b->level_chain) - if (b == current_binding_level) - break; - if (b) - b = class_binding_level; - else - b = current_binding_level; - } - else - b = current_binding_level; - print_other_binding_stack (b); - fprintf (stderr, "global:\n"); - print_binding_level (NAMESPACE_LEVEL (global_namespace)); -} - -/* Namespace binding access routines: The namespace_bindings field of - the identifier is polymorphic, with three possible values: - NULL_TREE, a list of "cxx_binding"s. */ - -/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we - select a name that is unique to this compilation unit. */ - -void -push_namespace (tree name) -{ - tree d = NULL_TREE; - int need_new = 1; - int implicit_use = 0; - - timevar_push (TV_NAME_LOOKUP); - - /* We should not get here if the global_namespace is not yet constructed - nor if NAME designates the global namespace: The global scope is - constructed elsewhere. */ - my_friendly_assert (global_namespace != NULL && name != global_scope_name, - 20030531); - - if (!name) - { - /* The name of anonymous namespace is unique for the translation - unit. */ - if (!anonymous_namespace_name) - anonymous_namespace_name = get_file_function_name ('N'); - name = anonymous_namespace_name; - d = IDENTIFIER_NAMESPACE_VALUE (name); - if (d) - /* Reopening anonymous namespace. */ - need_new = 0; - implicit_use = 1; - } - else - { - /* Check whether this is an extended namespace definition. */ - d = IDENTIFIER_NAMESPACE_VALUE (name); - if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL) - { - need_new = 0; - if (DECL_NAMESPACE_ALIAS (d)) - { - error ("namespace alias `%D' not allowed here, assuming `%D'", - d, DECL_NAMESPACE_ALIAS (d)); - d = DECL_NAMESPACE_ALIAS (d); - } - } - } - - if (need_new) - { - /* Make a new namespace, binding the name to it. */ - d = build_lang_decl (NAMESPACE_DECL, name, void_type_node); - DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace); - d = pushdecl (d); - begin_scope (sk_namespace, d); - } - else - resume_binding_level (NAMESPACE_LEVEL (d)); - - if (implicit_use) - do_using_directive (d); - /* Enter the name space. */ - current_namespace = d; - - timevar_pop (TV_NAME_LOOKUP); -} - -/* Pop from the scope of the current namespace. */ - -void -pop_namespace (void) -{ - my_friendly_assert (current_namespace != global_namespace, 20010801); - current_namespace = CP_DECL_CONTEXT (current_namespace); - /* The binding level is not popped, as it might be re-opened later. */ - leave_scope (); -} - -/* Push into the scope of the namespace NS, even if it is deeply - nested within another namespace. */ - -void -push_nested_namespace (tree ns) -{ - if (ns == global_namespace) - push_to_top_level (); - else - { - push_nested_namespace (CP_DECL_CONTEXT (ns)); - push_namespace (DECL_NAME (ns)); - } -} - -/* Pop back from the scope of the namespace NS, which was previously - entered with push_nested_namespace. */ - -void -pop_nested_namespace (tree ns) -{ - timevar_push (TV_NAME_LOOKUP); - while (ns != global_namespace) - { - pop_namespace (); - ns = CP_DECL_CONTEXT (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 - are at all visible. Simply setting current_binding_level to the global - scope isn't enough, because more binding levels may be pushed. */ -struct saved_scope *scope_chain; - -static cxx_saved_binding * -store_bindings (tree names, cxx_saved_binding *old_bindings) -{ - tree t; - cxx_saved_binding *search_bindings = old_bindings; - - timevar_push (TV_NAME_LOOKUP); - for (t = names; t; t = TREE_CHAIN (t)) - { - tree id; - cxx_saved_binding *saved; - cxx_saved_binding *t1; - - if (TREE_CODE (t) == TREE_LIST) - id = TREE_PURPOSE (t); - else - id = DECL_NAME (t); - - if (!id - /* Note that we may have an IDENTIFIER_CLASS_VALUE even when - we have no IDENTIFIER_BINDING if we have left the class - scope, but cached the class-level declarations. */ - || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id))) - continue; - - for (t1 = search_bindings; t1; t1 = t1->previous) - if (t1->identifier == id) - goto skip_it; - - my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135); - 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; - old_bindings = saved; - skip_it: - ; - } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings); -} - -void -maybe_push_to_top_level (int pseudo) -{ - struct saved_scope *s; - struct cp_binding_level *b; - cxx_saved_binding *old_bindings; - int need_pop; - - timevar_push (TV_NAME_LOOKUP); - s = ggc_alloc_cleared (sizeof (struct saved_scope)); - - b = scope_chain ? current_binding_level : 0; - - /* If we're in the middle of some function, save our state. */ - if (cfun) - { - need_pop = 1; - push_function_context_to (NULL_TREE); - } - else - need_pop = 0; - - old_bindings = NULL; - if (scope_chain && previous_class_type) - old_bindings = store_bindings (previous_class_values, old_bindings); - - /* Have to include the global scope, because class-scope decls - aren't listed anywhere useful. */ - for (; b; b = b->level_chain) - { - tree t; - - /* Template IDs are inserted into the global level. If they were - inserted into namespace level, finish_file wouldn't find them - when doing pending instantiations. Therefore, don't stop at - namespace level, but continue until :: . */ - if (global_scope_p (b) || (pseudo && b->kind == sk_template_parms)) - break; - - old_bindings = store_bindings (b->names, old_bindings); - /* We also need to check class_shadowed to save class-level type - bindings, since pushclass doesn't fill in b->names. */ - if (b->kind == sk_class) - old_bindings = store_bindings (b->class_shadowed, old_bindings); - - /* Unwind type-value slots back to top level. */ - for (t = b->type_shadowed; t; t = TREE_CHAIN (t)) - SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t)); - } - s->prev = scope_chain; - s->old_bindings = old_bindings; - s->bindings = b; - s->need_pop_function_context = need_pop; - s->function_decl = current_function_decl; - s->last_parms = last_function_parms; - - scope_chain = s; - current_function_decl = NULL_TREE; - 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 -push_to_top_level (void) -{ - maybe_push_to_top_level (0); -} - -void -pop_from_top_level (void) -{ - struct saved_scope *s = scope_chain; - cxx_saved_binding *saved; - - timevar_push (TV_NAME_LOOKUP); - /* Clear out class-level bindings cache. */ - if (previous_class_type) - invalidate_class_lookup_cache (); - - current_lang_base = 0; - - scope_chain = s->prev; - for (saved = s->old_bindings; saved; saved = saved->previous) - { - tree id = saved->identifier; - - 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 - state. */ - if (s->need_pop_function_context) - 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 named ID. into - binding_level B. DECL is a TYPE_DECL for the type. We assume that - the tag ID is not already defined. */ - -static void -set_identifier_type_value_with_scope (tree id, - tree decl, - struct cp_binding_level* b) -{ - tree type; - - if (b->kind != sk_namespace) - { - /* Shadow the marker, not the real thing, so that the marker - gets restored later. */ - tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id); - b->type_shadowed - = tree_cons (id, old_type_value, b->type_shadowed); - type = decl ? TREE_TYPE (decl) : NULL_TREE; - } - else - { - cxx_binding *binding = - binding_for_name (NAMESPACE_LEVEL (current_namespace), id); - if (decl) - { - if (binding->value) - supplement_binding (binding, decl); - else - binding->value = decl; - } - else - abort (); - /* Store marker instead of real type. */ - type = global_type_node; - } - SET_IDENTIFIER_TYPE_VALUE (id, type); -} - -/* As set_identifier_type_value_with_scope, but using current_binding_level. */ - -void -set_identifier_type_value (tree id, tree decl) -{ - set_identifier_type_value_with_scope (id, decl, current_binding_level); -} - -/* Return the type associated with id. */ - -tree -identifier_type_value (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); - /* 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)); - /* 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, LOOKUP_COMPLAIN); - if (id) - 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. - - We don't pop past namespaces, as they might be valid. */ - -void -pop_everything (void) -{ - if (ENABLE_SCOPE_CHECKING) - verbatim ("XXX entering pop_everything ()\n"); - while (!toplevel_bindings_p ()) - { - if (current_binding_level->kind == sk_class) - pop_nested_class (); - else - poplevel (0, 0, 0); - } - if (ENABLE_SCOPE_CHECKING) - verbatim ("XXX leaving pop_everything ()\n"); -} - -/* The type TYPE is being declared. If it is a class template, or a - specialization of a class template, do any processing required and - perform error-checking. If IS_FRIEND is nonzero, this TYPE is - being declared a friend. B is the binding level at which this TYPE - should be bound. - - Returns the TYPE_DECL for TYPE, which may have been altered by this - processing. */ - -static tree -maybe_process_template_type_declaration (tree type, - int globalize, - struct cp_binding_level* b) -{ - tree decl = TYPE_NAME (type); - - if (processing_template_parmlist) - /* You can't declare a new template type in a template parameter - list. But, you can declare a non-template type: - - template <class A*> struct S; - - is a forward-declaration of `A'. */ - ; - else - { - maybe_check_template_type (type); - - my_friendly_assert (IS_AGGR_TYPE (type) - || TREE_CODE (type) == ENUMERAL_TYPE, 0); - - - if (processing_template_decl) - { - /* This may change after the call to - push_template_decl_real, but we want the original value. */ - tree name = DECL_NAME (decl); - - decl = push_template_decl_real (decl, globalize); - /* If the current binding level is the binding level for the - template parameters (see the comment in - begin_template_parm_list) and the enclosing level is a class - scope, and we're not looking at a friend, push the - declaration of the member class into the class scope. In the - friend case, push_template_decl will already have put the - friend into global scope, if appropriate. */ - if (TREE_CODE (type) != ENUMERAL_TYPE - && !globalize && b->kind == sk_template_parms - && b->level_chain->kind == sk_class) - { - finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type)); - /* Put this UDT in the table of UDTs for the class, since - that won't happen below because B is not the class - binding level, but is instead the pseudo-global level. */ - if (b->level_chain->type_decls == NULL) - b->level_chain->type_decls = - binding_table_new (SCOPE_DEFAULT_HT_SIZE); - binding_table_insert (b->level_chain->type_decls, name, type); - if (!COMPLETE_TYPE_P (current_class_type)) - { - maybe_add_class_template_decl_list (current_class_type, - type, /*friend_p=*/0); - CLASSTYPE_NESTED_UTDS (current_class_type) = - b->level_chain->type_decls; - } - } - } - } - - return decl; -} - /* In C++, you don't have to write `struct S' to refer to `S'; you can just use `S'. We accomplish this by creating a TYPE_DECL as if the user had written `typedef struct S S'. Create and return @@ -2237,130 +988,6 @@ push_local_name (tree decl) timevar_pop (TV_NAME_LOOKUP); } -/* Push a tag name NAME for struct/class/union/enum type TYPE. - Normally put it into the inner-most non-sk_cleanup scope, - but if GLOBALIZE is true, put it in the inner-most non-class scope. - The latter is needed for implicit declarations. */ - -void -pushtag (tree name, tree type, int globalize) -{ - register struct cp_binding_level *b; - - timevar_push (TV_NAME_LOOKUP); - b = current_binding_level; - while (b->kind == sk_cleanup - || (b->kind == sk_class - && (globalize - /* We may be defining a new type in the initializer - of a static member variable. We allow this when - not pedantic, and it is particularly useful for - type punning via an anonymous union. */ - || COMPLETE_TYPE_P (b->this_entity)))) - b = b->level_chain; - - if (b->type_decls == NULL) - b->type_decls = binding_table_new (SCOPE_DEFAULT_HT_SIZE); - binding_table_insert (b->type_decls, name, type); - - if (name) - { - /* Do C++ gratuitous typedefing. */ - if (IDENTIFIER_TYPE_VALUE (name) != type) - { - register tree d = NULL_TREE; - int in_class = 0; - tree context = TYPE_CONTEXT (type); - - if (! context) - { - tree cs = current_scope (); - - if (! globalize) - context = cs; - else if (cs != NULL_TREE && TYPE_P (cs)) - /* When declaring a friend class of a local class, we want - to inject the newly named class into the scope - containing the local class, not the namespace scope. */ - context = decl_function_context (get_type_decl (cs)); - } - if (!context) - context = current_namespace; - - if (b->kind == sk_class - || (b->kind == sk_template_parms - && b->level_chain->kind == sk_class)) - in_class = 1; - - if (current_lang_name == lang_name_java) - TYPE_FOR_JAVA (type) = 1; - - d = create_implicit_typedef (name, type); - DECL_CONTEXT (d) = FROB_CONTEXT (context); - if (! in_class) - set_identifier_type_value_with_scope (name, d, b); - - d = maybe_process_template_type_declaration (type, - globalize, b); - - if (b->kind == sk_class) - { - if (!PROCESSING_REAL_TEMPLATE_DECL_P ()) - /* Put this TYPE_DECL on the TYPE_FIELDS list for the - class. But if it's a member template class, we - want the TEMPLATE_DECL, not the TYPE_DECL, so this - is done later. */ - finish_member_declaration (d); - else - pushdecl_class_level (d); - } - else - d = pushdecl_with_scope (d, b); - - /* FIXME what if it gets a name from typedef? */ - if (ANON_AGGRNAME_P (name)) - DECL_IGNORED_P (d) = 1; - - TYPE_CONTEXT (type) = DECL_CONTEXT (d); - - /* If this is a local class, keep track of it. We need this - information for name-mangling, and so that it is possible to find - all function definitions in a translation unit in a convenient - way. (It's otherwise tricky to find a member function definition - it's only pointed to from within a local class.) */ - if (TYPE_CONTEXT (type) - && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL - && !processing_template_decl) - VARRAY_PUSH_TREE (local_classes, type); - } - if (b->kind == sk_class - && !COMPLETE_TYPE_P (current_class_type)) - { - maybe_add_class_template_decl_list (current_class_type, - type, /*friend_p=*/0); - CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls; - } - } - - if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) - /* Use the canonical TYPE_DECL for this node. */ - TYPE_STUB_DECL (type) = TYPE_NAME (type); - else - { - /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE - will be the tagged type we just added to the current - binding level. This fake NULL-named TYPE_DECL node helps - dwarfout.c to know when it needs to output a - representation of a tagged type, and it also gives us a - convenient place to record the "scope start" address for - the tagged type. */ - - tree d = build_decl (TYPE_DECL, NULL_TREE, type); - TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b); - } - timevar_pop (TV_NAME_LOOKUP); -} - /* Counter used to create anonymous type names. */ static GTY(()) int anon_cnt; @@ -3776,81 +2403,6 @@ pushdecl (tree x) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); } -/* Same as pushdecl, but define X in binding-level LEVEL. We rely on the - caller to set DECL_CONTEXT properly. */ - -static tree -pushdecl_with_scope (tree x, struct cp_binding_level* 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->kind == sk_class) - { - b = class_binding_level; - class_binding_level = level; - pushdecl_class_level (x); - class_binding_level = b; - } - else - { - b = current_binding_level; - current_binding_level = level; - x = pushdecl (x); - current_binding_level = b; - } - current_function_decl = function_decl; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); -} - -/* Like pushdecl, only it places X in the current namespace, - if appropriate. */ - -tree -pushdecl_namespace_level (tree 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 - what we want. */ - if (TREE_CODE (x) == TYPE_DECL) - { - tree name = DECL_NAME (x); - tree newval; - tree *ptr = (tree *)0; - for (; !global_scope_p (b); b = b->level_chain) - { - tree shadowed = b->type_shadowed; - for (; shadowed; shadowed = TREE_CHAIN (shadowed)) - if (TREE_PURPOSE (shadowed) == name) - { - ptr = &TREE_VALUE (shadowed); - /* Can't break out of the loop here because sometimes - a binding level will have duplicate bindings for - PT names. It's gross, but I haven't time to fix it. */ - } - } - newval = TREE_TYPE (x); - if (ptr == (tree *)0) - { - /* @@ This shouldn't be needed. My test case "zstring.cc" trips - up here if this is changed to an assertion. --KR */ - SET_IDENTIFIER_TYPE_VALUE (name, x); - } - else - { - *ptr = newval; - } - } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); -} - /* Like pushdecl, only it places X in the global scope if appropriate. Calls cp_finish_decl to register the variable, initializing it with *INIT, if INIT is non-NULL. */ @@ -3885,48 +2437,6 @@ pushdecl_top_level_and_finish (tree x, tree init) return pushdecl_top_level_1 (x, &init); } -/* Make the declaration of X appear in CLASS scope. */ - -bool -pushdecl_class_level (tree x) -{ - tree name; - bool is_valid = true; - - timevar_push (TV_NAME_LOOKUP); - /* Get the name of X. */ - if (TREE_CODE (x) == OVERLOAD) - name = DECL_NAME (get_first_fn (x)); - else - name = DECL_NAME (x); - - if (name) - { - is_valid = push_class_level_binding (name, x); - if (TREE_CODE (x) == TYPE_DECL) - set_identifier_type_value (name, x); - } - else if (ANON_AGGR_TYPE_P (TREE_TYPE (x))) - { - /* If X is an anonymous aggregate, all of its members are - treated as if they were members of the class containing the - aggregate, for naming purposes. */ - tree f; - - for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f)) - { - location_t save_location = input_location; - input_location = DECL_SOURCE_LOCATION (f); - if (!pushdecl_class_level (f)) - is_valid = false; - input_location = save_location; - } - } - timevar_pop (TV_NAME_LOOKUP); - - return is_valid; -} - /* Enter DECL into the symbol table, if that's appropriate. Returns DECL, or a modified version thereof. */ @@ -3956,97 +2466,6 @@ maybe_push_decl (tree decl) return pushdecl (decl); } -/* 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) -{ - 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) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); - - /* Make sure that this new member does not have the same name - as a template parameter. */ - if (TYPE_BEING_DEFINED (current_class_type)) - check_template_shadow (x); - - /* If this declaration shadows a declaration from an enclosing - class, then we will need to restore IDENTIFIER_CLASS_VALUE when - we leave this class. Record the shadowed declaration here. */ - binding = IDENTIFIER_BINDING (name); - if (binding && binding->value) - { - tree bval = binding->value; - tree old_decl = NULL_TREE; - - if (INHERITED_VALUE_BINDING_P (binding)) - { - /* If the old binding was from a base class, and was for a - tag name, slide it over to make room for the new binding. - The old binding is still visible if explicitly qualified - with a class-key. */ - if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval) - && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))) - { - old_decl = binding->type; - binding->type = bval; - binding->value = NULL_TREE; - INHERITED_VALUE_BINDING_P (binding) = 0; - } - else - old_decl = bval; - } - 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); - 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); - - if (old_decl) - { - tree shadow; - - /* Find the previous binding of name on the class-shadowed - list, and update it. */ - for (shadow = class_binding_level->class_shadowed; - shadow; - shadow = TREE_CHAIN (shadow)) - if (TREE_PURPOSE (shadow) == name - && TREE_TYPE (shadow) == old_decl) - { - binding->value = x; - INHERITED_VALUE_BINDING_P (binding) = 0; - TREE_TYPE (shadow) = x; - IDENTIFIER_CLASS_VALUE (name) = x; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); - } - } - } - - /* If we didn't replace an existing binding, put the binding on the - stack of bindings for the identifier, and update the shadowed list. */ - if (push_class_binding (name, x)) - { - class_binding_level->class_shadowed - = tree_cons (name, NULL, - class_binding_level->class_shadowed); - /* Record the value we are binding NAME to so that we can know - what to pop later. */ - TREE_TYPE (class_binding_level->class_shadowed) = x; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); - } - - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false); -} - /* Insert another USING_DECL into the current binding level, returning this declaration. If this is a redeclaration, do nothing, and return NULL_TREE if this not in namespace scope (in namespace @@ -4073,33 +2492,6 @@ push_using_decl (tree scope, tree name) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); } -/* 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. */ - -tree -push_using_directive (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); - - 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; - - /* 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 other definitions already in place. We get around this by making the value of the identifier point to a list of all the things that @@ -4781,298 +3173,6 @@ finish_case_label (tree low_value, tree high_value) return r; } -/* Return the list of declarations of the current level. - Note that this list is in reverse order unless/until - you nreverse it; and when you do nreverse it, you must - store the result back using `storedecls' or you will lose. */ - -tree -getdecls (void) -{ - return current_binding_level->names; -} - -/* Store the list of declarations of the current level. - This is done for the parameter declarations of a function being defined, - after they are modified in the light of any missing parameters. */ - -static void -storedecls (tree decls) -{ - current_binding_level->names = decls; -} - -/* Set the current binding TABLE for type declarations.. This is a - temporary workaround of the fact that the data structure classtypes - does not currently carry its allocated cxx_scope structure. */ -void -cxx_remember_type_decls (binding_table table) -{ - current_binding_level->type_decls = table; -} - -/* Return the type that should be used when TYPE's name is preceded - by a tag such as 'struct' or 'union', or null if the name cannot - be used in this way. - - For example, when processing the third line of: - - struct A; - typedef struct A A; - struct A; - - lookup of A will find the typedef. Given A's typedef, this function - will return the type associated with "struct A". For the tag to be - anything other than TYPE, TYPE must be a typedef whose original type - has the same name and context as TYPE itself. - - It is not valid for a typedef of an anonymous type to be used with - an explicit tag: - - typedef struct { ... } B; - struct B; - - Return null for this case. */ - -static tree -follow_tag_typedef (tree type) -{ - tree original; - - original = original_type (type); - if (! TYPE_NAME (original)) - return NULL_TREE; - if (TYPE_IDENTIFIER (original) == TYPE_IDENTIFIER (type) - && (CP_DECL_CONTEXT (TYPE_NAME (original)) - == CP_DECL_CONTEXT (TYPE_NAME (type))) - && !(CLASS_TYPE_P (original) && TYPE_WAS_ANONYMOUS (original))) - return original; - else - return NULL_TREE; -} - -/* Given NAME, an IDENTIFIER_NODE, - return the structure (or union or enum) definition for that name. - Searches binding levels from its SCOPE up to the global level. - If THISLEVEL_ONLY is nonzero, searches only the specified context - (but skips any sk_cleanup contexts to find one that is - meaningful for tags). - FORM says which kind of type the caller wants; - it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE. - If the wrong kind of type is found, and it's not a template, an error is - reported. */ - -static tree -lookup_tag (enum tree_code form, tree name, - struct cp_binding_level* binding_level, int thislevel_only) -{ - register struct cp_binding_level *level; - /* Nonzero if, we should look past a template parameter level, even - if THISLEVEL_ONLY. */ - int allow_template_parms_p = 1; - bool type_is_anonymous = ANON_AGGRNAME_P (name); - - timevar_push (TV_NAME_LOOKUP); - for (level = binding_level; level; level = level->level_chain) - { - register tree tail; - if (type_is_anonymous && level->type_decls != NULL) - { - tree type = binding_table_find_anon_type (level->type_decls, name); - /* There is no need for error checking here, because - anon names are unique throughout the compilation. */ - if (type != NULL) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type); - } - else if (level->kind == sk_namespace) - /* Do namespace lookup. */ - for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail)) - { - cxx_binding *binding = - cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (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 - && binding && binding->value - && DECL_CLASS_TEMPLATE_P (binding->value)) - old = binding->value; - else if (binding) - old = select_decl (binding, LOOKUP_PREFER_TYPES); - else - old = NULL_TREE; - - if (old) - { - /* We've found something at this binding level. If it is - a typedef, extract the tag it refers to. Lookup fails - if the typedef doesn't refer to a taggable type. */ - old = TREE_TYPE (old); - old = follow_tag_typedef (old); - if (!old) - 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); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); - } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old); - } - if (thislevel_only || tail == global_namespace) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); - } - else if (level->type_decls != NULL) - { - binding_entry entry = binding_table_find (level->type_decls, name); - if (entry != NULL) - { - enum tree_code code = TREE_CODE (entry->type); - - if (code != form - && (form == ENUMERAL_TYPE || code == ENUMERAL_TYPE)) - { - /* Definition isn't the kind we were looking for. */ - error ("`%#D' redeclared as %C", entry->type, form); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); - } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->type); - } - } - if (thislevel_only && level->kind != sk_cleanup) - { - if (level->kind == sk_template_parms && allow_template_parms_p) - { - /* We must deal with cases like this: - - template <class T> struct S; - template <class T> struct S {}; - - When looking up `S', for the second declaration, we - would like to find the first declaration. But, we - are in the pseudo-global level created for the - template parameters, rather than the (surrounding) - namespace level. Thus, we keep going one more level, - even though THISLEVEL_ONLY is nonzero. */ - allow_template_parms_p = 0; - continue; - } - else - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); - } - } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); -} - -/* Given a type, find the tag that was defined for it and return the tag name. - Otherwise return 0. However, the value can never be 0 - in the cases in which this is used. - - C++: If NAME is nonzero, this is the new name to install. This is - done when replacing anonymous tags with real tag names. */ - -static tree -lookup_tag_reverse (tree type, tree name) -{ - register struct cp_binding_level *level; - - timevar_push (TV_NAME_LOOKUP); - for (level = current_binding_level; level; level = level->level_chain) - { - binding_entry entry = level->type_decls == NULL - ? NULL - : binding_table_reverse_maybe_remap (level->type_decls, type, name); - if (entry) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->name); - } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); -} - -/* Look up NAME in the NAMESPACE. */ - -tree -lookup_namespace_name (tree namespace, tree 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. */ - 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); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); - } - - namespace = ORIGINAL_NAMESPACE (namespace); - - if (TREE_CODE (name) == TEMPLATE_ID_EXPR) - { - template_id = name; - name = TREE_OPERAND (name, 0); - if (TREE_CODE (name) == OVERLOAD) - name = DECL_NAME (OVL_CURRENT (name)); - else if (DECL_P (name)) - name = DECL_NAME (name); - } - - my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373); - - 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 = binding.value; - - if (template_id) - { - if (DECL_CLASS_TEMPLATE_P (val)) - val = lookup_template_class (val, - TREE_OPERAND (template_id, 1), - /*in_decl=*/NULL_TREE, - /*context=*/NULL_TREE, - /*entering_scope=*/0, - tf_error | tf_warning); - else if (DECL_FUNCTION_TEMPLATE_P (val) - || TREE_CODE (val) == OVERLOAD) - val = lookup_template_function (val, - TREE_OPERAND (template_id, 1)); - else - { - error ("`%D::%D' is not a template", - namespace, name); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); - } - } - - /* If we have a single function from a using decl, pull it out. */ - if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val)) - val = OVL_FUNCTION (val); - - /* Ignore built-in functions that haven't been prototyped yet. */ - if (!val || !DECL_P(val) - || !DECL_LANG_SPECIFIC(val) - || !DECL_ANTICIPATED (val)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); - } - - error ("`%D' undeclared in namespace `%D'", name, namespace); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); -} - /* Hash a TYPENAME_TYPE. K is really of type `tree'. */ static hashval_t @@ -5336,172 +3436,6 @@ make_unbound_class_template (tree context, tree name, tsubst_flags_t complain) return t; } -/* Select the right _DECL from multiple choices. */ - -static tree -select_decl (cxx_binding *binding, int flags) -{ - tree val; - val = binding->value; - - timevar_push (TV_NAME_LOOKUP); - if (LOOKUP_NAMESPACES_ONLY (flags)) - { - /* We are not interested in types. */ - if (val && TREE_CODE (val) == NAMESPACE_DECL) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); - } - - /* If looking for a type, or if there is no non-type binding, select - the value binding. */ - if (binding->type && (!val || (flags & LOOKUP_PREFER_TYPES))) - val = binding->type; - /* Don't return non-types if we really prefer types. */ - else if (val && LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL - && (TREE_CODE (val) != TEMPLATE_DECL - || !DECL_CLASS_TEMPLATE_P (val))) - val = NULL_TREE; - - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); -} - -/* Unscoped lookup of a global: iterate over current namespaces, - considering using-directives. If SPACESP is non-NULL, store a list - of the namespaces we've considered in it. */ - -tree -unqualified_namespace_lookup (tree name, int flags, tree* spacesp) -{ - 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 = - cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name); - if (spacesp) - *spacesp = tree_cons (scope, NULL_TREE, *spacesp); - - /* Ignore anticipated built-in functions. */ - if (b && b->value && DECL_P (b->value) - && DECL_LANG_SPECIFIC (b->value) && DECL_ANTICIPATED (b->value)) - /* Keep binding cleared. */; - else if (b) - { - /* Initialize binding for this context. */ - binding.value = b->value; - binding.type = b->type; - } - - /* Add all _DECLs seen through local using-directives. */ - for (level = current_binding_level; - level->kind != sk_namespace; - level = level->level_chain) - if (!lookup_using_namespace (name, &binding, level->using_directives, - scope, flags, spacesp)) - /* Give up because of error. */ - 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, &binding, - DECL_NAMESPACE_USING (siter), - scope, flags, spacesp)) - /* Give up because of error. */ - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); - if (siter == scope) break; - siter = CP_DECL_CONTEXT (siter); - } - - val = select_decl (&binding, flags); - if (scope == global_namespace) - break; - } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); -} - -/* Combine prefer_type and namespaces_only into flags. */ - -static int -lookup_flags (int prefer_type, int namespaces_only) -{ - if (namespaces_only) - return LOOKUP_PREFER_NAMESPACES; - if (prefer_type > 1) - return LOOKUP_PREFER_TYPES; - if (prefer_type > 0) - return LOOKUP_PREFER_BOTH; - return 0; -} - -/* Given a lookup that returned VAL, use FLAGS to decide if we want to - ignore it or not. Subroutine of lookup_name_real. */ - -static tree -qualify_lookup (tree val, int flags) -{ - if (val == NULL_TREE) - return val; - if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL) - return val; - if ((flags & LOOKUP_PREFER_TYPES) - && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL)) - return val; - if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES)) - return NULL_TREE; - return val; -} - -/* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL - or a class TYPE). If IS_TYPE_P is TRUE, then ignore non-type - bindings. - - Returns a DECL (or OVERLOAD, or BASELINK) representing the - declaration found. If no suitable declaration can be found, - ERROR_MARK_NODE is returned. Iif COMPLAIN is true and SCOPE is - neither a class-type nor a namespace a diagnostic is issued. */ - -tree -lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain) -{ - int flags = 0; - - if (TREE_CODE (scope) == NAMESPACE_DECL) - { - cxx_binding binding; - - cxx_binding_clear (&binding); - flags |= LOOKUP_COMPLAIN; - if (is_type_p) - flags |= LOOKUP_PREFER_TYPES; - if (qualified_lookup_using_namespace (name, scope, &binding, - flags)) - return select_decl (&binding, flags); - } - else if (is_aggr_type (scope, complain)) - { - tree t; - t = lookup_member (scope, name, 0, is_type_p); - if (t) - return t; - } - - return error_mark_node; -} - /* Check to see whether or not DECL is a variable that would have been in scope under the ARM, but is not in scope under the ANSI/ISO standard. If so, issue an error message. If name lookup would @@ -5561,191 +3495,6 @@ check_for_out_of_scope_variable (tree decl) return decl; } -/* Look up NAME in the current binding level and its superiors in the - namespace of variables, functions and typedefs. Return a ..._DECL - node of some kind representing its definition if there is only one - such declaration, or return a TREE_LIST with all the overloaded - definitions if there are many, or return 0 if it is undefined. - - If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces. - If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces). - Otherwise we prefer non-TYPE_DECLs. - - If NONCLASS is nonzero, we don't look for the NAME in class scope, - using IDENTIFIER_CLASS_VALUE. */ - -tree -lookup_name_real (tree name, int prefer_type, int nonclass, - 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. */ - if (IDENTIFIER_TYPENAME_P (name)) - { - struct cp_binding_level *level; - - for (level = current_binding_level; - level && level->kind != sk_namespace; - level = level->level_chain) - { - tree class_type; - tree operators; - - /* A conversion operator can only be declared in a class - scope. */ - if (level->kind != sk_class) - continue; - - /* Lookup the conversion operator in the class. */ - class_type = level->this_entity; - operators = lookup_fnfields (class_type, name, /*protect=*/0); - if (operators) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators); - } - - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); - } - - flags |= lookup_flags (prefer_type, namespaces_only); - - /* First, look in non-namespace scopes. */ - - if (current_class_type == NULL_TREE) - nonclass = 1; - - for (iter = IDENTIFIER_BINDING (name); iter; iter = iter->previous) - { - tree binding; - - 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 (iter->value, flags)) - binding = iter->value; - else if ((flags & LOOKUP_PREFER_TYPES) - && qualify_lookup (iter->type, flags)) - binding = iter->type; - else - binding = NULL_TREE; - - if (binding) - { - val = binding; - break; - } - } - - /* Now lookup in namespace scopes. */ - if (!val) - { - tree t = unqualified_namespace_lookup (name, flags, 0); - if (t) - val = t; - } - - if (val) - { - /* If we have a single function from a using decl, pull it out. */ - if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val)) - val = OVL_FUNCTION (val); - } - - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); -} - -tree -lookup_name_nonclass (tree name) -{ - return lookup_name_real (name, 0, 1, 0, LOOKUP_COMPLAIN); -} - -tree -lookup_function_nonclass (tree name, tree args) -{ - return lookup_arg_dependent (name, lookup_name_nonclass (name), args); -} - -tree -lookup_name (tree name, int prefer_type) -{ - return lookup_name_real (name, prefer_type, 0, 0, LOOKUP_COMPLAIN); -} - -/* Similar to `lookup_name' but look only in the innermost non-class - binding level. */ - -tree -lookup_name_current_level (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) - { - t = IDENTIFIER_NAMESPACE_VALUE (name); - - /* extern "C" function() */ - if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST) - t = TREE_VALUE (t); - } - else if (IDENTIFIER_BINDING (name) - && LOCAL_BINDING_P (IDENTIFIER_BINDING (name))) - { - while (1) - { - if (IDENTIFIER_BINDING (name)->scope == b) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name)); - - if (b->kind == sk_cleanup) - b = b->level_chain; - else - break; - } - } - - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); -} - -/* Like lookup_name_current_level, but for types. */ - -tree -lookup_type_current_level (tree name) -{ - register tree t = NULL_TREE; - - timevar_push (TV_NAME_LOOKUP); - my_friendly_assert (current_binding_level->kind != sk_namespace, - 980716); - - if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE - && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node) - { - struct cp_binding_level *b = current_binding_level; - while (1) - { - if (purpose_member (name, b->type_shadowed)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, - REAL_IDENTIFIER_TYPE_VALUE (name)); - if (b->kind == sk_cleanup) - b = b->level_chain; - else - break; - } - } - - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); -} - /* A chain of TYPE_DECLs for the builtin types. */ @@ -13457,7 +11206,7 @@ store_parm_decls (tree current_function_parms) /* Must clear this because it might contain TYPE_DECLs declared at class level. */ - storedecls (NULL_TREE); + current_binding_level->names = NULL; /* If we're doing semantic analysis, then we'll call pushdecl for each of these. We must do them in reverse order so that @@ -13496,7 +11245,7 @@ store_parm_decls (tree current_function_parms) as the decl-chain of the current lexical scope. Put the enumerators in as well, at the front so that DECL_ARGUMENTS is not modified. */ - storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl))); + current_binding_level->names = chainon (nonparms, DECL_ARGUMENTS (fndecl)); /* Do the starting of the exception specifications, if we have any. */ if (flag_exceptions && !processing_template_decl @@ -14250,15 +11999,6 @@ cp_tree_node_structure (union lang_tree_node * t) } } -/* 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++. */ - -tree -identifier_global_value (tree t) -{ - return IDENTIFIER_GLOBAL_VALUE (t); -} - /* Build the void_list_node (void_type_node having been created). */ tree build_void_list_node (void) diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 3e9d2ca..4f59998 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -28,6 +28,11 @@ Boston, MA 02111-1307, USA. */ #include "name-lookup.h" #include "timevar.h" #include "toplev.h" +#include "diagnostic.h" + +static cxx_scope *innermost_nonclass_level (void); +static tree select_decl (cxx_binding *, int); + /* Compute the chain index of a binding_entry given the HASH value of its name and the total COUNT of chains. COUNT is assumed to be a power @@ -100,7 +105,7 @@ binding_table_construct (binding_table table, size_t chain_count) /* Make TABLE's entries ready for reuse. */ -void +static void binding_table_free (binding_table table) { size_t i; @@ -125,7 +130,7 @@ binding_table_free (binding_table table) /* Allocate a table with CHAIN_COUNT, assumed to be a power of two. */ -binding_table +static inline binding_table binding_table_new (size_t chain_count) { binding_table table = ggc_alloc (sizeof (struct binding_table_s)); @@ -164,7 +169,7 @@ binding_table_expand (binding_table table) /* Insert a binding for NAME to TYPE into TABLE. */ -void +static void binding_table_insert (binding_table table, tree name, tree type) { const unsigned int hash = IDENTIFIER_HASH_VALUE (name); @@ -195,7 +200,7 @@ binding_table_find (binding_table table, tree name) /* Return the binding_entry, if any, that maps NAME to an anonymous type. */ -tree +static tree binding_table_find_anon_type (binding_table table, tree name) { const unsigned int hash = IDENTIFIER_HASH_VALUE (name); @@ -210,7 +215,7 @@ binding_table_find_anon_type (binding_table table, tree name) /* Return the binding_entry, if any, that has TYPE as target. If NAME is non-null, then set the domain and rehash that entry. */ -binding_entry +static binding_entry binding_table_reverse_maybe_remap (binding_table table, tree type, tree name) { const size_t chain_count = table->chain_count; @@ -285,6 +290,11 @@ binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data) } } +#ifndef ENABLE_SCOPE_CHECKING +# define ENABLE_SCOPE_CHECKING 0 +#else +# define ENABLE_SCOPE_CHECKING 1 +#endif /* A free list of "cxx_binding"s, connected by their PREVIOUS. */ @@ -292,7 +302,7 @@ static GTY((deletable (""))) cxx_binding *free_bindings; /* (GC)-allocate a binding object with VALUE and TYPE member initialized. */ -cxx_binding * +static cxx_binding * cxx_binding_make (tree value, tree type) { cxx_binding *binding; @@ -313,7 +323,7 @@ cxx_binding_make (tree value, tree type) /* Put BINDING back on the free list. */ -void +static inline void cxx_binding_free (cxx_binding *binding) { binding->scope = NULL; @@ -321,6 +331,64 @@ cxx_binding_free (cxx_binding *binding) free_bindings = binding; } +/* Make DECL the innermost binding for ID. The LEVEL is the binding + level at which this declaration is being bound. */ + +static void +push_binding (tree id, tree decl, cxx_scope* level) +{ + cxx_binding *binding = cxx_binding_make (decl, NULL); + + /* Now, fill in the binding information. */ + binding->previous = IDENTIFIER_BINDING (id); + binding->scope = level; + INHERITED_VALUE_BINDING_P (binding) = 0; + LOCAL_BINDING_P (binding) = (level != class_binding_level); + + /* And put it on the front of the list of bindings for ID. */ + IDENTIFIER_BINDING (id) = binding; +} + +/* Remove the binding for DECL which should be the innermost binding + for ID. */ + +void +pop_binding (tree id, tree decl) +{ + cxx_binding *binding; + + if (id == NULL_TREE) + /* It's easiest to write the loops that call this function without + checking whether or not the entities involved have names. We + get here for such an entity. */ + return; + + /* Get the innermost binding for ID. */ + binding = IDENTIFIER_BINDING (id); + + /* The name should be bound. */ + my_friendly_assert (binding != NULL, 0); + + /* The DECL will be either the ordinary binding or the type + binding for this identifier. Remove that binding. */ + if (binding->value == decl) + binding->value = NULL_TREE; + else if (binding->type == decl) + binding->type = NULL_TREE; + else + abort (); + + if (!binding->value && !binding->type) + { + /* We're completely done with the innermost binding for this + identifier. Unhook it from the list of bindings. */ + IDENTIFIER_BINDING (id) = binding->previous; + + /* Add it to the free list. */ + cxx_binding_free (binding); + } +} + /* BINDING records an existing declaration for a namein the current scope. But, DECL is another declaration for that same identifier in the same scope. This is the `struct stat' hack whereby a non-typedef @@ -339,7 +407,7 @@ cxx_binding_free (cxx_binding *binding) inserting this name is valid here. Returns nonzero if the new binding was successful. */ -bool +static bool supplement_binding (cxx_binding *binding, tree decl) { tree bval = binding->value; @@ -407,7 +475,649 @@ supplement_binding (cxx_binding *binding, tree decl) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok); } + +/* Add DECL to the list of things declared in B. */ + +void +add_decl_to_level (tree decl, cxx_scope *b) +{ + if (TREE_CODE (decl) == NAMESPACE_DECL + && !DECL_NAMESPACE_ALIAS (decl)) + { + TREE_CHAIN (decl) = b->namespaces; + b->namespaces = decl; + } + else if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl)) + { + TREE_CHAIN (decl) = b->vtables; + b->vtables = decl; + } + else + { + /* We build up the list in reverse order, and reverse it later if + necessary. */ + TREE_CHAIN (decl) = b->names; + b->names = decl; + b->names_size++; + + /* If appropriate, add decl to separate list of statics */ + if (b->kind == sk_namespace) + 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); + } +} + +/* Bind DECL to ID in the current_binding_level, assumed to be a local + binding level. If PUSH_USING is set in FLAGS, we know that DECL + doesn't really belong to this binding level, that it got here + through a using-declaration. */ + +void +push_local_binding (tree id, tree decl, int flags) +{ + struct cp_binding_level *b; + + /* Skip over any local classes. This makes sense if we call + push_local_binding with a friend decl of a local class. */ + b = innermost_nonclass_level (); + + if (lookup_name_current_level (id)) + { + /* Supplement the existing binding. */ + if (!supplement_binding (IDENTIFIER_BINDING (id), decl)) + /* It didn't work. Something else must be bound at this + level. Do not add DECL to the list of things to pop + later. */ + return; + } + else + /* Create a new binding. */ + push_binding (id, decl, b); + + if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING)) + /* We must put the OVERLOAD into a TREE_LIST since the + TREE_CHAIN of an OVERLOAD is already used. Similarly for + decls that got here through a using-declaration. */ + decl = build_tree_list (NULL_TREE, decl); + + /* And put DECL on the list of things declared by the current + binding level. */ + add_decl_to_level (decl, b); +} + +/* true means unconditionally make a BLOCK for the next level pushed. */ + +static bool keep_next_level_flag; + +static int binding_depth = 0; +static int is_class_level = 0; + +static void +indent (int depth) +{ + int i; + + for (i = 0; i < depth * 2; i++) + putc (' ', stderr); +} + +/* Return a string describing the kind of SCOPE we have. */ +static const char * +cxx_scope_descriptor (cxx_scope *scope) +{ + /* The order of this table must match the "scope_kind" + enumerators. */ + static const char* scope_kind_names[] = { + "block-scope", + "cleanup-scope", + "try-scope", + "catch-scope", + "for-scope", + "function-parameter-scope", + "class-scope", + "namespace-scope", + "template-parameter-scope", + "template-explicit-spec-scope" + }; + const scope_kind kind = scope->explicit_spec_p + ? sk_template_spec : scope->kind; + + return scope_kind_names[kind]; +} + +/* Output a debugging information about SCOPE when performning + ACTION at LINE. */ +static void +cxx_scope_debug (cxx_scope *scope, int line, const char *action) +{ + const char *desc = cxx_scope_descriptor (scope); + if (scope->this_entity) + verbatim ("%s %s(%E) %p %d\n", action, desc, + scope->this_entity, (void *) scope, line); + else + verbatim ("%s %s %p %d\n", action, desc, (void *) scope, line); +} + +/* Return the estimated initial size of the hashtable of a NAMESPACE + scope. */ + +static inline size_t +namespace_scope_ht_size (tree ns) +{ + tree name = DECL_NAME (ns); + + return name == std_identifier + ? NAMESPACE_STD_HT_SIZE + : (name == global_scope_name + ? GLOBAL_SCOPE_HT_SIZE + : NAMESPACE_ORDINARY_HT_SIZE); +} + +/* A chain of binding_level structures awaiting reuse. */ + +static GTY((deletable (""))) struct cp_binding_level *free_binding_level; + +/* Create a new KIND scope and make it the top of the active scopes stack. + ENTITY is the scope of the associated C++ entity (namespace, class, + function); it is NULL otherwise. */ + +cxx_scope * +begin_scope (scope_kind kind, tree entity) +{ + cxx_scope *scope; + + /* Reuse or create a struct for this binding level. */ + if (!ENABLE_SCOPE_CHECKING && free_binding_level) + { + scope = free_binding_level; + free_binding_level = scope->level_chain; + } + else + scope = ggc_alloc (sizeof (cxx_scope)); + memset (scope, 0, sizeof (cxx_scope)); + + scope->this_entity = entity; + scope->more_cleanups_ok = true; + switch (kind) + { + case sk_cleanup: + scope->keep = true; + break; + + case sk_template_spec: + scope->explicit_spec_p = true; + kind = sk_template_parms; + /* fall through */ + case sk_template_parms: + case sk_block: + case sk_try: + case sk_catch: + case sk_for: + case sk_class: + case sk_function_parms: + scope->keep = keep_next_level_flag; + break; + + case sk_namespace: + scope->type_decls = binding_table_new (namespace_scope_ht_size (entity)); + NAMESPACE_LEVEL (entity) = scope; + VARRAY_TREE_INIT (scope->static_decls, + DECL_NAME (entity) == std_identifier + || DECL_NAME (entity) == global_scope_name + ? 200 : 10, + "Static declarations"); + break; + + default: + /* Should not happen. */ + my_friendly_assert (false, 20030922); + break; + } + scope->kind = kind; + + /* Add it to the front of currently active scopes stack. */ + scope->level_chain = current_binding_level; + current_binding_level = scope; + keep_next_level_flag = false; + + if (ENABLE_SCOPE_CHECKING) + { + scope->binding_depth = binding_depth; + indent (binding_depth); + cxx_scope_debug (scope, input_location.line, "push"); + is_class_level = 0; + binding_depth++; + } + + return scope; +} + +/* We're about to leave current scope. Pop the top of the stack of + currently active scopes. Return the enclosing scope, now active. */ + +cxx_scope * +leave_scope (void) +{ + cxx_scope *scope = current_binding_level; + + if (scope->kind == sk_namespace && class_binding_level) + current_binding_level = class_binding_level; + + /* We cannot leave a scope, if there are none left. */ + if (NAMESPACE_LEVEL (global_namespace)) + my_friendly_assert (!global_scope_p (scope), 20030527); + + if (ENABLE_SCOPE_CHECKING) + { + indent (--binding_depth); + cxx_scope_debug (scope, input_location.line, "leave"); + if (is_class_level != (scope == class_binding_level)) + { + indent (binding_depth); + verbatim ("XXX is_class_level != (current_scope == class_scope)\n"); + } + is_class_level = 0; + } + + /* Move one nesting level up. */ + current_binding_level = scope->level_chain; + + /* Namespace-scopes are left most probably temporarily, not completely; + they can be reopen later, e.g. in namespace-extension or any name + binding acttivity that requires us to resume a namespace. For other + scopes, we just make the structure available for reuse. */ + if (scope->kind != sk_namespace) + { + scope->level_chain = free_binding_level; + if (scope->kind == sk_class) + scope->type_decls = NULL; + else + binding_table_free (scope->type_decls); + my_friendly_assert (!ENABLE_SCOPE_CHECKING + || scope->binding_depth == binding_depth, + 20030529); + free_binding_level = scope; + } + + /* Find the innermost enclosing class scope, and reset + CLASS_BINDING_LEVEL appropriately. */ + for (scope = current_binding_level; + scope && scope->kind != sk_class; + scope = scope->level_chain) + ; + class_binding_level = scope && scope->kind == sk_class ? scope : NULL; + + return current_binding_level; +} + +static void +resume_scope (struct cp_binding_level* b) +{ + /* Resuming binding levels is meant only for namespaces, + and those cannot nest into classes. */ + my_friendly_assert(!class_binding_level, 386); + /* Also, resuming a non-directly nested namespace is a no-no. */ + my_friendly_assert(b->level_chain == current_binding_level, 386); + current_binding_level = b; + if (ENABLE_SCOPE_CHECKING) + { + b->binding_depth = binding_depth; + indent (binding_depth); + cxx_scope_debug (b, input_location.line, "resume"); + is_class_level = 0; + binding_depth++; + } +} + +/* Return the innermost binding level that is not for a class scope. */ + +static cxx_scope * +innermost_nonclass_level (void) +{ + cxx_scope *b; + + b = current_binding_level; + while (b->kind == sk_class) + b = b->level_chain; + + return b; +} + +/* We're defining an object of type TYPE. If it needs a cleanup, but + we're not allowed to add any more objects with cleanups to the current + scope, create a new binding level. */ + +void +maybe_push_cleanup_level (tree type) +{ + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) + && current_binding_level->more_cleanups_ok == 0) + { + begin_scope (sk_cleanup, NULL); + clear_last_expr (); + add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1); + } +} + +/* Nonzero if we are currently in the global binding level. */ + +int +global_bindings_p (void) +{ + return global_scope_p (current_binding_level); +} + +/* True if we are currently in a toplevel binding level. This + means either the global binding level or a namespace in a toplevel + binding level. Since there are no non-toplevel namespace levels, + this really means any namespace or template parameter level. We + also include a class whose context is toplevel. */ + +bool +toplevel_bindings_p (void) +{ + struct cp_binding_level *b = innermost_nonclass_level (); + + return b->kind == sk_namespace || b->kind == sk_template_parms; +} + +/* True if this is a namespace scope, or if we are defining a class + which is itself at namespace scope, or whose enclosing class is + such a class, etc. */ + +bool +namespace_bindings_p (void) +{ + struct cp_binding_level *b = innermost_nonclass_level (); + + return b->kind == sk_namespace; +} + +/* True if the current level needs to have a BLOCK made. */ + +bool +kept_level_p (void) +{ + return (current_binding_level->blocks != NULL_TREE + || current_binding_level->keep + || current_binding_level->kind == sk_cleanup + || current_binding_level->names != NULL_TREE + || current_binding_level->type_decls != NULL); +} + +/* Returns the kind of the innermost scope. */ + +scope_kind +innermost_scope_kind (void) +{ + return current_binding_level->kind; +} + +/* Returns true if this scope was created to store template parameters. */ + +bool +template_parm_scope_p (void) +{ + return innermost_scope_kind () == sk_template_parms; +} + +/* If KEEP is true, make a BLOCK node for the next binding level, + unconditionally. Otherwise, use the normal logic to decide whether + or not to create a BLOCK. */ + +void +keep_next_level (bool keep) +{ + keep_next_level_flag = keep; +} + +/* Return the list of declarations of the current level. + Note that this list is in reverse order unless/until + you nreverse it; and when you do nreverse it, you must + store the result back using `storedecls' or you will lose. */ + +tree +getdecls (void) +{ + return current_binding_level->names; +} + +/* Set the current binding TABLE for type declarations.. This is a + temporary workaround of the fact that the data structure classtypes + does not currently carry its allocated cxx_scope structure. */ +void +cxx_remember_type_decls (binding_table table) +{ + current_binding_level->type_decls = table; +} + +/* For debugging. */ +static int no_print_functions = 0; +static int no_print_builtins = 0; + +/* Called from print_binding_level through binding_table_foreach to + print the content of binding ENTRY. DATA is a pointer to line offset + marker. */ +static void +bt_print_entry (binding_entry entry, void *data) +{ + int *p = (int *) data; + int len; + + if (entry->name == NULL) + len = 3; + else if (entry->name == TYPE_IDENTIFIER (entry->type)) + len = 2; + else + len = 4; + len = 4; + + *p += len; + + if (*p > 5) + { + fprintf (stderr, "\n\t"); + *p = len; + } + if (entry->name == NULL) + { + print_node_brief (stderr, "<unnamed-typedef", entry->type, 0); + fprintf (stderr, ">"); + } + else if (entry->name == TYPE_IDENTIFIER (entry->type)) + print_node_brief (stderr, "", entry->type, 0); + else + { + print_node_brief (stderr, "<typedef", entry->name, 0); + print_node_brief (stderr, "", entry->type, 0); + fprintf (stderr, ">"); + } +} + +void +print_binding_level (struct cp_binding_level* lvl) +{ + tree t; + int i = 0, len; + fprintf (stderr, " blocks=" HOST_PTR_PRINTF, (void *) lvl->blocks); + if (lvl->more_cleanups_ok) + fprintf (stderr, " more-cleanups-ok"); + if (lvl->have_cleanups) + fprintf (stderr, " have-cleanups"); + fprintf (stderr, "\n"); + if (lvl->names) + { + fprintf (stderr, " names:\t"); + /* We can probably fit 3 names to a line? */ + for (t = lvl->names; t; t = TREE_CHAIN (t)) + { + if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL)) + continue; + if (no_print_builtins + && (TREE_CODE (t) == TYPE_DECL) + && (!strcmp (DECL_SOURCE_FILE (t),"<built-in>"))) + continue; + + /* Function decls tend to have longer names. */ + if (TREE_CODE (t) == FUNCTION_DECL) + len = 3; + else + len = 2; + i += len; + if (i > 6) + { + fprintf (stderr, "\n\t"); + i = len; + } + print_node_brief (stderr, "", t, 0); + if (t == error_mark_node) + break; + } + if (i) + fprintf (stderr, "\n"); + } + if (lvl->type_decls) + { + fprintf (stderr, " tags:\t"); + i = 0; + binding_table_foreach (lvl->type_decls, bt_print_entry, &i); + if (i) + fprintf (stderr, "\n"); + } + if (lvl->class_shadowed) + { + fprintf (stderr, " class-shadowed:"); + for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t)) + { + fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); + } + fprintf (stderr, "\n"); + } + if (lvl->type_shadowed) + { + fprintf (stderr, " type-shadowed:"); + for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t)) + { + fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); + } + fprintf (stderr, "\n"); + } +} + +void +print_other_binding_stack (struct cp_binding_level *stack) +{ + struct cp_binding_level *level; + for (level = stack; !global_scope_p (level); level = level->level_chain) + { + fprintf (stderr, "binding level " HOST_PTR_PRINTF "\n", (void *) level); + print_binding_level (level); + } +} + +void +print_binding_stack (void) +{ + struct cp_binding_level *b; + fprintf (stderr, "current_binding_level=" HOST_PTR_PRINTF + "\nclass_binding_level=" HOST_PTR_PRINTF + "\nNAMESPACE_LEVEL (global_namespace)=" HOST_PTR_PRINTF "\n", + (void *) current_binding_level, (void *) class_binding_level, + (void *) NAMESPACE_LEVEL (global_namespace)); + if (class_binding_level) + { + for (b = class_binding_level; b; b = b->level_chain) + if (b == current_binding_level) + break; + if (b) + b = class_binding_level; + else + b = current_binding_level; + } + else + b = current_binding_level; + print_other_binding_stack (b); + fprintf (stderr, "global:\n"); + print_binding_level (NAMESPACE_LEVEL (global_namespace)); +} +/* Return the type associated with id. */ + +tree +identifier_type_value (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); + /* 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)); + /* 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, LOOKUP_COMPLAIN); + if (id) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_TYPE (id)); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); +} + +/* 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++. */ + +tree +identifier_global_value (tree t) +{ + return IDENTIFIER_GLOBAL_VALUE (t); +} + +/* Push a definition of struct, union or enum tag named ID. into + binding_level B. DECL is a TYPE_DECL for the type. We assume that + the tag ID is not already defined. */ + +static void +set_identifier_type_value_with_scope (tree id, tree decl, cxx_scope *b) +{ + tree type; + + if (b->kind != sk_namespace) + { + /* Shadow the marker, not the real thing, so that the marker + gets restored later. */ + tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id); + b->type_shadowed + = tree_cons (id, old_type_value, b->type_shadowed); + type = decl ? TREE_TYPE (decl) : NULL_TREE; + } + else + { + cxx_binding *binding = + binding_for_name (NAMESPACE_LEVEL (current_namespace), id); + if (decl) + { + if (binding->value) + supplement_binding (binding, decl); + else + binding->value = decl; + } + else + abort (); + /* Store marker instead of real type. */ + type = global_type_node; + } + SET_IDENTIFIER_TYPE_VALUE (id, type); +} + +/* As set_identifier_type_value_with_scope, but using + current_binding_level. */ + +void +set_identifier_type_value (tree id, tree decl) +{ + set_identifier_type_value_with_scope (id, decl, current_binding_level); +} + /* Return (from the stack of) the BINDING, if any, establihsed at SCOPE. */ static inline cxx_binding * @@ -458,9 +1168,515 @@ binding_for_name (cxx_scope *scope, tree name) IDENTIFIER_NAMESPACE_BINDINGS (name) = result; return result; } + +/* Same as pushdecl, but define X in binding-level LEVEL. We rely on the + caller to set DECL_CONTEXT properly. */ + +tree +pushdecl_with_scope (tree x, cxx_scope *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->kind == sk_class) + { + b = class_binding_level; + class_binding_level = level; + pushdecl_class_level (x); + class_binding_level = b; + } + else + { + b = current_binding_level; + current_binding_level = level; + x = pushdecl (x); + current_binding_level = b; + } + current_function_decl = function_decl; + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); +} + +/* Return the type that should be used when TYPE's name is preceded + by a tag such as 'struct' or 'union', or null if the name cannot + be used in this way. + + For example, when processing the third line of: + + struct A; + typedef struct A A; + struct A; + + lookup of A will find the typedef. Given A's typedef, this function + will return the type associated with "struct A". For the tag to be + anything other than TYPE, TYPE must be a typedef whose original type + has the same name and context as TYPE itself. + + It is not valid for a typedef of an anonymous type to be used with + an explicit tag: + + typedef struct { ... } B; + struct B; + + Return null for this case. */ + +static tree +follow_tag_typedef (tree type) +{ + tree original; + + original = original_type (type); + if (! TYPE_NAME (original)) + return NULL_TREE; + if (TYPE_IDENTIFIER (original) == TYPE_IDENTIFIER (type) + && (CP_DECL_CONTEXT (TYPE_NAME (original)) + == CP_DECL_CONTEXT (TYPE_NAME (type))) + && !(CLASS_TYPE_P (original) && TYPE_WAS_ANONYMOUS (original))) + return original; + else + return NULL_TREE; +} + +/* Given NAME, an IDENTIFIER_NODE, + return the structure (or union or enum) definition for that name. + Searches binding levels from its SCOPE up to the global level. + If THISLEVEL_ONLY is nonzero, searches only the specified context + (but skips any sk_cleanup contexts to find one that is + meaningful for tags). + FORM says which kind of type the caller wants; + it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE. + If the wrong kind of type is found, and it's not a template, an error is + reported. */ + +tree +lookup_tag (enum tree_code form, tree name, + cxx_scope *binding_level, int thislevel_only) +{ + register struct cp_binding_level *level; + /* Nonzero if, we should look past a template parameter level, even + if THISLEVEL_ONLY. */ + int allow_template_parms_p = 1; + bool type_is_anonymous = ANON_AGGRNAME_P (name); + + timevar_push (TV_NAME_LOOKUP); + for (level = binding_level; level; level = level->level_chain) + { + register tree tail; + if (type_is_anonymous && level->type_decls != NULL) + { + tree type = binding_table_find_anon_type (level->type_decls, name); + /* There is no need for error checking here, because + anon names are unique throughout the compilation. */ + if (type != NULL) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type); + } + else if (level->kind == sk_namespace) + /* Do namespace lookup. */ + for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail)) + { + cxx_binding *binding = + cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (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 + && binding && binding->value + && DECL_CLASS_TEMPLATE_P (binding->value)) + old = binding->value; + else if (binding) + old = select_decl (binding, LOOKUP_PREFER_TYPES); + else + old = NULL_TREE; + + if (old) + { + /* We've found something at this binding level. If it is + a typedef, extract the tag it refers to. Lookup fails + if the typedef doesn't refer to a taggable type. */ + old = TREE_TYPE (old); + old = follow_tag_typedef (old); + if (!old) + 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); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + } + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old); + } + if (thislevel_only || tail == global_namespace) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + } + else if (level->type_decls != NULL) + { + binding_entry entry = binding_table_find (level->type_decls, name); + if (entry != NULL) + { + enum tree_code code = TREE_CODE (entry->type); + + if (code != form + && (form == ENUMERAL_TYPE || code == ENUMERAL_TYPE)) + { + /* Definition isn't the kind we were looking for. */ + error ("`%#D' redeclared as %C", entry->type, form); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + } + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->type); + } + } + if (thislevel_only && level->kind != sk_cleanup) + { + if (level->kind == sk_template_parms && allow_template_parms_p) + { + /* We must deal with cases like this: + + template <class T> struct S; + template <class T> struct S {}; + + When looking up `S', for the second declaration, we + would like to find the first declaration. But, we + are in the pseudo-global level created for the + template parameters, rather than the (surrounding) + namespace level. Thus, we keep going one more level, + even though THISLEVEL_ONLY is nonzero. */ + allow_template_parms_p = 0; + continue; + } + else + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + } + } + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); +} + +/* Given a type, find the tag that was defined for it and return the tag name. + Otherwise return 0. However, the value can never be 0 + in the cases in which this is used. + + C++: If NAME is nonzero, this is the new name to install. This is + done when replacing anonymous tags with real tag names. */ + +tree +lookup_tag_reverse (tree type, tree name) +{ + register struct cp_binding_level *level; + + timevar_push (TV_NAME_LOOKUP); + for (level = current_binding_level; level; level = level->level_chain) + { + binding_entry entry = level->type_decls == NULL + ? NULL + : binding_table_reverse_maybe_remap (level->type_decls, type, name); + if (entry) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->name); + } + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); +} -/* Namespace-scope manipulation routines. */ +/* Do a pushlevel for class declarations. */ + +void +pushlevel_class (void) +{ + if (ENABLE_SCOPE_CHECKING) + is_class_level = 1; + + class_binding_level = begin_scope (sk_class, current_class_type); +} + +/* ...and a poplevel for class declarations. */ +void +poplevel_class (void) +{ + 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 + of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot + shouldn't even be used when current_class_type isn't set, and second, + if we don't touch it here, we're able to use the cache effect if the + next time we're entering a class scope, it is the same class. */ + if (current_class_depth != 1) + { + struct cp_binding_level* b; + + /* Clear out our IDENTIFIER_CLASS_VALUEs. */ + for (shadowed = level->class_shadowed; + shadowed; + shadowed = TREE_CHAIN (shadowed)) + IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = NULL_TREE; + + /* Find the next enclosing class, and recreate + IDENTIFIER_CLASS_VALUEs appropriate for that class. */ + b = level->level_chain; + while (b && b->kind != sk_class) + b = b->level_chain; + + if (b) + for (shadowed = b->class_shadowed; + shadowed; + shadowed = TREE_CHAIN (shadowed)) + { + cxx_binding *binding; + + binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed)); + while (binding && binding->scope != b) + binding = binding->previous; + + if (binding) + IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) + = binding->value; + } + } + else + /* Remember to save what IDENTIFIER's were bound in this scope so we + can recover from cache misses. */ + { + previous_class_type = current_class_type; + previous_class_values = class_binding_level->class_shadowed; + } + for (shadowed = level->type_shadowed; + shadowed; + shadowed = TREE_CHAIN (shadowed)) + SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed)); + + /* Remove the bindings for all of the class-level declarations. */ + for (shadowed = level->class_shadowed; + shadowed; + shadowed = TREE_CHAIN (shadowed)) + pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed)); + + /* Now, pop out of the binding level which we created up in the + `pushlevel_class' routine. */ + if (ENABLE_SCOPE_CHECKING) + is_class_level = 1; + + leave_scope (); + timevar_pop (TV_NAME_LOOKUP); +} + +/* Bind DECL to ID in the class_binding_level. Returns nonzero if the + binding was successful. */ + +int +push_class_binding (tree id, tree decl) +{ + int result = 1; + 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. */ + note_name_declared_in_class (id, decl); + + if (binding && binding->scope == class_binding_level) + /* Supplement the existing binding. */ + result = supplement_binding (IDENTIFIER_BINDING (id), decl); + else + /* Create a new binding. */ + push_binding (id, decl, class_binding_level); + + /* Update the IDENTIFIER_CLASS_VALUE for this ID to be the + class-level declaration. Note that we do not use DECL here + because of the possibility of the `struct stat' hack; if DECL is + a class-name or enum-name we might prefer a field-name, or some + such. */ + IDENTIFIER_CLASS_VALUE (id) = IDENTIFIER_BINDING (id)->value; + + /* If this is a binding from a base class, mark it as such. */ + binding = IDENTIFIER_BINDING (id); + if (binding->value == decl && TREE_CODE (decl) != TREE_LIST) + { + if (TREE_CODE (decl) == OVERLOAD) + context = CP_DECL_CONTEXT (OVL_CURRENT (decl)); + else + { + my_friendly_assert (DECL_P (decl), 0); + context = context_for_name_lookup (decl); + } + + if (is_properly_derived_from (current_class_type, context)) + INHERITED_VALUE_BINDING_P (binding) = 1; + else + INHERITED_VALUE_BINDING_P (binding) = 0; + } + else if (binding->value == decl) + /* We only encounter a TREE_LIST when push_class_decls detects an + ambiguity. Such an ambiguity can be overridden by a definition + in this class. */ + INHERITED_VALUE_BINDING_P (binding) = 1; + + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result); +} + +/* We are entering the scope of a class. Clear IDENTIFIER_CLASS_VALUE + for any names in enclosing classes. */ + +void +clear_identifier_class_values (void) +{ + tree t; + + if (!class_binding_level) + return; + + for (t = class_binding_level->class_shadowed; + t; + t = TREE_CHAIN (t)) + IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; +} + +/* Make the declaration of X appear in CLASS scope. */ + +bool +pushdecl_class_level (tree x) +{ + tree name; + bool is_valid = true; + + timevar_push (TV_NAME_LOOKUP); + /* Get the name of X. */ + if (TREE_CODE (x) == OVERLOAD) + name = DECL_NAME (get_first_fn (x)); + else + name = DECL_NAME (x); + + if (name) + { + is_valid = push_class_level_binding (name, x); + if (TREE_CODE (x) == TYPE_DECL) + set_identifier_type_value (name, x); + } + else if (ANON_AGGR_TYPE_P (TREE_TYPE (x))) + { + /* If X is an anonymous aggregate, all of its members are + treated as if they were members of the class containing the + aggregate, for naming purposes. */ + tree f; + + for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f)) + { + location_t save_location = input_location; + input_location = DECL_SOURCE_LOCATION (f); + if (!pushdecl_class_level (f)) + is_valid = false; + input_location = save_location; + } + } + timevar_pop (TV_NAME_LOOKUP); + + return is_valid; +} + +/* 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) +{ + 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) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + + /* Make sure that this new member does not have the same name + as a template parameter. */ + if (TYPE_BEING_DEFINED (current_class_type)) + check_template_shadow (x); + + /* If this declaration shadows a declaration from an enclosing + class, then we will need to restore IDENTIFIER_CLASS_VALUE when + we leave this class. Record the shadowed declaration here. */ + binding = IDENTIFIER_BINDING (name); + if (binding && binding->value) + { + tree bval = binding->value; + tree old_decl = NULL_TREE; + + if (INHERITED_VALUE_BINDING_P (binding)) + { + /* If the old binding was from a base class, and was for a + tag name, slide it over to make room for the new binding. + The old binding is still visible if explicitly qualified + with a class-key. */ + if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval) + && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))) + { + old_decl = binding->type; + binding->type = bval; + binding->value = NULL_TREE; + INHERITED_VALUE_BINDING_P (binding) = 0; + } + else + old_decl = bval; + } + 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); + 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); + + if (old_decl) + { + tree shadow; + + /* Find the previous binding of name on the class-shadowed + list, and update it. */ + for (shadow = class_binding_level->class_shadowed; + shadow; + shadow = TREE_CHAIN (shadow)) + if (TREE_PURPOSE (shadow) == name + && TREE_TYPE (shadow) == old_decl) + { + binding->value = x; + INHERITED_VALUE_BINDING_P (binding) = 0; + TREE_TYPE (shadow) = x; + IDENTIFIER_CLASS_VALUE (name) = x; + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + } + } + } + + /* If we didn't replace an existing binding, put the binding on the + stack of bindings for the identifier, and update the shadowed list. */ + if (push_class_binding (name, x)) + { + class_binding_level->class_shadowed + = tree_cons (name, NULL, + class_binding_level->class_shadowed); + /* Record the value we are binding NAME to so that we can know + what to pop later. */ + TREE_TYPE (class_binding_level->class_shadowed) = x; + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + } + + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false); +} + +void +set_class_shadows (tree shadows) +{ + class_binding_level->class_shadowed = shadows; +} + /* Return the binding value for name in scope. */ tree @@ -494,4 +1710,1011 @@ set_namespace_binding (tree name, tree scope, tree val) timevar_pop (TV_NAME_LOOKUP); } +/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we + select a name that is unique to this compilation unit. */ + +void +push_namespace (tree name) +{ + tree d = NULL_TREE; + int need_new = 1; + int implicit_use = 0; + + timevar_push (TV_NAME_LOOKUP); + + /* We should not get here if the global_namespace is not yet constructed + nor if NAME designates the global namespace: The global scope is + constructed elsewhere. */ + my_friendly_assert (global_namespace != NULL && name != global_scope_name, + 20030531); + + if (!name) + { + /* The name of anonymous namespace is unique for the translation + unit. */ + if (!anonymous_namespace_name) + anonymous_namespace_name = get_file_function_name ('N'); + name = anonymous_namespace_name; + d = IDENTIFIER_NAMESPACE_VALUE (name); + if (d) + /* Reopening anonymous namespace. */ + need_new = 0; + implicit_use = 1; + } + else + { + /* Check whether this is an extended namespace definition. */ + d = IDENTIFIER_NAMESPACE_VALUE (name); + if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL) + { + need_new = 0; + if (DECL_NAMESPACE_ALIAS (d)) + { + error ("namespace alias `%D' not allowed here, assuming `%D'", + d, DECL_NAMESPACE_ALIAS (d)); + d = DECL_NAMESPACE_ALIAS (d); + } + } + } + + if (need_new) + { + /* Make a new namespace, binding the name to it. */ + d = build_lang_decl (NAMESPACE_DECL, name, void_type_node); + DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace); + d = pushdecl (d); + begin_scope (sk_namespace, d); + } + else + resume_scope (NAMESPACE_LEVEL (d)); + + if (implicit_use) + do_using_directive (d); + /* Enter the name space. */ + current_namespace = d; + + timevar_pop (TV_NAME_LOOKUP); +} + +/* Pop from the scope of the current namespace. */ + +void +pop_namespace (void) +{ + my_friendly_assert (current_namespace != global_namespace, 20010801); + current_namespace = CP_DECL_CONTEXT (current_namespace); + /* The binding level is not popped, as it might be re-opened later. */ + leave_scope (); +} + +/* Push into the scope of the namespace NS, even if it is deeply + nested within another namespace. */ + +void +push_nested_namespace (tree ns) +{ + if (ns == global_namespace) + push_to_top_level (); + else + { + push_nested_namespace (CP_DECL_CONTEXT (ns)); + push_namespace (DECL_NAME (ns)); + } +} + +/* Pop back from the scope of the namespace NS, which was previously + entered with push_nested_namespace. */ + +void +pop_nested_namespace (tree ns) +{ + timevar_push (TV_NAME_LOOKUP); + while (ns != global_namespace) + { + pop_namespace (); + ns = CP_DECL_CONTEXT (ns); + } + + pop_from_top_level (); + timevar_pop (TV_NAME_LOOKUP); +} + +/* Like pushdecl, only it places X in the current namespace, + if appropriate. */ + +tree +pushdecl_namespace_level (tree 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 + what we want. */ + if (TREE_CODE (x) == TYPE_DECL) + { + tree name = DECL_NAME (x); + tree newval; + tree *ptr = (tree *)0; + for (; !global_scope_p (b); b = b->level_chain) + { + tree shadowed = b->type_shadowed; + for (; shadowed; shadowed = TREE_CHAIN (shadowed)) + if (TREE_PURPOSE (shadowed) == name) + { + ptr = &TREE_VALUE (shadowed); + /* Can't break out of the loop here because sometimes + a binding level will have duplicate bindings for + PT names. It's gross, but I haven't time to fix it. */ + } + } + newval = TREE_TYPE (x); + if (ptr == (tree *)0) + { + /* @@ This shouldn't be needed. My test case "zstring.cc" trips + up here if this is changed to an assertion. --KR */ + SET_IDENTIFIER_TYPE_VALUE (name, x); + } + else + { + *ptr = newval; + } + } + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); +} + +/* Return the declarations that are members of the namespace NS. */ + +tree +cp_namespace_decls (tree ns) +{ + return NAMESPACE_LEVEL (ns)->names; +} + +/* Combine prefer_type and namespaces_only into flags. */ + +static int +lookup_flags (int prefer_type, int namespaces_only) +{ + if (namespaces_only) + return LOOKUP_PREFER_NAMESPACES; + if (prefer_type > 1) + return LOOKUP_PREFER_TYPES; + if (prefer_type > 0) + return LOOKUP_PREFER_BOTH; + return 0; +} + +/* Given a lookup that returned VAL, use FLAGS to decide if we want to + ignore it or not. Subroutine of lookup_name_real. */ + +static tree +qualify_lookup (tree val, int flags) +{ + if (val == NULL_TREE) + return val; + if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL) + return val; + if ((flags & LOOKUP_PREFER_TYPES) + && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL)) + return val; + if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES)) + return NULL_TREE; + return val; +} + +/* Look up NAME in the NAMESPACE. */ + +tree +lookup_namespace_name (tree namespace, tree 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. */ + 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); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + } + + namespace = ORIGINAL_NAMESPACE (namespace); + + if (TREE_CODE (name) == TEMPLATE_ID_EXPR) + { + template_id = name; + name = TREE_OPERAND (name, 0); + if (TREE_CODE (name) == OVERLOAD) + name = DECL_NAME (OVL_CURRENT (name)); + else if (DECL_P (name)) + name = DECL_NAME (name); + } + + my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373); + + 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 = binding.value; + + if (template_id) + { + if (DECL_CLASS_TEMPLATE_P (val)) + val = lookup_template_class (val, + TREE_OPERAND (template_id, 1), + /*in_decl=*/NULL_TREE, + /*context=*/NULL_TREE, + /*entering_scope=*/0, + tf_error | tf_warning); + else if (DECL_FUNCTION_TEMPLATE_P (val) + || TREE_CODE (val) == OVERLOAD) + val = lookup_template_function (val, + TREE_OPERAND (template_id, 1)); + else + { + error ("`%D::%D' is not a template", + namespace, name); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + } + } + + /* If we have a single function from a using decl, pull it out. */ + if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val)) + val = OVL_FUNCTION (val); + + /* Ignore built-in functions that haven't been prototyped yet. */ + if (!val || !DECL_P(val) + || !DECL_LANG_SPECIFIC(val) + || !DECL_ANTICIPATED (val)) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); + } + + error ("`%D' undeclared in namespace `%D'", name, namespace); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); +} + +/* Select the right _DECL from multiple choices. */ + +static tree +select_decl (cxx_binding *binding, int flags) +{ + tree val; + val = binding->value; + + timevar_push (TV_NAME_LOOKUP); + if (LOOKUP_NAMESPACES_ONLY (flags)) + { + /* We are not interested in types. */ + if (val && TREE_CODE (val) == NAMESPACE_DECL) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + } + + /* If looking for a type, or if there is no non-type binding, select + the value binding. */ + if (binding->type && (!val || (flags & LOOKUP_PREFER_TYPES))) + val = binding->type; + /* Don't return non-types if we really prefer types. */ + else if (val && LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL + && (TREE_CODE (val) != TEMPLATE_DECL + || !DECL_CLASS_TEMPLATE_P (val))) + val = NULL_TREE; + + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); +} + +/* Unscoped lookup of a global: iterate over current namespaces, + considering using-directives. If SPACESP is non-NULL, store a list + of the namespaces we've considered in it. */ + +tree +unqualified_namespace_lookup (tree name, int flags, tree* spacesp) +{ + 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 = + cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name); + if (spacesp) + *spacesp = tree_cons (scope, NULL_TREE, *spacesp); + + /* Ignore anticipated built-in functions. */ + if (b && b->value && DECL_P (b->value) + && DECL_LANG_SPECIFIC (b->value) && DECL_ANTICIPATED (b->value)) + /* Keep binding cleared. */; + else if (b) + { + /* Initialize binding for this context. */ + binding.value = b->value; + binding.type = b->type; + } + + /* Add all _DECLs seen through local using-directives. */ + for (level = current_binding_level; + level->kind != sk_namespace; + level = level->level_chain) + if (!lookup_using_namespace (name, &binding, level->using_directives, + scope, flags, spacesp)) + /* Give up because of error. */ + 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, &binding, + DECL_NAMESPACE_USING (siter), + scope, flags, spacesp)) + /* Give up because of error. */ + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + if (siter == scope) break; + siter = CP_DECL_CONTEXT (siter); + } + + val = select_decl (&binding, flags); + if (scope == global_namespace) + break; + } + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); +} + +/* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL + or a class TYPE). If IS_TYPE_P is TRUE, then ignore non-type + bindings. + + Returns a DECL (or OVERLOAD, or BASELINK) representing the + declaration found. If no suitable declaration can be found, + ERROR_MARK_NODE is returned. Iif COMPLAIN is true and SCOPE is + neither a class-type nor a namespace a diagnostic is issued. */ + +tree +lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain) +{ + int flags = 0; + + if (TREE_CODE (scope) == NAMESPACE_DECL) + { + cxx_binding binding; + + cxx_binding_clear (&binding); + flags |= LOOKUP_COMPLAIN; + if (is_type_p) + flags |= LOOKUP_PREFER_TYPES; + if (qualified_lookup_using_namespace (name, scope, &binding, + flags)) + return select_decl (&binding, flags); + } + else if (is_aggr_type (scope, complain)) + { + tree t; + t = lookup_member (scope, name, 0, is_type_p); + if (t) + return t; + } + + return error_mark_node; +} + +/* Look up NAME in the current binding level and its superiors in the + namespace of variables, functions and typedefs. Return a ..._DECL + node of some kind representing its definition if there is only one + such declaration, or return a TREE_LIST with all the overloaded + definitions if there are many, or return 0 if it is undefined. + + If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces. + If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces). + Otherwise we prefer non-TYPE_DECLs. + + If NONCLASS is nonzero, we don't look for the NAME in class scope, + using IDENTIFIER_CLASS_VALUE. */ + +tree +lookup_name_real (tree name, int prefer_type, int nonclass, + 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. */ + if (IDENTIFIER_TYPENAME_P (name)) + { + struct cp_binding_level *level; + + for (level = current_binding_level; + level && level->kind != sk_namespace; + level = level->level_chain) + { + tree class_type; + tree operators; + + /* A conversion operator can only be declared in a class + scope. */ + if (level->kind != sk_class) + continue; + + /* Lookup the conversion operator in the class. */ + class_type = level->this_entity; + operators = lookup_fnfields (class_type, name, /*protect=*/0); + if (operators) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators); + } + + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + } + + flags |= lookup_flags (prefer_type, namespaces_only); + + /* First, look in non-namespace scopes. */ + + if (current_class_type == NULL_TREE) + nonclass = 1; + + for (iter = IDENTIFIER_BINDING (name); iter; iter = iter->previous) + { + tree binding; + + 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 (iter->value, flags)) + binding = iter->value; + else if ((flags & LOOKUP_PREFER_TYPES) + && qualify_lookup (iter->type, flags)) + binding = iter->type; + else + binding = NULL_TREE; + + if (binding) + { + val = binding; + break; + } + } + + /* Now lookup in namespace scopes. */ + if (!val) + { + tree t = unqualified_namespace_lookup (name, flags, 0); + if (t) + val = t; + } + + if (val) + { + /* If we have a single function from a using decl, pull it out. */ + if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val)) + val = OVL_FUNCTION (val); + } + + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); +} + +tree +lookup_name_nonclass (tree name) +{ + return lookup_name_real (name, 0, 1, 0, LOOKUP_COMPLAIN); +} + +tree +lookup_function_nonclass (tree name, tree args) +{ + return lookup_arg_dependent (name, lookup_name_nonclass (name), args); +} + +tree +lookup_name (tree name, int prefer_type) +{ + return lookup_name_real (name, prefer_type, 0, 0, LOOKUP_COMPLAIN); +} + +/* Similar to `lookup_name' but look only in the innermost non-class + binding level. */ + +tree +lookup_name_current_level (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) + { + t = IDENTIFIER_NAMESPACE_VALUE (name); + + /* extern "C" function() */ + if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST) + t = TREE_VALUE (t); + } + else if (IDENTIFIER_BINDING (name) + && LOCAL_BINDING_P (IDENTIFIER_BINDING (name))) + { + while (1) + { + if (IDENTIFIER_BINDING (name)->scope == b) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name)); + + if (b->kind == sk_cleanup) + b = b->level_chain; + else + break; + } + } + + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); +} + +/* Like lookup_name_current_level, but for types. */ + +tree +lookup_type_current_level (tree name) +{ + register tree t = NULL_TREE; + + timevar_push (TV_NAME_LOOKUP); + my_friendly_assert (current_binding_level->kind != sk_namespace, + 980716); + + if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE + && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node) + { + struct cp_binding_level *b = current_binding_level; + while (1) + { + if (purpose_member (name, b->type_shadowed)) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, + REAL_IDENTIFIER_TYPE_VALUE (name)); + if (b->kind == sk_cleanup) + b = b->level_chain; + else + break; + } + } + + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); +} + +/* 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. */ + +tree +push_using_directive (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); + + 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; + + /* 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); +} + +/* The type TYPE is being declared. If it is a class template, or a + specialization of a class template, do any processing required and + perform error-checking. If IS_FRIEND is nonzero, this TYPE is + being declared a friend. B is the binding level at which this TYPE + should be bound. + + Returns the TYPE_DECL for TYPE, which may have been altered by this + processing. */ + +static tree +maybe_process_template_type_declaration (tree type, int globalize, + cxx_scope *b) +{ + tree decl = TYPE_NAME (type); + + if (processing_template_parmlist) + /* You can't declare a new template type in a template parameter + list. But, you can declare a non-template type: + + template <class A*> struct S; + + is a forward-declaration of `A'. */ + ; + else + { + maybe_check_template_type (type); + + my_friendly_assert (IS_AGGR_TYPE (type) + || TREE_CODE (type) == ENUMERAL_TYPE, 0); + + + if (processing_template_decl) + { + /* This may change after the call to + push_template_decl_real, but we want the original value. */ + tree name = DECL_NAME (decl); + + decl = push_template_decl_real (decl, globalize); + /* If the current binding level is the binding level for the + template parameters (see the comment in + begin_template_parm_list) and the enclosing level is a class + scope, and we're not looking at a friend, push the + declaration of the member class into the class scope. In the + friend case, push_template_decl will already have put the + friend into global scope, if appropriate. */ + if (TREE_CODE (type) != ENUMERAL_TYPE + && !globalize && b->kind == sk_template_parms + && b->level_chain->kind == sk_class) + { + finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type)); + /* Put this UDT in the table of UDTs for the class, since + that won't happen below because B is not the class + binding level, but is instead the pseudo-global level. */ + if (b->level_chain->type_decls == NULL) + b->level_chain->type_decls = + binding_table_new (SCOPE_DEFAULT_HT_SIZE); + binding_table_insert (b->level_chain->type_decls, name, type); + if (!COMPLETE_TYPE_P (current_class_type)) + { + maybe_add_class_template_decl_list (current_class_type, + type, /*friend_p=*/0); + CLASSTYPE_NESTED_UTDS (current_class_type) = + b->level_chain->type_decls; + } + } + } + } + + return decl; +} + +/* Push a tag name NAME for struct/class/union/enum type TYPE. + Normally put it into the inner-most non-sk_cleanup scope, + but if GLOBALIZE is true, put it in the inner-most non-class scope. + The latter is needed for implicit declarations. */ + +void +pushtag (tree name, tree type, int globalize) +{ + register struct cp_binding_level *b; + + timevar_push (TV_NAME_LOOKUP); + b = current_binding_level; + while (b->kind == sk_cleanup + || (b->kind == sk_class + && (globalize + /* We may be defining a new type in the initializer + of a static member variable. We allow this when + not pedantic, and it is particularly useful for + type punning via an anonymous union. */ + || COMPLETE_TYPE_P (b->this_entity)))) + b = b->level_chain; + + if (b->type_decls == NULL) + b->type_decls = binding_table_new (SCOPE_DEFAULT_HT_SIZE); + binding_table_insert (b->type_decls, name, type); + + if (name) + { + /* Do C++ gratuitous typedefing. */ + if (IDENTIFIER_TYPE_VALUE (name) != type) + { + register tree d = NULL_TREE; + int in_class = 0; + tree context = TYPE_CONTEXT (type); + + if (! context) + { + tree cs = current_scope (); + + if (! globalize) + context = cs; + else if (cs != NULL_TREE && TYPE_P (cs)) + /* When declaring a friend class of a local class, we want + to inject the newly named class into the scope + containing the local class, not the namespace scope. */ + context = decl_function_context (get_type_decl (cs)); + } + if (!context) + context = current_namespace; + + if (b->kind == sk_class + || (b->kind == sk_template_parms + && b->level_chain->kind == sk_class)) + in_class = 1; + + if (current_lang_name == lang_name_java) + TYPE_FOR_JAVA (type) = 1; + + d = create_implicit_typedef (name, type); + DECL_CONTEXT (d) = FROB_CONTEXT (context); + if (! in_class) + set_identifier_type_value_with_scope (name, d, b); + + d = maybe_process_template_type_declaration (type, + globalize, b); + + if (b->kind == sk_class) + { + if (!PROCESSING_REAL_TEMPLATE_DECL_P ()) + /* Put this TYPE_DECL on the TYPE_FIELDS list for the + class. But if it's a member template class, we + want the TEMPLATE_DECL, not the TYPE_DECL, so this + is done later. */ + finish_member_declaration (d); + else + pushdecl_class_level (d); + } + else + d = pushdecl_with_scope (d, b); + + /* FIXME what if it gets a name from typedef? */ + if (ANON_AGGRNAME_P (name)) + DECL_IGNORED_P (d) = 1; + + TYPE_CONTEXT (type) = DECL_CONTEXT (d); + + /* If this is a local class, keep track of it. We need this + information for name-mangling, and so that it is possible to find + all function definitions in a translation unit in a convenient + way. (It's otherwise tricky to find a member function definition + it's only pointed to from within a local class.) */ + if (TYPE_CONTEXT (type) + && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL + && !processing_template_decl) + VARRAY_PUSH_TREE (local_classes, type); + } + if (b->kind == sk_class + && !COMPLETE_TYPE_P (current_class_type)) + { + maybe_add_class_template_decl_list (current_class_type, + type, /*friend_p=*/0); + CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls; + } + } + + if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) + /* Use the canonical TYPE_DECL for this node. */ + TYPE_STUB_DECL (type) = TYPE_NAME (type); + else + { + /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE + will be the tagged type we just added to the current + binding level. This fake NULL-named TYPE_DECL node helps + dwarfout.c to know when it needs to output a + representation of a tagged type, and it also gives us a + convenient place to record the "scope start" address for + the tagged type. */ + + tree d = build_decl (TYPE_DECL, NULL_TREE, type); + TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b); + } + 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 + are at all visible. Simply setting current_binding_level to the global + scope isn't enough, because more binding levels may be pushed. */ +struct saved_scope *scope_chain; + +static cxx_saved_binding * +store_bindings (tree names, cxx_saved_binding *old_bindings) +{ + tree t; + cxx_saved_binding *search_bindings = old_bindings; + + timevar_push (TV_NAME_LOOKUP); + for (t = names; t; t = TREE_CHAIN (t)) + { + tree id; + cxx_saved_binding *saved; + cxx_saved_binding *t1; + + if (TREE_CODE (t) == TREE_LIST) + id = TREE_PURPOSE (t); + else + id = DECL_NAME (t); + + if (!id + /* Note that we may have an IDENTIFIER_CLASS_VALUE even when + we have no IDENTIFIER_BINDING if we have left the class + scope, but cached the class-level declarations. */ + || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id))) + continue; + + for (t1 = search_bindings; t1; t1 = t1->previous) + if (t1->identifier == id) + goto skip_it; + + my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135); + 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; + old_bindings = saved; + skip_it: + ; + } + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings); +} + +void +maybe_push_to_top_level (int pseudo) +{ + struct saved_scope *s; + struct cp_binding_level *b; + cxx_saved_binding *old_bindings; + int need_pop; + + timevar_push (TV_NAME_LOOKUP); + s = ggc_alloc_cleared (sizeof (struct saved_scope)); + + b = scope_chain ? current_binding_level : 0; + + /* If we're in the middle of some function, save our state. */ + if (cfun) + { + need_pop = 1; + push_function_context_to (NULL_TREE); + } + else + need_pop = 0; + + old_bindings = NULL; + if (scope_chain && previous_class_type) + old_bindings = store_bindings (previous_class_values, old_bindings); + + /* Have to include the global scope, because class-scope decls + aren't listed anywhere useful. */ + for (; b; b = b->level_chain) + { + tree t; + + /* Template IDs are inserted into the global level. If they were + inserted into namespace level, finish_file wouldn't find them + when doing pending instantiations. Therefore, don't stop at + namespace level, but continue until :: . */ + if (global_scope_p (b) || (pseudo && b->kind == sk_template_parms)) + break; + + old_bindings = store_bindings (b->names, old_bindings); + /* We also need to check class_shadowed to save class-level type + bindings, since pushclass doesn't fill in b->names. */ + if (b->kind == sk_class) + old_bindings = store_bindings (b->class_shadowed, old_bindings); + + /* Unwind type-value slots back to top level. */ + for (t = b->type_shadowed; t; t = TREE_CHAIN (t)) + SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t)); + } + s->prev = scope_chain; + s->old_bindings = old_bindings; + s->bindings = b; + s->need_pop_function_context = need_pop; + s->function_decl = current_function_decl; + s->last_parms = last_function_parms; + + scope_chain = s; + current_function_decl = NULL_TREE; + 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 +push_to_top_level (void) +{ + maybe_push_to_top_level (0); +} + +void +pop_from_top_level (void) +{ + struct saved_scope *s = scope_chain; + cxx_saved_binding *saved; + + timevar_push (TV_NAME_LOOKUP); + /* Clear out class-level bindings cache. */ + if (previous_class_type) + invalidate_class_lookup_cache (); + + current_lang_base = 0; + + scope_chain = s->prev; + for (saved = s->old_bindings; saved; saved = saved->previous) + { + tree id = saved->identifier; + + 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 + state. */ + if (s->need_pop_function_context) + pop_function_context_from (NULL_TREE); + current_function_decl = s->function_decl; + last_function_parms = s->last_parms; + timevar_pop (TV_NAME_LOOKUP); +} + +/* Pop off extraneous binding levels left over due to syntax errors. + + We don't pop past namespaces, as they might be valid. */ + +void +pop_everything (void) +{ + if (ENABLE_SCOPE_CHECKING) + verbatim ("XXX entering pop_everything ()\n"); + while (!toplevel_bindings_p ()) + { + if (current_binding_level->kind == sk_class) + pop_nested_class (); + else + poplevel (0, 0, 0); + } + if (ENABLE_SCOPE_CHECKING) + verbatim ("XXX leaving pop_everything ()\n"); +} + #include "gt-cp-name-lookup.h" diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 15f1936..7153cbe 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -46,12 +46,6 @@ struct binding_entry_s GTY(()) #define NAMESPACE_STD_HT_SIZE (1 << 8) #define GLOBAL_SCOPE_HT_SIZE (1 << 8) -extern binding_table binding_table_new (size_t); -extern void binding_table_free (binding_table); -extern void binding_table_insert (binding_table, tree, tree); -extern tree binding_table_find_anon_type (binding_table, tree); -extern binding_entry binding_table_reverse_maybe_remap (binding_table, - tree, tree); extern void binding_table_remove_anonymous_types (binding_table); extern void binding_table_foreach (binding_table, bt_foreach_proc, void *); extern binding_entry binding_table_find (binding_table, tree); @@ -93,9 +87,10 @@ struct cxx_binding GTY(()) unsigned is_local : 1; }; -extern cxx_binding *cxx_binding_make (tree, tree); -extern void cxx_binding_free (cxx_binding *); -extern bool supplement_binding (cxx_binding *, tree); +extern tree identifier_type_value (tree); +extern void set_identifier_type_value (tree, tree); +extern void pop_binding (tree, tree); +extern void clear_identifier_class_values (void); /* The kinds of scopes we recognize. */ typedef enum scope_kind { @@ -246,16 +241,66 @@ struct cp_binding_level GTY(()) /* The tree node representing the global scope. */ extern GTY(()) tree global_namespace; +extern GTY(()) tree global_scope_name; + +/* Indicates that there is a type value in some namespace, although + that is not necessarily in scope at the moment. */ + +extern GTY(()) tree global_type_node; /* True if SCOPE designates the global scope binding contour. */ #define global_scope_p(SCOPE) \ ((SCOPE) == NAMESPACE_LEVEL (global_namespace)) +extern cxx_scope *leave_scope (void); +extern bool kept_level_p (void); +extern int global_bindings_p (void); +extern bool toplevel_bindings_p (void); +extern bool namespace_bindings_p (void); +extern bool template_parm_scope_p (void); +extern scope_kind innermost_scope_kind (void); +extern cxx_scope *begin_scope (scope_kind, tree); +extern void print_binding_stack (void); +extern void print_binding_level (cxx_scope *); +extern void push_to_top_level (void); +extern void pop_from_top_level (void); +extern void maybe_push_to_top_level (int); +extern void pop_everything (void); +extern void keep_next_level (bool); + +extern void push_namespace (tree); +extern void pop_namespace (void); +extern void push_nested_namespace (tree); +extern void pop_nested_namespace (tree); +extern tree push_using_directive (tree); +extern void pushlevel_class (void); +extern void poplevel_class (void); extern cxx_binding *cxx_scope_find_binding_for_name (cxx_scope *, tree); extern cxx_binding *binding_for_name (cxx_scope *, tree); - +extern tree pushdecl_with_scope (tree, cxx_scope *); +extern tree lookup_tag (enum tree_code, tree, cxx_scope *, int); +extern tree lookup_tag_reverse (tree, tree); +extern tree lookup_name (tree, int); +extern tree lookup_name_real (tree, int, int, int, int); +extern tree lookup_name_current_level (tree); +extern tree lookup_type_current_level (tree); extern tree namespace_binding (tree, tree); +extern void add_decl_to_level (tree, cxx_scope *); extern void set_namespace_binding (tree, tree, tree); +extern tree lookup_namespace_name (tree, tree); +extern tree unqualified_namespace_lookup (tree, int, tree *); +extern tree lookup_qualified_name (tree, tree, bool, bool); +extern tree lookup_name_nonclass (tree); +extern tree lookup_function_nonclass (tree, tree); +extern void push_local_binding (tree, tree, int); +extern int push_class_binding (tree, tree); +extern bool pushdecl_class_level (tree); +extern tree pushdecl_namespace_level (tree); +extern bool push_class_level_binding (tree, tree); +extern void storetags (tree); +extern tree getdecls (void); +extern tree cp_namespace_decls (tree); +extern void set_class_shadows (tree); /* Set *DECL to the (non-hidden) declaration for ID at global scope, |