decl.c (grokdeclarator): Don't try to use TYPE_OBSTACK on an error_mark_node.
authorMark Mitchell <mark@markmitchell.com>
Wed, 27 May 1998 07:07:24 +0000 (07:07 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 27 May 1998 07:07:24 +0000 (07:07 +0000)
* decl.c (grokdeclarator): Don't try to use TYPE_OBSTACK on an
error_mark_node.

From-SVN: r20088

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/pt.c

index 378577715588d9ca298f23e4a761623d9a1b4fd9..cd341f73d22de00a917dc4971a30a415f701e5da 100644 (file)
@@ -1,3 +1,8 @@
+1998-05-27  Mark Mitchell  <mark@markmitchell.com>
+
+       * decl.c (grokdeclarator): Don't try to use TYPE_OBSTACK on an
+       error_mark_node.
+
 1998-05-27  Kevin Buhr  <buhr@stat.wisc.edu>
 
        * parse.y (base_class): Use is_aggr_type, not IS_AGGR_TYPE.
index 069163e752714e8e0e048df32258cadd1c79e23c..a927b6c23602137774109afce5d37fe38f780043 100644 (file)
@@ -9590,9 +9590,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
        {
          /* Make sure this typedef lives as long as its type,
             since it might be used as a template parameter. */
-         push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
+         if (type != error_mark_node)
+           push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
          decl = build_decl (TYPE_DECL, declarator, type);
-         pop_obstacks ();
+         if (type != error_mark_node)
+           pop_obstacks ();
        }
 
       /* If the user declares "struct {...} foo" then `foo' will have
index 509aa15a3d3a1b4bf5d0e4dc025c3a49fae9c79f..1e5b767cf106e99462bbadbda8c1d9d7be4f10cf 100644 (file)
@@ -3572,17 +3572,17 @@ tsubst_friend_function (decl, args)
   return new_friend;
 }
 
-/* FRIEND_TYPE is a friend RECORD_TYPE or UNION_TYPE.  ARGS is the
-   vector of template arguments, as for tsubst.
+/* FRIEND_TMPL is a friend TEMPLATE_DECL.  ARGS is the vector of
+   template arguments, as for tsubst.
 
    Returns an appropriate tsbust'd friend type.  */
 
 static tree
-tsubst_friend_class (friend_type, args)
-     tree friend_type;
+tsubst_friend_class (friend_tmpl, args)
+     tree friend_tmpl;
      tree args;
 {
-  tree friend_tmpl = CLASSTYPE_TI_TEMPLATE (friend_type);
+  tree friend_type;
   tree tmpl = lookup_name (DECL_NAME (friend_tmpl), 1); 
 
   tmpl = maybe_get_template_decl_from_type_decl (tmpl);
@@ -3591,9 +3591,8 @@ tsubst_friend_class (friend_type, args)
     {
       /* The friend template has already been declared.  Just
         check to see that the declarations match.  */
-      if (tmpl != friend_tmpl)
-       redeclare_class_template (TREE_TYPE (tmpl),
-                                 DECL_TEMPLATE_PARMS (friend_tmpl));
+      redeclare_class_template (TREE_TYPE (tmpl),
+                               DECL_TEMPLATE_PARMS (friend_tmpl));
       friend_type = TREE_TYPE (tmpl);
     }
   else
@@ -3886,19 +3885,29 @@ instantiate_class_template (type)
        t = TREE_CHAIN (t))
     {
       tree friend_type = TREE_VALUE (t);
+      tree new_friend_type;
 
-      if (!CLASSTYPE_IS_TEMPLATE (friend_type))
+      if (TREE_CODE (friend_type) != TEMPLATE_DECL)
        /* The call to xref_tag_from_type does injection for friend
           classes.  */
-       friend_type = 
+       new_friend_type = 
          xref_tag_from_type (tsubst (friend_type, args, NULL_TREE),
                              NULL_TREE, 1);
       else
-       friend_type = tsubst_friend_class (friend_type, args);
+       new_friend_type = tsubst_friend_class (friend_type, args);
+
+      if (TREE_CODE (friend_type) == TEMPLATE_DECL)
+       /* Trick make_friend_class into realizing that the friend
+          we're adding is a template, not an ordinary class.  It's
+          important that we use make_friend_class since it will
+          perform some error-checking and output cross-reference
+          information.  */
+       ++processing_template_decl;
+
+      make_friend_class (type, new_friend_type);
 
-      CLASSTYPE_FRIEND_CLASSES (type) = 
-       tree_cons (NULL_TREE, friend_type,
-                  CLASSTYPE_FRIEND_CLASSES (type));
+      if (TREE_CODE (friend_type) == TEMPLATE_DECL)
+       --processing_template_decl;
     }
 
   /* This does injection for friend functions. */