aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c1382
1 files changed, 709 insertions, 673 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 4d650c5e23d..12baea14a33 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -88,20 +88,18 @@ 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 (tree, tree, tree);
static void push_access_scope (tree);
static void pop_access_scope (tree);
static int resolve_overloaded_unification (tree, tree, tree, tree,
unification_kind_t, int);
static int try_one_overload (tree, tree, tree, tree, tree,
- unification_kind_t, int);
+ unification_kind_t, int, bool);
static int unify (tree, tree, tree, tree, int);
static void add_pending_template (tree);
static void reopen_tinst_level (tree);
static tree classtype_mangled_name (tree);
static char* mangle_class_name_for_template (const char *, tree, tree);
static tree tsubst_initializer_list (tree, tree);
-static int list_eq (tree, tree);
static tree get_class_bindings (tree, tree, tree);
static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, int);
static void tsubst_enum (tree, tree, tree);
@@ -112,8 +110,6 @@ static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*);
static int type_unification_real (tree, tree, tree, tree,
int, unification_kind_t, int, int);
static void note_template_header (int);
-static tree maybe_fold_nontype_arg (tree);
-static void maybe_fold_nontype_args (tree);
static tree convert_nontype_argument (tree, tree);
static tree convert_template_argument (tree, tree, tree,
tsubst_flags_t, int, tree);
@@ -126,7 +122,6 @@ static tree retrieve_specialization (tree, tree);
static tree retrieve_local_specialization (tree);
static tree register_specialization (tree, tree, tree);
static void register_local_specialization (tree, tree);
-static int unregister_specialization (tree, tree);
static tree reduce_template_parm_level (tree, tree, int);
static tree build_template_decl (tree, tree);
static int mark_template_parm (tree, void *);
@@ -134,10 +129,12 @@ static int template_parm_this_level_p (tree, void *);
static tree tsubst_friend_function (tree, tree);
static tree tsubst_friend_class (tree, tree);
static int can_complete_type_without_circularity (tree);
+static tree get_bindings (tree, tree, tree);
static tree get_bindings_real (tree, tree, tree, int, int, int);
static int template_decl_level (tree);
static int check_cv_quals_for_unify (int, tree, tree);
-static tree tsubst_template_arg_vector (tree, tree, tsubst_flags_t);
+static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
static void regenerate_decl_from_template (tree, tree);
static tree most_specialized (tree, tree, tree);
@@ -173,49 +170,22 @@ static tree tsubst_copy (tree, tree, tsubst_flags_t, tree);
/* 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. */
+ template, or VAR_DECL for static member variable (need by
+ instantiate_decl). */
static void
-push_access_scope_real (tree t, tree args, tree context)
+push_access_scope (tree t)
{
- 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;
- }
- }
+ my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL
+ || TREE_CODE (t) == VAR_DECL,
+ 0);
- if (!context)
- context = DECL_CONTEXT (t);
- if (context && TYPE_P (context))
- push_nested_class (context);
+ if (DECL_CLASS_SCOPE_P (t))
+ push_nested_class (DECL_CONTEXT (t));
else
push_to_top_level ();
- if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t))
+ if (TREE_CODE (t) == FUNCTION_DECL)
{
saved_access_scope = tree_cons
(NULL_TREE, current_function_decl, saved_access_scope);
@@ -223,21 +193,13 @@ push_access_scope_real (tree t, tree args, tree context)
}
}
-/* Like push_access_scope_real, but always uses DECL_CONTEXT. */
-
-static void
-push_access_scope (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. */
static void
pop_access_scope (tree t)
{
- if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t))
+ if (TREE_CODE (t) == FUNCTION_DECL)
{
current_function_decl = TREE_VALUE (saved_access_scope);
saved_access_scope = TREE_CHAIN (saved_access_scope);
@@ -876,9 +838,8 @@ retrieve_specialization (tree tmpl, tree args)
static tree
retrieve_local_specialization (tree tmpl)
{
- tree spec =
- (tree) htab_find_with_hash (local_specializations, tmpl,
- htab_hash_pointer (tmpl));
+ tree spec = htab_find_with_hash (local_specializations, tmpl,
+ htab_hash_pointer (tmpl));
return spec ? TREE_PURPOSE (spec) : NULL_TREE;
}
@@ -1023,11 +984,11 @@ register_specialization (tree spec, tree tmpl, tree args)
}
/* Unregister the specialization SPEC as a specialization of TMPL.
- Returns nonzero if the SPEC was listed as a specialization of
- TMPL. */
+ Replace it with NEW_SPEC, if NEW_SPEC is non-NULL. Returns true
+ if the SPEC was listed as a specialization of TMPL. */
-static int
-unregister_specialization (tree spec, tree tmpl)
+bool
+reregister_specialization (tree spec, tree tmpl, tree new_spec)
{
tree* s;
@@ -1036,7 +997,10 @@ unregister_specialization (tree spec, tree tmpl)
s = &TREE_CHAIN (*s))
if (TREE_VALUE (*s) == spec)
{
- *s = TREE_CHAIN (*s);
+ if (!new_spec)
+ *s = TREE_CHAIN (*s);
+ else
+ TREE_VALUE (*s) = new_spec;
return 1;
}
@@ -1418,9 +1382,9 @@ copy_default_args_to_explicit_spec (tree decl)
TREE_VALUE (in_charge),
new_spec_types);
- new_type = build_cplus_method_type (object_type,
- TREE_TYPE (old_type),
- new_spec_types);
+ new_type = build_method_type_directly (object_type,
+ TREE_TYPE (old_type),
+ new_spec_types);
}
else
new_type = build_function_type (TREE_TYPE (old_type),
@@ -1673,15 +1637,6 @@ check_explicit_specialization (tree declarator,
return decl;
}
- else if (TREE_CODE (TREE_OPERAND (declarator, 0)) == LOOKUP_EXPR)
- {
- /* A friend declaration. We can't do much, because we don't
- know what this resolves to, yet. */
- my_friendly_assert (is_friend != 0, 0);
- my_friendly_assert (!explicit_instantiation, 0);
- SET_DECL_IMPLICIT_INSTANTIATION (decl);
- return decl;
- }
else if (ctype != NULL_TREE
&& (TREE_CODE (TREE_OPERAND (declarator, 0)) ==
IDENTIFIER_NODE))
@@ -2451,11 +2406,11 @@ process_partial_specialization (tree decl)
{
/* We haven't yet initialized TPD2. Do so now. */
tpd2.arg_uses_template_parms
- = (int*) alloca (sizeof (int) * nargs);
+ = alloca (sizeof (int) * nargs);
/* The number of parameters here is the number in the
main template, which, as checked in the assertion
above, is NARGS. */
- tpd2.parms = (int*) alloca (sizeof (int) * nargs);
+ tpd2.parms = alloca (sizeof (int) * nargs);
tpd2.level =
TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl));
}
@@ -2719,6 +2674,15 @@ push_template_decl_real (tree decl, int is_friend)
else if (TREE_CODE (decl) == TYPE_DECL
&& ANON_AGGRNAME_P (DECL_NAME (decl)))
error ("template class without a name");
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DESTRUCTOR_P (decl))
+ {
+ /* [temp.mem]
+
+ A destructor shall not be a member template. */
+ error ("destructor `%D' declared as member template", decl);
+ return error_mark_node;
+ }
else if ((DECL_IMPLICIT_TYPEDEF_P (decl)
&& CLASS_TYPE_P (TREE_TYPE (decl)))
|| (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx))
@@ -2982,8 +2946,7 @@ redeclare_class_template (tree type, tree parms)
A template-parameter may not be given default arguments
by two different declarations in the same scope. */
error ("redefinition of default argument for `%#D'", parm);
- error ("%H original definition appeared here",
- &DECL_SOURCE_LOCATION (tmpl_parm));
+ error ("%J original definition appeared here", tmpl_parm);
return;
}
@@ -3047,14 +3010,12 @@ convert_nontype_argument (tree type, tree expr)
Check this first since if expr_type is the unknown_type_node
we would otherwise complain below. */
;
- else if (TYPE_PTRMEM_P (expr_type)
- || TYPE_PTRMEMFUNC_P (expr_type))
+ else if (TYPE_PTR_TO_MEMBER_P (expr_type))
{
if (TREE_CODE (expr) != PTRMEM_CST)
goto bad_argument;
}
else if (TYPE_PTR_P (expr_type)
- || TYPE_PTRMEM_P (expr_type)
|| TREE_CODE (expr_type) == ARRAY_TYPE
|| TREE_CODE (type) == REFERENCE_TYPE
/* If expr is the address of an overloaded function, we
@@ -3082,8 +3043,7 @@ convert_nontype_argument (tree type, tree expr)
else
error ("it must be the address of an object with external linkage");
}
- else if (TYPE_PTRMEM_P (expr_type)
- || TYPE_PTRMEMFUNC_P (expr_type))
+ else if (TYPE_PTR_TO_MEMBER_P (expr_type))
error ("it must be a pointer-to-member of the form `&X::Y'");
return NULL_TREE;
@@ -3100,6 +3060,9 @@ convert_nontype_argument (tree type, tree expr)
return NULL_TREE;
}
+ if (TREE_CODE (referent) == SCOPE_REF)
+ referent = TREE_OPERAND (referent, 1);
+
if (is_overloaded_fn (referent))
/* We'll check that it has external linkage later. */
;
@@ -3111,9 +3074,7 @@ convert_nontype_argument (tree type, tree expr)
return error_mark_node;
}
}
- else if (INTEGRAL_TYPE_P (expr_type)
- || TYPE_PTRMEM_P (expr_type)
- || TYPE_PTRMEMFUNC_P (expr_type))
+ else if (INTEGRAL_TYPE_P (expr_type) || TYPE_PTR_TO_MEMBER_P (expr_type))
{
if (! TREE_CONSTANT (expr))
{
@@ -3125,7 +3086,14 @@ convert_nontype_argument (tree type, tree expr)
}
else
{
- error ("object `%E' cannot be used as template argument", expr);
+ if (TYPE_P (expr))
+ error ("type '%T' cannot be used as a value for a non-type "
+ "template-parameter", expr);
+ else if (DECL_P (expr))
+ error ("invalid use of '%D' as a non-type template-argument", expr);
+ else
+ error ("invalid use of '%E' as a non-type template-argument", expr);
+
return NULL_TREE;
}
@@ -3151,31 +3119,32 @@ convert_nontype_argument (tree type, tree expr)
goto non_constant;
return expr;
-
+
+ case OFFSET_TYPE:
+ {
+ tree e;
+
+ /* For a non-type template-parameter of type pointer to data
+ member, qualification conversions (_conv.qual_) are
+ applied. */
+ e = perform_qualification_conversions (type, expr);
+ if (TREE_CODE (e) == NOP_EXPR)
+ /* The call to perform_qualification_conversions will
+ insert a NOP_EXPR over EXPR to do express conversion,
+ if necessary. But, that will confuse us if we use
+ this (converted) template parameter to instantiate
+ another template; then the thing will not look like a
+ valid template argument. So, just make a new
+ constant, of the appropriate type. */
+ e = make_ptrmem_cst (type, PTRMEM_CST_MEMBER (expr));
+ return e;
+ }
+
case POINTER_TYPE:
{
tree type_pointed_to = TREE_TYPE (type);
- if (TYPE_PTRMEM_P (type))
- {
- tree e;
-
- /* For a non-type template-parameter of type pointer to data
- member, qualification conversions (_conv.qual_) are
- applied. */
- e = perform_qualification_conversions (type, expr);
- if (TREE_CODE (e) == NOP_EXPR)
- /* The call to perform_qualification_conversions will
- insert a NOP_EXPR over EXPR to do express conversion,
- if necessary. But, that will confuse us if we use
- this (converted) template parameter to instantiate
- another template; then the thing will not look like a
- valid template argument. So, just make a new
- constant, of the appropriate type. */
- e = make_ptrmem_cst (type, PTRMEM_CST_MEMBER (expr));
- return e;
- }
- else if (TREE_CODE (type_pointed_to) == FUNCTION_TYPE)
+ if (TREE_CODE (type_pointed_to) == FUNCTION_TYPE)
{
/* For a non-type template-parameter of type pointer to
function, only the function-to-pointer conversion
@@ -3239,9 +3208,12 @@ convert_nontype_argument (tree type, tree expr)
tree type_referred_to = TREE_TYPE (type);
/* If this expression already has reference type, get the
- underling object. */
+ underlying object. */
if (TREE_CODE (expr_type) == REFERENCE_TYPE)
{
+ if (TREE_CODE (expr) == NOP_EXPR
+ && TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
+ STRIP_NOPS (expr);
my_friendly_assert (TREE_CODE (expr) == ADDR_EXPR, 20000604);
expr = TREE_OPERAND (expr, 0);
expr_type = TREE_TYPE (expr);
@@ -3295,7 +3267,7 @@ convert_nontype_argument (tree type, tree expr)
}
cxx_mark_addressable (expr);
- return build1 (ADDR_EXPR, type, expr);
+ return build_nop (type, build_address (expr));
}
break;
@@ -3409,9 +3381,8 @@ coerce_template_template_parms (tree parm_parms,
tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
- if (!coerce_template_template_parms (parmparm, argparm,
- complain, in_decl,
- outer_args))
+ if (!coerce_template_template_parms
+ (parmparm, argparm, complain, in_decl, outer_args))
return 0;
}
break;
@@ -3420,9 +3391,9 @@ coerce_template_template_parms (tree parm_parms,
/* The tsubst call is used to handle cases such as
template <class T, template <T> class TT> class D;
i.e. the parameter list of TT depends on earlier parameters. */
- if (!same_type_p (tsubst (TREE_TYPE (parm), outer_args,
- complain, in_decl),
- TREE_TYPE (arg)))
+ if (!same_type_p
+ (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl),
+ TREE_TYPE (arg)))
return 0;
break;
@@ -3455,8 +3426,7 @@ convert_template_argument (tree parm,
inner_args = INNERMOST_TEMPLATE_ARGS (args);
if (TREE_CODE (arg) == TREE_LIST
- && TREE_TYPE (arg) != NULL_TREE
- && TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
+ && TREE_CODE (TREE_VALUE (arg)) == OFFSET_REF)
{
/* The template argument was the name of some
member function. That's usually
@@ -3471,33 +3441,15 @@ convert_template_argument (tree parm,
requires_type = (TREE_CODE (parm) == TYPE_DECL
|| requires_tmpl_type);
- if (TREE_CODE (arg) != RECORD_TYPE)
- is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL
- && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
- || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
- || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
- else if (CLASSTYPE_TEMPLATE_INFO (arg) && !CLASSTYPE_USE_TEMPLATE (arg)
- && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg)))
- {
- if (is_base_of_enclosing_class (arg, current_class_type))
- /* This is a template name used within the scope of the
- template. It could be the template, or it could be the
- instantiation. Choose whichever makes sense. */
- is_tmpl_type = requires_tmpl_type;
- else
- is_tmpl_type = 1;
- }
- else
- /* It is a non-template class, or a specialization of a template
- class, or a non-template member of a template class. */
- is_tmpl_type = 0;
+ is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL
+ && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
+ || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
if (is_tmpl_type
&& (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE))
arg = TYPE_STUB_DECL (arg);
- else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE)
- arg = CLASSTYPE_TI_TEMPLATE (arg);
is_type = TYPE_P (arg) || is_tmpl_type;
@@ -3641,7 +3593,7 @@ coerce_template_parms (tree parms,
tree new_inner_args;
inner_args = INNERMOST_TEMPLATE_ARGS (args);
- nargs = NUM_TMPL_ARGS (inner_args);
+ nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
nparms = TREE_VEC_LENGTH (parms);
if (nargs > nparms
@@ -3672,39 +3624,18 @@ coerce_template_parms (tree parms,
parm = TREE_VEC_ELT (parms, i);
/* Calculate the Ith argument. */
- if (inner_args && TREE_CODE (inner_args) == TREE_LIST)
- {
- arg = TREE_VALUE (inner_args);
- inner_args = TREE_CHAIN (inner_args);
- }
- else if (i < nargs)
+ if (i < nargs)
arg = TREE_VEC_ELT (inner_args, i);
- /* If no template argument was supplied, look for a default
- value. */
- else if (TREE_PURPOSE (parm) == NULL_TREE)
- {
- /* There was no default value. */
- my_friendly_assert (!require_all_arguments, 0);
- break;
- }
- else if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL)
- arg = tsubst (TREE_PURPOSE (parm), new_args, complain, in_decl);
+ else if (require_all_arguments)
+ /* There must be a default arg in this case. */
+ arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args,
+ complain, in_decl);
else
- arg = tsubst_expr (TREE_PURPOSE (parm), new_args, complain,
- in_decl);
-
- /* Now, convert the Ith argument, as necessary. */
- if (arg == NULL_TREE)
- /* We're out of arguments. */
- {
- my_friendly_assert (!require_all_arguments, 0);
- break;
- }
- else if (arg == error_mark_node)
- {
- error ("template argument %d is invalid", i + 1);
- arg = error_mark_node;
- }
+ break;
+
+ my_friendly_assert (arg, 20030727);
+ if (arg == error_mark_node)
+ error ("template argument %d is invalid", i + 1);
else
arg = convert_template_argument (TREE_VALUE (parm),
arg, new_args, complain, i,
@@ -3826,13 +3757,6 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
else
my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269);
- if (TREE_CODE (arg) == TREE_LIST)
- {
- /* New list cell was built because old chain link was in
- use. */
- my_friendly_assert (TREE_PURPOSE (arg) == NULL_TREE, 270);
- arg = TREE_VALUE (arg);
- }
/* No need to check arglist against parmlist here; we did that
in coerce_template_parms, called from lookup_template_class. */
cat (expr_as_string (arg, TFF_PLAIN_IDENTIFIER));
@@ -3928,7 +3852,9 @@ lookup_template_function (tree fns, tree arglist)
if (fns == error_mark_node || arglist == error_mark_node)
return error_mark_node;
- if (fns == NULL_TREE)
+ my_friendly_assert (!arglist || TREE_CODE (arglist) == TREE_VEC, 20030726);
+ if (fns == NULL_TREE
+ || TREE_CODE (fns) == FUNCTION_DECL)
{
error ("non-template used as template");
return error_mark_node;
@@ -3937,8 +3863,7 @@ lookup_template_function (tree fns, tree arglist)
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,
+ || TREE_CODE (fns) == IDENTIFIER_NODE,
20020730);
if (BASELINK_P (fns))
@@ -3979,9 +3904,6 @@ maybe_get_template_decl_from_type_decl (tree decl)
parameters, find the desired type.
D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments.
- (Actually ARGLIST may be either a TREE_LIST or a TREE_VEC. It will
- be a TREE_LIST if called directly from the parser, and a TREE_VEC
- otherwise.)
IN_DECL, if non-NULL, is the template declaration we are trying to
instantiate.
@@ -4005,8 +3927,9 @@ lookup_template_class (tree d1,
{
tree template = NULL_TREE, parmlist;
tree t;
-
+
timevar_push (TV_NAME_LOOKUP);
+
if (TREE_CODE (d1) == IDENTIFIER_NODE)
{
if (IDENTIFIER_VALUE (d1)
@@ -4066,11 +3989,10 @@ lookup_template_class (tree d1,
}
if (TREE_CODE (template) != TEMPLATE_DECL
- /* If we're called from the parser, make sure it's a user visible
- template. */
- || ((!arglist || TREE_CODE (arglist) == TREE_LIST)
- && !DECL_TEMPLATE_PARM_P (template)
- && !PRIMARY_TEMPLATE_P (template)))
+ /* Make sure it's a user visible template, if it was named by
+ the user. */
+ || ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (template)
+ && !PRIMARY_TEMPLATE_P (template)))
{
if (complain & tf_error)
{
@@ -4081,6 +4003,8 @@ lookup_template_class (tree d1,
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
+ complain &= ~tf_user;
+
if (DECL_TEMPLATE_TEMPLATE_PARM_P (template))
{
/* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store
@@ -4314,7 +4238,6 @@ lookup_template_class (tree d1,
t = make_aggr_type (TREE_CODE (template_type));
CLASSTYPE_DECLARED_CLASS (t)
= CLASSTYPE_DECLARED_CLASS (template_type);
- CLASSTYPE_GOT_SEMICOLON (t) = 1;
SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);
TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA (template_type);
@@ -4611,7 +4534,6 @@ for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d)
case ARROW_EXPR:
case DOTSTAR_EXPR:
case TYPEID_EXPR:
- case LOOKUP_EXPR:
case PSEUDO_DTOR_EXPR:
if (!fn)
return error_mark_node;
@@ -4944,8 +4866,9 @@ tsubst_friend_function (tree decl, tree args)
DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info;
if (TREE_CODE (old_decl) != TEMPLATE_DECL)
- /* duplicate_decls will take care of this case. */
- ;
+ reregister_specialization (new_friend,
+ most_general_template (old_decl),
+ old_decl);
else
{
tree t;
@@ -5077,6 +5000,8 @@ tsubst_friend_class (tree friend_tmpl, tree args)
DECL_USE_TEMPLATE (tmpl) = 0;
DECL_TEMPLATE_INFO (tmpl) = NULL_TREE;
CLASSTYPE_USE_TEMPLATE (TREE_TYPE (tmpl)) = 0;
+ CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl))
+ = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl)));
/* Inject this template into the global scope. */
friend_type = TREE_TYPE (pushdecl_top_level (tmpl));
@@ -5105,7 +5030,8 @@ can_complete_type_without_circularity (tree type)
return 1;
else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
return can_complete_type_without_circularity (TREE_TYPE (type));
- else if (CLASS_TYPE_P (type) && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type)))
+ else if (CLASS_TYPE_P (type)
+ && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type)))
return 0;
else
return 1;
@@ -5144,8 +5070,7 @@ instantiate_class_template (tree type)
for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t;
t = TREE_CHAIN (t))
{
- if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t),
- args))
+ if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args))
{
cp_error_at ("%s %+#T", str, TREE_TYPE (t));
str = " ";
@@ -5226,11 +5151,12 @@ instantiate_class_template (tree type)
SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
}
+ /* Set the input location to the template definition. This is needed
+ if tsubsting causes an error. */
+ input_location = DECL_SOURCE_LOCATION (TYPE_NAME (pattern));
+
TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
TYPE_HAS_DESTRUCTOR (type) = TYPE_HAS_DESTRUCTOR (pattern);
- TYPE_OVERLOADS_CALL_EXPR (type) = TYPE_OVERLOADS_CALL_EXPR (pattern);
- TYPE_OVERLOADS_ARRAY_REF (type) = TYPE_OVERLOADS_ARRAY_REF (pattern);
- TYPE_OVERLOADS_ARROW (type) = TYPE_OVERLOADS_ARROW (pattern);
TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern);
TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern);
@@ -5261,8 +5187,14 @@ instantiate_class_template (tree type)
tree base_list = NULL_TREE;
tree pbases = BINFO_BASETYPES (pbinfo);
tree paccesses = BINFO_BASEACCESSES (pbinfo);
+ tree context = TYPE_CONTEXT (type);
int i;
+ /* We must enter the scope containing the type, as that is where
+ the accessibility of types named in dependent bases are
+ looked up from. */
+ push_scope (context ? context : global_namespace);
+
/* Substitute into each of the bases to determine the actual
basetypes. */
for (i = 0; i < TREE_VEC_LENGTH (pbases); ++i)
@@ -5289,6 +5221,8 @@ instantiate_class_template (tree type)
/* Now call xref_basetypes to set up all the base-class
information. */
xref_basetypes (type, base_list);
+
+ pop_scope (context ? context : global_namespace);
}
/* Now that our base classes are set up, enter the scope of the
@@ -5296,10 +5230,11 @@ instantiate_class_template (tree type)
correctly. This is precisely analogous to what we do in
begin_class_definition when defining an ordinary non-template
class. */
- pushclass (type, true);
+ pushclass (type);
/* Now members are processed in the order of declaration. */
- for (member = CLASSTYPE_DECL_LIST (pattern); member; member = TREE_CHAIN (member))
+ for (member = CLASSTYPE_DECL_LIST (pattern);
+ member; member = TREE_CHAIN (member))
{
tree t = TREE_VALUE (member);
@@ -5320,12 +5255,14 @@ instantiate_class_template (tree 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.) */
+ 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
@@ -5342,8 +5279,13 @@ instantiate_class_template (tree type)
|| DECL_FUNCTION_TEMPLATE_P (t))
{
/* Build new TYPE_METHODS. */
-
- tree r = tsubst (t, args, tf_error, NULL_TREE);
+ tree r;
+
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ processing_template_decl++;
+ r = tsubst (t, args, tf_error, NULL_TREE);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ processing_template_decl--;
set_current_access_from_decl (r);
grok_special_member_properties (r);
finish_member_declaration (r);
@@ -5362,7 +5304,11 @@ instantiate_class_template (tree type)
restore these. */
input_location = DECL_SOURCE_LOCATION (t);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ processing_template_decl++;
r = tsubst (t, args, tf_error | tf_warning, NULL_TREE);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ processing_template_decl--;
if (TREE_CODE (r) == VAR_DECL)
{
tree init;
@@ -5373,9 +5319,8 @@ instantiate_class_template (tree type)
else
init = NULL_TREE;
- finish_static_data_member_decl (r, init,
- /*asmspec_tree=*/NULL_TREE,
- /*flags=*/0);
+ finish_static_data_member_decl
+ (r, init, /*asmspec_tree=*/NULL_TREE, /*flags=*/0);
if (DECL_INITIALIZED_IN_CLASS_P (r))
check_static_variable_definition (r, TREE_TYPE (r));
@@ -5448,14 +5393,16 @@ instantiate_class_template (tree type)
++processing_template_decl;
if (new_friend_type != error_mark_node)
- make_friend_class (type, new_friend_type);
+ make_friend_class (type, new_friend_type,
+ /*complain=*/false);
if (TREE_CODE (friend_type) == TEMPLATE_DECL)
--processing_template_decl;
}
else
/* Build new DECL_FRIENDLIST. */
- add_friend (type, tsubst_friend_function (t, args));
+ add_friend (type, tsubst_friend_function (t, args),
+ /*complain=*/false);
}
}
@@ -5468,7 +5415,6 @@ instantiate_class_template (tree type)
unreverse_member_declarations (type);
finish_struct_1 (type);
- CLASSTYPE_GOT_SEMICOLON (type) = 1;
/* Clear this now so repo_template_used is happy. */
TYPE_BEING_DEFINED (type) = 0;
@@ -5497,108 +5443,78 @@ instantiate_class_template (tree type)
return type;
}
-static int
-list_eq (tree t1, tree t2)
-{
- if (t1 == NULL_TREE)
- return t2 == NULL_TREE;
- if (t2 == NULL_TREE)
- return 0;
- /* Don't care if one declares its arg const and the other doesn't -- the
- main variant of the arg type is all that matters. */
- if (TYPE_MAIN_VARIANT (TREE_VALUE (t1))
- != TYPE_MAIN_VARIANT (TREE_VALUE (t2)))
- return 0;
- return list_eq (TREE_CHAIN (t1), TREE_CHAIN (t2));
-}
-
-/* If arg is a non-type template parameter that does not depend on template
- arguments, fold it like we weren't in the body of a template. */
-
static tree
-maybe_fold_nontype_arg (tree arg)
+tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
- if (arg && !TYPE_P (arg) && !uses_template_parms (arg))
+ tree r;
+
+ if (!t)
+ r = t;
+ else if (TYPE_P (t))
+ r = tsubst (t, args, complain, in_decl);
+ else
{
- /* Sometimes, one of the args was an expression involving a
- template constant parameter, like N - 1. Now that we've
- tsubst'd, we might have something like 2 - 1. This will
- confuse lookup_template_class, so we do constant folding
- here. We have to unset processing_template_decl, to fool
- tsubst_copy_and_build() into building an actual tree. */
+ r = tsubst_expr (t, args, complain, in_decl);
- /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
- as simple as it's going to get, and trying to reprocess
- the trees will break. */
- if (!TREE_TYPE (arg))
+ if (!uses_template_parms (r))
{
- int saved_processing_template_decl = processing_template_decl;
- processing_template_decl = 0;
- arg = tsubst_copy_and_build (arg,
- /*args=*/NULL_TREE,
- tf_error,
- /*in_decl=*/NULL_TREE);
- processing_template_decl = saved_processing_template_decl;
- }
+ /* Sometimes, one of the args was an expression involving a
+ template constant parameter, like N - 1. Now that we've
+ tsubst'd, we might have something like 2 - 1. This will
+ confuse lookup_template_class, so we do constant folding
+ here. We have to unset processing_template_decl, to fool
+ tsubst_copy_and_build() into building an actual tree. */
- arg = fold (arg);
- }
- return arg;
-}
-
-/* Apply maybe_fold_nontype_arg on a list or vector of args. */
-
-static void
-maybe_fold_nontype_args (tree targs)
-{
- if (!targs)
- /*OK*/;
- else if (TREE_CODE (targs) == TREE_LIST)
- {
- tree chain;
- for (chain = targs; chain; chain = TREE_CHAIN (chain))
- TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain));
- }
- else
- {
- int i;
- for (i = 0; i < TREE_VEC_LENGTH (targs); ++i)
- TREE_VEC_ELT (targs, i)
- = maybe_fold_nontype_arg (TREE_VEC_ELT (targs, i));
+ /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
+ as simple as it's going to get, and trying to reprocess
+ the trees will break. Once tsubst_expr et al DTRT for
+ non-dependent exprs, this code can go away, as the type
+ will always be set. */
+ if (!TREE_TYPE (r))
+ {
+ int saved_processing_template_decl = processing_template_decl;
+ processing_template_decl = 0;
+ r = tsubst_copy_and_build (r, /*args=*/NULL_TREE,
+ tf_error, /*in_decl=*/NULL_TREE,
+ /*function_p=*/false);
+ processing_template_decl = saved_processing_template_decl;
+ }
+ r = fold (r);
+ }
}
+ return r;
}
-/* Substitute ARGS into the vector of template arguments T. */
+/* Substitute ARGS into the vector or list of template arguments T. */
static tree
-tsubst_template_arg_vector (tree t, tree args, tsubst_flags_t complain)
+tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
- int len = TREE_VEC_LENGTH (t), need_new = 0, i;
- tree *elts = (tree *) alloca (len * sizeof (tree));
-
- memset ((char *) elts, 0, len * sizeof (tree));
+ int len = TREE_VEC_LENGTH (t);
+ int need_new = 0, i;
+ tree *elts = alloca (len * sizeof (tree));
for (i = 0; i < len; i++)
{
- if (TREE_VEC_ELT (t, i) != NULL_TREE
- && TREE_CODE (TREE_VEC_ELT (t, i)) == TREE_VEC)
- elts[i] = tsubst_template_arg_vector (TREE_VEC_ELT (t, i),
- args, complain);
+ tree orig_arg = TREE_VEC_ELT (t, i);
+ tree new_arg;
+
+ if (TREE_CODE (orig_arg) == TREE_VEC)
+ new_arg = tsubst_template_args (orig_arg, args, complain, in_decl);
else
- elts[i] = maybe_fold_nontype_arg
- (tsubst_expr (TREE_VEC_ELT (t, i), args, complain,
- NULL_TREE));
+ new_arg = tsubst_template_arg (orig_arg, args, complain, in_decl);
- if (elts[i] == error_mark_node)
+ if (new_arg == error_mark_node)
return error_mark_node;
- if (elts[i] != TREE_VEC_ELT (t, i))
+ elts[i] = new_arg;
+ if (new_arg != orig_arg)
need_new = 1;
}
if (!need_new)
return t;
-
+
t = make_tree_vec (len);
for (i = 0; i < len; i++)
TREE_VEC_ELT (t, i) = elts[i];
@@ -5635,10 +5551,10 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
tree parm_decl = TREE_VALUE (tuple);
parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
- default_value = tsubst_expr (default_value, args,
- complain, NULL_TREE);
- tuple = build_tree_list (maybe_fold_nontype_arg (default_value),
- parm_decl);
+ default_value = tsubst_template_arg (default_value, args,
+ complain, NULL_TREE);
+
+ tuple = build_tree_list (default_value, parm_decl);
TREE_VEC_ELT (new_vec, i) = tuple;
}
@@ -5684,12 +5600,10 @@ tsubst_aggr_type (tree t,
/* First, determine the context for the type we are looking
up. */
- if (TYPE_CONTEXT (t) != NULL_TREE)
- context = tsubst_aggr_type (TYPE_CONTEXT (t), args,
- complain,
+ context = TYPE_CONTEXT (t);
+ if (context)
+ context = tsubst_aggr_type (context, args, complain,
in_decl, /*entering_scope=*/1);
- else
- context = NULL_TREE;
/* Then, figure out what arguments are appropriate for the
type we are trying to find. For example, given:
@@ -5700,8 +5614,8 @@ tsubst_aggr_type (tree t,
and supposing that we are instantiating f<int, double>,
then our ARGS will be {int, double}, but, when looking up
S we only want {double}. */
- argvec = tsubst_template_arg_vector (TYPE_TI_ARGS (t), args,
- complain);
+ argvec = tsubst_template_args (TYPE_TI_ARGS (t), args,
+ complain, in_decl);
if (argvec == error_mark_node)
return error_mark_node;
@@ -5817,10 +5731,10 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
: DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t));
tree full_args;
- full_args = tsubst_template_arg_vector (tmpl_args, args,
- complain);
+ full_args = tsubst_template_args (tmpl_args, args,
+ complain, in_decl);
- /* tsubst_template_arg_vector doesn't copy the vector if
+ /* tsubst_template_args doesn't copy the vector if
nothing changed. But, *something* should have
changed. */
my_friendly_assert (full_args != tmpl_args, 0);
@@ -5867,6 +5781,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
else
{
tree new_decl = tsubst (decl, args, complain, in_decl);
+ if (new_decl == error_mark_node)
+ return error_mark_node;
DECL_TEMPLATE_RESULT (r) = new_decl;
DECL_TI_TEMPLATE (new_decl) = r;
@@ -5888,14 +5804,10 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
if (PRIMARY_TEMPLATE_P (t))
DECL_PRIMARY_TEMPLATE (r) = r;
- /* We don't partially instantiate partial specializations. */
- if (TREE_CODE (decl) == TYPE_DECL)
- break;
-
- /* Record this partial instantiation. */
- register_specialization (r, t,
- DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)));
-
+ if (TREE_CODE (decl) != TYPE_DECL)
+ /* Record this non-type partial instantiation. */
+ register_specialization (r, t,
+ DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)));
}
break;
@@ -5931,10 +5843,9 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
specialization, and the complete set of arguments used to
specialize R. */
gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t));
- argvec
- = tsubst_template_arg_vector (DECL_TI_ARGS
- (DECL_TEMPLATE_RESULT (gen_tmpl)),
- args, complain);
+ argvec = tsubst_template_args (DECL_TI_ARGS
+ (DECL_TEMPLATE_RESULT (gen_tmpl)),
+ args, complain, in_decl);
/* Check to see if we already have this specialization. */
spec = retrieve_specialization (gen_tmpl, argvec);
@@ -5993,10 +5904,10 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
};
Here, the DECL_TI_TEMPLATE for the friend declaration
- will be a LOOKUP_EXPR or an IDENTIFIER_NODE. We are
- being called from tsubst_friend_function, and we want
- only to create a new decl (R) with appropriate types so
- that we can call determine_specialization. */
+ will be an IDENTIFIER_NODE. We are being called from
+ tsubst_friend_function, and we want only to create a
+ new decl (R) with appropriate types so that we can call
+ determine_specialization. */
gen_tmpl = NULL_TREE;
}
@@ -6007,8 +5918,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
else
member = 1;
ctx = tsubst_aggr_type (DECL_CONTEXT (t), args,
- complain, t,
- /*entering_scope=*/1);
+ complain, t, /*entering_scope=*/1);
}
else
{
@@ -6109,7 +6019,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
clone_function_decl (r, /*update_method_vec_p=*/0);
}
else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
- grok_op_properties (r, DECL_FRIEND_P (r));
+ grok_op_properties (r, DECL_FRIEND_P (r),
+ (complain & tf_error) != 0);
}
break;
@@ -6122,11 +6033,14 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
TREE_TYPE (r) = type;
c_apply_type_quals_to_decl (cp_type_quals (type), r);
- if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
- DECL_INITIAL (r) = TREE_TYPE (r);
- else
- DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
- complain, in_decl);
+ if (DECL_INITIAL (r))
+ {
+ if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
+ DECL_INITIAL (r) = TREE_TYPE (r);
+ else
+ DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
+ complain, in_decl);
+ }
DECL_CONTEXT (r) = NULL_TREE;
@@ -6157,6 +6071,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
case USING_DECL:
{
r = copy_node (t);
+ /* It is not a dependent using decl any more. */
+ TREE_TYPE (r) = void_type_node;
DECL_INITIAL (r)
= tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
TREE_CHAIN (r) = NULL_TREE;
@@ -6221,7 +6137,13 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
r = copy_decl (t);
if (TREE_CODE (r) == VAR_DECL)
- type = complete_type (type);
+ {
+ type = complete_type (type);
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
+ = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t);
+ }
+ else if (DECL_SELF_REFERENCE_P (t))
+ SET_DECL_SELF_REFERENCE_P (r);
TREE_TYPE (r) = type;
c_apply_type_quals_to_decl (cp_type_quals (type), r);
DECL_CONTEXT (r) = ctx;
@@ -6383,8 +6305,8 @@ tsubst_function_type (tree t,
return error_mark_node;
}
- fntype = build_cplus_method_type (r, return_type, TREE_CHAIN
- (arg_types));
+ fntype = build_method_type_directly (r, return_type,
+ TREE_CHAIN (arg_types));
}
fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain);
fntype = build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
@@ -6460,8 +6382,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
type = IDENTIFIER_TYPE_VALUE (t);
else
type = TREE_TYPE (t);
- if (type == unknown_type_node)
- abort ();
+
+ my_friendly_assert (type != unknown_type_node, 20030716);
if (type && TREE_CODE (t) != FUNCTION_DECL
&& TREE_CODE (t) != TYPENAME_TYPE
@@ -6507,12 +6429,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
- max = tsubst_expr (omax, args, complain, in_decl);
- if (max == error_mark_node)
- return error_mark_node;
-
- /* See if we can reduce this expression to something simpler. */
- max = maybe_fold_nontype_arg (max);
+ /* The array dimension behaves like a non-type template arg,
+ in that we want to fold it as much as possible. */
+ max = tsubst_template_arg (omax, args, complain, in_decl);
if (!processing_template_decl)
max = decl_constant_value (max);
@@ -6756,7 +6675,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
}
/* Otherwise, a vector of template arguments. */
- return tsubst_template_arg_vector (t, args, complain);
+ return tsubst_template_args (t, args, complain, in_decl);
case POINTER_TYPE:
case REFERENCE_TYPE:
@@ -6841,21 +6760,28 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
}
my_friendly_assert (TREE_CODE (type) != METHOD_TYPE, 20011231);
if (TREE_CODE (type) == FUNCTION_TYPE)
- /* This is really a method type. The cv qualifiers of the
- this pointer should _not_ be determined by the cv
- qualifiers of the class type. They should be held
- somewhere in the FUNCTION_TYPE, but we don't do that at
- the moment. Consider
- typedef void (Func) () const;
-
- template <typename T1> void Foo (Func T1::*);
-
- */
- return build_cplus_method_type (TYPE_MAIN_VARIANT (r),
- TREE_TYPE (type),
- TYPE_ARG_TYPES (type));
+ {
+ /* This is really a method type. The cv qualifiers of the
+ this pointer should _not_ be determined by the cv
+ qualifiers of the class type. They should be held
+ somewhere in the FUNCTION_TYPE, but we don't do that at
+ the moment. Consider
+ typedef void (Func) () const;
+
+ template <typename T1> void Foo (Func T1::*);
+
+ */
+ tree method_type;
+
+ method_type = build_method_type_directly (TYPE_MAIN_VARIANT (r),
+ TREE_TYPE (type),
+ TYPE_ARG_TYPES (type));
+ return build_ptrmemfunc_type (build_pointer_type (method_type));
+ }
else
- return build_offset_type (r, type);
+ return cp_build_qualified_type_real (build_ptrmem_type (r, type),
+ TYPE_QUALS (t),
+ complain);
}
case FUNCTION_TYPE:
case METHOD_TYPE:
@@ -7104,8 +7030,9 @@ tsubst_baselink (tree baselink, tree object_type,
template_id_p = true;
template_args = TREE_OPERAND (fns, 1);
fns = TREE_OPERAND (fns, 0);
- template_args = tsubst_copy_and_build (template_args, args,
- complain, in_decl);
+ if (template_args)
+ template_args = tsubst_template_args (template_args, args,
+ complain, in_decl);
}
name = DECL_NAME (get_first_fn (fns));
baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
@@ -7140,17 +7067,15 @@ tsubst_qualified_id (tree qualified_id, tree args,
my_friendly_assert (TREE_CODE (qualified_id) == SCOPE_REF, 20030706);
- /* Look up the qualified name. */
- scope = TREE_OPERAND (qualified_id, 0);
- scope = tsubst (scope, args, complain, in_decl);
-
/* Figure out what name to look up. */
name = TREE_OPERAND (qualified_id, 1);
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
{
is_template = true;
- template_args = tsubst_copy_and_build (TREE_OPERAND (name, 1),
- args, complain, in_decl);
+ template_args = TREE_OPERAND (name, 1);
+ if (template_args)
+ template_args = tsubst_template_args (template_args, args,
+ complain, in_decl);
name = TREE_OPERAND (name, 0);
}
else
@@ -7159,24 +7084,52 @@ tsubst_qualified_id (tree qualified_id, tree args,
template_args = NULL_TREE;
}
- expr = tsubst_copy (name, args, complain, in_decl);
- if (!BASELINK_P (name))
+ /* Substitute into the qualifying scope. When there are no ARGS, we
+ are just trying to simplify a non-dependent expression. In that
+ case the qualifying scope may be dependent, and, in any case,
+ substituting will not help. */
+ scope = TREE_OPERAND (qualified_id, 0);
+ if (args)
{
- expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0);
- if (DECL_P (expr))
- check_accessibility_of_qualified_id (expr,
- /*object_type=*/NULL_TREE,
- scope);
+ scope = tsubst (scope, args, complain, in_decl);
+ expr = tsubst_copy (name, args, complain, in_decl);
}
+ else
+ expr = name;
+ my_friendly_assert (!dependent_type_p (scope), 20030729);
+
+ if (!BASELINK_P (name) && !DECL_P (expr))
+ {
+ expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false);
+ if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL
+ ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL)
+ {
+ if (complain & tf_error)
+ error ("`%E' names a type, but a non-type is expected",
+ qualified_id);
+ return error_mark_node;
+ }
+ }
+
+ if (DECL_P (expr))
+ check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE,
+ scope);
+
/* Remember that there was a reference to this entity. */
if (DECL_P (expr))
- mark_used (expr);
+ {
+ mark_used (expr);
+ if (!args && TREE_CODE (expr) == VAR_DECL)
+ expr = DECL_INITIAL (expr);
+ }
if (is_template)
- lookup_template_function (expr, template_args);
+ expr = lookup_template_function (expr, template_args);
- if (TYPE_P (scope))
+ if (expr == error_mark_node && complain & tf_error)
+ qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1));
+ else if (TYPE_P (scope))
{
expr = (adjust_result_of_qualified_name_lookup
(expr, scope, current_class_type));
@@ -7215,8 +7168,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (DECL_TEMPLATE_PARM_P (t))
return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
- if (!DECL_CONTEXT (t))
- /* This is a global enumeration constant. */
+ /* There is no need to substitute into namespace-scope
+ enumerators. */
+ if (DECL_NAMESPACE_SCOPE_P (t))
return t;
/* Unfortunately, we cannot just call lookup_name here.
@@ -7300,25 +7254,6 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
/* Ordinary template template argument. */
return t;
- case LOOKUP_EXPR:
- {
- /* We must tsubst into a LOOKUP_EXPR in case the names to
- which it refers is a conversion operator; in that case the
- name will change. We avoid making unnecessary copies,
- however. */
-
- tree id = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
-
- if (id != TREE_OPERAND (t, 0))
- {
- r = build_nt (LOOKUP_EXPR, id);
- LOOKUP_EXPR_GLOBAL (r) = LOOKUP_EXPR_GLOBAL (t);
- t = r;
- }
-
- return t;
- }
-
case CAST_EXPR:
case REINTERPRET_CAST_EXPR:
case CONST_CAST_EXPR:
@@ -7389,7 +7324,6 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
case BIT_AND_EXPR:
- case BIT_ANDTC_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
case TRUNC_MOD_EXPR:
@@ -7439,8 +7373,10 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (!processing_template_decl)
{
tree stmt_expr = begin_stmt_expr ();
- tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl);
- return finish_stmt_expr (stmt_expr);
+
+ tsubst_expr (STMT_EXPR_STMT (t), args,
+ complain | tf_stmt_expr_cmpd, in_decl);
+ return finish_stmt_expr (stmt_expr, false);
}
return t;
@@ -7479,12 +7415,14 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
case TEMPLATE_ID_EXPR:
{
/* Substituted template arguments */
- tree targs = tsubst_copy (TREE_OPERAND (t, 1), args, complain,
- in_decl);
+ tree fn = TREE_OPERAND (t, 0);
+ tree targs = TREE_OPERAND (t, 1);
- maybe_fold_nontype_args (targs);
- return lookup_template_function
- (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), targs);
+ fn = tsubst_copy (fn, args, complain, in_decl);
+ if (targs)
+ targs = tsubst_template_args (targs, args, complain, in_decl);
+
+ return lookup_template_function (fn, targs);
}
case TREE_LIST:
@@ -7565,7 +7503,10 @@ static tree
tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
tree stmt, tmp;
+ tsubst_flags_t stmt_expr
+ = complain & (tf_stmt_expr_cmpd | tf_stmt_expr_body);
+ complain ^= stmt_expr;
if (t == NULL_TREE || t == error_mark_node)
return t;
@@ -7573,7 +7514,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return tsubst_copy (t, args, complain, in_decl);
if (!STATEMENT_CODE_P (TREE_CODE (t)))
- return tsubst_copy_and_build (t, args, complain, in_decl);
+ return tsubst_copy_and_build (t, args, complain, in_decl,
+ /*function_p=*/false);
switch (TREE_CODE (t))
{
@@ -7590,10 +7532,18 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
break;
case EXPR_STMT:
- prep_stmt (t);
- finish_expr_stmt (tsubst_expr (EXPR_STMT_EXPR (t),
- args, complain, in_decl));
- break;
+ {
+ tree r;
+
+ prep_stmt (t);
+
+ r = tsubst_expr (EXPR_STMT_EXPR (t), args, complain, in_decl);
+ if (stmt_expr & tf_stmt_expr_body && !TREE_CHAIN (t))
+ finish_stmt_expr_expr (r);
+ else
+ finish_expr_stmt (r);
+ break;
+ }
case USING_STMT:
prep_stmt (t);
@@ -7614,11 +7564,16 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
tree scope = DECL_INITIAL (decl);
tree name = DECL_NAME (decl);
+ tree decl;
scope = tsubst_expr (scope, args, complain, in_decl);
- do_local_using_decl (lookup_qualified_name (scope,
- name,
- /*is_type_p=*/0));
+ decl = lookup_qualified_name (scope, name,
+ /*is_type_p=*/false,
+ /*complain=*/false);
+ if (decl == error_mark_node)
+ qualified_name_lookup_error (scope, name);
+ else
+ do_local_using_decl (decl);
}
else
{
@@ -7642,7 +7597,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
else
{
maybe_push_decl (decl);
- if (DECL_PRETTY_FUNCTION_P (decl))
+ if (TREE_CODE (decl) == VAR_DECL
+ && DECL_PRETTY_FUNCTION_P (decl))
{
/* For __PRETTY_FUNCTION__ we have to adjust the
initializer. */
@@ -7740,12 +7696,14 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
else
stmt = begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
- tsubst_expr (COMPOUND_BODY (t), args, complain, in_decl);
+ tsubst_expr (COMPOUND_BODY (t), args,
+ complain | ((stmt_expr & tf_stmt_expr_cmpd) << 1),
+ in_decl);
if (COMPOUND_STMT_BODY_BLOCK (t))
finish_function_body (stmt);
else
- finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), stmt);
+ finish_compound_stmt (stmt);
}
break;
@@ -7878,18 +7836,40 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
abort ();
}
- return tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
+ return tsubst_expr (TREE_CHAIN (t), args, complain | stmt_expr, in_decl);
+}
+
+/* T is a postfix-expression that is not being used in a function
+ call. Return the substituted version of T. */
+
+static tree
+tsubst_non_call_postfix_expression (tree t, tree args,
+ tsubst_flags_t complain,
+ tree in_decl)
+{
+ if (TREE_CODE (t) == SCOPE_REF)
+ t = tsubst_qualified_id (t, args, complain, in_decl,
+ /*done=*/false, /*address_p=*/false);
+ else
+ t = tsubst_copy_and_build (t, args, complain, in_decl,
+ /*function_p=*/false);
+
+ return t;
}
/* Like tsubst but deals with expressions and performs semantic
- analysis. */
+ analysis. FUNCTION_P is true if T is the "F" in "F (ARGS)". */
tree
tsubst_copy_and_build (tree t,
tree args,
tsubst_flags_t complain,
- tree in_decl)
+ tree in_decl,
+ bool function_p)
{
+#define RECUR(NODE) \
+ tsubst_copy_and_build (NODE, args, complain, in_decl, /*function_p=*/false)
+
tree op1;
if (t == NULL_TREE || t == error_mark_node)
@@ -7897,45 +7877,53 @@ tsubst_copy_and_build (tree t,
switch (TREE_CODE (t))
{
+ case USING_DECL:
+ t = DECL_NAME (t);
+ /* Fallthrough. */
case IDENTIFIER_NODE:
- if (IDENTIFIER_TYPENAME_P (t))
- {
- tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
- return do_identifier (mangle_conv_op_name_for_type (new_type),
- NULL_TREE);
- }
- else
- return do_identifier (t, NULL_TREE);
-
- case LOOKUP_EXPR:
{
- if (LOOKUP_EXPR_GLOBAL (t))
- {
- tree token
- = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
- return do_scoped_id (token, IDENTIFIER_GLOBAL_VALUE (token));
- }
- else
+ tree decl;
+ cp_id_kind idk;
+ tree qualifying_class;
+ bool non_constant_expression_p;
+ const char *error_msg;
+
+ if (IDENTIFIER_TYPENAME_P (t))
{
- t = do_identifier
- (tsubst_copy
- (TREE_OPERAND (t, 0), args, complain, in_decl),
- NULL_TREE);
- if (TREE_CODE (t) == ALIAS_DECL)
- t = DECL_INITIAL (t);
- return t;
+ tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ t = mangle_conv_op_name_for_type (new_type);
}
+
+ /* Look up the name. */
+ decl = lookup_name (t, 0);
+
+ /* By convention, expressions use ERROR_MARK_NODE to indicate
+ failure, not NULL_TREE. */
+ if (decl == NULL_TREE)
+ decl = error_mark_node;
+
+ decl = finish_id_expression (t, decl, NULL_TREE,
+ &idk,
+ &qualifying_class,
+ /*constant_expression_p=*/false,
+ /*allow_non_constant_expression_p=*/false,
+ &non_constant_expression_p,
+ &error_msg);
+ if (error_msg)
+ error (error_msg);
+ if (!function_p && TREE_CODE (decl) == IDENTIFIER_NODE)
+ decl = unqualified_name_lookup_error (decl);
+ return decl;
}
case TEMPLATE_ID_EXPR:
{
tree object;
- tree template
- = tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain,
- in_decl);
- tree targs
- = tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain,
- in_decl);
+ tree template = RECUR (TREE_OPERAND (t, 0));
+ tree targs = TREE_OPERAND (t, 1);
+
+ if (targs)
+ targs = tsubst_template_args (targs, args, complain, in_decl);
if (TREE_CODE (template) == COMPONENT_REF)
{
@@ -7954,46 +7942,37 @@ tsubst_copy_and_build (tree t,
}
case INDIRECT_REF:
- return build_x_indirect_ref
- (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl),
- "unary *");
+ return build_x_indirect_ref (RECUR (TREE_OPERAND (t, 0)), "unary *");
case CAST_EXPR:
return build_functional_cast
(tsubst (TREE_TYPE (t), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl));
+ RECUR (TREE_OPERAND (t, 0)));
case REINTERPRET_CAST_EXPR:
return build_reinterpret_cast
(tsubst (TREE_TYPE (t), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl));
+ RECUR (TREE_OPERAND (t, 0)));
case CONST_CAST_EXPR:
return build_const_cast
(tsubst (TREE_TYPE (t), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl));
+ RECUR (TREE_OPERAND (t, 0)));
case DYNAMIC_CAST_EXPR:
return build_dynamic_cast
(tsubst (TREE_TYPE (t), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl));
+ RECUR (TREE_OPERAND (t, 0)));
case STATIC_CAST_EXPR:
return build_static_cast
(tsubst (TREE_TYPE (t), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl));
+ RECUR (TREE_OPERAND (t, 0)));
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
- op1 = TREE_OPERAND (t, 0);
- if (TREE_CODE (op1) == SCOPE_REF)
- op1 = tsubst_qualified_id (TREE_OPERAND (t, 0),
- args, complain,
- in_decl,
- /*done=*/false,
- /*address_p=*/false);
- else
- op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
+ op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
+ args, complain, in_decl);
return build_x_unary_op (TREE_CODE (t), op1);
case PREDECREMENT_EXPR:
@@ -8005,10 +7984,7 @@ tsubst_copy_and_build (tree t,
case CONVERT_EXPR: /* Unary + */
case REALPART_EXPR:
case IMAGPART_EXPR:
- return (build_x_unary_op
- (TREE_CODE (t),
- tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain,
- in_decl)));
+ return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0)));
case ADDR_EXPR:
op1 = TREE_OPERAND (t, 0);
@@ -8016,7 +7992,10 @@ tsubst_copy_and_build (tree t,
op1 = tsubst_qualified_id (op1, args, complain, in_decl,
/*done=*/true, /*address_p=*/true);
else
- op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
+ op1 = tsubst_non_call_postfix_expression (op1, args, complain,
+ in_decl);
+ if (TREE_CODE (op1) == LABEL_DECL)
+ return finish_label_address_expr (DECL_NAME (op1));
return build_x_unary_op (ADDR_EXPR, op1);
case PLUS_EXPR:
@@ -8028,7 +8007,6 @@ tsubst_copy_and_build (tree t,
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
case BIT_AND_EXPR:
- case BIT_ANDTC_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
case TRUNC_MOD_EXPR:
@@ -8050,15 +8028,11 @@ tsubst_copy_and_build (tree t,
case LT_EXPR:
case GT_EXPR:
case MEMBER_REF:
+ case DOTSTAR_EXPR:
return build_x_binary_op
(TREE_CODE (t),
- tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl));
-
- case DOTSTAR_EXPR:
- return build_m_component_ref
- (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl));
+ RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)));
case SCOPE_REF:
return tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true,
@@ -8068,24 +8042,14 @@ tsubst_copy_and_build (tree t,
if (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl)
== NULL_TREE)
/* new-type-id */
- return build_nt
- (ARRAY_REF, NULL_TREE,
- tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain,
- in_decl));
+ return build_nt (ARRAY_REF, NULL_TREE, RECUR (TREE_OPERAND (t, 1)));
- op1 = TREE_OPERAND (t, 0);
- if (TREE_CODE (op1) == SCOPE_REF)
- op1 = tsubst_qualified_id (op1, args, complain, in_decl,
- /*done=*/false, /*address_p=*/false);
- else
- op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
+ op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
+ args, complain, in_decl);
/* Remember that there was a reference to this entity. */
if (DECL_P (op1))
mark_used (op1);
- return grok_array_decl (op1,
- tsubst_copy_and_build (TREE_OPERAND (t, 1),
- args, complain,
- in_decl));
+ return grok_array_decl (op1, RECUR (TREE_OPERAND (t, 1)));
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
@@ -8101,27 +8065,23 @@ tsubst_copy_and_build (tree t,
else
{
++skip_evaluation;
- op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
+ op1 = RECUR (op1);
--skip_evaluation;
}
- if (TREE_CODE (t) == SIZEOF_EXPR)
- return finish_sizeof (op1);
+ if (TYPE_P (op1))
+ return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), true);
else
- return finish_alignof (op1);
+ return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t));
case MODOP_EXPR:
return build_x_modify_expr
- (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl),
+ (RECUR (TREE_OPERAND (t, 0)),
TREE_CODE (TREE_OPERAND (t, 1)),
- tsubst_copy_and_build (TREE_OPERAND (t, 2), args, complain, in_decl));
+ RECUR (TREE_OPERAND (t, 2)));
case ARROW_EXPR:
- op1 = TREE_OPERAND (t, 0);
- if (TREE_CODE (op1) == SCOPE_REF)
- op1 = tsubst_qualified_id (op1, args, complain, in_decl,
- /*done=*/false, /*address_p=*/false);
- else
- op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
+ op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
+ args, complain, in_decl);
/* Remember that there was a reference to this entity. */
if (DECL_P (op1))
mark_used (op1);
@@ -8129,38 +8089,33 @@ tsubst_copy_and_build (tree t,
case NEW_EXPR:
return build_new
- (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 2), args, complain, in_decl),
+ (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
+ RECUR (TREE_OPERAND (t, 2)),
NEW_EXPR_USE_GLOBAL (t));
case DELETE_EXPR:
return delete_sanity
- (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl),
+ (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
DELETE_EXPR_USE_VEC (t),
DELETE_EXPR_USE_GLOBAL (t));
case COMPOUND_EXPR:
- return (build_x_compound_expr
- (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain,
- in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain,
- in_decl)));
+ return build_x_compound_expr (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)));
case CALL_EXPR:
{
tree function;
tree call_args;
- tree koenig_name;
bool qualified_p;
+ bool koenig_p;
function = TREE_OPERAND (t, 0);
- if (TREE_CODE (function) == LOOKUP_EXPR
- && !LOOKUP_EXPR_GLOBAL (function))
- koenig_name = TREE_OPERAND (function, 0);
- else
- koenig_name = NULL_TREE;
+ /* When we parsed the expression, we determined whether or
+ not Koenig lookup should be performed. */
+ koenig_p = KOENIG_LOOKUP_P (t);
if (TREE_CODE (function) == SCOPE_REF)
{
qualified_p = true;
@@ -8174,24 +8129,31 @@ tsubst_copy_and_build (tree t,
&& (TREE_CODE (TREE_OPERAND (function, 1))
== SCOPE_REF));
function = tsubst_copy_and_build (function, args, complain,
- in_decl);
- function = convert_from_reference (function);
+ in_decl,
+ !qualified_p);
+ if (BASELINK_P (function))
+ qualified_p = true;
+ }
+
+ call_args = RECUR (TREE_OPERAND (t, 1));
+
+ if (koenig_p
+ && (is_overloaded_fn (function)
+ || DECL_P (function)
+ || TREE_CODE (function) == IDENTIFIER_NODE))
+ function = perform_koenig_lookup (function, call_args);
+
+ if (TREE_CODE (function) == IDENTIFIER_NODE)
+ {
+ unqualified_name_lookup_error (function);
+ return error_mark_node;
}
/* Remember that there was a reference to this entity. */
if (DECL_P (function))
mark_used (function);
- call_args = tsubst_copy_and_build (TREE_OPERAND (t, 1), args,
- complain, in_decl);
-
- if (BASELINK_P (function))
- qualified_p = 1;
-
- if (call_args != NULL_TREE && koenig_name)
- function = lookup_arg_dependent (koenig_name,
- function,
- call_args);
+ function = convert_from_reference (function);
if (TREE_CODE (function) == OFFSET_REF)
return build_offset_ref_call_from_tree (function, call_args);
@@ -8202,20 +8164,21 @@ tsubst_copy_and_build (tree t,
call_args, NULL_TREE,
qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL));
return finish_call_expr (function, call_args,
- /*disallow_virtual=*/qualified_p);
+ /*disallow_virtual=*/qualified_p,
+ koenig_p);
}
case COND_EXPR:
return build_x_conditional_expr
- (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 2), args, complain, in_decl));
+ (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
+ RECUR (TREE_OPERAND (t, 2)));
case PSEUDO_DTOR_EXPR:
return finish_pseudo_destructor_expr
- (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 1), args, complain, in_decl),
- tsubst_copy_and_build (TREE_OPERAND (t, 2), args, complain, in_decl));
+ (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
+ RECUR (TREE_OPERAND (t, 2)));
case TREE_LIST:
{
@@ -8226,13 +8189,13 @@ tsubst_copy_and_build (tree t,
purpose = TREE_PURPOSE (t);
if (purpose)
- purpose = tsubst_copy_and_build (purpose, args, complain, in_decl);
+ purpose = RECUR (purpose);
value = TREE_VALUE (t);
if (value)
- value = tsubst_copy_and_build (value, args, complain, in_decl);
+ value = RECUR (value);
chain = TREE_CHAIN (t);
if (chain && chain != void_type_node)
- chain = tsubst_copy_and_build (chain, args, complain, in_decl);
+ chain = RECUR (chain);
if (purpose == TREE_PURPOSE (t)
&& value == TREE_VALUE (t)
&& chain == TREE_CHAIN (t))
@@ -8245,13 +8208,8 @@ tsubst_copy_and_build (tree t,
tree object;
tree member;
- object = TREE_OPERAND (t, 0);
- if (TREE_CODE (object) == SCOPE_REF)
- object = tsubst_qualified_id (object, args, complain, in_decl,
- /*done=*/false, /*address_p=*/false);
- else
- object = tsubst_copy_and_build (object, args, complain, in_decl);
-
+ object = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
+ args, complain, in_decl);
/* Remember that there was a reference to this entity. */
if (DECL_P (object))
mark_used (object);
@@ -8286,27 +8244,28 @@ tsubst_copy_and_build (tree t,
scope is. */
tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0);
args = TREE_OPERAND (TREE_OPERAND (member, 1), 1);
- member = lookup_qualified_name (TREE_OPERAND (member, 0),
- tmpl,
- /*is_type=*/0);
+ member = lookup_qualified_name (TREE_OPERAND (member, 0), tmpl,
+ /*is_type_p=*/false,
+ /*complain=*/false);
if (BASELINK_P (member))
BASELINK_FUNCTIONS (member)
= build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
args);
else
{
- error ("`%D' is not a member of `%T'",
- tmpl, TREE_TYPE (object));
+ qualified_name_lookup_error (TREE_TYPE (object), tmpl);
return error_mark_node;
}
}
+ else if (TREE_CODE (member) == FIELD_DECL)
+ return finish_non_static_data_member (member, object, NULL_TREE);
return finish_class_member_access_expr (object, member);
}
case THROW_EXPR:
return build_throw
- (tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain, in_decl));
+ (RECUR (TREE_OPERAND (t, 0)));
case CONSTRUCTOR:
{
@@ -8332,9 +8291,8 @@ tsubst_copy_and_build (tree t,
tree value = TREE_VALUE (elts);
if (purpose && purpose_p)
- purpose
- = tsubst_copy_and_build (purpose, args, complain, in_decl);
- value = tsubst_copy_and_build (value, args, complain, in_decl);
+ purpose = RECUR (purpose);
+ value = RECUR (value);
r = tree_cons (purpose, value, r);
}
@@ -8348,10 +8306,7 @@ tsubst_copy_and_build (tree t,
case TYPEID_EXPR:
{
- tree operand_0
- = tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain,
- in_decl);
-
+ tree operand_0 = RECUR (TREE_OPERAND (t, 0));
if (TYPE_P (operand_0))
return get_typeid (operand_0);
return build_typeid (operand_0);
@@ -8371,14 +8326,15 @@ tsubst_copy_and_build (tree t,
return convert_from_reference (t);
case VA_ARG_EXPR:
- return build_x_va_arg
- (tsubst_copy_and_build
- (TREE_OPERAND (t, 0), args, complain, in_decl),
- tsubst_copy (TREE_TYPE (t), args, complain, in_decl));
+ return build_x_va_arg (RECUR (TREE_OPERAND (t, 0)),
+ tsubst_copy (TREE_TYPE (t), args, complain,
+ in_decl));
default:
return tsubst_copy (t, args, complain, in_decl);
}
+
+#undef RECUR
}
/* Verify that the instantiated ARGS are valid. For type arguments,
@@ -8497,18 +8453,23 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
complain))
return error_mark_node;
- /* 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,
- complain, gen_tmpl));
+ /* We are building a FUNCTION_DECL, during which the access of its
+ parameters and return types have to be checked. However this
+ FUNCTION_DECL which is the desired context for access checking
+ is not built yet. We solve this chicken-and-egg problem by
+ deferring all checks until we have the FUNCTION_DECL. */
+ push_deferring_access_checks (dk_deferred);
/* substitute template parameters */
fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl),
targ_ptr, complain, gen_tmpl);
- pop_access_scope (gen_tmpl);
+ /* Now we know the specialization, compute access previously
+ deferred. */
+ push_access_scope (fndecl);
+ perform_deferred_access_checks ();
+ pop_access_scope (fndecl);
+ pop_deferring_access_checks ();
/* The DECL_TI_TEMPLATE should always be the immediate parent
template, not the most general template. */
@@ -8605,6 +8566,7 @@ fn_type_unification (tree fn,
template results in an invalid type, type deduction fails. */
int i;
tree converted_args;
+ bool incomplete;
converted_args
= (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn),
@@ -8613,12 +8575,22 @@ fn_type_unification (tree fn,
if (converted_args == error_mark_node)
return 1;
+ /* Substitute the explicit args into the function type. This is
+ necessary so that, for instance, explicitly declared function
+ arguments can match null pointed constants. If we were given
+ an incomplete set of explicit args, we must not do semantic
+ processing during substitution as we could create partial
+ instantiations. */
+ incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs);
+ processing_template_decl += incomplete;
fntype = tsubst (fntype, converted_args, tf_none, NULL_TREE);
+ processing_template_decl -= incomplete;
+
if (fntype == error_mark_node)
return 1;
/* Place the explicitly specified arguments in TARGS. */
- for (i = 0; i < TREE_VEC_LENGTH (targs); i++)
+ for (i = NUM_TMPL_ARGS (converted_args); i--;)
TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (converted_args, i);
}
@@ -8795,9 +8767,7 @@ type_unification_real (tree tparms,
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. */
- if (xargs)
- my_friendly_assert (TREE_CODE (xargs) == TREE_LIST, 291);
+ my_friendly_assert (!xargs || TREE_CODE (xargs) == TREE_LIST, 291);
my_friendly_assert (ntparms > 0, 292);
switch (strict)
@@ -8962,9 +8932,15 @@ resolve_overloaded_unification (tree tparms,
{
tree tempargs = copy_node (targs);
int good = 0;
+ bool addr_p;
if (TREE_CODE (arg) == ADDR_EXPR)
- arg = TREE_OPERAND (arg, 0);
+ {
+ arg = TREE_OPERAND (arg, 0);
+ addr_p = true;
+ }
+ else
+ addr_p = false;
if (TREE_CODE (arg) == COMPONENT_REF)
/* Handle `&x' where `x' is some static or non-static member
@@ -9000,10 +8976,8 @@ resolve_overloaded_unification (tree tparms,
if (subargs)
{
elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE);
- if (TREE_CODE (elem) == METHOD_TYPE)
- elem = build_ptrmemfunc_type (build_pointer_type (elem));
- good += try_one_overload (tparms, targs, tempargs, parm, elem,
- strict, sub_strict);
+ good += try_one_overload (tparms, targs, tempargs, parm,
+ elem, strict, sub_strict, addr_p);
}
}
}
@@ -9011,14 +8985,9 @@ resolve_overloaded_unification (tree tparms,
|| TREE_CODE (arg) == FUNCTION_DECL)
{
for (; arg; arg = OVL_NEXT (arg))
- {
- tree type = TREE_TYPE (OVL_CURRENT (arg));
- if (TREE_CODE (type) == METHOD_TYPE)
- type = build_ptrmemfunc_type (build_pointer_type (type));
- good += try_one_overload (tparms, targs, tempargs, parm,
- type,
- strict, sub_strict);
- }
+ good += try_one_overload (tparms, targs, tempargs, parm,
+ TREE_TYPE (OVL_CURRENT (arg)),
+ strict, sub_strict, addr_p);
}
else
abort ();
@@ -9047,6 +9016,9 @@ resolve_overloaded_unification (tree tparms,
/* Subroutine of resolve_overloaded_unification; does deduction for a single
overload. Fills TARGS with any deduced arguments, or error_mark_node if
different overloads deduce different arguments for a given parm.
+ ADDR_P is true if the expression for which deduction is being
+ performed was of the form "& fn" rather than simply "fn".
+
Returns 1 on success. */
static int
@@ -9056,7 +9028,8 @@ try_one_overload (tree tparms,
tree parm,
tree arg,
unification_kind_t strict,
- int sub_strict)
+ int sub_strict,
+ bool addr_p)
{
int nargs;
tree tempargs;
@@ -9072,6 +9045,11 @@ try_one_overload (tree tparms,
if (uses_template_parms (arg))
return 1;
+ if (TREE_CODE (arg) == METHOD_TYPE)
+ arg = build_ptrmemfunc_type (build_pointer_type (arg));
+ else if (addr_p)
+ arg = build_pointer_type (arg);
+
sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
/* We don't copy orig_targs for this because if we have already deduced
@@ -9535,12 +9513,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int 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;
@@ -9641,18 +9613,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
level of pointers. */
strict |= (strict_in & UNIFY_ALLOW_DERIVED);
- if (TREE_CODE (TREE_TYPE (parm)) == OFFSET_TYPE
- && TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
- {
- /* Avoid getting confused about cv-quals; don't recurse here.
- Pointers to members should really be just OFFSET_TYPE, not
- this two-level nonsense... */
-
- parm = TREE_TYPE (parm);
- arg = TREE_TYPE (arg);
- goto offset;
- }
-
return unify (tparms, targs, TREE_TYPE (parm),
TREE_TYPE (arg), strict);
}
@@ -9806,7 +9766,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
DEDUCE_EXACT, 0, -1);
case OFFSET_TYPE:
- offset:
if (TREE_CODE (arg) != OFFSET_TYPE)
return 1;
if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
@@ -9946,6 +9905,10 @@ more_specialized (tree pat1, tree pat2, int deduce, int len)
tree targs;
int winner = 0;
+ /* If template argument deduction succeeds, we substitute the
+ resulting arguments into non-deduced contexts. While doing that,
+ we must be aware that we may encounter dependent types. */
+ ++processing_template_decl;
targs = get_bindings_real (pat1, DECL_TEMPLATE_RESULT (pat2),
NULL_TREE, 0, deduce, len);
if (targs)
@@ -9955,6 +9918,7 @@ more_specialized (tree pat1, tree pat2, int deduce, int len)
NULL_TREE, 0, deduce, len);
if (targs)
++winner;
+ --processing_template_decl;
return winner;
}
@@ -9963,21 +9927,24 @@ more_specialized (tree pat1, tree pat2, int deduce, int len)
1 if PAT1 is more specialized than PAT2 as described in [temp.class.order].
-1 if PAT2 is more specialized than PAT1.
- 0 if neither is more specialized. */
+ 0 if neither is more specialized.
+
+ FULL_ARGS is the full set of template arguments that triggers this
+ partial ordering. */
int
-more_specialized_class (tree pat1, tree pat2)
+more_specialized_class (tree pat1, tree pat2, tree full_args)
{
tree targs;
int winner = 0;
targs = get_class_bindings (TREE_VALUE (pat1), TREE_PURPOSE (pat1),
- TREE_PURPOSE (pat2));
+ add_outermost_template_args (full_args, TREE_PURPOSE (pat2)));
if (targs)
--winner;
targs = get_class_bindings (TREE_VALUE (pat2), TREE_PURPOSE (pat2),
- TREE_PURPOSE (pat1));
+ add_outermost_template_args (full_args, TREE_PURPOSE (pat1)));
if (targs)
++winner;
@@ -10050,7 +10017,7 @@ get_bindings_real (tree fn,
/* For most uses, we want to check the return type. */
-tree
+static tree
get_bindings (tree fn, tree decl, tree explicit_args)
{
return get_bindings_real (fn, decl, explicit_args, 1, DEDUCE_EXACT, -1);
@@ -10205,8 +10172,8 @@ most_general_template (tree decl)
/* Look for more and more general templates. */
while (DECL_TEMPLATE_INFO (decl))
{
- /* The DECL_TI_TEMPLATE can be a LOOKUP_EXPR or IDENTIFIER_NODE
- in some cases. (See cp-tree.h for details.) */
+ /* The DECL_TI_TEMPLATE can be an IDENTIFIER_NODE in some cases.
+ (See cp-tree.h for details.) */
if (TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL)
break;
@@ -10258,7 +10225,7 @@ most_specialized_class (tree tmpl, tree args)
t = TREE_CHAIN (t);
for (; t; t = TREE_CHAIN (t))
{
- fate = more_specialized_class (champ, t);
+ fate = more_specialized_class (champ, t, args);
if (fate == 1)
;
else
@@ -10275,7 +10242,7 @@ most_specialized_class (tree tmpl, tree args)
for (t = list; t && t != champ; t = TREE_CHAIN (t))
{
- fate = more_specialized_class (champ, t);
+ fate = more_specialized_class (champ, t, args);
if (fate != 1)
return error_mark_node;
}
@@ -10595,7 +10562,7 @@ regenerate_decl_from_template (tree decl, tree tmpl)
tree args;
tree code_pattern;
tree new_decl;
- int unregistered;
+ bool unregistered;
args = DECL_TI_ARGS (decl);
code_pattern = DECL_TEMPLATE_RESULT (tmpl);
@@ -10606,14 +10573,18 @@ regenerate_decl_from_template (tree decl, tree 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);
+ unregistered = reregister_specialization (decl, gen_tmpl,
+ /*new_spec=*/NULL_TREE);
/* If the DECL was not unregistered then something peculiar is
happening: we created a specialization but did not call
register_specialization for it. */
my_friendly_assert (unregistered, 0);
+ /* Make sure that we can see identifiers, and compute access
+ correctly. */
+ push_access_scope (decl);
+
/* Do the substitution to get the new declaration. */
new_decl = tsubst (code_pattern, args, tf_error, NULL_TREE);
@@ -10775,10 +10746,14 @@ instantiate_decl (tree d, int defer_ok)
timevar_push (TV_PARSE);
- /* We may be in the middle of deferred access check. Disable
- it now. */
+ /* We may be in the middle of deferred access check. Disable it now. */
push_deferring_access_checks (dk_no_deferred);
+ /* Our caller does not expect collection to happen, which it might if
+ we decide to compile the function to rtl now. Arrange for a new
+ gc context to be created if so. */
+ function_depth++;
+
/* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern
for the instantiation. */
td = template_for_substitution (d);
@@ -11023,6 +10998,7 @@ out:
input_location = saved_loc;
pop_deferring_access_checks ();
pop_tinst_level ();
+ function_depth--;
timevar_pop (TV_PARSE);
@@ -11185,18 +11161,20 @@ tsubst_enum (tree tag, tree newtag, tree args)
for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e))
{
tree value;
-
+ tree decl;
+
+ decl = TREE_VALUE (e);
/* Note that in a template enum, the TREE_VALUE is the
CONST_DECL, not the corresponding INTEGER_CST. */
- value = tsubst_expr (DECL_INITIAL (TREE_VALUE (e)),
+ value = tsubst_expr (DECL_INITIAL (decl),
args, tf_error | tf_warning,
NULL_TREE);
/* Give this enumeration constant the correct access. */
- set_current_access_from_decl (TREE_VALUE (e));
+ set_current_access_from_decl (decl);
/* Actually build the enumerator itself. */
- build_enumerator (TREE_PURPOSE (e), value, newtag);
+ build_enumerator (DECL_NAME (decl), value, newtag);
}
finish_enum (newtag);
@@ -11303,9 +11281,7 @@ invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain)
return 0;
else if (POINTER_TYPE_P (type))
return 0;
- else if (TYPE_PTRMEM_P (type))
- return 0;
- else if (TYPE_PTRMEMFUNC_P (type))
+ else if (TYPE_PTR_TO_MEMBER_P (type))
return 0;
else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
return 0;
@@ -11342,7 +11318,7 @@ dependent_type_p_r (tree type)
dependent. */
type = TYPE_MAIN_VARIANT (type);
/* -- a compound type constructed from any dependent type. */
- if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type))
+ if (TYPE_PTR_TO_MEMBER_P (type))
return (dependent_type_p (TYPE_PTRMEM_CLASS_TYPE (type))
|| dependent_type_p (TYPE_PTRMEM_POINTED_TO_TYPE
(type)));
@@ -11376,25 +11352,24 @@ dependent_type_p_r (tree type)
return true;
return dependent_type_p (TREE_TYPE (type));
}
+
/* -- a template-id in which either the template name is a template
- parameter or any of the template arguments is a dependent type or
- an expression that is type-dependent or value-dependent.
-
- This language seems somewhat confused; for example, it does not
- discuss template template arguments. Therefore, we use the
- definition for dependent template arguments in [temp.dep.temp]. */
- if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type)
- && (dependent_template_id_p
- (CLASSTYPE_TI_TEMPLATE (type),
- CLASSTYPE_TI_ARGS (type))))
+ parameter ... */
+ if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
return true;
- else if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ /* ... or any of the template arguments is a dependent type or
+ an expression that is type-dependent or value-dependent. */
+ else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type)
+ && (any_dependent_template_arguments_p
+ (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type)))))
return true;
+
/* All TYPEOF_TYPEs are dependent; if the argument of the `typeof'
expression is not type-dependent, then it should already been
have resolved. */
if (TREE_CODE (type) == TYPEOF_TYPE)
return true;
+
/* The standard does not specifically mention types that are local
to template functions or local classes, but they should be
considered dependent too. For example:
@@ -11447,6 +11422,40 @@ dependent_type_p (tree type)
return TYPE_DEPENDENT_P (type);
}
+/* Returns TRUE if EXPRESSION is dependent, according to CRITERION. */
+
+static bool
+dependent_scope_ref_p (tree expression, bool criterion (tree))
+{
+ tree scope;
+ tree name;
+
+ my_friendly_assert (TREE_CODE (expression) == SCOPE_REF, 20030714);
+
+ if (!TYPE_P (TREE_OPERAND (expression, 0)))
+ return true;
+
+ scope = TREE_OPERAND (expression, 0);
+ name = TREE_OPERAND (expression, 1);
+
+ /* [temp.dep.expr]
+
+ An id-expression is type-dependent if it contains a
+ nested-name-specifier that contains a class-name that names a
+ dependent type. */
+ /* The suggested resolution to Core Issue 2 implies that if the
+ qualifying type is the current class, then we must peek
+ inside it. */
+ if (DECL_P (name)
+ && currently_open_class (scope)
+ && !criterion (name))
+ return false;
+ if (dependent_type_p (scope))
+ return true;
+
+ return false;
+}
+
/* Returns TRUE if the EXPRESSION is value-dependent, in the sense of
[temp.dep.constexpr] */
@@ -11457,7 +11466,7 @@ value_dependent_expression_p (tree expression)
return false;
/* A name declared with a dependent type. */
- if (TREE_CODE (expression) == LOOKUP_EXPR
+ if (TREE_CODE (expression) == IDENTIFIER_NODE
|| (DECL_P (expression)
&& type_dependent_expression_p (expression)))
return true;
@@ -11510,6 +11519,8 @@ value_dependent_expression_p (tree expression)
return dependent_type_p (expression);
return type_dependent_expression_p (expression);
}
+ if (TREE_CODE (expression) == SCOPE_REF)
+ return dependent_scope_ref_p (expression, value_dependent_expression_p);
/* A constant expression is value-dependent if any subexpression is
value-dependent. */
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression))))
@@ -11555,6 +11566,13 @@ type_dependent_expression_p (tree expression)
if (!processing_template_decl)
return false;
+ if (expression == error_mark_node)
+ return false;
+
+ /* An unresolved name is always dependent. */
+ if (TREE_CODE (expression) == IDENTIFIER_NODE)
+ return true;
+
/* Some expression forms are never type-dependent. */
if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR
|| TREE_CODE (expression) == SIZEOF_EXPR
@@ -11593,24 +11611,37 @@ type_dependent_expression_p (tree expression)
return dependent_type_p (type);
}
+ if (TREE_CODE (expression) == SCOPE_REF
+ && dependent_scope_ref_p (expression,
+ type_dependent_expression_p))
+ return true;
+
if (TREE_CODE (expression) == FUNCTION_DECL
&& DECL_LANG_SPECIFIC (expression)
&& DECL_TEMPLATE_INFO (expression)
- && (dependent_template_id_p
- (DECL_TI_TEMPLATE (expression),
- INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
+ && (any_dependent_template_arguments_p
+ (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
return true;
if (TREE_TYPE (expression) == unknown_type_node)
{
if (TREE_CODE (expression) == ADDR_EXPR)
return type_dependent_expression_p (TREE_OPERAND (expression, 0));
+ if (TREE_CODE (expression) == COMPONENT_REF)
+ {
+ if (type_dependent_expression_p (TREE_OPERAND (expression, 0)))
+ return true;
+ expression = TREE_OPERAND (expression, 1);
+ if (TREE_CODE (expression) == IDENTIFIER_NODE)
+ return false;
+ }
+
if (TREE_CODE (expression) == BASELINK)
expression = BASELINK_FUNCTIONS (expression);
if (TREE_CODE (expression) == TEMPLATE_ID_EXPR)
{
- if (any_dependent_template_arguments_p (TREE_OPERAND (expression,
- 1)))
+ if (any_dependent_template_arguments_p
+ (TREE_OPERAND (expression, 1)))
return true;
expression = TREE_OPERAND (expression, 0);
}
@@ -11638,7 +11669,9 @@ any_type_dependent_arguments_p (tree args)
{
while (args)
{
- if (type_dependent_expression_p (TREE_VALUE (args)))
+ tree arg = TREE_VALUE (args);
+
+ if (type_dependent_expression_p (arg))
return true;
args = TREE_CHAIN (args);
}
@@ -11669,29 +11702,14 @@ dependent_template_arg_p (tree arg)
bool
any_dependent_template_arguments_p (tree args)
{
+ int i;
+
if (!args)
return false;
- my_friendly_assert (TREE_CODE (args) == TREE_LIST
- || TREE_CODE (args) == TREE_VEC,
- 20030707);
-
- if (TREE_CODE (args) == TREE_LIST)
- {
- while (args)
- {
- if (dependent_template_arg_p (TREE_VALUE (args)))
- return true;
- args = TREE_CHAIN (args);
- }
- }
- else
- {
- int i;
- for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
- if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
- return true;
- }
+ for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
+ if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
+ return true;
return false;
}
@@ -11787,8 +11805,7 @@ resolve_typename_type (tree type, bool only_current_p)
args = TREE_OPERAND (TYPENAME_TYPE_FULLNAME (type), 1);
/* Instantiate the template. */
type = lookup_template_class (tmpl, args, NULL_TREE, NULL_TREE,
- /*entering_scope=*/0,
- tf_error);
+ /*entering_scope=*/0, tf_error | tf_user);
}
else
type = error_mark_node;
@@ -11816,6 +11833,25 @@ build_non_dependent_expr (tree expr)
types. */
if (TREE_CODE (expr) == OVERLOAD)
return expr;
+ /* Preserve string constants; conversions from string constants to
+ "char *" are allowed, even though normally a "const char *"
+ cannot be used to initialize a "char *". */
+ if (TREE_CODE (expr) == STRING_CST)
+ return expr;
+
+ if (TREE_CODE (expr) == COND_EXPR)
+ return build (COND_EXPR,
+ TREE_TYPE (expr),
+ TREE_OPERAND (expr, 0),
+ build_non_dependent_expr (TREE_OPERAND (expr, 1)),
+ build_non_dependent_expr (TREE_OPERAND (expr, 2)));
+ if (TREE_CODE (expr) == COMPOUND_EXPR
+ && !COMPOUND_EXPR_OVERLOADED (expr))
+ return build (COMPOUND_EXPR,
+ TREE_TYPE (expr),
+ TREE_OPERAND (expr, 0),
+ build_non_dependent_expr (TREE_OPERAND (expr, 1)));
+
/* Otherwise, build a NON_DEPENDENT_EXPR.
REFERENCE_TYPEs are not stripped for expressions in templates
@@ -11830,7 +11866,7 @@ build_non_dependent_expr (tree expr)
the expression so that mangling (say) "f<g>" inside the body of
"f" works out correctly. Therefore, the REFERENCE_TYPE is
stripped here. */
- return build (NON_DEPENDENT_EXPR, non_reference (TREE_TYPE (expr)));
+ return build1 (NON_DEPENDENT_EXPR, non_reference (TREE_TYPE (expr)), expr);
}
/* ARGS is a TREE_LIST of expressions as arguments to a function call.