aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-05 15:48:55 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-05 15:48:55 +0000
commit61c4d28e36cd3f1be392cb77f07436d1fa6b0f9f (patch)
tree89f1f1bc62bd5e77e02ef2206ec4b308599e33c0 /lib/Parse/ParseTemplate.cpp
parent07fa2fa8b9a0f7982a31e12f4164550d004543ae (diff)
Implement support for template template parameter packs, e.g.,
template<template<class> class ...Metafunctions> struct apply_to_each; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122874 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseTemplate.cpp')
-rw-r--r--lib/Parse/ParseTemplate.cpp31
1 files changed, 22 insertions, 9 deletions
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index afa2cc62f9..8fb6b96673 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -421,12 +421,14 @@ bool Parser::isStartOfTemplateTypeParameter() {
/// parameter-declaration
///
/// type-parameter: (see below)
-/// 'class' ...[opt][C++0x] identifier[opt]
+/// 'class' ...[opt] identifier[opt]
/// 'class' identifier[opt] '=' type-id
-/// 'typename' ...[opt][C++0x] identifier[opt]
+/// 'typename' ...[opt] identifier[opt]
/// 'typename' identifier[opt] '=' type-id
-/// 'template' ...[opt][C++0x] '<' template-parameter-list '>' 'class' identifier[opt]
-/// 'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression
+/// 'template' '<' template-parameter-list '>'
+/// 'class' ...[opt] identifier[opt]
+/// 'template' '<' template-parameter-list '>' 'class' identifier[opt]
+/// = id-expression
Decl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
if (isStartOfTemplateTypeParameter())
return ParseTypeParameter(Depth, Position);
@@ -502,8 +504,10 @@ Decl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
/// template parameters.
///
/// type-parameter: [C++ temp.param]
-/// 'template' '<' template-parameter-list '>' 'class' identifier[opt]
-/// 'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression
+/// 'template' '<' template-parameter-list '>' 'class'
+/// ...[opt] identifier[opt]
+/// 'template' '<' template-parameter-list '>' 'class' identifier[opt]
+/// = id-expression
Decl *
Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");
@@ -529,6 +533,15 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
}
SourceLocation ClassLoc = ConsumeToken();
+ // Parse the ellipsis, if given.
+ SourceLocation EllipsisLoc;
+ if (Tok.is(tok::ellipsis)) {
+ EllipsisLoc = ConsumeToken();
+
+ if (!getLang().CPlusPlus0x)
+ Diag(EllipsisLoc, diag::err_variadic_templates);
+ }
+
// Get the identifier, if given.
SourceLocation NameLoc;
IdentifierInfo* ParamName = 0;
@@ -569,9 +582,9 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
}
return Actions.ActOnTemplateTemplateParameter(getCurScope(), TemplateLoc,
- ParamList, ParamName,
- NameLoc, Depth, Position,
- EqualLoc, DefaultArg);
+ ParamList, EllipsisLoc,
+ ParamName, NameLoc, Depth,
+ Position, EqualLoc, DefaultArg);
}
/// ParseNonTypeTemplateParameter - Handle the parsing of non-type