+2005-06-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21903
+ * cp-tree.def (DEFAULT_ARG): Document TREE_CHAIN use.
+ * parser.c (cp_parser_late_parsing_default_args): Propagate parsed
+ argument to any early instantiations.
+ * pt.c (tsubst_arg_types): Chain early instantiation of default
+ arg.
+
+ PR c++/19884
+ * pt.c (check_explicit_specialization): Make sure namespace
+ binding lookup found an overloaded function.
+ (lookup_template_function): Just assert FNS is an overloaded
+ function.
+
+ PR c++/19608
+ * parser.c (cp_parser_late_parsing_for_member): Use
+ current_function_decl as scope to push to and from.
+ testsuite:
+
2005-06-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/20563
/* A using directive. The operand is USING_STMT_NAMESPACE. */
DEFTREECODE (USING_STMT, "using_directive", 'e', 1)
-/* An un-parsed default argument. Looks like an IDENTIFIER_NODE. */
+/* An un-parsed default argument.
+ TREE_CHAIN is used to hold instantiations of functions that had to
+ be instantiated before the argument was parsed. */
DEFTREECODE (DEFAULT_ARG, "default_arg", 'x', 0)
/* A template-id, like foo<int>. The first operand is the template.
tokens = DECL_PENDING_INLINE_INFO (member_function);
DECL_PENDING_INLINE_INFO (member_function) = NULL;
DECL_PENDING_INLINE_P (member_function) = 0;
- /* If this was an inline function in a local class, enter the scope
- of the containing function. */
- function_scope = decl_function_context (member_function);
+
+ /* If this is a local class, enter the scope of the containing
+ function. */
+ function_scope = current_function_decl;
if (function_scope)
push_function_context_to (function_scope);
parameters;
parameters = TREE_CHAIN (parameters))
{
- if (!TREE_PURPOSE (parameters)
- || TREE_CODE (TREE_PURPOSE (parameters)) != DEFAULT_ARG)
+ tree default_arg = TREE_PURPOSE (parameters);
+ tree parsed_arg;
+
+ if (!default_arg)
+ continue;
+
+ if (TREE_CODE (default_arg) != DEFAULT_ARG)
+ /* This can happen for a friend declaration for a function
+ already declared with default arguments. */
continue;
- /* Save away the current lexer. */
+ /* Save away the current lexer. */
saved_lexer = parser->lexer;
- /* Create a new one, using the tokens we have saved. */
- tokens = DEFARG_TOKENS (TREE_PURPOSE (parameters));
+ /* Create a new one, using the tokens we have saved. */
+ tokens = DEFARG_TOKENS (default_arg);
parser->lexer = cp_lexer_new_from_tokens (tokens);
- /* Set the current source position to be the location of the
- first token in the default argument. */
+ /* Set the current source position to be the location of the
+ first token in the default argument. */
cp_lexer_peek_token (parser->lexer);
- /* Local variable names (and the `this' keyword) may not appear
- in a default argument. */
+ /* Local variable names (and the `this' keyword) may not appear
+ in a default argument. */
saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
parser->local_variables_forbidden_p = true;
- /* Parse the assignment-expression. */
+
+ /* Parse the assignment-expression. */
if (DECL_FRIEND_CONTEXT (fn))
push_nested_class (DECL_FRIEND_CONTEXT (fn));
else if (DECL_CLASS_SCOPE_P (fn))
push_nested_class (DECL_CONTEXT (fn));
- TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser);
+ parsed_arg = cp_parser_assignment_expression (parser);
if (DECL_FRIEND_CONTEXT (fn) || DECL_CLASS_SCOPE_P (fn))
pop_nested_class ();
-
+
+ TREE_PURPOSE (parameters) = parsed_arg;
+
+ /* Update any instantiations we've already created. */
+ for (default_arg = TREE_CHAIN (default_arg);
+ default_arg;
+ default_arg = TREE_CHAIN (default_arg))
+ TREE_PURPOSE (TREE_PURPOSE (default_arg)) = parsed_arg;
+
/* If the token stream has not been completely used up, then
there was extra junk after the end of the default
argument. */
/* Find the namespace binding, using the declaration
context. */
fns = namespace_binding (dname, CP_DECL_CONTEXT (decl));
+ if (!fns || !is_overloaded_fn (fns))
+ {
+ error ("`%D' is not a template function", dname);
+ fns = error_mark_node;
+ }
}
declarator = lookup_template_function (fns, NULL_TREE);
return error_mark_node;
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;
- }
-
- my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL
- || TREE_CODE (fns) == OVERLOAD
- || BASELINK_P (fns)
- || TREE_CODE (fns) == IDENTIFIER_NODE,
- 20020730);
+ my_friendly_assert (fns && (is_overloaded_fn (fns)
+ || TREE_CODE (fns) == IDENTIFIER_NODE),
+ 20050608);
if (BASELINK_P (fns))
{
{
tree remaining_arg_types;
tree type;
+ tree default_arg;
+ tree result = NULL_TREE;
if (!arg_types || arg_types == void_list_node)
return arg_types;
top-level qualifiers as required. */
type = TYPE_MAIN_VARIANT (type_decays_to (type));
- /* Note that we do not substitute into default arguments here. The
- standard mandates that they be instantiated only when needed,
- which is done in build_over_call. */
- return hash_tree_cons (TREE_PURPOSE (arg_types), type,
- remaining_arg_types);
-
+ /* We do not substitute into default arguments here. The standard
+ mandates that they be instantiated only when needed, which is
+ done in build_over_call. */
+ default_arg = TREE_PURPOSE (arg_types);
+
+ if (default_arg && TREE_CODE (default_arg) == DEFAULT_ARG)
+ {
+ /* We've instantiated a template before its default arguments
+ have been parsed. This can happen for a nested template
+ class, and is not an error unless we require the default
+ argument in a call of this function. */
+ result = tree_cons (default_arg, type, remaining_arg_types);
+ TREE_CHAIN (default_arg) = tree_cons (result, NULL_TREE,
+ TREE_CHAIN (default_arg));
+ }
+ else
+ result = hash_tree_cons (default_arg, type, remaining_arg_types);
+
+ return result;
}
/* Substitute into a FUNCTION_TYPE or METHOD_TYPE. This routine does
+2005-06-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21903
+ * g++.dg/parse/defarg9.C: New.
+
+ PR c++/19884
+ * g++.old-deja/g++.oliva/template6.C: Add another case.
+ * g++.dg/template/explicit6.C: New.
+
+ PR c++/19608
+ * g++.dg/parse/local-class1.C: New.
+
2005-06-08 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/tls/debug-1.c: New test.
// simplified from bug report by Meenaradchagan Vishnu <mvishnu@fore.com>
template <typename> struct foo {};
-template <> void foo(); // { dg-error "" } bad specialization
+template <> void foo(); // { dg-error "not a template function" } bad specialization
+
+struct baz {};
+template <> void baz (); // { dg-error "not a template function" } bad specialization