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
This commit is contained in:
parent
79edd21c9d
commit
ae0a6181ec
2 changed files with 48 additions and 0 deletions
|
@ -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>
|
Tue May 19 14:50:27 1998 Mark Mitchell <mmitchell@usa.net>
|
||||||
|
|
||||||
* call.c (compare_qual): Remove.
|
* call.c (compare_qual): Remove.
|
||||||
|
|
|
@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA. */
|
||||||
extern tree builtin_return_address_fndecl;
|
extern tree builtin_return_address_fndecl;
|
||||||
|
|
||||||
extern struct obstack permanent_obstack;
|
extern struct obstack permanent_obstack;
|
||||||
|
extern struct obstack* saveable_obstack;
|
||||||
|
|
||||||
extern int current_class_depth;
|
extern int current_class_depth;
|
||||||
|
|
||||||
|
@ -3368,11 +3369,52 @@ pushdecl (x)
|
||||||
}
|
}
|
||||||
else if (type != error_mark_node && TYPE_NAME (type) != 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;
|
DECL_ORIGINAL_TYPE (x) = type;
|
||||||
type = build_type_copy (type);
|
type = build_type_copy (type);
|
||||||
TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
|
TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
|
||||||
TYPE_NAME (type) = x;
|
TYPE_NAME (type) = x;
|
||||||
TREE_TYPE (x) = type;
|
TREE_TYPE (x) = type;
|
||||||
|
|
||||||
|
pop_obstacks ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != error_mark_node
|
if (type != error_mark_node
|
||||||
|
|
Loading…
Add table
Reference in a new issue