[cfe-commits] r73937 - in /cfe/trunk: include/clang/AST/DeclTemplate.h lib/AST/DeclTemplate.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateDeduction.cpp

Anders Carlsson andersca at mac.com
Mon Jun 22 18:26:57 PDT 2009


Author: andersca
Date: Mon Jun 22 20:26:57 2009
New Revision: 73937

URL: http://llvm.org/viewvc/llvm-project?rev=73937&view=rev
Log:
Check in a new template argument list builder that should work better for variadic templates.

Modified:
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=73937&r1=73936&r2=73937&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Mon Jun 22 20:26:57 2009
@@ -469,10 +469,6 @@
   /// occur in a non-dependent, canonical template argument list.
   TemplateArgument(Expr *E);
 
-  /// \brief Construct a template argument pack.
-  TemplateArgument(SourceLocation Loc, TemplateArgument *Args, 
-                   unsigned NumArgs, bool CopyArgs);
-  
   /// \brief Copy constructor for a template argument.
   TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
     if (Kind == Integral) {
@@ -587,6 +583,9 @@
   /// \brief Retrieve the location where the template argument starts.
   SourceLocation getLocation() const { return StartLoc; }
 
+  /// \brief Construct a template argument pack.
+  void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
+
   /// \brief Used to insert TemplateArguments into FoldingSets.
   void Profile(llvm::FoldingSetNodeID &ID) const {
     ID.AddInteger(Kind);
@@ -622,47 +621,51 @@
 
 /// \brief A helper class for making template argument lists.
 class TemplateArgumentListBuilder {
-  /// FlatArgs - contains the template arguments in flat form.
-  llvm::SmallVector<TemplateArgument, 16> FlatArgs;
-  
-  llvm::SmallVector<TemplateArgument, 16> StructuredArgs;
-
-  ASTContext &Context;
+  TemplateArgument *StructuredArgs;
+  unsigned MaxStructuredArgs;
+  unsigned NumStructuredArgs;
+    
+  TemplateArgument *FlatArgs;
+  unsigned MaxFlatArgs;
+  unsigned NumFlatArgs;
   
+  bool AddingToPack;
   unsigned PackBeginIndex;
-
-  /// isAddingFromParameterPack - Returns whether we're adding arguments from
-  /// a parameter pack.
-  bool isAddingFromParameterPack() const { 
-    return PackBeginIndex != std::numeric_limits<unsigned>::max();
-  }
   
 public:
-  TemplateArgumentListBuilder(ASTContext &Context) : Context(Context),
-    PackBeginIndex(std::numeric_limits<unsigned>::max()) { }
+  TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
+                              unsigned NumTemplateArgs)
+    : StructuredArgs(0), MaxStructuredArgs(Parameters->size()), 
+    NumStructuredArgs(0), FlatArgs(0), 
+    MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
+    AddingToPack(false), PackBeginIndex(0) { }
   
-  size_t structuredSize() const { 
-    assert(!isAddingFromParameterPack() && 
-           "Size is not valid when adding from a parameter pack");
-    
-    return StructuredArgs.size();
-  }
-  
-  size_t flatSize() const { return FlatArgs.size(); }
+  void Append(const TemplateArgument& Arg);
+  void BeginPack();
+  void EndPack();
 
-  void push_back(const TemplateArgument& Arg);
-  
-  /// BeginParameterPack - Start adding arguments from a parameter pack.
-  void BeginParameterPack();
+  void ReleaseArgs();
   
-  /// EndParameterPack - Finish adding arguments from a parameter pack.
-  void EndParameterPack();
+  unsigned flatSize() const { 
+    return NumFlatArgs;
+  }
+  const TemplateArgument *getFlatArguments() const {
+    return FlatArgs;
+  }
   
-  const TemplateArgument *getFlatArgumentList() const { 
-      return FlatArgs.data();
+  unsigned structuredSize() const {
+    // If we don't have any structured args, just reuse the flat size.
+    if (!StructuredArgs)
+      return flatSize();
+
+    return NumStructuredArgs;
   }
-  TemplateArgument *getFlatArgumentList() { 
-      return FlatArgs.data();
+  const TemplateArgument *getStructuredArguments() const {
+    // If we don't have any structured args, just reuse the flat args.
+    if (!StructuredArgs)
+      return getFlatArguments();
+    
+    return StructuredArgs;
   }
 };
 
@@ -676,22 +679,25 @@
   ///
   /// The integer value will be non-zero to indicate that this
   /// template argument list does not own the pointer.
-  llvm::PointerIntPair<TemplateArgument *, 1> Arguments;
+  llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
 
   /// \brief The number of template arguments in this template
   /// argument list.
-  unsigned NumArguments;
+  unsigned NumFlatArguments;
 
+  llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
+  unsigned NumStructuredArguments;
+  
 public:
   TemplateArgumentList(ASTContext &Context,
                        TemplateArgumentListBuilder &Builder,
-                       bool CopyArgs, bool FlattenArgs);
+                       bool TakeArgs);
 
   ~TemplateArgumentList();
 
   /// \brief Retrieve the template argument at a given index.
   const TemplateArgument &get(unsigned Idx) const { 
-    assert(Idx < NumArguments && "Invalid template argument index");
+    assert(Idx < NumFlatArguments && "Invalid template argument index");
     return getFlatArgumentList()[Idx];
   }
 
@@ -700,15 +706,15 @@
 
   /// \brief Retrieve the number of template arguments in this
   /// template argument list.
-  unsigned size() const { return NumArguments; }
+  unsigned size() const { return NumFlatArguments; }
 
   /// \brief Retrieve the number of template arguments in the
   /// flattened template argument list.
-  unsigned flat_size() const { return NumArguments; }
+  unsigned flat_size() const { return NumFlatArguments; }
 
   /// \brief Retrieve the flattened template argument list.
   const TemplateArgument *getFlatArgumentList() const { 
-    return Arguments.getPointer();
+    return FlatArguments.getPointer();
   }
 };
 

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=73937&r1=73936&r2=73937&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Mon Jun 22 20:26:57 2009
@@ -239,79 +239,103 @@
 }
 
 /// \brief Construct a template argument pack.
-TemplateArgument::TemplateArgument(SourceLocation Loc, TemplateArgument *args, 
-                                   unsigned NumArgs, bool CopyArgs) 
-  : Kind(Pack) {
-    Args.NumArgs = NumArgs;
-    Args.CopyArgs = CopyArgs;
-    if (!Args.CopyArgs) {
-      Args.Args = args;
-      return;
-    }
-
-    Args.Args = new TemplateArgument[NumArgs];
-    for (unsigned I = 0; I != NumArgs; ++I)
-      Args.Args[I] = args[I];
+void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs, 
+                                       bool CopyArgs) {
+  assert(isNull() && "Must call setArgumentPack on a null argument");
+  
+  Kind = Pack;
+  Args.NumArgs = NumArgs;
+  Args.CopyArgs = CopyArgs;
+  if (!Args.CopyArgs) {
+    Args.Args = args;
+    return;
+  }
+  
+  Args.Args = new TemplateArgument[NumArgs];
+  for (unsigned I = 0; I != Args.NumArgs; ++I)
+    Args.Args[I] = args[I];
 }
 
 //===----------------------------------------------------------------------===//
 // TemplateArgumentListBuilder Implementation
 //===----------------------------------------------------------------------===//
-void TemplateArgumentListBuilder::push_back(const TemplateArgument& Arg) {
+
+void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) {
   switch (Arg.getKind()) {
-  default: break;
-  case TemplateArgument::Type:
-    assert(Arg.getAsType()->isCanonical() && "Type must be canonical!");
-    break;
+    default: break;
+    case TemplateArgument::Type:
+      assert(Arg.getAsType()->isCanonical() && "Type must be canonical!");
+      break;
   }
   
-  FlatArgs.push_back(Arg);
+  assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!");
+  assert(!StructuredArgs && 
+         "Can't append arguments when an argument pack has been added!");
   
-  if (!isAddingFromParameterPack())
-    StructuredArgs.push_back(Arg);
+  if (!FlatArgs)
+    FlatArgs = new TemplateArgument[MaxFlatArgs];
+  
+  FlatArgs[NumFlatArgs++] = Arg;
 }
 
-void TemplateArgumentListBuilder::BeginParameterPack() {
-  assert(!isAddingFromParameterPack() && "Already adding to parameter pack!");
-
-  PackBeginIndex = FlatArgs.size();
+void TemplateArgumentListBuilder::BeginPack() {
+  assert(!AddingToPack && "Already adding to pack!");
+  assert(!StructuredArgs && "Argument list already contains a pack!");
+  
+  AddingToPack = true;
+  PackBeginIndex = NumFlatArgs;
 }
 
-void TemplateArgumentListBuilder::EndParameterPack() {
-  assert(isAddingFromParameterPack() && "Not adding to parameter pack!");
+void TemplateArgumentListBuilder::EndPack() {
+  assert(AddingToPack && "Not adding to pack!");
+  assert(!StructuredArgs && "Argument list already contains a pack!");
+  
+  AddingToPack = false;
 
-  unsigned NumArgs = FlatArgs.size() - PackBeginIndex;
-  TemplateArgument *Args = NumArgs ? &FlatArgs[PackBeginIndex] : 0;
+  StructuredArgs = new TemplateArgument[MaxStructuredArgs];
   
-  StructuredArgs.push_back(TemplateArgument(SourceLocation(), Args, NumArgs,
-                                            /*CopyArgs=*/false));
+  // First copy the flat entries over to the list  (if any)
+  for (unsigned I = 0; I != PackBeginIndex; ++I) {
+    NumStructuredArgs++;
+    StructuredArgs[I] = FlatArgs[I];
+  }
+  
+  // Next, set the pack.
+  TemplateArgument *PackArgs = 0;
+  unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
+  if (NumPackArgs)
+    PackArgs = &FlatArgs[PackBeginIndex];
   
-  PackBeginIndex = std::numeric_limits<unsigned>::max();
-}  
+  StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs, 
+                                                      /*CopyArgs=*/false);
+}
+
+void TemplateArgumentListBuilder::ReleaseArgs() {
+  FlatArgs = 0;
+  NumFlatArgs = 0;
+  MaxFlatArgs = 0;
+  StructuredArgs = 0;
+  NumStructuredArgs = 0;
+  MaxStructuredArgs = 0;
+}
 
 //===----------------------------------------------------------------------===//
 // TemplateArgumentList Implementation
 //===----------------------------------------------------------------------===//
 TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
                                            TemplateArgumentListBuilder &Builder,
-                                           bool CopyArgs, bool FlattenArgs)
-  : NumArguments(Builder.flatSize()) {
-  if (!CopyArgs) {
-    Arguments.setPointer(Builder.getFlatArgumentList());
-    Arguments.setInt(1);
-    return;
-  }
-
+                                           bool TakeArgs)
+  : FlatArguments(Builder.getFlatArguments(), TakeArgs), 
+    NumFlatArguments(Builder.flatSize()), 
+    StructuredArguments(Builder.getStructuredArguments(), TakeArgs),
+    NumStructuredArguments(Builder.structuredSize()) {
   
-  unsigned Size = sizeof(TemplateArgument) * Builder.flatSize();
-  unsigned Align = llvm::AlignOf<TemplateArgument>::Alignment;
-  void *Mem = Context.Allocate(Size, Align);
-  Arguments.setPointer((TemplateArgument *)Mem);
-  Arguments.setInt(0);
-
-  TemplateArgument *Args = (TemplateArgument *)Mem;
-  for (unsigned I = 0; I != NumArguments; ++I)
-    new (Args + I) TemplateArgument(Builder.getFlatArgumentList()[I]);
+  if (!TakeArgs)
+    return;
+    
+  if (Builder.getStructuredArguments() == Builder.getFlatArguments())
+    StructuredArguments.setInt(0);
+  Builder.ReleaseArgs();
 }
 
 TemplateArgumentList::~TemplateArgumentList() {
@@ -333,7 +357,7 @@
                   // class template specializations?
                   SpecializedTemplate->getIdentifier()),
     SpecializedTemplate(SpecializedTemplate),
-    TemplateArgs(Context, Builder, /*CopyArgs=*/true, /*FlattenArgs=*/true),
+    TemplateArgs(Context, Builder, /*TakeArgs=*/true),
     SpecializationKind(TSK_Undeclared) {
 }
                   

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=73937&r1=73936&r2=73937&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Jun 22 20:26:57 2009
@@ -847,13 +847,14 @@
 
   // Check that the template argument list is well-formed for this
   // template.
-  TemplateArgumentListBuilder ConvertedTemplateArgs(Context);
+  TemplateArgumentListBuilder Converted(Template->getTemplateParameters(),
+                                        NumTemplateArgs);
   if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc, 
                                 TemplateArgs, NumTemplateArgs, RAngleLoc,
-                                ConvertedTemplateArgs))
+                                Converted))
     return QualType();
 
-  assert((ConvertedTemplateArgs.structuredSize() == 
+  assert((Converted.structuredSize() == 
             Template->getTemplateParameters()->size()) &&
          "Converted template argument list is too short!");
 
@@ -871,16 +872,16 @@
     //   template<typename T, typename U = T> struct A;
     TemplateName CanonName = Context.getCanonicalTemplateName(Name);
     CanonType = Context.getTemplateSpecializationType(CanonName, 
-                                    ConvertedTemplateArgs.getFlatArgumentList(),
-                                    ConvertedTemplateArgs.flatSize());
+                                                   Converted.getFlatArguments(),
+                                                   Converted.flatSize());
   } else if (ClassTemplateDecl *ClassTemplate 
                = dyn_cast<ClassTemplateDecl>(Template)) {
     // Find the class template specialization declaration that
     // corresponds to these arguments.
     llvm::FoldingSetNodeID ID;
     ClassTemplateSpecializationDecl::Profile(ID, 
-                                    ConvertedTemplateArgs.getFlatArgumentList(),
-                                    ConvertedTemplateArgs.flatSize());
+                                             Converted.getFlatArguments(),
+                                             Converted.flatSize());
     void *InsertPos = 0;
     ClassTemplateSpecializationDecl *Decl
       = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
@@ -892,7 +893,7 @@
                                     ClassTemplate->getDeclContext(),
                                     TemplateLoc,
                                     ClassTemplate,
-                                    ConvertedTemplateArgs, 0);
+                                    Converted, 0);
       ClassTemplate->getSpecializations().InsertNode(Decl, InsertPos);
       Decl->setLexicalDeclContext(CurContext);
     }
@@ -1003,7 +1004,7 @@
     return true;
   
   // Add the converted template type argument.
-  Converted.push_back(
+  Converted.Append(
                  TemplateArgument(Arg.getLocation(),
                                   Context.getCanonicalType(Arg.getAsType())));
   return false;
@@ -1061,9 +1062,9 @@
       // parameter.
       if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
         if (TTP->isParameterPack()) {
-          // We have an empty parameter pack.
-          Converted.BeginParameterPack();
-          Converted.EndParameterPack();
+          // We have an empty argument pack.
+          Converted.BeginPack();
+          Converted.EndPack();
           break;
         }
         
@@ -1076,13 +1077,12 @@
         // on the previously-computed template arguments.
         if (ArgType->isDependentType()) {
           InstantiatingTemplate Inst(*this, TemplateLoc, 
-                                     Template, Converted.getFlatArgumentList(),
+                                     Template, Converted.getFlatArguments(),
                                      Converted.flatSize(),
                                      SourceRange(TemplateLoc, RAngleLoc));
 
           TemplateArgumentList TemplateArgs(Context, Converted,
-                                            /*CopyArgs=*/false,
-                                            /*FlattenArgs=*/false);
+                                            /*TakeArgs=*/false);
           ArgType = InstantiateType(ArgType, TemplateArgs,
                                     TTP->getDefaultArgumentLoc(),
                                     TTP->getDeclName());
@@ -1098,13 +1098,12 @@
           break;
 
         InstantiatingTemplate Inst(*this, TemplateLoc, 
-                                   Template, Converted.getFlatArgumentList(),
+                                   Template, Converted.getFlatArguments(),
                                    Converted.flatSize(),
                                    SourceRange(TemplateLoc, RAngleLoc));
         
         TemplateArgumentList TemplateArgs(Context, Converted,
-                                          /*CopyArgs=*/false,
-                                          /*FlattenArgs=*/false);
+                                          /*TakeArgs=*/false);
 
         Sema::OwningExprResult E = InstantiateExpr(NTTP->getDefaultArgument(), 
                                                    TemplateArgs);
@@ -1130,14 +1129,14 @@
 
     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
       if (TTP->isParameterPack()) {
-        Converted.BeginParameterPack();
+        Converted.BeginPack();
         // Check all the remaining arguments (if any).
         for (; ArgIdx < NumArgs; ++ArgIdx) {
           if (CheckTemplateTypeArgument(TTP, TemplateArgs[ArgIdx], Converted))
             Invalid = true;
         }
         
-        Converted.EndParameterPack();
+        Converted.EndPack();
       } else {
         if (CheckTemplateTypeArgument(TTP, Arg, Converted))
           Invalid = true;
@@ -1152,13 +1151,12 @@
       if (NTTPType->isDependentType()) {
         // Instantiate the type of the non-type template parameter.
         InstantiatingTemplate Inst(*this, TemplateLoc, 
-                                   Template, Converted.getFlatArgumentList(),
+                                   Template, Converted.getFlatArguments(),
                                    Converted.flatSize(),
                                    SourceRange(TemplateLoc, RAngleLoc));
 
         TemplateArgumentList TemplateArgs(Context, Converted,
-                                          /*CopyArgs=*/false,
-                                          /*FlattenArgs=*/false);
+                                          /*TakeArgs=*/false);
         NTTPType = InstantiateType(NTTPType, TemplateArgs,
                                    NTTP->getLocation(),
                                    NTTP->getDeclName());
@@ -1167,7 +1165,6 @@
         if (!NTTPType.isNull())
           NTTPType = CheckNonTypeTemplateParameterType(NTTPType, 
                                                        NTTP->getLocation());
-
         if (NTTPType.isNull()) {
           Invalid = true;
           break;
@@ -1185,7 +1182,7 @@
         if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
           Invalid = true;
         else
-          Converted.push_back(Result);
+          Converted.Append(Result);
         break;
       }
 
@@ -1193,7 +1190,7 @@
       case TemplateArgument::Integral:
         // We've already checked this template argument, so just copy
         // it to the list of converted arguments.
-        Converted.push_back(Arg);
+        Converted.Append(Arg);
         break;
 
       case TemplateArgument::Type:
@@ -1240,7 +1237,7 @@
           // Add the converted template argument.
           Decl *D 
             = Context.getCanonicalDecl(cast<DeclRefExpr>(ArgExpr)->getDecl());
-          Converted.push_back(TemplateArgument(Arg.getLocation(), D));
+          Converted.Append(TemplateArgument(Arg.getLocation(), D));
           continue;
         }
       }
@@ -1257,7 +1254,7 @@
       case TemplateArgument::Declaration:
         // We've already checked this template argument, so just copy
         // it to the list of converted arguments.
-        Converted.push_back(Arg);
+        Converted.Append(Arg);
         break;
         
       case TemplateArgument::Integral:
@@ -2102,7 +2099,7 @@
   // accommodate variadic templates.
   MirrorsPrimaryTemplate = true;
   
-  const TemplateArgument *ArgList = TemplateArgs.getFlatArgumentList();
+  const TemplateArgument *ArgList = TemplateArgs.getFlatArguments();
   
   for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
     // Determine whether the template argument list of the partial
@@ -2298,13 +2295,14 @@
 
   // Check that the template argument list is well-formed for this
   // template.
-  TemplateArgumentListBuilder ConvertedTemplateArgs(Context);
+  TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
+                                        TemplateArgs.size());
   if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc, 
                                 TemplateArgs.data(), TemplateArgs.size(),
-                                RAngleLoc, ConvertedTemplateArgs))
+                                RAngleLoc, Converted))
     return true;
 
-  assert((ConvertedTemplateArgs.structuredSize() == 
+  assert((Converted.structuredSize() == 
             ClassTemplate->getTemplateParameters()->size()) &&
          "Converted template argument list is too short!");
   
@@ -2315,8 +2313,7 @@
     bool MirrorsPrimaryTemplate;
     if (CheckClassTemplatePartialSpecializationArgs(
                                          ClassTemplate->getTemplateParameters(),
-                                         ConvertedTemplateArgs,
-                                         MirrorsPrimaryTemplate))
+                                         Converted, MirrorsPrimaryTemplate))
       return true;
 
     if (MirrorsPrimaryTemplate) {
@@ -2338,13 +2335,13 @@
 
     // FIXME: Template parameter list matters, too
     ClassTemplatePartialSpecializationDecl::Profile(ID, 
-                                    ConvertedTemplateArgs.getFlatArgumentList(),
-                                              ConvertedTemplateArgs.flatSize());
+                                                   Converted.getFlatArguments(),
+                                                   Converted.flatSize());
   }
   else
     ClassTemplateSpecializationDecl::Profile(ID,
-                                    ConvertedTemplateArgs.getFlatArgumentList(),
-                                             ConvertedTemplateArgs.flatSize());
+                                             Converted.getFlatArguments(),
+                                             Converted.flatSize());
   void *InsertPos = 0;
   ClassTemplateSpecializationDecl *PrevDecl = 0;
 
@@ -2387,7 +2384,7 @@
                                                        TemplateNameLoc,
                                                        TemplateParams,
                                                        ClassTemplate,
-                                                       ConvertedTemplateArgs,
+                                                       Converted,
                                                        PrevPartial);
 
     if (PrevPartial) {
@@ -2437,7 +2434,7 @@
                                              ClassTemplate->getDeclContext(),
                                                 TemplateNameLoc,
                                                 ClassTemplate, 
-                                                ConvertedTemplateArgs,
+                                                Converted,
                                                 PrevDecl);
 
     if (PrevDecl) {
@@ -2559,13 +2556,14 @@
 
   // Check that the template argument list is well-formed for this
   // template.
-  TemplateArgumentListBuilder ConvertedTemplateArgs(Context);
+  TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
+                                        TemplateArgs.size());
   if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc, 
                                 TemplateArgs.data(), TemplateArgs.size(),
-                                RAngleLoc, ConvertedTemplateArgs))
+                                RAngleLoc, Converted))
     return true;
 
-  assert((ConvertedTemplateArgs.structuredSize() == 
+  assert((Converted.structuredSize() == 
             ClassTemplate->getTemplateParameters()->size()) &&
          "Converted template argument list is too short!");
   
@@ -2573,8 +2571,8 @@
   // corresponds to these arguments.
   llvm::FoldingSetNodeID ID;
   ClassTemplateSpecializationDecl::Profile(ID, 
-                                    ConvertedTemplateArgs.getFlatArgumentList(),
-                                           ConvertedTemplateArgs.flatSize());
+                                           Converted.getFlatArguments(),
+                                           Converted.flatSize());
   void *InsertPos = 0;
   ClassTemplateSpecializationDecl *PrevDecl
     = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
@@ -2617,7 +2615,7 @@
                                              ClassTemplate->getDeclContext(),
                                                   TemplateNameLoc,
                                                   ClassTemplate,
-                                                  ConvertedTemplateArgs, 0);
+                                                  Converted, 0);
       Specialization->setLexicalDeclContext(CurContext);
       CurContext->addDecl(Context, Specialization);
       return DeclPtrTy::make(Specialization);
@@ -2643,7 +2641,7 @@
                                              ClassTemplate->getDeclContext(),
                                                 TemplateNameLoc,
                                                 ClassTemplate,
-                                                ConvertedTemplateArgs, 0);
+                                                Converted, 0);
 
     ClassTemplate->getSpecializations().InsertNode(Specialization, 
                                                    InsertPos);

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=73937&r1=73936&r2=73937&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Mon Jun 22 20:26:57 2009
@@ -654,7 +654,8 @@
   // C++ [temp.deduct.type]p2:
   //   [...] or if any template argument remains neither deduced nor
   //   explicitly specified, template argument deduction fails.
-  TemplateArgumentListBuilder Builder(Context);
+  TemplateArgumentListBuilder Builder(Partial->getTemplateParameters(),
+                                      Deduced.size());
   for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
     if (Deduced[I].isNull()) {
       Decl *Param 
@@ -669,13 +670,12 @@
       return TDK_Incomplete;
     }
 
-    Builder.push_back(Deduced[I]);
+    Builder.Append(Deduced[I]);
   }
 
   // Form the template argument list from the deduced template arguments.
   TemplateArgumentList *DeducedArgumentList 
-    = new (Context) TemplateArgumentList(Context, Builder, /*CopyArgs=*/true,
-                                         /*FlattenArgs=*/true);
+    = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
   Info.reset(DeducedArgumentList);
 
   // Substitute the deduced template arguments into the template





More information about the cfe-commits mailing list