return DECL_TEMPLATE_TEMPLATE_PARM_P (parm);
}
-/* Return true iff PARM is a DECL representing a type template
- parameter. */
-
-bool
-template_type_parameter_p (const_tree parm)
-{
- return (parm
- && (TREE_CODE (parm) == TYPE_DECL
- || TREE_CODE (parm) == TEMPLATE_DECL)
- && DECL_TEMPLATE_PARM_P (parm));
-}
-
/* Return the template parameters of T if T is a
primary template instantiation, NULL otherwise. */
}
PACK_EXPANSION_PARAMETER_PACKS (result) = parameter_packs;
+ PACK_EXPANSION_LOCAL_P (result) = at_function_scope_p ();
+
return result;
}
return argument_pack;
}
+/* Returns true if the template argument vector ARGS contains
+ any pack expansions, false otherwise. */
+
+static bool
+any_pack_expanson_args_p (tree args)
+{
+ int i;
+ if (args)
+ for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
+ if (PACK_EXPANSION_P (TREE_VEC_ELT (args, i)))
+ return true;
+ return false;
+}
+
/* Convert all template arguments to their appropriate types, and
return a vector containing the innermost resulting template
arguments. If any error occurs, return error_mark_node. Error and
if ((nargs > nparms && !variadic_p)
|| (nargs < nparms - variadic_p
&& require_all_args
+ && !any_pack_expanson_args_p (inner_args)
&& (!use_default_args
|| (TREE_VEC_ELT (parms, nargs) != error_mark_node
&& !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))))))
return level;
}
+/* Returns TRUE if PARM is a parameter of the template TEMPL. */
+
+bool
+parameter_of_template_p (tree parm, tree templ)
+{
+ tree parms;
+ int i;
+
+ if (!parm || !templ)
+ return false;
+
+ gcc_assert (DECL_TEMPLATE_PARM_P (parm));
+ gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL);
+
+ parms = DECL_TEMPLATE_PARMS (templ);
+ parms = INNERMOST_TEMPLATE_PARMS (parms);
+
+ for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
+ {
+ tree p = TREE_VALUE (TREE_VEC_ELT (parms, i));
+ if (p == error_mark_node)
+ continue;
+
+ if (parm == p
+ || (DECL_INITIAL (parm)
+ && DECL_INITIAL (parm) == DECL_INITIAL (p)))
+ return true;
+ }
+
+ return false;
+}
+
/* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the
vector of template arguments, as for tsubst.
}
if (TREE_CODE (parm_pack) == PARM_DECL)
{
- if (at_function_scope_p ())
+ if (PACK_EXPANSION_LOCAL_P (t))
arg_pack = retrieve_local_specialization (parm_pack);
else
{
complain | tf_ignore_bad_quals);
return r;
}
- /* Else we must be instantiating the typedef, so fall through. */
+ else
+ /* We don't have an instantiation yet, so drop the typedef. */
+ t = DECL_ORIGINAL_TYPE (decl);
}
if (type
tree optype;
tree template_args = 0;
bool template_id_p = false;
+ bool qualified = BASELINK_QUALIFIED_P (baselink);
/* A baselink indicates a function from a base class. Both the
BASELINK_ACCESS_BINFO and the base class referenced may
if (!object_type)
object_type = current_class_type;
- return adjust_result_of_qualified_name_lookup (baselink,
- qualifying_scope,
- object_type);
+
+ if (qualified)
+ baselink = adjust_result_of_qualified_name_lookup (baselink,
+ qualifying_scope,
+ object_type);
+ return baselink;
}
/* Like tsubst_expr for a SCOPE_REF, given by QUALIFIED_ID. DONE is
if (purpose)
purpose = RECUR (purpose);
value = TREE_VALUE (t);
- if (value && TREE_CODE (value) != LABEL_DECL)
- value = RECUR (value);
+ if (value)
+ {
+ if (TREE_CODE (value) != LABEL_DECL)
+ value = RECUR (value);
+ else
+ {
+ value = lookup_label (DECL_NAME (value));
+ gcc_assert (TREE_CODE (value) == LABEL_DECL);
+ TREE_USED (value) = 1;
+ }
+ }
chain = TREE_CHAIN (t);
if (chain && chain != void_type_node)
chain = RECUR (chain);
/* Build a dummy EXPR_PACK_EXPANSION that will be used to
expand each argument in the TREE_VALUE of t. */
expr = make_node (EXPR_PACK_EXPANSION);
+ PACK_EXPANSION_LOCAL_P (expr) = true;
PACK_EXPANSION_PARAMETER_PACKS (expr) =
PACK_EXPANSION_PARAMETER_PACKS (TREE_PURPOSE (t));
}
else
{
+ tree tmp;
decl = tsubst_copy (TREE_PURPOSE (t), argvec,
tf_warning_or_error, NULL_TREE);
in_base_initializer = 1;
init = TREE_VALUE (t);
+ tmp = init;
if (init != void_type_node)
init = tsubst_expr (init, argvec,
tf_warning_or_error, NULL_TREE,
/*integral_constant_expression_p=*/false);
+ if (init == NULL_TREE && tmp != NULL_TREE)
+ /* If we had an initializer but it instantiated to nothing,
+ value-initialize the object. This will only occur when
+ the initializer was a pack expansion where the parameter
+ packs used in that expansion were of length zero. */
+ init = void_type_node;
in_base_initializer = 0;
}