]> granicus.if.org Git - clang/commitdiff
More parameter pack work.
authorAnders Carlsson <andersca@mac.com>
Mon, 15 Jun 2009 17:56:45 +0000 (17:56 +0000)
committerAnders Carlsson <andersca@mac.com>
Mon, 15 Jun 2009 17:56:45 +0000 (17:56 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73395 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclTemplate.h
lib/AST/DeclTemplate.cpp
lib/Sema/SemaTemplate.cpp

index 7d5dc06f235a19af33c86a7d192534a799af7ba4..58325908f0dfb9d37325fd8b5540e0df060f0d28 100644 (file)
@@ -470,14 +470,18 @@ public:
 
   /// \brief Construct a template argument pack.
   TemplateArgument(SourceLocation Loc, TemplateArgument *Args, 
-                   unsigned NumArgs, bool OwnsArgs);
+                   unsigned NumArgs, bool CopyArgs);
   
   /// \brief Copy constructor for a template argument.
   TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
-    assert(Kind != Pack && "FIXME: Handle packs");
     if (Kind == Integral) {
       new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
       Integer.Type = Other.Integer.Type;
+    } else if (Kind == Pack) {
+      Args.NumArgs = Other.Args.NumArgs;
+      Args.Args = new TemplateArgument[Args.NumArgs];
+      for (unsigned I = 0; I != Args.NumArgs; ++I)
+            Args.Args[I] = Other.Args.Args[I];
     }
     else
       TypeOrValue = Other.TypeOrValue;
@@ -617,28 +621,33 @@ public:
 
 /// \brief A helper class for making template argument lists.
 class TemplateArgumentListBuilder {
-  /// Args - contains the template arguments.
-  llvm::SmallVector<TemplateArgument, 16> Args;
+  /// FlatArgs - contains the template arguments in flat form.
+  llvm::SmallVector<TemplateArgument, 16> FlatArgs;
   
-  llvm::SmallVector<unsigned, 32> Indices;
+  llvm::SmallVector<TemplateArgument, 16> StructuredArgs;
 
   ASTContext &Context;
   
+  unsigned PackBeginIndex;
+
   /// isAddingFromParameterPack - Returns whether we're adding arguments from
   /// a parameter pack.
-  bool isAddingFromParameterPack() const { return Indices.size() % 2; }
+  bool isAddingFromParameterPack() const { 
+    return PackBeginIndex != std::numeric_limits<unsigned>::max();
+  }
   
 public:
-  TemplateArgumentListBuilder(ASTContext &Context) : Context(Context) { }
+  TemplateArgumentListBuilder(ASTContext &Context) : Context(Context),
+    PackBeginIndex(std::numeric_limits<unsigned>::max()) { }
   
-  size_t size() const { 
+  size_t structuredSize() const { 
     assert(!isAddingFromParameterPack() && 
            "Size is not valid when adding from a parameter pack");
     
-    return Indices.size() / 2;
+    return StructuredArgs.size();
   }
   
-  size_t flatSize() const { return Args.size(); }
+  size_t flatSize() const { return FlatArgs.size(); }
 
   void push_back(const TemplateArgument& Arg);
   
@@ -648,8 +657,12 @@ public:
   /// EndParameterPack - Finish adding arguments from a parameter pack.
   void EndParameterPack();
   
-  const TemplateArgument *getFlatArgumentList() const { return Args.data(); }
-  TemplateArgument *getFlatArgumentList() { return Args.data(); }
+  const TemplateArgument *getFlatArgumentList() const { 
+      return FlatArgs.data();
+  }
+  TemplateArgument *getFlatArgumentList() { 
+      return FlatArgs.data();
+  }
 };
 
 /// \brief A template argument list.
index d57a43040f6bb54d1c667365e651c145d9158779..ea8dd0d3c035f4374229a042f412c638c75a7839 100644 (file)
@@ -265,25 +265,28 @@ void TemplateArgumentListBuilder::push_back(const TemplateArgument& Arg) {
     break;
   }
   
-  if (!isAddingFromParameterPack()) {
-    // Add begin and end indicies.
-    Indices.push_back(Args.size());
-    Indices.push_back(Args.size());
-  }
-
-  Args.push_back(Arg);
+  FlatArgs.push_back(Arg);
+  
+  if (!isAddingFromParameterPack())
+    StructuredArgs.push_back(Arg);
 }
 
 void TemplateArgumentListBuilder::BeginParameterPack() {
   assert(!isAddingFromParameterPack() && "Already adding to parameter pack!");
-  
-  Indices.push_back(Args.size());
+
+  PackBeginIndex = FlatArgs.size();
 }
 
 void TemplateArgumentListBuilder::EndParameterPack() {
   assert(isAddingFromParameterPack() && "Not adding to parameter pack!");
+
+  unsigned NumArgs = FlatArgs.size() - PackBeginIndex;
+  TemplateArgument *Args = NumArgs ? &FlatArgs[PackBeginIndex] : 0;
+  
+  StructuredArgs.push_back(TemplateArgument(SourceLocation(), Args, NumArgs,
+                                            /*CopyArgs=*/false));
   
-  Indices.push_back(Args.size());
+  PackBeginIndex = std::numeric_limits<unsigned>::max();
 }  
 
 //===----------------------------------------------------------------------===//
index 2b2272d9995ba14d318e3f4b82049b3bdf2f7b5a..d7a8a727f8a1937753f6961bcaff5033ecf2f61a 100644 (file)
@@ -850,7 +850,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
                                 ConvertedTemplateArgs))
     return QualType();
 
-  assert((ConvertedTemplateArgs.size() == 
+  assert((ConvertedTemplateArgs.structuredSize() == 
             Template->getTemplateParameters()->size()) &&
          "Converted template argument list is too short!");
 
@@ -2301,7 +2301,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
                                 RAngleLoc, ConvertedTemplateArgs))
     return true;
 
-  assert((ConvertedTemplateArgs.size() == 
+  assert((ConvertedTemplateArgs.structuredSize() == 
             ClassTemplate->getTemplateParameters()->size()) &&
          "Converted template argument list is too short!");
   
@@ -2562,7 +2562,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
                                 RAngleLoc, ConvertedTemplateArgs))
     return true;
 
-  assert((ConvertedTemplateArgs.size() == 
+  assert((ConvertedTemplateArgs.structuredSize() == 
             ClassTemplate->getTemplateParameters()->size()) &&
          "Converted template argument list is too short!");