From: Anders Carlsson Date: Tue, 23 Jun 2009 01:26:57 +0000 (+0000) Subject: Check in a new template argument list builder that should work better for variadic... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fb25052736439d72a557cddd41dfb927bcb3d3e5;p=clang Check in a new template argument list builder that should work better for variadic templates. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73937 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index af06965f84..2608dd9d31 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -469,10 +469,6 @@ public: /// 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 @@ public: /// \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 @@ public: /// \brief A helper class for making template argument lists. class TemplateArgumentListBuilder { - /// FlatArgs - contains the template arguments in flat form. - llvm::SmallVector FlatArgs; - - llvm::SmallVector 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::max(); - } public: - TemplateArgumentListBuilder(ASTContext &Context) : Context(Context), - PackBeginIndex(std::numeric_limits::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 @@ class TemplateArgumentList { /// /// The integer value will be non-zero to indicate that this /// template argument list does not own the pointer. - llvm::PointerIntPair Arguments; + llvm::PointerIntPair FlatArguments; /// \brief The number of template arguments in this template /// argument list. - unsigned NumArguments; + unsigned NumFlatArguments; + llvm::PointerIntPair 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 @@ public: /// \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(); } }; diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index 23c2637875..165672d50f 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -239,79 +239,103 @@ TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) { } /// \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 (!FlatArgs) + FlatArgs = new TemplateArgument[MaxFlatArgs]; - if (!isAddingFromParameterPack()) - StructuredArgs.push_back(Arg); + 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]; + + // First copy the flat entries over to the list (if any) + for (unsigned I = 0; I != PackBeginIndex; ++I) { + NumStructuredArgs++; + StructuredArgs[I] = FlatArgs[I]; + } - StructuredArgs.push_back(TemplateArgument(SourceLocation(), Args, NumArgs, - /*CopyArgs=*/false)); + // Next, set the pack. + TemplateArgument *PackArgs = 0; + unsigned NumPackArgs = NumFlatArgs - PackBeginIndex; + if (NumPackArgs) + PackArgs = &FlatArgs[PackBeginIndex]; - PackBeginIndex = std::numeric_limits::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::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 @@ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, // class template specializations? SpecializedTemplate->getIdentifier()), SpecializedTemplate(SpecializedTemplate), - TemplateArgs(Context, Builder, /*CopyArgs=*/true, /*FlattenArgs=*/true), + TemplateArgs(Context, Builder, /*TakeArgs=*/true), SpecializationKind(TSK_Undeclared) { } diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index fb41b2b753..e98ebb13f8 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -847,13 +847,14 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // 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 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // template 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(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 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, ClassTemplate->getDeclContext(), TemplateLoc, ClassTemplate, - ConvertedTemplateArgs, 0); + Converted, 0); ClassTemplate->getSpecializations().InsertNode(Decl, InsertPos); Decl->setLexicalDeclContext(CurContext); } @@ -1003,7 +1004,7 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, 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 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // parameter. if (TemplateTypeParmDecl *TTP = dyn_cast(*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 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // 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 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, 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 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, if (TemplateTypeParmDecl *TTP = dyn_cast(*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 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, 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 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, if (!NTTPType.isNull()) NTTPType = CheckNonTypeTemplateParameterType(NTTPType, NTTP->getLocation()); - if (NTTPType.isNull()) { Invalid = true; break; @@ -1185,7 +1182,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, if (CheckTemplateArgument(NTTP, NTTPType, E, Result)) Invalid = true; else - Converted.push_back(Result); + Converted.Append(Result); break; } @@ -1193,7 +1190,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, 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 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // Add the converted template argument. Decl *D = Context.getCanonicalDecl(cast(ArgExpr)->getDecl()); - Converted.push_back(TemplateArgument(Arg.getLocation(), D)); + Converted.Append(TemplateArgument(Arg.getLocation(), D)); continue; } } @@ -1257,7 +1254,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, 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 @@ bool Sema::CheckClassTemplatePartialSpecializationArgs( // 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 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, // 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 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, bool MirrorsPrimaryTemplate; if (CheckClassTemplatePartialSpecializationArgs( ClassTemplate->getTemplateParameters(), - ConvertedTemplateArgs, - MirrorsPrimaryTemplate)) + Converted, MirrorsPrimaryTemplate)) return true; if (MirrorsPrimaryTemplate) { @@ -2338,13 +2335,13 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, // 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 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, TemplateNameLoc, TemplateParams, ClassTemplate, - ConvertedTemplateArgs, + Converted, PrevPartial); if (PrevPartial) { @@ -2437,7 +2434,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, ClassTemplate->getDeclContext(), TemplateNameLoc, ClassTemplate, - ConvertedTemplateArgs, + Converted, PrevDecl); if (PrevDecl) { @@ -2559,13 +2556,14 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, // 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 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, // 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 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, ClassTemplate->getDeclContext(), TemplateNameLoc, ClassTemplate, - ConvertedTemplateArgs, 0); + Converted, 0); Specialization->setLexicalDeclContext(CurContext); CurContext->addDecl(Context, Specialization); return DeclPtrTy::make(Specialization); @@ -2643,7 +2641,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, ClassTemplate->getDeclContext(), TemplateNameLoc, ClassTemplate, - ConvertedTemplateArgs, 0); + Converted, 0); ClassTemplate->getSpecializations().InsertNode(Specialization, InsertPos); diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 784e451804..de3e52df37 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -654,7 +654,8 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, // 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 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, 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