if (TREE_CODE (template_id) == TEMPLATE_ID_EXPR)
SET_EXPR_LOCATION (template_id, combined_loc);
}
+ else if (TREE_CODE (templ) == TYPE_DECL
+ && TREE_CODE (TREE_TYPE (templ)) == TYPENAME_TYPE)
+ {
+ /* Some type template in dependent scope. */
+ tree &name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (templ));
+ name = build_min_nt_loc (combined_loc,
+ TEMPLATE_ID_EXPR,
+ name, arguments);
+ template_id = templ;
+ }
else
{
/* If it's not a class-template or a template-template, it should be
}
/* cp_parser_lookup_name clears OBJECT_TYPE. */
- const bool scoped_p = ((parser->scope ? parser->scope
- : parser->context->object_type) != NULL_TREE);
+ tree scope = (parser->scope ? parser->scope
+ : parser->context->object_type);
/* Look up the name. */
decl = cp_parser_lookup_name (parser, identifier,
decl = strip_using_decl (decl);
+ /* 13.3 [temp.names] A < is interpreted as the delimiter of a
+ template-argument-list if it follows a name that is not a
+ conversion-function-id and
+ - that follows the keyword template or a ~ after a nested-name-specifier or
+ in a class member access expression, or
+ - for which name lookup finds the injected-class-name of a class template
+ or finds any declaration of a template, or
+ - that is an unqualified name for which name lookup either finds one or
+ more functions or finds nothing, or
+ - that is a terminal name in a using-declarator (9.9), in a declarator-id
+ (9.3.4), or in a type-only context other than a nested-name-specifier
+ (13.8). */
+
/* If DECL is a template, then the name was a template-name. */
if (TREE_CODE (decl) == TEMPLATE_DECL)
{
}
else
{
- /* The standard does not explicitly indicate whether a name that
- names a set of overloaded declarations, some of which are
- templates, is a template-name. However, such a name should
- be a template-name; otherwise, there is no way to form a
- template-id for the overloaded templates. */
+ /* Look through an overload set for any templates. */
bool found = false;
for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (decl));
if (TREE_CODE (*iter) == TEMPLATE_DECL)
found = true;
+ /* "an unqualified name for which name lookup either finds one or more
+ functions or finds nothing". */
if (!found
&& (cxx_dialect > cxx17)
- && !scoped_p
+ && !scope
&& cp_lexer_next_token_is (parser->lexer, CPP_LESS)
&& tag_type == none_type)
{
- /* [temp.names] says "A name is also considered to refer to a template
- if it is an unqualified-id followed by a < and name lookup finds
- either one or more functions or finds nothing." */
-
/* The "more functions" case. Just use the OVERLOAD as normally.
We don't use is_overloaded_fn here to avoid considering
BASELINKs. */
if (TREE_CODE (decl) == OVERLOAD
/* Name lookup found one function. */
- || TREE_CODE (decl) == FUNCTION_DECL)
+ || TREE_CODE (decl) == FUNCTION_DECL
+ /* Name lookup found nothing. */
+ || decl == error_mark_node)
found = true;
- /* Name lookup found nothing. */
- else if (decl == error_mark_node)
- return identifier;
}
+ /* "in a type-only context" */
+ if (!found && scope
+ && tag_type != none_type
+ && dependentish_scope_p (scope)
+ && cp_parser_nth_token_starts_template_argument_list_p (parser, 1))
+ found = true;
+
if (!found)
{
/* The name does not name a template. */
cp_parser_error (parser, "expected template-name");
return error_mark_node;
}
+ else if (decl == error_mark_node)
+ /* Repeat the lookup at instantiation time. */
+ decl = identifier;
}
return decl;
consider class templates. */
: is_template ? LOOK_want::TYPE
: prefer_type_arg (tag_type));
+
+ /* If we know we're looking for a type (e.g. A in p->A::x),
+ mock up a typename. */
+ if (!decl && object_type && tag_type != none_type
+ && dependentish_scope_p (object_type))
+ {
+ tree type = build_typename_type (object_type, name, name,
+ typename_type);
+ decl = TYPE_NAME (type);
+ }
+
parser->object_scope = object_type;
parser->qualifying_scope = NULL_TREE;
}