diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-05 15:48:55 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-05 15:48:55 +0000 |
commit | 61c4d28e36cd3f1be392cb77f07436d1fa6b0f9f (patch) | |
tree | 89f1f1bc62bd5e77e02ef2206ec4b308599e33c0 /lib/Parse/ParseTemplate.cpp | |
parent | 07fa2fa8b9a0f7982a31e12f4164550d004543ae (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.cpp | 31 |
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 |