re PR c++/3907 (nested template parm collides with member name)
authorMark Mitchell <mark@codesourcery.com>
Mon, 15 Sep 2003 00:59:28 +0000 (00:59 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 15 Sep 2003 00:59:28 +0000 (00:59 +0000)
* 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.

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.

PR c++/3907
* g++.dg/parse/template12.C: New test.

* g++.dg/abi/bitfield11.C: New test.
* g++.dg/abi/bitfield12.C: Likewise.

From-SVN: r71393

13 files changed:
gcc/ChangeLog
gcc/coverage.c
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-lang.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/semantics.c
gcc/langhooks-def.h
gcc/langhooks.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/template12.C [new file with mode: 0644]

index bf770b8..d7e7d64 100644 (file)
@@ -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
index 6facdce..e6f4129 100644 (file)
@@ -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);
 
index 3d2b3a5..374e7e5 100644 (file)
@@ -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
index bc7e3b8..214fbae 100644 (file)
@@ -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))
index 706ebbf..1809f2d 100644 (file)
@@ -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
index e71d53a..3e229a0 100644 (file)
@@ -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
index 8ab8c6c..1d126e8 100644 (file)
@@ -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);
index 6886fe4..92e8597 100644 (file)
@@ -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;
index b4ea1a1..4956b41 100644 (file)
@@ -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);
index 57b10da..2f34664 100644 (file)
@@ -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);
index 2b9f0ec..6c74ed2 100644 (file)
@@ -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
index 802d53e..d3dc2c0 100644 (file)
@@ -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 (file)
index 0000000..ba375bc
--- /dev/null
@@ -0,0 +1,10 @@
+template <int J>
+struct A {
+};
+
+struct B {
+  template <int I>
+  struct C : public A<I> {};
+
+  typedef double I;
+};