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>
|
1998-11-17 Jason Merrill <jason@yorick.cygnus.com>
|
||||||
|
|
||||||
* pt.c (tsubst): Add diagnostics for invalid array, reference
|
* 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@
|
repo.o @extra_cxx_objs@
|
||||||
|
|
||||||
# Language-independent object files.
|
# Language-independent object files.
|
||||||
OBJS = `cat ../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
|
OBJDEPS = ../stamp-objlist ../c-common.o ../c-pragma.o ../hash.o
|
||||||
|
|
||||||
compiler: ../cc1plus$(exeext)
|
compiler: ../cc1plus$(exeext)
|
||||||
../cc1plus$(exeext): $(P) $(OBJDEPS) $(CXX_OBJS) $(LIBDEPS)
|
../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
|
$(srcdir)/../output.h $(srcdir)/../mbchar.h
|
||||||
decl.o : decl.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
|
decl.o : decl.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
|
||||||
lex.h decl.h $(srcdir)/../stack.h $(srcdir)/../output.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 \
|
decl2.o : decl2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
|
||||||
lex.h decl.h $(EXPR_H) $(srcdir)/../except.h \
|
lex.h decl.h $(EXPR_H) $(srcdir)/../except.h \
|
||||||
$(srcdir)/../output.h $(srcdir)/../except.h $(srcdir)/../system.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
|
tree previous_class_values; /* TREE_LIST: copy of the class_shadowed list
|
||||||
when leaving an outermost class scope. */
|
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;
|
struct base_info;
|
||||||
|
|
||||||
static tree get_vfield_name PROTO((tree));
|
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) */
|
will fill in the right line number. (mrs) */
|
||||||
if (DECL_SOURCE_LINE (name))
|
if (DECL_SOURCE_LINE (name))
|
||||||
DECL_SOURCE_LINE (name) = lineno;
|
DECL_SOURCE_LINE (name) = lineno;
|
||||||
CLASSTYPE_SOURCE_LINE (t) = lineno;
|
|
||||||
name = DECL_NAME (name);
|
name = DECL_NAME (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4701,6 +4706,11 @@ pushclass (type, modify)
|
||||||
/* Forcibly remove any old class remnants. */
|
/* Forcibly remove any old class remnants. */
|
||||||
popclass (-1);
|
popclass (-1);
|
||||||
previous_class_type = NULL_TREE;
|
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 ();
|
pushlevel_class ();
|
||||||
|
@ -4794,7 +4804,8 @@ popclass (modify)
|
||||||
TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
|
TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
|
||||||
tags = TREE_CHAIN (tags);
|
tags = TREE_CHAIN (tags);
|
||||||
}
|
}
|
||||||
goto ret;
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modify)
|
if (modify)
|
||||||
|
@ -4824,9 +4835,6 @@ popclass (modify)
|
||||||
current_class_name = current_class_stack[current_class_depth].name;
|
current_class_name = current_class_stack[current_class_depth].name;
|
||||||
current_class_type = current_class_stack[current_class_depth].type;
|
current_class_type = current_class_stack[current_class_depth].type;
|
||||||
current_access_specifier = current_class_stack[current_class_depth].access;
|
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. */
|
/* 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
|
/* 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
|
decls that may be cached in the previous_class_values list. The
|
||||||
use the permanent obstack, later we may create a dedicated obstack just
|
effect is undone by pop_obstacks. */
|
||||||
for this purpose. The effect is undone by pop_obstacks. */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
maybe_push_cache_obstack ()
|
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 ();
|
push_obstacks_nochange ();
|
||||||
if (current_class_depth == 1)
|
current_obstack = &class_cache_obstack;
|
||||||
current_obstack = &permanent_obstack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build a dummy reference to ourselves so Derived::Base (and A::A) works,
|
/* Build a dummy reference to ourselves so Derived::Base (and A::A) works,
|
||||||
|
|
133
gcc/cp/cp-tree.h
133
gcc/cp/cp-tree.h
|
@ -72,6 +72,19 @@ Boston, MA 02111-1307, USA. */
|
||||||
5: DECL_INTERFACE_KNOWN.
|
5: DECL_INTERFACE_KNOWN.
|
||||||
6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL).
|
6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL).
|
||||||
7: DECL_DEAD_FOR_LOCAL (in VAR_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. */
|
/* 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,
|
for template type parameters and typename types. Despite its name,
|
||||||
this macro has nothing to do with the definition of aggregate given
|
this macro has nothing to do with the definition of aggregate given
|
||||||
in the standard. Think of this macro as MAYBE_CLASS_TYPE_P. */
|
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,
|
/* Nonzero if T is a class type. Zero for template type parameters,
|
||||||
typename types, and so forth. */
|
typename types, and so forth. */
|
||||||
#define CLASS_TYPE_P(t) \
|
#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_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE)
|
||||||
#define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
|
#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 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)
|
#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
|
/* This structure provides additional information above and beyond
|
||||||
thousands of different types during a compilation run, it
|
what is provide in the ordinary tree_type. In the past, we used it
|
||||||
generates relatively few (tens) of classtypes. Because of this,
|
for the types of class types, template parameters types, typename
|
||||||
it is not costly to store a generous amount of information
|
types, and so forth. However, there can be many (tens to hundreds
|
||||||
in classtype nodes. This struct must fill out to a multiple of 4 bytes. */
|
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 lang_type
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
|
@ -621,25 +651,20 @@ struct lang_type
|
||||||
unsigned has_arrow_overloaded : 1;
|
unsigned has_arrow_overloaded : 1;
|
||||||
unsigned interface_only : 1;
|
unsigned interface_only : 1;
|
||||||
unsigned interface_unknown : 1;
|
unsigned interface_unknown : 1;
|
||||||
|
|
||||||
unsigned needs_virtual_reinit : 1;
|
unsigned needs_virtual_reinit : 1;
|
||||||
|
|
||||||
|
unsigned marks: 6;
|
||||||
unsigned vec_delete_takes_size : 1;
|
unsigned vec_delete_takes_size : 1;
|
||||||
unsigned declared_class : 1;
|
unsigned declared_class : 1;
|
||||||
|
|
||||||
unsigned being_defined : 1;
|
unsigned being_defined : 1;
|
||||||
unsigned redefined : 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 debug_requested : 1;
|
||||||
unsigned use_template : 2;
|
unsigned use_template : 2;
|
||||||
unsigned got_semicolon : 1;
|
unsigned got_semicolon : 1;
|
||||||
unsigned ptrmemfunc_flag : 1;
|
unsigned ptrmemfunc_flag : 1;
|
||||||
|
|
||||||
unsigned is_signature : 1;
|
unsigned is_signature : 1;
|
||||||
|
|
||||||
unsigned is_signature_pointer : 1;
|
unsigned is_signature_pointer : 1;
|
||||||
unsigned is_signature_reference : 1;
|
unsigned is_signature_reference : 1;
|
||||||
unsigned has_opaque_typedecls : 1;
|
unsigned has_opaque_typedecls : 1;
|
||||||
|
@ -647,8 +672,8 @@ struct lang_type
|
||||||
unsigned was_anonymous : 1;
|
unsigned was_anonymous : 1;
|
||||||
unsigned has_real_assignment : 1;
|
unsigned has_real_assignment : 1;
|
||||||
unsigned has_real_assign_ref : 1;
|
unsigned has_real_assign_ref : 1;
|
||||||
|
|
||||||
unsigned has_const_init_ref : 1;
|
unsigned has_const_init_ref : 1;
|
||||||
|
|
||||||
unsigned has_complex_init_ref : 1;
|
unsigned has_complex_init_ref : 1;
|
||||||
unsigned has_complex_assign_ref : 1;
|
unsigned has_complex_assign_ref : 1;
|
||||||
unsigned has_abstract_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 *signature_reference_to;
|
||||||
|
|
||||||
union tree_node *template_info;
|
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.
|
/* Indicates whether or not (and how) a template was expanded for this class.
|
||||||
0=no information yet/non-template class
|
0=no information yet/non-template class
|
||||||
1=implicit template instantiation
|
1=implicit template instantiation
|
||||||
|
@ -839,25 +860,45 @@ struct lang_type
|
||||||
#define CLASSTYPE_BASELINK_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->baselink_vec)
|
#define CLASSTYPE_BASELINK_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->baselink_vec)
|
||||||
|
|
||||||
/* Mark bits for depth-first and breath-first searches. */
|
/* 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)
|
/* Get the value of the Nth mark bit. */
|
||||||
#define CLASSTYPE_MARKED3(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked3)
|
#define CLASSTYPE_MARKED_N(NODE, N) \
|
||||||
#define CLASSTYPE_MARKED4(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked4)
|
(((CLASS_TYPE_P (NODE) ? TYPE_LANG_SPECIFIC (NODE)->type_flags.marks \
|
||||||
#define CLASSTYPE_MARKED5(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked5)
|
: TYPE_ALIAS_SET (NODE)) & (1 << N)) != 0)
|
||||||
#define CLASSTYPE_MARKED6(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked6)
|
|
||||||
|
/* 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 */
|
/* Macros to modify the above flags */
|
||||||
#define SET_CLASSTYPE_MARKED(NODE) (CLASSTYPE_MARKED(NODE) = 1)
|
#define SET_CLASSTYPE_MARKED(NODE) SET_CLASSTYPE_MARKED_N(NODE, 0)
|
||||||
#define CLEAR_CLASSTYPE_MARKED(NODE) (CLASSTYPE_MARKED(NODE) = 0)
|
#define CLEAR_CLASSTYPE_MARKED(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 0)
|
||||||
#define SET_CLASSTYPE_MARKED2(NODE) (CLASSTYPE_MARKED2(NODE) = 1)
|
#define SET_CLASSTYPE_MARKED2(NODE) SET_CLASSTYPE_MARKED_N(NODE, 1)
|
||||||
#define CLEAR_CLASSTYPE_MARKED2(NODE) (CLASSTYPE_MARKED2(NODE) = 0)
|
#define CLEAR_CLASSTYPE_MARKED2(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 1)
|
||||||
#define SET_CLASSTYPE_MARKED3(NODE) (CLASSTYPE_MARKED3(NODE) = 1)
|
#define SET_CLASSTYPE_MARKED3(NODE) SET_CLASSTYPE_MARKED_N(NODE, 2)
|
||||||
#define CLEAR_CLASSTYPE_MARKED3(NODE) (CLASSTYPE_MARKED3(NODE) = 0)
|
#define CLEAR_CLASSTYPE_MARKED3(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 2)
|
||||||
#define SET_CLASSTYPE_MARKED4(NODE) (CLASSTYPE_MARKED4(NODE) = 1)
|
#define SET_CLASSTYPE_MARKED4(NODE) SET_CLASSTYPE_MARKED_N(NODE, 3)
|
||||||
#define CLEAR_CLASSTYPE_MARKED4(NODE) (CLASSTYPE_MARKED4(NODE) = 0)
|
#define CLEAR_CLASSTYPE_MARKED4(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 3)
|
||||||
#define SET_CLASSTYPE_MARKED5(NODE) (CLASSTYPE_MARKED5(NODE) = 1)
|
#define SET_CLASSTYPE_MARKED5(NODE) SET_CLASSTYPE_MARKED_N(NODE, 4)
|
||||||
#define CLEAR_CLASSTYPE_MARKED5(NODE) (CLASSTYPE_MARKED5(NODE) = 0)
|
#define CLEAR_CLASSTYPE_MARKED5(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 4)
|
||||||
#define SET_CLASSTYPE_MARKED6(NODE) (CLASSTYPE_MARKED6(NODE) = 1)
|
#define SET_CLASSTYPE_MARKED6(NODE) SET_CLASSTYPE_MARKED_N(NODE, 5)
|
||||||
#define CLEAR_CLASSTYPE_MARKED6(NODE) (CLASSTYPE_MARKED6(NODE) = 0)
|
#define CLEAR_CLASSTYPE_MARKED6(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 5)
|
||||||
|
|
||||||
/* A list of the nested tag-types (class, struct, union, or enum)
|
/* 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
|
found within this class. The TREE_PURPOSE of each node is the name
|
||||||
|
@ -1301,10 +1342,16 @@ struct lang_decl
|
||||||
non-type template parameters. */
|
non-type template parameters. */
|
||||||
#define ENUM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE))
|
#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. */
|
/* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE. */
|
||||||
#define TYPE_TEMPLATE_INFO(NODE) \
|
#define TYPE_TEMPLATE_INFO(NODE) \
|
||||||
(TREE_CODE (NODE) == ENUMERAL_TYPE \
|
(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
|
/* Set the template information for an ENUMERAL_, RECORD_, or
|
||||||
UNION_TYPE to VAL. */
|
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
|
this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the
|
||||||
corresponding TYPE_DECL. However, this may also be a
|
corresponding TYPE_DECL. However, this may also be a
|
||||||
TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'. */
|
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
|
/* Nonzero in INTEGER_CST means that this int is negative by dint of
|
||||||
using a twos-complement negated operand. */
|
using a twos-complement negated operand. */
|
||||||
|
|
127
gcc/cp/decl.c
127
gcc/cp/decl.c
|
@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA. */
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "except.h"
|
#include "except.h"
|
||||||
#include "toplev.h"
|
#include "toplev.h"
|
||||||
|
#include "../hash.h"
|
||||||
|
|
||||||
#define obstack_chunk_alloc xmalloc
|
#define obstack_chunk_alloc xmalloc
|
||||||
#define obstack_chunk_free free
|
#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 void lang_print_error_function PROTO((char *));
|
||||||
static tree maybe_process_template_type_declaration PROTO((tree, int, struct binding_level*));
|
static tree maybe_process_template_type_declaration PROTO((tree, int, struct binding_level*));
|
||||||
static void check_for_uninitialized_const_var PROTO((tree));
|
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)
|
#if defined (DEBUG_CP_BINDING_LEVELS)
|
||||||
static void indent PROTO((void));
|
static void indent PROTO((void));
|
||||||
|
@ -4778,6 +4781,47 @@ lookup_namespace_name (namespace, name)
|
||||||
return error_mark_node;
|
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
|
/* 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
|
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
|
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 t;
|
||||||
tree d;
|
tree d;
|
||||||
|
struct hash_entry* e;
|
||||||
|
|
||||||
if (processing_template_decl)
|
static struct hash_table ht;
|
||||||
push_obstacks (&permanent_obstack, &permanent_obstack);
|
|
||||||
|
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. */
|
/* Build the TYPENAME_TYPE. */
|
||||||
t = make_lang_type (TYPENAME_TYPE);
|
t = make_lang_type (TYPENAME_TYPE);
|
||||||
TYPE_CONTEXT (t) = FROB_CONTEXT (context);
|
TYPE_CONTEXT (t) = FROB_CONTEXT (context);
|
||||||
TYPENAME_TYPE_FULLNAME (t) = fullname;
|
TYPENAME_TYPE_FULLNAME (t) = fullname;
|
||||||
TREE_TYPE (t) = base_type;
|
TREE_TYPE (t) = base_type;
|
||||||
CLASSTYPE_GOT_SEMICOLON (t) = 1;
|
|
||||||
|
|
||||||
/* Build the corresponding TYPE_DECL. */
|
/* Build the corresponding TYPE_DECL. */
|
||||||
d = build_decl (TYPE_DECL, name, t);
|
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;
|
TYPE_STUB_DECL (TREE_TYPE (d)) = d;
|
||||||
DECL_CONTEXT (d) = FROB_CONTEXT (context);
|
DECL_CONTEXT (d) = FROB_CONTEXT (context);
|
||||||
|
|
||||||
if (processing_template_decl)
|
/* See if we already have this type. */
|
||||||
pop_obstacks ();
|
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;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -8399,7 +8461,7 @@ build_ptrmemfunc_type (type)
|
||||||
push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
|
push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
|
||||||
|
|
||||||
u = make_lang_type (UNION_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[0] = build_lang_field_decl (FIELD_DECL, pfn_identifier, type);
|
||||||
fields[1] = build_lang_field_decl (FIELD_DECL, delta2_identifier,
|
fields[1] = build_lang_field_decl (FIELD_DECL, delta2_identifier,
|
||||||
delta_type_node);
|
delta_type_node);
|
||||||
|
@ -8411,7 +8473,7 @@ build_ptrmemfunc_type (type)
|
||||||
/* Let the front-end know this is a pointer to member function... */
|
/* Let the front-end know this is a pointer to member function... */
|
||||||
TYPE_PTRMEMFUNC_FLAG (t) = 1;
|
TYPE_PTRMEMFUNC_FLAG (t) = 1;
|
||||||
/* ... and not really an aggregate. */
|
/* ... 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,
|
fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier,
|
||||||
delta_type_node);
|
delta_type_node);
|
||||||
|
@ -10074,7 +10136,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||||
ctype = TREE_OPERAND (declarator, 0);
|
ctype = TREE_OPERAND (declarator, 0);
|
||||||
|
|
||||||
t = ctype;
|
t = ctype;
|
||||||
while (t != NULL_TREE)
|
while (t != NULL_TREE && CLASS_TYPE_P (t))
|
||||||
{
|
{
|
||||||
if (CLASSTYPE_TEMPLATE_INFO (t) &&
|
if (CLASSTYPE_TEMPLATE_INFO (t) &&
|
||||||
!CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
|
!CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
|
||||||
|
@ -12001,9 +12063,12 @@ xref_basetypes (code_type_node, name, ref, binfo)
|
||||||
individual inheritance contains flags which say what
|
individual inheritance contains flags which say what
|
||||||
the `accessibility' of that particular inheritance is.) */
|
the `accessibility' of that particular inheritance is.) */
|
||||||
|
|
||||||
base_binfo = make_binfo (integer_zero_node, basetype,
|
base_binfo
|
||||||
TYPE_BINFO_VTABLE (basetype),
|
= make_binfo (integer_zero_node, basetype,
|
||||||
TYPE_BINFO_VIRTUALS (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_VEC_ELT (binfos, i) = base_binfo;
|
||||||
TREE_VIA_PUBLIC (base_binfo) = via_public;
|
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_USES_COMPLEX_INHERITANCE (ref) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype);
|
if (CLASS_TYPE_P (basetype))
|
||||||
TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
|
{
|
||||||
|
TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype);
|
||||||
|
TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
|
||||||
|
}
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12038,8 +12107,14 @@ xref_basetypes (code_type_node, name, ref, binfo)
|
||||||
if (i > 1)
|
if (i > 1)
|
||||||
TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1;
|
TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1;
|
||||||
else if (i == 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))
|
if (TYPE_USES_MULTIPLE_INHERITANCE (ref))
|
||||||
TYPE_USES_COMPLEX_INHERITANCE (ref) = 1;
|
TYPE_USES_COMPLEX_INHERITANCE (ref) = 1;
|
||||||
|
|
||||||
|
@ -12466,8 +12541,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
|
||||||
fntype = TREE_TYPE (decl1);
|
fntype = TREE_TYPE (decl1);
|
||||||
|
|
||||||
restype = TREE_TYPE (fntype);
|
restype = TREE_TYPE (fntype);
|
||||||
if (IS_AGGR_TYPE (restype) && ! TYPE_PTRMEMFUNC_P (restype)
|
if (CLASS_TYPE_P (restype) && !CLASSTYPE_GOT_SEMICOLON (restype))
|
||||||
&& ! CLASSTYPE_GOT_SEMICOLON (restype))
|
|
||||||
{
|
{
|
||||||
cp_error ("semicolon missing after declaration of `%#T'", restype);
|
cp_error ("semicolon missing after declaration of `%#T'", restype);
|
||||||
shadow_tag (build_expr_list (NULL_TREE, 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)
|
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_ptr = NULL_TREE;
|
||||||
current_class_ref = build_indirect_ref (t, NULL_PTR);
|
current_class_ref = build_indirect_ref (t, NULL_PTR);
|
||||||
current_class_ptr = t;
|
current_class_ptr = t;
|
||||||
|
|
||||||
resume_momentary (i);
|
resume_momentary (i);
|
||||||
|
if (! hack_decl_function_context (decl1))
|
||||||
|
end_temporary_allocation ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* We're having a signature pointer here. */
|
/* We're having a signature pointer here. */
|
||||||
|
@ -12693,9 +12778,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
current_class_ptr = current_class_ref = NULL_TREE;
|
||||||
current_class_ptr = current_class_ref = NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pushlevel (0);
|
pushlevel (0);
|
||||||
current_binding_level->parm_flag = 1;
|
current_binding_level->parm_flag = 1;
|
||||||
|
|
|
@ -271,7 +271,7 @@ dump_type_real (t, v, canonical_name)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TEMPLATE_TEMPLATE_PARM:
|
case TEMPLATE_TEMPLATE_PARM:
|
||||||
if (!CLASSTYPE_TEMPLATE_INFO (t))
|
if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
|
||||||
{
|
{
|
||||||
/* For parameters inside template signature. */
|
/* For parameters inside template signature. */
|
||||||
if (TYPE_IDENTIFIER (t))
|
if (TYPE_IDENTIFIER (t))
|
||||||
|
@ -282,7 +282,7 @@ dump_type_real (t, v, canonical_name)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
tree args = CLASSTYPE_TI_ARGS (t);
|
tree args = TYPE_TI_ARGS (t);
|
||||||
OB_PUTID (TYPE_IDENTIFIER (t));
|
OB_PUTID (TYPE_IDENTIFIER (t));
|
||||||
OB_PUTC ('<');
|
OB_PUTC ('<');
|
||||||
for (i = 0; i < TREE_VEC_LENGTH (args); i++)
|
for (i = 0; i < TREE_VEC_LENGTH (args); i++)
|
||||||
|
|
58
gcc/cp/lex.c
58
gcc/cp/lex.c
|
@ -2129,7 +2129,7 @@ note_got_semicolon (type)
|
||||||
{
|
{
|
||||||
if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
|
if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
|
||||||
my_friendly_abort (60);
|
my_friendly_abort (60);
|
||||||
if (IS_AGGR_TYPE (type))
|
if (CLASS_TYPE_P (type))
|
||||||
CLASSTYPE_GOT_SEMICOLON (type) = 1;
|
CLASSTYPE_GOT_SEMICOLON (type) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4666,38 +4666,48 @@ make_lang_type (code)
|
||||||
{
|
{
|
||||||
extern struct obstack *current_obstack, *saveable_obstack;
|
extern struct obstack *current_obstack, *saveable_obstack;
|
||||||
register tree t = make_node (code);
|
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. */
|
/* 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))
|
if (! TREE_PERMANENT (t))
|
||||||
obstack = saveable_obstack;
|
obstack = saveable_obstack;
|
||||||
else
|
else
|
||||||
my_friendly_assert (obstack == &permanent_obstack, 236);
|
my_friendly_assert (obstack == &permanent_obstack, 236);
|
||||||
|
|
||||||
pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
|
pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
|
||||||
while (i > 0)
|
while (i > 0)
|
||||||
pi[--i] = 0;
|
pi[--i] = 0;
|
||||||
|
|
||||||
TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
|
TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
|
||||||
CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t);
|
CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t);
|
||||||
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
|
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
|
||||||
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
|
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
|
||||||
TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE);
|
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.
|
/* Make sure this is laid out, for ease of use later. In the
|
||||||
In the presence of parse errors, the normal was of assuring
|
presence of parse errors, the normal was of assuring this
|
||||||
this might not ever get executed, so we lay it out *immediately*. */
|
might not ever get executed, so we lay it out *immediately*. */
|
||||||
build_pointer_type (t);
|
build_pointer_type (t);
|
||||||
|
|
||||||
#ifdef GATHER_STATISTICS
|
#ifdef GATHER_STATISTICS
|
||||||
tree_node_counts[(int)lang_type] += 1;
|
tree_node_counts[(int)lang_type] += 1;
|
||||||
tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
|
tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
|
||||||
#endif
|
#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;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
|
@ -916,7 +916,7 @@ build_overload_identifier (name)
|
||||||
tree name;
|
tree name;
|
||||||
{
|
{
|
||||||
if (TREE_CODE (name) == TYPE_DECL
|
if (TREE_CODE (name) == TYPE_DECL
|
||||||
&& IS_AGGR_TYPE (TREE_TYPE (name))
|
&& CLASS_TYPE_P (TREE_TYPE (name))
|
||||||
&& CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name))
|
&& CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name))
|
||||||
&& (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)))
|
&& (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)))
|
||||||
|| (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE
|
|| (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE
|
||||||
|
@ -1435,14 +1435,14 @@ process_overload_item (parmtype, extra_Gcode)
|
||||||
case TEMPLATE_TEMPLATE_PARM:
|
case TEMPLATE_TEMPLATE_PARM:
|
||||||
/* Find and output the original template parameter
|
/* Find and output the original template parameter
|
||||||
declaration. */
|
declaration. */
|
||||||
if (CLASSTYPE_TEMPLATE_INFO (parmtype))
|
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parmtype))
|
||||||
{
|
{
|
||||||
build_mangled_template_parm_index ("tzX",
|
build_mangled_template_parm_index ("tzX",
|
||||||
TEMPLATE_TYPE_PARM_INDEX
|
TEMPLATE_TYPE_PARM_INDEX
|
||||||
(parmtype));
|
(parmtype));
|
||||||
build_template_parm_names
|
build_template_parm_names
|
||||||
(DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (parmtype)),
|
(DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (parmtype)),
|
||||||
CLASSTYPE_TI_ARGS (parmtype));
|
TYPE_TI_ARGS (parmtype));
|
||||||
}
|
}
|
||||||
else
|
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);
|
decl = build_decl (TYPE_DECL, parm, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASSTYPE_GOT_SEMICOLON (t) = 1;
|
|
||||||
TYPE_NAME (t) = decl;
|
TYPE_NAME (t) = decl;
|
||||||
TYPE_STUB_DECL (t) = decl;
|
TYPE_STUB_DECL (t) = decl;
|
||||||
parm = decl;
|
parm = decl;
|
||||||
|
@ -2885,7 +2884,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
|
||||||
= ((TREE_CODE (arg) == TEMPLATE_DECL
|
= ((TREE_CODE (arg) == TEMPLATE_DECL
|
||||||
&& TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
|
&& TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
|
||||||
|| (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
|
|| (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
|
||||||
&& !CLASSTYPE_TEMPLATE_INFO (arg))
|
&& !TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (arg))
|
||||||
|| (TREE_CODE (arg) == RECORD_TYPE
|
|| (TREE_CODE (arg) == RECORD_TYPE
|
||||||
&& CLASSTYPE_TEMPLATE_INFO (arg)
|
&& CLASSTYPE_TEMPLATE_INFO (arg)
|
||||||
&& TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL
|
&& 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 template2 = TYPE_STUB_DECL (parm);
|
||||||
tree arglist2;
|
tree arglist2;
|
||||||
|
|
||||||
CLASSTYPE_GOT_SEMICOLON (parm) = 1;
|
|
||||||
parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
|
parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
|
||||||
|
|
||||||
arglist2 = coerce_template_parms (parmlist, arglist, template, 1, 1);
|
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;
|
return error_mark_node;
|
||||||
|
|
||||||
arglist2 = copy_to_permanent (arglist2);
|
arglist2 = copy_to_permanent (arglist2);
|
||||||
CLASSTYPE_TEMPLATE_INFO (parm)
|
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm)
|
||||||
= perm_tree_cons (template2, arglist2, NULL_TREE);
|
= perm_tree_cons (template2, arglist2, NULL_TREE);
|
||||||
TYPE_SIZE (parm) = 0;
|
TYPE_SIZE (parm) = 0;
|
||||||
return parm;
|
return parm;
|
||||||
|
@ -3491,6 +3489,10 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
|
||||||
parm_depth = TMPL_PARMS_DEPTH (parmlist);
|
parm_depth = TMPL_PARMS_DEPTH (parmlist);
|
||||||
arg_depth = TMPL_ARGS_DEPTH (arglist);
|
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)
|
if (arg_depth == 1 && parm_depth > 1)
|
||||||
{
|
{
|
||||||
/* We've been given an incomplete set of template arguments.
|
/* 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 (found)
|
||||||
{
|
{
|
||||||
if (can_free (&permanent_obstack, arglist))
|
pop_momentary ();
|
||||||
obstack_free (&permanent_obstack, arglist);
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3753,6 +3754,9 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
|
||||||
|
|
||||||
/* We're done with the permanent obstack, now. */
|
/* We're done with the permanent obstack, now. */
|
||||||
pop_obstacks ();
|
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
|
/* Reset the name of the type, now that CLASSTYPE_TEMPLATE_INFO
|
||||||
is set up. */
|
is set up. */
|
||||||
|
@ -3928,8 +3932,8 @@ for_each_template_parm (t, fn, data)
|
||||||
/* template parm nodes */
|
/* template parm nodes */
|
||||||
case TEMPLATE_TEMPLATE_PARM:
|
case TEMPLATE_TEMPLATE_PARM:
|
||||||
/* Record template parameters such as `T' inside `TT<T>'. */
|
/* Record template parameters such as `T' inside `TT<T>'. */
|
||||||
if (CLASSTYPE_TEMPLATE_INFO (t)
|
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)
|
||||||
&& for_each_template_parm (CLASSTYPE_TI_ARGS (t), fn, data))
|
&& for_each_template_parm (TYPE_TI_ARGS (t), fn, data))
|
||||||
return 1;
|
return 1;
|
||||||
case TEMPLATE_TYPE_PARM:
|
case TEMPLATE_TYPE_PARM:
|
||||||
case TEMPLATE_PARM_INDEX:
|
case TEMPLATE_PARM_INDEX:
|
||||||
|
@ -4454,6 +4458,12 @@ instantiate_class_template (type)
|
||||||
if (TYPE_BEING_DEFINED (type) || TYPE_SIZE (type))
|
if (TYPE_BEING_DEFINED (type) || TYPE_SIZE (type))
|
||||||
return 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));
|
template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
|
||||||
args = CLASSTYPE_TI_ARGS (type);
|
args = CLASSTYPE_TI_ARGS (type);
|
||||||
my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
|
my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
|
||||||
|
@ -4473,7 +4483,8 @@ instantiate_class_template (type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TYPE_BEING_DEFINED (type) = 1;
|
TYPE_BEING_DEFINED (type) = 1;
|
||||||
return error_mark_node;
|
type = error_mark_node;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
else if (t)
|
else if (t)
|
||||||
pattern = TREE_TYPE (t);
|
pattern = TREE_TYPE (t);
|
||||||
|
@ -4481,7 +4492,7 @@ instantiate_class_template (type)
|
||||||
pattern = TREE_TYPE (template);
|
pattern = TREE_TYPE (template);
|
||||||
|
|
||||||
if (TYPE_SIZE (pattern) == NULL_TREE)
|
if (TYPE_SIZE (pattern) == NULL_TREE)
|
||||||
return type;
|
goto end;
|
||||||
|
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
|
@ -4520,13 +4531,13 @@ instantiate_class_template (type)
|
||||||
type as complete so that, for example, declaring one of its
|
type as complete so that, for example, declaring one of its
|
||||||
members to be a friend will not be rejected. */
|
members to be a friend will not be rejected. */
|
||||||
TYPE_SIZE (type) = integer_zero_node;
|
TYPE_SIZE (type) = integer_zero_node;
|
||||||
return type;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE_BEING_DEFINED (type) = 1;
|
TYPE_BEING_DEFINED (type) = 1;
|
||||||
|
|
||||||
if (! push_tinst_level (type))
|
if (! push_tinst_level (type))
|
||||||
return type;
|
goto end;
|
||||||
|
|
||||||
maybe_push_to_top_level (uses_template_parms (type));
|
maybe_push_to_top_level (uses_template_parms (type));
|
||||||
pushclass (type, 0);
|
pushclass (type, 0);
|
||||||
|
@ -4598,7 +4609,7 @@ instantiate_class_template (type)
|
||||||
TYPE_METHODS (type) = TYPE_METHODS (pattern);
|
TYPE_METHODS (type) = TYPE_METHODS (pattern);
|
||||||
CLASSTYPE_TAGS (type) = CLASSTYPE_TAGS (pattern);
|
CLASSTYPE_TAGS (type) = CLASSTYPE_TAGS (pattern);
|
||||||
TYPE_SIZE (type) = integer_zero_node;
|
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;
|
TYPE_BEING_DEFINED (type) = 0;
|
||||||
repo_template_used (type);
|
repo_template_used (type);
|
||||||
|
|
||||||
end:
|
done_with_instantiation:
|
||||||
TYPE_BEING_DEFINED (type) = 0;
|
TYPE_BEING_DEFINED (type) = 0;
|
||||||
popclass (0);
|
popclass (0);
|
||||||
|
|
||||||
pop_from_top_level ();
|
pop_from_top_level ();
|
||||||
pop_tinst_level ();
|
pop_tinst_level ();
|
||||||
|
|
||||||
|
end:
|
||||||
|
pop_momentary ();
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4921,7 +4935,7 @@ tsubst_template_arg_vector (t, args)
|
||||||
if (!need_new)
|
if (!need_new)
|
||||||
return t;
|
return t;
|
||||||
|
|
||||||
t = make_tree_vec (len);
|
t = make_temp_vec (len);
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
TREE_VEC_ELT (t, i) = elts[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>,
|
and supposing that we are instantiating f<int, double>,
|
||||||
then our ARGS will be {int, double}, but, when looking up
|
then our ARGS will be {int, double}, but, when looking up
|
||||||
S we only want {double}. */
|
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,
|
r = lookup_template_class (t, argvec, in_decl, context,
|
||||||
entering_scope);
|
entering_scope);
|
||||||
|
pop_momentary ();
|
||||||
|
|
||||||
return cp_build_qualified_type (r, TYPE_QUALS (t));
|
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)
|
tree tmpl_args = DECL_CLASS_TEMPLATE_P (t)
|
||||||
? CLASSTYPE_TI_ARGS (TREE_TYPE (t))
|
? CLASSTYPE_TI_ARGS (TREE_TYPE (t))
|
||||||
: DECL_TI_ARGS (DECL_RESULT (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
|
/* tsubst_template_arg_vector doesn't copy the vector if
|
||||||
nothing changed. But, *something* should have
|
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);
|
my_friendly_assert (full_args != tmpl_args, 0);
|
||||||
|
|
||||||
spec = retrieve_specialization (t, full_args);
|
spec = retrieve_specialization (t, full_args);
|
||||||
|
pop_momentary ();
|
||||||
if (spec != NULL_TREE)
|
if (spec != NULL_TREE)
|
||||||
{
|
{
|
||||||
r = spec;
|
r = spec;
|
||||||
|
@ -5234,21 +5254,34 @@ tsubst_decl (t, args, type, in_decl)
|
||||||
{
|
{
|
||||||
tree spec;
|
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
|
/* Calculate the most general template of which R is a
|
||||||
specialization, and the complete set of arguments used to
|
specialization, and the complete set of arguments used to
|
||||||
specialize R. */
|
specialize R. */
|
||||||
gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t));
|
gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t));
|
||||||
argvec = tsubst (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (gen_tmpl)),
|
argvec
|
||||||
args, in_decl);
|
= tsubst_template_arg_vector (DECL_TI_ARGS
|
||||||
|
(DECL_TEMPLATE_RESULT (gen_tmpl)),
|
||||||
|
args);
|
||||||
|
|
||||||
/* Check to see if we already have this specialization. */
|
/* Check to see if we already have this specialization. */
|
||||||
spec = retrieve_specialization (gen_tmpl, argvec);
|
spec = retrieve_specialization (gen_tmpl, argvec);
|
||||||
|
|
||||||
if (spec)
|
if (spec)
|
||||||
{
|
{
|
||||||
r = spec;
|
r = spec;
|
||||||
|
pop_momentary ();
|
||||||
break;
|
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:
|
/* Here, we deal with the peculiar case:
|
||||||
|
|
||||||
template <class T> struct S {
|
template <class T> struct S {
|
||||||
|
@ -5375,6 +5408,9 @@ tsubst_decl (t, args, type, in_decl)
|
||||||
case mentioned above where GEN_TMPL is NULL. */
|
case mentioned above where GEN_TMPL is NULL. */
|
||||||
if (gen_tmpl)
|
if (gen_tmpl)
|
||||||
{
|
{
|
||||||
|
/* The ARGVEC was built on the momentary obstack. Make it
|
||||||
|
permanent now. */
|
||||||
|
argvec = copy_to_permanent (argvec);
|
||||||
DECL_TEMPLATE_INFO (r)
|
DECL_TEMPLATE_INFO (r)
|
||||||
= perm_tree_cons (gen_tmpl, argvec, NULL_TREE);
|
= perm_tree_cons (gen_tmpl, argvec, NULL_TREE);
|
||||||
SET_DECL_IMPLICIT_INSTANTIATION (r);
|
SET_DECL_IMPLICIT_INSTANTIATION (r);
|
||||||
|
@ -5631,6 +5667,7 @@ tsubst (t, args, in_decl)
|
||||||
|
|
||||||
{
|
{
|
||||||
tree max = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
|
tree max = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
|
||||||
|
|
||||||
max = tsubst_expr (max, args, in_decl);
|
max = tsubst_expr (max, args, in_decl);
|
||||||
if (processing_template_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));
|
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);
|
return build_index_type (max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5696,11 +5735,11 @@ tsubst (t, args, in_decl)
|
||||||
}
|
}
|
||||||
else if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
|
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
|
/* We are processing a type constructed from
|
||||||
a template template parameter */
|
a template template parameter */
|
||||||
tree argvec = tsubst (CLASSTYPE_TI_ARGS (t),
|
tree argvec = tsubst (TYPE_TI_ARGS (t),
|
||||||
args, in_decl);
|
args, in_decl);
|
||||||
|
|
||||||
/* We can get a TEMPLATE_TEMPLATE_PARM here when
|
/* We can get a TEMPLATE_TEMPLATE_PARM here when
|
||||||
|
@ -5751,10 +5790,10 @@ tsubst (t, args, in_decl)
|
||||||
TYPE_REFERENCE_TO (r) = NULL_TREE;
|
TYPE_REFERENCE_TO (r) = NULL_TREE;
|
||||||
|
|
||||||
if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
|
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);
|
tree argvec = tsubst (TYPE_TI_ARGS (t), args, in_decl);
|
||||||
CLASSTYPE_TEMPLATE_INFO (r)
|
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
|
||||||
= perm_tree_cons (TYPE_NAME (t), argvec, NULL_TREE);
|
= perm_tree_cons (TYPE_NAME (t), argvec, NULL_TREE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -7348,7 +7387,7 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
|
||||||
|
|
||||||
if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM)
|
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
|
/* We arrive here when PARM does not involve template
|
||||||
specialization. */
|
specialization. */
|
||||||
|
@ -7358,8 +7397,8 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
{
|
{
|
||||||
tree parmtmpl = CLASSTYPE_TI_TEMPLATE (parm);
|
tree parmtmpl = TYPE_TI_TEMPLATE (parm);
|
||||||
tree parmvec = CLASSTYPE_TI_ARGS (parm);
|
tree parmvec = TYPE_TI_ARGS (parm);
|
||||||
tree argvec = CLASSTYPE_TI_ARGS (arg);
|
tree argvec = CLASSTYPE_TI_ARGS (arg);
|
||||||
tree argtmplvec
|
tree argtmplvec
|
||||||
= DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (arg));
|
= DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (arg));
|
||||||
|
@ -8170,7 +8209,7 @@ do_type_instantiation (t, storage)
|
||||||
if (TREE_CODE (t) == TYPE_DECL)
|
if (TREE_CODE (t) == TYPE_DECL)
|
||||||
t = TREE_TYPE (t);
|
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);
|
cp_error ("explicit instantiation of non-template type `%T'", t);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1281,7 +1281,8 @@ static int
|
||||||
lookup_fnfields_1 (type, name)
|
lookup_fnfields_1 (type, name)
|
||||||
tree 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)
|
if (method_vec != 0)
|
||||||
{
|
{
|
||||||
|
@ -3006,6 +3007,7 @@ dfs_pushdecls (binfo)
|
||||||
|
|
||||||
/* If the class value is not an envelope of the kind described in
|
/* If the class value is not an envelope of the kind described in
|
||||||
the comment above, we create a new envelope. */
|
the comment above, we create a new envelope. */
|
||||||
|
maybe_push_cache_obstack ();
|
||||||
if (class_value == NULL_TREE || TREE_CODE (class_value) != TREE_LIST
|
if (class_value == NULL_TREE || TREE_CODE (class_value) != TREE_LIST
|
||||||
|| TREE_PURPOSE (class_value) == NULL_TREE
|
|| TREE_PURPOSE (class_value) == NULL_TREE
|
||||||
|| TREE_CODE (TREE_PURPOSE (class_value)) == IDENTIFIER_NODE)
|
|| TREE_CODE (TREE_PURPOSE (class_value)) == IDENTIFIER_NODE)
|
||||||
|
@ -3018,10 +3020,11 @@ dfs_pushdecls (binfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
envelope_add_decl (type, fields, &TREE_PURPOSE (class_value));
|
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)
|
if (method_vec && ! dummy)
|
||||||
{
|
{
|
||||||
tree *methods;
|
tree *methods;
|
||||||
|
@ -3043,6 +3046,8 @@ dfs_pushdecls (binfo)
|
||||||
name = DECL_NAME (OVL_CURRENT (*methods));
|
name = DECL_NAME (OVL_CURRENT (*methods));
|
||||||
class_value = IDENTIFIER_CLASS_VALUE (name);
|
class_value = IDENTIFIER_CLASS_VALUE (name);
|
||||||
|
|
||||||
|
maybe_push_cache_obstack ();
|
||||||
|
|
||||||
/* If the class value is not an envelope of the kind described in
|
/* If the class value is not an envelope of the kind described in
|
||||||
the comment above, we create a new envelope. */
|
the comment above, we create a new envelope. */
|
||||||
if (class_value == NULL_TREE || TREE_CODE (class_value) != TREE_LIST
|
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.
|
/* Here we try to rule out possible ambiguities.
|
||||||
If we can't do that, keep a TREE_LIST with possibly ambiguous
|
If we can't do that, keep a TREE_LIST with possibly ambiguous
|
||||||
decls in there. */
|
decls in there. */
|
||||||
maybe_push_cache_obstack ();
|
|
||||||
/* Arbitrarily choose the first function in the list. This is OK
|
/* Arbitrarily choose the first function in the list. This is OK
|
||||||
because this is only used for initial lookup; anything that
|
because this is only used for initial lookup; anything that
|
||||||
actually uses the function will look it up again. */
|
actually uses the function will look it up again. */
|
||||||
|
@ -3081,7 +3085,8 @@ dfs_compress_decls (binfo)
|
||||||
tree binfo;
|
tree binfo;
|
||||||
{
|
{
|
||||||
tree type = BINFO_TYPE (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
|
if (processing_template_decl && type != current_class_type
|
||||||
&& dependent_base_p (binfo))
|
&& dependent_base_p (binfo))
|
||||||
|
@ -3131,6 +3136,11 @@ push_class_decls (type)
|
||||||
struct obstack *ambient_obstack = current_obstack;
|
struct obstack *ambient_obstack = current_obstack;
|
||||||
search_stack = push_search_level (search_stack, &search_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. */
|
/* Push class fields into CLASS_VALUE scope, and mark. */
|
||||||
dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarked_pushdecls_p);
|
dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarked_pushdecls_p);
|
||||||
|
|
||||||
|
@ -3198,6 +3208,10 @@ push_class_decls (type)
|
||||||
pushdecl_class_level (new);
|
pushdecl_class_level (new);
|
||||||
closed_envelopes = TREE_CHAIN (closed_envelopes);
|
closed_envelopes = TREE_CHAIN (closed_envelopes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Undo the call to maybe_push_cache_obstack above. */
|
||||||
|
pop_obstacks ();
|
||||||
|
|
||||||
current_obstack = ambient_obstack;
|
current_obstack = ambient_obstack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1616,7 +1616,6 @@ finish_typeof (expr)
|
||||||
end_temporary_allocation ();
|
end_temporary_allocation ();
|
||||||
|
|
||||||
t = make_lang_type (TYPEOF_TYPE);
|
t = make_lang_type (TYPEOF_TYPE);
|
||||||
CLASSTYPE_GOT_SEMICOLON (t) = 1;
|
|
||||||
TYPE_FIELDS (t) = expr;
|
TYPE_FIELDS (t) = expr;
|
||||||
|
|
||||||
pop_obstacks ();
|
pop_obstacks ();
|
||||||
|
|
|
@ -209,7 +209,7 @@ build_signature_pointer_or_reference_type (to_type, type_quals, refp)
|
||||||
TYPE_ALIGN (optr_type));
|
TYPE_ALIGN (optr_type));
|
||||||
|
|
||||||
/* A signature pointer/reference type isn't a `real' class 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
|
else
|
||||||
{
|
{
|
||||||
type = binfo;
|
type = binfo;
|
||||||
binfo = TYPE_BINFO (binfo);
|
binfo = CLASS_TYPE_P (type) ? TYPE_BINFO (binfo) : NULL_TREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
|
TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
|
||||||
|
@ -1506,7 +1506,8 @@ copy_template_template_parm (t)
|
||||||
|
|
||||||
/* No need to copy these */
|
/* No need to copy these */
|
||||||
TYPE_FIELDS (t2) = TYPE_FIELDS (t);
|
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;
|
return t2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2490,17 +2491,17 @@ cp_tree_equal (t1, t2)
|
||||||
return -1;
|
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
|
tree
|
||||||
make_temp_vec (len)
|
make_temp_vec (len)
|
||||||
int len;
|
int len;
|
||||||
{
|
{
|
||||||
register tree node;
|
register tree node;
|
||||||
register struct obstack *ambient_obstack = current_obstack;
|
push_expression_obstack ();
|
||||||
current_obstack = expression_obstack;
|
|
||||||
node = make_tree_vec (len);
|
node = make_tree_vec (len);
|
||||||
current_obstack = ambient_obstack;
|
pop_obstacks ();
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ complete_type (type)
|
||||||
TYPE_NEEDS_DESTRUCTOR (type)
|
TYPE_NEEDS_DESTRUCTOR (type)
|
||||||
= TYPE_NEEDS_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
|
= 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));
|
instantiate_class_template (TYPE_MAIN_VARIANT (type));
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
|
@ -773,7 +773,8 @@ comptypes (type1, type2, strict)
|
||||||
if (! comp_template_parms (DECL_TEMPLATE_PARMS (TYPE_NAME (t1)),
|
if (! comp_template_parms (DECL_TEMPLATE_PARMS (TYPE_NAME (t1)),
|
||||||
DECL_TEMPLATE_PARMS (TYPE_NAME (t2))))
|
DECL_TEMPLATE_PARMS (TYPE_NAME (t2))))
|
||||||
return 0;
|
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;
|
return 1;
|
||||||
/* Don't check inheritance. */
|
/* Don't check inheritance. */
|
||||||
strict = COMPARE_STRICT;
|
strict = COMPARE_STRICT;
|
||||||
|
@ -781,11 +782,11 @@ comptypes (type1, type2, strict)
|
||||||
|
|
||||||
case RECORD_TYPE:
|
case RECORD_TYPE:
|
||||||
case UNION_TYPE:
|
case UNION_TYPE:
|
||||||
if (CLASSTYPE_TEMPLATE_INFO (t1) && CLASSTYPE_TEMPLATE_INFO (t2)
|
if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
|
||||||
&& (CLASSTYPE_TI_TEMPLATE (t1) == CLASSTYPE_TI_TEMPLATE (t2)
|
&& (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
|
||||||
|| TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM))
|
|| TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM))
|
||||||
val = comp_template_args (CLASSTYPE_TI_ARGS (t1),
|
val = comp_template_args (TYPE_TI_ARGS (t1),
|
||||||
CLASSTYPE_TI_ARGS (t2));
|
TYPE_TI_ARGS (t2));
|
||||||
look_hard:
|
look_hard:
|
||||||
if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
|
if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue