cp-tree.h (TYPE_ALIAS_SET): Document language-dependent uses.

* cp-tree.h (TYPE_ALIAS_SET): Document language-dependent uses.
	(TYPE_BINFO): Likewise.
	(IS_AGGR_TYPE): Tweak.
	(SET_IS_AGGR_TYPE): New macro.
	(CLASS_TYPE_P): Tweak.
	(lang_type): Group mark bitfields together.  Remove linenum.
	(CLASSTYPE_SOURCE_LINE): Remove macro.
	(CLASSTYPE_MARKED_N): New macro.
	(SET_CLASSTYPE_MARKED_N): Likewise.
	(CLEAR_CLASSTYPE_MARKED_N): Likewise.
	(CLASS_TYPE_MARKED_*): Use them.
	(SET_CLASSTYPE_MARKED_*): Likewise.
	(CLEAR_CLASSTYPE_MARKED_*): Likewise.
	(TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise.
	(TYPE_TEMPLATE_INFO): Handle TEMPLATE_TEMPLATE_PARMs as well.
	(TYPENAME_TYPE_FULLNAME): Use TYPE_BINFO rather than CLASSTYPE_SIZE.
	* class.c (class_cache_obstack): New variable.
	(class_cache_firstobj): Likewise.
	(finish_struct): Don't set CLASSTYPE_SOURCE_LINE.
	(pushclass): Free the cache, when appropriate.
	(popclass): Tidy.
	(maybe_push_cache_obstack): Use class_cache_obstack.
	* decl.c (include hash.h).
	(typename_hash): New function.
	(typename_compare): Likewise.
	(build_typename_type): Check the hash table to avoid creating
	duplicates.
	(build_ptrmemfunc_type): Use SET_IS_AGGR_TYPE.
	(grokdeclarator): Use CLASS_TYPE_P.
	(xref_basetypes): Likewise.
	(start_function): Likewise.  Don't put current_class_ref on the
	permanent obstack.
	* error.c (dump_type_real): Use	TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO
	and TYPE_TI_ARGS.
	* lex.c (note_got_semicolon): Use CLASS_TYPE_P.
	(make_lang_type): Don't create TYPE_LANG_SPECIFIC and associated
	fields for types other than class types.  Do clear TYPE_ALIAS_SET
	for types other than class types, though.
	* method.c (build_overload_identifier): Use CLASS_TYPE_P and
	TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
	* pt.c (process_template_parm): Don't set
	CLASSTYPE_GOT_SEMICOLON.
	(lookup_template_class) Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
	Coerce arguments on the momentary obstack.
	(for_each_template_parm): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
	(instantiate_class_template): Calculate template arguments on the
	momentary obstack.  Tidy.
	(tsubst_template_arg_vector): Use make_temp_vec.
	(tsubst_aggr_type): Put template arguments on the momentary
	obstack.
	(tsubst_decl): Likewise.
	(tsubst): Copy the array bounds index to the permanent obstack
	before building index types.  Use new macros.
	(unify): Use new macros.
	(do_type_instantiation): Likewise.
	* search.c (lookup_fnfields_1): Use new macros.
	(dfs_pushdecls): Build envelopes on the cache obstack.
	(dfs_compress_decls): Use new macros.
	(push_class_decls): Build on the cache obstack.
	* semantics.c (finish_typeof): Don't set CLASSTYPE_GOT_SEMICOLON.
	* sign.c (build_signature_pointer_or_reference_type): Use
	SET_IS_AGGR_TYPE.
	* tree.c (make_binfo): Check CLASS_TYPE_P.
	(copy_template_template_parm): Adjust.
	(make_temp_vec): Use push_expresion_obstack.
	* typeck.c (complete_type): Use new macros.
	(comptypes): Likewise.

From-SVN: r23686
This commit is contained in:
Mark Mitchell 1998-11-17 12:51:20 +00:00 committed by Mark Mitchell
parent 990ece87bd
commit 7ddedda4aa
14 changed files with 435 additions and 154 deletions

View File

@ -1,3 +1,73 @@
1998-11-17 Mark Mitchell <mark@markmitchell.com>
* cp-tree.h (TYPE_ALIAS_SET): Document language-dependent uses.
(TYPE_BINFO): Likewise.
(IS_AGGR_TYPE): Tweak.
(SET_IS_AGGR_TYPE): New macro.
(CLASS_TYPE_P): Tweak.
(lang_type): Group mark bitfields together. Remove linenum.
(CLASSTYPE_SOURCE_LINE): Remove macro.
(CLASSTYPE_MARKED_N): New macro.
(SET_CLASSTYPE_MARKED_N): Likewise.
(CLEAR_CLASSTYPE_MARKED_N): Likewise.
(CLASS_TYPE_MARKED_*): Use them.
(SET_CLASSTYPE_MARKED_*): Likewise.
(CLEAR_CLASSTYPE_MARKED_*): Likewise.
(TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise.
(TYPE_TEMPLATE_INFO): Handle TEMPLATE_TEMPLATE_PARMs as well.
(TYPENAME_TYPE_FULLNAME): Use TYPE_BINFO rather than CLASSTYPE_SIZE.
* class.c (class_cache_obstack): New variable.
(class_cache_firstobj): Likewise.
(finish_struct): Don't set CLASSTYPE_SOURCE_LINE.
(pushclass): Free the cache, when appropriate.
(popclass): Tidy.
(maybe_push_cache_obstack): Use class_cache_obstack.
* decl.c (include hash.h).
(typename_hash): New function.
(typename_compare): Likewise.
(build_typename_type): Check the hash table to avoid creating
duplicates.
(build_ptrmemfunc_type): Use SET_IS_AGGR_TYPE.
(grokdeclarator): Use CLASS_TYPE_P.
(xref_basetypes): Likewise.
(start_function): Likewise. Don't put current_class_ref on the
permanent obstack.
* error.c (dump_type_real): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO
and TYPE_TI_ARGS.
* lex.c (note_got_semicolon): Use CLASS_TYPE_P.
(make_lang_type): Don't create TYPE_LANG_SPECIFIC and associated
fields for types other than class types. Do clear TYPE_ALIAS_SET
for types other than class types, though.
* method.c (build_overload_identifier): Use CLASS_TYPE_P and
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
* pt.c (process_template_parm): Don't set
CLASSTYPE_GOT_SEMICOLON.
(lookup_template_class) Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
Coerce arguments on the momentary obstack.
(for_each_template_parm): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
(instantiate_class_template): Calculate template arguments on the
momentary obstack. Tidy.
(tsubst_template_arg_vector): Use make_temp_vec.
(tsubst_aggr_type): Put template arguments on the momentary
obstack.
(tsubst_decl): Likewise.
(tsubst): Copy the array bounds index to the permanent obstack
before building index types. Use new macros.
(unify): Use new macros.
(do_type_instantiation): Likewise.
* search.c (lookup_fnfields_1): Use new macros.
(dfs_pushdecls): Build envelopes on the cache obstack.
(dfs_compress_decls): Use new macros.
(push_class_decls): Build on the cache obstack.
* semantics.c (finish_typeof): Don't set CLASSTYPE_GOT_SEMICOLON.
* sign.c (build_signature_pointer_or_reference_type): Use
SET_IS_AGGR_TYPE.
* tree.c (make_binfo): Check CLASS_TYPE_P.
(copy_template_template_parm): Adjust.
(make_temp_vec): Use push_expresion_obstack.
* typeck.c (complete_type): Use new macros.
(comptypes): Likewise.
1998-11-17 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (tsubst): Add diagnostics for invalid array, reference

View File

@ -184,8 +184,8 @@ CXX_OBJS = call.o decl.o errfn.o expr.o pt.o sig.o typeck2.o \
repo.o @extra_cxx_objs@
# Language-independent object files.
OBJS = `cat ../stamp-objlist` ../c-common.o ../c-pragma.o
OBJDEPS = ../stamp-objlist ../c-common.o ../c-pragma.o
OBJS = `cat ../stamp-objlist` ../c-common.o ../c-pragma.o ../hash.o
OBJDEPS = ../stamp-objlist ../c-common.o ../c-pragma.o ../hash.o
compiler: ../cc1plus$(exeext)
../cc1plus$(exeext): $(P) $(OBJDEPS) $(CXX_OBJS) $(LIBDEPS)
@ -249,7 +249,8 @@ lex.o : lex.c $(CONFIG_H) $(CXX_TREE_H) \
$(srcdir)/../output.h $(srcdir)/../mbchar.h
decl.o : decl.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(srcdir)/../stack.h $(srcdir)/../output.h \
$(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h
$(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h \
$(srcdir)/../hash.h
decl2.o : decl2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(EXPR_H) $(srcdir)/../except.h \
$(srcdir)/../output.h $(srcdir)/../except.h $(srcdir)/../system.h \

View File

@ -82,6 +82,12 @@ tree previous_class_type; /* _TYPE: the previous type that was a class */
tree previous_class_values; /* TREE_LIST: copy of the class_shadowed list
when leaving an outermost class scope. */
/* The obstack on which the cached class declarations are kept. */
static struct obstack class_cache_obstack;
/* The first object allocated on that obstack. We can use
obstack_free with tis value to free the entire obstack. */
static char *class_cache_firstobj;
struct base_info;
static tree get_vfield_name PROTO((tree));
@ -4404,7 +4410,6 @@ finish_struct (t, attributes, warn_anon)
will fill in the right line number. (mrs) */
if (DECL_SOURCE_LINE (name))
DECL_SOURCE_LINE (name) = lineno;
CLASSTYPE_SOURCE_LINE (t) = lineno;
name = DECL_NAME (name);
}
@ -4701,6 +4706,11 @@ pushclass (type, modify)
/* Forcibly remove any old class remnants. */
popclass (-1);
previous_class_type = NULL_TREE;
/* Now, free the obstack on which we cached all the values. */
obstack_free (&class_cache_obstack, class_cache_firstobj);
class_cache_firstobj
= (char*) obstack_finish (&class_cache_obstack);
}
pushlevel_class ();
@ -4794,7 +4804,8 @@ popclass (modify)
TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
tags = TREE_CHAIN (tags);
}
goto ret;
return;
}
if (modify)
@ -4824,9 +4835,6 @@ popclass (modify)
current_class_name = current_class_stack[current_class_depth].name;
current_class_type = current_class_stack[current_class_depth].type;
current_access_specifier = current_class_stack[current_class_depth].access;
ret:
;
}
/* Returns 1 if current_class_type is either T or a nested type of T. */
@ -5443,16 +5451,24 @@ print_class_statistics ()
}
/* Push an obstack which is sufficiently long-lived to hold such class
decls that may be cached in the previous_class_values list. For now, let's
use the permanent obstack, later we may create a dedicated obstack just
for this purpose. The effect is undone by pop_obstacks. */
decls that may be cached in the previous_class_values list. The
effect is undone by pop_obstacks. */
void
maybe_push_cache_obstack ()
{
static int cache_obstack_initialized;
if (!cache_obstack_initialized)
{
gcc_obstack_init (&class_cache_obstack);
class_cache_firstobj
= (char*) obstack_finish (&class_cache_obstack);
cache_obstack_initialized = 1;
}
push_obstacks_nochange ();
if (current_class_depth == 1)
current_obstack = &permanent_obstack;
current_obstack = &class_cache_obstack;
}
/* Build a dummy reference to ourselves so Derived::Base (and A::A) works,

View File

@ -72,6 +72,19 @@ Boston, MA 02111-1307, USA. */
5: DECL_INTERFACE_KNOWN.
6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL).
7: DECL_DEAD_FOR_LOCAL (in VAR_DECL).
Usage of language-independent fields in a language-dependent manner:
TYPE_ALIAS_SET
This field is used by TYPENAME_TYPEs, TEMPLATE_TYPE_PARMs, and so
forth as a substitute for the mark bits provided in `lang_type'.
At present, only the six low-order bits are used.
TYPE_BINFO
For an ENUMERAL_TYPE, this is ENUM_TEMPLATE_INFO.
For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME.
For a TEMPLATE_TEMPLATE_PARM, this is
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
*/
/* Language-dependent contents of an identifier. */
@ -517,12 +530,21 @@ enum languages { lang_c, lang_cplusplus, lang_java };
for template type parameters and typename types. Despite its name,
this macro has nothing to do with the definition of aggregate given
in the standard. Think of this macro as MAYBE_CLASS_TYPE_P. */
#define IS_AGGR_TYPE(t) (TYPE_LANG_FLAG_5 (t))
#define IS_AGGR_TYPE(t) \
(TREE_CODE (t) == TEMPLATE_TYPE_PARM \
|| TREE_CODE (t) == TYPENAME_TYPE \
|| TREE_CODE (t) == TYPEOF_TYPE \
|| TYPE_LANG_FLAG_5 (t))
/* Set IS_AGGR_TYPE for T to VAL. T must be a class, struct, or
union type. */
#define SET_IS_AGGR_TYPE(T, VAL) \
(TYPE_LANG_FLAG_5 (T) = (VAL))
/* Nonzero if T is a class type. Zero for template type parameters,
typename types, and so forth. */
#define CLASS_TYPE_P(t) \
(IS_AGGR_TYPE (t) && IS_AGGR_TYPE_CODE (TREE_CODE (t)))
(IS_AGGR_TYPE_CODE (TREE_CODE (t)) && IS_AGGR_TYPE (t))
#define IS_AGGR_TYPE_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE)
#define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
@ -591,11 +613,19 @@ enum languages { lang_c, lang_cplusplus, lang_java };
#define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 1, (tree *)0) >= 0)
#define DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) != -1)
/* Statistics show that while the GNU C++ compiler may generate
thousands of different types during a compilation run, it
generates relatively few (tens) of classtypes. Because of this,
it is not costly to store a generous amount of information
in classtype nodes. This struct must fill out to a multiple of 4 bytes. */
/* This structure provides additional information above and beyond
what is provide in the ordinary tree_type. In the past, we used it
for the types of class types, template parameters types, typename
types, and so forth. However, there can be many (tens to hundreds
of thousands) of template parameter types in a compilation, and
there's no need for this additional information in that case.
Therefore, we now use this data structure only for class types.
In the past, it was thought that there would be relatively few
class types. However, in the presence of heavy use of templates,
many (i.e., thousands) of classes can easily be generated.
Therefore, we should endeavor to keep the size of this structure to
a minimum. */
struct lang_type
{
struct
@ -621,25 +651,20 @@ struct lang_type
unsigned has_arrow_overloaded : 1;
unsigned interface_only : 1;
unsigned interface_unknown : 1;
unsigned needs_virtual_reinit : 1;
unsigned marks: 6;
unsigned vec_delete_takes_size : 1;
unsigned declared_class : 1;
unsigned being_defined : 1;
unsigned redefined : 1;
unsigned marked : 1;
unsigned marked2 : 1;
unsigned marked3 : 1;
unsigned marked4 : 1;
unsigned marked5 : 1;
unsigned marked6 : 1;
unsigned debug_requested : 1;
unsigned use_template : 2;
unsigned got_semicolon : 1;
unsigned ptrmemfunc_flag : 1;
unsigned is_signature : 1;
unsigned is_signature_pointer : 1;
unsigned is_signature_reference : 1;
unsigned has_opaque_typedecls : 1;
@ -647,8 +672,8 @@ 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 has_abstract_assign_ref : 1;
@ -695,12 +720,8 @@ struct lang_type
union tree_node *signature_reference_to;
union tree_node *template_info;
int linenum;
};
#define CLASSTYPE_SOURCE_LINE(NODE) (TYPE_LANG_SPECIFIC(NODE)->linenum)
/* Indicates whether or not (and how) a template was expanded for this class.
0=no information yet/non-template class
1=implicit template instantiation
@ -839,25 +860,45 @@ struct lang_type
#define CLASSTYPE_BASELINK_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->baselink_vec)
/* Mark bits for depth-first and breath-first searches. */
#define CLASSTYPE_MARKED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked)
#define CLASSTYPE_MARKED2(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked2)
#define CLASSTYPE_MARKED3(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked3)
#define CLASSTYPE_MARKED4(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked4)
#define CLASSTYPE_MARKED5(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked5)
#define CLASSTYPE_MARKED6(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked6)
/* Get the value of the Nth mark bit. */
#define CLASSTYPE_MARKED_N(NODE, N) \
(((CLASS_TYPE_P (NODE) ? TYPE_LANG_SPECIFIC (NODE)->type_flags.marks \
: TYPE_ALIAS_SET (NODE)) & (1 << N)) != 0)
/* Set the Nth mark bit. */
#define SET_CLASSTYPE_MARKED_N(NODE, N) \
(CLASS_TYPE_P (NODE) \
? (TYPE_LANG_SPECIFIC (NODE)->type_flags.marks |= (1 << (N))) \
: (TYPE_ALIAS_SET (NODE) |= (1 << (N))))
/* Clear the Nth mark bit. */
#define CLEAR_CLASSTYPE_MARKED_N(NODE, N) \
(CLASS_TYPE_P (NODE) \
? (TYPE_LANG_SPECIFIC (NODE)->type_flags.marks &= ~(1 << (N))) \
: (TYPE_ALIAS_SET (NODE) &= ~(1 << (N))))
/* Get the value of the mark bits. */
#define CLASSTYPE_MARKED(NODE) CLASSTYPE_MARKED_N(NODE, 0)
#define CLASSTYPE_MARKED2(NODE) CLASSTYPE_MARKED_N(NODE, 1)
#define CLASSTYPE_MARKED3(NODE) CLASSTYPE_MARKED_N(NODE, 2)
#define CLASSTYPE_MARKED4(NODE) CLASSTYPE_MARKED_N(NODE, 3)
#define CLASSTYPE_MARKED5(NODE) CLASSTYPE_MARKED_N(NODE, 4)
#define CLASSTYPE_MARKED6(NODE) CLASSTYPE_MARKED_N(NODE, 5)
/* Macros to modify the above flags */
#define SET_CLASSTYPE_MARKED(NODE) (CLASSTYPE_MARKED(NODE) = 1)
#define CLEAR_CLASSTYPE_MARKED(NODE) (CLASSTYPE_MARKED(NODE) = 0)
#define SET_CLASSTYPE_MARKED2(NODE) (CLASSTYPE_MARKED2(NODE) = 1)
#define CLEAR_CLASSTYPE_MARKED2(NODE) (CLASSTYPE_MARKED2(NODE) = 0)
#define SET_CLASSTYPE_MARKED3(NODE) (CLASSTYPE_MARKED3(NODE) = 1)
#define CLEAR_CLASSTYPE_MARKED3(NODE) (CLASSTYPE_MARKED3(NODE) = 0)
#define SET_CLASSTYPE_MARKED4(NODE) (CLASSTYPE_MARKED4(NODE) = 1)
#define CLEAR_CLASSTYPE_MARKED4(NODE) (CLASSTYPE_MARKED4(NODE) = 0)
#define SET_CLASSTYPE_MARKED5(NODE) (CLASSTYPE_MARKED5(NODE) = 1)
#define CLEAR_CLASSTYPE_MARKED5(NODE) (CLASSTYPE_MARKED5(NODE) = 0)
#define SET_CLASSTYPE_MARKED6(NODE) (CLASSTYPE_MARKED6(NODE) = 1)
#define CLEAR_CLASSTYPE_MARKED6(NODE) (CLASSTYPE_MARKED6(NODE) = 0)
#define SET_CLASSTYPE_MARKED(NODE) SET_CLASSTYPE_MARKED_N(NODE, 0)
#define CLEAR_CLASSTYPE_MARKED(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 0)
#define SET_CLASSTYPE_MARKED2(NODE) SET_CLASSTYPE_MARKED_N(NODE, 1)
#define CLEAR_CLASSTYPE_MARKED2(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 1)
#define SET_CLASSTYPE_MARKED3(NODE) SET_CLASSTYPE_MARKED_N(NODE, 2)
#define CLEAR_CLASSTYPE_MARKED3(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 2)
#define SET_CLASSTYPE_MARKED4(NODE) SET_CLASSTYPE_MARKED_N(NODE, 3)
#define CLEAR_CLASSTYPE_MARKED4(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 3)
#define SET_CLASSTYPE_MARKED5(NODE) SET_CLASSTYPE_MARKED_N(NODE, 4)
#define CLEAR_CLASSTYPE_MARKED5(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 4)
#define SET_CLASSTYPE_MARKED6(NODE) SET_CLASSTYPE_MARKED_N(NODE, 5)
#define CLEAR_CLASSTYPE_MARKED6(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 5)
/* A list of the nested tag-types (class, struct, union, or enum)
found within this class. The TREE_PURPOSE of each node is the name
@ -1301,10 +1342,16 @@ struct lang_decl
non-type template parameters. */
#define ENUM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE))
/* Template information for a template template parameter. */
#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE))
/* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE. */
#define TYPE_TEMPLATE_INFO(NODE) \
(TREE_CODE (NODE) == ENUMERAL_TYPE \
? ENUM_TEMPLATE_INFO (NODE) : CLASSTYPE_TEMPLATE_INFO (NODE))
#define TYPE_TEMPLATE_INFO(NODE) \
(TREE_CODE (NODE) == ENUMERAL_TYPE \
? ENUM_TEMPLATE_INFO (NODE) : \
(TREE_CODE (NODE) == TEMPLATE_TEMPLATE_PARM \
? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \
: CLASSTYPE_TEMPLATE_INFO (NODE)))
/* Set the template information for an ENUMERAL_, RECORD_, or
UNION_TYPE to VAL. */
@ -1387,7 +1434,7 @@ struct lang_decl
this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the
corresponding TYPE_DECL. However, this may also be a
TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'. */
#define TYPENAME_TYPE_FULLNAME(NODE) CLASSTYPE_SIZE (NODE)
#define TYPENAME_TYPE_FULLNAME(NODE) TYPE_BINFO (NODE)
/* Nonzero in INTEGER_CST means that this int is negative by dint of
using a twos-complement negated operand. */

View File

@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "except.h"
#include "toplev.h"
#include "../hash.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
@ -178,6 +179,8 @@ static void bad_specifiers PROTO((tree, char *, int, int, int, int,
static void lang_print_error_function PROTO((char *));
static tree maybe_process_template_type_declaration PROTO((tree, int, struct binding_level*));
static void check_for_uninitialized_const_var PROTO((tree));
static unsigned long typename_hash PROTO((hash_table_key));
static boolean typename_compare PROTO((hash_table_key, hash_table_key));
#if defined (DEBUG_CP_BINDING_LEVELS)
static void indent PROTO((void));
@ -4778,6 +4781,47 @@ lookup_namespace_name (namespace, name)
return error_mark_node;
}
/* Hash a TYPENAME_TYPE. K is really of type `tree'. */
static unsigned long
typename_hash (k)
hash_table_key k;
{
unsigned long hash;
tree t;
t = (tree) k;
hash = (((unsigned long) TYPE_CONTEXT (t))
^ ((unsigned long) DECL_NAME (TYPE_NAME (t))));
return hash;
}
/* Compare two TYPENAME_TYPEs. K1 and K2 are really of type `tree'. */
static boolean
typename_compare (k1, k2)
hash_table_key k1;
hash_table_key k2;
{
tree t1;
tree t2;
tree d1;
tree d2;
t1 = (tree) k1;
t2 = (tree) k2;
d1 = TYPE_NAME (t1);
d2 = TYPE_NAME (t2);
return (DECL_NAME (d1) == DECL_NAME (d2)
&& same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2))
&& ((TREE_TYPE (t1) != NULL_TREE)
== (TREE_TYPE (t2) != NULL_TREE))
&& same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
&& TYPENAME_TYPE_FULLNAME (t1) == TYPENAME_TYPE_FULLNAME (t2));
}
/* Build a TYPENAME_TYPE. If the type is `typename T::t', CONTEXT is
the type of `T', NAME is the IDENTIFIER_NODE for `t'. If BASE_TYPE
is non-NULL, this type is being created by the implicit typename
@ -4795,16 +4839,22 @@ build_typename_type (context, name, fullname, base_type)
{
tree t;
tree d;
struct hash_entry* e;
if (processing_template_decl)
push_obstacks (&permanent_obstack, &permanent_obstack);
static struct hash_table ht;
push_obstacks (&permanent_obstack, &permanent_obstack);
if (!ht.table
&& !hash_table_init (&ht, &hash_newfunc, &typename_hash,
&typename_compare))
fatal ("virtual memory exhausted");
/* Build the TYPENAME_TYPE. */
t = make_lang_type (TYPENAME_TYPE);
TYPE_CONTEXT (t) = FROB_CONTEXT (context);
TYPENAME_TYPE_FULLNAME (t) = fullname;
TREE_TYPE (t) = base_type;
CLASSTYPE_GOT_SEMICOLON (t) = 1;
/* Build the corresponding TYPE_DECL. */
d = build_decl (TYPE_DECL, name, t);
@ -4812,8 +4862,20 @@ build_typename_type (context, name, fullname, base_type)
TYPE_STUB_DECL (TREE_TYPE (d)) = d;
DECL_CONTEXT (d) = FROB_CONTEXT (context);
if (processing_template_decl)
pop_obstacks ();
/* See if we already have this type. */
e = hash_lookup (&ht, t, /*create=*/false, /*copy=*/0);
if (e)
{
/* This will free not only TREE_TYPE, but the lang-specific data
and the TYPE_DECL as well. */
obstack_free (&permanent_obstack, t);
t = (tree) e->key;
}
else
/* Insert the type into the table. */
hash_lookup (&ht, t, /*create=*/true, /*copy=*/0);
pop_obstacks ();
return t;
}
@ -8399,7 +8461,7 @@ build_ptrmemfunc_type (type)
push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
u = make_lang_type (UNION_TYPE);
IS_AGGR_TYPE (u) = 0;
SET_IS_AGGR_TYPE (u, 0);
fields[0] = build_lang_field_decl (FIELD_DECL, pfn_identifier, type);
fields[1] = build_lang_field_decl (FIELD_DECL, delta2_identifier,
delta_type_node);
@ -8411,7 +8473,7 @@ build_ptrmemfunc_type (type)
/* Let the front-end know this is a pointer to member function... */
TYPE_PTRMEMFUNC_FLAG (t) = 1;
/* ... and not really an aggregate. */
IS_AGGR_TYPE (t) = 0;
SET_IS_AGGR_TYPE (t, 0);
fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier,
delta_type_node);
@ -10074,7 +10136,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
ctype = TREE_OPERAND (declarator, 0);
t = ctype;
while (t != NULL_TREE)
while (t != NULL_TREE && CLASS_TYPE_P (t))
{
if (CLASSTYPE_TEMPLATE_INFO (t) &&
!CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
@ -12001,9 +12063,12 @@ xref_basetypes (code_type_node, name, ref, binfo)
individual inheritance contains flags which say what
the `accessibility' of that particular inheritance is.) */
base_binfo = make_binfo (integer_zero_node, basetype,
TYPE_BINFO_VTABLE (basetype),
TYPE_BINFO_VIRTUALS (basetype));
base_binfo
= make_binfo (integer_zero_node, basetype,
CLASS_TYPE_P (basetype)
? TYPE_BINFO_VTABLE (basetype) : NULL_TREE,
CLASS_TYPE_P (basetype)
? TYPE_BINFO_VIRTUALS (basetype) : NULL_TREE);
TREE_VEC_ELT (binfos, i) = base_binfo;
TREE_VIA_PUBLIC (base_binfo) = via_public;
@ -12025,8 +12090,12 @@ xref_basetypes (code_type_node, name, ref, binfo)
TYPE_USES_COMPLEX_INHERITANCE (ref) = 1;
}
TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype);
TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
if (CLASS_TYPE_P (basetype))
{
TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype);
TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
}
i += 1;
}
}
@ -12038,8 +12107,14 @@ xref_basetypes (code_type_node, name, ref, binfo)
if (i > 1)
TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1;
else if (i == 1)
TYPE_USES_MULTIPLE_INHERITANCE (ref)
= TYPE_USES_MULTIPLE_INHERITANCE (BINFO_TYPE (TREE_VEC_ELT (binfos, 0)));
{
tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, 0));
if (CLASS_TYPE_P (basetype))
TYPE_USES_MULTIPLE_INHERITANCE (ref)
= TYPE_USES_MULTIPLE_INHERITANCE (basetype);
}
if (TYPE_USES_MULTIPLE_INHERITANCE (ref))
TYPE_USES_COMPLEX_INHERITANCE (ref) = 1;
@ -12466,8 +12541,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
fntype = TREE_TYPE (decl1);
restype = TREE_TYPE (fntype);
if (IS_AGGR_TYPE (restype) && ! TYPE_PTRMEMFUNC_P (restype)
&& ! CLASSTYPE_GOT_SEMICOLON (restype))
if (CLASS_TYPE_P (restype) && !CLASSTYPE_GOT_SEMICOLON (restype))
{
cp_error ("semicolon missing after declaration of `%#T'", restype);
shadow_tag (build_expr_list (NULL_TREE, restype));
@ -12678,13 +12752,24 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
{
int i = suspend_momentary ();
int i;
/* Fool build_indirect_ref. */
if (! hack_decl_function_context (decl1))
temporary_allocation ();
i = suspend_momentary ();
/* Normally, build_indirect_ref returns
current_class_ref whenever current_class_ptr is
dereferenced. This time, however, we want it to
*create* current_class_ref, so we temporarily clear
current_class_ptr to fool it. */
current_class_ptr = NULL_TREE;
current_class_ref = build_indirect_ref (t, NULL_PTR);
current_class_ptr = t;
resume_momentary (i);
if (! hack_decl_function_context (decl1))
end_temporary_allocation ();
}
else
/* We're having a signature pointer here. */
@ -12693,9 +12778,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
}
}
else
{
current_class_ptr = current_class_ref = NULL_TREE;
}
current_class_ptr = current_class_ref = NULL_TREE;
pushlevel (0);
current_binding_level->parm_flag = 1;

View File

@ -271,7 +271,7 @@ dump_type_real (t, v, canonical_name)
break;
case TEMPLATE_TEMPLATE_PARM:
if (!CLASSTYPE_TEMPLATE_INFO (t))
if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
{
/* For parameters inside template signature. */
if (TYPE_IDENTIFIER (t))
@ -282,7 +282,7 @@ dump_type_real (t, v, canonical_name)
else
{
int i;
tree args = CLASSTYPE_TI_ARGS (t);
tree args = TYPE_TI_ARGS (t);
OB_PUTID (TYPE_IDENTIFIER (t));
OB_PUTC ('<');
for (i = 0; i < TREE_VEC_LENGTH (args); i++)

View File

@ -2129,7 +2129,7 @@ note_got_semicolon (type)
{
if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
my_friendly_abort (60);
if (IS_AGGR_TYPE (type))
if (CLASS_TYPE_P (type))
CLASSTYPE_GOT_SEMICOLON (type) = 1;
}
@ -4666,38 +4666,48 @@ make_lang_type (code)
{
extern struct obstack *current_obstack, *saveable_obstack;
register tree t = make_node (code);
struct obstack *obstack = current_obstack;
register int i = sizeof (struct lang_type) / sizeof (int);
register int *pi;
/* Set up some flags that give proper default behavior. */
IS_AGGR_TYPE (t) = 1;
if (IS_AGGR_TYPE_CODE (code))
{
struct obstack *obstack = current_obstack;
register int i = sizeof (struct lang_type) / sizeof (int);
register int *pi;
SET_IS_AGGR_TYPE (t, 1);
if (! TREE_PERMANENT (t))
obstack = saveable_obstack;
else
my_friendly_assert (obstack == &permanent_obstack, 236);
if (! TREE_PERMANENT (t))
obstack = saveable_obstack;
else
my_friendly_assert (obstack == &permanent_obstack, 236);
pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
while (i > 0)
pi[--i] = 0;
pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
while (i > 0)
pi[--i] = 0;
TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t);
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE);
CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t));
TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t);
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE);
CLASSTYPE_BINFO_AS_LIST (t)
= build_tree_list (NULL_TREE, TYPE_BINFO (t));
/* Make sure this is laid out, for ease of use later.
In the presence of parse errors, the normal was of assuring
this might not ever get executed, so we lay it out *immediately*. */
build_pointer_type (t);
/* Make sure this is laid out, for ease of use later. In the
presence of parse errors, the normal was of assuring this
might not ever get executed, so we lay it out *immediately*. */
build_pointer_type (t);
#ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_type] += 1;
tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
tree_node_counts[(int)lang_type] += 1;
tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
#endif
}
else
/* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits. But,
TYPE_ALIAS_SET is initialized to -1 by default, so we must
clear it here. */
TYPE_ALIAS_SET (t) = 0;
return t;
}

View File

@ -916,7 +916,7 @@ build_overload_identifier (name)
tree name;
{
if (TREE_CODE (name) == TYPE_DECL
&& IS_AGGR_TYPE (TREE_TYPE (name))
&& CLASS_TYPE_P (TREE_TYPE (name))
&& CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name))
&& (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)))
|| (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE
@ -1435,14 +1435,14 @@ process_overload_item (parmtype, extra_Gcode)
case TEMPLATE_TEMPLATE_PARM:
/* Find and output the original template parameter
declaration. */
if (CLASSTYPE_TEMPLATE_INFO (parmtype))
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parmtype))
{
build_mangled_template_parm_index ("tzX",
TEMPLATE_TYPE_PARM_INDEX
(parmtype));
build_template_parm_names
(DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (parmtype)),
CLASSTYPE_TI_ARGS (parmtype));
(DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (parmtype)),
TYPE_TI_ARGS (parmtype));
}
else
{

View File

@ -1656,7 +1656,6 @@ process_template_parm (list, next)
decl = build_decl (TYPE_DECL, parm, t);
}
CLASSTYPE_GOT_SEMICOLON (t) = 1;
TYPE_NAME (t) = decl;
TYPE_STUB_DECL (t) = decl;
parm = decl;
@ -2885,7 +2884,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
= ((TREE_CODE (arg) == TEMPLATE_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
|| (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
&& !CLASSTYPE_TEMPLATE_INFO (arg))
&& !TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (arg))
|| (TREE_CODE (arg) == RECORD_TYPE
&& CLASSTYPE_TEMPLATE_INFO (arg)
&& TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL
@ -3464,7 +3463,6 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
tree template2 = TYPE_STUB_DECL (parm);
tree arglist2;
CLASSTYPE_GOT_SEMICOLON (parm) = 1;
parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
arglist2 = coerce_template_parms (parmlist, arglist, template, 1, 1);
@ -3472,7 +3470,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
return error_mark_node;
arglist2 = copy_to_permanent (arglist2);
CLASSTYPE_TEMPLATE_INFO (parm)
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm)
= perm_tree_cons (template2, arglist2, NULL_TREE);
TYPE_SIZE (parm) = 0;
return parm;
@ -3491,6 +3489,10 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
parm_depth = TMPL_PARMS_DEPTH (parmlist);
arg_depth = TMPL_ARGS_DEPTH (arglist);
/* We build up the coerced arguments and such on the
momentary_obstack. */
push_momentary ();
if (arg_depth == 1 && parm_depth > 1)
{
/* We've been given an incomplete set of template arguments.
@ -3626,8 +3628,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
if (found)
{
if (can_free (&permanent_obstack, arglist))
obstack_free (&permanent_obstack, arglist);
pop_momentary ();
return found;
}
@ -3753,6 +3754,9 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
/* We're done with the permanent obstack, now. */
pop_obstacks ();
/* We're also done with the momentary allocation we started
above. */
pop_momentary ();
/* Reset the name of the type, now that CLASSTYPE_TEMPLATE_INFO
is set up. */
@ -3928,8 +3932,8 @@ for_each_template_parm (t, fn, data)
/* template parm nodes */
case TEMPLATE_TEMPLATE_PARM:
/* Record template parameters such as `T' inside `TT<T>'. */
if (CLASSTYPE_TEMPLATE_INFO (t)
&& for_each_template_parm (CLASSTYPE_TI_ARGS (t), fn, data))
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)
&& for_each_template_parm (TYPE_TI_ARGS (t), fn, data))
return 1;
case TEMPLATE_TYPE_PARM:
case TEMPLATE_PARM_INDEX:
@ -4454,6 +4458,12 @@ instantiate_class_template (type)
if (TYPE_BEING_DEFINED (type) || TYPE_SIZE (type))
return type;
/* We want to allocate temporary vectors of template arguments and
template argument expressions on the momentary obstack, not on
the expression obstack. Otherwise, all the space allocated in
argument coercion and such is simply lost. */
push_momentary ();
template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
args = CLASSTYPE_TI_ARGS (type);
my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
@ -4473,7 +4483,8 @@ instantiate_class_template (type)
}
}
TYPE_BEING_DEFINED (type) = 1;
return error_mark_node;
type = error_mark_node;
goto end;
}
else if (t)
pattern = TREE_TYPE (t);
@ -4481,7 +4492,7 @@ instantiate_class_template (type)
pattern = TREE_TYPE (template);
if (TYPE_SIZE (pattern) == NULL_TREE)
return type;
goto end;
if (t)
{
@ -4520,13 +4531,13 @@ instantiate_class_template (type)
type as complete so that, for example, declaring one of its
members to be a friend will not be rejected. */
TYPE_SIZE (type) = integer_zero_node;
return type;
goto end;
}
TYPE_BEING_DEFINED (type) = 1;
if (! push_tinst_level (type))
return type;
goto end;
maybe_push_to_top_level (uses_template_parms (type));
pushclass (type, 0);
@ -4598,7 +4609,7 @@ instantiate_class_template (type)
TYPE_METHODS (type) = TYPE_METHODS (pattern);
CLASSTYPE_TAGS (type) = CLASSTYPE_TAGS (pattern);
TYPE_SIZE (type) = integer_zero_node;
goto end;
goto done_with_instantiation;
}
{
@ -4830,13 +4841,16 @@ instantiate_class_template (type)
TYPE_BEING_DEFINED (type) = 0;
repo_template_used (type);
end:
done_with_instantiation:
TYPE_BEING_DEFINED (type) = 0;
popclass (0);
pop_from_top_level ();
pop_tinst_level ();
end:
pop_momentary ();
return type;
}
@ -4921,7 +4935,7 @@ tsubst_template_arg_vector (t, args)
if (!need_new)
return t;
t = make_tree_vec (len);
t = make_temp_vec (len);
for (i = 0; i < len; i++)
TREE_VEC_ELT (t, i) = elts[i];
@ -5026,10 +5040,12 @@ tsubst_aggr_type (t, args, in_decl, entering_scope)
and supposing that we are instantiating f<int, double>,
then our ARGS will be {int, double}, but, when looking up
S we only want {double}. */
argvec = tsubst (TYPE_TI_ARGS (t), args, in_decl);
push_momentary ();
argvec = tsubst_template_arg_vector (TYPE_TI_ARGS (t), args);
r = lookup_template_class (t, argvec, in_decl, context,
entering_scope);
pop_momentary ();
return cp_build_qualified_type (r, TYPE_QUALS (t));
}
@ -5083,7 +5099,10 @@ tsubst_decl (t, args, type, in_decl)
tree tmpl_args = DECL_CLASS_TEMPLATE_P (t)
? CLASSTYPE_TI_ARGS (TREE_TYPE (t))
: DECL_TI_ARGS (DECL_RESULT (t));
tree full_args = tsubst (tmpl_args, args, in_decl);
tree full_args;
push_momentary ();
full_args = tsubst_template_arg_vector (tmpl_args, args);
/* tsubst_template_arg_vector doesn't copy the vector if
nothing changed. But, *something* should have
@ -5091,6 +5110,7 @@ tsubst_decl (t, args, type, in_decl)
my_friendly_assert (full_args != tmpl_args, 0);
spec = retrieve_specialization (t, full_args);
pop_momentary ();
if (spec != NULL_TREE)
{
r = spec;
@ -5234,21 +5254,34 @@ tsubst_decl (t, args, type, in_decl)
{
tree spec;
/* Allocate template arguments on the momentary obstack,
in case we don't need to keep them. */
push_momentary ();
/* Calculate the most general template of which R is a
specialization, and the complete set of arguments used to
specialize R. */
gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t));
argvec = tsubst (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (gen_tmpl)),
args, in_decl);
argvec
= tsubst_template_arg_vector (DECL_TI_ARGS
(DECL_TEMPLATE_RESULT (gen_tmpl)),
args);
/* Check to see if we already have this specialization. */
spec = retrieve_specialization (gen_tmpl, argvec);
if (spec)
{
r = spec;
pop_momentary ();
break;
}
/* We're going to need to keep the ARGVEC, so we copy it
here. */
argvec = copy_to_permanent (argvec);
pop_momentary ();
/* Here, we deal with the peculiar case:
template <class T> struct S {
@ -5375,6 +5408,9 @@ tsubst_decl (t, args, type, in_decl)
case mentioned above where GEN_TMPL is NULL. */
if (gen_tmpl)
{
/* The ARGVEC was built on the momentary obstack. Make it
permanent now. */
argvec = copy_to_permanent (argvec);
DECL_TEMPLATE_INFO (r)
= perm_tree_cons (gen_tmpl, argvec, NULL_TREE);
SET_DECL_IMPLICIT_INSTANTIATION (r);
@ -5631,6 +5667,7 @@ tsubst (t, args, in_decl)
{
tree max = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
max = tsubst_expr (max, args, in_decl);
if (processing_template_decl)
{
@ -5650,6 +5687,8 @@ tsubst (t, args, in_decl)
}
max = fold (build_binary_op (MINUS_EXPR, max, integer_one_node, 1));
if (!TREE_PERMANENT (max) && !allocation_temporary_p ())
max = copy_to_permanent (max);
return build_index_type (max);
}
@ -5696,11 +5735,11 @@ tsubst (t, args, in_decl)
}
else if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
{
if (CLASSTYPE_TEMPLATE_INFO (t))
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
{
/* We are processing a type constructed from
a template template parameter */
tree argvec = tsubst (CLASSTYPE_TI_ARGS (t),
tree argvec = tsubst (TYPE_TI_ARGS (t),
args, in_decl);
/* We can get a TEMPLATE_TEMPLATE_PARM here when
@ -5751,10 +5790,10 @@ tsubst (t, args, in_decl)
TYPE_REFERENCE_TO (r) = NULL_TREE;
if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
&& CLASSTYPE_TEMPLATE_INFO (t))
&& TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
{
tree argvec = tsubst (CLASSTYPE_TI_ARGS (t), args, in_decl);
CLASSTYPE_TEMPLATE_INFO (r)
tree argvec = tsubst (TYPE_TI_ARGS (t), args, in_decl);
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
= perm_tree_cons (TYPE_NAME (t), argvec, NULL_TREE);
}
break;
@ -7348,7 +7387,7 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM)
{
if (CLASSTYPE_TEMPLATE_INFO (parm))
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm))
{
/* We arrive here when PARM does not involve template
specialization. */
@ -7358,8 +7397,8 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
return 1;
{
tree parmtmpl = CLASSTYPE_TI_TEMPLATE (parm);
tree parmvec = CLASSTYPE_TI_ARGS (parm);
tree parmtmpl = TYPE_TI_TEMPLATE (parm);
tree parmvec = TYPE_TI_ARGS (parm);
tree argvec = CLASSTYPE_TI_ARGS (arg);
tree argtmplvec
= DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (arg));
@ -8170,7 +8209,7 @@ do_type_instantiation (t, storage)
if (TREE_CODE (t) == TYPE_DECL)
t = TREE_TYPE (t);
if (! IS_AGGR_TYPE (t) || ! CLASSTYPE_TEMPLATE_INFO (t))
if (! CLASS_TYPE_P (t) || ! CLASSTYPE_TEMPLATE_INFO (t))
{
cp_error ("explicit instantiation of non-template type `%T'", t);
return;

View File

@ -1281,7 +1281,8 @@ static int
lookup_fnfields_1 (type, name)
tree type, name;
{
register tree method_vec = CLASSTYPE_METHOD_VEC (type);
register tree method_vec
= CLASS_TYPE_P (type) ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE;
if (method_vec != 0)
{
@ -3006,6 +3007,7 @@ dfs_pushdecls (binfo)
/* If the class value is not an envelope of the kind described in
the comment above, we create a new envelope. */
maybe_push_cache_obstack ();
if (class_value == NULL_TREE || TREE_CODE (class_value) != TREE_LIST
|| TREE_PURPOSE (class_value) == NULL_TREE
|| TREE_CODE (TREE_PURPOSE (class_value)) == IDENTIFIER_NODE)
@ -3018,10 +3020,11 @@ dfs_pushdecls (binfo)
}
envelope_add_decl (type, fields, &TREE_PURPOSE (class_value));
pop_obstacks ();
}
}
method_vec = CLASSTYPE_METHOD_VEC (type);
method_vec = CLASS_TYPE_P (type) ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE;
if (method_vec && ! dummy)
{
tree *methods;
@ -3043,6 +3046,8 @@ dfs_pushdecls (binfo)
name = DECL_NAME (OVL_CURRENT (*methods));
class_value = IDENTIFIER_CLASS_VALUE (name);
maybe_push_cache_obstack ();
/* If the class value is not an envelope of the kind described in
the comment above, we create a new envelope. */
if (class_value == NULL_TREE || TREE_CODE (class_value) != TREE_LIST
@ -3059,7 +3064,6 @@ dfs_pushdecls (binfo)
/* Here we try to rule out possible ambiguities.
If we can't do that, keep a TREE_LIST with possibly ambiguous
decls in there. */
maybe_push_cache_obstack ();
/* Arbitrarily choose the first function in the list. This is OK
because this is only used for initial lookup; anything that
actually uses the function will look it up again. */
@ -3081,7 +3085,8 @@ dfs_compress_decls (binfo)
tree binfo;
{
tree type = BINFO_TYPE (binfo);
tree method_vec = CLASSTYPE_METHOD_VEC (type);
tree method_vec
= CLASS_TYPE_P (type) ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE;
if (processing_template_decl && type != current_class_type
&& dependent_base_p (binfo))
@ -3131,6 +3136,11 @@ push_class_decls (type)
struct obstack *ambient_obstack = current_obstack;
search_stack = push_search_level (search_stack, &search_obstack);
/* Build up all the relevant bindings and such on the cache
obstack. That way no memory is wasted when we throw away the
cache later. */
maybe_push_cache_obstack ();
/* Push class fields into CLASS_VALUE scope, and mark. */
dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarked_pushdecls_p);
@ -3198,6 +3208,10 @@ push_class_decls (type)
pushdecl_class_level (new);
closed_envelopes = TREE_CHAIN (closed_envelopes);
}
/* Undo the call to maybe_push_cache_obstack above. */
pop_obstacks ();
current_obstack = ambient_obstack;
}

View File

@ -1616,7 +1616,6 @@ finish_typeof (expr)
end_temporary_allocation ();
t = make_lang_type (TYPEOF_TYPE);
CLASSTYPE_GOT_SEMICOLON (t) = 1;
TYPE_FIELDS (t) = expr;
pop_obstacks ();

View File

@ -209,7 +209,7 @@ build_signature_pointer_or_reference_type (to_type, type_quals, refp)
TYPE_ALIGN (optr_type));
/* A signature pointer/reference type isn't a `real' class type. */
IS_AGGR_TYPE (t) = 0;
SET_IS_AGGR_TYPE (t, 0);
}
{

View File

@ -1169,7 +1169,7 @@ make_binfo (offset, binfo, vtable, virtuals)
else
{
type = binfo;
binfo = TYPE_BINFO (binfo);
binfo = CLASS_TYPE_P (type) ? TYPE_BINFO (binfo) : NULL_TREE;
}
TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
@ -1506,7 +1506,8 @@ copy_template_template_parm (t)
/* No need to copy these */
TYPE_FIELDS (t2) = TYPE_FIELDS (t);
CLASSTYPE_TEMPLATE_INFO (t2) = CLASSTYPE_TEMPLATE_INFO (t);
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2)
= TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t);
return t2;
}
@ -2490,17 +2491,17 @@ cp_tree_equal (t1, t2)
return -1;
}
/* Similar to make_tree_vec, but build on a temporary obstack. */
/* Similar to make_tree_vec, but build on the momentary_obstack.
Thus, these vectors are really and truly temporary. */
tree
make_temp_vec (len)
int len;
{
register tree node;
register struct obstack *ambient_obstack = current_obstack;
current_obstack = expression_obstack;
push_expression_obstack ();
node = make_tree_vec (len);
current_obstack = ambient_obstack;
pop_obstacks ();
return node;
}

View File

@ -154,7 +154,7 @@ complete_type (type)
TYPE_NEEDS_DESTRUCTOR (type)
= TYPE_NEEDS_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
}
else if (IS_AGGR_TYPE (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
instantiate_class_template (TYPE_MAIN_VARIANT (type));
return type;
@ -773,7 +773,8 @@ comptypes (type1, type2, strict)
if (! comp_template_parms (DECL_TEMPLATE_PARMS (TYPE_NAME (t1)),
DECL_TEMPLATE_PARMS (TYPE_NAME (t2))))
return 0;
if (! CLASSTYPE_TEMPLATE_INFO (t1) && ! CLASSTYPE_TEMPLATE_INFO (t2))
if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t1)
&& ! TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2))
return 1;
/* Don't check inheritance. */
strict = COMPARE_STRICT;
@ -781,11 +782,11 @@ comptypes (type1, type2, strict)
case RECORD_TYPE:
case UNION_TYPE:
if (CLASSTYPE_TEMPLATE_INFO (t1) && CLASSTYPE_TEMPLATE_INFO (t2)
&& (CLASSTYPE_TI_TEMPLATE (t1) == CLASSTYPE_TI_TEMPLATE (t2)
if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
&& (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
|| TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM))
val = comp_template_args (CLASSTYPE_TI_ARGS (t1),
CLASSTYPE_TI_ARGS (t2));
val = comp_template_args (TYPE_TI_ARGS (t1),
TYPE_TI_ARGS (t2));
look_hard:
if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
{