aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@markmitchell.com>1998-05-27 07:07:24 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-05-27 07:07:24 +0000
commit1aed535530fda367c1ec38d7db7450951ab2a003 (patch)
tree38e82b511a50dc8b1c0272b97bbdb85200c39b1c /gcc
parentd499463f267ac9eb8172a715c472588f96b6e1ba (diff)
downloadgcc-1aed535530fda367c1ec38d7db7450951ab2a003.zip
gcc-1aed535530fda367c1ec38d7db7450951ab2a003.tar.gz
gcc-1aed535530fda367c1ec38d7db7450951ab2a003.tar.bz2
decl.c (grokdeclarator): Don't try to use TYPE_OBSTACK on an error_mark_node.
* decl.c (grokdeclarator): Don't try to use TYPE_OBSTACK on an error_mark_node. From-SVN: r20088
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/decl.c6
-rw-r--r--gcc/cp/pt.c37
3 files changed, 32 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3785777..cd341f7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 069163e..a927b6c 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 509aa15..1e5b767 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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. */