aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mmitchell@usa.net>1998-05-19 15:15:22 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-05-19 15:15:22 +0000
commitae0a6181ecc5b70c69810de5f9887291294ac2d9 (patch)
treec4ebe4e769e50541db7cd4df4e5cb06b128f43a6 /gcc
parent79edd21c9de35e7269dc1f9346cbc799e380563a (diff)
downloadgcc-ae0a6181ecc5b70c69810de5f9887291294ac2d9.zip
gcc-ae0a6181ecc5b70c69810de5f9887291294ac2d9.tar.gz
gcc-ae0a6181ecc5b70c69810de5f9887291294ac2d9.tar.bz2
decl.c (saveable_obstack): Declare.
* decl.c (saveable_obstack): Declare. (pushdecl): Copy TYPE_DECLs to the same obstack as the type they declare, if necessary. From-SVN: r19882
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c42
2 files changed, 48 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4050467..63ed57b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+Tue May 19 15:13:39 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * decl.c (saveable_obstack): Declare.
+ (pushdecl): Copy TYPE_DECLs to the same obstack as the type they
+ declare, if necessary.
+
Tue May 19 14:50:27 1998 Mark Mitchell <mmitchell@usa.net>
* call.c (compare_qual): Remove.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d5816f4..b6b2f66 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA. */
extern tree builtin_return_address_fndecl;
extern struct obstack permanent_obstack;
+extern struct obstack* saveable_obstack;
extern int current_class_depth;
@@ -3368,11 +3369,52 @@ pushdecl (x)
}
else if (type != error_mark_node && TYPE_NAME (type) != x)
{
+ push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
+
+ if (!TREE_PERMANENT (x)
+ && TYPE_OBSTACK (type) != saveable_obstack)
+ {
+ /* X should have been allocated on the saveable
+ obstack. Since the type was not, the type may
+ outlive X, unless we make a copy of X. Here are
+ some examples:
+
+ template <class T>
+ void f()
+ {
+ typedef S<T> Type_t;
+ Type_t::foo();
+ }
+
+ Here, we will create a SCOPE_REF with Type_t as
+ its first argument, and save the SCOPE_REF for
+ later, so that we can tsubst into it. But, that
+ means we need to save the TYPE_DECL for Type_t.
+
+ But, we must save the TYPE_DECL even when not
+ processing_template_decl. For example,
+
+ void f()
+ {
+ typedef int I;
+ g<I>();
+ }
+
+ may create a declaration of g with `I' as one of
+ the arguments. In the old days, we used to use
+ the underlying types for things, but now we try
+ to use the typedef names for readability. */
+ x = copy_node (x);
+ copy_lang_decl (x);
+ }
+
DECL_ORIGINAL_TYPE (x) = type;
type = build_type_copy (type);
TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
TYPE_NAME (type) = x;
TREE_TYPE (x) = type;
+
+ pop_obstacks ();
}
if (type != error_mark_node