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:
parent
990ece87bd
commit
7ddedda4aa
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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,
|
||||
|
|
129
gcc/cp/cp-tree.h
129
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))
|
||||
? 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. */
|
||||
|
|
115
gcc/cp/decl.c
115
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;
|
||||
|
||||
static struct hash_table ht;
|
||||
|
||||
if (processing_template_decl)
|
||||
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,7 +4862,19 @@ 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)
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, 0));
|
||||
|
||||
if (CLASS_TYPE_P (basetype))
|
||||
TYPE_USES_MULTIPLE_INHERITANCE (ref)
|
||||
= TYPE_USES_MULTIPLE_INHERITANCE (BINFO_TYPE (TREE_VEC_ELT (binfos, 0)));
|
||||
= 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;
|
||||
}
|
||||
|
||||
pushlevel (0);
|
||||
current_binding_level->parm_flag = 1;
|
||||
|
|
|
@ -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++)
|
||||
|
|
24
gcc/cp/lex.c
24
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,12 +4666,15 @@ make_lang_type (code)
|
|||
{
|
||||
extern struct obstack *current_obstack, *saveable_obstack;
|
||||
register tree t = make_node (code);
|
||||
|
||||
/* Set up some flags that give proper default behavior. */
|
||||
if (IS_AGGR_TYPE_CODE (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;
|
||||
SET_IS_AGGR_TYPE (t, 1);
|
||||
|
||||
if (! TREE_PERMANENT (t))
|
||||
obstack = saveable_obstack;
|
||||
|
@ -4687,17 +4690,24 @@ make_lang_type (code)
|
|||
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));
|
||||
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*. */
|
||||
/* 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);
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
95
gcc/cp/pt.c
95
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<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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue