]> granicus.if.org Git - clang/commitdiff
Parse support for C++0x type parameter packs.
authorAnders Carlsson <andersca@mac.com>
Fri, 12 Jun 2009 19:58:00 +0000 (19:58 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 12 Jun 2009 19:58:00 +0000 (19:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73247 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Action.h
lib/Parse/ParseTemplate.cpp
lib/Sema/Sema.h
lib/Sema/SemaTemplate.cpp
test/SemaTemplate/variadic-parse.cpp [new file with mode: 0644]

index 813b5974e3f4f375bc2e3c8c5bfa12c45fa254e2..43406b99a679bdb1e37c40711f24776e3a477e78 100644 (file)
@@ -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,
index 2a79b99d29c9bfcd282f28b96842703d184e5d04..30924b217f2b527b5e3e4d42f5655030fd885c62 100644 (file)
@@ -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);
 
index 7e3ed36585d8b06871b75f01d4a2a0c1496baeed..03ff7a20156f43a41bd4a17f0dfdf48bca660c92 100644 (file)
@@ -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,
index d08e268b6378b2edaa3bec10847b76d2a1bd50a5..5fb1fb89f057aebff4164e27618e637073fda0f7 100644 (file)
@@ -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 (file)
index 0000000..e1d1b1f
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x
+
+// Parsing type parameter packs.
+template <typename ... Args> struct T1 {};
+template <typename ... > struct T2 {};
+