diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/coverage.c | 7 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 70 | ||||
-rw-r--r-- | gcc/cp/call.c | 8 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-lang.c | 4 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 30 | ||||
-rw-r--r-- | gcc/cp/decl.c | 279 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 4 | ||||
-rw-r--r-- | gcc/langhooks-def.h | 1 | ||||
-rw-r--r-- | gcc/langhooks.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/template12.C | 10 |
13 files changed, 230 insertions, 205 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bf770b8..d7e7d64 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2003-09-12 Mark Mitchell <mark@codesourcery.com> + + * coverage.c (create_coverage): Do not call pushlevel/poplevel. + * langhooks-def.h (lhd_do_nothing_iii_return_null_tree): New + function. + * langhooks.c (lhd_do_nothing_iii_return_null_tree): Define it. + 2003-09-14 Kazu Hirata <kazu@cs.umass.edu> * combine.c (simplify_comparison): Convert diff --git a/gcc/coverage.c b/gcc/coverage.c index 6facdce..e6f4129 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -854,19 +854,18 @@ create_coverage (void) rest_of_decl_compilation (ctor, 0, 1, 0); announce_function (ctor); current_function_decl = ctor; - DECL_INITIAL (ctor) = error_mark_node; make_decl_rtl (ctor, NULL); init_function_start (ctor); - (*lang_hooks.decls.pushlevel) (0); expand_function_start (ctor, 0); - /* Actually generate the code to call __gcov_init. */ gcov_info_address = force_reg (Pmode, XEXP (DECL_RTL (gcov_info), 0)); emit_library_call (gcov_init_libfunc, LCT_NORMAL, VOIDmode, 1, gcov_info_address, Pmode); expand_function_end (); - (*lang_hooks.decls.poplevel) (1, 0, 1); + /* Create a dummy BLOCK. */ + DECL_INITIAL (ctor) = make_node (BLOCK); + TREE_USED (DECL_INITIAL (ctor)) = 1; rest_of_compilation (ctor); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3d2b3a5..374e7e5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,73 @@ +2003-09-12 Mark Mitchell <mark@codesourcery.com> + + PR c++/3907 + * class.c (maybe_note_name_used_in_class): Refine test for whether + or not we are in a class scope. + + * cp-tree.h (language_function): Remove x_expanding_p. + (expanding_p): Remove. + (doing_semantic_analysis_p): Remove. + (scope_kind): Add sk_function_parms, sk_class, + sk_namespace. + (innermost_scope_kind): New method. + * call.c (cxx_type_promotes_to): Use type_decays_to. + * cp-lang.c (LANG_HOOKS_PUSHLEVEL): Redefine. + (LANG_HOOKS_POPLEVEL): Likewise. + * decl.c (cp_binding_level): Remove parm_flag, template_parms_p, + template_spec_p, namespace_p, is_for_scope, is_try_scope, and + is_catch_scope. Add kind and explicit_spec_p. + (cxx_scope_descriptor): Use a lookup table. + (find_class_binding_level): Use "kind" field in binding_level, not + the various flags. + (pop_binding_level): Likewise. + (innermost_nonclass_level): Likewise. + (toplevel_bindings_p): Likewise. + (namespace_bindings_p): Likewise. + (template_parm_scope_p): Likewise. + (innermost_scope_kind): New method. + (current_tmpl_spec_kind): Use "kind" field in binding_level, not + the various flags. + (pushlevel): Remove check for doing_semantic_analysis_p. + (begin_scope): Simplify. + (add_decl_to_level): Use "kind" field in binding_level, not + the various flags. + (push_local_binding): Likewise. + (pop_label): Remove check for doing_semantic_analysis_p. + (poplevel): Use "kind" field in binding_level, not + the various flags. + (set_block): Remove check for doing_semantic_analysis_p. + (pushlevel_class): Use "kind" field in binding_level, not + the various flags. + (poplevel_class): Likewise. + (initial_push_namespace_scope): Likewise. + (maybe_push_to_top_level): Likewise. + (set_identifier_type_value_with_scope): Likewise. + (pop_everything): Likewise. + (maybe_process_template_type_declaration): Likewise. + (pushtag): Likewise. + (pushdecl): Likewise. + (pushdecl_with_scope): Likewise. + (check_previous_goto_1): Likewise. + (define_label): Likewise. + (finish_case_label): Likewise. + (lookup_tag): Likewise. + (unqualified_namespace_lookup): Likewise. + (lookup_name_real): Likewise. + (lookup_name_current_level): Likewise. + (lookup_type_current_level): Likewise. + (record_builtin_type): Likewise. + (cp_make_fname_decl): Likewise. + (maybe_inject_for_scope_var): Likewise. + (cp_finish_decl): Remove check for doing_semantic_analysis_p. + (start_function): Use begin_scope, not pushlevel. + (finish_function): Use "kind" field in binding_level, not + the various flags. + (start_method): Use begin_scope, not pushlevel. + (make_label_decl): Do not check expanding_p. + (save_function-data): Do not set expanding_p. + (cxx_push_function_context): Do not clear expanding_p. + * semantics.c (cxx_expand_function_start): Do not set expanding_p. + 2003-09-14 Mark Mitchell <mark@codesourcery.com> * class.c (layout_class_type): Make DECL_MODE match TYPE_MODE for diff --git a/gcc/cp/call.c b/gcc/cp/call.c index bc7e3b8..214fbae 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4278,11 +4278,9 @@ cxx_type_promotes_to (tree type) { tree promote; - if (TREE_CODE (type) == ARRAY_TYPE) - return build_pointer_type (TREE_TYPE (type)); - - if (TREE_CODE (type) == FUNCTION_TYPE) - return build_pointer_type (type); + /* Perform the array-to-pointer and function-to-pointer + conversions. */ + type = type_decays_to (type); promote = type_promotes_to (type); if (same_type_p (type, promote)) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 706ebbf..1809f2d 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -6358,7 +6358,7 @@ maybe_note_name_used_in_class (tree name, tree decl) splay_tree names_used; /* If we're not defining a class, there's nothing to do. */ - if (!current_class_type || !TYPE_BEING_DEFINED (current_class_type)) + if (innermost_scope_kind() != sk_class) return; /* If there's already a binding for this NAME, then we don't have diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index e71d53a..3e229a0 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -102,6 +102,10 @@ static void cxx_initialize_diagnostics (diagnostic_context *); #define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name #undef LANG_HOOKS_PRINT_ERROR_FUNCTION #define LANG_HOOKS_PRINT_ERROR_FUNCTION cxx_print_error_function +#undef LANG_HOOKS_PUSHLEVEL +#define LANG_HOOKS_PUSHLEVEL lhd_do_nothing_i +#undef LANG_HOOKS_POPLEVEL +#define LANG_HOOKS_POPLEVEL lhd_do_nothing_iii_return_null_tree #undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl #undef LANG_HOOKS_WRITE_GLOBALS diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8ab8c6c..1d126e8 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -798,7 +798,6 @@ struct language_function GTY(()) int returns_abnormally; int in_function_try_handler; int in_base_initializer; - int x_expanding_p; /* True if this function can throw an exception. */ bool can_throw : 1; @@ -860,17 +859,6 @@ struct language_function GTY(()) #define current_function_returns_abnormally \ cp_function_chain->returns_abnormally -/* Nonzero if we should generate RTL for functions that we process. - When this is zero, we just accumulate tree structure, without - interacting with the back end. */ - -#define expanding_p cp_function_chain->x_expanding_p - -/* Nonzero if we are in the semantic analysis phase for the current - function. */ - -#define doing_semantic_analysis_p() (!expanding_p) - /* Nonzero if we are processing a base initializer. Zero elsewhere. */ #define in_base_initializer cp_function_chain->in_base_initializer @@ -2942,15 +2930,24 @@ typedef enum cp_lvalue_kind { /* The kinds of scopes we recognize. */ typedef enum scope_kind { - sk_block, /* An ordinary block scope. */ + sk_block = 0, /* An ordinary block scope. This enumerator must + have the value zero because "cp_binding_level" + is initialized by using "memset" to set the + contents to zero, and the default scope kind + is "sk_block". */ sk_try, /* A try-block. */ sk_catch, /* A catch-block. */ sk_for, /* The scope of the variable declared in a for-init-statement. */ + sk_function_parms, /* The scope containing function parameters. */ + sk_class, /* The scope containing the members of a class. */ + sk_namespace, /* The scope containing the members of a + namespace, including the global scope. */ sk_template_parms, /* A scope for template parameters. */ - sk_template_spec /* A scope corresponding to a template - specialization. There is never anything in - this scope. */ + sk_template_spec /* Like sk_template_parms, but for an explicit + specialization. Since, by definition, an + explicit specialization is introduced by + "template <>", this scope is always empty. */ } scope_kind; /* Various kinds of template specialization, instantiation, etc. */ @@ -3622,6 +3619,7 @@ 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 (int); +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); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6886fe4d..92e8597 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -370,51 +370,31 @@ struct cp_binding_level GTY(()) TREE_LIST; the TREE_VALUE is the actual declaration. */ tree dead_vars_from_for; - /* 1 for the level that holds the parameters of a function. - 2 for the level that holds a class declaration. */ - unsigned parm_flag : 2; + /* Binding depth at which this level began. */ + unsigned binding_depth; + + /* The kind of scope that this object represents. However, a + SK_TEMPLATE_SPEC scope is represented with KIND set to + SK_TEMPALTE_PARMS and EXPLICIT_SPEC_P set to true. */ + enum scope_kind kind : 4; + + /* True if this scope is an SK_TEMPLATE_SPEC scope. This field is + only valid if KIND == SK_TEMPLATE_PARMS. */ + bool explicit_spec_p : 1; /* 1 means make a BLOCK for this level regardless of all else. 2 for temporary binding contours created by the compiler. */ unsigned keep : 2; - /* Nonzero if this level "doesn't exist" for tags. */ - unsigned tag_transparent : 1; - /* Nonzero if this level can safely have additional cleanup-needing variables added to it. */ unsigned more_cleanups_ok : 1; unsigned have_cleanups : 1; - /* Nonzero if this scope is for storing the decls for template - parameters and generic decls; these decls will be discarded and - replaced with a TEMPLATE_DECL. */ - unsigned template_parms_p : 1; - - /* Nonzero if this scope corresponds to the `<>' in a - `template <>' clause. Whenever this flag is set, - TEMPLATE_PARMS_P will be set as well. */ - unsigned template_spec_p : 1; - - /* This is set for a namespace binding level. */ - unsigned namespace_p : 1; - - /* True if this level is that of a for-statement where we need to - worry about ambiguous (ARM or ISO) scope rules. */ - unsigned is_for_scope : 1; - - /* True if this level corresponds to a TRY block. Currently this - information is only available while building the tree structure. */ - unsigned is_try_scope : 1; - - /* True if this level corresponds to a CATCH block. Currently this - information is only available while building the tree structure. */ - unsigned is_catch_scope : 1; - - /* Three bits left for this word. */ + /* Nonzero if this level "doesn't exist" for tags. */ + unsigned tag_transparent : 1; - /* Binding depth at which this level began. */ - unsigned binding_depth; + /* 20 bits left to fill a 32-bit word. */ }; #define NULL_BINDING_LEVEL ((struct cp_binding_level *) NULL) @@ -468,28 +448,18 @@ static tree pushdecl_with_scope (tree, struct cp_binding_level *); static const char * cxx_scope_descriptor (cxx_scope *scope) { - const char *desc; - - if (scope->namespace_p) - desc = "namespace-scope"; - else if (scope->parm_flag == 1) - desc = "function-prototype-scope"; - else if (scope->parm_flag == 2) - desc = "class-scope"; - else if (scope->is_for_scope) - desc = "for-scope"; - else if (scope->is_try_scope) - desc = "try-scope"; - else if (scope->is_catch_scope) - desc = "catch-scope"; - else if (scope->template_spec_p) - desc = "template-explicit-spec-scope"; - else if (scope->template_parms_p) - desc = "template-prototype-scope"; - else - desc = "block-scope"; + /* The order of this table must match the "scope_kind" + enumerators. */ + static const char* scope_kind_names[] = { + "block-scope", + "try-scope", + "catch-scope", + "for-scope", + "template-parameter-scope", + "template-explicit-spec-scope" + }; - return desc; + return scope_kind_names[scope->kind]; } /* Output a debugging information about SCOPE when performning @@ -555,9 +525,9 @@ find_class_binding_level (void) { struct cp_binding_level *level = current_binding_level; - while (level && level->parm_flag != 2) + while (level && level->kind != sk_class) level = level->level_chain; - if (level && level->parm_flag == 2) + if (level && level->kind == sk_class) class_binding_level = level; else class_binding_level = 0; @@ -586,7 +556,7 @@ pop_binding_level (void) register struct cp_binding_level *level = current_binding_level; current_binding_level = current_binding_level->level_chain; level->level_chain = free_binding_level; - if (level->parm_flag == 2) + if (level->kind == sk_class) level->type_decls = NULL; else binding_table_free (level->type_decls); @@ -659,7 +629,7 @@ innermost_nonclass_level (void) struct cp_binding_level *b; b = current_binding_level; - while (b->parm_flag == 2) + while (b->kind == sk_class) b = b->level_chain; return b; @@ -676,7 +646,7 @@ toplevel_bindings_p (void) { struct cp_binding_level *b = innermost_nonclass_level (); - return b->namespace_p || b->template_parms_p; + return b->kind == sk_namespace || b->kind == sk_template_parms; } /* Nonzero if this is a namespace scope, or if we are defining a class @@ -688,7 +658,7 @@ namespace_bindings_p (void) { struct cp_binding_level *b = innermost_nonclass_level (); - return b->namespace_p; + return b->kind == sk_namespace; } /* If KEEP is nonzero, make a BLOCK node for the next binding level, @@ -713,13 +683,21 @@ kept_level_p (void) && !current_binding_level->tag_transparent)); } +/* 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 current_binding_level->template_parms_p; + return innermost_scope_kind () == sk_template_parms; } /* Returns the kind of template specialization we are currently @@ -735,7 +713,9 @@ current_tmpl_spec_kind (int n_class_scopes) struct cp_binding_level *b; /* Scan through the template parameter scopes. */ - for (b = current_binding_level; b->template_parms_p; b = b->level_chain) + for (b = current_binding_level; + b->kind == sk_template_parms; + b = b->level_chain) { /* If we see a specialization scope inside a parameter scope, then something is wrong. That corresponds to a declaration @@ -746,7 +726,7 @@ current_tmpl_spec_kind (int n_class_scopes) which is always invalid since [temp.expl.spec] forbids the specialization of a class member template if the enclosing class templates are not explicitly specialized as well. */ - if (b->template_spec_p) + if (b->explicit_spec_p) { if (n_template_parm_scopes == 0) innermost_specialization_p = 1; @@ -823,9 +803,6 @@ set_class_shadows (tree shadows) void pushlevel (int tag_transparent) { - if (cfun && !doing_semantic_analysis_p ()) - return; - push_binding_level (make_cxx_scope (tag_transparent, keep_next_level_flag)); keep_next_level_flag = 0; } @@ -854,35 +831,12 @@ void begin_scope (scope_kind sk) { pushlevel (0); - - switch (sk) + if (sk == sk_template_spec) { - case sk_block: - break; - - case sk_try: - current_binding_level->is_try_scope = 1; - break; - - case sk_catch: - current_binding_level->is_catch_scope = 1; - break; - - case sk_for: - current_binding_level->is_for_scope = 1; - break; - - case sk_template_spec: - current_binding_level->template_spec_p = 1; - /* Fall through. */ - - case sk_template_parms: - current_binding_level->template_parms_p = 1; - break; - - default: - abort (); + current_binding_level->explicit_spec_p = true; + sk = sk_template_parms; } + current_binding_level->kind = sk; } /* Exit the current scope. */ @@ -937,7 +891,7 @@ add_decl_to_level (tree decl, b->names_size++; /* If appropriate, add decl to separate list of statics */ - if (b->namespace_p) + 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)))) @@ -957,9 +911,7 @@ push_local_binding (tree id, tree decl, int flags) /* Skip over any local classes. This makes sense if we call push_local_binding with a friend decl of a local class. */ - b = current_binding_level; - while (b->parm_flag == 2) - b = b->level_chain; + b = innermost_nonclass_level (); if (lookup_name_current_level (id)) { @@ -1091,7 +1043,7 @@ pop_binding (tree id, tree decl) static void pop_label (tree label, tree old_value) { - if (!processing_template_decl && doing_semantic_analysis_p ()) + if (!processing_template_decl) { if (DECL_INITIAL (label) == NULL_TREE) { @@ -1163,11 +1115,8 @@ poplevel (int keep, int reverse, int functionbody) int leaving_for_scope; timevar_push (TV_NAME_LOOKUP); - if (cfun && !doing_semantic_analysis_p ()) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); - my_friendly_assert (current_binding_level->parm_flag != 2, - 19990916); + my_friendly_assert (current_binding_level->kind != sk_class, 19990916); real_functionbody = (current_binding_level->keep == 2 ? ((functionbody = 0), tmp) : functionbody); @@ -1198,9 +1147,9 @@ poplevel (int keep, int reverse, int functionbody) if (labels->binding_level == current_binding_level) { tree decl; - if (current_binding_level->is_try_scope) + if (current_binding_level->kind == sk_try) labels->in_try_scope = 1; - if (current_binding_level->is_catch_scope) + if (current_binding_level->kind == sk_catch) labels->in_catch_scope = 1; for (decl = labels->names_in_scope; decl; decl = TREE_CHAIN (decl)) @@ -1282,7 +1231,7 @@ poplevel (int keep, int reverse, int functionbody) ended. We only use the new rules if flag_new_for_scope is nonzero. */ leaving_for_scope - = current_binding_level->is_for_scope && flag_new_for_scope == 1; + = current_binding_level->kind == sk_for && flag_new_for_scope == 1; /* Remove declarations for all the DECLs in this level. */ for (link = decls; link; link = TREE_CHAIN (link)) @@ -1499,7 +1448,6 @@ set_block (tree block ATTRIBUTE_UNUSED ) { /* The RTL expansion machinery requires us to provide this callback, but it is not applicable in function-at-a-time mode. */ - my_friendly_assert (cfun && !doing_semantic_analysis_p (), 20000911); } /* Do a pushlevel for class declarations. */ @@ -1510,10 +1458,8 @@ pushlevel_class (void) if (ENABLE_SCOPE_CHECKING) is_class_level = 1; - push_binding_level (make_cxx_scope (false, 0)); - + begin_scope (sk_class); class_binding_level = current_binding_level; - class_binding_level->parm_flag = 2; class_binding_level->this_entity = current_class_type; } @@ -1546,7 +1492,7 @@ poplevel_class (void) /* Find the next enclosing class, and recreate IDENTIFIER_CLASS_VALUEs appropriate for that class. */ b = level->level_chain; - while (b && b->parm_flag != 2) + while (b && b->kind != sk_class) b = b->level_chain; if (b) @@ -1937,9 +1883,8 @@ initial_push_namespace_scope (tree ns) tree name = DECL_NAME (ns); cxx_scope *scope; - pushlevel (0); + begin_scope (sk_namespace); scope = current_binding_level; - scope->namespace_p = true; scope->type_decls = binding_table_new (name == std_identifier ? NAMESPACE_STD_HT_SIZE : (name == global_scope_name @@ -2167,13 +2112,13 @@ maybe_push_to_top_level (int pseudo) 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->template_parms_p)) + 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->parm_flag == 2) + if (b->kind == sk_class) old_bindings = store_bindings (b->class_shadowed, old_bindings); /* Unwind type-value slots back to top level. */ @@ -2244,7 +2189,7 @@ set_identifier_type_value_with_scope (tree id, { tree type; - if (!b->namespace_p) + if (b->kind != sk_namespace) { /* Shadow the marker, not the real thing, so that the marker gets restored later. */ @@ -2311,7 +2256,7 @@ pop_everything (void) verbatim ("XXX entering pop_everything ()\n"); while (!toplevel_bindings_p ()) { - if (current_binding_level->parm_flag == 2) + if (current_binding_level->kind == sk_class) pop_nested_class (); else poplevel (0, 0, 0); @@ -2367,8 +2312,8 @@ maybe_process_template_type_declaration (tree type, friend case, push_template_decl will already have put the friend into global scope, if appropriate. */ if (TREE_CODE (type) != ENUMERAL_TYPE - && !globalize && b->template_parms_p - && b->level_chain->parm_flag == 2) + && !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 @@ -2464,7 +2409,7 @@ pushtag (tree name, tree type, int globalize) timevar_push (TV_NAME_LOOKUP); b = current_binding_level; while (b->tag_transparent - || (b->parm_flag == 2 + || (b->kind == sk_class && (globalize /* We may be defining a new type in the initializer of a static member variable. We allow this when @@ -2501,8 +2446,9 @@ pushtag (tree name, tree type, int globalize) if (!context) context = current_namespace; - if ((b->template_parms_p && b->level_chain->parm_flag == 2) - || b->parm_flag == 2) + 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) @@ -2516,7 +2462,7 @@ pushtag (tree name, tree type, int globalize) d = maybe_process_template_type_declaration (type, globalize, b); - if (b->parm_flag == 2) + if (b->kind == sk_class) { if (!PROCESSING_REAL_TEMPLATE_DECL_P ()) /* Put this TYPE_DECL on the TYPE_FIELDS list for the @@ -2546,14 +2492,12 @@ pushtag (tree name, tree type, int globalize) && !processing_template_decl) VARRAY_PUSH_TREE (local_classes, type); } - if (b->parm_flag == 2) + if (b->kind == sk_class + && !COMPLETE_TYPE_P (current_class_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->type_decls; - } + maybe_add_class_template_decl_list (current_class_type, + type, /*friend_p=*/0); + CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls; } } @@ -3559,10 +3503,6 @@ pushdecl (tree x) int need_new_binding; timevar_push (TV_NAME_LOOKUP); - /* We shouldn't be calling pushdecl when we're generating RTL for a - function that we already did semantic analysis on previously. */ - my_friendly_assert (!cfun || doing_semantic_analysis_p (), - 19990913); need_new_binding = 1; @@ -3943,10 +3883,10 @@ pushdecl (tree x) b = b->level_chain; /* ARM $8.3 */ - if (b->parm_flag == 1) + if (b->kind == sk_function_parms) { error ("declaration of `%#D' shadows a parameter", - name); + name); err = true; } } @@ -4007,7 +3947,7 @@ pushdecl_with_scope (tree x, struct cp_binding_level* level) timevar_push (TV_NAME_LOOKUP); current_function_decl = NULL_TREE; - if (level->parm_flag == 2) + if (level->kind == sk_class) { b = class_binding_level; class_binding_level = level; @@ -4574,9 +4514,6 @@ make_label_decl (tree id, int local_p) tree decl; decl = build_decl (LABEL_DECL, id, void_type_node); - if (expanding_p) - /* Make sure every label has an rtx. */ - label_rtx (decl); DECL_CONTEXT (decl) = current_function_decl; DECL_MODE (decl) = VOIDmode; @@ -4745,7 +4682,7 @@ check_previous_goto_1 (tree decl, if (b == level) break; - if ((b->is_try_scope || b->is_catch_scope) && ! saw_eh) + if ((b->kind == sk_try || b->kind == sk_catch) && ! saw_eh) { if (! identified) { @@ -4758,7 +4695,7 @@ check_previous_goto_1 (tree decl, pedwarn ("%H from here", locus); identified = 1; } - if (b->is_try_scope) + if (b->kind == sk_try) error (" enters try block"); else error (" enters catch block"); @@ -4880,7 +4817,9 @@ define_label (location_t location, tree name) /* After labels, make any new cleanups in the function go into their own new (temporary) binding contour. */ - for (p = current_binding_level; !(p->parm_flag); p = p->level_chain) + for (p = current_binding_level; + p->kind != sk_function_parms; + p = p->level_chain) p->more_cleanups_ok = 0; if (name == get_identifier ("wchar_t")) @@ -4995,7 +4934,9 @@ finish_case_label (tree low_value, tree high_value) /* After labels, make any new cleanups in the function go into their own new (temporary) binding contour. */ - for (p = current_binding_level; !(p->parm_flag); p = p->level_chain) + for (p = current_binding_level; + p->kind != sk_function_parms; + p = p->level_chain) p->more_cleanups_ok = 0; return r; @@ -5104,7 +5045,7 @@ lookup_tag (enum tree_code form, tree name, if (type != NULL) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type); } - else if (level->namespace_p) + else if (level->kind == sk_namespace) /* Do namespace lookup. */ for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail)) { @@ -5165,7 +5106,7 @@ lookup_tag (enum tree_code form, tree name, } if (thislevel_only && ! level->tag_transparent) { - if (level->template_parms_p && allow_template_parms_p) + if (level->kind == sk_template_parms && allow_template_parms_p) { /* We must deal with cases like this: @@ -5628,7 +5569,7 @@ unqualified_namespace_lookup (tree name, int flags, tree* spacesp) /* Add all _DECLs seen through local using-directives. */ for (level = current_binding_level; - !level->namespace_p; + level->kind != sk_namespace; level = level->level_chain) if (!lookup_using_namespace (name, &binding, level->using_directives, scope, flags, spacesp)) @@ -5813,7 +5754,7 @@ lookup_name_real (tree name, int prefer_type, int nonclass, struct cp_binding_level *level; for (level = current_binding_level; - level && !level->namespace_p; + level && level->kind != sk_namespace; level = level->level_chain) { tree class_type; @@ -5821,7 +5762,7 @@ lookup_name_real (tree name, int prefer_type, int nonclass, /* A conversion operator can only be declared in a class scope. */ - if (level->parm_flag != 2) + if (level->kind != sk_class) continue; /* Lookup the conversion operator in the class. */ @@ -5911,11 +5852,9 @@ lookup_name_current_level (tree name) tree t = NULL_TREE; timevar_push (TV_NAME_LOOKUP); - b = current_binding_level; - while (b->parm_flag == 2) - b = b->level_chain; + b = innermost_nonclass_level (); - if (b->namespace_p) + if (b->kind == sk_namespace) { t = IDENTIFIER_NAMESPACE_VALUE (name); @@ -5949,7 +5888,8 @@ lookup_type_current_level (tree name) register tree t = NULL_TREE; timevar_push (TV_NAME_LOOKUP); - my_friendly_assert (! current_binding_level->namespace_p, 980716); + 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) @@ -5998,8 +5938,7 @@ record_builtin_type (enum rid rid_index, { tdecl = build_decl (TYPE_DECL, tname, type); DECL_ARTIFICIAL (tdecl) = 1; - if (tname) - SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl); + SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl); } if (rname) { @@ -6381,7 +6320,7 @@ cp_make_fname_decl (tree id, int type_dep) if (current_function_decl) { struct cp_binding_level *b = current_binding_level; - while (b->level_chain->parm_flag == 0) + while (b->level_chain->kind != sk_function_parms) b = b->level_chain; pushdecl_with_scope (decl, b); } @@ -7830,7 +7769,7 @@ maybe_inject_for_scope_var (tree decl) return; } - if (current_binding_level->is_for_scope) + if (current_binding_level->kind == sk_for) { struct cp_binding_level *outer = current_binding_level->level_chain; @@ -7853,7 +7792,7 @@ maybe_inject_for_scope_var (tree decl) { BINDING_VALUE (outer_binding) = DECL_SHADOWED_FOR_VAR (BINDING_VALUE (outer_binding)); - current_binding_level->is_for_scope = 0; + current_binding_level->kind = sk_block; } } timevar_pop (TV_NAME_LOOKUP); @@ -8144,8 +8083,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) if (DECL_FUNCTION_SCOPE_P (decl)) { /* This is a local declaration. */ - if (doing_semantic_analysis_p ()) - maybe_inject_for_scope_var (decl); + maybe_inject_for_scope_var (decl); /* Initialize the local variable. */ if (processing_template_decl) { @@ -13630,8 +13568,7 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) DECL_INTERFACE_KNOWN (decl1) = 1; } - pushlevel (0); - current_binding_level->parm_flag = 1; + begin_scope (sk_function_parms); ++function_depth; @@ -13752,9 +13689,6 @@ save_function_data (tree decl) f->bindings = NULL; f->x_local_names = NULL; - /* When we get back here again, we will be expanding. */ - f->x_expanding_p = 1; - /* If we've already decided that we cannot inline this function, we must remember that fact when we actually go to expand the function. */ @@ -14006,7 +13940,7 @@ finish_function (int flags) /* If the current binding level isn't the outermost binding level for this function, either there is a bug, or we have experienced syntax errors and the statement tree is malformed. */ - if (current_binding_level->parm_flag != 1) + if (current_binding_level->kind != sk_function_parms) { /* Make sure we have already experienced errors. */ if (errorcount == 0) @@ -14016,9 +13950,9 @@ finish_function (int flags) levels. */ DECL_SAVED_TREE (fndecl) = build_stmt (COMPOUND_STMT, NULL_TREE); - while (current_binding_level->parm_flag != 1) + while (current_binding_level->kind != sk_function_parms) { - if (current_binding_level->parm_flag == 2) + if (current_binding_level->kind == sk_class) pop_nested_class (); else poplevel (0, 0, 0); @@ -14211,8 +14145,7 @@ start_method (tree declspecs, tree declarator, tree attrlist) cp_finish_decl (fndecl, NULL_TREE, NULL_TREE, 0); /* Make a place for the parms */ - pushlevel (0); - current_binding_level->parm_flag = 1; + begin_scope (sk_function_parms); DECL_IN_AGGR_P (fndecl) = 1; return fndecl; @@ -14416,10 +14349,6 @@ cxx_push_function_context (struct function * f) = ggc_alloc_cleared (sizeof (struct language_function)); f->language = p; - /* It takes an explicit call to expand_body to generate RTL for a - function. */ - expanding_p = 0; - /* Whenever we start a new function, we destroy temporaries in the usual way. */ current_stmt_tree ()->stmts_are_full_exprs_p = 1; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b4ea1a1..4956b41 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2971,10 +2971,6 @@ nullify_returns_r (tree* tp, int* walk_subtrees, void* data) void cxx_expand_function_start (void) { - /* Let everybody know that we're expanding this function, not doing - semantic analysis. */ - expanding_p = 1; - /* Give our named return value the same RTL as our RESULT_DECL. */ if (current_function_return_value) COPY_DECL_RTL (DECL_RESULT (cfun->decl), current_function_return_value); diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index 57b10da..2f34664 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -47,6 +47,7 @@ extern bool lhd_post_options (const char **); extern HOST_WIDE_INT lhd_get_alias_set (tree); extern tree lhd_return_tree (tree); extern tree lhd_return_null_tree (tree); +extern tree lhd_do_nothing_iii_return_null_tree (int, int, int); extern int lhd_safe_from_p (rtx, tree); extern int lhd_staticp (tree); extern int lhd_unsafe_for_reeval (tree); diff --git a/gcc/langhooks.c b/gcc/langhooks.c index 2b9f0ec..6c74ed2 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -56,6 +56,16 @@ lhd_do_nothing_i (int i ATTRIBUTE_UNUSED) { } +/* Do nothing (int, int, int). Return NULL_TREE. */ + +tree +lhd_do_nothing_iii_return_null_tree (int i ATTRIBUTE_UNUSED, + int j ATTRIBUTE_UNUSED, + int k ATTRIBUTE_UNUSED) +{ + return NULL_TREE; +} + /* Do nothing (function). */ void diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 802d53e..d3dc2c0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2003-09-14 Mark Mitchell <mark@codesourcery.com> + PR c++/3907 + * g++.dg/parse/template12.C: New test. + * g++.dg/abi/bitfield11.C: New test. * g++.dg/abi/bitfield12.C: Likewise. diff --git a/gcc/testsuite/g++.dg/parse/template12.C b/gcc/testsuite/g++.dg/parse/template12.C new file mode 100644 index 0000000..ba375bc --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/template12.C @@ -0,0 +1,10 @@ +template <int J> +struct A { +}; + +struct B { + template <int I> + struct C : public A<I> {}; + + typedef double I; +}; |