From e4e283ecbf481b0c32987dd178a4078f7d404a15 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Tue, 17 Nov 1998 12:51:20 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@23686 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 70 ++++++++++++++++++++++++++++ gcc/cp/Makefile.in | 7 +-- gcc/cp/class.c | 36 +++++++++++---- gcc/cp/cp-tree.h | 133 ++++++++++++++++++++++++++++++++++++----------------- gcc/cp/decl.c | 127 +++++++++++++++++++++++++++++++++++++++++--------- gcc/cp/error.c | 4 +- gcc/cp/lex.c | 58 +++++++++++++---------- gcc/cp/method.c | 8 ++-- gcc/cp/pt.c | 95 +++++++++++++++++++++++++++----------- gcc/cp/search.c | 22 +++++++-- gcc/cp/semantics.c | 1 - gcc/cp/sig.c | 2 +- gcc/cp/tree.c | 13 +++--- gcc/cp/typeck.c | 13 +++--- 14 files changed, 435 insertions(+), 154 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6c3895f..1102b9e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,73 @@ +1998-11-17 Mark Mitchell + + * 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 * pt.c (tsubst): Add diagnostics for invalid array, reference diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in index 0bc20fe..463c0f6 100644 --- a/gcc/cp/Makefile.in +++ b/gcc/cp/Makefile.in @@ -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 \ diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 41ca265..7668697 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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, diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 033c29a..99cb2d9 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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'. */ -#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. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a9779f9..bd8c5c8 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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; diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 13469c0..d754601 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -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++) diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 5901c8a..5bbb966 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -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; } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 21dbbab..8428e85 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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 { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a416bf9..9955835 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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'. */ - 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, 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 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; diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 4157a5d..ee44bba 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -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; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index e2cf813..5e3876f 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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 (); diff --git a/gcc/cp/sig.c b/gcc/cp/sig.c index 00ba770..fdc1ea2 100644 --- a/gcc/cp/sig.c +++ b/gcc/cp/sig.c @@ -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); } { diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 1b27762..deaa20c 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 53ca221..8f7e329 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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)) { -- 2.7.4