]> gcc.gnu.org Git - gcc.git/commitdiff
32nd Cygnus<->FSF merge
authorMike Stump <mrs@gcc.gnu.org>
Fri, 15 Apr 1994 01:44:15 +0000 (01:44 +0000)
committerMike Stump <mrs@gcc.gnu.org>
Fri, 15 Apr 1994 01:44:15 +0000 (01:44 +0000)
From-SVN: r7047

18 files changed:
gcc/cp/Makefile.in
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/gxxint.texi
gcc/cp/init.c
gcc/cp/lex.c
gcc/cp/lex.h
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/ptree.c
gcc/cp/search.c
gcc/cp/spew.c

index 90d72f11eacce0c168b4a69ba985c9e5a6a16c02..9b5b508570b9918ba3e7f8ab7f8c58d4681f718f 100644 (file)
@@ -200,7 +200,7 @@ parse.o : $(srcdir)/parse.c $(CONFIG_H) $(CXX_TREE_H) ../flags.h lex.h
   `echo $(srcdir)/parse.c | sed 's,^\./,,'`
 
 $(srcdir)/parse.c $(srcdir)/parse.h : $(srcdir)/parse.y
-       @echo expect 24 reduce/reduce conflicts.
+       @echo expect 33 reduce/reduce conflicts.
        cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y
        cd $(srcdir); grep '^#define[   ]*YYEMPTY' parse.c >>parse.h
 
index 5a1e161c00856ee9f82f07cd9aa9e8cd0419568c..261b16b24eabab91e3276076a8a57b45cfc24cac 100644 (file)
@@ -2673,10 +2673,7 @@ build_scoped_method_call (exp, scopes, name, parms)
        {
          /* Explicit call to destructor.  */
          name = TREE_OPERAND (name, 0);
-         if (TREE_TYPE (decl) !=
-             (IDENTIFIER_CLASS_VALUE (name)
-              ? IDENTIFIER_CLASS_TYPE_VALUE (name)
-              : IDENTIFIER_TYPE_VALUE (name)))
+         if (name != constructor_name (TREE_TYPE (decl)))
            {
              cp_error
                ("qualified type `%T' does not match destructor type `%T'",
@@ -2808,6 +2805,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
       /* If it doesn't work, two argument delete must work */
       TREE_CHAIN (parms) = save_last;
     }
+  /* We already know whether it's needed or not for vec delete.  */
+  else if (name == ansi_opname[(int) VEC_DELETE_EXPR]
+          && ! TYPE_VEC_DELETE_TAKES_SIZE (TREE_TYPE (instance)))
+    TREE_CHAIN (parms) = NULL_TREE;
 
   if (TREE_CODE (name) == BIT_NOT_EXPR)
     {
index 20116fe25ade522258c15e0af38cd9b67d6d225c..b60cdec641f00fe3a05bece5be4efbb91cf652a5 100644 (file)
@@ -2494,7 +2494,9 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
 
              for (x = *testp; x; x = DECL_CHAIN (x))
                {
-                 if (DECL_NAME (fn_fields) == ansi_opname[(int) DELETE_EXPR])
+                 if (DECL_NAME (fn_fields) == ansi_opname[(int) DELETE_EXPR]
+                     || DECL_NAME (fn_fields)
+                        == ansi_opname[(int) VEC_DELETE_EXPR])
                    {
                      /* ANSI C++ June 5 1992 WP 12.5.5.1 */
                      cp_error_at ("`%D' overloaded", fn_fields);
@@ -4149,8 +4151,10 @@ finish_struct (t, list_of_fieldlists, warn_anon)
   else if (flag_dossier && ! CLASSTYPE_DOSSIER (t))
     build_t_desc (t, 1);
 
+#if 0
   if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
     undo_template_name_overload (TYPE_IDENTIFIER (t), 1);
+#endif
   if (current_class_type)
     popclass (0);
   else
@@ -4426,10 +4430,7 @@ pushclass (type, modify)
        current_function_decl = NULL_TREE;
 
       if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE)
-        {
-          declare_uninstantiated_type_level ();
-         overload_template_name (current_class_name, 0);
-        }
+       declare_uninstantiated_type_level ();
       else if (type != previous_class_type || current_class_depth > 1)
        {
          build_mi_matrix (type);
@@ -4457,6 +4458,9 @@ pushclass (type, modify)
          unuse_fields (type);
        }
 
+      if (IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (type)))
+       overload_template_name (current_class_name, 0);
+
       for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags))
        {
          TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 1;
@@ -4513,9 +4517,9 @@ popclass (modify)
          TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
          tags = TREE_CHAIN (tags);
        }
+      if (IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type)))
+       undo_template_name_overload (current_class_name, 0);
     }
-  if (TREE_CODE (current_class_type) == UNINSTANTIATED_P_TYPE)
-    undo_template_name_overload (current_class_name, 0);
 
   poplevel_class ();
 
@@ -4583,7 +4587,12 @@ push_nested_class (type, modify)
      tree type;
      int modify;
 {
-  tree context = DECL_CONTEXT (TYPE_NAME (type));
+  tree context;
+
+  if (type == error_mark_node || ! IS_AGGR_TYPE (type))
+    return;
+  
+  context = DECL_CONTEXT (TYPE_NAME (type));
 
   if (context && TREE_CODE (context) == RECORD_TYPE)
     push_nested_class (context, 2);
index 3ddb359fcf740734af933adce94d3517902f847c..4f73664f24a7bcd1807825ace4fc1402374d3470 100644 (file)
@@ -32,6 +32,7 @@ DEFTREECODE (CP_OFFSET_REF, "cp_offset_ref", "r", 2)
    Operand 1 is the value to pass to the destroying function
    saying whether the store should be deallocated as well.  */
 DEFTREECODE (DELETE_EXPR, "dl_expr", "e", 2)
+DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", "e", 2)
 
 /* Value is reference to particular overloaded class method.
    Operand 0 is the class name (an IDENTIFIER_NODE);
@@ -52,6 +53,7 @@ DEFTREECODE (TYPE_EXPR, "type_expr", "e", 1)
    operand 1 is argument list to initialization function,
    and operand 2 is the slot which was allocated for this expression.  */
 DEFTREECODE (NEW_EXPR, "nw_expr", "e", 3)
+DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", "e", 3)
 
 /* Distinguish variables that are only used to identify exceptions
    that were caught.  Only the DECL_NAME (and TREE_CHAIN)
index e5a10db5b0f521785142fb47a536d96fdac3a7a3..1fb1bb17da07562af3051cd02b5c7563b5984e77 100644 (file)
@@ -68,10 +68,6 @@ struct lang_id2
 #define IDENTIFIER_TYPE_VALUE(NODE) (TREE_TYPE (NODE))
 #define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = TYPE)
 #define IDENTIFIER_HAS_TYPE_VALUE(NODE) (TREE_TYPE (NODE) ? 1 : 0)
-#define IDENTIFIER_HAS_CLASS_TYPE_VALUE(NODE) \
-  (IDENTIFIER_CLASS_VALUE (NODE) && TREE_TYPE (IDENTIFIER_CLASS_VALUE (NODE)))
-#define IDENTIFIER_CLASS_TYPE_VALUE(NODE) \
-  TREE_TYPE (IDENTIFIER_CLASS_VALUE (NODE))
 
 #define LANG_ID_FIELD(NAME,NODE) \
   (((struct lang_identifier *)(NODE))->x \
@@ -325,7 +321,7 @@ enum languages { lang_c, lang_cplusplus };
 #define TYPE_ASSEMBLER_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE))))
 
 #define IS_AGGR_TYPE(t)                (TYPE_LANG_FLAG_5 (t))
-#define IS_AGGR_TYPE_CODE(t)   (t == RECORD_TYPE || t == UNION_TYPE)
+#define IS_AGGR_TYPE_CODE(t)   (t == RECORD_TYPE || t == UNION_TYPE || t == UNINSTANTIATED_P_TYPE)
 #define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
   (TREE_CODE (TYPE1) == TREE_CODE (TYPE2)      \
    && IS_AGGR_TYPE (TYPE1)&IS_AGGR_TYPE (TYPE2))
@@ -395,14 +391,13 @@ struct lang_type
       unsigned vtable_needs_writing : 1;
 
       unsigned has_assign_ref : 1;
-      unsigned gets_new : 1;
-      unsigned gets_placed_new : 1;
-      unsigned gets_delete : 1;
+      unsigned gets_new : 2;
+      unsigned gets_delete : 2;
       unsigned has_call_overloaded : 1;
       unsigned has_array_ref_overloaded : 1;
       unsigned has_arrow_overloaded : 1;
-      unsigned local_typedecls : 1;
 
+      unsigned local_typedecls : 1;
       unsigned interface_only : 1;
       unsigned interface_unknown : 1;
       unsigned needs_virtual_reinit : 1;
@@ -410,16 +405,16 @@ struct lang_type
       unsigned declared_class : 1;
       unsigned being_defined : 1;
       unsigned redefined : 1;
-      unsigned no_globalize : 1;
 
+      unsigned no_globalize : 1;
       unsigned marked : 1;
       unsigned marked2 : 1;
       unsigned marked3 : 1;
       unsigned marked4 : 1;
       unsigned marked5 : 1;
       unsigned marked6 : 1;
-      unsigned use_template : 2;
 
+      unsigned use_template : 2;
       unsigned debug_requested : 1;
       unsigned has_method_call_overloaded : 1;
       unsigned private_attr : 1;
@@ -427,8 +422,8 @@ struct lang_type
       unsigned ptrmemfunc_flag : 1;
       unsigned is_signature : 1;
       unsigned is_signature_pointer : 1;
-      unsigned is_signature_reference : 1;
 
+      unsigned is_signature_reference : 1;
       unsigned has_default_implementation : 1;
       unsigned grokking_typedef : 1;
       unsigned has_opaque_typedecls : 1;
@@ -436,15 +431,16 @@ struct lang_type
       unsigned was_anonymous : 1;
       unsigned has_real_assignment : 1;
       unsigned has_real_assign_ref : 1;
+
       unsigned has_const_init_ref : 1;
-      
       unsigned has_complex_init_ref : 1;
       unsigned has_complex_assign_ref : 1;
+      unsigned vec_delete_takes_size : 1;
 
       /* The MIPS compiler gets it wrong if this struct also
         does not fill out to a multiple of 4 bytes.  Add a
         member `dummy' with new bits if you go over the edge.  */
-      unsigned dummy : 22;
+      unsigned dummy : 20;
 
       unsigned n_vancestors : 16;
     } type_flags;
@@ -519,9 +515,17 @@ struct lang_type
 
 /* Nonzero for _CLASSTYPE means that operator new and delete are defined,
    respectively.  */
-#define TREE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new)
-#define TREE_GETS_PLACED_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_placed_new)
-#define TREE_GETS_DELETE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_delete)
+#define TYPE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new)
+#define TYPE_GETS_DELETE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_delete)
+#define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1)
+
+/* Nonzero for _CLASSTYPE means that operator vec delete is defined and
+   takes the optional size_t argument.  */
+#define TYPE_VEC_DELETE_TAKES_SIZE(NODE) \
+  (TYPE_LANG_SPECIFIC(NODE)->type_flags.vec_delete_takes_size)
+#define TYPE_VEC_NEW_USES_COOKIE(NODE) \
+  (TYPE_NEEDS_DESTRUCTOR (NODE) \
+   || (TYPE_LANG_SPECIFIC (NODE) && TYPE_VEC_DELETE_TAKES_SIZE (NODE)))
 
 /* Nonzero for TREE_LIST or _TYPE node means that this node is class-local.  */
 #define TREE_NONLOCAL_FLAG(NODE) (TREE_LANG_FLAG_0 (NODE))
@@ -1972,7 +1976,7 @@ extern tree expand_vec_init                       PROTO((tree, tree, tree, tree, int));
 extern tree build_x_delete                     PROTO((tree, tree, int, tree));
 extern tree build_delete                       PROTO((tree, tree, tree, int, int));
 extern tree build_vbase_delete                 PROTO((tree, tree));
-extern tree build_vec_delete                   PROTO((tree, tree, tree, tree, tree, tree));
+extern tree build_vec_delete                   PROTO((tree, tree, tree, tree, tree, int));
 
 /* in input.c */
 
@@ -2081,6 +2085,7 @@ extern int do_pending_expansions          PROTO((void));
 extern void do_pending_templates               PROTO((void));
 struct tinst_level *tinst_for_decl             PROTO((void));
 extern void do_function_instantiation          PROTO((tree, tree));
+extern tree create_nested_upt                  PROTO((tree, tree));
 
 /* in search.c */
 extern tree make_memoized_table_entry          PROTO((tree, tree, int));
@@ -2092,6 +2097,7 @@ extern enum access_type compute_access            PROTO((tree, tree));
 extern tree lookup_field                       PROTO((tree, tree, int, int));
 extern tree lookup_nested_field                        PROTO((tree, int));
 extern tree lookup_fnfields                    PROTO((tree, tree, int));
+extern tree lookup_nested_tag                  PROTO((tree, tree));
 extern HOST_WIDE_INT breadth_first_search      PROTO((tree, int (*)(), int (*)()));
 extern int tree_needs_constructor_p            PROTO((tree, int));
 extern int tree_has_any_destructor_p           PROTO((tree, int));
@@ -2193,6 +2199,7 @@ extern int comp_target_types                      PROTO((tree, tree, int));
 extern tree common_base_types                  PROTO((tree, tree));
 extern int compparms                           PROTO((tree, tree, int));
 extern int comp_target_types                   PROTO((tree, tree, int));
+extern int self_promoting_args_p               PROTO((tree));
 extern tree unsigned_type                      PROTO((tree));
 extern tree signed_type                                PROTO((tree));
 extern tree signed_or_unsigned_type            PROTO((int, tree));
index fbe0d61a8650986962f3912ad5691830a7a45cfd..d19354d33ae0c6c065e57e81f7cebcc59f57faa8 100644 (file)
@@ -720,8 +720,16 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
     {
       /* When casting an lvalue to a reference type, just convert into
         a pointer to the new type and deference it.  This is allowed
-        by San Diego WP section 5.2.8 paragraph 9, though perhaps it
+        by San Diego WP section 5.2.9 paragraph 12, though perhaps it
         should be done directly (jason).  (int &)ri ---> *(int*)&ri */
+
+      /* B* bp; A& ar = (A&)bp; is legal, but it's probably not what they
+         meant.  */
+      if (form == POINTER_TYPE
+         && (comptypes (TREE_TYPE (intype), type, strict)))
+       cp_warning ("casting `%T' to `%T' does not dereference pointer",
+                   intype, reftype);
+         
       rval = build_unary_op (ADDR_EXPR, expr, 0);
       if (rval != error_mark_node)
        rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), rval);
@@ -744,6 +752,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
       
       /* Definitely need to go through a constructor here.  */
       if (TYPE_HAS_CONSTRUCTOR (type)
+         && ! CLASSTYPE_ABSTRACT_VIRTUALS (type)
          && (rval = build_method_call
              (NULL_TREE, constructor_name_full (type),
               build_tree_list (NULL_TREE, expr), TYPE_BINFO (type),
index 67812169a2e2d68c3515ef68187fe7f49ec222d1..3dce83c650eb8e81f30acd09d50283e19f8c83ac 100644 (file)
@@ -1964,7 +1964,8 @@ decls_match (newdecl, olddecl)
 {
   int types_match;
 
-  if (TREE_CODE (newdecl) == FUNCTION_DECL && TREE_CODE (olddecl) == FUNCTION_DECL)
+  if (TREE_CODE (newdecl) == FUNCTION_DECL
+      && TREE_CODE (olddecl) == FUNCTION_DECL)
     {
       tree f1 = TREE_TYPE (newdecl);
       tree f2 = TREE_TYPE (olddecl);
@@ -1997,10 +1998,19 @@ decls_match (newdecl, olddecl)
       if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (f1)),
                     TYPE_MAIN_VARIANT (TREE_TYPE (f2)), 2))
        {
-         if (DECL_LANGUAGE (olddecl) == lang_c
-             && ! strict_prototypes_lang_c
+         if (! strict_prototypes_lang_c && DECL_LANGUAGE (olddecl) == lang_c
              && p2 == NULL_TREE)
-           types_match = self_promoting_args_p (p1);
+           {
+             types_match = self_promoting_args_p (p1);
+             if (p1 == void_list_node)
+               TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
+           }
+         else if (!strict_prototypes_lang_c && DECL_LANGUAGE (olddecl)==lang_c
+                  && DECL_LANGUAGE (newdecl) == lang_c && p1 == NULL_TREE)
+           {
+             types_match = self_promoting_args_p (p2);
+             TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
+           }
          else
            types_match = compparms (p1, p2, 1);
        }
@@ -2249,12 +2259,7 @@ duplicate_decls (newdecl, olddecl)
             int foo () { bar (); }
             is OK.  */
          if (current_lang_stack == current_lang_base)
-           {
-             DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl);
-             if (TYPE_ARG_TYPES (TREE_TYPE (olddecl)) == NULL_TREE
-                 && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) == void_list_node)
-               TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
-           }
+           DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl);
          else
            {
              cp_error_at ("previous declaration of `%#D' with %L linkage",
@@ -2268,7 +2273,8 @@ duplicate_decls (newdecl, olddecl)
       if (pedantic
          && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
              || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl)))
-       cp_error_at ("type qualifiers for `%D' conflict with previous decl", newdecl);
+       cp_error_at ("type qualifiers for `%D' conflict with previous decl",
+                    newdecl);
     }
 
   /* If new decl is `static' and an `extern' was seen previously,
@@ -2318,7 +2324,8 @@ duplicate_decls (newdecl, olddecl)
                } Thing;
       */
 #if 0
-      my_friendly_assert (DECL_IGNORED_P (olddecl) == DECL_IGNORED_P (newdecl), 139);
+      my_friendly_assert (DECL_IGNORED_P (olddecl) == DECL_IGNORED_P (newdecl),
+                         139);
 #endif
     }
 
@@ -2363,9 +2370,10 @@ duplicate_decls (newdecl, olddecl)
          TREE_TYPE (olddecl) = build_exception_variant (ctype, newtype,
                                                         TYPE_RAISES_EXCEPTIONS (oldtype));
 
-         if (! compexcepttypes (TREE_TYPE (newdecl), TREE_TYPE(olddecl), 0))
+         if (! compexcepttypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl), 0))
            {
-             cp_error ("declaration of `%D' raises different exceptions...", newdecl);
+             cp_error ("declaration of `%D' raises different exceptions...",
+                       newdecl);
              cp_error_at ("...from previous declaration here", olddecl);
            }
        }
@@ -2683,7 +2691,8 @@ pushdecl (x)
 
                  if (extra_warnings)
                    {
-                     cp_warning ("`static' missing from declaration of `%D'", t);
+                     cp_warning ("`static' missing from declaration of `%D'",
+                                 t);
                      warning_with_file_and_line (file, line,
                                                  "previous declaration of `%s'",
                                                  decl_as_string (t, 0));
@@ -3176,8 +3185,11 @@ push_overloaded_decl (decl, forgettable)
            {
              if (decl == tmp || duplicate_decls (decl, tmp))
                return tmp;
-             if (compparms (TYPE_ARG_TYPES (TREE_TYPE (decl)),
-                            TYPE_ARG_TYPES (TREE_TYPE (tmp)), 2))
+             /* Avoid doing things about built-ins, since duplicate_decls
+                will have given warnings/errors for them.  */
+             if (!DECL_BUILT_IN (tmp) && !DECL_BUILT_IN_NONANSI (tmp)
+                 && compparms (TYPE_ARG_TYPES (TREE_TYPE (decl)),
+                               TYPE_ARG_TYPES (TREE_TYPE (tmp)), 2))
                {
                  cp_error ("new declaration `%#D'", decl);
                  cp_error_at ("ambiguates old declaration `%#D'", tmp);
@@ -3762,7 +3774,8 @@ lookup_nested_type (type, context)
          }
          break;
        case FUNCTION_DECL:
-         return TYPE_IDENTIFIER (type) ? lookup_name (TYPE_IDENTIFIER (type), 1) : NULL_TREE;
+         return TYPE_IDENTIFIER (type) ?
+           lookup_name (TYPE_IDENTIFIER (type), 1) : NULL_TREE;
          break;
        default:
          my_friendly_abort (12);
@@ -3778,6 +3791,7 @@ lookup_nested_type (type, context)
    definitions if there are many, or return 0 if it is undefined.
 
    If PREFER_TYPE is > 0, we prefer TYPE_DECLs.
+   If PREFER_TYPE is -2, we're being called from yylex(). (UGLY)
    Otherwise we prefer non-TYPE_DECLs.  */
 
 tree
@@ -3786,7 +3800,43 @@ lookup_name (name, prefer_type)
      int prefer_type;
 {
   register tree val;
+  int yylex = 0;
 
+  if (prefer_type == -2)
+    {
+      extern int looking_for_typename;
+
+      yylex = 1;
+      prefer_type = looking_for_typename;
+      
+      if (got_scope != NULL_TREE)
+       {
+         if (got_scope == void_type_node)
+           val = IDENTIFIER_GLOBAL_VALUE (name);
+         else if (TREE_CODE (got_scope) == TEMPLATE_TYPE_PARM
+                  /* TFIXME -- don't do this for UPTs in new model.  */
+                  || TREE_CODE (got_scope) == UNINSTANTIATED_P_TYPE)
+           {
+             if (prefer_type > 0)
+               val = create_nested_upt (got_scope, name);
+             else
+               val = NULL_TREE;
+           }
+         else if (! IS_AGGR_TYPE (got_scope))
+           /* Someone else will give an error about this if needed. */
+           val = NULL_TREE;
+         else if (got_scope == current_class_type)
+           val = IDENTIFIER_CLASS_VALUE (name);
+         else if (TYPE_BEING_DEFINED (got_scope))
+           val = lookup_nested_tag (got_scope, name);
+         else
+           val = lookup_field (got_scope, name, 0, 0);
+
+         got_scope = NULL_TREE;
+         goto done;
+       }
+    }
+    
   if (current_binding_level != global_binding_level
       && IDENTIFIER_LOCAL_VALUE (name))
     val = IDENTIFIER_LOCAL_VALUE (name);
@@ -3802,7 +3852,7 @@ lookup_name (name, prefer_type)
          /* Try to find values from base classes
             if we are presently defining a type.
             We are presently only interested in TYPE_DECLs.  */
-         val = lookup_field (current_class_type, name, 0, prefer_type < 0);
+         val = lookup_field (current_class_type, name, 0, 1);
          if (val == error_mark_node)
            return val;
          if (val && TREE_CODE (val) != TYPE_DECL)
@@ -3813,7 +3863,7 @@ lookup_name (name, prefer_type)
         the nested name at the point where we haven't even, for example,
         created the COMPONENT_REF or anything like that.  */
       if (val == NULL_TREE)
-       val = lookup_nested_field (name, prefer_type != -2);
+       val = lookup_nested_field (name, ! yylex);
 
       if (val == NULL_TREE)
        val = IDENTIFIER_GLOBAL_VALUE (name);
@@ -3821,21 +3871,19 @@ lookup_name (name, prefer_type)
   else
     val = IDENTIFIER_GLOBAL_VALUE (name);
 
+ done:
   if (val)
     {
-      extern int looking_for_typename;
-
       /* Arbitrate between finding a TYPE_DECL and finding
         other kinds of _DECLs.  */
-      if (TREE_CODE (val) == TYPE_DECL || looking_for_typename < 0)
+      if (TREE_CODE (val) == TYPE_DECL || prefer_type < 0)
        return val;
 
       if (IDENTIFIER_HAS_TYPE_VALUE (name))
        {
          register tree val_as_type = TYPE_NAME (IDENTIFIER_TYPE_VALUE (name));
 
-         if (val == val_as_type || prefer_type > 0
-             || looking_for_typename > 0)
+         if (val == val_as_type || prefer_type > 0)
            return val_as_type;
 
          return val;
@@ -4088,7 +4136,8 @@ init_decl_processing ()
   error_mark_list = build_tree_list (error_mark_node, error_mark_node);
   TREE_TYPE (error_mark_list) = error_mark_node;
 
-  pushlevel (0);       /* make the binding_level structure for global names.  */
+  /* Make the binding_level structure for global names.  */
+  pushlevel (0);
   global_binding_level = current_binding_level;
 
   this_identifier = get_identifier (THIS_NAME);
@@ -4229,7 +4278,8 @@ init_decl_processing ()
   TREE_TYPE (void_zero_node) = void_type_node;
 
   string_type_node = build_pointer_type (char_type_node);
-  const_string_type_node = build_pointer_type (build_type_variant (char_type_node, 1, 0));
+  const_string_type_node =
+    build_pointer_type (build_type_variant (char_type_node, 1, 0));
   record_builtin_type (RID_MAX, NULL_PTR, string_type_node);
 
   /* Make a type to be the domain of a few array types
@@ -4257,7 +4307,8 @@ init_decl_processing ()
   build_pointer_type (default_function_type);
 
   ptr_type_node = build_pointer_type (void_type_node);
-  const_ptr_type_node = build_pointer_type (build_type_variant (void_type_node, 1, 0));
+  const_ptr_type_node =
+    build_pointer_type (build_type_variant (void_type_node, 1, 0));
   record_builtin_type (RID_MAX, NULL_PTR, ptr_type_node);
   endlink = void_list_node;
   int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
@@ -4269,14 +4320,16 @@ init_decl_processing ()
 
   double_ftype_double_double
     = build_function_type (double_type_node,
-                          tree_cons (NULL_TREE, double_type_node, double_endlink));
+                          tree_cons (NULL_TREE, double_type_node,
+                                     double_endlink));
 
   int_ftype_int
     = build_function_type (integer_type_node, int_endlink);
 
   long_ftype_long
     = build_function_type (long_integer_type_node,
-                          tree_cons (NULL_TREE, long_integer_type_node, endlink));
+                          tree_cons (NULL_TREE, long_integer_type_node,
+                                     endlink));
 
   void_ftype_ptr_ptr_int
     = build_function_type (void_type_node,
@@ -4466,7 +4519,8 @@ init_decl_processing ()
       builtin_function ("memcmp", int_ftype_cptr_cptr_sizet, BUILT_IN_MEMCMP,
                        NULL_PTR);
       builtin_function ("strcmp", int_ftype_string_string, BUILT_IN_STRCMP, NULL_PTR);
-      builtin_function ("strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY, NULL_PTR);
+      builtin_function ("strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY,
+                       NULL_PTR);
 #if 0
       /* Not yet.  */
       builtin_function ("strncpy", strncpy_ftype, BUILT_IN_STRNCPY, NULL_PTR);
@@ -4481,13 +4535,19 @@ init_decl_processing ()
      or build_function_call.  */
   builtin_function ("__builtin_div", default_ftype, BUILT_IN_DIV, 0);
   builtin_function ("__builtin_ldiv", default_ftype, BUILT_IN_LDIV, 0);
-  builtin_function ("__builtin_ffloor", double_ftype_double, BUILT_IN_FFLOOR, 0);
+  builtin_function ("__builtin_ffloor", double_ftype_double, BUILT_IN_FFLOOR,
+                   0);
   builtin_function ("__builtin_fceil", double_ftype_double, BUILT_IN_FCEIL, 0);
-  builtin_function ("__builtin_fmod", double_ftype_double_double, BUILT_IN_FMOD, 0);
-  builtin_function ("__builtin_frem", double_ftype_double_double, BUILT_IN_FREM, 0);
-  builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int, BUILT_IN_MEMSET, 0);
-  builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP, 0);
-  builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN, 0);
+  builtin_function ("__builtin_fmod", double_ftype_double_double,
+                   BUILT_IN_FMOD, 0);
+  builtin_function ("__builtin_frem", double_ftype_double_double,
+                   BUILT_IN_FREM, 0);
+  builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int, BUILT_IN_MEMSET,
+                   0);
+  builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP,
+                   0);
+  builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN,
+                   0);
 #endif
 
   /* C++ extensions */
@@ -4507,7 +4567,7 @@ init_decl_processing ()
   TYPE_MODE (unknown_type_node) = TYPE_MODE (void_type_node);
   /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node.  */
   TREE_TYPE (unknown_type_node) = unknown_type_node;
-  /* Looking up TYPE_POINTER_TO and TYPE_REFERENCE_TO yield the same result.  */
+  /* Looking up TYPE_POINTER_TO and TYPE_REFERENCE_TO yield the same result. */
   TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
   TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;
 
@@ -4544,9 +4604,12 @@ init_decl_processing ()
      fields names so that the debugger can use them.  */
 
   memptr_type = make_lang_type (RECORD_TYPE);
-  fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier, delta_type_node);
-  fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier, delta_type_node);
-  fields[2] = build_lang_field_decl (FIELD_DECL, pfn_identifier, ptr_type_node);
+  fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier,
+                                    delta_type_node);
+  fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier,
+                                    delta_type_node);
+  fields[2] = build_lang_field_decl (FIELD_DECL, pfn_identifier,
+                                    ptr_type_node);
   finish_builtin_type (memptr_type, VTBL_PTR_TYPE, fields, 2,
                       double_type_node);
 
@@ -4588,9 +4651,15 @@ init_decl_processing ()
   if (flag_handle_signatures)
     {
       sigtable_entry_type = make_lang_type (RECORD_TYPE);
-      fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier (SIGTABLE_CODE_NAME), short_integer_type_node);
-      fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier (SIGTABLE_OFFSET_NAME), short_integer_type_node);
-      fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier (SIGTABLE_PFN_NAME), ptr_type_node);
+      fields[0] = build_lang_field_decl (FIELD_DECL,
+                                        get_identifier (SIGTABLE_CODE_NAME),
+                                        short_integer_type_node);
+      fields[1] = build_lang_field_decl (FIELD_DECL,
+                                        get_identifier (SIGTABLE_OFFSET_NAME),
+                                        short_integer_type_node);
+      fields[2] = build_lang_field_decl (FIELD_DECL,
+                                        get_identifier (SIGTABLE_PFN_NAME),
+                                        ptr_type_node);
       finish_builtin_type (sigtable_entry_type, SIGTABLE_PTR_TYPE, fields, 2,
                           double_type_node);
       sigtable_entry_type = build_type_variant (sigtable_entry_type, 1, 0);
@@ -4620,9 +4689,12 @@ init_decl_processing ()
       __t_desc_type_node = make_lang_type (RECORD_TYPE);
       __i_desc_type_node = make_lang_type (RECORD_TYPE);
       __m_desc_type_node = make_lang_type (RECORD_TYPE);
-      __t_desc_array_type = build_array_type (TYPE_POINTER_TO (__t_desc_type_node), NULL_TREE);
-      __i_desc_array_type = build_array_type (TYPE_POINTER_TO (__i_desc_type_node), NULL_TREE);
-      __m_desc_array_type = build_array_type (TYPE_POINTER_TO (__m_desc_type_node), NULL_TREE);
+      __t_desc_array_type =
+       build_array_type (TYPE_POINTER_TO (__t_desc_type_node), NULL_TREE);
+      __i_desc_array_type =
+       build_array_type (TYPE_POINTER_TO (__i_desc_type_node), NULL_TREE);
+      __m_desc_array_type =
+       build_array_type (TYPE_POINTER_TO (__m_desc_type_node), NULL_TREE);
 
       fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("name"),
                                         string_type_node);
@@ -4630,7 +4702,8 @@ init_decl_processing ()
                                         unsigned_type_node);
       fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("bits"),
                                         unsigned_type_node);
-      fields[3] = build_lang_field_decl (FIELD_DECL, get_identifier ("points_to"),
+      fields[3] = build_lang_field_decl (FIELD_DECL,
+                                        get_identifier ("points_to"),
                                         TYPE_POINTER_TO (__t_desc_type_node));
       fields[4] = build_lang_field_decl (FIELD_DECL,
                                         get_identifier ("ivars_count"),
@@ -4666,7 +4739,8 @@ init_decl_processing ()
                                         integer_type_node);
       fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("type"),
                                         TYPE_POINTER_TO (__t_desc_type_node));
-      finish_builtin_type (__i_desc_type_node, "__i_desc", fields, 2, integer_type_node);
+      finish_builtin_type (__i_desc_type_node, "__i_desc", fields, 2,
+                          integer_type_node);
 
       /* method descriptors look like this:
 
@@ -4699,7 +4773,8 @@ init_decl_processing ()
                                         short_integer_type_node);
       fields[7] = build_lang_field_decl (FIELD_DECL, get_identifier ("parm_types"),
                                         build_pointer_type (build_array_type (TYPE_POINTER_TO (__t_desc_type_node), NULL_TREE)));
-      finish_builtin_type (__m_desc_type_node, "__m_desc", fields, 7, integer_type_node);
+      finish_builtin_type (__m_desc_type_node, "__m_desc", fields, 7,
+                          integer_type_node);
     }
 
   /* Now, C++.  */
@@ -4720,11 +4795,21 @@ init_decl_processing ()
                                      tree_cons (NULL_TREE, sizetype,
                                                 void_list_node)),
                 NOT_BUILT_IN);
+  auto_function (ansi_opname[(int) VEC_NEW_EXPR],
+                build_function_type (ptr_type_node,
+                                     tree_cons (NULL_TREE, sizetype,
+                                                void_list_node)),
+                NOT_BUILT_IN);
   auto_function (ansi_opname[(int) DELETE_EXPR],
                 build_function_type (void_type_node,
                                      tree_cons (NULL_TREE, ptr_type_node,
                                                 void_list_node)),
                 NOT_BUILT_IN);
+  auto_function (ansi_opname[(int) VEC_DELETE_EXPR],
+                build_function_type (void_type_node,
+                                     tree_cons (NULL_TREE, ptr_type_node,
+                                                void_list_node)),
+                NOT_BUILT_IN);
 
   abort_fndecl
     = define_function ("abort",
@@ -4889,7 +4974,8 @@ shadow_tag (declspecs)
         function members.  */
       if (TYPE_FIELDS (t))
        {
-         tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0, NULL_TREE);
+         tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0,
+                                     NULL_TREE);
          finish_anon_union (decl);
        }
       else
@@ -4982,7 +5068,8 @@ start_decl (declarator, declspecs, initialized, raises)
   /* This should only be done once on the top most decl. */
   if (have_extern_spec && !used_extern_spec)
     {
-      declspecs = decl_tree_cons (NULL_TREE, get_identifier ("extern"), declspecs);
+      declspecs = decl_tree_cons (NULL_TREE, get_identifier ("extern"),
+                                 declspecs);
       used_extern_spec = 1;
     }
 
@@ -5057,9 +5144,11 @@ start_decl (declarator, declspecs, initialized, raises)
           DECL_ARGUMENTS (decl) = args;
         }
       d = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), TREE_TYPE (decl));
-      if (interface_unknown && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl))
+      if (interface_unknown && flag_external_templates
+         && ! DECL_IN_SYSTEM_HEADER (decl))
        warn_if_unknown_interface ();
-      TREE_PUBLIC (d) = TREE_PUBLIC (decl) = flag_external_templates && !interface_unknown;
+      TREE_PUBLIC (d) = TREE_PUBLIC (decl) =
+       flag_external_templates && !interface_unknown;
       TREE_STATIC (d) = TREE_STATIC (decl);
       DECL_EXTERNAL (d) = (DECL_EXTERNAL (decl)
                           && !(context && !DECL_THIS_EXTERN (decl)));
@@ -5251,7 +5340,8 @@ start_decl (declarator, declspecs, initialized, raises)
         use temporary storage.  Do this even if we will ignore the value.  */
       if (current_binding_level == global_binding_level && debug_temp_inits)
        {
-         if (TYPE_NEEDS_CONSTRUCTING (type) || TREE_CODE (type) == REFERENCE_TYPE)
+         if (TYPE_NEEDS_CONSTRUCTING (type)
+             || TREE_CODE (type) == REFERENCE_TYPE)
            /* In this case, the initializer must lay down in permanent
               storage, since it will be saved until `finish_file' is run.   */
            ;
@@ -5463,7 +5553,8 @@ grok_reference_init (decl, type, init, cleanupp)
          TREE_OPERAND (TREE_OPERAND (tmp, 0), 2) = error_mark_node;
        }
       if (IS_AGGR_TYPE (TREE_TYPE (this_ptr_type)))
-       DECL_INITIAL (decl) = convert_pointer_to (TREE_TYPE (this_ptr_type), tmp);
+       DECL_INITIAL (decl) = convert_pointer_to (TREE_TYPE (this_ptr_type),
+                                                 tmp);
       else
        DECL_INITIAL (decl) = convert (this_ptr_type, tmp);
 
@@ -5481,7 +5572,8 @@ grok_reference_init (decl, type, init, cleanupp)
       if (TREE_CODE (actual_init) == ADDR_EXPR
          && TREE_CODE (TREE_OPERAND (actual_init, 0)) == TARGET_EXPR)
        actual_init = save_expr (actual_init);
-      DECL_INITIAL (decl) = convert_pointer_to (TREE_TYPE (this_ptr_type), actual_init);
+      DECL_INITIAL (decl) = convert_pointer_to (TREE_TYPE (this_ptr_type),
+                                               actual_init);
       DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl));
       TREE_TYPE (DECL_INITIAL (decl)) = type;
     }
@@ -5689,7 +5781,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
            {
              if (TYPE_NEEDS_CONSTRUCTING (type))
                {
-                 cp_error ("`%D' must be initialized by constructor, not by `{...}'", decl);
+                 cp_error ("`%D' must be initialized by constructor, not by `{...}'",
+                           decl);
                  init = error_mark_node;
                }
              else
@@ -5780,7 +5873,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
          if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (ctype))
            cp_error ("structure `%D' with uninitialized const members", decl);
          if (CLASSTYPE_REF_FIELDS_NEED_INIT (ctype))
-           cp_error ("structure `%D' with uninitialized reference members", decl);
+           cp_error ("structure `%D' with uninitialized reference members",
+                     decl);
        }
 
       if (TREE_CODE (decl) == VAR_DECL
@@ -6002,9 +6096,6 @@ finish_decl (decl, init, asmspec_tree, need_pop)
            }
          else if (toplev)
            {
-             /* Keep GCC from complaining that this variable
-                is defined but never used.  */
-             TREE_USED (decl) = 1;
              /* If this is a static const, change its apparent linkage
                 if it belongs to a #pragma interface.  */
              if (TREE_STATIC (decl) && !interface_unknown)
@@ -6092,7 +6183,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
                        : & TYPE_ARG_TYPES (type);
 
                      *argp = NULL_TREE;
-                     fnname = build_decl_overload (original_name, TYPE_ARG_TYPES (type), 0);
+                     fnname = build_decl_overload (original_name,
+                                                   TYPE_ARG_TYPES (type), 0);
                      *argp = parmtypes;
                      fndecl = build_decl (FUNCTION_DECL, fnname, type);
                      DECL_EXTERNAL (fndecl) = DECL_EXTERNAL (decl);
@@ -6169,7 +6261,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
 
              if (init || TYPE_NEEDS_CONSTRUCTING (type))
                {
-                 emit_line_note (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
+                 emit_line_note (DECL_SOURCE_FILE (decl),
+                                 DECL_SOURCE_LINE (decl));
                  expand_aggr_init (decl, init, 0);
                }
 
@@ -6182,7 +6275,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
              if (cleanup)
                {
                  if (! expand_decl_cleanup (decl, cleanup))
-                   cp_error ("parser lost in parsing declaration of `%D'", decl);
+                   cp_error ("parser lost in parsing declaration of `%D'",
+                             decl);
                }
            }
        }
@@ -6380,7 +6474,8 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
   if (inlinep)
     cp_error ("`%D' declared as an `inline' %s", object, type);
   if (quals)
-    cp_error ("`const' and `volatile' function specifiers on `%D' invalid in %s declaration", object, type);
+    cp_error ("`const' and `volatile' function specifiers on `%D' invalid in %s declaration",
+             object, type);
   if (friendp)
     cp_error_at ("invalid friend declaration", object);
   if (raises)
@@ -6399,7 +6494,8 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
    CHECK is 1 if we must find this method in CTYPE, 0 if we should
    not look, and -1 if we should not call `grokclassfn' at all.  */
 static tree
-grokfndecl (ctype, type, declarator, virtualp, flags, quals, raises, check, publicp)
+grokfndecl (ctype, type, declarator, virtualp, flags, quals,
+           raises, check, publicp)
      tree ctype, type;
      tree declarator;
      int virtualp;
@@ -6530,7 +6626,8 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals, raises, check, publ
        for (i = 0; i < n_baselinks; i++)
          {
            tree base_binfo = TREE_VEC_ELT (binfos, i);
-           if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo)) || flag_all_virtual == 1)
+           if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo))
+               || flag_all_virtual == 1)
              {
                tmp = get_first_matching_virtual (base_binfo, decl,
                                                  flags == DTOR_FLAG);
@@ -6547,8 +6644,10 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals, raises, check, publ
                       path to its virtual baseclass.  */
                    if (staticp)
                      {
-                       cp_error ("method `%D' may not be declared static", decl);
-                       cp_error_at ("(since `%D' declared virtual in base class.)", tmp);
+                       cp_error ("method `%D' may not be declared static",
+                                 decl);
+                       cp_error_at ("(since `%D' declared virtual in base class.)",
+                                    tmp);
                        break;
                      }
                    virtualp = 1;
@@ -6716,7 +6815,8 @@ build_ptrmemfunc_type (type)
 
   u = make_lang_type (UNION_TYPE);
   fields[0] = build_lang_field_decl (FIELD_DECL, pfn_identifier, type);
-  fields[1] = build_lang_field_decl (FIELD_DECL, delta2_identifier, delta_type_node);
+  fields[1] = build_lang_field_decl (FIELD_DECL, delta2_identifier,
+                                    delta_type_node);
   finish_builtin_type (u, "__ptrmemfunc_type", fields, 1, ptr_type_node);
   TYPE_NAME (u) = NULL_TREE;
 
@@ -6725,8 +6825,10 @@ build_ptrmemfunc_type (type)
   /* Let the front-end know this is a pointer to member function. */
   TYPE_PTRMEMFUNC_FLAG(t) = 1;
 
-  fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier, delta_type_node);
-  fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier, delta_type_node);
+  fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier,
+                                    delta_type_node);
+  fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier,
+                                    delta_type_node);
   fields[2] = build_lang_field_decl (FIELD_DECL, pfn_or_delta2_identifier, u);
   finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node);
 
@@ -6839,7 +6941,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
   tree ctype = current_class_type;
   tree ctor_return_type = NULL_TREE;
   enum overload_flags flags = NO_SPECIAL;
-  int seen_scope_ref = 0;
   tree quals = NULL_TREE;
 
   RIDBIT_RESET_ALL (specbits);
@@ -6957,7 +7058,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
          dname = decl;
          decl = NULL_TREE;
 
-         if (IDENTIFIER_TYPENAME_P (dname))
+         /* This may just be a variable starting with __op.  */
+         if (IDENTIFIER_TYPENAME_P (dname) && TREE_TYPE (dname))
            {
              my_friendly_assert (flags == NO_SPECIAL, 154);
              flags = TYPENAME_FLAG;
@@ -6987,11 +7089,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
 
          /* C++ extension */
        case SCOPE_REF:
-/*
-         if (seen_scope_ref == 1)
-           error ("multiple `::' terms in declarator invalid");
-*/
-         seen_scope_ref += 1;
          {
            /* Perform error checking, and convert class names to types.
               We may call grokdeclarator multiple times for the same
@@ -7239,14 +7336,24 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
        }
       else
        {
-         if (funcdef_flag && warn_return_type
-             && return_type == return_normal
-             && ! (RIDBIT_SETP (RID_SIGNED, specbits)
-                   || RIDBIT_SETP (RID_UNSIGNED, specbits)
-                   || RIDBIT_SETP (RID_LONG, specbits)
-                   || RIDBIT_SETP (RID_SHORT, specbits)))
-           warn_about_return_type = 1;
-         /* Save warning until we know what is really going on.  */
+         if (funcdef_flag)
+           {
+             if (warn_return_type
+                 && return_type == return_normal
+                 && ! (RIDBIT_SETP (RID_SIGNED, specbits)
+                       || RIDBIT_SETP (RID_UNSIGNED, specbits)
+                       || RIDBIT_SETP (RID_LONG, specbits)
+                       || RIDBIT_SETP (RID_SHORT, specbits)))
+               /* Save warning until we know what is really going on.  */
+               warn_about_return_type = 1;
+           }
+         else if (class_binding_level && declarator
+                  && TREE_CODE (declarator) == SCOPE_REF)
+           /* OK -- access declaration */;
+         else if (declspecs == NULL_TREE &&
+                  (innermost_code != CALL_EXPR || pedantic))
+           cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type or storage class",
+                       dname);
          type = integer_type_node;
        }
     }
@@ -7486,7 +7593,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
        }
       if (volatilep)
        {
-         error ("`volatile' specified for signature member function `%s'", name);
+         error ("`volatile' specified for signature member function `%s'",
+                name);
          volatilep = 0;
        }
       if (inlinep)
@@ -7502,7 +7610,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
        }
       if (virtualp)
        {
-         error ("`virtual' specified for signature member function `%s'", name);
+         error ("`virtual' specified for signature member function `%s'",
+                name);
          /* Later, we'll make signature member functions virtual.  */
          virtualp = 0;
        }
@@ -7816,7 +7925,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                else
                  {
                    if (pedantic)
-                     cp_pedwarn ("ANSI C++ forbids variable-size array `%D'", dname);
+                     cp_pedwarn ("ANSI C++ forbids variable-size array `%D'",
+                                 dname);
                  dont_grok_size:
                    itype =
                      build_binary_op (MINUS_EXPR, size, integer_one_node, 1);
@@ -8177,11 +8287,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
              /* don't fall out into global scope. Hides real bug? --eichin */ ;
            else if (TREE_COMPLEXITY (declarator) == current_class_depth)
              {
-               /* I'm not really sure what pushclass calls this popclass
-                  corresponds to.  One is in build_push_scope and that has
-                  been changed to a push_nested_class call, that's why I
-                  try to use pop_nested_class here instead.
-                  -niklas@appli.se */
+               /* This pop_nested_class corresponds to the
+                   push_nested_class used to push into class scope for
+                   parsing the argument list of a function decl, in
+                   qualified_id.  */
                pop_nested_class (1);
                TREE_COMPLEXITY (declarator) = current_class_depth;
              }
@@ -8631,7 +8740,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                  }
 
                if (declarator == ansi_opname[(int) NEW_EXPR]
-                   || declarator == ansi_opname[(int) DELETE_EXPR])
+                   || declarator == ansi_opname[(int) VEC_NEW_EXPR]
+                   || declarator == ansi_opname[(int) DELETE_EXPR]
+                   || declarator == ansi_opname[(int) VEC_DELETE_EXPR])
                  {
                    if (virtualp)
                      {
@@ -9328,7 +9439,8 @@ grok_ctor_properties (ctype, decl)
 }
 
 /* An operator with this name can be either unary or binary.  */
-int ambi_op_p (name)
+static int
+ambi_op_p (name)
      tree name;
 {
   return (name == ansi_opname [(int) INDIRECT_REF]
@@ -9340,7 +9452,8 @@ int ambi_op_p (name)
 }
 
 /* An operator with this name can only be unary.  */
-int unary_op_p (name)
+static int
+unary_op_p (name)
      tree name;
 {
   return (name == ansi_opname [(int) TRUTH_NOT_EXPR]
@@ -9358,44 +9471,39 @@ grok_op_properties (decl, virtualp, friendp)
   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
   int methodp = (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE);
   tree name = DECL_NAME (decl);
-  tree t;
 
-  if (! friendp)
-    for (t = current_class_type; t; t = TYPE_NEXT_VARIANT (t))
-      {
-       if (name == ansi_opname[(int) MODIFY_EXPR])
-         TYPE_HAS_ASSIGNMENT (t) = 1;
-       else if (name == ansi_opname[(int) CALL_EXPR])
-         TYPE_OVERLOADS_CALL_EXPR (t) = 1;
-       else if (name == ansi_opname[(int) ARRAY_REF])
-         TYPE_OVERLOADS_ARRAY_REF (t) = 1;
-       else if (name == ansi_opname[(int) COMPONENT_REF]
-                || name == ansi_opname[(int) MEMBER_REF])
-         TYPE_OVERLOADS_ARROW (t) = 1;
-       else if (name == ansi_opname[(int) NEW_EXPR])
-         {
-           if (TREE_CHAIN (argtypes) == void_list_node)
-             TREE_GETS_NEW (t) = 1;
-           else
-             TREE_GETS_PLACED_NEW (t) = 1;
-         }
-       else if (name == ansi_opname[(int) DELETE_EXPR])
-         TREE_GETS_DELETE (t) = 1;
-#if 0
-       else if (name == ansi_opname[(int) VEC_NEW_EXPR])
-         TREE_GETS_NEW (t) = 1;
-       else if (name == ansi_opname[(int) VEC_DELETE_EXPR])
-         TREE_GETS_DELETE (t) = 1;
-#endif
-      }
+  if (current_class_type == NULL_TREE)
+    friendp = 1;
 
-  if (name == ansi_opname[(int) NEW_EXPR])
+  if (! friendp)
+    {
+      if (name == ansi_opname[(int) MODIFY_EXPR])
+       TYPE_HAS_ASSIGNMENT (current_class_type) = 1;
+      else if (name == ansi_opname[(int) CALL_EXPR])
+       TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1;
+      else if (name == ansi_opname[(int) ARRAY_REF])
+       TYPE_OVERLOADS_ARRAY_REF (current_class_type) = 1;
+      else if (name == ansi_opname[(int) COMPONENT_REF]
+              || name == ansi_opname[(int) MEMBER_REF])
+       TYPE_OVERLOADS_ARROW (current_class_type) = 1;
+      else if (name == ansi_opname[(int) NEW_EXPR])
+       TYPE_GETS_NEW (current_class_type) |= 1;
+      else if (name == ansi_opname[(int) DELETE_EXPR])
+       TYPE_GETS_DELETE (current_class_type) |= 1;
+      else if (name == ansi_opname[(int) VEC_NEW_EXPR])
+       TYPE_GETS_NEW (current_class_type) |= 2;
+      else if (name == ansi_opname[(int) VEC_DELETE_EXPR])
+       TYPE_GETS_DELETE (current_class_type) |= 2;
+    }
+
+  if (name == ansi_opname[(int) NEW_EXPR]
+      || name == ansi_opname[(int) VEC_NEW_EXPR])
     {
-#if 0
       /* When the compiler encounters the definition of A::operator new, it
         doesn't look at the class declaration to find out if it's static.  */
-      my_friendly_assert (!methodp, 355);
-#endif
+      if (methodp)
+       revert_static_member_fn (&TREE_TYPE (decl), &decl,
+                                &TYPE_ARG_TYPES (TREE_TYPE (decl)));
      
       /* Take care of function decl if we had syntax errors.  */
       if (argtypes == NULL_TREE)
@@ -9404,18 +9512,14 @@ grok_op_properties (decl, virtualp, friendp)
                               hash_tree_chain (integer_type_node,
                                                void_list_node));
       else
-       decl = coerce_new_type (TREE_TYPE (decl));
+       TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
     }
-#if 0
-  else if (name == ansi_opname[(int) VEC_NEW_EXPR])
-    {
-    }
-#endif
-  else if (name == ansi_opname[(int) DELETE_EXPR])
+  else if (name == ansi_opname[(int) DELETE_EXPR]
+          || name == ansi_opname[(int) VEC_DELETE_EXPR])
     {
-#if 0
-      my_friendly_assert (!methodp, 355);
-#endif
+      if (methodp)
+       revert_static_member_fn (&TREE_TYPE (decl), &decl,
+                                &TYPE_ARG_TYPES (TREE_TYPE (decl)));
      
       if (argtypes == NULL_TREE)
        TREE_TYPE (decl) =
@@ -9423,13 +9527,15 @@ grok_op_properties (decl, virtualp, friendp)
                               hash_tree_chain (ptr_type_node,
                                                void_list_node));
       else
-       decl = coerce_delete_type (TREE_TYPE (decl));
-    }
-#if 0
-  else if (name == ansi_opname[(int) VEC_DELETE_EXPR])
-    {
+       {
+         TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
+
+         if (! friendp && name == ansi_opname[(int) VEC_DELETE_EXPR]
+             && (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)))
+                 != void_list_node))
+           TYPE_VEC_DELETE_TAKES_SIZE (current_class_type) = 1;
+       }
     }
-#endif
   else
     {
       /* An operator function must either be a non-static member function
@@ -9484,8 +9590,9 @@ grok_op_properties (decl, virtualp, friendp)
          parmtype = TREE_VALUE (TREE_CHAIN (argtypes));
 
          if (TREE_CODE (parmtype) == REFERENCE_TYPE
-             && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype))
-             == current_class_type)
+             && (TYPE_MAIN_VARIANT (TREE_TYPE (parmtype))
+                 == current_class_type)
+             && ! friendp)
            {
              TYPE_HAS_ASSIGN_REF (current_class_type) = 1;
              if (TYPE_READONLY (TREE_TYPE (parmtype)))
@@ -9957,9 +10064,8 @@ if (CLASSTYPE_N_BASECLASSES (basetype) == NULL_TREE
                }
 
              TYPE_OVERLOADS_METHOD_CALL_EXPR (ref) |= TYPE_OVERLOADS_METHOD_CALL_EXPR (basetype);
-             TREE_GETS_NEW (ref) |= TREE_GETS_NEW (basetype);
-             TREE_GETS_PLACED_NEW (ref) |= TREE_GETS_PLACED_NEW (basetype);
-             TREE_GETS_DELETE (ref) |= TREE_GETS_DELETE (basetype);
+             TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype);
+             TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
              CLASSTYPE_LOCAL_TYPEDECLS (ref) |= CLASSTYPE_LOCAL_TYPEDECLS (basetype);
              i += 1;
            }
@@ -10439,7 +10545,8 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
          /* If this doesn't return integer_type, complain.  */
          if (TREE_TYPE (TREE_TYPE (decl1)) != integer_type_node)
            {
-             warning ("return type for `main' changed to integer type");
+             if (pedantic || warn_return_type)
+               warning ("return type for `main' changed to integer type");
              TREE_TYPE (decl1) = fntype = default_function_type;
            }
          warn_about_return_type = 0;
@@ -11040,7 +11147,7 @@ finish_function (lineno, call_poplevel)
 
       /* These are two cases where we cannot delegate deletion.  */
       if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)
-         || TREE_GETS_DELETE (current_class_type))
+         || TYPE_GETS_REG_DELETE (current_class_type))
        exprstmt = build_delete (current_class_type, C_C_D, integer_zero_node,
                                 LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
       else
@@ -11096,7 +11203,7 @@ finish_function (lineno, call_poplevel)
       virtual_size = c_sizeof (current_class_type);
 
       /* At the end, call delete if that's what's requested.  */
-      if (TREE_GETS_DELETE (current_class_type))
+      if (TYPE_GETS_REG_DELETE (current_class_type))
        /* This NOP_EXPR means we are in a static call context.  */
        exprstmt =
          build_method_call
@@ -11216,7 +11323,7 @@ finish_function (lineno, call_poplevel)
              expand_decl_init (allocated_this);
              /* How we cleanup `this' if an exception was raised before
                 we are ready to bail out.  */
-             cleanup = TREE_GETS_DELETE (current_class_type)
+             cleanup = TYPE_GETS_REG_DELETE (current_class_type)
                ? build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, allocated_this, virtual_size, NULL_TREE)
                  /* The size of allocated_this is wrong, and hence the
                     second argument to operator delete will be wrong. */
index 2177713958c4f6dadd391bfeb03bc3a3eb3a5459..aad0c15fe9f3d4c63c3b5332019c7d3ed1081874 100644 (file)
@@ -1071,6 +1071,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
       return error_mark_node;
     }
 
+#if 0
   /* If the type has no destructor, then we should build a regular
      delete, instead of a vector delete.  Otherwise, we would end
      up passing a bogus offset into __builtin_delete, which is
@@ -1082,15 +1083,15 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
       doing_vec = 0;
       use_global_delete = 1;
     }
+#endif
 
   if (doing_vec)
-    return build_vec_delete (t, maxindex, elt_size, NULL_TREE,
-                            integer_one_node, integer_two_node);
+    return build_vec_delete (t, maxindex, elt_size, integer_one_node,
+                            integer_two_node, use_global_delete);
   else
     return build_delete (type, t, integer_three_node,
                         LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE,
-                        use_global_delete
-                        || TYPE_HAS_DESTRUCTOR (TREE_TYPE (type)));
+                        use_global_delete);
 }
 
 /* Sanity check: report error if this function FUNCTION is not
@@ -1456,6 +1457,7 @@ grokbitfield (declarator, declspecs, width)
   return value;
 }
 
+#if 0
 /* Like GROKFIELD, except that the declarator has been
    buried in DECLSPECS.  Find the declarator, and
    return something that looks like it came from
@@ -1634,6 +1636,7 @@ groktypefield (declspecs, parmlist)
   DECL_IN_AGGR_P (decl) = 1;
   return decl;
 }
+#endif
 
 tree
 grokoptypename (declspecs, declarator)
@@ -2278,7 +2281,7 @@ coerce_delete_type (type)
   else if (e3 |= e2)
     {
       if (arg_types == NULL_TREE)
-       arg_types = void_list_node;
+       arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
       else
        arg_types = tree_cons (NULL_TREE, ptr_type_node, TREE_CHAIN (arg_types));
     }
@@ -2853,7 +2856,11 @@ reparse_decl_as_expr1 (decl)
     case BIT_NOT_EXPR:
       return build_x_unary_op (BIT_NOT_EXPR,
                               reparse_decl_as_expr1 (TREE_OPERAND (decl, 0)));
-
+    case SCOPE_REF:
+      return build_offset_ref (TREE_OPERAND (decl, 0), TREE_OPERAND (decl, 1));
+    case ARRAY_REF:
+      return grok_array_decl (reparse_decl_as_expr1 (TREE_OPERAND (decl, 0)),
+                             TREE_OPERAND (decl, 1));
     default:
       my_friendly_abort (5);
       return NULL_TREE;
@@ -2901,6 +2908,9 @@ finish_decl_parsing (decl)
       push_nested_class (TREE_OPERAND (decl, 0), 3);
       TREE_COMPLEXITY (decl) = current_class_depth;
       return decl;
+    case ARRAY_REF:
+      TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0));
+      return decl;
     default:
       my_friendly_abort (5);
       return NULL_TREE;
index 1878c86a5142074430a9663f0d06441955ed0bf8..d27fe70c791715e44ad748635b65e6f5e433265c 100644 (file)
@@ -1059,17 +1059,18 @@ It is ambiguous whether @code{class T} should be parsed as the
 declaration of a template type parameter named @code{T} or an unnamed
 constant parameter of type @code{class T}.  Section 14.6, paragraph 3 of
 the January '94 working paper states that the first interpretation is
-the correct one.  This ambiguity results in four reduce/reduce conflicts.
+the correct one.  This ambiguity results in two reduce/reduce conflicts.
 
-2) Between @code{primary} and @code{typename} for code like @samp{int()}
+2) Between @code{primary} and @code{type_id} for code like @samp{int()}
 in places where both can be accepted, such as the argument to
 @code{sizeof}.  Section 8.1 of the pre-San Diego working paper specifies
 that these ambiguous constructs will be interpreted as @code{typename}s.
-This ambiguity results in six reduce/reduce conflicts.
+This ambiguity results in six reduce/reduce conflicts between
+@samp{absdcl} and @samp{functional_cast}.
 
-3) Between @code{primary}/@code{functional_cast} and
-@code{expr_or_declarator}/@code{complex_direct_notype_declarator}, for
-various token strings.  This situation occurs in code looking like
+3) Between @code{functional_cast} and
+@code{complex_direct_notype_declarator}, for various token strings.
+This situation occurs in code looking like
 
 @example
 int (*a);
@@ -1078,11 +1079,23 @@ int (*a);
 This code is ambiguous; it could be a declaration of the variable
 @samp{a} as a pointer to @samp{int}, or it could be a functional cast of
 @samp{*a} to @samp{int}.  Section 6.8 specifies that the former
-interpretation is correct.  This ambiguity results in 12 reduce/reduce
-conflicts.  Ack.
-
-4) Between @code{after_type_declarator} and @code{parm}, for the token
-@code{TYPENAME}.  This occurs in (as one example) code like
+interpretation is correct.  This ambiguity results in 7 reduce/reduce
+conflicts.  Another aspect of this ambiguity is code like 'int (x[2]);',
+which is resolved at the '[' and accounts for 6 reduce/reduce conflicts
+between @samp{direct_notype_declarator} and
+@samp{primary}/@samp{overqualified_id}.  Finally, there are 4 r/r
+conflicts between @samp{expr_or_declarator} and @samp{primary} over code
+like 'int (a);', which could probably be resolved but would also
+probably be more trouble than it's worth.  In all, this situation
+accounts for 17 conflicts.  Ack!
+
+The second case above is responsible for the failure to parse 'LinppFile
+ppfile (String (argv[1]), &outs, argc, argv);' (from Rogue Wave
+Math.h++) as an object declaration, and must be fixed so that it does
+not resolve until later.
+
+4) Indirectly between @code{after_type_declarator} and @code{parm}, for
+type names.  This occurs in (as one example) code like
 
 @example
 typedef int foo, bar;
@@ -1093,11 +1106,12 @@ class A @{
 
 What is @code{bar} inside the class definition?  We currently interpret
 it as a @code{parm}, as does Cfront, but IBM xlC interprets it as an
-@code{after_type_declarator}.  I suspect that xlC is correct, in light
+@code{after_type_declarator}.  I believe that xlC is correct, in light
 of 7.1p2, which says "The longest sequence of @i{decl-specifiers} that
 could possibly be a type name is taken as the @i{decl-specifier-seq} of
 a @i{declaration}."  However, it seems clear that this rule must be
-violated in the case of constructors, so...
+violated in the case of constructors.  This ambiguity accounts for 8
+conflicts.
 
 Unlike the others, this ambiguity is not recognized by the Working Paper.
 
index 90ff11cc529969ba56a177237267ee8c52e35905..4d2cbf7332cc57b1bb995e8f3a0edd7d30a7b5bf 100644 (file)
@@ -52,12 +52,11 @@ static void expand_recursive_init_1 ();
 static void expand_recursive_init ();
 static void expand_virtual_init PROTO((tree, tree, tree));
 tree expand_vec_init ();
-tree build_vec_delete ();
 
 static void add_friend (), add_friends ();
 
 /* Cache _builtin_new and _builtin_delete exprs.  */
-static tree BIN, BID;
+static tree BIN, BID, BIVN, BIVD;
 
 /* Cache the identifier nodes for the two magic field of a new cookie.  */
 static tree nc_nelts_field_id;
@@ -81,6 +80,10 @@ void init_init_processing ()
   TREE_USED (TREE_OPERAND (BIN, 0)) = 0;
   BID = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) DELETE_EXPR])));
   TREE_USED (TREE_OPERAND (BID, 0)) = 0;
+  BIVN = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) VEC_NEW_EXPR])));
+  TREE_USED (TREE_OPERAND (BIVN, 0)) = 0;
+  BIVD = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) VEC_DELETE_EXPR])));
+  TREE_USED (TREE_OPERAND (BIVD, 0)) = 0;
   minus_one = build_int_2 (-1, -1);
 
   /* Define the structure that holds header information for
@@ -1801,12 +1804,10 @@ is_aggr_typedef (name, or_else)
 
   if (IDENTIFIER_HAS_TYPE_VALUE (name))
     type = IDENTIFIER_TYPE_VALUE (name);
-  else if (IDENTIFIER_HAS_CLASS_TYPE_VALUE (name))
-    type = IDENTIFIER_CLASS_TYPE_VALUE (name);
   else
     {
       if (or_else)
-       cp_error ("`%T' fails to be an aggregate typedef", name);
+       cp_error ("`%T' is not an aggregate typedef", name);
       return 0;
     }
 
@@ -1814,7 +1815,7 @@ is_aggr_typedef (name, or_else)
       && TREE_CODE (type) != TEMPLATE_TYPE_PARM)
     {
       if (or_else)
-       cp_error ("type `%T' is of non-aggregate type", type);
+       cp_error ("`%T' is not an aggregate type", type);
       return 0;
     }
   return 1;
@@ -1833,8 +1834,6 @@ get_aggr_from_typedef (name, or_else)
 
   if (IDENTIFIER_HAS_TYPE_VALUE (name))
     type = IDENTIFIER_TYPE_VALUE (name);
-  else if (IDENTIFIER_HAS_CLASS_TYPE_VALUE (name))
-    type = IDENTIFIER_CLASS_TYPE_VALUE (name);
   else
     {
       if (or_else)
@@ -1861,8 +1860,6 @@ get_type_value (name)
 
   if (IDENTIFIER_HAS_TYPE_VALUE (name))
     return IDENTIFIER_TYPE_VALUE (name);
-  else if (IDENTIFIER_CLASS_VALUE (name))
-    return IDENTIFIER_CLASS_TYPE_VALUE (name);
   else
     return NULL_TREE;
 }
@@ -2808,13 +2805,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
       TREE_PUBLIC (decl) = 1;
       add_friend (current_class_type, decl);
       DECL_FRIEND_P (decl) = 1;
-      if (IDENTIFIER_POINTER (declarator)[0] == '_')
-       {
-         if (! strcmp (IDENTIFIER_POINTER (declarator)+10, "new"))
-           TREE_GETS_NEW (current_class_type) = 0;
-         else if (! strcmp (IDENTIFIER_POINTER (declarator)+10, "delete"))
-           TREE_GETS_DELETE (current_class_type) = 0;
-       }
       decl = void_type_node;
     }
   /* A global friend.
@@ -2980,6 +2970,7 @@ build_new (placement, decl, init, use_global_new)
   tree type, true_type, size, rval;
   tree nelts;
   int has_array = 0;
+  enum tree_code code = NEW_EXPR;
 
   tree pending_sizes = NULL_TREE;
 
@@ -3155,27 +3146,28 @@ build_new (placement, decl, init, use_global_new)
 
   /* Get a little extra space to store a couple of things before the new'ed
      array. */
-  if (has_array && TYPE_NEEDS_DESTRUCTOR (true_type))
+  if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type))
     {
       tree extra = BI_header_size;
 
       size = size_binop (PLUS_EXPR, size, extra);
     }
 
+  if (has_array)
+    code = VEC_NEW_EXPR;
+
   /* Allocate the object. */
-  if (TYPE_LANG_SPECIFIC (true_type)
-      && (TREE_GETS_NEW (true_type) || TREE_GETS_PLACED_NEW (true_type))
-      && !use_global_new
-      && !has_array)
-    rval = build_opfncall (NEW_EXPR, LOOKUP_NORMAL,
+  if (! use_global_new && TYPE_LANG_SPECIFIC (true_type)
+      && (TYPE_GETS_NEW (true_type) & (1 << has_array)))
+    rval = build_opfncall (code, LOOKUP_NORMAL,
                           TYPE_POINTER_TO (true_type), size, placement);
   else if (placement)
     {
-      rval = build_opfncall (NEW_EXPR, LOOKUP_GLOBAL|LOOKUP_COMPLAIN,
+      rval = build_opfncall (code, LOOKUP_GLOBAL|LOOKUP_COMPLAIN,
                             ptr_type_node, size, placement);
       rval = convert (TYPE_POINTER_TO (true_type), rval);
     }
-  else if (flag_this_is_variable > 0
+  else if (! has_array && flag_this_is_variable > 0
           && TYPE_HAS_CONSTRUCTOR (true_type) && init != void_type_node)
     {
       if (init == NULL_TREE || TREE_CODE (init) == TREE_LIST)
@@ -3189,7 +3181,8 @@ build_new (placement, decl, init, use_global_new)
   else
     {
       rval = build_builtin_call (build_pointer_type (true_type),
-                                BIN, build_tree_list (NULL_TREE, size));
+                                has_array ? BIVN : BIN,
+                                build_tree_list (NULL_TREE, size));
 #if 0
       /* See comment above as to why this is disabled.  */
       if (alignment)
@@ -3202,14 +3195,13 @@ build_new (placement, decl, init, use_global_new)
        }
 #endif
       TREE_CALLS_NEW (rval) = 1;
-      TREE_SIDE_EFFECTS (rval) = 1;
     }
 
   /* if rval is NULL_TREE I don't have to allocate it, but are we totally
      sure we have some extra bytes in that case for the BI_header_size
      cookies? And how does that interact with the code below? (mrs) */
   /* Finish up some magic for new'ed arrays */
-  if (has_array && TYPE_NEEDS_DESTRUCTOR (true_type) && rval != NULL_TREE)
+  if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type) && rval != NULL_TREE)
     {
       tree extra = BI_header_size;
       tree cookie, exp1;
@@ -3594,20 +3586,21 @@ expand_vec_init (decl, base, maxindex, init, from_array)
 
    This does not call any destructors.  */
 tree
-build_x_delete (type, addr, use_global_delete, virtual_size)
+build_x_delete (type, addr, which_delete, virtual_size)
      tree type, addr;
-     int use_global_delete;
+     int which_delete;
      tree virtual_size;
 {
+  int use_global_delete = which_delete & 1;
+  int use_vec_delete = !!(which_delete & 2);
   tree rval;
+  enum tree_code code = use_vec_delete ? VEC_DELETE_EXPR : DELETE_EXPR;
 
-  if (!use_global_delete
-      && TYPE_LANG_SPECIFIC (TREE_TYPE (type))
-      && TREE_GETS_DELETE (TREE_TYPE (type)))
-    rval = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr,
-                          virtual_size, NULL_TREE);
+  if (! use_global_delete && TYPE_LANG_SPECIFIC (TREE_TYPE (type))
+      && (TYPE_GETS_DELETE (TREE_TYPE (type)) & (1 << use_vec_delete)))
+    rval = build_opfncall (code, LOOKUP_NORMAL, addr, virtual_size, NULL_TREE);
   else
-    rval = build_builtin_call (void_type_node, BID,
+    rval = build_builtin_call (void_type_node, use_vec_delete ? BIVD : BID,
                               build_tree_list (NULL_TREE, addr));
   return rval;
 }
@@ -3674,7 +3667,8 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
        addr = save_expr (addr);
       return build_vec_delete (addr, array_type_nelts (type),
                               c_sizeof_nowarn (TREE_TYPE (type)),
-                              NULL_TREE, auto_delete, integer_two_node);
+                              auto_delete, integer_two_node,
+                              use_global_delete);
     }
   else
     {
@@ -3707,10 +3701,8 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
 
       /* Pass the size of the object down to the operator delete() in
         addition to the ADDR.  */
-      if (TREE_GETS_DELETE (type) && !use_global_delete)
+      if (TYPE_GETS_REG_DELETE (type) && !use_global_delete)
        {
-         /* This is probably wrong. It should be the size of the virtual
-            object being deleted.  */
          tree virtual_size = c_sizeof_nowarn (type);
          return build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr,
                                 virtual_size, NULL_TREE);
@@ -3837,7 +3829,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
         operator delete, call the parent parent destructor (if any),
         but let this node do the deleting.  Otherwise, it is ok
         to let the parent destructor do the deleting.  */
-      if (TREE_GETS_DELETE (type) && !use_global_delete)
+      if (TYPE_GETS_REG_DELETE (type) && !use_global_delete)
        {
          parent_auto_delete = integer_zero_node;
          if (auto_delete == integer_zero_node)
@@ -3970,8 +3962,6 @@ build_vbase_delete (type, decl)
    MAXINDEX is the number of elements to be deleted.
    ELT_SIZE is the nominal size of each element in the vector.
    BASE is the expression that should yield the store to be deleted.
-   DTOR_DUMMY is a placeholder for a destructor.  The library function
-   __builtin_vec_delete has a pointer to function in this position.
    This function expands (or synthesizes) these calls itself.
    AUTO_DELETE_VEC says whether the container (vector) should be deallocated.
    AUTO_DELETE say whether each item in the container should be deallocated.
@@ -3985,10 +3975,11 @@ build_vbase_delete (type, decl)
    confirm the size, and trap if the numbers differ; not clear that it'd
    be worth bothering.)  */
 tree
-build_vec_delete (base, maxindex, elt_size, dtor_dummy, auto_delete_vec, auto_delete)
+build_vec_delete (base, maxindex, elt_size, auto_delete_vec, auto_delete,
+                 use_global_delete)
      tree base, maxindex, elt_size;
-     tree dtor_dummy;
      tree auto_delete_vec, auto_delete;
+     int use_global_delete;
 {
   tree ptype = TREE_TYPE (base);
   tree type;
@@ -4081,7 +4072,8 @@ build_vec_delete (base, maxindex, elt_size, dtor_dummy, auto_delete_vec, auto_de
       /* This is the real size */
       virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size);
       body = build_tree_list (NULL_TREE,
-                             build_x_delete (ptr_type_node, base_tbd, 1,
+                             build_x_delete (ptype, base_tbd,
+                                             2 | use_global_delete,
                                              virtual_size));
       body = build (COND_EXPR, void_type_node,
                    build (BIT_AND_EXPR, integer_type_node,
@@ -4124,7 +4116,7 @@ build_vec_delete (base, maxindex, elt_size, dtor_dummy, auto_delete_vec, auto_de
       /* The below is short by BI_header_size */
       virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex));
 
-      if (loop == integer_zero_node)
+      if (! TYPE_VEC_NEW_USES_COOKIE (type))
        /* no header */
        base_tbd = base;
       else
@@ -4137,7 +4129,8 @@ build_vec_delete (base, maxindex, elt_size, dtor_dummy, auto_delete_vec, auto_de
          /* True size with header. */
          virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size);
        }
-      deallocate_expr = build_x_delete (ptr_type_node, base_tbd, 1,
+      deallocate_expr = build_x_delete (ptype, base_tbd,
+                                       2 | use_global_delete,
                                        virtual_size);
       if (auto_delete_vec != integer_one_node)
        deallocate_expr = build (COND_EXPR, void_type_node,
index 26155a7b707d4e5cfc57da62de9e685cbcc2a2a9..478cd106a12085acfbc4d1fe1b358bbfaab9afd8 100644 (file)
@@ -542,6 +542,10 @@ init_lex ()
   IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1;
   ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl");
   IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1;
+  ansi_opname[(int) VEC_NEW_EXPR] = get_identifier ("__vn");
+  IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1;
+  ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd");
+  IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1;
   ansi_opname[(int) TYPE_EXPR] = get_identifier ("__op");
   IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1;
 
@@ -681,6 +685,8 @@ init_lex ()
   opname_tab[(int) MODIFY_EXPR] = "=";
   opname_tab[(int) NEW_EXPR] = "new";
   opname_tab[(int) DELETE_EXPR] = "delete";
+  opname_tab[(int) VEC_NEW_EXPR] = "new []";
+  opname_tab[(int) VEC_DELETE_EXPR] = "delete []";
   opname_tab[(int) COND_EXPR] = "... ? ... : ...";
   opname_tab[(int) CALL_EXPR] = "()";
   opname_tab[(int) PLUS_EXPR] = "+";
@@ -841,10 +847,7 @@ yyprint (file, yychar, yylval)
     case IDENTIFIER_DEFN:
     case TYPENAME_DEFN:
     case PTYPENAME_DEFN:
-    case TYPENAME_COLON:
     case TYPENAME_ELLIPSIS:
-    case SCOPED_TYPENAME:
-    case SCOPED_NAME:
     case SCSPEC:
     case PRE_PARSED_CLASS_DECL:
       t = yylval.ttype;
@@ -2324,14 +2327,15 @@ check_newline ()
   register int c;
   register int token;
 
-  lineno++;
-
-  /* Read first nonwhite char on the line.  */
+  /* Read first nonwhite char on the line.  Do this before incrementing the
+     line number, in case we're at the end of saved text.  */
 
   do
     c = getch ();
   while (c == ' ' || c == '\t');
 
+  lineno++;
+
   if (c != '#')
     {
       /* If not #, return it so caller will use it.  */
@@ -3080,12 +3084,13 @@ readescape (ignore_ptr)
   return c;
 }
 
-/* Value is 1 if we should try to make the next identifier look like a
-   typename (when it may be a local variable or a class variable).
-   Value is 0 if we treat this name in a default fashion.
-   Value is -1 if we must not see a type name.  */
+/* Value is 1 (or 2) if we should try to make the next identifier look like
+   a typename (when it may be a local variable or a class variable).
+   Value is 0 if we treat this name in a default fashion.  */
 int looking_for_typename = 0;
 
+#if 0
+/* NO LONGER USED: Value is -1 if we must not see a type name.  */
 void
 dont_see_typename ()
 {
@@ -3096,6 +3101,7 @@ dont_see_typename ()
       lastiddecl = 0;
     }
 }
+#endif
 
 #ifdef __GNUC__
 extern __inline int identifier_type ();
@@ -3119,7 +3125,7 @@ see_typename ()
   looking_for_typename = 0;
   if (yychar == IDENTIFIER)
     {
-      lastiddecl = lookup_name (yylval.ttype, -1);
+      lastiddecl = lookup_name (yylval.ttype, -2);
       if (lastiddecl == 0)
        {
          if (flag_labels_ok)
@@ -3540,7 +3546,6 @@ real_yylex ()
          }
        if (value == NEW && ! global_bindings_p ())
          {
-           looking_for_typename = 1;
            value = NEW;
            goto done;
          }
index 457fa39502ddc5226bbd0ed39b0fbf3c73036437..5288a02435911e695f4a6bf2ba13e6df6ca1d354 100644 (file)
@@ -114,6 +114,9 @@ extern char *token_buffer;  /* Pointer to token buffer.  */
 /* Back-door communication channel to the lexer.  */
 extern int looking_for_typename;
 
+/* Tell the lexer where to look for names.  */
+extern tree got_scope;
+
 /* Pending language change.
    Positive is push count, negative is pop count.  */
 extern int pending_lang_change;
index cdf3d196c7612adcc9a52809803a2bb379e56e00..a39f9a57ae32a78e216b5a23cbc48d0b4651950e 100644 (file)
@@ -840,27 +840,22 @@ build_decl_overload (dname, parms, for_method)
 {
   char *name = IDENTIFIER_POINTER (dname);
 
-  if (dname == ansi_opname[(int) NEW_EXPR]
-      && parms != NULL_TREE
-      && TREE_CODE (parms) == TREE_LIST
-      && TREE_VALUE (parms) == sizetype
-      && TREE_CHAIN (parms) == void_list_node)
-    return get_identifier ("__builtin_new");
-  else if (dname == ansi_opname[(int) DELETE_EXPR]
-          && parms != NULL_TREE
-          && TREE_CODE (parms) == TREE_LIST
-          && TREE_VALUE (parms) == ptr_type_node
-          && TREE_CHAIN (parms) == void_list_node)
-    return get_identifier ("__builtin_delete");
-  else if (dname == ansi_opname[(int) DELETE_EXPR]
-          && parms != NULL_TREE
-          && TREE_CODE (parms) == TREE_LIST
-          && TREE_VALUE (parms) == ptr_type_node
-          && TREE_CHAIN (parms) != NULL_TREE
-          && TREE_CODE (TREE_CHAIN (parms)) == TREE_LIST
-          && TREE_VALUE (TREE_CHAIN (parms)) == sizetype
-          && TREE_CHAIN (TREE_CHAIN (parms)) == void_list_node)
-    return get_identifier ("__builtin_delete");
+  /* member operators new and delete look like methods at this point.  */
+  if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST)
+    {
+      if (TREE_VALUE (parms) == sizetype
+         && TREE_CHAIN (parms) == void_list_node)
+       {
+         if (dname == ansi_opname[(int) NEW_EXPR])
+           return get_identifier ("__builtin_new");
+         else if (dname == ansi_opname[(int) VEC_NEW_EXPR])
+           return get_identifier ("__builtin_vec_new");
+       }
+      else if (dname == ansi_opname[(int) DELETE_EXPR])
+       return get_identifier ("__builtin_delete");
+      else if (dname == ansi_opname[(int) VEC_DELETE_EXPR])
+       return get_identifier ("__builtin_vec_delete");
+    }
 
   OB_INIT ();
   if (for_method != 2)
@@ -1112,19 +1107,19 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
       try_second = 0;
       break;
 
+    case VEC_NEW_EXPR:
     case NEW_EXPR:
       {
-       fnname = ansi_opname[(int) NEW_EXPR];
+       tree args = tree_cons (NULL_TREE, xarg2, arg3);
+       fnname = ansi_opname[(int) code];
        if (flags & LOOKUP_GLOBAL)
-         return build_overload_call (fnname, tree_cons (NULL_TREE, xarg2, arg3),
-                                     flags & LOOKUP_COMPLAIN,
+         return build_overload_call (fnname, args, flags & LOOKUP_COMPLAIN,
                                      (struct candidate *)0);
 
        rval = build_method_call
          (build_indirect_ref (build1 (NOP_EXPR, xarg1, error_mark_node),
                               "new"),
-          fnname, tree_cons (NULL_TREE, xarg2, arg3),
-          NULL_TREE, flags);
+          fnname, args, NULL_TREE, flags);
        if (rval == error_mark_node)
          /* User might declare fancy operator new, but invoke it
             like standard one.  */
@@ -1136,13 +1131,13 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
       }
       break;
 
+    case VEC_DELETE_EXPR:
     case DELETE_EXPR:
       {
-       fnname = ansi_opname[(int) DELETE_EXPR];
+       fnname = ansi_opname[(int) code];
        if (flags & LOOKUP_GLOBAL)
          return build_overload_call (fnname,
-                                     tree_cons (NULL_TREE, xarg1,
-                                                build_tree_list (NULL_TREE, xarg2)),
+                                     build_tree_list (NULL_TREE, xarg1),
                                      flags & LOOKUP_COMPLAIN,
                                      (struct candidate *)0);
 
@@ -1151,7 +1146,7 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
                                       error_mark_node),
                               NULL_PTR),
           fnname, tree_cons (NULL_TREE, xarg1,
-                             build_tree_list (NULL_TREE, xarg2)),
+                              build_tree_list (NULL_TREE, xarg2)),
           NULL_TREE, flags);
        /* This happens when the user mis-declares `operator delete'.
           Should now be impossible.  */
index 9730a62ad7e5983e70348532256b54a928de5a6f..e199708966a4d8f6d4d2481f72b47dfaf1927e19 100644 (file)
@@ -66,12 +66,16 @@ extern int errno;
 #endif
 
 extern int end_of_file;
+extern int current_class_depth;
 
 void yyerror ();
 
 /* Like YYERROR but do call yyerror.  */
 #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
 
+#define OP0(NODE) (TREE_OPERAND (NODE, 0))
+#define OP1(NODE) (TREE_OPERAND (NODE, 1))
+
 /* Contains the statement keyword (if/while/do) to include in an
    error message if the user supplies an empty conditional expression.  */
 static char *cond_stmt_keyword;
@@ -112,12 +116,6 @@ empty_parms ()
    but they can also serve as typespecs in declarations.  */
 %token TYPENAME
 
-/* Qualified identifiers that end in a TYPENAME.  */
-%token SCOPED_TYPENAME
-
-/* Qualified identifiers that end in a IDENTIFIER.  */
-%token SCOPED_NAME
-
 /* Reserved words that specify storage class.
    yylval contains an IDENTIFIER_NODE which indicates which one.  */
 %token SCSPEC
@@ -156,11 +154,6 @@ empty_parms ()
 %token TYPEID DYNAMIC_CAST
 %token <itype> SCOPE
 
-/* Special token created by the lexer to separate TYPENAME
-   from an ABSDCL.  This allows us to parse `foo (*pf)()'.  */
-
-%token START_DECLARATOR
-
 /* Define the operator tokens and their precedences.
    The value is an integer because, if used, it is the tree code
    to use in the expression made from the operator.  */
@@ -173,7 +166,7 @@ empty_parms ()
 %nonassoc IF
 %nonassoc ELSE
 
-%left IDENTIFIER TYPENAME PTYPENAME TYPENAME_COLON SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR ELLIPSIS SCOPED_TYPENAME TYPEOF SIGOF START_DECLARATOR OPERATOR
+%left IDENTIFIER TYPENAME PTYPENAME SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR
 
 %left '{' ',' ';'
 
@@ -217,30 +210,28 @@ empty_parms ()
 %type <ttype> compstmt except_stmts ansi_except_stmts implicitly_scoped_stmt
 
 %type <ttype> declarator notype_declarator after_type_declarator
-%type <ttype> notype_declarator1 after_type_declarator1
 %type <ttype> direct_notype_declarator direct_after_type_declarator
 
 %type <ttype> structsp opt.component_decl_list component_decl_list
 %type <ttype> component_decl components component_declarator
 %type <ttype> notype_components notype_component_declarator
 %type <ttype> after_type_component_declarator after_type_component_declarator0
-%type <ttype> notype_component_declarator0
+%type <ttype> notype_component_declarator0 component_decl_1
 %type <ttype> enumlist enumerator
-%type <ttype> type_id absdcl absdcl1 type_quals
+%type <ttype> type_id absdcl type_quals
 %type <ttype> direct_abstract_declarator conversion_declarator
 %type <ttype> new_type_id new_declarator direct_new_declarator
 %type <ttype> xexpr parmlist parms parm bad_parm
 %type <ttype> identifiers_or_typenames
 %type <ttype> fcast_or_absdcl regcast_or_absdcl sub_cast_expr
-%type <ttype> expr_or_declarator complex_notype_declarator1
-%type <ttype> notype_unqualified_id
+%type <ttype> expr_or_declarator complex_notype_declarator
+%type <ttype> notype_unqualified_id unqualified_id qualified_id
+%type <ttype> overqualified_id notype_qualified_id
 %type <ttype> complex_direct_notype_declarator functional_cast
 %type <ttype> named_parm complex_parmlist typed_declspecs1 parms_comma
 
 /* C++ extensions */
-%type <ttype> typename_scope
-%token <ttype> TYPENAME_COLON TYPENAME_ELLIPSIS
-%token <ttype> PTYPENAME SCOPED_TYPENAME SCOPED_NAME
+%token <ttype> TYPENAME_ELLIPSIS PTYPENAME
 %token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
 %token <ttype> PRE_PARSED_CLASS_DECL
 %type <ttype> fn.def1 /* Not really! */
@@ -251,21 +242,26 @@ empty_parms ()
 %type <itype> base_class_access_list
 %type <ttype> base_class maybe_base_class_list base_class.1
 %type <ttype> maybe_raises raise_identifier raise_identifiers ansi_raise_identifier ansi_raise_identifiers
-%type <ttype> component_declarator0 id_scope scoped_typename scoped_base_class
-%type <ttype> forhead.1 identifier_or_opname operator_name
-%type <ttype> new delete object aggr
+%type <ttype> component_declarator0
+%type <ttype> forhead.1 operator_name
+%type <ttype> new object aggr
+%type <itype> delete
 /* %type <ttype> primary_no_id */
 %type <ttype> nonmomentary_expr
 %type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list
 %type <itype> .scope try ansi_try
 %type <ttype> template_header template_parm_list template_parm
 %type <ttype> template_type template_arg_list template_arg
-%type <ttype> template_instantiation template_type_name tmpl.1 tmpl.2
+%type <ttype> template_instantiation template_type_name tmpl.2
 %type <ttype> template_instantiate_once template_instantiate_some
 %type <itype> fn_tmpl_end
 /* %type <itype> try_for_typename */
 %type <ttype> condition partially_scoped_stmt xcond paren_cond_or_null
 %type <strtype> .kindof_pushlevel
+%type <ttype> type_name nested_name_specifier nested_type ptr_to_mem
+%type <ttype> qualified_type_name complete_type_name notype_identifier
+%type <ttype> complex_type_name nested_name_specifier_1
+%type <itype> nomods_initdecls nomods_initdcl0
 
 /* in order to recognize aggr tags as defining and thus shadowing. */
 %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
@@ -405,15 +401,6 @@ template_parm:
                  warning ("restricted template type parameters not yet implemented");
                  $$ = build_tree_list ($2, $4);
                }
-       | aggr TYPENAME_COLON base_class.1
-               {
-                 if ($1 == signature_type_node)
-                   sorry ("signature as template type parameter");
-                 else if ($1 != class_type_node)
-                   error ("template type parameter must use keyword `class'");
-                 warning ("restricted template type parameters not yet implemented");
-                 $$ = build_tree_list ($2, $3);
-               }
        | parm
        ;
 
@@ -528,11 +515,8 @@ fn_tmpl_end: '{'           { $$ = '{'; }
        ;
 
 datadef:
-         notype_initdecls ';'
-               { if (pedantic)
-                   pedwarn ("ANSI C++ forbids data definition with no type or storage class");
-                 else if (! flag_traditional && ! have_extern_spec)
-                   warning ("data definition has no type or storage class"); }
+         nomods_initdecls ';'
+               {}
        | declmods notype_initdecls ';'
                {}
        /* Normal case to make fast: "const i;".  */
@@ -649,26 +633,6 @@ fn.def1:
                    YYERROR1;
                  reinit_parse_for_function ();
                  $$ = NULL_TREE; }
-       | TYPENAME '(' parmlist ')' type_quals maybe_raises
-               { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, $3, $5), $6, 0))
-                   YYERROR1;
-                 reinit_parse_for_function ();
-                 $$ = NULL_TREE; }
-       | scoped_typename '(' parmlist ')' type_quals maybe_raises
-               { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, $3, $5), $6, 0))
-                   YYERROR1;
-                 reinit_parse_for_function ();
-                 $$ = NULL_TREE; }
-       | TYPENAME LEFT_RIGHT type_quals maybe_raises
-               { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, empty_parms (), $3), $4, 0))
-                   YYERROR1;
-                 reinit_parse_for_function ();
-                 $$ = NULL_TREE; }
-       | scoped_typename LEFT_RIGHT type_quals maybe_raises
-               { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, empty_parms (), $3), $4, 0))
-                   YYERROR1;
-                 reinit_parse_for_function ();
-                 $$ = NULL_TREE; }
        | PRE_PARSED_FUNCTION_DECL
                { start_function (NULL_TREE, TREE_VALUE ($$), NULL_TREE, 1);
                  reinit_parse_for_function (); }
@@ -679,8 +643,9 @@ fn.def1:
 fn.def2:
          typed_declspecs '(' parmlist ')' type_quals maybe_raises
                {
-                 tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), $3, $5);
-                 $$ = start_method (TREE_CHAIN ($$), decl, $6);
+                 $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5);
+                 $$ = start_method (TREE_CHAIN ($1), $$, $6);
+                rest_of_mdef:
                  if (! $$)
                    YYERROR1;
                  if (yychar == YYEMPTY)
@@ -688,52 +653,17 @@ fn.def2:
                  reinit_parse_for_method (yychar, $$); }
        | typed_declspecs LEFT_RIGHT type_quals maybe_raises
                {
-                 tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), empty_parms (), $3);
-                 $$ = start_method (TREE_CHAIN ($$), decl, $4);
-                 if (! $$)
-                   YYERROR1;
-                 if (yychar == YYEMPTY)
-                   yychar = YYLEX;
-                 reinit_parse_for_method (yychar, $$); }
+                 $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
+                                        empty_parms (), $3);
+                 $$ = start_method (TREE_CHAIN ($1), $$, $4);
+                 goto rest_of_mdef;
+               }
        | typed_declspecs declarator maybe_raises
-               { $$ = start_method ($$, $2, $3);
-                 if (! $$)
-                   YYERROR1;
-                 if (yychar == YYEMPTY)
-                   yychar = YYLEX;
-                 reinit_parse_for_method (yychar, $$); }
-       | declmods '(' parmlist ')' type_quals maybe_raises
-               {
-                 tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), $3, $5);
-                 $$ = start_method (TREE_CHAIN ($$), decl, $6);
-                 if (! $$)
-                   YYERROR1;
-                 if (yychar == YYEMPTY)
-                   yychar = YYLEX;
-                 reinit_parse_for_method (yychar, $$); }
-       | declmods LEFT_RIGHT type_quals maybe_raises
-               {
-                 tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), empty_parms (), $3);
-                 $$ = start_method (TREE_CHAIN ($$), decl, $4);
-                 if (! $$)
-                   YYERROR1;
-                 if (yychar == YYEMPTY)
-                   yychar = YYLEX;
-                 reinit_parse_for_method (yychar, $$); }
+               { $$ = start_method ($$, $2, $3); goto rest_of_mdef; }
        | declmods notype_declarator maybe_raises
-               { $$ = start_method ($$, $2, $3);
-                 if (! $$)
-                   YYERROR1;
-                 if (yychar == YYEMPTY)
-                   yychar = YYLEX;
-                 reinit_parse_for_method (yychar, $$); }
+               { $$ = start_method ($$, $2, $3); goto rest_of_mdef; }
        | notype_declarator maybe_raises
-               { $$ = start_method (NULL_TREE, $$, $2);
-                 if (! $$)
-                   YYERROR1;
-                 if (yychar == YYEMPTY)
-                   yychar = YYLEX;
-                 reinit_parse_for_method (yychar, $$); }
+               { $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; }
        ;
 
 return_id: RETURN IDENTIFIER
@@ -811,27 +741,22 @@ member_init: '(' nonnull_exprlist ')'
                    pedwarn ("anachronistic old style base class initializer");
                  expand_member_init (C_C_D, NULL_TREE, void_type_node);
                }
-       | identifier '(' nonnull_exprlist ')'
-               {
-                 expand_member_init (C_C_D, $<ttype>$, $3);
-               }
-       | identifier LEFT_RIGHT
-               { expand_member_init (C_C_D, $<ttype>$, void_type_node); }
-       | template_type_name '(' nonnull_exprlist ')'
+       | notype_identifier '(' nonnull_exprlist ')'
                { expand_member_init (C_C_D, $<ttype>$, $3); }
-       | template_type_name LEFT_RIGHT
+       | notype_identifier LEFT_RIGHT
                { expand_member_init (C_C_D, $<ttype>$, void_type_node); }
-       | scoped_typename '(' nonnull_exprlist ')'
+       | complete_type_name '(' nonnull_exprlist ')'
                { expand_member_init (C_C_D, $<ttype>$, $3); }
-       | scoped_typename LEFT_RIGHT
+       | complete_type_name LEFT_RIGHT
                { expand_member_init (C_C_D, $<ttype>$, void_type_node); }
-       | id_scope identifier '(' nonnull_exprlist ')'
+       /* GNU extension */
+       | notype_qualified_id '(' nonnull_exprlist ')'
                {
-                 do_member_init ($<ttype>$, $2, $4);
+                 do_member_init (OP0 ($1), OP1 ($1), $3);
                }
-       | id_scope identifier LEFT_RIGHT
+       | notype_qualified_id LEFT_RIGHT
                {
-                 do_member_init ($<ttype>$, $2, void_type_node);
+                 do_member_init (OP0 ($1), OP1 ($1), void_type_node);
                }
        ;
 
@@ -841,23 +766,17 @@ identifier:
        | PTYPENAME
        ;
 
+notype_identifier:
+         IDENTIFIER
+       | PTYPENAME %prec EMPTY
+       ;
+
 identifier_defn:
          IDENTIFIER_DEFN
        | TYPENAME_DEFN
        | PTYPENAME_DEFN
        ;
 
-identifier_or_opname:
-         IDENTIFIER
-       | TYPENAME
-       | PTYPENAME
-/*     | '~' TYPENAME
-               { $$ = build_parse_node (BIT_NOT_EXPR, $2); }*/
-       /* get rid of the next line, replace it with the above */
-       | '~' identifier { $$ = build_parse_node (BIT_NOT_EXPR,$2);}
-       | operator_name
-       ;
-
 explicit_instantiation:
          TEMPLATE aggr template_type
        | TEMPLATE typed_declspecs declarator
@@ -865,32 +784,8 @@ explicit_instantiation:
        ;
 
 template_type:
-         template_type_name tmpl.1 template_instantiation
-               {
-                 extern tree template_type_seen_before_scope;
-
-                 if ($3) 
-                   $$ = $3;
-                 else if ($$ != error_mark_node)
-                   $$ = IDENTIFIER_TYPE_VALUE ($$);
-                 /* This is a kludge: In order to detect nested types inside
-                  * template classes, we have to tell the lexer that it should
-                  * try to replace a following SCOPE token with the correct
-                  * SCOPED_TYPENAME for the nested type.  This SCOPED_TYPENAME
-                  * token will be handled in the rule "scoped_typename".
-                  * - niklas@appli.se */
-                 if (yychar == SCOPE)
-                   {
-                     /* We set template_type_seen_before_scope to be
-                        an error_mark_node so we can avoid meaningless
-                        and unhelpful syntax errors later.  */
-                     if ($$ != error_mark_node)
-                       template_type_seen_before_scope = TYPE_IDENTIFIER ($$);
-                     else
-                       template_type_seen_before_scope = error_mark_node;
-                     yychar = YYLEX;
-                   }
-               }
+         template_type_name tmpl.2 template_instantiation
+               { if ($3) $$ = $3; }
        ;
 
 template_type_name:
@@ -900,16 +795,7 @@ template_type_name:
                { $$ = lookup_template_class ($$, $3, NULL_TREE); }
        ;
 
-tmpl.1:
-       /* Expansion of template may be required, unless we're followed by
-          a class definition.  */
-         '{'   { yyungetc ('{', 1); $$ = 0; }
-       | ':'   { yyungetc (':', 1); $$ = 0; }
-       | /* empty */ %prec EMPTY
-                { $$ = instantiate_class_template ($<ttype>0, 1); }
-       ;
-
-tmpl.2:
+tmpl.2: %prec EMPTY
        /* Always do expansion if it hasn't been done already. */
                { $$ = instantiate_class_template ($<ttype>0, 1); }
        ;
@@ -961,7 +847,7 @@ template_instantiate_once:
                }
          left_curly opt.component_decl_list '}'
                {
-                 $$ = finish_struct ($<ttype>3, $5, 0);
+                 tree t = finish_struct ($<ttype>3, $5, 0);
 
                  pop_obstacks ();
                  end_template_instantiation ($1);
@@ -971,7 +857,7 @@ template_instantiate_once:
 
                  pop_tinst_level();
 
-                 CLASSTYPE_GOT_SEMICOLON ($$) = 1;
+                 CLASSTYPE_GOT_SEMICOLON (t) = 1;
                }
        ;
 
@@ -1229,20 +1115,15 @@ unary_expr:
        | .scope new '(' nonnull_exprlist ')' '(' type_id ')'
                { $$ = build_new ($4, groktypename ($7), NULL_TREE,
                                  $$ != NULL_TREE); }
-       /* Unswallow a ':' which is probably meant for ?: expression.  */
-       | .scope new TYPENAME_COLON
-               { yyungetc (':', 1); $$ = build_new ($2, $3, NULL_TREE, $$ != NULL_TREE); }
-       | .scope new '(' nonnull_exprlist ')' TYPENAME_COLON
-               { yyungetc (':', 1); $$ = build_new ($4, $6, NULL_TREE, $$ != NULL_TREE); }
 
        | delete cast_expr  %prec UNARY
-               { $$ = delete_sanity ($2, NULL_TREE, 0, $$ != NULL_TREE); }
+               { $$ = delete_sanity ($2, NULL_TREE, 0, $1); }
        | delete '[' ']' cast_expr  %prec UNARY
-               { $$ = delete_sanity ($4, NULL_TREE, 1, $$ != NULL_TREE);
+               { $$ = delete_sanity ($4, NULL_TREE, 1, $1);
                  if (yychar == YYEMPTY)
                    yychar = YYLEX; }
        | delete '[' expr ']' cast_expr %prec UNARY
-               { $$ = delete_sanity ($5, $3, 2, $$ != NULL_TREE);
+               { $$ = delete_sanity ($5, $3, 2, $1);
                  if (yychar == YYEMPTY)
                    yychar = YYLEX; }
        ;
@@ -1368,33 +1249,33 @@ expr_no_commas:
        ;
 
 notype_unqualified_id:
-         '~' see_typename TYPENAME
-               {
-               destructor_name:
-                 $$ = build_parse_node (BIT_NOT_EXPR, $3);
-               }
-       | '~' see_typename IDENTIFIER
-                { goto destructor_name; }
-       | '~' see_typename PTYPENAME
-                { goto destructor_name; }
+         '~' see_typename identifier
+               { $$ = build_parse_node (BIT_NOT_EXPR, $3); }
        | operator_name
        | IDENTIFIER
        | PTYPENAME %prec EMPTY
        ;
 
+unqualified_id:
+         notype_unqualified_id
+       | TYPENAME
+       ;
+
 expr_or_declarator:
-         '*' expr_or_declarator %prec UNARY
+         notype_unqualified_id
+       | notype_qualified_id
+       | '*' expr_or_declarator %prec UNARY
                { $$ = build_parse_node (INDIRECT_REF, $2); }
        | '&' expr_or_declarator %prec UNARY
                { $$ = build_parse_node (ADDR_EXPR, $2); }
-       | notype_unqualified_id
-               { see_typename (); }
        ;
 
 direct_notype_declarator:
          complex_direct_notype_declarator
        | notype_unqualified_id
-               { see_typename (); }
+       | notype_qualified_id
+               { push_nested_class (TREE_TYPE (OP0 ($$)), 3);
+                 TREE_COMPLEXITY ($$) = current_class_depth; }
        ;
 
 primary:
@@ -1474,10 +1355,6 @@ primary:
                 }
        | primary '[' expr ']'
                { $$ = grok_array_decl ($$, $3); }
-       | object identifier_or_opname  %prec UNARY
-               { $$ = build_component_ref ($$, $2, NULL_TREE, 1); }
-       | object id_scope identifier_or_opname %prec UNARY
-               { $$ = build_object_ref ($$, $2, $3); }
        | primary PLUSPLUS
                { /* If we get an OFFSET_REF, turn it into what it really
                     means (e.g., a COMPONENT_REF).  This way if we've got,
@@ -1569,7 +1446,7 @@ primary:
        | TYPEID '(' type_id ')'
                { tree type = groktypename ($3);
                  $$ = get_typeid (type); }
-       | SCOPE IDENTIFIER
+       | global_scope IDENTIFIER
                {
                do_scoped_id:
                  $$ = IDENTIFIER_GLOBAL_VALUE ($2);
@@ -1608,19 +1485,24 @@ primary:
                    }
 
                }
-       | SCOPE operator_name
+       | global_scope operator_name
                {
+                 got_scope = NULL_TREE;
                  if (TREE_CODE ($2) == IDENTIFIER_NODE)
                    goto do_scoped_id;
                  $$ = $2;
                }
-       | id_scope identifier_or_opname  %prec HYPERUNARY
-               { $$ = build_offset_ref ($$, $2); }
-       | id_scope identifier_or_opname '(' nonnull_exprlist ')'
-               { $$ = build_member_call ($$, $2, $4); }
-       | id_scope identifier_or_opname LEFT_RIGHT
-               { $$ = build_member_call ($$, $2, NULL_TREE); }
-       | object identifier_or_opname '(' nonnull_exprlist ')'
+       | overqualified_id %prec HYPERUNARY
+               { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
+       | overqualified_id '(' nonnull_exprlist ')'
+               { $$ = build_member_call (OP0 ($$), OP1 ($$), $3); }
+       | overqualified_id LEFT_RIGHT
+               { $$ = build_member_call (OP0 ($$), OP1 ($$), NULL_TREE); }
+       | object unqualified_id  %prec UNARY
+               { $$ = build_component_ref ($$, $2, NULL_TREE, 1); }
+       | object qualified_id %prec UNARY
+               { $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
+       | object unqualified_id '(' nonnull_exprlist ')'
                {
 #if 0
                  /* This is a future direction of this code, but because
@@ -1635,7 +1517,7 @@ primary:
                                          (LOOKUP_NORMAL|LOOKUP_AGGR));
 #endif
                }
-       | object identifier_or_opname LEFT_RIGHT
+       | object unqualified_id LEFT_RIGHT
                {
 #if 0
                  /* This is a future direction of this code, but because
@@ -1650,27 +1532,27 @@ primary:
                                          (LOOKUP_NORMAL|LOOKUP_AGGR));
 #endif
                }
-       | object id_scope identifier_or_opname '(' nonnull_exprlist ')'
+       | object qualified_id '(' nonnull_exprlist ')'
                {
-                 if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE ($2)))
+                 if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
                    {
                      warning ("signature name in scope resolution ignored");
-                     $$ = build_method_call ($$, $3, $5, NULL_TREE,
+                     $$ = build_method_call ($$, OP1 ($2), $4, NULL_TREE,
                                              (LOOKUP_NORMAL|LOOKUP_AGGR));
                    }
                  else
-                   $$ = build_scoped_method_call ($$, $2, $3, $5);
+                   $$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), $4);
                }
-       | object id_scope identifier_or_opname LEFT_RIGHT
+       | object qualified_id LEFT_RIGHT
                {
-                 if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE ($2)))
+                 if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
                    {
                      warning ("signature name in scope resolution ignored");
-                     $$ = build_method_call ($$, $3, NULL_TREE, NULL_TREE,
+                     $$ = build_method_call ($$, OP1 ($2), NULL_TREE, NULL_TREE,
                                              (LOOKUP_NORMAL|LOOKUP_AGGR));
                    }
                  else
-                   $$ = build_scoped_method_call ($$, $2, $3, NULL_TREE);
+                   $$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), NULL_TREE);
                }
        /* p->int::~int() is valid -- 12.4 */
        | object '~' TYPESPEC LEFT_RIGHT
@@ -1741,17 +1623,14 @@ new:      NEW
 .scope:
        /* empty  */
                { $$ = 0; }
-       | SCOPE
-               { $$ = 1; }
+       | global_scope
+               { got_scope = NULL_TREE; $$ = 1; }
        ;
 
 delete:          DELETE
-               { $$ = NULL_TREE; }
-       | SCOPE delete
-               { if ($2)
-                   error ("extra `::' before `delete' ignored");
-                 $$ = error_mark_node;
-               }
+               { $$ = 0; }
+       | global_scope delete
+               { got_scope = NULL_TREE; $$ = 1; }
        ;
 
 /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it.  */
@@ -1782,18 +1661,16 @@ object:   primary '.'
        ;
 
 decl:
-         typed_declspecs initdecls ';'
-               {
-                 resume_momentary ($2);
-                 note_list_got_semicolon ($1);
-               }
-       | typespec initdecls ';'
-               {
-                 resume_momentary ($2);
+       /* Normal case: make this fast.  */
+         typespec declarator ';'
+               { tree d = get_decl_list ($1);
+                 int yes = suspend_momentary ();
+                 d = start_decl ($2, d, 0, NULL_TREE);
+                 finish_decl (d, NULL_TREE, NULL_TREE, 0);
+                 resume_momentary (yes);
                  if (IS_AGGR_TYPE_CODE (TREE_CODE ($1)))
                    note_got_semicolon ($1);
                }
-       /* Normal case: make this fast.  */
        | typed_declspecs declarator ';'
                { tree d = $1;
                  int yes = suspend_momentary ();
@@ -1802,29 +1679,23 @@ decl:
                  resume_momentary (yes);
                  note_list_got_semicolon ($1);
                }
-       | typespec declarator ';'
-               { tree d = get_decl_list ($1);
-                 int yes = suspend_momentary ();
-                 d = start_decl ($2, d, 0, NULL_TREE);
-                 finish_decl (d, NULL_TREE, NULL_TREE, 0);
-                 resume_momentary (yes);
+       | typespec initdecls ';'
+               {
+                 resume_momentary ($2);
                  if (IS_AGGR_TYPE_CODE (TREE_CODE ($1)))
                    note_got_semicolon ($1);
                }
-       | declmods notype_initdecls ';'
-               { resume_momentary ((int) $<itype>2); }
-       /* Normal case: make this fast.  */
-       | declmods notype_declarator ';'
-               { tree d;
-                 int yes = suspend_momentary ();
-                 d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE);
-                 finish_decl (d, NULL_TREE, NULL_TREE, 0);
-                 resume_momentary (yes);
+       | typed_declspecs initdecls ';'
+               {
+                 resume_momentary ($2);
+                 note_list_got_semicolon ($1);
                }
+       | declmods notype_initdecls ';'
+               { resume_momentary ($2); }
        | typed_declspecs ';'
                {
-                 shadow_tag ($<ttype>$);
-                 note_list_got_semicolon ($<ttype>$);
+                 shadow_tag ($1);
+                 note_list_got_semicolon ($1);
                }
        | declmods ';'
                { warning ("empty declaration"); }
@@ -1950,22 +1821,7 @@ reserved_typespecquals:
 
 typespec: structsp
        | TYPESPEC  %prec EMPTY
-       | TYPENAME  %prec EMPTY
-       | scoped_typename %prec EMPTY
-       | SCOPE TYPENAME %prec EMPTY
-               { $$ = IDENTIFIER_GLOBAL_VALUE ($2);
-                  if (!$$)
-                   {
-                      error ("undeclared variable `%s' (first use here)",
-                      IDENTIFIER_POINTER ($2));
-                      $$ = error_mark_node;
-                      IDENTIFIER_GLOBAL_VALUE ($2) = error_mark_node;
-                   }
-                 else 
-                   {
-                     $$ = TREE_TYPE($$);
-                   }
-               }
+       | complete_type_name
        | TYPEOF '(' expr ')'
                { $$ = TREE_TYPE ($3);
                  if (pedantic)
@@ -2002,7 +1858,6 @@ typespec: structsp
                      $$ = error_mark_node;
                    }
                }
-       | template_type %prec EMPTY
        ;
 
 /* A typespec that is a reserved word, or a type qualifier.  */
@@ -2022,6 +1877,11 @@ notype_initdecls:
        | notype_initdecls ',' initdcl
        ;
 
+nomods_initdecls:
+         nomods_initdcl0
+       | nomods_initdecls ',' initdcl
+       ;
+
 maybeasm:
          /* empty */
                { $$ = NULL_TREE; }
@@ -2098,6 +1958,25 @@ notype_initdcl0:
                  finish_decl (d, NULL_TREE, $3, 0); }
        ;
 
+nomods_initdcl0:
+         notype_declarator maybe_raises maybeasm maybe_attribute '='
+               { current_declspecs = NULL_TREE;
+                 $<itype>5 = suspend_momentary ();
+                 $<ttype>$ = start_decl ($1, current_declspecs, 1, $2);
+                 cplus_decl_attributes ($<ttype>$, $4); }
+         init
+/* Note how the declaration of the variable is in effect while its init is parsed! */
+               { finish_decl ($<ttype>6, $7, $3, 0);
+                 $$ = $<itype>5; }
+       | notype_declarator maybe_raises maybeasm maybe_attribute
+               { tree d;
+                 current_declspecs = NULL_TREE;
+                 $$ = suspend_momentary ();
+                 d = start_decl ($1, current_declspecs, 0, $2);
+                 cplus_decl_attributes (d, $4);
+                 finish_decl (d, NULL_TREE, $3, 0); }
+       ;
+
 /* the * rules are dummies to accept the Apollo extended syntax
    so that the header files compile. */
 maybe_attribute:
@@ -2223,6 +2102,8 @@ structsp:
                  check_for_missing_semicolon ($$); }
        | ENUM identifier
                { $$ = xref_tag (enum_type_node, $2, NULL_TREE, 0); }
+       | ENUM complex_type_name
+               { $$ = xref_tag (enum_type_node, $2, NULL_TREE, 0); }
 
        /* C++ extensions, merged with C to avoid shift/reduce conflicts */
        | class_head left_curly opt.component_decl_list '}'
@@ -2319,11 +2200,11 @@ aggr:     AGGR
 
 named_class_head_sans_basetype:
          aggr identifier
-               { aggr1: current_aggr = $$; $$ = $2; }
-       | aggr template_type_name  %prec EMPTY
                { current_aggr = $$; $$ = $2; }
-       | aggr TYPENAME_COLON
-               { yyungetc (':', 1); goto aggr1; }
+       | aggr complex_type_name
+               { current_aggr = $$; $$ = $2; }
+       | aggr template_type %prec EMPTY
+               { current_aggr = $$; $$ = $2; }
        | aggr template_type_name '{'
                { yyungetc ('{', 1);
                aggr2:
@@ -2415,10 +2296,6 @@ base_class:
                  else
                    $$ = build_tree_list ((tree)access_default, $$);
                }
-       | scoped_base_class
-               {
-                 goto do_base_class1;
-               }
        | base_class_access_list base_class.1
                {
                  tree type;
@@ -2448,36 +2325,10 @@ base_class:
                  else
                    $$ = build_tree_list ((tree) $$, $2);
                }
-       | base_class_access_list scoped_base_class
-               {
-                 goto do_base_class2;
-               }
        ;
 
-scoped_base_class:
-         base_class.1 SCOPED_TYPENAME
-               {
-                 /* Kludge!!! See rule "template_type" and the code
-                  * dealing with "template_type_seen_before_scope" in
-                  * yylex(). */
-                 $$ = $2;
-               }
-       ;
 base_class.1:
-         template_type_name tmpl.2 template_instantiation
-               {
-                 extern tree template_type_seen_before_scope;
-                 tree id = $3 ? TYPE_IDENTIFIER ($3) : $1;
-
-                 /* Check the rule template_type to get this... */
-                 if (yychar == YYEMPTY)
-                   yychar = YYLEX;
-                 if (yychar == SCOPE) {
-                   template_type_seen_before_scope = id;
-                   yychar = YYLEX;
-                 }
-               }
-       | identifier
+         complete_type_name
        | SIGOF '(' expr ')'
                {
                  if (current_aggr == signature_type_node)
@@ -2585,9 +2436,11 @@ left_curly: '{'
                     }
                  pushclass ($<ttype>0, 0);
                  TYPE_BEING_DEFINED ($<ttype>0) = 1;
+#if 0
                  t = TYPE_IDENTIFIER ($<ttype>0);
                  if (t && IDENTIFIER_TEMPLATE (t))
                    overload_template_name (t, 1);
+#endif
                }
        ;
 
@@ -2642,81 +2495,58 @@ component_decl_list:
        ;
 
 component_decl:
-       /* Do not add a "typed_declspecs declarator ';'" rule here for
+         component_decl_1 ';'
+       | component_decl_1 '}'
+               { error ("missing ';' before right brace");
+                 yyungetc ('}', 0); }
+       /* C++: handle constructors, destructors and inline functions */
+       /* note that INLINE is like a TYPESPEC */
+       | fn.def2 ':' /* base_init compstmt */
+               { $$ = finish_method ($$); }
+       | fn.def2 '{' /* nodecls compstmt */
+               { $$ = finish_method ($$); }
+       ;
+
+component_decl_1:
+       /* Do not add a "typed_declspecs declarator" rule here for
           speed; we need to call grok_x_components for enums, so the
           speedup would be insignificant.  */
-         typed_declspecs components ';'
+         typed_declspecs components
                {
                  $$ = grok_x_components ($$, $2);
                  end_exception_decls ();
                }
-       /* These rules introduce a reduce/reduce conflict; in
-               typedef int foo, bar;
-               class A {
-                 foo (bar);
-               };
-          should "A::foo" be declared as a function or data member?  
-          In other words, is "bar" an after_type_declarator or a parmlist? */
-       | typed_declspecs '(' parmlist ')' ';'
-               { $$ = groktypefield ($$, $3); }
-       | typed_declspecs '(' parmlist ')' '}'
-               { error ("missing ';' before right brace");
-                 yyungetc ('}', 0);
-                 $$ = groktypefield ($$, $3); }
-       | typed_declspecs LEFT_RIGHT ';'
-               { $$ = groktypefield ($$, empty_parms ()); }
-       | typed_declspecs LEFT_RIGHT '}'
-               { error ("missing ';' before right brace");
-                 yyungetc ('}', 0);
-                 $$ = groktypefield ($$, empty_parms ()); }
-       | declmods notype_components ';'
+       | declmods notype_components
                { 
                  $$ = grok_x_components ($$, $2);
                  end_exception_decls ();
                }
-       /* Normal case: make this fast.  */
-       | declmods notype_declarator ';'
-               { $$ = grokfield ($<ttype>2, $<ttype>$,
-                                 NULL_TREE, NULL_TREE, NULL_TREE); }
-       | declmods notype_components '}'
-               { error ("missing ';' before right brace");
-                 yyungetc ('}', 0);
-                 $$ = grok_x_components ($$, $2);
-                 end_exception_decls ();
-               }
-       | declmods '(' parmlist ')' ';'
-               { $$ = groktypefield ($$, $3); }
-       | declmods '(' parmlist ')' '}'
-               { error ("missing ';' before right brace");
-                 yyungetc ('}', 0);
-                 $$ = groktypefield ($$, $3); }
-       | declmods LEFT_RIGHT ';'
-               { $$ = groktypefield ($$, empty_parms ()); }
-       | declmods LEFT_RIGHT '}'
-               { error ("missing ';' before right brace");
-                 yyungetc ('}', 0);
-                 $$ = groktypefield ($$, empty_parms ()); }
-       | ':' expr_no_commas ';'
+       | notype_declarator maybe_raises maybeasm maybe_attribute
+               { $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, $3);
+                 cplus_decl_attributes ($$, $4); }
+       | ':' expr_no_commas
                { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
-       | ':' expr_no_commas '}'
-               { error ("missing ';' before right brace");
-                 yyungetc ('}', 0);
-                 $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
        | error
                { $$ = NULL_TREE; }
 
-       /* C++: handle constructors, destructors and inline functions */
-       /* note that INLINE is like a TYPESPEC */
-       | fn.def2 ':' /* base_init compstmt */
-               { $$ = finish_method ($$); }
-       | fn.def2 '{' /* nodecls compstmt */
-               { $$ = finish_method ($$); }
-       | notype_declarator maybe_raises ';'
-               { $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, NULL_TREE); }
-       | notype_declarator maybe_raises '}'
-               { error ("missing ';' before right brace");
-                 yyungetc ('}', 0);
-                 $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, NULL_TREE); }
+       /* These rules introduce a reduce/reduce conflict; in
+               typedef int foo, bar;
+               class A {
+                 foo (bar);
+               };
+          should "A::foo" be declared as a function or "A::bar" as a data
+          member? In other words, is "bar" an after_type_declarator or a
+          parmlist? */
+       | typed_declspecs '(' parmlist ')' type_quals
+               { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
+                                        $3, $5);
+                 $$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE,
+                                 NULL_TREE); }
+       | typed_declspecs LEFT_RIGHT type_quals
+               { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
+                                        empty_parms (), $3);
+                 $$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE,
+                                 NULL_TREE); }
        ;
 
 /* The case of exactly one component is handled directly by component_decl. */
@@ -2850,13 +2680,6 @@ new_type_id:
                { $$ = build_decl_list ($$, NULL_TREE); }
        ;
 
-/* ANSI abstract-declarator (8.1) */
-absdcl:
-         absdcl1  %prec EMPTY
-       | START_DECLARATOR absdcl1  %prec EMPTY
-               { $$ = $2; }
-       ;
-
 type_quals:
          /* empty */ %prec EMPTY
                { $$ = NULL_TREE; }
@@ -2883,32 +2706,31 @@ nonmomentary_expr:
 /* A declarator that is allowed only after an explicit typespec.  */
 /* may all be followed by prec '.' */
 after_type_declarator:
-         after_type_declarator1
-       | START_DECLARATOR after_type_declarator1
-               { $$ = $2; }
-       ;
-
-after_type_declarator1:
-         '*' nonempty_type_quals after_type_declarator1  %prec UNARY
+         '*' nonempty_type_quals after_type_declarator  %prec UNARY
                { $$ = make_pointer_declarator ($2, $3); }
-       | '&' nonempty_type_quals after_type_declarator1  %prec UNARY
+       | '&' nonempty_type_quals after_type_declarator  %prec UNARY
                { $$ = make_reference_declarator ($2, $3); }
-       | '*' after_type_declarator1  %prec UNARY
+       | '*' after_type_declarator  %prec UNARY
                { $$ = make_pointer_declarator (NULL_TREE, $2); }
-       | '&' after_type_declarator1  %prec UNARY
+       | '&' after_type_declarator  %prec UNARY
                { $$ = make_reference_declarator (NULL_TREE, $2); }
-       | id_scope '*' type_quals after_type_declarator1
-               { tree arg = make_pointer_declarator ($3, $4);
-                 if (TREE_CODE ($$) != SCOPE_REF)
-                   $$ = build_push_scope ($$, arg);
-                 else if (TREE_OPERAND ($$, 1) == NULL_TREE)
-                   TREE_OPERAND ($$, 1) = arg;
-                 else
-                   $$ = build_parse_node (SCOPE_REF, $$, arg);
+       | ptr_to_mem type_quals after_type_declarator
+               { tree arg = make_pointer_declarator ($2, $3);
+                 $$ = build_parse_node (SCOPE_REF, $1, arg);
                }
        | direct_after_type_declarator
        ;
 
+qualified_type_name:
+         type_name %prec EMPTY
+       | nested_type
+       ;
+
+nested_type:
+       nested_name_specifier type_name %prec EMPTY
+               { $$ = $2; }
+       ;
+
 direct_after_type_declarator:
          direct_after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
                { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
@@ -2922,58 +2744,46 @@ direct_after_type_declarator:
                { $$ = build_parse_node (ARRAY_REF, $$, $3); }
        | direct_after_type_declarator '[' ']'
                { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
-       | '(' after_type_declarator1 ')'
+       | '(' after_type_declarator ')'
                { $$ = $2; }
-       | TYPENAME %prec EMPTY
+       | nested_name_specifier type_name %prec EMPTY
+               { push_nested_class (TREE_TYPE ($$), 3);
+                 $$ = build_parse_node (SCOPE_REF, $$, $2);
+                 TREE_COMPLEXITY ($$) = current_class_depth; }
+       | type_name %prec EMPTY
        ;
 
 /* A declarator allowed whether or not there has been
    an explicit typespec.  These cannot redeclare a typedef-name.  */
 
 notype_declarator:
-          notype_declarator1
-        | START_DECLARATOR notype_declarator1
-               { $$ = $2; }
-       ;
-
-notype_declarator1:
-         '*' nonempty_type_quals notype_declarator1  %prec UNARY
+         '*' nonempty_type_quals notype_declarator  %prec UNARY
                { $$ = make_pointer_declarator ($2, $3); }
-       | '&' nonempty_type_quals notype_declarator1  %prec UNARY
+       | '&' nonempty_type_quals notype_declarator  %prec UNARY
                { $$ = make_reference_declarator ($2, $3); }
-       | '*' notype_declarator1  %prec UNARY
+       | '*' notype_declarator  %prec UNARY
                { $$ = make_pointer_declarator (NULL_TREE, $2); }
-       | '&' notype_declarator1  %prec UNARY
+       | '&' notype_declarator  %prec UNARY
                { $$ = make_reference_declarator (NULL_TREE, $2); }
-       | id_scope '*' type_quals notype_declarator1
-               { tree arg = make_pointer_declarator ($3, $4);
-                 if (TREE_CODE ($$) != SCOPE_REF)
-                   $$ = build_push_scope ($$, arg);
-                 else if (TREE_OPERAND ($$, 1) == NULL_TREE)
-                   TREE_OPERAND ($$, 1) = arg;
-                 else
-                   $$ = build_parse_node (SCOPE_REF, $$, arg);
+       | ptr_to_mem type_quals notype_declarator
+               { tree arg = make_pointer_declarator ($2, $3);
+                 $$ = build_parse_node (SCOPE_REF, $1, arg);
                }
        | direct_notype_declarator
        ;
 
-complex_notype_declarator1:
-         '*' nonempty_type_quals notype_declarator1  %prec UNARY
+complex_notype_declarator:
+         '*' nonempty_type_quals notype_declarator  %prec UNARY
                { $$ = make_pointer_declarator ($2, $3); }
-       | '&' nonempty_type_quals notype_declarator1  %prec UNARY
+       | '&' nonempty_type_quals notype_declarator  %prec UNARY
                { $$ = make_reference_declarator ($2, $3); }
-       | '*' complex_notype_declarator1  %prec UNARY
+       | '*' complex_notype_declarator  %prec UNARY
                { $$ = make_pointer_declarator (NULL_TREE, $2); }
-       | '&' complex_notype_declarator1  %prec UNARY
+       | '&' complex_notype_declarator  %prec UNARY
                { $$ = make_reference_declarator (NULL_TREE, $2); }
-       | id_scope '*' type_quals notype_declarator1
-               { tree arg = make_pointer_declarator ($3, $4);
-                 if (TREE_CODE ($$) != SCOPE_REF)
-                   $$ = build_push_scope ($$, arg);
-                 else if (TREE_OPERAND ($$, 1) == NULL_TREE)
-                   TREE_OPERAND ($$, 1) = arg;
-                 else
-                   $$ = build_parse_node (SCOPE_REF, $$, arg);
+       | ptr_to_mem type_quals notype_declarator
+               { tree arg = make_pointer_declarator ($2, $3);
+                 $$ = build_parse_node (SCOPE_REF, $1, arg);
                }
        | complex_direct_notype_declarator
        ;
@@ -2989,40 +2799,30 @@ complex_direct_notype_declarator:
                { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
        | '(' expr_or_declarator ')'
                { $$ = finish_decl_parsing ($2); }
-       | '(' complex_notype_declarator1 ')'
+       | '(' complex_notype_declarator ')'
                { $$ = $2; }
        | direct_notype_declarator '[' nonmomentary_expr ']'
                { $$ = build_parse_node (ARRAY_REF, $$, $3); }
        | direct_notype_declarator '[' ']'
                { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
+       ;
 
-       /* C++ extensions.  */
-       | id_scope see_typename notype_unqualified_id
-               { see_typename ();
-                 if (TREE_CODE ($$) != SCOPE_REF)
-                   $$ = build_push_scope ($$, $3);
-                 else if (TREE_OPERAND ($$, 1) == NULL_TREE)
-                   TREE_OPERAND ($$, 1) = $3;
-                 else
-                   $$ = build_parse_node (SCOPE_REF, $$, $3);
-               }
-       | id_scope see_typename TYPENAME
-               { $$ = build_push_scope ($$, $3); }
-       | SCOPE see_typename direct_notype_declarator
-               { $$ = build_parse_node (SCOPE_REF, NULL_TREE, $3); }
-       | template_type SCOPED_NAME 
-               { tree t;
-                 extern int current_class_depth;
+qualified_id:
+       nested_name_specifier unqualified_id
+               { got_scope = NULL_TREE;
+                 $$ = build_parse_node (SCOPE_REF, $$, $2); }
+       ;
 
-                 t = TREE_TYPE(TREE_OPERAND($2, 0));
-                 if (t != current_class_type &&
-                     TREE_CODE(t) != TEMPLATE_TYPE_PARM)
-                   {
-                     push_nested_class(t, 3);
-                     TREE_COMPLEXITY ($2) = current_class_depth;
-                   }
-                 $$ = $2; 
-               }
+notype_qualified_id:
+       nested_name_specifier notype_unqualified_id
+               { got_scope = NULL_TREE;
+                 $$ = build_parse_node (SCOPE_REF, $$, $2); }
+       ;
+
+overqualified_id:
+         notype_qualified_id
+       | global_scope notype_qualified_id
+               { $$ = $2; }
        ;
 
 functional_cast:
@@ -3034,61 +2834,60 @@ functional_cast:
                { $$ = reparse_absdcl_as_expr ($$, $2); }
        ;
 
-id_scope: typename_scope
-               { tree t;
-                  do_id_scope:
+type_name:
+         TYPENAME
+       | template_type %prec EMPTY
+       ;
 
-                 t = resolve_scope_to_name (NULL_TREE, $$);
-                 if (t == NULL_TREE)
-                   {
-                     cp_error ("`%T' is not a valid scope", $$);
-                     $$ = error_mark_node; 
-                   }
-                 else
-                   $$ = t;
-               }
+nested_name_specifier:
+         nested_name_specifier_1
+       | nested_name_specifier nested_name_specifier_1
+               { $$ = $2; }
+       ;
+
+/* Why the @#$%^& do type_name and notype_identifier need to be expanded
+   inline here?!?  (jason) */
+nested_name_specifier_1:
+         TYPENAME SCOPE
+               { got_scope = TREE_TYPE ($$); }
+       | template_type SCOPE
+               { got_scope = TREE_TYPE ($$); }
+/*     These break 'const i;'
        | IDENTIFIER SCOPE
-               { goto do_id_scope; }
-       | template_type SCOPE /* try_for_typename %prec EMPTY */
                {
-                  if ($$ == error_mark_node)
-                    /* leave it alone */;
-                  else
-                   {
-                     $$ = resolve_scope_to_name (NULL_TREE, TYPE_IDENTIFIER ($$));
-                     if ($$ == NULL_TREE)
-                       {
-                         error ("undefined explicitly scoped type");
-                         $$ = error_mark_node; 
-                       }
-                   }
-/*                  if ($3) popclass (1); */
+                failed_scope:
+                 cp_error ("`%D' is not an aggregate typedef", 
+                           lastiddecl ? lastiddecl : $$);
+                 $$ = error_mark_node;
                }
+       | PTYPENAME SCOPE
+               { goto failed_scope; } */
        ;
 
-typename_scope:
-       TYPENAME SCOPE;
+complete_type_name:
+         qualified_type_name
+       | global_scope qualified_type_name
+               { $$ = $2; }
+       ;
 
-scoped_typename: SCOPED_TYPENAME
-       | template_type SCOPED_TYPENAME
-               {
-                 /* Kludge!!! See rule "template_type" and the code
-                  * dealing with "template_type_seen_before_scope" in
-                  * yylex(). */
-                 $$ = $2;
-               }
-/*     | template_type SCOPE try_for_typename TYPENAME
-               {
-                  if ($$ == error_mark_node)
-                    ;
-                 else
-                   {
-                      $$ = build_parse_node (SCOPE_REF,
-                                             TYPE_IDENTIFIER ($$),
-                                             $4);
-                    }
-                 if ($3) popclass (1);
-               } */
+complex_type_name:
+         nested_type
+       | global_scope qualified_type_name
+               { $$ = $2; }
+       ;
+
+ptr_to_mem:
+         nested_name_specifier '*'
+               { got_scope = NULL_TREE; }
+       | global_scope nested_name_specifier '*'
+               { $$ = $2; got_scope = NULL_TREE; }
+       ;
+
+/* All uses of explicit global scope must go through this nonterminal so
+   that got_scope will be set before yylex is called to get the next token. */
+global_scope:
+         SCOPE
+               { got_scope = void_type_node; }
        ;
 
 /* ANSI new-declarator (5.3.4) */
@@ -3101,23 +2900,13 @@ new_declarator:
                { $$ = make_reference_declarator ($2, $3); }
        | '&' type_quals %prec EMPTY
                { $$ = make_reference_declarator ($2, NULL_TREE); }
-       | id_scope '*' type_quals %prec EMPTY
-               { tree arg = make_pointer_declarator ($3, NULL_TREE);
-                 if (TREE_CODE ($$) != SCOPE_REF)
-                   $$ = build_push_scope ($$, arg);
-                 else if (TREE_OPERAND ($$, 1) == NULL_TREE)
-                   TREE_OPERAND ($$, 1) = arg;
-                 else
-                   $$ = build_parse_node (SCOPE_REF, $$, arg);
+       | ptr_to_mem type_quals %prec EMPTY
+               { tree arg = make_pointer_declarator ($2, NULL_TREE);
+                 $$ = build_parse_node (SCOPE_REF, $1, arg);
                }
-       | id_scope '*' type_quals new_declarator
-               { tree arg = make_pointer_declarator ($3, $4);
-                 if (TREE_CODE ($$) != SCOPE_REF)
-                   $$ = build_push_scope ($$, arg);
-                 else if (TREE_OPERAND ($$, 1) == NULL_TREE)
-                   TREE_OPERAND ($$, 1) = arg;
-                 else
-                   $$ = build_parse_node (SCOPE_REF, $$, arg);
+       | ptr_to_mem type_quals new_declarator
+               { tree arg = make_pointer_declarator ($2, $3);
+                 $$ = build_parse_node (SCOPE_REF, $1, arg);
                }
        | direct_new_declarator %prec EMPTY
        ;
@@ -3131,48 +2920,36 @@ direct_new_declarator:
        ;
 
 /* ANSI abstract-declarator (8.1) */
-absdcl1:
-         '*' nonempty_type_quals absdcl1
+absdcl:
+         '*' nonempty_type_quals absdcl
                { $$ = make_pointer_declarator ($2, $3); }
-       | '*' absdcl1
+       | '*' absdcl
                { $$ = make_pointer_declarator (NULL_TREE, $2); }
        | '*' type_quals  %prec EMPTY
                { $$ = make_pointer_declarator ($2, NULL_TREE); }
-       | '&' nonempty_type_quals absdcl1
+       | '&' nonempty_type_quals absdcl
                { $$ = make_reference_declarator ($2, $3); }
-       | '&' absdcl1
+       | '&' absdcl
                { $$ = make_reference_declarator (NULL_TREE, $2); }
        | '&' type_quals %prec EMPTY
                { $$ = make_reference_declarator ($2, NULL_TREE); }
-       | id_scope '*' type_quals %prec EMPTY
-               { tree arg = make_pointer_declarator ($3, NULL_TREE);
-                 if (TREE_CODE ($$) != SCOPE_REF)
-                   $$ = build_push_scope ($$, arg);
-                 else if (TREE_OPERAND ($$, 1) == NULL_TREE)
-                   TREE_OPERAND ($$, 1) = arg;
-                 else
-                   $$ = build_parse_node (SCOPE_REF, $$, arg);
+       | ptr_to_mem type_quals %prec EMPTY
+               { tree arg = make_pointer_declarator ($2, NULL_TREE);
+                 $$ = build_parse_node (SCOPE_REF, $1, arg);
                }
-       | id_scope '*' type_quals absdcl1
-               { tree arg = make_pointer_declarator ($3, $4);
-                 if (TREE_CODE ($$) != SCOPE_REF)
-                   $$ = build_push_scope ($$, arg);
-                 else if (TREE_OPERAND ($$, 1) == NULL_TREE)
-                   TREE_OPERAND ($$, 1) = arg;
-                 else
-                   $$ = build_parse_node (SCOPE_REF, $$, arg);
+       | ptr_to_mem type_quals absdcl
+               { tree arg = make_pointer_declarator ($2, $3);
+                 $$ = build_parse_node (SCOPE_REF, $1, arg);
                }
        | direct_abstract_declarator %prec EMPTY
        ;
 
 /* ANSI direct-abstract-declarator (8.1) */
 direct_abstract_declarator:
-         '(' absdcl1 ')'
-               { see_typename ();
-                 $$ = $2; }
+         '(' absdcl ')'
+               { $$ = $2; }
          /* `(typedef)1' is `int'.  */
        | PAREN_STAR_PAREN
-               { see_typename (); }
        | direct_abstract_declarator '(' parmlist ')' type_quals  %prec '.'
                { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
        | direct_abstract_declarator LEFT_RIGHT type_quals  %prec '.'
@@ -3813,11 +3590,6 @@ label_colon:
                }
        | PTYPENAME ':'
                { goto do_label; }
-       | TYPENAME_COLON
-               { tree label = define_label (input_filename, lineno, $1);
-                 if (label)
-                   expand_label (label);
-               }
        ;
 
 try_head: TRY '{' { cplus_expand_start_try (0); } .pushlevel
@@ -4160,23 +3932,17 @@ named_parm:
        /* Here we expand typed_declspecs inline to avoid mis-parsing of
           TYPESPEC IDENTIFIER.  */
          typed_declspecs1 declarator
-               { $$ = build_tree_list ($$, $2);
-                 see_typename (); }
+               { $$ = build_tree_list ($$, $2); }
        | typed_typespecs declarator
-               { $$ = build_tree_list ($$, $2);
-                 see_typename (); }
+               { $$ = build_tree_list ($$, $2); }
        | typespec declarator
-               { $$ = build_tree_list (get_decl_list ($$), $2);
-                 see_typename (); }
+               { $$ = build_tree_list (get_decl_list ($$), $2); }
        | typed_declspecs1 absdcl
-               { $$ = build_tree_list ($$, $2);
-                 see_typename (); }
+               { $$ = build_tree_list ($$, $2); }
        | typed_declspecs1 %prec EMPTY
-               { $$ = build_tree_list ($$, NULL_TREE);
-                 see_typename (); }
+               { $$ = build_tree_list ($$, NULL_TREE); }
        | declmods notype_declarator
-               { $$ = build_tree_list ($$, $2);
-                 see_typename (); }
+               { $$ = build_tree_list ($$, $2); }
        ;
 
 parm:
@@ -4235,13 +4001,10 @@ raise_identifier:
                { $$ = build_decl_list (NULL_TREE, $$); }
        | TYPENAME
                { $$ = build_decl_list (NULL_TREE, $$); }
-       | SCOPE IDENTIFIER
-               { $$ = build_decl_list (void_type_node, $2); }
-       | SCOPE TYPENAME
-               { $$ = build_decl_list (void_type_node, $2); }
-       | id_scope IDENTIFIER
-               { $$ = build_decl_list ($$, $2); }
-       | scoped_typename
+       | global_scope IDENTIFIER
+               { $$ = build_decl_list (NULL_TREE, $2); }
+       | global_scope TYPENAME
+               { $$ = build_decl_list (NULL_TREE, $2); }
        ;
 
 ansi_raise_identifier:
@@ -4274,87 +4037,87 @@ conversion_declarator:
                { $$ = make_pointer_declarator ($2, $3); }
        | '&' type_quals conversion_declarator
                { $$ = make_reference_declarator ($2, $3); }
-       | id_scope '*' type_quals conversion_declarator
-               { tree arg = make_pointer_declarator ($3, $4);
-                 if (TREE_CODE ($$) != SCOPE_REF)
-                   $$ = build_push_scope ($$, arg);
-                 else if (TREE_OPERAND ($$, 1) == NULL_TREE)
-                   TREE_OPERAND ($$, 1) = arg;
-                 else
-                   $$ = build_parse_node (SCOPE_REF, $$, arg);
+       | ptr_to_mem type_quals conversion_declarator
+               { tree arg = make_pointer_declarator ($2, $3);
+                 $$ = build_parse_node (SCOPE_REF, $1, arg);
                }
        ;
 
+operator: OPERATOR
+               { got_scope = NULL_TREE; }
+       ;
+
 operator_name:
-         OPERATOR '*'
+         operator '*'
                { $$ = ansi_opname[MULT_EXPR]; }
-       | OPERATOR '/'
+       | operator '/'
                { $$ = ansi_opname[TRUNC_DIV_EXPR]; }
-       | OPERATOR '%'
+       | operator '%'
                { $$ = ansi_opname[TRUNC_MOD_EXPR]; }
-       | OPERATOR '+'
+       | operator '+'
                { $$ = ansi_opname[PLUS_EXPR]; }
-       | OPERATOR '-'
+       | operator '-'
                { $$ = ansi_opname[MINUS_EXPR]; }
-       | OPERATOR '&'
+       | operator '&'
                { $$ = ansi_opname[BIT_AND_EXPR]; }
-       | OPERATOR '|'
+       | operator '|'
                { $$ = ansi_opname[BIT_IOR_EXPR]; }
-       | OPERATOR '^'
+       | operator '^'
                { $$ = ansi_opname[BIT_XOR_EXPR]; }
-       | OPERATOR '~'
+       | operator '~'
                { $$ = ansi_opname[BIT_NOT_EXPR]; }
-       | OPERATOR ','
+       | operator ','
                { $$ = ansi_opname[COMPOUND_EXPR]; }
-       | OPERATOR ARITHCOMPARE
+       | operator ARITHCOMPARE
                { $$ = ansi_opname[$2]; }
-       | OPERATOR '<'
+       | operator '<'
                { $$ = ansi_opname[LT_EXPR]; }
-       | OPERATOR '>'
+       | operator '>'
                { $$ = ansi_opname[GT_EXPR]; }
-       | OPERATOR EQCOMPARE
+       | operator EQCOMPARE
                { $$ = ansi_opname[$2]; }
-       | OPERATOR ASSIGN
+       | operator ASSIGN
                { $$ = ansi_assopname[$2]; }
-       | OPERATOR '='
+       | operator '='
                { $$ = ansi_opname [MODIFY_EXPR]; }
-       | OPERATOR LSHIFT
+       | operator LSHIFT
                { $$ = ansi_opname[$2]; }
-       | OPERATOR RSHIFT
+       | operator RSHIFT
                { $$ = ansi_opname[$2]; }
-       | OPERATOR PLUSPLUS
+       | operator PLUSPLUS
                { $$ = ansi_opname[POSTINCREMENT_EXPR]; }
-       | OPERATOR MINUSMINUS
+       | operator MINUSMINUS
                { $$ = ansi_opname[PREDECREMENT_EXPR]; }
-       | OPERATOR ANDAND
+       | operator ANDAND
                { $$ = ansi_opname[TRUTH_ANDIF_EXPR]; }
-       | OPERATOR OROR
+       | operator OROR
                { $$ = ansi_opname[TRUTH_ORIF_EXPR]; }
-       | OPERATOR '!'
+       | operator '!'
                { $$ = ansi_opname[TRUTH_NOT_EXPR]; }
-       | OPERATOR '?' ':'
+       | operator '?' ':'
                { $$ = ansi_opname[COND_EXPR]; }
-       | OPERATOR MIN_MAX
+       | operator MIN_MAX
                { $$ = ansi_opname[$2]; }
-       | OPERATOR POINTSAT  %prec EMPTY
+       | operator POINTSAT  %prec EMPTY
                { $$ = ansi_opname[COMPONENT_REF]; }
-       | OPERATOR POINTSAT_STAR  %prec EMPTY
+       | operator POINTSAT_STAR  %prec EMPTY
                { $$ = ansi_opname[MEMBER_REF]; }
-       | OPERATOR LEFT_RIGHT
+       | operator LEFT_RIGHT
                { $$ = ansi_opname[CALL_EXPR]; }
-       | OPERATOR '[' ']'
+       | operator '[' ']'
                { $$ = ansi_opname[ARRAY_REF]; }
-       | OPERATOR NEW
+       | operator NEW %prec EMPTY
                { $$ = ansi_opname[NEW_EXPR]; }
-       | OPERATOR DELETE
+       | operator DELETE %prec EMPTY
                { $$ = ansi_opname[DELETE_EXPR]; }
-/*     | OPERATOR NEW '[' ']'
+       | operator NEW '[' ']'
                { $$ = ansi_opname[VEC_NEW_EXPR]; }
-       | OPERATOR DELETE '[' ']'
-               { $$ = ansi_opname[VEC_DELETE_EXPR]; }  */
-       | OPERATOR typed_typespecs conversion_declarator
+       | operator DELETE '[' ']'
+               { $$ = ansi_opname[VEC_DELETE_EXPR]; }
+       /* Should we be pushing into class scope to parse this?  */
+       | operator typed_typespecs conversion_declarator
                { $$ = grokoptypename ($2, $3); }
-       | OPERATOR error
+       | operator error
                { $$ = ansi_opname[ERROR_MARK]; }
        ;
 
index e9810e1177162d52cc9a5577e298bbfce9fb3848..ef2fbb28f1ac56dce8c0129a84b4b2dff6219cdd 100644 (file)
@@ -1690,6 +1690,7 @@ instantiate_template (tmpl, targ_ptr)
   return fndecl;
 }
 
+/* classlevel should now never be true.  jason 4/12/94 */
 void
 undo_template_name_overload (id, classlevel)
      tree id;
@@ -1711,6 +1712,7 @@ undo_template_name_overload (id, classlevel)
 #endif
 }
 
+/* classlevel should now never be true.  jason 4/12/94 */
 void
 overload_template_name (id, classlevel)
      tree id;
@@ -1731,12 +1733,9 @@ overload_template_name (id, classlevel)
 
 #if 1 /* XXX */
   /* This was a botch... names of templates do not get their own private
-     scopes.  Rather, the names of generated template instances should
-     just get pushed into whatever scope we happen to be in at the moment.
-     This will typically (but not always) be the global scope.  (Maybe
-     what we really want to do here is a `push_to_toplevel' and then stay
-     there while we are generating the instance; popping back out to the
-     current scope when we are done generating the instance.)  */
+     scopes.  Rather, they should go into the binding level already created
+     by push_template_decls.  Except that there isn't one of those for
+     specializations.  */
   if (!classlevel)
     {
       pushlevel (1);
@@ -1765,20 +1764,13 @@ overload_template_name (id, classlevel)
   if (classlevel)
     pushdecl_class_level (decl);
   else
-#if 0 /* not yet, should get fixed properly later */
     pushdecl (decl);
-  pushlevel (1);
-#else
-    {
-      pushdecl (decl);
-      /* @@ Is this necessary now?  */
-      IDENTIFIER_LOCAL_VALUE (template) = decl;
-    }
-#endif
 
+#if 0 /* This seems bogus to me; if it isn't, explain why.  (jason) */
   /* Fake this for now, just to make dwarfout.c happy.  It will have to
      be done in a proper way later on.  */
   DECL_CONTEXT (decl) = t;
+#endif
 }
 
 /* NAME is the IDENTIFIER value of a PRE_PARSED_CLASS_DECL. */
@@ -2028,6 +2020,22 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
        return 0;
       else if (targs[idx])
        {
+         tree t = targs[idx];
+         if (TREE_CODE (t) == TREE_CODE (arg))
+           switch (TREE_CODE (arg))
+             {
+             case INTEGER_CST:
+               if (tree_int_cst_equal (t, arg))
+                 return 0;
+               break;
+             case REAL_CST:
+               if (REAL_VALUES_EQUAL (TREE_REAL_CST (t), TREE_REAL_CST (arg)))
+                 return 0;
+               break;
+             /* STRING_CST values are not valid template const parms.  */
+             default:
+               ;
+             }
          my_friendly_abort (87);
          return 1;
        }
@@ -2306,3 +2314,18 @@ do_function_instantiation (declspecs, declarator)
   if (!result)
     cp_error ("no matching template for `%D' found", decl);
 }
+
+tree
+create_nested_upt (scope, name)
+     tree scope, name;
+{
+  tree t = make_lang_type (UNINSTANTIATED_P_TYPE);
+  tree d = build_lang_decl (TYPE_DECL, name, t);
+
+  TYPE_NAME (t) = d;
+  TYPE_VALUES (t) = TYPE_VALUES (scope);
+  TYPE_CONTEXT (t) = scope;
+
+  pushdecl (d);
+  return d;
+}
index a259cbe2174d939dfb18dcc5eb564a148b3894b7..38e3c77aad795fe502be5f426f0e20ecc757ac73 100644 (file)
@@ -108,10 +108,14 @@ print_lang_type (file, node, indent)
       else
        fputs (" X(X&)", file);
     }
-  if (TREE_GETS_NEW (node))
-    fputs (" gets-new", file);
-  if (TREE_GETS_DELETE (node))
-    fputs (" gets-delete", file);
+  if (TYPE_GETS_NEW (node) & 1)
+    fputs (" new", file);
+  if (TYPE_GETS_NEW (node) & 2)
+    fputs (" new[]", file);
+  if (TYPE_GETS_DELETE (node) & 1)
+    fputs (" delete", file);
+  if (TYPE_GETS_DELETE (node) & 2)
+    fputs (" delete[]", file);
   if (TYPE_HAS_ASSIGNMENT (node))
     fputs (" has=", file);
   if (TYPE_HAS_ASSIGN_REF (node))
index 984ee439964a678d92c5f0a18f31b74bd3011676..576eaecda9033a9fa839ac84f4c625b5cd404872 100644 (file)
@@ -1079,16 +1079,16 @@ lookup_field (xbasetype, name, protect, want_type)
          if (TREE_CODE (rval) == CONST_DECL)
            {
              if (this_v == access_private)
-               errstr = "enum `%s' is a private value of class `%s'";
+               errstr = "enum `%D' is a private value of class `%T'";
              else if (this_v == access_protected)
-               errstr = "enum `%s' is a protected value of class `%s'";
+               errstr = "enum `%D' is a protected value of class `%T'";
            }
          else
            {
              if (this_v == access_private)
-               errstr = "member `%s' is a private member of class `%s'";
+               errstr = "member `%D' is a private member of class `%T'";
              else if (this_v == access_protected)
-               errstr = "member `%s' is a protected member of class `%s'";
+               errstr = "member `%D' is a protected member of class `%T'";
            }
        }
 
@@ -1214,7 +1214,7 @@ lookup_field (xbasetype, name, protect, want_type)
          else
            {
              /* This is ambiguous. */
-             errstr = "request for member `%s' is ambiguous";
+             errstr = "request for member `%D' is ambiguous";
              protect = 2;
              break;
            }
@@ -1250,7 +1250,7 @@ lookup_field (xbasetype, name, protect, want_type)
              new_v = compute_access (TREE_VALUE (TREE_CHAIN (*tp)), rval);
            if (this_v != access_default && new_v != this_v)
              {
-               errstr = "conflicting access to member `%s'";
+               errstr = "conflicting access to member `%D'";
                this_v = access_default;
              }
            own_access = new_v;
@@ -1272,17 +1272,17 @@ lookup_field (xbasetype, name, protect, want_type)
   if (errstr == 0)
     {
       if (own_access == access_private)
-       errstr = "member `%s' declared private";
+       errstr = "member `%D' declared private";
       else if (own_access == access_protected)
-       errstr = "member `%s' declared protected";
+       errstr = "member `%D' declared protected";
       else if (this_v == access_private)
        errstr = TREE_PRIVATE (rval)
-         ? "member `%s' is private"
-           : "member `%s' is from private base class";
+         ? "member `%D' is private"
+           : "member `%D' is from private base class";
       else if (this_v == access_protected)
        errstr = TREE_PROTECTED (rval)
-         ? "member `%s' is protected"
-           : "member `%s' is from protected base class";
+         ? "member `%D' is protected"
+           : "member `%D' is from protected base class";
     }
 
   if (entry)
@@ -1302,17 +1302,7 @@ lookup_field (xbasetype, name, protect, want_type)
 
   if (errstr && protect)
     {
-      char *p = IDENTIFIER_POINTER (name), *q = NULL;
-      if (IDENTIFIER_OPNAME_P (name))
-       {
-         q = operator_name_string (name);
-         p = (char *) xmalloc (9 + strlen (q) + 1);
-         sprintf (p, "operator %s", q);
-       }
-
-      error (errstr, p, TYPE_NAME_STRING (type));
-      if (q)
-       free (p);
+      cp_error (errstr, name, type);
       rval = error_mark_node;
     }
   return rval;
@@ -3031,15 +3021,15 @@ push_class_decls (type)
   search_stack = push_search_level (search_stack, &search_obstack);
 
   id = TYPE_IDENTIFIER (type);
+#if 0
   if (IDENTIFIER_TEMPLATE (id) != 0)
     {
-#if 0
       tree tmpl = IDENTIFIER_TEMPLATE (id);
       push_template_decls (DECL_ARGUMENTS (TREE_PURPOSE (tmpl)),
                           TREE_VALUE (tmpl), 1);
-#endif
       overload_template_name (id, 1);
     }
+#endif
 
   /* Push class fields into CLASS_VALUE scope, and mark.  */
   dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarkedp);
@@ -3227,3 +3217,27 @@ reinit_search_statistics ()
   n_outer_fields_searched = 0;
   n_contexts_saved = 0;
 }
+
+tree
+lookup_nested_tag (type, name)
+     tree type, name;
+{
+  tree tags = CLASSTYPE_TAGS (type);
+
+  for (; tags; tags = TREE_CHAIN (tags))
+    {
+      /* The TREE_PURPOSE of an enum tag (which becomes a member of the
+        enclosing class) is set to the name for the enum type.  So, if
+        name is `bar', and we strike `baz' for `enum bar { baz }', then
+        this test will be true.  */
+      if (TREE_PURPOSE (tags) == name)
+       break;
+    }
+  if (tags)
+    return TYPE_NAME (TREE_VALUE (tags));
+
+  if (TYPE_CONTEXT (type))
+    return lookup_nested_tag (TYPE_CONTEXT (type), name);
+
+  return NULL_TREE;
+}
index da707eb0848a90910d2125f5f3c14725a8f4f0f8..b7fc7d5732341252a506f7a7d6354a3491a9c4c6 100644 (file)
@@ -45,12 +45,6 @@ struct token  {
 };
 
 static int do_aggr ();
-static struct token frob_identifier ();
-static tree hack_more_ids ();
-#if 0
-static struct token hack_scope ();
-static tree hack_ptype ();
-#endif
 
 /* From lex.c: */
 /* the declaration found for the last IDENTIFIER token read in.
@@ -72,51 +66,10 @@ static unsigned int yylex_ctr = 0;
 static int debug_yychar ();
 #endif
 
-#if 0                          /* Used by arbitrate_lookup */
-static char follows_typename[END_OF_SAVED_INPUT+1];
-static char follows_identifier[END_OF_SAVED_INPUT+1];
-#endif
-
-/* This is a hack!!! TEMPLATE_TYPE_SEEN_BEFORE_SCOPE consists of the name
- * of the last template_type parsed in parse.y if it is followed by a
- * scope operator.  It will be reset inside the next invocation of yylex().
- * This is used for recognizing nested types inside templates.
- * - niklas@appli.se */
-tree template_type_seen_before_scope;
-
 /* Initialize token_obstack. Called once, from init_lex.  */
 void
 init_spew ()
 {
-#if 0                          /* Used by arbitrate_lookup */
-  static char *chars_following_identifier = ".+-|/%^!?:";
-  short *ps;
-  static short toks_follow_ids[] =
-    { ASSIGN, RANGE, OROR, ANDAND, MIN_MAX, EQCOMPARE,
-      ARITHCOMPARE, LSHIFT, RSHIFT, UNARY, PLUSPLUS, MINUSMINUS, POINTSAT,
-      POINTSAT_STAR, DOT_STAR, CONSTANT, STRING, SIZEOF, ENUM, IF,
-      ELSE, WHILE, DO, FOR, SWITCH, CASE, DEFAULT, BREAK, CONTINUE,
-      RETURN, GOTO, ASM_KEYWORD, GCC_ASM_KEYWORD, TYPEOF, ALIGNOF, HEADOF,
-      CLASSOF, SIGOF, ATTRIBUTE, AGGR, VISSPEC, DELETE, RAISE, RERAISE, TRY,
-      EXCEPT, CATCH, THROW, ANSI_TRY, ANSI_THROW, DYNAMIC_CAST, TYPEID,
-      EXTERN_LANG_STRING, ALL, END_OF_SAVED_INPUT, -1 };
-  static short toks_follow_types[] =
-    { IDENTIFIER, TYPENAME, SCOPED_TYPENAME, SCOPED_NAME, SCSPEC, 
-      TYPESPEC, TYPE_QUAL,
-      ELLIPSIS, THIS, OPERATOR, TEMPLATE, SCOPE, START_DECLARATOR,
-      TYPENAME_COLON, PAREN_STAR_PAREN, TYPENAME_ELLIPSIS, PTYPENAME,
-      PRE_PARSED_FUNCTION_DECL, PRE_PARSED_CLASS_DECL, -1 };
-
-  /* Initialize the arrays saying what tokens are definitely
-     (or possibly) valid following typenames and identifiers.  */
-  while (*chars_following_identifier)
-    follows_identifier[*chars_following_identifier++] = 1;
-  for (ps = toks_follow_ids; *ps != -1; ps++)
-    follows_identifier[*ps] = 1;
-  for (ps = toks_follow_types; *ps != -1; ps++)
-    follows_typename[*ps] = 1;
-#endif
-
   gcc_obstack_init(&token_obstack);
 }
 
@@ -181,7 +134,8 @@ consume_token()
    : first_token++)
 #endif
 
-/* Pull in enough tokens from real_yylex that the queue is N long.  */
+/* Pull in enough tokens from real_yylex that the queue is N long beyond
+   the current token.  */
 
 static void
 scan_tokens (n)
@@ -278,13 +232,13 @@ probe_obstack (h, obj, nlevels)
 }
 
 /* from lex.c: */
-/* Value is 1 if we should try to make the next identifier look like a
-   typename (when it may be a local variable or a class variable).
-   Value is 0 if we treat this name in a default fashion.
-   Value is -1 if we must not see a type name.  */
+/* Value is 1 (or 2) if we should try to make the next identifier look like
+   a typename (when it may be a local variable or a class variable).
+   Value is 0 if we treat this name in a default fashion. */
 extern int looking_for_typename;
 
 extern struct obstack *current_obstack, *saveable_obstack;
+tree got_scope;
 
 int
 yylex()
@@ -300,36 +254,6 @@ yylex()
     fprintf(stderr, "\t\t## %d ##",yylex_ctr);
   }
 #endif
-  
-  /* This is a kludge for recognizing nested types in templates */
-  if (template_type_seen_before_scope)
-    {
-      shift_tokens (2);                /* Sync in hack_more_ids (yes, it's ugly) */
-      nth_token (1)->yychar = SCOPE;
-      yylval.ttype = hack_more_ids (0, template_type_seen_before_scope);
-      template_type_seen_before_scope = 0;
-      if (!yylval.ttype)
-       {
-         /* Sync back again, leaving SCOPE on the token stream, because we
-          * failed to substitute the original SCOPE token with a
-          * SCOPED_TYPENAME.  See rule "template_type" in parse.y */
-         consume_token ();
-       }
-      else
-       {
-         tree t = TREE_TYPE(yylval.ttype);
-         if (TREE_CODE(yylval.ttype) == SCOPE_REF && 
-               t && TREE_CODE(t) == UNINSTANTIATED_P_TYPE)
-           yychar = SCOPED_NAME;
-         else
-           yychar = SCOPED_TYPENAME;
-#ifdef SPEW_DEBUG    
-         if (spew_debug)
-           debug_yychar(yychar);
-#endif
-         return yychar;
-       }
-    }
 
   /* if we've got tokens, send them */
   if (num_tokens())
@@ -370,7 +294,13 @@ yylex()
       goto retry;
 
     case IDENTIFIER:
+      scan_tokens (1);
+      if (nth_token (1)->yychar == SCOPE)
+       /* Don't interfere with the setting from an 'aggr' prefix.  */
+       looking_for_typename++;
+
       trrr = lookup_name (tmp_token.yylval.ttype, -2);
+
       if (trrr)
        {
          tmp_token.yychar = identifier_type (trrr);
@@ -378,28 +308,17 @@ yylex()
            {
            case TYPENAME:
              lastiddecl = identifier_typedecl_value (tmp_token.yylval.ttype);
-             if (lastiddecl == NULL_TREE)
-               lastiddecl = trrr;
+             if (lastiddecl != trrr)
+               {
+                 lastiddecl = trrr;
+                 tmp_token.yylval.ttype = DECL_NESTED_TYPENAME (trrr);
+               }
              break;
            case IDENTIFIER:
              lastiddecl = trrr;
              break;
            case PTYPENAME:
-             /* This is for cases like
-                   template<class A> X<A>::operator[] ...
-                since "X" is (presumably) a PTYPENAME; we might want to
-                avoid seeing the entire thing as a type name, but X<A>
-                must be one.
-
-                It might not work right if the thing after the ::
-                can be a typename nested in X<A>, but I don't think the
-                PT code would be up to dealing with that anyways.  --KR  */
-             if (looking_for_typename == -1)
-               {
-                 scan_tokens (2);
-                 if (nth_token(1)->yychar == '<')
-                   looking_for_typename = 0;
-               }
+             lastiddecl = NULL_TREE;
              break;
            default:
              my_friendly_abort (101);
@@ -410,120 +329,20 @@ yylex()
       /* and fall through to... */
     case TYPENAME:
     case PTYPENAME:
-      /* if (new_token) add_token (&tmp_token); */
-      *nth_token(0) = tmp_token;
-      tmp_token = frob_identifier ();
-      if (looking_for_typename < 0)
-       {
-         tmp_token.yychar = IDENTIFIER;
-         lastiddecl = 0;
-         looking_for_typename = 0;
-       }
-      else if (lastiddecl && TREE_CODE (lastiddecl) == TYPE_DECL)
-       {
-         scan_tokens (2);
-         if (nth_token(0)->yychar == IDENTIFIER
-             && nth_token (1)->yychar != SCOPE)
-           looking_for_typename = -1;
-         else
-           looking_for_typename = 0;
-         goto finish_typename_processing;
-       }
-      else
-       looking_for_typename = 0;
+      consume_token ();
+      if (looking_for_typename > 0)
+       looking_for_typename--;
       break;
 
     case SCSPEC:
       /* do_aggr needs to check if the previous token was RID_FRIEND,
         so just increment first_token instead of calling consume_token. */
       first_token++;
-      goto finish_typename_processing;
+      break;
     case TYPESPEC:
       consume_token ();
-    finish_typename_processing:
-#if 0
-      /* Now see if we should insert a START_DECLARATOR token.
-         Here are the cases caught:
-
-        typespec ( * ID ) (    // ptr to function
-        typespec ( & ID ) (    // ref to function
-        typespec ( * ID ) [    // array of pointers
-        typespec ( & ID ) [    // array of references
-
-        This is a terrible kludge.  */
-
-      scan_tokens (2);
-      if (nth_token (0)->yychar == '('
-         && (nth_token (1)->yychar == '*'
-             || nth_token (1)->yychar == '&'))
-       {
-         scan_tokens (5);
-         if (nth_token (3)->yychar == ')'
-             && (nth_token (4)->yychar == '('
-                 || nth_token (4)->yychar == '['
-                 || nth_token (4)->yychar == LEFT_RIGHT)
-             && (nth_token (2)->yychar == IDENTIFIER
-                 || nth_token (2)->yychar == TYPENAME))
-           {
-             shift_tokens (1);
-             nth_token (0)->yychar = START_DECLARATOR;
-           }
-       }
-      /* Extend to handle:
-
-        typespec (ID::* qf)(   // ptr to member function
-        typespec (ID::* qf)[   // array of ptr to member functions
-
-        */
-      if (nth_token (0)->yychar == '('
-         && (nth_token (1)->yychar == IDENTIFIER
-             || nth_token (1)->yychar == TYPENAME))
-       {
-         scan_tokens (7);
-         if (nth_token (2)->yychar == SCOPE
-             && nth_token (3)->yychar == '*'
-             && (nth_token (4)->yychar == IDENTIFIER
-                 || nth_token (4)->yychar == TYPENAME)
-             && nth_token (5)->yychar == ')'
-             && (nth_token (6)->yychar == '('
-                 || nth_token (6)->yychar == '['
-                 || nth_token (6)->yychar == LEFT_RIGHT))
-           {
-             shift_tokens (1);
-             nth_token (0)->yychar = START_DECLARATOR;
-           }
-       }
-#endif
       break;
 
-#if 0
-    case '(':
-      /* Handle casts.  We are looking for one of:
-         `( TYPENAME' followed by `)', or
-        `( TYPENAME *' followed by one of `[,*,&,)', or
-        `( TYPENAME &' followed by one of `[,*,&,)', or
-        `( TYPENAME [' followed by `]'.  We are punting
-        generality on scanning casts to array types.  */
-      scan_tokens (4);
-      if (nth_token (1)->yychar == IDENTIFIER)
-       {
-         tree type = identifier_typedecl_value (nth_token (1)->yylval.ttype);
-         if (type)
-           switch (nth_token (2)->yychar)
-             {
-             default:
-               break;
-             }
-       }
-      break;
-
-    case SCOPE:
-      /* if (new_token) add_token (&tmp_token); */
-      *nth_token(0) = tmp_token;
-      tmp_token = hack_scope ();
-      break;
-#endif
-
     case AGGR:
       *nth_token(0) = tmp_token;
       do_aggr ();
@@ -533,36 +352,7 @@ yylex()
       looking_for_typename = 1;
       /* fall through... */
     default:
-#ifdef SPEW_DEBUG    
-      if (spew_debug)
-       debug_yychar(tmp_token.yychar);
-#endif
       consume_token();
-      yylval = tmp_token.yylval;
-      yychar = tmp_token.yychar;
-      end_of_file = tmp_token.end_of_file;
-      return tmp_token.yychar;
-    }
-
-  if (tmp_token.yychar == SCOPED_TYPENAME)
-    {
-#if 0
-      tree t2 = resolve_scope_to_name (NULL_TREE, tmp_token.yylval.ttype);
-      if (t2 != NULL_TREE)
-       {
-         tmp_token.yylval.ttype = t2;
-         tmp_token.yychar = TYPENAME;
-       }
-      else
-       {
-         /* unwind? */
-       }
-    }
-  else
-    {
-      /* couldn't get here, as is... */
-#endif
-      tmp_token.yychar = TYPENAME;
     }
 
   yylval = tmp_token.yylval;
@@ -572,7 +362,6 @@ yylex()
   if (spew_debug)
     debug_yychar(yychar);
 #endif
-/*  consume_token(); */ /* already eaten by frob_identifier?... */
   return yychar;
 }
 
@@ -618,515 +407,6 @@ do_aggr ()
     }
   return 0;
 }  
-
-static struct token
-frob_identifier ()
-{
-  /* we could have a type, if it is followed by :: (if so, suck it all up); */
-  /* we could have a ptypename; */
-  /* we could have a normal identifier. */
-  tree t1;
-  struct token rt;
-  
-  scan_tokens(1);
-  rt = *nth_token(0);
-
-#if 0
-  if (nth_token(1)->yychar == '<')
-    {
-      t1 = hack_ptype();       /* suck up the whole thing */
-      if (t1)
-       {
-         rt.yylval.ttype = t1;
-         rt.yychar = TYPENAME;
-         *nth_token(0) = rt;
-       }
-      /* else fall out bottom */
-    }  
-#endif
-
-  if (nth_token(1)->yychar == SCOPE)
-    {
-#if 0
-      t1 = hack_more_ids(0);
-      if (t1 && TREE_CODE(t1) == SCOPE_REF)
-#else
-      t1 = hack_more_ids(0, nth_token (0)->yylval.ttype);
-      if (t1)
-#endif
-       {
-         rt.yylval.ttype = t1;
-         rt.yychar = SCOPED_TYPENAME ;
-         return rt;
-       }
-      else
-       {
-         /* deal with types (enums?) in classes... */
-         struct token *tok;
-         tree ta, tb;
-         scan_tokens(3);
-
-         /* Have to check for a type conversion operator
-            to a nested type.  */
-         if (nth_token (2)->yychar == OPERATOR)
-           tok = nth_token (3);
-         else
-           tok = nth_token(2);
-
-         if (tok->yychar == IDENTIFIER || tok->yychar == TYPENAME)
-           {
-             ta = build_parse_node (SCOPE_REF,
-                                    nth_token(0)->yylval.ttype,
-                                    tok->yylval.ttype);
-             tb = resolve_scope_to_name (NULL_TREE, ta);
-
-             if (tb != NULL_TREE)
-               {
-                 if (nth_token (2)->yychar == OPERATOR)
-                   {
-                     /* Have to keep these tokens around
-                        so we can finish parsing the declaration.
-                        What do we do for
-
-                        int foo::operator bar::baz (); 
-
-                        where bar is a nested class in foo?  */
-                     nth_token (3)->yychar = TYPENAME;
-                     nth_token (3)->yylval.ttype = tb;
-                   }
-                 else
-                   {
-                     consume_token (); /* base type */
-                     consume_token (); /* SCOPE */
-                     consume_token (); /* member type */
-                     rt.yychar = TYPENAME;
-                     rt.yylval.ttype = tb;
-                     rt.end_of_file = tok->end_of_file;
-                     return rt;
-                   }
-                 
-               }
-           }      
-         /* else fall out bottom */
-       }
-    }
-            
-  consume_token();
-  return rt;
-}
-
-#if 0
-/* When this function is called, nth_token(0) is the current
-   token we are scanning.  This means that the next token we'll
-   scan is nth_token (1).  Usually the next token we'll scan
-   is nth_token (0) (and the current token is in [yylval,yychar]).  */
-tree
-arbitrate_lookup (name, exp_decl, type_decl)
-     tree name, exp_decl, type_decl;
-{
-  int ch;
-  tree t;
-  char *assume;
-
-  scan_tokens (3);
-  ch = nth_token (1)->yychar;
-
-  switch (ch)
-    {
-    case '(':
-    case LEFT_RIGHT:
-      /* If we guessed wrong here, `build_functional_cast' can fix it.  */
-      return type_decl;
-
-    case '=':
-      if (global_bindings_p ())
-       /* Probably a default parameter.  */
-       return type_decl;
-      /* Probably not an initialization.  */
-      return exp_decl;
-
-    case '[':
-      /* This needs special help because an expression inside the
-        brackets means nothing.  */
-      {
-       int i;
-
-       for (i = 0; i < 42; i++)
-         {
-           int ith_yychar;
-
-           scan_tokens (3+i);
-           ith_yychar = nth_token (2+i)->yychar;
-
-           /* If we hit an undefined identifier, assume
-              the decl in arbitration is its type specifier.  */
-           if (ith_yychar == IDENTIFIER
-               && lookup_name (nth_token (2+i)->yylval.ttype, 0) == 0)
-             return type_decl;
-           else if (ith_yychar == ']')
-             {
-               /* There are only a few things we expect after a ']'
-                  in a declarator.  */
-               i += 1;
-               scan_tokens (4+i);
-               ith_yychar = nth_token (2+i)->yychar;
-
-               /* These are inconclusive.  */
-               if (ith_yychar == LEFT_RIGHT
-                   || ith_yychar == '('
-                   || ith_yychar == '['
-                   || ith_yychar == ',')
-                 continue;
-               /* stmt or decl?  We'll probably never know.  */
-               else if (ith_yychar == ';')
-                 goto warn_ambiguous;
-
-               if (ith_yychar == '=')
-                 {
-                   if (nth_token (3+i)->yychar == '{')
-                     return type_decl;
-                   continue;
-                 }
-
-               /* Whatever it is, it looks like we're processing an expr.  */
-               return exp_decl;
-             }
-         }
-       goto warn_ambiguous;
-      }
-
-    case ',':
-    case ';':
-    case '&':
-    case '<':
-    case '*':
-    case ']':
-    case ')':
-    case '>':
-      /* see if the next token looks like it wants to be part
-        of a declaration list or an expression list.  */
-      {
-       int i;
-
-       /* Some heuristics: if we are inside a function definition,
-          prefer the local declaration.  */
-       if (! global_bindings_p ())
-         {
-           if (IDENTIFIER_LOCAL_VALUE (name) == exp_decl)
-             return exp_decl;
-           if (IDENTIFIER_LOCAL_VALUE (name) != type_decl
-               && IDENTIFIER_CLASS_VALUE (name) == exp_decl)
-             return exp_decl;
-         }
-       /* If these symbols follow in a list, we know it's a list of
-          expressions.  */
-       if (follows_identifier[nth_token (2)->yychar])
-         return exp_decl;
-
-       /* If we see a id&, or id&) the we are probably in an argument list. */
-       if (ch=='&'
-           && (nth_token (2)->yychar == ',' || nth_token (2)->yychar == ')'))
-         return type_decl;
-
-       /* Look for the first identifier or other distinguishing token
-          we find in the next several tokens.  */
-       for (i = 0; i < 42; i++)
-         {
-           int ith_yychar;
-
-           scan_tokens (3+i);
-           ith_yychar = nth_token (2+i)->yychar;
-
-           if (ith_yychar == IDENTIFIER)
-             {
-               tree as_type = lookup_name (nth_token (2+i)->yylval.ttype, 1);
-               if (as_type && TREE_CODE (as_type) != TYPE_DECL)
-                 return exp_decl;
-               /* An undeclared identifier or a typename means we're
-                  probably looking at a typename.  */
-               return type_decl;
-             }
-           else if (ith_yychar == EMPTY
-                    || follows_identifier[ith_yychar])
-             return exp_decl;
-           else if (follows_typename[ith_yychar])
-             return type_decl;
-           /* stmt or decl?  We'll probably never know.  */
-           else if (ith_yychar == ';')
-             goto warn_ambiguous;
-         }
-       goto warn_ambiguous;
-      }
-
-    default:
-      if (follows_identifier[ch])
-       return exp_decl;
-      if (follows_typename[ch])
-       return type_decl;
-
-      /* Fall through...  */
-    warn_ambiguous:
-      if (ch == '[')
-       {
-         assume = "expression";
-         t = exp_decl;
-       }
-      else
-       {
-         assume = "type";
-         t = type_decl;
-       }
-
-      warning ("name `%s' could be type or expression; compiler assuming %s",
-              IDENTIFIER_POINTER (DECL_NAME (t)), assume);
-      return t;
-    }
-}
-#endif
-
-/* now returns decl_node */
-
-#if 0
-static tree
-hack_ptype()
-{
-  /* when we get here, we know that [0] is a ptype and [1] is '<'.
-   * now we loop over simple parameters. */
-  struct token this_param;
-  int n = 2;
-  tree tplist = 0;
-  tree tc;
-  scan_tokens(n+1);
-  
-  while((this_param = *nth_token(n)).yychar != '>')
-    {
-      /* if it is a type, add it to the list */
-      tree thistype;
-    
-      switch(this_param.yychar)
-       {
-       case IDENTIFIER:
-       case TYPENAME:
-       case TYPESPEC:
-         break;
-       default:
-         return 0;
-       }
-
-      thistype = this_param.yylval.ttype;
-      thistype = lookup_name(thistype, 1);
-      thistype = TREE_TYPE (thistype);
-        
-      if (tplist)
-       tplist = chainon (tplist, build_tree_list (NULL_TREE, thistype));
-      else
-       tplist = build_tree_list(NULL_TREE, thistype);
-    
-    
-      /* then suck up the comma */
-      n++;
-      scan_tokens(n+1);
-      this_param = *nth_token(n);
-      if (this_param.yychar == ',')
-       {
-         n++;
-         scan_tokens(n+1);
-         continue;
-       }
-      if (this_param.yychar == '>')
-       break;
-      return 0;
-    }
-
-  /* once we're done, lookup_template_class -> identifier */
-  tc = lookup_template_class (nth_token(0)->yylval.ttype,tplist);
-  /* then lookup_name on that to get a type, if there is one */
-  tc = lookup_name (tc, 1);
-  if (tc)
-    {
-      int i;
-      /* don't actually eat the trailing '>'... we can replace it! */
-      for (i=0; i<n; i++)
-       consume_token();
-      /*    IDENTIFIER_TYPE_VALUE (DECL_NAME (tc)) = */
-      return DECL_NAME (tc);
-    }
-  return NULL_TREE;
-}
-#endif
-
-#if 0
-static tree
-hack_more_ids (n)
-     int n;
-{
-  /*
-   * The recursion should probably do consume_tokens(), since once we've started
-   * down an IDENTIFIER SCOPE ... chain, we don't need to back-track - we just
-   * get as much as we can, make SCOPE_REF's out of it, and return it.
-   */
-  struct token this_iter, this2_iter;
-  int tmp_y;
-  
-  scan_tokens(n+1);
-  this_iter = *nth_token(n);
-
-  tmp_y = nth_token(n)->yychar;
-  if (tmp_y == IDENTIFIER || tmp_y == TYPENAME)
-    {
-      scan_tokens(n+2+2);
-      if (nth_token(n+1)->yychar == SCOPE)
-       {
-         if (nth_token(n+1+2)->yychar == SCOPE)
-           {
-             tree hmi;
-       
-             consume_token();  /* last IDENTIFIER (this_iter) */
-             consume_token();  /* last SCOPE */
-             this2_iter = *nth_token(n);
-       
-             hmi = hack_more_ids (n);
-       
-             if (hmi)
-               return build_parse_node (SCOPE_REF, this_iter.yylval.ttype, hmi);
-             consume_token(); /* last IDENTIFIER (this2_iter) */
-             return build_parse_node (SCOPE_REF, this_iter.yylval.ttype,
-                                      this2_iter.yylval.ttype);
-           }
-         else
-           {
-             /* consume_token();       */      /* last IDENTIFIER */
-             /* leave whatever else we got */
-             /* return this_iter.yylval.ttype; */
-             return NULL_TREE;
-           }
-       }
-    }
-  return NULL_TREE;            /* @@ may need to backtrack */
-}
-#else
-/* niklas@appli.se says:  I didn't understand how the code above was intended
- * to work, so I rewrote it (also changed the interface a bit).  This code
- * dives down an IDENTIFIER/TYPENAME SCOPE ... chain as long as the parsed
- * type prefix constitutes recognizable (by resolve_scope_to_name) types.
- * Interface changed like this:
- * 1. Takes an extra argument containing the name of the the type recognized
- *    so far.
- * 2. Now returns the name of the type instead of a SCOPE_REF. */
-static tree
-hack_more_ids(n, outer)
-  int n;
-  tree outer;
-{
-  int ch;
-  tree type, val, inner, outer_t;
-
-  scan_tokens (n + 2);
-  if (nth_token (n + 1)->yychar != SCOPE
-      || ((ch = nth_token (n + 2)->yychar) != IDENTIFIER && ch != TYPENAME))
-    return NULL_TREE;
-
-  inner = nth_token(n+2)->yylval.ttype;
-  val = build_parse_node (SCOPE_REF, outer, inner);
-  outer_t = TREE_TYPE(outer);
-  if (outer_t && TREE_CODE(outer_t) == UNINSTANTIATED_P_TYPE)
-    {
-      tree t = make_lang_type (UNINSTANTIATED_P_TYPE);
-      tree id = inner;
-      tree d = build_lang_decl (TYPE_DECL, id, t);
-
-      TYPE_NAME (t) = d;
-      TYPE_VALUES (t) = TYPE_VALUES(outer_t);
-      TYPE_CONTEXT(t) = outer_t;
-/*
-      pushdecl_top_level (d);
-*/
-      pushdecl(d);
-
-      type = val;
-      TREE_TYPE(type) = t;
-    }
-  else
-    {
-      type = resolve_scope_to_name (NULL_TREE, val);
-      if (type == NULL_TREE)
-        return NULL_TREE;
-    }
-  consume_token ();
-  consume_token ();
-  val = hack_more_ids (n, type);
-  if (! val)
-    consume_token ();
-  return val ? val : type;
-}
-#endif
-
-#if 0
-static struct token
-hack_scope ()
-{
-  /* we've got a :: - what follows is either a global var or a type. */
-  /* hmm, template names can be in the global scope too... */
-  tree t1;
-  struct token rt;
-  
-  scan_tokens(1);
-  if (nth_token(1)->yychar == IDENTIFIER)
-    {
-      /* @@ this is probably not right, but doesn't get hit yet */
-      t1 = build_parse_node (SCOPE_REF,
-                            NULL_TREE, /* to get "global" scope */
-                            hack_more_ids(0)); /* do some prefetching */
-      rt.yylval.ttype = t1;
-      rt.yychar =              /*SCOPED_*/TYPENAME;
-      return rt;
-    }
-  else
-    {
-      rt = *nth_token(0);
-      consume_token();
-      return rt;
-    }
-}
-#endif
-  
-/*
- * Generations:
- *     
- * PINST: PTYPE { saved_arg_count = arg_count($1) }
- *        '<' { arg_c = 0; } PARGS '>'
- *        ;
- * PARG: TYPE
- *       | VALUE
- *       ;
- * (of course the arg counting doesn't work for recursion... Do it right.)
- * PARGS: PARG { assert(arg_c == saved_arg_count); }
- *        | PARG ',' PARGS     { arg_c++; }
- *        ;
- * ATYPE: PINST
- *        | TYPEID
- *        ;
- * TYPE: ATYPE
- *       | ATYPE { basetype = $1; } '::' TYPEKIDS
- *       ;
- * TYPEKIDS: TYPE { assert ($1 is a member of basetype); }
- *       | TYPEKIDS { basetype += $1} TYPE { assert( $3 is in basetype ); }
- *       ;
- *
- *
- * state0: ; ATYPE
- *     TYPE '<': ac = args($0), base = CALL state1, state3     
- *     TYPE '::': base=$0, state3
- *     else return TYPE
- * state1: ; begin PARGS
- *     if(ac < list length) punt
- *     PARG ",": add to list, state1
- *     PARG ">": add to list, return
- *     else unravel
- * state3: ; begin TYPEKIDS
- *     TYPE: 
- */
-  
   
 #ifdef SPEW_DEBUG    
 /* debug_yychar takes a yychar (token number) value and prints its name. */
This page took 0.19205 seconds and 5 git commands to generate.