summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/pt.c')
-rw-r--r--contrib/gcc/cp/pt.c1222
1 files changed, 776 insertions, 446 deletions
diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c
index b751ad4..22f93bf 100644
--- a/contrib/gcc/cp/pt.c
+++ b/contrib/gcc/cp/pt.c
@@ -47,35 +47,32 @@ Boston, MA 02111-1307, USA. */
returning an int. */
typedef int (*tree_fn_t) PARAMS ((tree, void*));
-extern struct obstack permanent_obstack;
-
/* The PENDING_TEMPLATES is a TREE_LIST of templates whose
instantiations have been deferred, either because their definitions
were not yet available, or because we were putting off doing the
work. The TREE_PURPOSE of each entry is a SRCLOC indicating where
- the instantiate request occurred; the TREE_VALUE is a either a DECL
+ the instantiate request occurred; the TREE_VALUE is either a DECL
(for a function or static data member), or a TYPE (for a class)
indicating what we are hoping to instantiate. */
-static tree pending_templates;
+static GTY(()) tree pending_templates;
static tree last_pending_template;
int processing_template_parmlist;
static int template_header_count;
-static tree saved_trees;
-static varray_type inline_parm_levels;
+static GTY(()) tree saved_trees;
+static GTY(()) varray_type inline_parm_levels;
static size_t inline_parm_levels_used;
-static tree current_tinst_level;
+static GTY(()) tree current_tinst_level;
+
+static GTY(()) tree saved_access_scope;
/* A map from local variable declarations in the body of the template
presently being instantiated to the corresponding instantiated
local variables. */
static htab_t local_specializations;
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-
#define UNIFY_ALLOW_NONE 0
#define UNIFY_ALLOW_MORE_CV_QUAL 1
#define UNIFY_ALLOW_LESS_CV_QUAL 2
@@ -92,6 +89,9 @@ static htab_t local_specializations;
#define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current
type with the desired type. */
+static void push_access_scope_real PARAMS ((tree, tree, tree));
+static void push_access_scope PARAMS ((tree));
+static void pop_access_scope PARAMS ((tree));
static int resolve_overloaded_unification PARAMS ((tree, tree, tree, tree,
unification_kind_t, int));
static int try_one_overload PARAMS ((tree, tree, tree, tree, tree,
@@ -120,7 +120,7 @@ static tree convert_nontype_argument PARAMS ((tree, tree));
static tree convert_template_argument PARAMS ((tree, tree, tree,
tsubst_flags_t, int, tree));
static tree get_bindings_overload PARAMS ((tree, tree, tree));
-static int for_each_template_parm PARAMS ((tree, tree_fn_t, void*));
+static int for_each_template_parm PARAMS ((tree, tree_fn_t, void*, htab_t));
static tree build_template_parm_index PARAMS ((int, int, int, tree, tree));
static int inline_needs_template_parms PARAMS ((tree));
static void push_inline_template_parms_recursive PARAMS ((tree, int));
@@ -132,6 +132,7 @@ static int unregister_specialization PARAMS ((tree, tree));
static tree reduce_template_parm_level PARAMS ((tree, tree, int));
static tree build_template_decl PARAMS ((tree, tree));
static int mark_template_parm PARAMS ((tree, void *));
+static int template_parm_this_level_p PARAMS ((tree, void *));
static tree tsubst_friend_function PARAMS ((tree, tree));
static tree tsubst_friend_class PARAMS ((tree, tree));
static int can_complete_type_without_circularity PARAMS ((tree));
@@ -170,14 +171,85 @@ static tree copy_default_args_to_explicit_spec_1 PARAMS ((tree, tree));
static void copy_default_args_to_explicit_spec PARAMS ((tree));
static int invalid_nontype_parm_type_p PARAMS ((tree, tsubst_flags_t));
-/* Called once to initialize pt.c. */
+/* Make the current scope suitable for access checking when we are
+ processing T. T can be FUNCTION_DECL for instantiated function
+ template, TEMPLATE_DECL for uninstantiated one, or VAR_DECL for
+ static member variable (need by instantiate_decl). ARGS is the
+ template argument for TEMPLATE_DECL. If CONTEXT is not NULL_TREE,
+ this is used instead of the context of T. */
+
+void
+push_access_scope_real (t, args, context)
+ tree t, args, context;
+{
+ if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t))
+ {
+ /* When we are processing specialization `foo<Outer>' for code like
+
+ template <class U> typename U::Inner foo ();
+ class Outer {
+ struct Inner {};
+ friend Outer::Inner foo<Outer> ();
+ };
+
+ `T' is a TEMPLATE_DECL, but `Outer' is only a friend of one of
+ its specialization. We can get the FUNCTION_DECL with the right
+ information because this specialization has already been
+ registered by the friend declaration above. */
+
+ if (DECL_FUNCTION_TEMPLATE_P (t) && args)
+ {
+ tree full_args = tsubst_template_arg_vector
+ (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t)), args, tf_none);
+ tree spec = NULL_TREE;
+ if (full_args != error_mark_node)
+ spec = retrieve_specialization (t, full_args);
+ if (spec)
+ t = spec;
+ }
+ }
+
+ if (!context)
+ context = DECL_CONTEXT (t);
+ if (context && TYPE_P (context))
+ push_nested_class (context, 2);
+ else
+ push_to_top_level ();
+
+ if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t))
+ {
+ saved_access_scope = tree_cons
+ (NULL_TREE, current_function_decl, saved_access_scope);
+ current_function_decl = t;
+ }
+}
+
+/* Like push_access_scope_real, but always uses DECL_CONTEXT. */
+
+void
+push_access_scope (t)
+ tree t;
+{
+ push_access_scope_real (t, NULL_TREE, NULL_TREE);
+}
+
+/* Restore the scope set up by push_access_scope. T is the node we
+ are processing. */
void
-init_pt ()
+pop_access_scope (t)
+ tree t;
{
- ggc_add_tree_root (&pending_templates, 1);
- ggc_add_tree_root (&saved_trees, 1);
- ggc_add_tree_root (&current_tinst_level, 1);
+ if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t))
+ {
+ current_function_decl = TREE_VALUE (saved_access_scope);
+ saved_access_scope = TREE_CHAIN (saved_access_scope);
+ }
+
+ if (DECL_CLASS_SCOPE_P (t))
+ pop_nested_class ();
+ else
+ pop_from_top_level ();
}
/* Do any processing required when DECL (a member template declaration
@@ -395,7 +467,7 @@ maybe_begin_member_template_processing (decl)
++inline_parm_levels_used;
}
-/* Undo the effects of begin_member_template_processing. */
+/* Undo the effects of begin_member_template_processing. */
void
maybe_end_member_template_processing ()
@@ -416,7 +488,7 @@ maybe_end_member_template_processing ()
}
}
-/* Returns non-zero iff T is a member template function. We must be
+/* Returns nonzero iff T is a member template function. We must be
careful as in
template <class T> class C { void f(); }
@@ -453,7 +525,7 @@ is_member_template (t)
}
#if 0 /* UNUSED */
-/* Returns non-zero iff T is a member template class. See
+/* Returns nonzero iff T is a member template class. See
is_member_template for a description of what precisely constitutes
a member template. */
@@ -599,7 +671,7 @@ begin_template_parm_list ()
}
/* This routine is called when a specialization is declared. If it is
- illegal to declare a specialization here, an error is reported. */
+ invalid to declare a specialization here, an error is reported. */
static void
check_specialization_scope ()
@@ -631,7 +703,7 @@ check_specialization_scope ()
error ("enclosing class templates are not explicitly specialized");
}
-/* We've just seen template <>. */
+/* We've just seen template <>. */
void
begin_specialization ()
@@ -652,7 +724,7 @@ end_specialization ()
}
/* Any template <>'s that we have seen thus far are not referring to a
- function specialization. */
+ function specialization. */
void
reset_specialization ()
@@ -661,7 +733,7 @@ reset_specialization ()
template_header_count = 0;
}
-/* We've just seen a template header. If SPECIALIZATION is non-zero,
+/* We've just seen a template header. If SPECIALIZATION is nonzero,
it was of the form template <>. */
static void
@@ -695,8 +767,22 @@ void
maybe_process_partial_specialization (type)
tree type;
{
- if (IS_AGGR_TYPE (type) && CLASSTYPE_USE_TEMPLATE (type))
+ /* TYPE maybe an ERROR_MARK_NODE. */
+ tree context = TYPE_P (type) ? TYPE_CONTEXT (type) : NULL_TREE;
+
+ if (CLASS_TYPE_P (type) && CLASSTYPE_USE_TEMPLATE (type))
{
+ /* This is for ordinary explicit specialization and partial
+ specialization of a template class such as:
+
+ template <> class C<int>;
+
+ or:
+
+ template <class T> class C<T*>;
+
+ Make sure that `C<int>' and `C<T*>' are implicit instantiations. */
+
if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
&& !COMPLETE_TYPE_P (type))
{
@@ -714,6 +800,62 @@ maybe_process_partial_specialization (type)
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
error ("specialization of `%T' after instantiation", type);
}
+ else if (CLASS_TYPE_P (type)
+ && !CLASSTYPE_USE_TEMPLATE (type)
+ && CLASSTYPE_TEMPLATE_INFO (type)
+ && context && CLASS_TYPE_P (context)
+ && CLASSTYPE_TEMPLATE_INFO (context))
+ {
+ /* This is for an explicit specialization of member class
+ template according to [temp.expl.spec/18]:
+
+ template <> template <class U> class C<int>::D;
+
+ The context `C<int>' must be an implicit instantiation.
+ Otherwise this is just a member class template declared
+ earlier like:
+
+ template <> class C<int> { template <class U> class D; };
+ template <> template <class U> class C<int>::D;
+
+ In the first case, `C<int>::D' is a specialization of `C<T>::D'
+ while in the second case, `C<int>::D' is a primary template
+ and `C<T>::D' may not exist. */
+
+ if (CLASSTYPE_IMPLICIT_INSTANTIATION (context)
+ && !COMPLETE_TYPE_P (type))
+ {
+ tree t;
+
+ if (current_namespace
+ != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
+ {
+ pedwarn ("specializing `%#T' in different namespace", type);
+ cp_pedwarn_at (" from definition of `%#D'",
+ CLASSTYPE_TI_TEMPLATE (type));
+ }
+
+ /* Check for invalid specialization after instantiation:
+
+ template <> template <> class C<int>::D<int>;
+ template <> template <class U> class C<int>::D; */
+
+ for (t = DECL_TEMPLATE_INSTANTIATIONS
+ (most_general_template (CLASSTYPE_TI_TEMPLATE (type)));
+ t; t = TREE_CHAIN (t))
+ if (TREE_VALUE (t) != type
+ && TYPE_CONTEXT (TREE_VALUE (t)) == context)
+ error ("specialization `%T' after instantiation `%T'",
+ type, TREE_VALUE (t));
+
+ /* Mark TYPE as a specialization. And as a result, we only
+ have one level of template argument for the innermost
+ class template. */
+ SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type);
+ CLASSTYPE_TI_ARGS (type)
+ = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
+ }
+ }
else if (processing_specialization)
error ("explicit specialization of non-template `%T'", type);
}
@@ -758,7 +900,7 @@ retrieve_local_specialization (tmpl)
return (tree) htab_find (local_specializations, tmpl);
}
-/* Returns non-zero iff DECL is a specialization of TMPL. */
+/* Returns nonzero iff DECL is a specialization of TMPL. */
int
is_specialization_of (decl, tmpl)
@@ -961,7 +1103,7 @@ print_candidates (fns)
NULL_TREE if none is available. In that case, the functions in
TEMPLATE_ID are non-members.
- If NEED_MEMBER_TEMPLATE is non-zero the function is known to be a
+ If NEED_MEMBER_TEMPLATE is nonzero the function is known to be a
specialization of a member template.
The template args (those explicitly specified and those deduced)
@@ -995,9 +1137,9 @@ determine_specialization (template_id, decl, targs_out,
if (fns == error_mark_node)
return error_mark_node;
- /* Check for baselinks. */
+ /* Check for baselinks. */
if (BASELINK_P (fns))
- fns = TREE_VALUE (fns);
+ fns = BASELINK_FUNCTIONS (fns);
if (!is_overloaded_fn (fns))
{
@@ -1007,28 +1149,58 @@ determine_specialization (template_id, decl, targs_out,
for (; fns; fns = OVL_NEXT (fns))
{
- tree tmpl;
-
tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL)
- /* DECL might be a specialization of FN. */
- tmpl = fn;
+ {
+ tree decl_arg_types;
+
+ /* DECL might be a specialization of FN. */
+
+ /* Adjust the type of DECL in case FN is a static member. */
+ decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ if (DECL_STATIC_FUNCTION_P (fn)
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ decl_arg_types = TREE_CHAIN (decl_arg_types);
+
+ /* Check that the number of function parameters matches.
+ For example,
+ template <class T> void f(int i = 0);
+ template <> void f<int>();
+ The specialization f<int> is invalid but is not caught
+ by get_bindings below. */
+
+ if (list_length (TYPE_ARG_TYPES (TREE_TYPE (fn)))
+ != list_length (decl_arg_types))
+ continue;
+
+ /* See whether this function might be a specialization of this
+ template. */
+ targs = get_bindings (fn, decl, explicit_targs);
+
+ if (!targs)
+ /* We cannot deduce template arguments that when used to
+ specialize TMPL will produce DECL. */
+ continue;
+
+ /* Save this template, and the arguments deduced. */
+ templates = tree_cons (targs, fn, templates);
+ }
else if (need_member_template)
/* FN is an ordinary member function, and we need a
specialization of a member template. */
- continue;
+ ;
else if (TREE_CODE (fn) != FUNCTION_DECL)
/* We can get IDENTIFIER_NODEs here in certain erroneous
cases. */
- continue;
+ ;
else if (!DECL_FUNCTION_MEMBER_P (fn))
/* This is just an ordinary non-member function. Nothing can
be a specialization of that. */
- continue;
+ ;
else if (DECL_ARTIFICIAL (fn))
/* Cannot specialize functions that are created implicitly. */
- continue;
+ ;
else
{
tree decl_arg_types;
@@ -1064,21 +1236,7 @@ determine_specialization (template_id, decl, targs_out,
decl_arg_types))
/* They match! */
candidates = tree_cons (NULL_TREE, fn, candidates);
-
- continue;
}
-
- /* See whether this function might be a specialization of this
- template. */
- targs = get_bindings (tmpl, decl, explicit_targs);
-
- if (!targs)
- /* We cannot deduce template arguments that when used to
- specialize TMPL will produce DECL. */
- continue;
-
- /* Save this template, and the arguments deduced. */
- templates = tree_cons (targs, tmpl, templates);
}
if (templates && TREE_CHAIN (templates))
@@ -1108,7 +1266,7 @@ determine_specialization (template_id, decl, targs_out,
template.
So, we do use the partial ordering rules, at least for now.
- This extension can only serve to make illegal programs legal,
+ This extension can only serve to make invalid programs valid,
so it's safe. And, there is strong anecdotal evidence that
the committee intended the partial ordering rules to apply;
the EDG front-end has that behavior, and John Spicer claims
@@ -1139,7 +1297,7 @@ determine_specialization (template_id, decl, targs_out,
return error_mark_node;
}
- /* We have one, and exactly one, match. */
+ /* We have one, and exactly one, match. */
if (candidates)
{
/* It was a specialization of an ordinary member function in a
@@ -1313,7 +1471,7 @@ copy_default_args_to_explicit_spec (decl)
template <> void S<int>::f();
the TEMPLATE_COUNT would be 0. (Note that this declaration is
- illegal; there should be no template <>.)
+ invalid; there should be no template <>.)
If the function is a specialization, it is marked as such via
DECL_TEMPLATE_SPECIALIZATION. Furthermore, its DECL_TEMPLATE_INFO
@@ -1414,7 +1572,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
template <class T> struct S { void f(); };
void S<int>::f() {} // Missing template <>
- That used to be legal C++. */
+ That used to be valid C++. */
if (pedantic)
pedwarn
("explicit specialization not preceded by `template <>'");
@@ -1496,13 +1654,13 @@ check_explicit_specialization (declarator, decl, template_count, flags)
if (ctype != NULL_TREE && TYPE_BEING_DEFINED (ctype))
{
if (!explicit_instantiation)
- /* A specialization in class scope. This is illegal,
+ /* A specialization in class scope. This is invalid,
but the error will already have been flagged by
check_specialization_scope. */
return error_mark_node;
else
{
- /* It's not legal to write an explicit instantiation in
+ /* It's not valid to write an explicit instantiation in
class scope, e.g.:
class C { template void f(); }
@@ -1512,7 +1670,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
template class C { void f(); };
- (which is illegal) we can get here. The error will be
+ (which is invalid) we can get here. The error will be
issued later. */
;
}
@@ -1538,8 +1696,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
tree fns = NULL_TREE;
int idx;
- if (name == constructor_name (ctype)
- || name == constructor_name_full (ctype))
+ if (constructor_name_p (name, ctype))
{
int is_constructor = DECL_CONSTRUCTOR_P (decl);
@@ -1580,7 +1737,8 @@ check_explicit_specialization (declarator, decl, template_count, flags)
methods = CLASSTYPE_METHOD_VEC (ctype);
if (methods)
- for (idx = 2; idx < TREE_VEC_LENGTH (methods); ++idx)
+ for (idx = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ idx < TREE_VEC_LENGTH (methods); ++idx)
{
tree ovl = TREE_VEC_ELT (methods, idx);
@@ -1653,6 +1811,18 @@ check_explicit_specialization (declarator, decl, template_count, flags)
return instantiate_template (tmpl, targs);
}
+ /* If we thought that the DECL was a member function, but it
+ turns out to be specializing a static member function,
+ make DECL a static member function as well. We also have
+ to adjust last_function_parms to avoid confusing
+ start_function later. */
+ if (DECL_STATIC_FUNCTION_P (tmpl)
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ {
+ revert_static_member_fn (decl);
+ last_function_parms = TREE_CHAIN (last_function_parms);
+ }
+
/* If this is a specialization of a member template of a
template class. In we want to return the TEMPLATE_DECL,
not the specialization of it. */
@@ -1663,16 +1833,6 @@ check_explicit_specialization (declarator, decl, template_count, flags)
return tmpl;
}
- /* If we thought that the DECL was a member function, but it
- turns out to be specializing a static member function,
- make DECL a static member function as well. */
- if (DECL_STATIC_FUNCTION_P (tmpl)
- && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
- {
- revert_static_member_fn (decl);
- last_function_parms = TREE_CHAIN (last_function_parms);
- }
-
/* Set up the DECL_TEMPLATE_INFO for DECL. */
DECL_TEMPLATE_INFO (decl) = tree_cons (tmpl, targs, NULL_TREE);
@@ -1732,7 +1892,7 @@ maybe_check_template_type (type)
struct I {};
};
- is illegal, but:
+ is invalid, but:
template <class T> struct S {
template <class U> struct I;
@@ -2104,10 +2264,9 @@ build_template_decl (decl, parms)
DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
if (DECL_LANG_SPECIFIC (decl))
{
- if (CAN_HAVE_FULL_LANG_DECL_P (decl))
- DECL_VIRTUAL_CONTEXT (tmpl) = DECL_VIRTUAL_CONTEXT (decl);
DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl);
DECL_CONSTRUCTOR_P (tmpl) = DECL_CONSTRUCTOR_P (decl);
+ DECL_DESTRUCTOR_P (tmpl) = DECL_DESTRUCTOR_P (decl);
DECL_NONCONVERTING_P (tmpl) = DECL_NONCONVERTING_P (decl);
DECL_ASSIGNMENT_OPERATOR_P (tmpl) = DECL_ASSIGNMENT_OPERATOR_P (decl);
if (DECL_OVERLOADED_OPERATOR_P (decl))
@@ -2129,12 +2288,12 @@ struct template_parm_data
int current_arg;
/* An array whose size is the number of template parameters. The
- elements are non-zero if the parameter has been used in any one
+ elements are nonzero if the parameter has been used in any one
of the arguments processed so far. */
int* parms;
/* An array whose size is the number of template arguments. The
- elements are non-zero if the argument makes use of template
+ elements are nonzero if the argument makes use of template
parameters of this level. */
int* arg_uses_template_parms;
};
@@ -2218,7 +2377,7 @@ process_partial_specialization (decl)
struct S2<T>;
};
- The S2<T> declaration is actually illegal; it is a
+ The S2<T> declaration is actually invalid; it is a
full-specialization. Of course,
template <class U>
@@ -2236,7 +2395,8 @@ process_partial_specialization (decl)
tpd.current_arg = i;
for_each_template_parm (TREE_VEC_ELT (inner_args, i),
&mark_template_parm,
- &tpd);
+ &tpd,
+ NULL);
}
for (i = 0; i < ntparms; ++i)
if (tpd.parms[i] == 0)
@@ -2317,7 +2477,8 @@ process_partial_specialization (decl)
memset ((PTR) tpd2.parms, 0, sizeof (int) * nargs);
for_each_template_parm (type,
&mark_template_parm,
- &tpd2);
+ &tpd2,
+ NULL);
if (tpd2.arg_uses_template_parms [i])
{
@@ -2352,8 +2513,8 @@ process_partial_specialization (decl)
/* Check that a template declaration's use of default arguments is not
invalid. Here, PARMS are the template parameters. IS_PRIMARY is
- non-zero if DECL is the thing declared by a primary template.
- IS_PARTIAL is non-zero if DECL is a partial specialization. */
+ nonzero if DECL is the thing declared by a primary template.
+ IS_PARTIAL is nonzero if DECL is a partial specialization. */
static void
check_default_tmpl_args (decl, parms, is_primary, is_partial)
@@ -2457,7 +2618,7 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
/* If we're inside a class definition, there's no need to
examine the parameters to the class itself. On the one
hand, they will be checked when the class is defined, and,
- on the other, default arguments are legal in things like:
+ on the other, default arguments are valid in things like:
template <class T = double>
struct S { template <class U> void f(U); };
Here the default argument for `S' has no bearing on the
@@ -2497,12 +2658,32 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
}
}
+/* Worker for push_template_decl_real, called via
+ for_each_template_parm. DATA is really an int, indicating the
+ level of the parameters we are interested in. If T is a template
+ parameter of that level, return nonzero. */
+
+static int
+template_parm_this_level_p (t, data)
+ tree t;
+ void *data;
+{
+ int this_level = *(int *)data;
+ int level;
+
+ if (TREE_CODE (t) == TEMPLATE_PARM_INDEX)
+ level = TEMPLATE_PARM_LEVEL (t);
+ else
+ level = TEMPLATE_TYPE_LEVEL (t);
+ return level == this_level;
+}
+
/* Creates a TEMPLATE_DECL for the indicated DECL using the template
parameters given by current_template_args, or reuses a
previously existing one, if appropriate. Returns the DECL, or an
equivalent one, if it is replaced via a call to duplicate_decls.
- If IS_FRIEND is non-zero, DECL is a friend declaration. */
+ If IS_FRIEND is nonzero, DECL is a friend declaration. */
tree
push_template_decl_real (decl, is_friend)
@@ -2593,7 +2774,7 @@ push_template_decl_real (decl, is_friend)
{
/* Since a template declaration already existed for this
class-type, we must be redeclaring it here. Make sure
- that the redeclaration is legal. */
+ that the redeclaration is valid. */
redeclare_class_template (TREE_TYPE (decl),
current_template_parms);
/* We don't need to create a new TEMPLATE_DECL; just use the
@@ -2609,7 +2790,7 @@ push_template_decl_real (decl, is_friend)
&& DECL_TEMPLATE_SPECIALIZATION (decl))
{
/* A specialization of a member template of a template
- class. */
+ class. */
SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
DECL_TEMPLATE_INFO (tmpl) = DECL_TEMPLATE_INFO (decl);
DECL_TEMPLATE_INFO (decl) = NULL_TREE;
@@ -2719,7 +2900,22 @@ push_template_decl_real (decl, is_friend)
tmpl = pushdecl_namespace_level (tmpl);
if (primary)
- DECL_PRIMARY_TEMPLATE (tmpl) = tmpl;
+ {
+ DECL_PRIMARY_TEMPLATE (tmpl) = tmpl;
+ if (DECL_CONV_FN_P (tmpl))
+ {
+ int depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl));
+
+ /* It is a conversion operator. See if the type converted to
+ depends on innermost template operands. */
+
+ if (for_each_template_parm (TREE_TYPE (TREE_TYPE (tmpl)),
+ template_parm_this_level_p,
+ &depth,
+ NULL))
+ DECL_TEMPLATE_CONV_FN_P (tmpl) = 1;
+ }
+ }
info = tree_cons (tmpl, args, NULL_TREE);
@@ -2962,7 +3158,7 @@ convert_nontype_argument (type, expr)
case ENUMERAL_TYPE:
/* For a non-type template-parameter of integral or enumeration
type, integral promotions (_conv.prom_) and integral
- conversions (_conv.integral_) are applied. */
+ conversions (_conv.integral_) are applied. */
if (!INTEGRAL_TYPE_P (expr_type))
return error_mark_node;
@@ -3120,7 +3316,7 @@ convert_nontype_argument (type, expr)
return error_mark_node;
}
- mark_addressable (expr);
+ cxx_mark_addressable (expr);
return build1 (ADDR_EXPR, type, expr);
}
break;
@@ -3287,7 +3483,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
{
/* The template argument was the name of some
member function. That's usually
- illegal, but static members are OK. In any
+ invalid, but static members are OK. In any
case, grab the underlying fields/functions
and issue an error later if required. */
arg = TREE_VALUE (arg);
@@ -3458,7 +3654,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
extension, since deciding whether or not these
conversions can occur is part of determining which
function template to call, or whether a given explicit
- argument specification is legal. */
+ argument specification is valid. */
val = convert_nontype_argument (t, arg);
else
val = arg;
@@ -3480,7 +3676,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
messages are issued even if COMPLAIN is zero; for instance, if a
template argument is composed from a local class.
- If REQUIRE_ALL_ARGUMENTS is non-zero, all arguments must be
+ If REQUIRE_ALL_ARGUMENTS is nonzero, all arguments must be
provided in ARGLIST, or else trailing parameters must have default
values. If REQUIRE_ALL_ARGUMENTS is zero, we will attempt argument
deduction for any unspecified trailing arguments. */
@@ -3781,9 +3977,9 @@ add_pending_template (d)
}
-/* Return a TEMPLATE_ID_EXPR corresponding to the indicated FNS (which
- may be either a _DECL or an overloaded function or an
- IDENTIFIER_NODE), and ARGLIST. */
+/* Return a TEMPLATE_ID_EXPR corresponding to the indicated FNS and
+ ARGLIST. Valid choices for FNS are given in the cp-tree.def
+ documentation for TEMPLATE_ID_EXPR. */
tree
lookup_template_function (fns, arglist)
@@ -3791,20 +3987,36 @@ lookup_template_function (fns, arglist)
{
tree type;
+ if (fns == error_mark_node || arglist == error_mark_node)
+ return error_mark_node;
+
if (fns == NULL_TREE)
{
error ("non-template used as template");
return error_mark_node;
}
+ my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL
+ || TREE_CODE (fns) == OVERLOAD
+ || BASELINK_P (fns)
+ || TREE_CODE (fns) == IDENTIFIER_NODE
+ || TREE_CODE (fns) == LOOKUP_EXPR,
+ 20020730);
+
+ if (BASELINK_P (fns))
+ {
+ BASELINK_FUNCTIONS (fns) = build (TEMPLATE_ID_EXPR,
+ unknown_type_node,
+ BASELINK_FUNCTIONS (fns),
+ arglist);
+ return fns;
+ }
+
type = TREE_TYPE (fns);
if (TREE_CODE (fns) == OVERLOAD || !type)
type = unknown_type_node;
-
- if (processing_template_decl)
- return build_min (TEMPLATE_ID_EXPR, type, fns, arglist);
- else
- return build (TEMPLATE_ID_EXPR, type, fns, arglist);
+
+ return build (TEMPLATE_ID_EXPR, type, fns, arglist);
}
/* Within the scope of a template class S<T>, the name S gets bound
@@ -3837,7 +4049,7 @@ maybe_get_template_decl_from_type_decl (decl)
IN_DECL, if non-NULL, is the template declaration we are trying to
instantiate.
- If ENTERING_SCOPE is non-zero, we are about to enter the scope of
+ If ENTERING_SCOPE is nonzero, we are about to enter the scope of
the class we are looking up.
Issue error and warning messages under control of COMPLAIN.
@@ -3857,6 +4069,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
tree template = NULL_TREE, parmlist;
tree t;
+ timevar_push (TV_NAME_LOOKUP);
if (TREE_CODE (d1) == IDENTIFIER_NODE)
{
if (IDENTIFIER_VALUE (d1)
@@ -3912,7 +4125,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
{
if (complain & tf_error)
error ("`%T' is not a template", d1);
- return error_mark_node;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
if (TREE_CODE (template) != TEMPLATE_DECL
@@ -3928,7 +4141,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
if (in_decl)
cp_error_at ("for template declaration `%D'", in_decl);
}
- return error_mark_node;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
if (DECL_TEMPLATE_TEMPLATE_PARM_P (template))
@@ -3963,10 +4176,10 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
arglist2 = coerce_template_parms (parmlist, arglist, template,
complain, /*require_all_args=*/1);
if (arglist2 == error_mark_node)
- return error_mark_node;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
parm = bind_template_template_parm (TREE_TYPE (template), arglist2);
- return parm;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, parm);
}
else
{
@@ -4053,7 +4266,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
if (arglist == error_mark_node)
/* We were unable to bind the arguments. */
- return error_mark_node;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
/* In the scope of a template class, explicit references to the
template class refer to the type of the template, not any
@@ -4090,7 +4303,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
}
}
if (found)
- return found;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
for (tp = &DECL_TEMPLATE_INSTANTIATIONS (template);
*tp;
@@ -4106,7 +4319,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
= DECL_TEMPLATE_INSTANTIATIONS (template);
DECL_TEMPLATE_INSTANTIATIONS (template) = found;
- return TREE_VALUE (found);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_VALUE (found));
}
/* This type is a "partial instantiation" if any of the template
@@ -4122,7 +4335,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
found = xref_tag_from_type (TREE_TYPE (template),
DECL_NAME (template),
/*globalize=*/1);
- return found;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
}
context = tsubst (DECL_CONTEXT (template), arglist,
@@ -4168,14 +4381,17 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
type_decl = create_implicit_typedef (DECL_NAME (template), t);
DECL_CONTEXT (type_decl) = TYPE_CONTEXT (t);
TYPE_STUB_DECL (t) = type_decl;
- DECL_SOURCE_FILE (type_decl)
- = DECL_SOURCE_FILE (TYPE_STUB_DECL (template_type));
- DECL_SOURCE_LINE (type_decl)
- = DECL_SOURCE_LINE (TYPE_STUB_DECL (template_type));
+ DECL_SOURCE_LOCATION (type_decl)
+ = DECL_SOURCE_LOCATION (TYPE_STUB_DECL (template_type));
}
else
type_decl = TYPE_NAME (t);
+ TREE_PRIVATE (type_decl)
+ = TREE_PRIVATE (TYPE_STUB_DECL (template_type));
+ TREE_PROTECTED (type_decl)
+ = TREE_PROTECTED (TYPE_STUB_DECL (template_type));
+
/* Set up the template information. We have to figure out which
template is the immediate parent if this is a full
instantiation. */
@@ -4275,14 +4491,16 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
code that generates debugging information will crash. */
DECL_IGNORED_P (TYPE_STUB_DECL (t)) = 1;
- return t;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
+ timevar_pop (TV_NAME_LOOKUP);
}
struct pair_fn_data
{
tree_fn_t fn;
void *data;
+ htab_t visited;
};
/* Called from for_each_template_parm via walk_tree. */
@@ -4297,9 +4515,20 @@ for_each_template_parm_r (tp, walk_subtrees, d)
struct pair_fn_data *pfd = (struct pair_fn_data *) d;
tree_fn_t fn = pfd->fn;
void *data = pfd->data;
-
+ void **slot;
+
+ /* If we have already visited this tree, there's no need to walk
+ subtrees. Otherwise, add it to the visited table. */
+ slot = htab_find_slot (pfd->visited, *tp, INSERT);
+ if (*slot)
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+ *slot = *tp;
+
if (TYPE_P (t)
- && for_each_template_parm (TYPE_CONTEXT (t), fn, data))
+ && for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited))
return error_mark_node;
switch (TREE_CODE (t))
@@ -4314,20 +4543,21 @@ for_each_template_parm_r (tp, walk_subtrees, d)
if (!TYPE_TEMPLATE_INFO (t))
*walk_subtrees = 0;
else if (for_each_template_parm (TREE_VALUE (TYPE_TEMPLATE_INFO (t)),
- fn, data))
+ fn, data, pfd->visited))
return error_mark_node;
break;
case METHOD_TYPE:
/* Since we're not going to walk subtrees, we have to do this
explicitly here. */
- if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data))
+ if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data,
+ pfd->visited))
return error_mark_node;
/* Fall through. */
case FUNCTION_TYPE:
/* Check the return type. */
- if (for_each_template_parm (TREE_TYPE (t), fn, data))
+ if (for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited))
return error_mark_node;
/* Check the parameter types. Since default arguments are not
@@ -4340,7 +4570,8 @@ for_each_template_parm_r (tp, walk_subtrees, d)
tree parm;
for (parm = TYPE_ARG_TYPES (t); parm; parm = TREE_CHAIN (parm))
- if (for_each_template_parm (TREE_VALUE (parm), fn, data))
+ if (for_each_template_parm (TREE_VALUE (parm), fn, data,
+ pfd->visited))
return error_mark_node;
/* Since we've already handled the TYPE_ARG_TYPES, we don't
@@ -4352,20 +4583,22 @@ for_each_template_parm_r (tp, walk_subtrees, d)
case FUNCTION_DECL:
case VAR_DECL:
if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
- && for_each_template_parm (DECL_TI_ARGS (t), fn, data))
+ && for_each_template_parm (DECL_TI_ARGS (t), fn, data,
+ pfd->visited))
return error_mark_node;
/* Fall through. */
case CONST_DECL:
case PARM_DECL:
if (DECL_CONTEXT (t)
- && for_each_template_parm (DECL_CONTEXT (t), fn, data))
+ && for_each_template_parm (DECL_CONTEXT (t), fn, data,
+ pfd->visited))
return error_mark_node;
break;
case BOUND_TEMPLATE_TEMPLATE_PARM:
/* Record template parameters such as `T' inside `TT<T>'. */
- if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data))
+ if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited))
return error_mark_node;
/* Fall through. */
@@ -4381,7 +4614,7 @@ for_each_template_parm_r (tp, walk_subtrees, d)
case TEMPLATE_DECL:
/* A template template parameter is encountered */
if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)
- && for_each_template_parm (TREE_TYPE (t), fn, data))
+ && for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited))
return error_mark_node;
/* Already substituted template template parameter */
@@ -4389,14 +4622,17 @@ for_each_template_parm_r (tp, walk_subtrees, d)
break;
case TYPENAME_TYPE:
- if (!fn || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn, data))
+ if (!fn
+ || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn,
+ data, pfd->visited))
return error_mark_node;
break;
case CONSTRUCTOR:
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))
&& for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE
- (TREE_TYPE (t)), fn, data))
+ (TREE_TYPE (t)), fn, data,
+ pfd->visited))
return error_mark_node;
break;
@@ -4423,6 +4659,16 @@ for_each_template_parm_r (tp, walk_subtrees, d)
return error_mark_node;
break;
+ case BASELINK:
+ /* If we do not handle this case specially, we end up walking
+ the BINFO hierarchy, which is circular, and therefore
+ confuses walk_tree. */
+ *walk_subtrees = 0;
+ if (for_each_template_parm (BASELINK_FUNCTIONS (*tp), fn, data,
+ pfd->visited))
+ return error_mark_node;
+ break;
+
default:
break;
}
@@ -4434,19 +4680,21 @@ for_each_template_parm_r (tp, walk_subtrees, d)
/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM,
BOUND_TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX in T,
call FN with the parameter and the DATA.
- If FN returns non-zero, the iteration is terminated, and
+ If FN returns nonzero, the iteration is terminated, and
for_each_template_parm returns 1. Otherwise, the iteration
- continues. If FN never returns a non-zero value, the value
+ continues. If FN never returns a nonzero value, the value
returned by for_each_template_parm is 0. If FN is NULL, it is
considered to be the function which always returns 1. */
static int
-for_each_template_parm (t, fn, data)
+for_each_template_parm (t, fn, data, visited)
tree t;
tree_fn_t fn;
void* data;
+ htab_t visited;
{
struct pair_fn_data pfd;
+ int result;
/* Set up. */
pfd.fn = fn;
@@ -4455,18 +4703,30 @@ for_each_template_parm (t, fn, data)
/* Walk the tree. (Conceptually, we would like to walk without
duplicates, but for_each_template_parm_r recursively calls
for_each_template_parm, so we would need to reorganize a fair
- bit to use walk_tree_without_duplicates.) */
- return walk_tree (&t,
- for_each_template_parm_r,
- &pfd,
- NULL) != NULL_TREE;
+ bit to use walk_tree_without_duplicates, so we keep our own
+ visited list.) */
+ if (visited)
+ pfd.visited = visited;
+ else
+ pfd.visited = htab_create (37, htab_hash_pointer, htab_eq_pointer,
+ NULL);
+ result = walk_tree (&t,
+ for_each_template_parm_r,
+ &pfd,
+ NULL) != NULL_TREE;
+
+ /* Clean up. */
+ if (!visited)
+ htab_delete (pfd.visited);
+
+ return result;
}
int
uses_template_parms (t)
tree t;
{
- return for_each_template_parm (t, 0, 0);
+ return for_each_template_parm (t, 0, 0, NULL);
}
static int tinst_depth;
@@ -4681,7 +4941,7 @@ tsubst_friend_function (decl, args)
/* Inside pushdecl_namespace_level, we will push into the
current namespace. However, the friend function should go
- into the namespace of the template. */
+ into the namespace of the template. */
ns = decl_namespace_context (new_friend);
push_nested_namespace (ns);
old_decl = pushdecl_namespace_level (new_friend);
@@ -4912,7 +5172,7 @@ tree
instantiate_class_template (type)
tree type;
{
- tree template, args, pattern, t;
+ tree template, args, pattern, t, member;
tree typedecl;
if (type == error_mark_node)
@@ -5007,7 +5267,8 @@ instantiate_class_template (type)
TYPE_BINFO_BASETYPES (type) = TYPE_BINFO_BASETYPES (pattern);
TYPE_FIELDS (type) = TYPE_FIELDS (pattern);
TYPE_METHODS (type) = TYPE_METHODS (pattern);
- CLASSTYPE_TAGS (type) = CLASSTYPE_TAGS (pattern);
+ CLASSTYPE_DECL_LIST (type) = CLASSTYPE_DECL_LIST (pattern);
+ CLASSTYPE_NESTED_UDTS (type) = CLASSTYPE_NESTED_UDTS (pattern);
CLASSTYPE_VBASECLASSES (type) = CLASSTYPE_VBASECLASSES (pattern);
/* Pretend that the type is complete, so that we will look
@@ -5028,7 +5289,7 @@ instantiate_class_template (type)
if (t)
{
- /* This TYPE is actually a instantiation of of a partial
+ /* This TYPE is actually an instantiation of a partial
specialization. We replace the innermost set of ARGS with
the arguments appropriate for substitution. For example,
given:
@@ -5101,6 +5362,10 @@ instantiate_class_template (type)
if (ANON_AGGR_TYPE_P (pattern))
SET_ANON_AGGR_TYPE_P (type);
+ if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (pattern)))
+ /* First instantiate our enclosing class. */
+ complete_type (TYPE_CONTEXT (type));
+
if (TYPE_BINFO_BASETYPES (pattern))
{
tree base_list = NULL_TREE;
@@ -5150,13 +5415,7 @@ instantiate_class_template (type)
/* Now call xref_basetypes to set up all the base-class
information. */
- xref_basetypes (TREE_CODE (pattern) == RECORD_TYPE
- ? (CLASSTYPE_DECLARED_CLASS (pattern)
- ? class_type_node : record_type_node)
- : union_type_node,
- DECL_NAME (TYPE_NAME (pattern)),
- type,
- base_list);
+ xref_basetypes (type, base_list);
}
/* Now that our base classes are set up, enter the scope of the
@@ -5166,175 +5425,170 @@ instantiate_class_template (type)
class. */
pushclass (type, 1);
- for (t = CLASSTYPE_TAGS (pattern); t; t = TREE_CHAIN (t))
+ /* Now members are processed in the order of declaration. */
+ for (member = CLASSTYPE_DECL_LIST (pattern); member; member = TREE_CHAIN (member))
{
- tree tag = TREE_VALUE (t);
- tree name = TYPE_IDENTIFIER (tag);
- tree newtag;
+ tree t = TREE_VALUE (member);
- newtag = tsubst (tag, args, tf_error, NULL_TREE);
- my_friendly_assert (newtag != error_mark_node, 20010206);
- if (TREE_CODE (newtag) != ENUMERAL_TYPE)
+ if (TREE_PURPOSE (member))
{
- if (TYPE_LANG_SPECIFIC (tag) && CLASSTYPE_IS_TEMPLATE (tag))
- /* Unfortunately, lookup_template_class sets
- CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
- instantiation (i.e., for the type of a member template
- class nested within a template class.) This behavior is
- required for maybe_process_partial_specialization to work
- correctly, but is not accurate in this case; the TAG is not
- an instantiation of anything. (The corresponding
- TEMPLATE_DECL is an instantiation, but the TYPE is not.) */
- CLASSTYPE_USE_TEMPLATE (newtag) = 0;
-
- /* Now, we call pushtag to put this NEWTAG into the scope of
- TYPE. We first set up the IDENTIFIER_TYPE_VALUE to avoid
- pushtag calling push_template_decl. We don't have to do
- this for enums because it will already have been done in
- tsubst_enum. */
- if (name)
- SET_IDENTIFIER_TYPE_VALUE (name, newtag);
- pushtag (name, newtag, /*globalize=*/0);
- }
- }
-
- /* Don't replace enum constants here. */
- for (t = TYPE_FIELDS (pattern); t; t = TREE_CHAIN (t))
- if (TREE_CODE (t) != CONST_DECL)
- {
- tree r;
+ if (TYPE_P (t))
+ {
+ /* Build new CLASSTYPE_NESTED_UDTS. */
- /* The the file and line for this declaration, to assist in
- error message reporting. Since we called push_tinst_level
- above, we don't need to restore these. */
- lineno = DECL_SOURCE_LINE (t);
- input_filename = DECL_SOURCE_FILE (t);
+ tree tag = t;
+ tree name = TYPE_IDENTIFIER (tag);
+ tree newtag;
- r = tsubst (t, args, tf_error | tf_warning, NULL_TREE);
- if (TREE_CODE (r) == VAR_DECL)
- {
- tree init;
+ newtag = tsubst (tag, args, tf_error, NULL_TREE);
+ my_friendly_assert (newtag != error_mark_node, 20010206);
+ if (TREE_CODE (newtag) != ENUMERAL_TYPE)
+ {
+ if (TYPE_LANG_SPECIFIC (tag) && CLASSTYPE_IS_TEMPLATE (tag))
+ /* Unfortunately, lookup_template_class sets
+ CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
+ instantiation (i.e., for the type of a member template
+ class nested within a template class.) This behavior is
+ required for maybe_process_partial_specialization to work
+ correctly, but is not accurate in this case; the TAG is not
+ an instantiation of anything. (The corresponding
+ TEMPLATE_DECL is an instantiation, but the TYPE is not.) */
+ CLASSTYPE_USE_TEMPLATE (newtag) = 0;
+
+ /* Now, we call pushtag to put this NEWTAG into the scope of
+ TYPE. We first set up the IDENTIFIER_TYPE_VALUE to avoid
+ pushtag calling push_template_decl. We don't have to do
+ this for enums because it will already have been done in
+ tsubst_enum. */
+ if (name)
+ SET_IDENTIFIER_TYPE_VALUE (name, newtag);
+ pushtag (name, newtag, /*globalize=*/0);
+ }
+ }
+ else if (TREE_CODE (t) == FUNCTION_DECL
+ || DECL_FUNCTION_TEMPLATE_P (t))
+ {
+ /* Build new TYPE_METHODS. */
- if (DECL_INITIALIZED_IN_CLASS_P (r))
- init = tsubst_expr (DECL_INITIAL (t), args,
- tf_error | tf_warning, NULL_TREE);
- else
- init = NULL_TREE;
+ tree r = tsubst (t, args, tf_error, NULL_TREE);
+ set_current_access_from_decl (r);
+ grok_special_member_properties (r);
+ finish_member_declaration (r);
+ }
+ else
+ {
+ /* Build new TYPE_FIELDS. */
- finish_static_data_member_decl (r, init,
- /*asmspec_tree=*/NULL_TREE,
- /*flags=*/0);
+ if (TREE_CODE (t) != CONST_DECL)
+ {
+ tree r;
- if (DECL_INITIALIZED_IN_CLASS_P (r))
- check_static_variable_definition (r, TREE_TYPE (r));
- }
- else if (TREE_CODE (r) == FIELD_DECL)
- {
- /* Determine whether R has a valid type and can be
- completed later. If R is invalid, then it is replaced
- by error_mark_node so that it will not be added to
- TYPE_FIELDS. */
- tree rtype = TREE_TYPE (r);
- if (!can_complete_type_without_circularity (rtype))
- {
- incomplete_type_error (r, rtype);
- r = error_mark_node;
- }
- }
+ /* The the file and line for this declaration, to assist
+ in error message reporting. Since we called
+ push_tinst_level above, we don't need to restore these. */
+ lineno = DECL_SOURCE_LINE (t);
+ input_filename = DECL_SOURCE_FILE (t);
- /* R will have a TREE_CHAIN if and only if it has already been
- processed by finish_member_declaration. This can happen
- if, for example, it is a TYPE_DECL for a class-scoped
- ENUMERAL_TYPE; such a thing will already have been added to
- the field list by tsubst_enum above. */
- if (!TREE_CHAIN (r))
- {
- set_current_access_from_decl (r);
- finish_member_declaration (r);
- }
- }
+ r = tsubst (t, args, tf_error | tf_warning, NULL_TREE);
+ if (TREE_CODE (r) == VAR_DECL)
+ {
+ tree init;
- /* Set up the list (TYPE_METHODS) and vector (CLASSTYPE_METHOD_VEC)
- for this instantiation. */
- for (t = TYPE_METHODS (pattern); t; t = TREE_CHAIN (t))
- {
- tree r = tsubst (t, args, tf_error, NULL_TREE);
- set_current_access_from_decl (r);
- grok_special_member_properties (r);
- finish_member_declaration (r);
- }
+ if (DECL_INITIALIZED_IN_CLASS_P (r))
+ init = tsubst_expr (DECL_INITIAL (t), args,
+ tf_error | tf_warning, NULL_TREE);
+ else
+ init = NULL_TREE;
- /* Construct the DECL_FRIENDLIST for the new class type. */
- typedecl = TYPE_MAIN_DECL (type);
- for (t = DECL_FRIENDLIST (TYPE_MAIN_DECL (pattern));
- t != NULL_TREE;
- t = TREE_CHAIN (t))
- {
- tree friends;
-
- for (friends = TREE_VALUE (t);
- friends != NULL_TREE;
- friends = TREE_CHAIN (friends))
- if (TREE_PURPOSE (friends) == error_mark_node)
- add_friend (type,
- tsubst_friend_function (TREE_VALUE (friends),
- args));
- else
- abort ();
- }
+ finish_static_data_member_decl (r, init,
+ /*asmspec_tree=*/NULL_TREE,
+ /*flags=*/0);
- for (t = CLASSTYPE_FRIEND_CLASSES (pattern);
- t != NULL_TREE;
- t = TREE_CHAIN (t))
- {
- tree friend_type = TREE_VALUE (t);
- tree new_friend_type;
+ if (DECL_INITIALIZED_IN_CLASS_P (r))
+ check_static_variable_definition (r, TREE_TYPE (r));
+ }
+ else if (TREE_CODE (r) == FIELD_DECL)
+ {
+ /* Determine whether R has a valid type and can be
+ completed later. If R is invalid, then it is
+ replaced by error_mark_node so that it will not be
+ added to TYPE_FIELDS. */
+ tree rtype = TREE_TYPE (r);
+ if (can_complete_type_without_circularity (rtype))
+ complete_type (rtype);
+
+ if (!COMPLETE_TYPE_P (rtype))
+ {
+ cxx_incomplete_type_error (r, rtype);
+ r = error_mark_node;
+ }
+ }
- if (TREE_CODE (friend_type) == TEMPLATE_DECL)
- new_friend_type = tsubst_friend_class (friend_type, args);
- else if (uses_template_parms (friend_type))
- new_friend_type = tsubst (friend_type, args,
- tf_error | tf_warning, NULL_TREE);
- else
- {
- tree ns = decl_namespace_context (TYPE_MAIN_DECL (friend_type));
-
- /* The call to xref_tag_from_type does injection for friend
- classes. */
- push_nested_namespace (ns);
- new_friend_type =
- xref_tag_from_type (friend_type, NULL_TREE, 1);
- pop_nested_namespace (ns);
+ /* If it is a TYPE_DECL for a class-scoped ENUMERAL_TYPE,
+ such a thing will already have been added to the field
+ list by tsubst_enum in finish_member_declaration in the
+ CLASSTYPE_NESTED_UDTS case above. */
+ if (!(TREE_CODE (r) == TYPE_DECL
+ && TREE_CODE (TREE_TYPE (r)) == ENUMERAL_TYPE
+ && DECL_ARTIFICIAL (r)))
+ {
+ set_current_access_from_decl (r);
+ finish_member_declaration (r);
+ }
+ }
+ }
}
+ else
+ {
+ if (TYPE_P (t) || DECL_CLASS_TEMPLATE_P (t))
+ {
+ /* Build new CLASSTYPE_FRIEND_CLASSES. */
+
+ tree friend_type = t;
+ tree new_friend_type;
- if (TREE_CODE (friend_type) == TEMPLATE_DECL)
- /* Trick make_friend_class into realizing that the friend
- we're adding is a template, not an ordinary class. It's
- important that we use make_friend_class since it will
- perform some error-checking and output cross-reference
- information. */
- ++processing_template_decl;
+ if (TREE_CODE (friend_type) == TEMPLATE_DECL)
+ new_friend_type = tsubst_friend_class (friend_type, args);
+ else if (uses_template_parms (friend_type))
+ new_friend_type = tsubst (friend_type, args,
+ tf_error | tf_warning, NULL_TREE);
+ else
+ {
+ tree ns = decl_namespace_context (TYPE_MAIN_DECL (friend_type));
+
+ /* The call to xref_tag_from_type does injection for friend
+ classes. */
+ push_nested_namespace (ns);
+ new_friend_type =
+ xref_tag_from_type (friend_type, NULL_TREE, 1);
+ pop_nested_namespace (ns);
+ }
- if (new_friend_type != error_mark_node)
- make_friend_class (type, new_friend_type);
+ if (TREE_CODE (friend_type) == TEMPLATE_DECL)
+ /* Trick make_friend_class into realizing that the friend
+ we're adding is a template, not an ordinary class. It's
+ important that we use make_friend_class since it will
+ perform some error-checking and output cross-reference
+ information. */
+ ++processing_template_decl;
- if (TREE_CODE (friend_type) == TEMPLATE_DECL)
- --processing_template_decl;
- }
+ if (new_friend_type != error_mark_node)
+ make_friend_class (type, new_friend_type);
- /* Now that TYPE_FIELDS and TYPE_METHODS are set up. We can
- instantiate templates used by this class. */
- for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
- if (TREE_CODE (t) == FIELD_DECL)
- {
- TREE_TYPE (t) = complete_type (TREE_TYPE (t));
- require_complete_type (t);
- }
+ if (TREE_CODE (friend_type) == TEMPLATE_DECL)
+ --processing_template_decl;
+ }
+ else
+ /* Build new DECL_FRIENDLIST. */
+ add_friend (type, tsubst_friend_function (t, args));
+ }
+ }
/* Set the file and line number information to whatever is given for
the class itself. This puts error messages involving generated
implicit functions at a predictable point, and the same point
that would be used for non-template classes. */
+ typedecl = TYPE_MAIN_DECL (type);
lineno = DECL_SOURCE_LINE (typedecl);
input_filename = DECL_SOURCE_FILE (typedecl);
@@ -5362,6 +5616,9 @@ instantiate_class_template (type)
pop_from_top_level ();
pop_tinst_level ();
+ if (TYPE_CONTAINS_VPTR_P (type))
+ keyed_classes = tree_cons (NULL_TREE, type, keyed_classes);
+
return type;
}
@@ -5506,7 +5763,7 @@ tsubst_template_parms (parms, args, complain)
/* Substitute the ARGS into the indicated aggregate (or enumeration)
type T. If T is not an aggregate or enumeration type, it is
handled as if by tsubst. IN_DECL is as for tsubst. If
- ENTERING_SCOPE is non-zero, T is the context for a template which
+ ENTERING_SCOPE is nonzero, T is the context for a template which
we are presently tsubst'ing. Return the substituted value. */
static tree
@@ -5592,15 +5849,19 @@ tsubst_default_argument (fn, type, arg)
};
we must be careful to do name lookup in the scope of S<T>,
- rather than in the current class. */
- if (DECL_CLASS_SCOPE_P (fn))
- pushclass (DECL_CONTEXT (fn), 2);
+ rather than in the current class.
+
+ ??? current_class_type affects a lot more than name lookup. This is
+ very fragile. Fortunately, it will go away when we do 2-phase name
+ binding properly. */
+
+ /* FN is already the desired FUNCTION_DECL. */
+ push_access_scope (fn);
arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
tf_error | tf_warning, NULL_TREE);
- if (DECL_CLASS_SCOPE_P (fn))
- popclass ();
+ pop_access_scope (fn);
/* Make sure the default argument is reasonable. */
arg = check_default_argument (type, arg);
@@ -5650,8 +5911,6 @@ tsubst_decl (t, args, type, complain)
tree r = NULL_TREE;
tree in_decl = t;
- my_friendly_assert (complain & tf_error, 20011214);
-
/* Set the filename and linenumber to improve error-reporting. */
saved_lineno = lineno;
saved_filename = input_filename;
@@ -5716,10 +5975,6 @@ tsubst_decl (t, args, type, complain)
= tsubst_aggr_type (DECL_CONTEXT (t), args,
complain, in_decl,
/*entering_scope=*/1);
- DECL_VIRTUAL_CONTEXT (r)
- = tsubst_aggr_type (DECL_VIRTUAL_CONTEXT (t), args,
- complain, in_decl,
- /*entering_scope=*/1);
DECL_TEMPLATE_INFO (r) = build_tree_list (t, args);
if (TREE_CODE (decl) == TYPE_DECL)
@@ -5746,7 +6001,7 @@ tsubst_decl (t, args, type, complain)
/* The template parameters for this new template are all the
template parameters for the old template, except the
- outermost level of parameters. */
+ outermost level of parameters. */
DECL_TEMPLATE_PARMS (r)
= tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args,
complain);
@@ -5782,6 +6037,10 @@ tsubst_decl (t, args, type, complain)
{
tree spec;
+ /* If T is not dependent, just return it. */
+ if (!uses_template_parms (DECL_TI_ARGS (t)))
+ return t;
+
/* Calculate the most general template of which R is a
specialization, and the complete set of arguments used to
specialize R. */
@@ -5890,10 +6149,6 @@ tsubst_decl (t, args, type, complain)
SET_DECL_RTL (r, NULL_RTX);
DECL_CONTEXT (r) = ctx;
- DECL_VIRTUAL_CONTEXT (r)
- = tsubst_aggr_type (DECL_VIRTUAL_CONTEXT (t), args,
- complain, t,
- /*entering_scope=*/1);
if (member && DECL_CONV_FN_P (r))
/* Type-conversion operator. Reconstruct the name, in
@@ -5981,7 +6236,7 @@ tsubst_decl (t, args, type, complain)
r = copy_node (t);
if (DECL_TEMPLATE_PARM_P (t))
SET_DECL_TEMPLATE_PARM_P (r);
-
+
TREE_TYPE (r) = type;
c_apply_type_quals_to_decl (cp_type_quals (type), r);
@@ -5992,10 +6247,9 @@ tsubst_decl (t, args, type, complain)
complain, in_decl);
DECL_CONTEXT (r) = NULL_TREE;
- if (!DECL_TEMPLATE_PARM_P (r) && PROMOTE_PROTOTYPES
- && INTEGRAL_TYPE_P (type)
- && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
- DECL_ARG_TYPE (r) = integer_type_node;
+
+ if (!DECL_TEMPLATE_PARM_P (r))
+ DECL_ARG_TYPE (r) = type_passed_as (type);
if (TREE_CHAIN (t))
TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args,
complain, TREE_CHAIN (t));
@@ -6102,7 +6356,10 @@ tsubst_decl (t, args, type, complain)
/* Even if the original location is out of scope, the newly
substituted one is not. */
if (TREE_CODE (r) == VAR_DECL)
- DECL_DEAD_FOR_LOCAL (r) = 0;
+ {
+ DECL_DEAD_FOR_LOCAL (r) = 0;
+ DECL_INITIALIZED_P (r) = 0;
+ }
if (!local_p)
{
@@ -6703,7 +6960,7 @@ tsubst (t, args, complain, in_decl)
}
if (TREE_CODE (type) == REFERENCE_TYPE)
{
- if (complain)
+ if (complain & tf_error)
error ("creating pointer to member reference type `%T'", type);
return error_mark_node;
@@ -6736,7 +6993,7 @@ tsubst (t, args, complain, in_decl)
if (fntype == error_mark_node)
return error_mark_node;
- /* Substitue the exception specification. */
+ /* Substitue the exception specification. */
raises = TYPE_RAISES_EXCEPTIONS (t);
if (raises)
{
@@ -6843,7 +7100,7 @@ tsubst (t, args, complain, in_decl)
if (!COMPLETE_TYPE_P (ctx))
{
if (complain & tf_error)
- incomplete_type_error (NULL_TREE, ctx);
+ cxx_incomplete_type_error (NULL_TREE, ctx);
return error_mark_node;
}
}
@@ -6931,7 +7188,10 @@ tsubst (t, args, complain, in_decl)
if (e1 == error_mark_node)
return error_mark_node;
- return TREE_TYPE (e1);
+ return cp_build_qualified_type_real (TREE_TYPE (e1),
+ cp_type_quals (t)
+ | cp_type_quals (TREE_TYPE (e1)),
+ complain);
}
default:
@@ -7330,22 +7590,14 @@ tsubst_expr (t, args, complain, in_decl)
break;
case CTOR_INITIALIZER:
- {
- tree member_init_list;
- tree base_init_list;
-
- prep_stmt (t);
- member_init_list
- = tsubst_initializer_list (TREE_OPERAND (t, 0), args);
- base_init_list
- = tsubst_initializer_list (TREE_OPERAND (t, 1), args);
- emit_base_init (member_init_list, base_init_list);
- break;
- }
+ prep_stmt (t);
+ finish_mem_initializers (tsubst_initializer_list
+ (TREE_OPERAND (t, 0), args));
+ break;
case RETURN_STMT:
prep_stmt (t);
- finish_return_stmt (tsubst_expr (RETURN_EXPR (t),
+ finish_return_stmt (tsubst_expr (RETURN_STMT_EXPR (t),
args, complain, in_decl));
break;
@@ -7405,7 +7657,7 @@ tsubst_expr (t, args, complain, in_decl)
/* For __PRETTY_FUNCTION__ we have to adjust the
initializer. */
const char *const name
- = (*decl_printable_name) (current_function_decl, 2);
+ = cxx_printable_name (current_function_decl, 2);
init = cp_fname_init (name);
TREE_TYPE (decl) = TREE_TYPE (init);
}
@@ -7417,7 +7669,7 @@ tsubst_expr (t, args, complain, in_decl)
}
/* A DECL_STMT can also be used as an expression, in the condition
- clause of a if/for/while construct. If we aren't followed by
+ clause of an if/for/while construct. If we aren't followed by
another statement, return our decl. */
if (TREE_CHAIN (t) == NULL_TREE)
return decl;
@@ -7632,10 +7884,6 @@ tsubst_expr (t, args, complain, in_decl)
tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
break;
- case CTOR_STMT:
- add_stmt (copy_node (t));
- break;
-
default:
abort ();
}
@@ -7667,7 +7915,7 @@ instantiate_template (tmpl, targ_ptr)
tree spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), targ_ptr);
tree clone;
- /* Look for the clone. */
+ /* Look for the clone. */
for (clone = TREE_CHAIN (spec);
clone && DECL_CLONED_FUNCTION_P (clone);
clone = TREE_CHAIN (clone))
@@ -7716,9 +7964,19 @@ instantiate_template (tmpl, targ_ptr)
}
}
+ /* Make sure that we can see identifiers, and compute access
+ correctly. The desired FUNCTION_DECL for FNDECL may or may not be
+ created earlier. Let push_access_scope_real figure that out. */
+ push_access_scope_real
+ (gen_tmpl, targ_ptr, tsubst (DECL_CONTEXT (gen_tmpl), targ_ptr,
+ tf_error, gen_tmpl));
+
/* substitute template parameters */
fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl),
targ_ptr, tf_error, gen_tmpl);
+
+ pop_access_scope (gen_tmpl);
+
/* The DECL_TI_TEMPLATE should always be the immediate parent
template, not the most general template. */
DECL_TI_TEMPLATE (fndecl) = tmpl;
@@ -7789,7 +8047,7 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
int result;
my_friendly_assert (TREE_CODE (fn) == TEMPLATE_DECL, 0);
-
+
fntype = TREE_TYPE (fn);
if (explicit_targs)
{
@@ -7967,6 +8225,12 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
*parm = TREE_TYPE (*parm);
result |= UNIFY_ALLOW_OUTER_MORE_CV_QUAL;
}
+
+ /* DR 322. For conversion deduction, remove a reference type on parm
+ too (which has been swapped into ARG). */
+ if (strict == DEDUCE_CONV && TREE_CODE (*arg) == REFERENCE_TYPE)
+ *arg = TREE_TYPE (*arg);
+
return result;
}
@@ -7995,8 +8259,7 @@ type_unification_real (tparms, targs, xparms, xargs, subr,
my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289);
my_friendly_assert (xparms == NULL_TREE
|| TREE_CODE (xparms) == TREE_LIST, 290);
- /* ARGS could be NULL (via a call from parse.y to
- build_x_function_call). */
+ /* ARGS could be NULL. */
if (xargs)
my_friendly_assert (TREE_CODE (xargs) == TREE_LIST, 291);
my_friendly_assert (ntparms > 0, 292);
@@ -8173,8 +8436,8 @@ resolve_overloaded_unification (tparms, targs, parm, arg, strict,
arg = TREE_OPERAND (arg, 1);
/* Strip baselink information. */
- while (TREE_CODE (arg) == TREE_LIST)
- arg = TREE_VALUE (arg);
+ if (BASELINK_P (arg))
+ arg = BASELINK_FUNCTIONS (arg);
if (TREE_CODE (arg) == TEMPLATE_ID_EXPR)
{
@@ -8205,7 +8468,8 @@ resolve_overloaded_unification (tparms, targs, parm, arg, strict,
}
}
}
- else if (TREE_CODE (arg) == OVERLOAD)
+ else if (TREE_CODE (arg) == OVERLOAD
+ || TREE_CODE (arg) == FUNCTION_DECL)
{
for (; arg; arg = OVL_NEXT (arg))
{
@@ -8332,29 +8596,12 @@ static int
verify_class_unification (targs, parms, args)
tree targs, parms, args;
{
- int i;
- int nparms = TREE_VEC_LENGTH (parms);
- tree new_parms = tsubst (parms, add_outermost_template_args (args, targs),
- tf_none, NULL_TREE);
- if (new_parms == error_mark_node)
+ parms = tsubst (parms, add_outermost_template_args (args, targs),
+ tf_none, NULL_TREE);
+ if (parms == error_mark_node)
return 1;
- args = INNERMOST_TEMPLATE_ARGS (args);
-
- for (i = 0; i < nparms; i++)
- {
- tree parm = TREE_VEC_ELT (new_parms, i);
- tree arg = TREE_VEC_ELT (args, i);
-
- /* In case we are deducing from a function argument of a function
- templates, some parameters may not be deduced yet. So we
- make sure that only fully substituted elements of PARM are
- compared below. */
-
- if (!uses_template_parms (parm) && !template_args_equal (parm, arg))
- return 1;
- }
- return 0;
+ return !comp_template_args (parms, INNERMOST_TEMPLATE_ARGS (args));
}
/* PARM is a template class (perhaps with unbound template
@@ -8372,7 +8619,8 @@ try_class_unification (tparms, targs, parm, arg)
tree copy_of_targs;
if (!CLASSTYPE_TEMPLATE_INFO (arg)
- || CLASSTYPE_TI_TEMPLATE (arg) != CLASSTYPE_TI_TEMPLATE (parm))
+ || (most_general_template (CLASSTYPE_TI_TEMPLATE (arg))
+ != most_general_template (CLASSTYPE_TI_TEMPLATE (parm))))
return NULL_TREE;
/* We need to make a new template argument vector for the call to
@@ -8401,7 +8649,7 @@ try_class_unification (tparms, targs, parm, arg)
Now, by the time we consider the unification involving `s2', we
already know that we must have `f<0, 0, 0>'. But, even though
- `S<0, 1, 2>' is derived from `S<0, 0, 0>', the code is not legal
+ `S<0, 1, 2>' is derived from `S<0, 0, 0>', the code is invalid
because there are two ways to unify base classes of S<0, 1, 2>
with S<I, I, I>. If we kept the already deduced knowledge, we
would reject the possibility I=1. */
@@ -8543,7 +8791,7 @@ template_decl_level (decl)
/* Decide whether ARG can be unified with PARM, considering only the
cv-qualifiers of each type, given STRICT as documented for unify.
- Returns non-zero iff the unification is OK on that basis.*/
+ Returns nonzero iff the unification is OK on that basis.*/
static int
check_cv_quals_for_unify (strict, arg, parm)
@@ -8763,6 +9011,12 @@ unify (tparms, targs, parm, arg, strict)
}
else
{
+ /* If ARG is an offset type, we're trying to unify '*T' with
+ 'U C::*', which is ill-formed. See the comment in the
+ POINTER_TYPE case about this ugliness. */
+ if (TREE_CODE (arg) == OFFSET_TYPE)
+ return 1;
+
/* If PARM is `const T' and ARG is only `int', we don't have
a match unless we are allowing additional qualification.
If ARG is `const int' and PARM is just `T' that's OK;
@@ -8831,8 +9085,12 @@ unify (tparms, targs, parm, arg, strict)
deduced from an array bound may be of any integral type.
The non-type parameter might use already deduced type parameters. */
tparm = tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE);
- if (same_type_p (TREE_TYPE (arg), tparm))
- /* OK */;
+ if (!TREE_TYPE (arg))
+ /* Template-parameter dependent expression. Just accept it for now.
+ It will later be processed in convert_template_argument. */
+ ;
+ else if (same_type_p (TREE_TYPE (arg), tparm))
+ /* OK */;
else if ((strict & UNIFY_ALLOW_INTEGER)
&& (TREE_CODE (tparm) == INTEGER_TYPE
|| TREE_CODE (tparm) == BOOLEAN_TYPE))
@@ -8872,7 +9130,7 @@ unify (tparms, targs, parm, arg, strict)
{
/* Avoid getting confused about cv-quals; don't recurse here.
Pointers to members should really be just OFFSET_TYPE, not
- this two-level nonsense... */
+ this two-level nonsense... */
parm = TREE_TYPE (parm);
arg = TREE_TYPE (arg);
@@ -8900,7 +9158,7 @@ unify (tparms, targs, parm, arg, strict)
TYPE_DOMAIN (arg), UNIFY_ALLOW_NONE) != 0)
return 1;
return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
- UNIFY_ALLOW_NONE);
+ strict & UNIFY_ALLOW_MORE_CV_QUAL);
case REAL_TYPE:
case COMPLEX_TYPE:
@@ -9117,11 +9375,6 @@ mark_decl_instantiated (result, extern_p)
tree result;
int extern_p;
{
- if (TREE_CODE (result) != FUNCTION_DECL)
- /* The TREE_PUBLIC flag for function declarations will have been
- set correctly by tsubst. */
- TREE_PUBLIC (result) = 1;
-
/* We used to set this unconditionally; we moved that to
do_decl_instantiation so it wouldn't get set on members of
explicit class template instantiations. But we still need to set
@@ -9130,6 +9383,19 @@ mark_decl_instantiated (result, extern_p)
if (extern_p)
SET_DECL_EXPLICIT_INSTANTIATION (result);
+ /* If this entity has already been written out, it's too late to
+ make any modifications. */
+ if (TREE_ASM_WRITTEN (result))
+ return;
+
+ if (TREE_CODE (result) != FUNCTION_DECL)
+ /* The TREE_PUBLIC flag for function declarations will have been
+ set correctly by tsubst. */
+ TREE_PUBLIC (result) = 1;
+
+ /* This might have been set by an earlier implicit instantiation. */
+ DECL_COMDAT (result) = 0;
+
if (! extern_p)
{
DECL_INTERFACE_KNOWN (result) = 1;
@@ -9143,7 +9409,8 @@ mark_decl_instantiated (result, extern_p)
else if (TREE_PUBLIC (result))
maybe_make_one_only (result);
}
- else if (TREE_CODE (result) == FUNCTION_DECL)
+
+ if (TREE_CODE (result) == FUNCTION_DECL)
defer_fn (result);
}
@@ -9234,7 +9501,7 @@ get_bindings_real (fn, decl, explicit_args, check_rettype, deduce, len)
if (DECL_TEMPLATE_INFO (decl))
tmpl = DECL_TI_TEMPLATE (decl);
else
- /* We can get here for some illegal specializations. */
+ /* We can get here for some invalid specializations. */
return NULL_TREE;
converted_args
@@ -9434,6 +9701,10 @@ most_general_template (decl)
if (TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL)
break;
+ if (CLASS_TYPE_P (TREE_TYPE (decl))
+ && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
+ break;
+
/* Stop if we run into an explicitly specialized class template. */
if (!DECL_NAMESPACE_SCOPE_P (decl)
&& DECL_CONTEXT (decl)
@@ -9505,13 +9776,11 @@ most_specialized_class (tmpl, args)
return champ;
}
-/* called from the parser. */
+/* Explicitly instantiate DECL. */
void
-do_decl_instantiation (declspecs, declarator, storage)
- tree declspecs, declarator, storage;
+do_decl_instantiation (tree decl, tree storage)
{
- tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL);
tree result = NULL_TREE;
int extern_p = 0;
@@ -9550,7 +9819,7 @@ do_decl_instantiation (declspecs, declarator, storage)
result = decl;
/* Check for various error cases. Note that if the explicit
- instantiation is legal the RESULT will currently be marked as an
+ instantiation is valid the RESULT will currently be marked as an
*implicit* instantiation; DECL_EXPLICIT_INSTANTIATION is not set
until we get here. */
@@ -9635,9 +9904,21 @@ mark_class_instantiated (t, extern_p)
}
}
+/* Called from do_type_instantiation through binding_table_foreach to
+ do recursive instantiation for the type bound in ENTRY. */
+static void
+bt_instantiate_type_proc (binding_entry entry, void *data)
+{
+ tree storage = *(tree *) data;
+
+ if (IS_AGGR_TYPE (entry->type)
+ && !uses_template_parms (CLASSTYPE_TI_ARGS (entry->type)))
+ do_type_instantiation (TYPE_MAIN_DECL (entry->type), storage, 0);
+}
+
/* Perform an explicit instantiation of template class T. STORAGE, if
non-null, is the RID for extern, inline or static. COMPLAIN is
- non-zero if this is called from the parser, zero if called recursively,
+ nonzero if this is called from the parser, zero if called recursively,
since the standard is unclear (as detailed below). */
void
@@ -9775,10 +10056,9 @@ do_type_instantiation (t, storage, complain)
instantiate_decl (tmp, /*defer_ok=*/1);
}
- for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp))
- if (IS_AGGR_TYPE (TREE_VALUE (tmp))
- && !uses_template_parms (CLASSTYPE_TI_ARGS (TREE_VALUE (tmp))))
- do_type_instantiation (TYPE_MAIN_DECL (TREE_VALUE (tmp)), storage, 0);
+ if (CLASSTYPE_NESTED_UDTS (t))
+ binding_table_foreach (CLASSTYPE_NESTED_UDTS (t),
+ bt_instantiate_type_proc, &storage);
}
}
@@ -9825,6 +10105,7 @@ regenerate_decl_from_template (decl, tmpl)
instantiation of a specialization, which it isn't: it's a full
instantiation. */
gen_tmpl = most_general_template (tmpl);
+ push_access_scope_real (gen_tmpl, args, DECL_CONTEXT (decl));
unregistered = unregister_specialization (decl, gen_tmpl);
/* If the DECL was not unregistered then something peculiar is
@@ -9832,11 +10113,6 @@ regenerate_decl_from_template (decl, tmpl)
register_specialization for it. */
my_friendly_assert (unregistered, 0);
- if (TREE_CODE (decl) == VAR_DECL)
- /* Make sure that we can see identifiers, and compute access
- correctly, for the class members used in the declaration of
- this static variable. */
- pushclass (DECL_CONTEXT (decl), 2);
/* Do the substitution to get the new declaration. */
new_decl = tsubst (code_pattern, args, tf_error, NULL_TREE);
@@ -9844,11 +10120,10 @@ regenerate_decl_from_template (decl, tmpl)
if (TREE_CODE (decl) == VAR_DECL)
{
/* Set up DECL_INITIAL, since tsubst doesn't. */
- DECL_INITIAL (new_decl) =
- tsubst_expr (DECL_INITIAL (code_pattern), args,
- tf_error, DECL_TI_TEMPLATE (decl));
- /* Pop the class context we pushed above. */
- popclass ();
+ if (!DECL_INITIALIZED_IN_CLASS_P (decl))
+ DECL_INITIAL (new_decl) =
+ tsubst_expr (DECL_INITIAL (code_pattern), args,
+ tf_error, DECL_TI_TEMPLATE (decl));
}
else if (TREE_CODE (decl) == FUNCTION_DECL)
{
@@ -9859,6 +10134,8 @@ regenerate_decl_from_template (decl, tmpl)
DECL_INITIAL (decl) = NULL_TREE;
}
+ pop_access_scope (decl);
+
/* The immediate parent of the new template is still whatever it was
before, even though tsubst sets DECL_TI_TEMPLATE up as the most
general template. We also reset the DECL_ASSEMBLER_NAME since
@@ -9879,7 +10156,7 @@ regenerate_decl_from_template (decl, tmpl)
}
/* Produce the definition of D, a _DECL generated from a template. If
- DEFER_OK is non-zero, then we don't have to actually do the
+ DEFER_OK is nonzero, then we don't have to actually do the
instantiation now; we just have to do it sometime. */
tree
@@ -9888,7 +10165,8 @@ instantiate_decl (d, defer_ok)
int defer_ok;
{
tree tmpl = DECL_TI_TEMPLATE (d);
- tree args = DECL_TI_ARGS (d);
+ tree gen_args;
+ tree args;
tree td;
tree code_pattern;
tree spec;
@@ -9903,6 +10181,9 @@ instantiate_decl (d, defer_ok)
my_friendly_assert (TREE_CODE (d) == FUNCTION_DECL
|| TREE_CODE (d) == VAR_DECL, 0);
+ if (TREE_CODE (d) == VAR_DECL)
+ defer_ok = 0;
+
/* Don't instantiate cloned functions. Instead, instantiate the
functions they cloned. */
if (TREE_CODE (d) == FUNCTION_DECL && DECL_CLONED_FUNCTION_P (d))
@@ -9922,7 +10203,8 @@ instantiate_decl (d, defer_ok)
specializations, so we must explicitly check
DECL_TEMPLATE_SPECIALIZATION. */
gen_tmpl = most_general_template (tmpl);
- spec = retrieve_specialization (gen_tmpl, args);
+ gen_args = DECL_TI_ARGS (d);
+ spec = retrieve_specialization (gen_tmpl, gen_args);
if (spec != NULL_TREE && DECL_TEMPLATE_SPECIALIZATION (spec))
return spec;
@@ -9983,6 +10265,16 @@ instantiate_decl (d, defer_ok)
code_pattern = DECL_TEMPLATE_RESULT (td);
+ if ((DECL_NAMESPACE_SCOPE_P (d) && !DECL_INITIALIZED_IN_CLASS_P (d))
+ || DECL_TEMPLATE_SPECIALIZATION (td))
+ /* In the case of a friend template whose definition is provided
+ outside the class, we may have too many arguments. Drop the
+ ones we don't need. The same is true for specializations. */
+ args = get_innermost_template_args
+ (gen_args, TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (td)));
+ else
+ args = gen_args;
+
if (TREE_CODE (d) == FUNCTION_DECL)
pattern_defined = (DECL_SAVED_TREE (code_pattern) != NULL_TREE);
else
@@ -10040,18 +10332,25 @@ instantiate_decl (d, defer_ok)
tree gen = DECL_TEMPLATE_RESULT (gen_tmpl);
tree type = TREE_TYPE (gen);
+ /* Make sure that we can see identifiers, and compute access
+ correctly. D is already the target FUNCTION_DECL with the
+ right context. */
+ push_access_scope (d);
+
if (TREE_CODE (gen) == FUNCTION_DECL)
{
- tsubst (DECL_ARGUMENTS (gen), args, tf_error | tf_warning, d);
- tsubst (TYPE_RAISES_EXCEPTIONS (type), args,
+ tsubst (DECL_ARGUMENTS (gen), gen_args, tf_error | tf_warning, d);
+ tsubst (TYPE_RAISES_EXCEPTIONS (type), gen_args,
tf_error | tf_warning, d);
/* Don't simply tsubst the function type, as that will give
duplicate warnings about poor parameter qualifications.
The function arguments are the same as the decl_arguments
- without the top level cv qualifiers. */
+ without the top level cv qualifiers. */
type = TREE_TYPE (type);
}
- tsubst (type, args, tf_error | tf_warning, d);
+ tsubst (type, gen_args, tf_error | tf_warning, d);
+
+ pop_access_scope (d);
}
if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d)
@@ -10092,15 +10391,10 @@ instantiate_decl (d, defer_ok)
if (need_push)
push_to_top_level ();
- /* We're now committed to instantiating this template. Mark it as
- instantiated so that recursive calls to instantiate_decl do not
- try to instantiate it again. */
- DECL_TEMPLATE_INSTANTIATED (d) = 1;
-
/* Regenerate the declaration in case the template has been modified
by a subsequent redeclaration. */
regenerate_decl_from_template (d, td);
-
+
/* We already set the file and line above. Reset them now in case
they changed as a result of calling regenerate_decl_from_template. */
lineno = DECL_SOURCE_LINE (d);
@@ -10108,20 +10402,52 @@ instantiate_decl (d, defer_ok)
if (TREE_CODE (d) == VAR_DECL)
{
+ /* Clear out DECL_RTL; whatever was there before may not be right
+ since we've reset the type of the declaration. */
+ SET_DECL_RTL (d, NULL_RTX);
+
DECL_IN_AGGR_P (d) = 0;
- if (DECL_INTERFACE_KNOWN (d))
- DECL_EXTERNAL (d) = ! DECL_NOT_REALLY_EXTERN (d);
+ import_export_decl (d);
+ DECL_EXTERNAL (d) = ! DECL_NOT_REALLY_EXTERN (d);
+
+ if (DECL_EXTERNAL (d))
+ {
+ /* The fact that this code is executing indicates that:
+
+ (1) D is a template static data member, for which a
+ definition is available.
+
+ (2) An implicit or explicit instantiation has occured.
+
+ (3) We are not going to emit a definition of the static
+ data member at this time.
+
+ This situation is peculiar, but it occurs on platforms
+ without weak symbols when performing an implicit
+ instantiation. There, we cannot implicitly instantiate a
+ defined static data member in more than one translation
+ unit, so import_export_decl marks the declaration as
+ external; we must rely on explicit instantiation. */
+ }
else
{
- DECL_EXTERNAL (d) = 1;
- DECL_NOT_REALLY_EXTERN (d) = 1;
+ /* Mark D as instantiated so that recursive calls to
+ instantiate_decl do not try to instantiate it again. */
+ DECL_TEMPLATE_INSTANTIATED (d) = 1;
+ cp_finish_decl (d,
+ (!DECL_INITIALIZED_IN_CLASS_P (d)
+ ? DECL_INITIAL (d) : NULL_TREE),
+ NULL_TREE, 0);
}
- cp_finish_decl (d, DECL_INITIAL (d), NULL_TREE, 0);
}
else if (TREE_CODE (d) == FUNCTION_DECL)
{
htab_t saved_local_specializations;
+ /* Mark D as instantiated so that recursive calls to
+ instantiate_decl do not try to instantiate it again. */
+ DECL_TEMPLATE_INSTANTIATED (d) = 1;
+
/* Save away the current list, in case we are instantiating one
template from within the body of another. */
saved_local_specializations = local_specializations;
@@ -10133,6 +10459,7 @@ instantiate_decl (d, defer_ok)
NULL);
/* Set up context. */
+ import_export_decl (d);
start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED);
/* Substitute into the body of the function. */
@@ -10144,7 +10471,8 @@ instantiate_decl (d, defer_ok)
local_specializations = saved_local_specializations;
/* Finish the function. */
- expand_body (finish_function (0));
+ d = finish_function (0);
+ expand_body (d);
}
/* We're not deferring instantiation any more. */
@@ -10260,8 +10588,7 @@ static tree
tsubst_initializer_list (t, argvec)
tree t, argvec;
{
- tree first = NULL_TREE;
- tree *p = &first;
+ tree inits = NULL_TREE;
for (; t; t = TREE_CHAIN (t))
{
@@ -10271,23 +10598,30 @@ tsubst_initializer_list (t, argvec)
decl = tsubst_copy (TREE_PURPOSE (t), argvec, tf_error | tf_warning,
NULL_TREE);
+ decl = expand_member_init (decl);
+ if (decl && !DECL_P (decl))
+ in_base_initializer = 1;
+
init = tsubst_expr (TREE_VALUE (t), argvec, tf_error | tf_warning,
NULL_TREE);
-
if (!init)
;
else if (TREE_CODE (init) == TREE_LIST)
for (val = init; val; val = TREE_CHAIN (val))
TREE_VALUE (val) = convert_from_reference (TREE_VALUE (val));
- else
+ else if (init != void_type_node)
init = convert_from_reference (init);
- *p = expand_member_init (current_class_ref, decl,
- init ? init : void_type_node);
- if (*p)
- p = &TREE_CHAIN (*p);
+ in_base_initializer = 0;
+
+ if (decl)
+ {
+ init = build_tree_list (decl, init);
+ TREE_CHAIN (init) = inits;
+ inits = init;
+ }
}
- return first;
+ return inits;
}
/* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL. */
@@ -10334,25 +10668,19 @@ tsubst_enum (tag, newtag, args)
}
finish_enum (newtag);
- DECL_SOURCE_LINE (TYPE_NAME (newtag)) = DECL_SOURCE_LINE (TYPE_NAME (tag));
- DECL_SOURCE_FILE (TYPE_NAME (newtag)) = DECL_SOURCE_FILE (TYPE_NAME (tag));
+ DECL_SOURCE_LOCATION (TYPE_NAME (newtag))
+ = DECL_SOURCE_LOCATION (TYPE_NAME (tag));
}
/* DECL is a FUNCTION_DECL that is a template specialization. Return
its type -- but without substituting the innermost set of template
arguments. So, innermost set of template parameters will appear in
- the type. If CONTEXTP is non-NULL, then the partially substituted
- DECL_CONTEXT (if any) will also be filled in. Similarly, TPARMSP
- will be filled in with the substituted template parameters, if it
- is non-NULL. */
+ the type. */
tree
-get_mostly_instantiated_function_type (decl, contextp, tparmsp)
+get_mostly_instantiated_function_type (decl)
tree decl;
- tree *contextp;
- tree *tparmsp;
{
- tree context = NULL_TREE;
tree fn_type;
tree tmpl;
tree targs;
@@ -10369,8 +10697,6 @@ get_mostly_instantiated_function_type (decl, contextp, tparmsp)
my_friendly_assert (parm_depth == TMPL_ARGS_DEPTH (targs), 0);
fn_type = TREE_TYPE (tmpl);
- if (DECL_STATIC_FUNCTION_P (decl))
- context = DECL_CONTEXT (decl);
if (parm_depth == 1)
/* No substitution is necessary. */
@@ -10390,11 +10716,16 @@ get_mostly_instantiated_function_type (decl, contextp, tparmsp)
TMPL_ARGS_DEPTH (targs),
make_tree_vec (DECL_NTPARMS (tmpl)));
+ /* Make sure that we can see identifiers, and compute access
+ correctly. We can just use the context of DECL for the
+ partial substitution here. It depends only on outer template
+ parameters, regardless of whether the innermost level is
+ specialized or not. */
+ push_access_scope (decl);
+
/* Now, do the (partial) substitution to figure out the
appropriate function type. */
fn_type = tsubst (fn_type, partial_args, tf_error, NULL_TREE);
- if (DECL_STATIC_FUNCTION_P (decl))
- context = tsubst (context, partial_args, tf_error, NULL_TREE);
/* Substitute into the template parameters to obtain the real
innermost set of parameters. This step is important if the
@@ -10402,12 +10733,9 @@ get_mostly_instantiated_function_type (decl, contextp, tparmsp)
parameters whose types depend on outer template parameters. */
TREE_VEC_LENGTH (partial_args)--;
tparms = tsubst_template_parms (tparms, partial_args, tf_error);
- }
- if (contextp)
- *contextp = context;
- if (tparmsp)
- *tparmsp = tparms;
+ pop_access_scope (decl);
+ }
return fn_type;
}
@@ -10434,7 +10762,7 @@ current_instantiation ()
}
/* [temp.param] Check that template non-type parm TYPE is of an allowable
- type. Return zero for ok, non-zero for disallowed. Issue error and
+ type. Return zero for ok, nonzero for disallowed. Issue error and
warning messages under control of COMPLAIN. */
static int
@@ -10460,3 +10788,5 @@ invalid_nontype_parm_type_p (type, complain)
type);
return 1;
}
+
+#include "gt-cp-pt.h"
OpenPOWER on IntegriCloud