From: Anders Carlsson Date: Fri, 12 Jun 2009 19:58:00 +0000 (+0000) Subject: Parse support for C++0x type parameter packs. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=941df7dac2c733bad57342a01ca4c8dac956ef63;p=clang Parse support for C++0x type parameter packs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73247 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 813b5974e3..43406b99a6 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -1166,16 +1166,18 @@ public: /// ActOnTypeParameter - Called when a C++ template type parameter /// (e.g., "typename T") has been parsed. Typename specifies whether /// the keyword "typename" was used to declare the type parameter - /// (otherwise, "class" was used), and KeyLoc is the location of the - /// "class" or "typename" keyword. ParamName is the name of the - /// parameter (NULL indicates an unnamed template parameter) and - /// ParamNameLoc is the location of the parameter name (if any). + /// (otherwise, "class" was used), ellipsis specifies whether this is a + /// C++0x parameter pack, EllipsisLoc specifies the start of the ellipsis, + /// and KeyLoc is the location of the "class" or "typename" keyword. + // ParamName is the name of the parameter (NULL indicates an unnamed template + // parameter) and ParamNameLoc is the location of the parameter name (if any) /// If the type parameter has a default argument, it will be added /// later via ActOnTypeParameterDefault. Depth and Position provide /// the number of enclosing templates (see /// ActOnTemplateParameterList) and the number of previous /// parameters within this template parameter list. - virtual DeclPtrTy ActOnTypeParameter(Scope *S, bool Typename, + virtual DeclPtrTy ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, + SourceLocation EllipsisLoc, SourceLocation KeyLoc, IdentifierInfo *ParamName, SourceLocation ParamNameLoc, diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 2a79b99d29..30924b217f 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -290,11 +290,11 @@ Parser::ParseTemplateParameterList(unsigned Depth, /// parameter-declaration /// /// type-parameter: (see below) -/// 'class' identifier[opt] +/// 'class' ...[opt] identifier[opt] /// 'class' identifier[opt] '=' type-id -/// 'typename' identifier[opt] +/// 'typename' ...[opt] identifier[opt] /// 'typename' identifier[opt] '=' type-id -/// 'template' '<' template-parameter-list '>' 'class' identifier[opt] +/// 'template' ...[opt] '<' template-parameter-list '>' 'class' identifier[opt] /// 'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression Parser::DeclPtrTy Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { @@ -319,9 +319,9 @@ Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { /// ParseTemplateTemplateParameter and ParseNonTypeTemplateParameter. /// /// type-parameter: [C++ temp.param] -/// 'class' identifier[opt] +/// 'class' ...[opt] identifier[opt] /// 'class' identifier[opt] '=' type-id -/// 'typename' identifier[opt] +/// 'typename' ...[opt] identifier[opt] /// 'typename' identifier[opt] '=' type-id Parser::DeclPtrTy Parser::ParseTypeParameter(unsigned Depth, unsigned Position){ assert((Tok.is(tok::kw_class) || Tok.is(tok::kw_typename)) && @@ -331,6 +331,14 @@ Parser::DeclPtrTy Parser::ParseTypeParameter(unsigned Depth, unsigned Position){ bool TypenameKeyword = Tok.is(tok::kw_typename); SourceLocation KeyLoc = ConsumeToken(); + // Grab the ellipsis (if given). + bool Ellipsis = false; + SourceLocation EllipsisLoc; + if (getLang().CPlusPlus0x && Tok.is(tok::ellipsis)) { + Ellipsis = true; + EllipsisLoc = ConsumeToken(); + } + // Grab the template parameter name (if given) SourceLocation NameLoc; IdentifierInfo* ParamName = 0; @@ -347,6 +355,7 @@ Parser::DeclPtrTy Parser::ParseTypeParameter(unsigned Depth, unsigned Position){ } DeclPtrTy TypeParam = Actions.ActOnTypeParameter(CurScope, TypenameKeyword, + Ellipsis, EllipsisLoc, KeyLoc, ParamName, NameLoc, Depth, Position); diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 7e3ed36585..03ff7a2015 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1880,7 +1880,8 @@ public: bool DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl); TemplateDecl *AdjustDeclIfTemplate(DeclPtrTy &Decl); - virtual DeclPtrTy ActOnTypeParameter(Scope *S, bool Typename, + virtual DeclPtrTy ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, + SourceLocation EllipsisLoc, SourceLocation KeyLoc, IdentifierInfo *ParamName, SourceLocation ParamNameLoc, diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index d08e268b63..5fb1fb89f0 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -140,7 +140,8 @@ TemplateDecl *Sema::AdjustDeclIfTemplate(DeclPtrTy &D) { /// ParamName is the location of the parameter name (if any). /// If the type parameter has a default argument, it will be added /// later via ActOnTypeParameterDefault. -Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, +Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, + SourceLocation EllipsisLoc, SourceLocation KeyLoc, IdentifierInfo *ParamName, SourceLocation ParamNameLoc, diff --git a/test/SemaTemplate/variadic-parse.cpp b/test/SemaTemplate/variadic-parse.cpp new file mode 100644 index 0000000000..e1d1b1f98d --- /dev/null +++ b/test/SemaTemplate/variadic-parse.cpp @@ -0,0 +1,6 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +// Parsing type parameter packs. +template struct T1 {}; +template struct T2 {}; +