// We parse an id-expression that refers to a class template or template
// alias. The grammar we parse is:
//
- // nested-name-specifier[opt] template[opt] identifier
+ // nested-name-specifier[opt] template[opt] identifier ...[opt]
//
// followed by a token that terminates a template argument, such as ',',
// '>', or (in some cases) '>>'.
ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
/*EnteringContext=*/false);
+ ParsedTemplateArgument Result;
+ SourceLocation EllipsisLoc;
if (SS.isSet() && Tok.is(tok::kw_template)) {
// Parse the optional 'template' keyword following the
// nested-name-specifier.
Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
ConsumeToken(); // the identifier
+ // Parse the ellipsis.
+ if (Tok.is(tok::ellipsis))
+ EllipsisLoc = ConsumeToken();
+
// If the next token signals the end of a template argument,
// then we have a dependent template name that could be a template
// template argument.
/*ObjectType=*/ ParsedType(),
/*EnteringContext=*/false,
Template))
- return ParsedTemplateArgument(SS, Template, Name.StartLocation);
+ Result = ParsedTemplateArgument(SS, Template, Name.StartLocation);
}
} else if (Tok.is(tok::identifier)) {
// We may have a (non-dependent) template name.
Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
ConsumeToken(); // the identifier
+ // Parse the ellipsis.
+ if (Tok.is(tok::ellipsis))
+ EllipsisLoc = ConsumeToken();
+
if (isEndOfTemplateArgument(Tok)) {
bool MemberOfUnknownSpecialization;
TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS,
if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template) {
// We have an id-expression that refers to a class template or
// (C++0x) template alias.
- return ParsedTemplateArgument(SS, Template, Name.StartLocation);
+ Result = ParsedTemplateArgument(SS, Template, Name.StartLocation);
}
}
}
- // We don't have a template template argument.
- return ParsedTemplateArgument();
+ // If this is a pack expansion, build it as such.
+ if (EllipsisLoc.isValid() && !Result.isInvalid())
+ Result = Actions.ActOnPackExpansion(Result, EllipsisLoc);
+
+ return Result;
}
/// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).