aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-05 17:33:50 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-05 17:33:50 +0000
commitec5e696a7523db8eae450f4593a80a27f32e530b (patch)
tree1651a3263fa408126604491e3a4ab66d29d51fe9 /lib/Parse/ParseTemplate.cpp
parentb49e41548d2392f1ce5488264a98685d98f90384 (diff)
Parse template template argument pack expansions. They're still not
implemented, however. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122888 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseTemplate.cpp')
-rw-r--r--lib/Parse/ParseTemplate.cpp23
1 files changed, 18 insertions, 5 deletions
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 8fb6b96673..aeafba8990 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -907,7 +907,7 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
// 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) '>>'.
@@ -915,6 +915,8 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
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.
@@ -926,6 +928,10 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
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.
@@ -936,7 +942,7 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
/*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.
@@ -945,6 +951,10 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
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,
@@ -957,13 +967,16 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
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]).