From: Douglas Gregor Date: Sun, 7 Nov 2010 23:05:16 +0000 (+0000) Subject: Remove broken support for variadic templates, along with the various X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=910f8008fea79120489a53593fe971b0b8a4a740;p=clang Remove broken support for variadic templates, along with the various abstractions (e.g., TemplateArgumentListBuilder) that were designed to support variadic templates. Only a few remnants of variadic templates remain, in the parser (parsing template type parameter packs), AST (template type parameter pack bits and TemplateArgument::Pack), and Sema; these are expected to be used in a future implementation of variadic templates. But don't get too excited about that happening now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118385 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 96ab4a8a1c..bde2e24e19 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -85,7 +85,7 @@ public: return begin()[Idx]; } - /// \btief Returns the minimum number of arguments needed to form a + /// \brief Returns the minimum number of arguments needed to form a /// template specialization. This may be fewer than the number of /// template parameters, if some of the parameters have default /// arguments or if there is a parameter pack. @@ -107,101 +107,57 @@ public: } }; -/// \brief A helper class for making template argument lists. -class TemplateArgumentListBuilder { - TemplateArgument *StructuredArgs; - unsigned MaxStructuredArgs; - unsigned NumStructuredArgs; - - llvm::SmallVector FlatArgs; - unsigned MaxFlatArgs; - unsigned NumFlatArgs; - - bool AddingToPack; - unsigned PackBeginIndex; - -public: - 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) { } - - void Append(const TemplateArgument &Arg); - void BeginPack(); - void EndPack(); - - unsigned flatSize() const { return FlatArgs.size(); } - const TemplateArgument *getFlatArguments() 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; - } - const TemplateArgument *getStructuredArguments() const { - // If we don't have any structured args, just reuse the flat args. - if (!StructuredArgs) - return getFlatArguments(); - - return StructuredArgs; - } -}; - /// \brief A template argument list. -/// -/// FIXME: In the future, this class will be extended to support -/// variadic templates and member templates, which will make some of -/// the function names below make more sense. class TemplateArgumentList { /// \brief The template argument list. /// /// The integer value will be non-zero to indicate that this /// template argument list does own the pointer. - llvm::PointerIntPair FlatArguments; + llvm::PointerIntPair Arguments; /// \brief The number of template arguments in this template /// argument list. - unsigned NumFlatArguments; - - llvm::PointerIntPair StructuredArguments; - unsigned NumStructuredArguments; + unsigned NumArguments; TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL void operator=(const TemplateArgumentList &Other); // DO NOT IMPL + + TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs, + bool Owned) + : Arguments(Args, Owned), NumArguments(NumArgs) { } + public: - /// TemplateArgumentList - If this constructor is passed "true" for 'TakeArgs' - /// it copies them into a locally new[]'d array. If passed "false", then it - /// just references the array passed in. This is only safe if the builder - /// outlives it, but saves a copy. - TemplateArgumentList(ASTContext &Context, - TemplateArgumentListBuilder &Builder, - bool TakeArgs); - - /// TemplateArgumentList - It copies the template arguments into a locally - /// new[]'d array. - TemplateArgumentList(ASTContext &Context, - const TemplateArgument *Args, unsigned NumArgs); - - /// Produces a shallow copy of the given template argument list. This - /// assumes that the input argument list outlives it. This takes the list as - /// a pointer to avoid looking like a copy constructor, since this really - /// really isn't safe to use that way. - explicit TemplateArgumentList(const TemplateArgumentList *Other); - - TemplateArgumentList() : NumFlatArguments(0), NumStructuredArguments(0) { } - - /// \brief Copies the template arguments into a locally new[]'d array. - void init(ASTContext &Context, - const TemplateArgument *Args, unsigned NumArgs); + /// \brief Type used to indicate that the template argument list itself is a + /// stack object. It does not own its template arguments. + enum OnStackType { OnStack }; + + /// \brief Create a new template argument list that copies the given set of + /// template arguments. + static TemplateArgumentList *CreateCopy(ASTContext &Context, + const TemplateArgument *Args, + unsigned NumArgs); + + /// \brief Construct a new, temporary template argument list on the stack. + /// + /// The template argument list does not own the template arguments + /// provided. + explicit TemplateArgumentList(OnStackType, + const TemplateArgument *Args, unsigned NumArgs) + : Arguments(Args, false), NumArguments(NumArgs) { } + + /// \brief Produces a shallow copy of the given template argument list. + /// + /// This operation assumes that the input argument list outlives it. + /// This takes the list as a pointer to avoid looking like a copy + /// constructor, since this really really isn't safe to use that + /// way. + explicit TemplateArgumentList(const TemplateArgumentList *Other) + : Arguments(Other->data(), false), NumArguments(Other->size()) { } /// \brief Retrieve the template argument at a given index. const TemplateArgument &get(unsigned Idx) const { - assert(Idx < NumFlatArguments && "Invalid template argument index"); - return getFlatArgumentList()[Idx]; + assert(Idx < NumArguments && "Invalid template argument index"); + return data()[Idx]; } /// \brief Retrieve the template argument at a given index. @@ -209,15 +165,11 @@ public: /// \brief Retrieve the number of template arguments in this /// template argument list. - unsigned size() const { return NumFlatArguments; } - - /// \brief Retrieve the number of template arguments in the - /// flattened template argument list. - unsigned flat_size() const { return NumFlatArguments; } + unsigned size() const { return NumArguments; } - /// \brief Retrieve the flattened template argument list. - const TemplateArgument *getFlatArgumentList() const { - return FlatArguments.getPointer(); + /// \brief Retrieve a pointer to the template argument list. + const TemplateArgument *data() const { + return Arguments.getPointer(); } }; @@ -369,8 +321,8 @@ public: } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, TemplateArguments->getFlatArgumentList(), - TemplateArguments->flat_size(), + Profile(ID, TemplateArguments->data(), + TemplateArguments->size(), Function->getASTContext()); } @@ -1229,7 +1181,7 @@ class ClassTemplateSpecializationDecl ExplicitSpecializationInfo *ExplicitInfo; /// \brief The template arguments used to describe this specialization. - TemplateArgumentList TemplateArgs; + TemplateArgumentList *TemplateArgs; /// \brief The point where this template was instantiated (if any) SourceLocation PointOfInstantiation; @@ -1242,7 +1194,8 @@ protected: ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, - TemplateArgumentListBuilder &Builder, + const TemplateArgument *Args, + unsigned NumArgs, ClassTemplateSpecializationDecl *PrevDecl); explicit ClassTemplateSpecializationDecl(Kind DK); @@ -1251,7 +1204,8 @@ public: static ClassTemplateSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, - TemplateArgumentListBuilder &Builder, + const TemplateArgument *Args, + unsigned NumArgs, ClassTemplateSpecializationDecl *PrevDecl); static ClassTemplateSpecializationDecl * Create(ASTContext &Context, EmptyShell Empty); @@ -1277,7 +1231,7 @@ public: /// \brief Retrieve the template arguments of the class template /// specialization. const TemplateArgumentList &getTemplateArgs() const { - return TemplateArgs; + return *TemplateArgs; } /// \brief Determine the kind of specialization that this @@ -1413,8 +1367,7 @@ public: SourceLocation getInnerLocStart() const { return getTemplateKeywordLoc(); } void Profile(llvm::FoldingSetNodeID &ID) const { - Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(), - getASTContext()); + Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext()); } static void @@ -1470,15 +1423,16 @@ class ClassTemplatePartialSpecializationDecl DeclContext *DC, SourceLocation L, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, - TemplateArgumentListBuilder &Builder, + const TemplateArgument *Args, + unsigned NumArgs, TemplateArgumentLoc *ArgInfos, unsigned NumArgInfos, ClassTemplatePartialSpecializationDecl *PrevDecl, unsigned SequenceNumber) : ClassTemplateSpecializationDecl(Context, ClassTemplatePartialSpecialization, - TK, DC, L, SpecializedTemplate, Builder, - PrevDecl), + TK, DC, L, SpecializedTemplate, + Args, NumArgs, PrevDecl), TemplateParams(Params), ArgsAsWritten(ArgInfos), NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber), InstantiatedFromMember(0, false) { } @@ -1494,7 +1448,8 @@ public: Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, - TemplateArgumentListBuilder &Builder, + const TemplateArgument *Args, + unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos, QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl, diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 7d5123fb04..3d16ac8e84 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -44,7 +44,6 @@ class TemplateArgument { struct { TemplateArgument *Args; unsigned NumArgs; - bool CopyArgs; } Args; }; @@ -92,6 +91,8 @@ public: /// \brief Construct an integral constant template argument. TemplateArgument(const llvm::APSInt &Value, QualType Type) : Kind(Integral) { + // FIXME: Large integral values will get leaked. Do something + // similar to what we did with IntegerLiteral. new (Integer.Value) llvm::APSInt(Value); Integer.Type = Type.getAsOpaquePtr(); } @@ -115,46 +116,54 @@ public: TypeOrValue = reinterpret_cast(E); } + /// \brief Construct a template argument that is a template argument pack. + /// + /// We assume that storage for the template arguments provided + /// outlives the TemplateArgument itself. + TemplateArgument(TemplateArgument *Args, unsigned NumArgs) : Kind(Pack) { + this->Args.Args = Args; + this->Args.NumArgs = NumArgs; + } + /// \brief Copy constructor for a template argument. TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) { + // FIXME: Large integral values will get leaked. Do something + // similar to what we did with IntegerLiteral. 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]; + Args.Args = Other.Args.Args; } else TypeOrValue = Other.TypeOrValue; } TemplateArgument& operator=(const TemplateArgument& Other) { - // FIXME: Does not provide the strong guarantee for exception - // safety. using llvm::APSInt; - // FIXME: Handle Packs - assert(Kind != Pack && "FIXME: Handle packs"); - assert(Other.Kind != Pack && "FIXME: Handle packs"); - if (Kind == Other.Kind && Kind == Integral) { // Copy integral values. *this->getAsIntegral() = *Other.getAsIntegral(); Integer.Type = Other.Integer.Type; - } else { - // Destroy the current integral value, if that's what we're holding. - if (Kind == Integral) - getAsIntegral()->~APSInt(); + return *this; + } + + // Destroy the current integral value, if that's what we're holding. + if (Kind == Integral) + getAsIntegral()->~APSInt(); - Kind = Other.Kind; + Kind = Other.Kind; - if (Other.Kind == Integral) { - new (Integer.Value) llvm::APSInt(*Other.getAsIntegral()); - Integer.Type = Other.Integer.Type; - } else - TypeOrValue = Other.TypeOrValue; + if (Other.Kind == Integral) { + new (Integer.Value) llvm::APSInt(*Other.getAsIntegral()); + Integer.Type = Other.Integer.Type; + } else if (Other.Kind == Pack) { + Args.NumArgs = Other.Args.NumArgs; + Args.Args = Other.Args.Args; + } else { + TypeOrValue = Other.TypeOrValue; } return *this; @@ -165,8 +174,6 @@ public: if (Kind == Integral) getAsIntegral()->~APSInt(); - else if (Kind == Pack && Args.CopyArgs) - delete[] Args.Args; } /// \brief Return the kind of stored template argument. @@ -260,9 +267,6 @@ public: /// same. bool structurallyEquals(const TemplateArgument &Other) const; - /// \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, ASTContext &Context) const; }; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index a5b0aa5ec1..8f36ec9db0 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1769,6 +1769,8 @@ def ext_template_outside_of_template : ExtWarn< "'template' keyword outside of a template">; // C++0x Variadic Templates +def err_variadic_templates_unsupported : Error< + "variadic templates are not yet implemented">; def err_template_param_pack_default_arg : Error< "template parameter pack cannot have a default argument">; def err_template_param_pack_must_be_last_template_parameter : Error< diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 54357eb1da..8e99ca1eb3 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -121,7 +121,6 @@ namespace clang { class TargetAttributesSema; class TemplateArgument; class TemplateArgumentList; - class TemplateArgumentListBuilder; class TemplateArgumentLoc; class TemplateDecl; class TemplateParameterList; @@ -2883,7 +2882,7 @@ public: bool CheckClassTemplatePartialSpecializationArgs( TemplateParameterList *TemplateParams, - const TemplateArgumentListBuilder &TemplateArgs, + llvm::SmallVectorImpl &TemplateArgs, bool &MirrorsPrimaryTemplate); DeclResult @@ -2958,7 +2957,7 @@ public: SourceLocation TemplateLoc, SourceLocation RAngleLoc, Decl *Param, - TemplateArgumentListBuilder &Converted); + llvm::SmallVectorImpl &Converted); /// \brief Specifies the context in which a particular template /// argument is being checked. @@ -2981,18 +2980,18 @@ public: TemplateDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, - TemplateArgumentListBuilder &Converted, + llvm::SmallVectorImpl &Converted, CheckTemplateArgumentKind CTAK = CTAK_Specified); bool CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, const TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs, - TemplateArgumentListBuilder &Converted); + llvm::SmallVectorImpl &Converted); bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, const TemplateArgumentLoc &Arg, - TemplateArgumentListBuilder &Converted); + llvm::SmallVectorImpl &Converted); bool CheckTemplateArgument(TemplateTypeParmDecl *Param, TypeSourceInfo *Arg); diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index a7b3b84618..23f1438f37 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -82,9 +82,8 @@ namespace clang { /// \brief Add a new outermost level to the multi-level template argument /// list. void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) { - TemplateArgumentLists.push_back( - ArgList(TemplateArgs->getFlatArgumentList(), - TemplateArgs->flat_size())); + TemplateArgumentLists.push_back(ArgList(TemplateArgs->data(), + TemplateArgs->size())); } /// \brief Add a new outmost level to the multi-level template argument diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 8f87b2f23b..b2451a2d86 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2684,17 +2684,15 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) { return TemplateArgument(getCanonicalType(Arg.getAsType())); case TemplateArgument::Pack: { - // FIXME: Allocate in ASTContext - TemplateArgument *CanonArgs = new TemplateArgument[Arg.pack_size()]; + TemplateArgument *CanonArgs + = new (*this) TemplateArgument[Arg.pack_size()]; unsigned Idx = 0; for (TemplateArgument::pack_iterator A = Arg.pack_begin(), AEnd = Arg.pack_end(); A != AEnd; (void)++A, ++Idx) CanonArgs[Idx] = getCanonicalTemplateArgument(*A); - TemplateArgument Result; - Result.setArgumentPack(CanonArgs, Arg.pack_size(), false); - return Result; + return TemplateArgument(CanonArgs, Arg.pack_size()); } } @@ -3897,8 +3895,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); std::string TemplateArgsStr = TemplateSpecializationType::PrintTemplateArgumentList( - TemplateArgs.getFlatArgumentList(), - TemplateArgs.flat_size(), + TemplateArgs.data(), + TemplateArgs.size(), (*this).PrintingPolicy); S += TemplateArgsStr; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index c88f79b29f..c448116ed2 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -164,8 +164,7 @@ static LVPair getLVForTemplateArgumentList(const TemplateArgument *Args, static LVPair getLVForTemplateArgumentList(const TemplateArgumentList &TArgs) { - return getLVForTemplateArgumentList(TArgs.getFlatArgumentList(), - TArgs.flat_size()); + return getLVForTemplateArgumentList(TArgs.data(), TArgs.size()); } /// getLVForDecl - Get the cached linkage and visibility for the given @@ -650,8 +649,8 @@ std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const { const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); std::string TemplateArgsStr = TemplateSpecializationType::PrintTemplateArgumentList( - TemplateArgs.getFlatArgumentList(), - TemplateArgs.flat_size(), + TemplateArgs.data(), + TemplateArgs.size(), P); OS << Spec->getName() << TemplateArgsStr; } else if (const NamespaceDecl *ND = dyn_cast(*I)) { @@ -1161,8 +1160,8 @@ void FunctionDecl::getNameForDiagnostic(std::string &S, const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs(); if (TemplateArgs) S += TemplateSpecializationType::PrintTemplateArgumentList( - TemplateArgs->getFlatArgumentList(), - TemplateArgs->flat_size(), + TemplateArgs->data(), + TemplateArgs->size(), Policy); } diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index c07d832073..cce434364f 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -19,6 +19,7 @@ #include "clang/AST/ASTMutationListener.h" #include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/STLExtras.h" +#include using namespace clang; //===----------------------------------------------------------------------===// @@ -393,121 +394,21 @@ TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params); } -//===----------------------------------------------------------------------===// -// TemplateArgumentListBuilder Implementation -//===----------------------------------------------------------------------===// - -void TemplateArgumentListBuilder::Append(const TemplateArgument &Arg) { - assert((Arg.getKind() != TemplateArgument::Type || - Arg.getAsType().isCanonical()) && "Type must be canonical!"); - assert(FlatArgs.size() < MaxFlatArgs && "Argument list builder is full!"); - assert(!StructuredArgs && - "Can't append arguments when an argument pack has been added!"); - - FlatArgs.push_back(Arg); -} - -void TemplateArgumentListBuilder::BeginPack() { - assert(!AddingToPack && "Already adding to pack!"); - assert(!StructuredArgs && "Argument list already contains a pack!"); - - AddingToPack = true; - PackBeginIndex = FlatArgs.size(); -} - -void TemplateArgumentListBuilder::EndPack() { - assert(AddingToPack && "Not adding to pack!"); - assert(!StructuredArgs && "Argument list already contains a pack!"); - - AddingToPack = false; - - // FIXME: This is a memory leak! - 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]; - } - - // Next, set the pack. - TemplateArgument *PackArgs = 0; - unsigned NumPackArgs = NumFlatArgs - PackBeginIndex; - // FIXME: NumPackArgs shouldn't be negative here??? - if (NumPackArgs) - PackArgs = FlatArgs.data()+PackBeginIndex; - - StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs, - /*CopyArgs=*/false); -} - //===----------------------------------------------------------------------===// // TemplateArgumentList Implementation //===----------------------------------------------------------------------===// -TemplateArgumentList::TemplateArgumentList(ASTContext &Context, - TemplateArgumentListBuilder &Builder, - bool TakeArgs) - : FlatArguments(Builder.getFlatArguments(), TakeArgs), - NumFlatArguments(Builder.flatSize()), - StructuredArguments(Builder.getStructuredArguments(), TakeArgs), - NumStructuredArguments(Builder.structuredSize()) { - - if (!TakeArgs) - return; - - // If this does take ownership of the arguments, then we have to new them - // and copy over. - TemplateArgument *NewArgs = - new (Context) TemplateArgument[Builder.flatSize()]; - std::copy(Builder.getFlatArguments(), - Builder.getFlatArguments()+Builder.flatSize(), NewArgs); - FlatArguments.setPointer(NewArgs); - - // Just reuse the structured and flat arguments array if possible. - if (Builder.getStructuredArguments() == Builder.getFlatArguments()) { - StructuredArguments.setPointer(NewArgs); - StructuredArguments.setInt(0); - } else { - TemplateArgument *NewSArgs = - new (Context) TemplateArgument[Builder.flatSize()]; - std::copy(Builder.getFlatArguments(), - Builder.getFlatArguments()+Builder.flatSize(), NewSArgs); - StructuredArguments.setPointer(NewSArgs); - } -} - -TemplateArgumentList::TemplateArgumentList(ASTContext &Context, - const TemplateArgument *Args, - unsigned NumArgs) - : NumFlatArguments(0), NumStructuredArguments(0) { - init(Context, Args, NumArgs); -} - -/// Produces a shallow copy of the given template argument list. This -/// assumes that the input argument list outlives it. This takes the list as -/// a pointer to avoid looking like a copy constructor, since this really -/// really isn't safe to use that way. -TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList *Other) - : FlatArguments(Other->FlatArguments.getPointer(), false), - NumFlatArguments(Other->flat_size()), - StructuredArguments(Other->StructuredArguments.getPointer(), false), - NumStructuredArguments(Other->NumStructuredArguments) { } - -void TemplateArgumentList::init(ASTContext &Context, - const TemplateArgument *Args, - unsigned NumArgs) { -assert(NumFlatArguments == 0 && NumStructuredArguments == 0 && - "Already initialized!"); - -NumFlatArguments = NumStructuredArguments = NumArgs; -TemplateArgument *NewArgs = new (Context) TemplateArgument[NumArgs]; -std::copy(Args, Args+NumArgs, NewArgs); -FlatArguments.setPointer(NewArgs); -FlatArguments.setInt(1); // Owns the pointer. - -// Just reuse the flat arguments array. -StructuredArguments.setPointer(NewArgs); -StructuredArguments.setInt(0); // Doesn't own the pointer. +TemplateArgumentList * +TemplateArgumentList::CreateCopy(ASTContext &Context, + const TemplateArgument *Args, + unsigned NumArgs) { + std::size_t Size = sizeof(TemplateArgumentList) + + NumArgs * sizeof(TemplateArgument); + void *Mem = Context.Allocate(Size); + TemplateArgument *StoredArgs + = reinterpret_cast( + static_cast(Mem) + 1); + std::uninitialized_copy(Args, Args + NumArgs, StoredArgs); + return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true); } //===----------------------------------------------------------------------===// @@ -517,14 +418,15 @@ ClassTemplateSpecializationDecl:: ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, - TemplateArgumentListBuilder &Builder, + const TemplateArgument *Args, + unsigned NumArgs, ClassTemplateSpecializationDecl *PrevDecl) : CXXRecordDecl(DK, TK, DC, L, SpecializedTemplate->getIdentifier(), PrevDecl), SpecializedTemplate(SpecializedTemplate), ExplicitInfo(0), - TemplateArgs(Context, Builder, /*TakeArgs=*/true), + TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), SpecializationKind(TSK_Undeclared) { } @@ -538,14 +440,15 @@ ClassTemplateSpecializationDecl * ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, - TemplateArgumentListBuilder &Builder, + const TemplateArgument *Args, + unsigned NumArgs, ClassTemplateSpecializationDecl *PrevDecl) { ClassTemplateSpecializationDecl *Result = new (Context)ClassTemplateSpecializationDecl(Context, ClassTemplateSpecialization, TK, DC, L, SpecializedTemplate, - Builder, + Args, NumArgs, PrevDecl); Context.getTypeDeclType(Result, PrevDecl); return Result; @@ -565,8 +468,8 @@ ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S, const TemplateArgumentList &TemplateArgs = getTemplateArgs(); S += TemplateSpecializationType::PrintTemplateArgumentList( - TemplateArgs.getFlatArgumentList(), - TemplateArgs.flat_size(), + TemplateArgs.data(), + TemplateArgs.size(), Policy); } @@ -586,7 +489,8 @@ ClassTemplatePartialSpecializationDecl:: Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, - TemplateArgumentListBuilder &Builder, + const TemplateArgument *Args, + unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos, QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl, @@ -600,7 +504,7 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L, = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC, L, Params, SpecializedTemplate, - Builder, + Args, NumArgs, ClonedArgs, N, PrevDecl, SequenceNumber); diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp index a3bf1459c2..4a1ebb46c1 100644 --- a/lib/AST/TemplateBase.cpp +++ b/lib/AST/TemplateBase.cpp @@ -26,25 +26,6 @@ using namespace clang; // TemplateArgument Implementation //===----------------------------------------------------------------------===// -/// \brief Construct a template argument pack. -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; - } - - // FIXME: Allocate in ASTContext - Args.Args = new TemplateArgument[NumArgs]; - for (unsigned I = 0; I != Args.NumArgs; ++I) - Args.Args[I] = args[I]; -} - void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const { ID.AddInteger(Kind); diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index b8ce77b7f8..333a10ede7 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -426,8 +426,8 @@ void TypePrinter::AppendScope(DeclContext *DC, std::string &Buffer) { const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); std::string TemplateArgsStr = TemplateSpecializationType::PrintTemplateArgumentList( - TemplateArgs.getFlatArgumentList(), - TemplateArgs.flat_size(), + TemplateArgs.data(), + TemplateArgs.size(), Policy); Buffer += Spec->getIdentifier()->getName(); Buffer += TemplateArgsStr; @@ -506,8 +506,8 @@ void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) { NumArgs = TST->getNumArgs(); } else { const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); - Args = TemplateArgs.getFlatArgumentList(); - NumArgs = TemplateArgs.flat_size(); + Args = TemplateArgs.data(); + NumArgs = TemplateArgs.size(); } Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args, NumArgs, diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index aab6fe7d24..9229eeb85c 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -136,8 +136,8 @@ CGDebugInfo::getClassName(RecordDecl *RD) { NumArgs = TST->getNumArgs(); } else { const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); - Args = TemplateArgs.getFlatArgumentList(); - NumArgs = TemplateArgs.flat_size(); + Args = TemplateArgs.data(); + NumArgs = TemplateArgs.size(); } Buffer = RD->getIdentifier()->getNameStart(); PrintingPolicy Policy(CGM.getLangOptions()); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 9ac4ce88d1..38e45c8a5f 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -8039,8 +8039,7 @@ bool MarkReferencedDecls::TraverseRecordType(RecordType *T) { if (ClassTemplateSpecializationDecl *Spec = dyn_cast(T->getDecl())) { const TemplateArgumentList &Args = Spec->getTemplateArgs(); - return TraverseTemplateArguments(Args.getFlatArgumentList(), - Args.flat_size()); + return TraverseTemplateArguments(Args.data(), Args.size()); } return true; diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 49ae0d202a..d7c809f35d 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1507,14 +1507,12 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // Check that the template argument list is well-formed for this // template. - TemplateArgumentListBuilder Converted(Template->getTemplateParameters(), - TemplateArgs.size()); + llvm::SmallVector Converted; if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs, false, Converted)) return QualType(); - assert((Converted.structuredSize() == - Template->getTemplateParameters()->size()) && + assert((Converted.size() == Template->getTemplateParameters()->size()) && "Converted template argument list is too short!"); QualType CanonType; @@ -1531,8 +1529,8 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // template struct A; TemplateName CanonName = Context.getCanonicalTemplateName(Name); CanonType = Context.getTemplateSpecializationType(CanonName, - Converted.getFlatArguments(), - Converted.flatSize()); + Converted.data(), + Converted.size()); // FIXME: CanonType is not actually the canonical type, and unfortunately // it is a TemplateSpecializationType that we will never use again. @@ -1583,8 +1581,8 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // corresponds to these arguments. void *InsertPos = 0; ClassTemplateSpecializationDecl *Decl - = ClassTemplate->findSpecialization(Converted.getFlatArguments(), - Converted.flatSize(), InsertPos); + = ClassTemplate->findSpecialization(Converted.data(), Converted.size(), + InsertPos); if (!Decl) { // This is the first time we have referenced this class template // specialization. Create the canonical declaration and add it to @@ -1593,8 +1591,9 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, ClassTemplate->getTemplatedDecl()->getTagKind(), ClassTemplate->getDeclContext(), ClassTemplate->getLocation(), - ClassTemplate, - Converted, 0); + ClassTemplate, + Converted.data(), + Converted.size(), 0); ClassTemplate->AddSpecialization(Decl, InsertPos); Decl->setLexicalDeclContext(CurContext); } @@ -1839,7 +1838,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, const TemplateArgumentLoc &AL, - TemplateArgumentListBuilder &Converted) { + llvm::SmallVectorImpl &Converted) { const TemplateArgument &Arg = AL.getArgument(); // Check template type parameter. @@ -1876,7 +1875,7 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, return true; // Add the converted template type argument. - Converted.Append( + Converted.push_back( TemplateArgument(Context.getCanonicalType(Arg.getAsType()))); return false; } @@ -1909,21 +1908,21 @@ SubstDefaultTemplateArgument(Sema &SemaRef, SourceLocation TemplateLoc, SourceLocation RAngleLoc, TemplateTypeParmDecl *Param, - TemplateArgumentListBuilder &Converted) { + llvm::SmallVectorImpl &Converted) { TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo(); // If the argument type is dependent, instantiate it now based // on the previously-computed template arguments. if (ArgType->getType()->isDependentType()) { - TemplateArgumentList TemplateArgs(SemaRef.Context, Converted, - /*TakeArgs=*/false); + TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, + Converted.data(), Converted.size()); MultiLevelTemplateArgumentList AllTemplateArgs = SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs); Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, - Template, Converted.getFlatArguments(), - Converted.flatSize(), + Template, Converted.data(), + Converted.size(), SourceRange(TemplateLoc, RAngleLoc)); ArgType = SemaRef.SubstType(ArgType, AllTemplateArgs, @@ -1962,16 +1961,16 @@ SubstDefaultTemplateArgument(Sema &SemaRef, SourceLocation TemplateLoc, SourceLocation RAngleLoc, NonTypeTemplateParmDecl *Param, - TemplateArgumentListBuilder &Converted) { - TemplateArgumentList TemplateArgs(SemaRef.Context, Converted, - /*TakeArgs=*/false); + llvm::SmallVectorImpl &Converted) { + TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, + Converted.data(), Converted.size()); MultiLevelTemplateArgumentList AllTemplateArgs = SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs); Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, - Template, Converted.getFlatArguments(), - Converted.flatSize(), + Template, Converted.data(), + Converted.size(), SourceRange(TemplateLoc, RAngleLoc)); return SemaRef.SubstExpr(Param->getDefaultArgument(), AllTemplateArgs); @@ -2005,16 +2004,16 @@ SubstDefaultTemplateArgument(Sema &SemaRef, SourceLocation TemplateLoc, SourceLocation RAngleLoc, TemplateTemplateParmDecl *Param, - TemplateArgumentListBuilder &Converted) { - TemplateArgumentList TemplateArgs(SemaRef.Context, Converted, - /*TakeArgs=*/false); + llvm::SmallVectorImpl &Converted) { + TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, + Converted.data(), Converted.size()); MultiLevelTemplateArgumentList AllTemplateArgs = SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs); Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, - Template, Converted.getFlatArguments(), - Converted.flatSize(), + Template, Converted.data(), + Converted.size(), SourceRange(TemplateLoc, RAngleLoc)); return SemaRef.SubstTemplateName( @@ -2031,8 +2030,8 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, Decl *Param, - TemplateArgumentListBuilder &Converted) { - if (TemplateTypeParmDecl *TypeParm = dyn_cast(Param)) { + llvm::SmallVectorImpl &Converted) { + if (TemplateTypeParmDecl *TypeParm = dyn_cast(Param)) { if (!TypeParm->hasDefaultArgument()) return TemplateArgumentLoc(); @@ -2089,7 +2088,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, - TemplateArgumentListBuilder &Converted, + llvm::SmallVectorImpl &Converted, CheckTemplateArgumentKind CTAK) { // Check template type parameters. if (TemplateTypeParmDecl *TTP = dyn_cast(Param)) @@ -2103,12 +2102,11 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, if (NTTPType->isDependentType()) { // Do substitution on the type of the non-type template parameter. InstantiatingTemplate Inst(*this, TemplateLoc, Template, - NTTP, Converted.getFlatArguments(), - Converted.flatSize(), + NTTP, Converted.data(), Converted.size(), SourceRange(TemplateLoc, RAngleLoc)); - TemplateArgumentList TemplateArgs(Context, Converted, - /*TakeArgs=*/false); + TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, + Converted.data(), Converted.size()); NTTPType = SubstType(NTTPType, MultiLevelTemplateArgumentList(TemplateArgs), NTTP->getLocation(), @@ -2133,7 +2131,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, if (CheckTemplateArgument(NTTP, NTTPType, E, Result, CTAK)) return true; - Converted.Append(Result); + Converted.push_back(Result); break; } @@ -2141,7 +2139,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, case TemplateArgument::Integral: // We've already checked this template argument, so just copy // it to the list of converted arguments. - Converted.Append(Arg.getArgument()); + Converted.push_back(Arg.getArgument()); break; case TemplateArgument::Template: @@ -2166,7 +2164,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, if (CheckTemplateArgument(NTTP, NTTPType, E, Result)) return true; - Converted.Append(Result); + Converted.push_back(Result); break; } @@ -2219,12 +2217,11 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, // Set up a template instantiation context. LocalInstantiationScope Scope(*this); InstantiatingTemplate Inst(*this, TemplateLoc, Template, - TempParm, Converted.getFlatArguments(), - Converted.flatSize(), + TempParm, Converted.data(), Converted.size(), SourceRange(TemplateLoc, RAngleLoc)); - TemplateArgumentList TemplateArgs(Context, Converted, - /*TakeArgs=*/false); + TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, + Converted.data(), Converted.size()); TempParm = cast_or_null( SubstDecl(TempParm, CurContext, MultiLevelTemplateArgumentList(TemplateArgs))); @@ -2243,7 +2240,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, if (CheckTemplateArgument(TempParm, Arg)) return true; - Converted.Append(Arg.getArgument()); + Converted.push_back(Arg.getArgument()); break; case TemplateArgument::Expression: @@ -2276,7 +2273,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, const TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs, - TemplateArgumentListBuilder &Converted) { + llvm::SmallVectorImpl &Converted) { TemplateParameterList *Params = Template->getTemplateParameters(); unsigned NumParams = Params->size(); unsigned NumArgs = TemplateArgs.size(); @@ -2322,16 +2319,8 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // If we have a template parameter pack, check every remaining template // argument against that template parameter pack. if ((*Param)->isTemplateParameterPack()) { - Converted.BeginPack(); - for (; ArgIdx < NumArgs; ++ArgIdx) { - if (CheckTemplateArgument(*Param, TemplateArgs[ArgIdx], Template, - TemplateLoc, RAngleLoc, Converted)) { - Invalid = true; - break; - } - } - Converted.EndPack(); - continue; + Diag(TemplateLoc, diag::err_variadic_templates_unsupported); + return true; } if (ArgIdx < NumArgs) { @@ -2410,8 +2399,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // Introduce an instantiation record that describes where we are using // the default template argument. InstantiatingTemplate Instantiating(*this, RAngleLoc, Template, *Param, - Converted.getFlatArguments(), - Converted.flatSize(), + Converted.data(), Converted.size(), SourceRange(TemplateLoc, RAngleLoc)); // Check the default template argument. @@ -3805,13 +3793,13 @@ static bool CheckTemplateSpecializationScope(Sema &S, /// \returns true if there was an error, false otherwise. bool Sema::CheckClassTemplatePartialSpecializationArgs( TemplateParameterList *TemplateParams, - const TemplateArgumentListBuilder &TemplateArgs, + llvm::SmallVectorImpl &TemplateArgs, bool &MirrorsPrimaryTemplate) { // FIXME: the interface to this function will have to change to // accommodate variadic templates. MirrorsPrimaryTemplate = true; - const TemplateArgument *ArgList = TemplateArgs.getFlatArguments(); + const TemplateArgument *ArgList = TemplateArgs.data(); for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) { // Determine whether the template argument list of the partial @@ -4036,14 +4024,12 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // Check that the template argument list is well-formed for this // template. - TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(), - TemplateArgs.size()); + llvm::SmallVector Converted; if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, TemplateArgs, false, Converted)) return true; - assert((Converted.structuredSize() == - ClassTemplate->getTemplateParameters()->size()) && + assert((Converted.size() == ClassTemplate->getTemplateParameters()->size()) && "Converted template argument list is too short!"); // Find the class template (partial) specialization declaration that @@ -4089,13 +4075,13 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, if (isPartialSpecialization) // FIXME: Template parameter list matters, too PrevDecl - = ClassTemplate->findPartialSpecialization(Converted.getFlatArguments(), - Converted.flatSize(), + = ClassTemplate->findPartialSpecialization(Converted.data(), + Converted.size(), InsertPos); else PrevDecl - = ClassTemplate->findSpecialization(Converted.getFlatArguments(), - Converted.flatSize(), InsertPos); + = ClassTemplate->findSpecialization(Converted.data(), + Converted.size(), InsertPos); ClassTemplateSpecializationDecl *Specialization = 0; @@ -4126,8 +4112,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // arguments of the class template partial specialization. TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name); CanonType = Context.getTemplateSpecializationType(CanonTemplate, - Converted.getFlatArguments(), - Converted.flatSize()); + Converted.data(), + Converted.size()); // Create a new class template partial specialization declaration node. ClassTemplatePartialSpecializationDecl *PrevPartial @@ -4140,7 +4126,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TemplateNameLoc, TemplateParams, ClassTemplate, - Converted, + Converted.data(), + Converted.size(), TemplateArgs, CanonType, PrevPartial, @@ -4201,7 +4188,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, ClassTemplate->getDeclContext(), TemplateNameLoc, ClassTemplate, - Converted, + Converted.data(), + Converted.size(), PrevDecl); SetNestedNameSpecifier(Specialization, SS); if (NumMatchedTemplateParamLists > 0 && SS.isSet()) { @@ -4995,22 +4983,20 @@ Sema::ActOnExplicitInstantiation(Scope *S, // Check that the template argument list is well-formed for this // template. - TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(), - TemplateArgs.size()); + llvm::SmallVector Converted; if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, TemplateArgs, false, Converted)) return true; - assert((Converted.structuredSize() == - ClassTemplate->getTemplateParameters()->size()) && + assert((Converted.size() == ClassTemplate->getTemplateParameters()->size()) && "Converted template argument list is too short!"); // Find the class template specialization declaration that // corresponds to these arguments. void *InsertPos = 0; ClassTemplateSpecializationDecl *PrevDecl - = ClassTemplate->findSpecialization(Converted.getFlatArguments(), - Converted.flatSize(), InsertPos); + = ClassTemplate->findSpecialization(Converted.data(), + Converted.size(), InsertPos); TemplateSpecializationKind PrevDecl_TSK = PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared; @@ -5060,7 +5046,9 @@ Sema::ActOnExplicitInstantiation(Scope *S, ClassTemplate->getDeclContext(), TemplateNameLoc, ClassTemplate, - Converted, PrevDecl); + Converted.data(), + Converted.size(), + PrevDecl); SetNestedNameSpecifier(Specialization, SS); if (!HasNoEffect && !PrevDecl) { @@ -5824,9 +5812,7 @@ bool Sema::RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS) { std::string Sema::getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgumentList &Args) { - // FIXME: For variadic templates, we'll need to get the structured list. - return getTemplateArgumentBindingsText(Params, Args.getFlatArgumentList(), - Args.flat_size()); + return getTemplateArgumentBindingsText(Params, Args.data(), Args.size()); } std::string diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 9b117b6813..e564298fee 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -1020,8 +1020,7 @@ FinishTemplateArgumentDeduction(Sema &S, // C++ [temp.deduct.type]p2: // [...] or if any template argument remains neither deduced nor // explicitly specified, template argument deduction fails. - TemplateArgumentListBuilder Builder(Partial->getTemplateParameters(), - Deduced.size()); + llvm::SmallVector Builder; for (unsigned I = 0, N = Deduced.size(); I != N; ++I) { if (Deduced[I].isNull()) { Decl *Param @@ -1031,13 +1030,14 @@ FinishTemplateArgumentDeduction(Sema &S, return Sema::TDK_Incomplete; } - Builder.Append(Deduced[I]); + Builder.push_back(Deduced[I]); } // Form the template argument list from the deduced template arguments. TemplateArgumentList *DeducedArgumentList - = new (S.Context) TemplateArgumentList(S.Context, Builder, - /*TakeArgs=*/true); + = TemplateArgumentList::CreateCopy(S.Context, Builder.data(), + Builder.size()); + Info.reset(DeducedArgumentList); // Substitute the deduced template arguments into the template @@ -1069,15 +1069,13 @@ FinishTemplateArgumentDeduction(Sema &S, InstArgs.addArgument(InstArg); } - TemplateArgumentListBuilder ConvertedInstArgs( - ClassTemplate->getTemplateParameters(), N); - + llvm::SmallVector ConvertedInstArgs; if (S.CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(), InstArgs, false, ConvertedInstArgs)) return Sema::TDK_SubstitutionFailure; - for (unsigned I = 0, E = ConvertedInstArgs.flatSize(); I != E; ++I) { - TemplateArgument InstArg = ConvertedInstArgs.getFlatArguments()[I]; + for (unsigned I = 0, E = ConvertedInstArgs.size(); I != E; ++I) { + TemplateArgument InstArg = ConvertedInstArgs.data()[I]; Decl *Param = const_cast( ClassTemplate->getTemplateParameters()->getParam(I)); @@ -1213,8 +1211,7 @@ Sema::SubstituteExplicitTemplateArguments( // declaration order of their corresponding template-parameters. The // template argument list shall not specify more template-arguments than // there are corresponding template-parameters. - TemplateArgumentListBuilder Builder(TemplateParams, - ExplicitTemplateArgs.size()); + llvm::SmallVector Builder; // Enter a new template instantiation context where we check the // explicitly-specified template arguments against this function template, @@ -1231,7 +1228,7 @@ Sema::SubstituteExplicitTemplateArguments( ExplicitTemplateArgs, true, Builder) || Trap.hasErrorOccurred()) { - unsigned Index = Builder.structuredSize(); + unsigned Index = Builder.size(); if (Index >= TemplateParams->size()) Index = TemplateParams->size() - 1; Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); @@ -1241,7 +1238,7 @@ Sema::SubstituteExplicitTemplateArguments( // Form the template argument list from the explicitly-specified // template arguments. TemplateArgumentList *ExplicitArgumentList - = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true); + = TemplateArgumentList::CreateCopy(Context, Builder.data(), Builder.size()); Info.reset(ExplicitArgumentList); // Template argument deduction and the final substitution should be @@ -1392,7 +1389,7 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, // C++ [temp.deduct.type]p2: // [...] or if any template argument remains neither deduced nor // explicitly specified, template argument deduction fails. - TemplateArgumentListBuilder Builder(TemplateParams, Deduced.size()); + llvm::SmallVector Builder; for (unsigned I = 0, N = Deduced.size(); I != N; ++I) { NamedDecl *Param = FunctionTemplate->getTemplateParameters()->getParam(I); if (!Deduced[I].isNull()) { @@ -1400,7 +1397,7 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, // We have already fully type-checked and converted this // argument, because it was explicitly-specified. Just record the // presence of this argument. - Builder.Append(Deduced[I]); + Builder.push_back(Deduced[I]); continue; } @@ -1416,16 +1413,18 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, if (Deduced[I].getKind() == TemplateArgument::Declaration) { NTTPType = NTTP->getType(); if (NTTPType->isDependentType()) { - TemplateArgumentList TemplateArgs(Context, Builder, - /*TakeArgs=*/false); + TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, + Builder.data(), Builder.size()); NTTPType = SubstType(NTTPType, MultiLevelTemplateArgumentList(TemplateArgs), NTTP->getLocation(), NTTP->getDeclName()); if (NTTPType.isNull()) { Info.Param = makeTemplateParameter(Param); - Info.reset(new (Context) TemplateArgumentList(Context, Builder, - /*TakeArgs=*/true)); + // FIXME: These template arguments are temporary. Free them! + Info.reset(TemplateArgumentList::CreateCopy(Context, + Builder.data(), + Builder.size())); return TDK_SubstitutionFailure; } } @@ -1451,8 +1450,9 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, : CTAK_Deduced)) { Info.Param = makeTemplateParameter( const_cast(TemplateParams->getParam(I))); - Info.reset(new (Context) TemplateArgumentList(Context, Builder, - /*TakeArgs=*/true)); + // FIXME: These template arguments are temporary. Free them! + Info.reset(TemplateArgumentList::CreateCopy(Context, Builder.data(), + Builder.size())); return TDK_SubstitutionFailure; } @@ -1483,8 +1483,9 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, CTAK_Deduced)) { Info.Param = makeTemplateParameter( const_cast(TemplateParams->getParam(I))); - Info.reset(new (Context) TemplateArgumentList(Context, Builder, - /*TakeArgs=*/true)); + // FIXME: These template arguments are temporary. Free them! + Info.reset(TemplateArgumentList::CreateCopy(Context, Builder.data(), + Builder.size())); return TDK_SubstitutionFailure; } @@ -1493,7 +1494,7 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, // Form the template argument list from the deduced template arguments. TemplateArgumentList *DeducedArgumentList - = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true); + = TemplateArgumentList::CreateCopy(Context, Builder.data(), Builder.size()); Info.reset(DeducedArgumentList); // Substitute the deduced template arguments into the function template diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index a594e678d6..c4bcc1e7d9 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1102,7 +1102,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, std::pair Innermost = TemplateArgs.getInnermost(); Function->setFunctionTemplateSpecialization(FunctionTemplate, - new (SemaRef.Context) TemplateArgumentList(SemaRef.Context, + TemplateArgumentList::CreateCopy(SemaRef.Context, Innermost.first, Innermost.second), InsertPos); @@ -1410,9 +1410,9 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, std::pair Innermost = TemplateArgs.getInnermost(); Method->setFunctionTemplateSpecialization(FunctionTemplate, - new (SemaRef.Context) TemplateArgumentList(SemaRef.Context, - Innermost.first, - Innermost.second), + TemplateArgumentList::CreateCopy(SemaRef.Context, + Innermost.first, + Innermost.second), InsertPos); } else if (!isFriend) { // Record that this is an instantiation of a member function. @@ -1842,8 +1842,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( // Check that the template argument list is well-formed for this // class template. - TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(), - InstTemplateArgs.size()); + llvm::SmallVector Converted; if (SemaRef.CheckTemplateArgumentList(ClassTemplate, PartialSpec->getLocation(), InstTemplateArgs, @@ -1855,15 +1854,15 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( // in the member template's set of class template partial specializations. void *InsertPos = 0; ClassTemplateSpecializationDecl *PrevDecl - = ClassTemplate->findPartialSpecialization(Converted.getFlatArguments(), - Converted.flatSize(), InsertPos); + = ClassTemplate->findPartialSpecialization(Converted.data(), + Converted.size(), InsertPos); // Build the canonical type that describes the converted template // arguments of the class template partial specialization. QualType CanonType = SemaRef.Context.getTemplateSpecializationType(TemplateName(ClassTemplate), - Converted.getFlatArguments(), - Converted.flatSize()); + Converted.data(), + Converted.size()); // Build the fully-sugared type for this class template // specialization as the user wrote in the specialization @@ -1911,7 +1910,8 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( PartialSpec->getLocation(), InstParams, ClassTemplate, - Converted, + Converted.data(), + Converted.size(), InstTemplateArgs, CanonType, 0, diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 41d8f2a711..47822c5a9b 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -2359,10 +2359,14 @@ bool TreeTransform::TransformTemplateArgument( TransformedArgs.push_back(OutputArg.getArgument()); } - TemplateArgument Result; - Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(), - true); - Output = TemplateArgumentLoc(Result, Input.getLocInfo()); + + TemplateArgument *TransformedArgsPtr + = new (getSema().Context) TemplateArgument[TransformedArgs.size()]; + std::copy(TransformedArgs.begin(), TransformedArgs.end(), + TransformedArgsPtr); + Output = TemplateArgumentLoc(TemplateArgument(TransformedArgsPtr, + TransformedArgs.size()), + Input.getLocInfo()); return false; } } diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index d70546dbbc..c0d347d039 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -4168,13 +4168,10 @@ ASTReader::ReadTemplateArgument(PerFileData &F, return TemplateArgument(ReadExpr(F)); case TemplateArgument::Pack: { unsigned NumArgs = Record[Idx++]; - llvm::SmallVector Args; - Args.reserve(NumArgs); - while (NumArgs--) - Args.push_back(ReadTemplateArgument(F, Record, Idx)); - TemplateArgument TemplArg; - TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true); - return TemplArg; + TemplateArgument *Args = new (*Context) TemplateArgument[NumArgs]; + for (unsigned I = 0; I != NumArgs; ++I) + Args[I] = ReadTemplateArgument(F, Record, Idx); + return TemplateArgument(Args, NumArgs); } } diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index c6cb8db439..4fca0927cf 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -327,7 +327,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { ASTContext &C = *Reader.getContext(); TemplateArgumentList *TemplArgList - = new (C) TemplateArgumentList(C, TemplArgs.data(), TemplArgs.size()); + = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size()); TemplateArgumentListInfo *TemplArgsInfo = new (C) TemplateArgumentListInfo(LAngleLoc, RAngleLoc); for (unsigned i=0, e = TemplArgLocs.size(); i != e; ++i) @@ -1051,7 +1051,8 @@ void ASTDeclReader::VisitClassTemplateSpecializationDecl( llvm::SmallVector TemplArgs; Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); TemplateArgumentList *ArgList - = new (C) TemplateArgumentList(C, TemplArgs.data(), TemplArgs.size()); + = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), + TemplArgs.size()); ClassTemplateSpecializationDecl::SpecializedPartialSpecialization *PS = new (C) ClassTemplateSpecializationDecl:: SpecializedPartialSpecialization(); @@ -1074,7 +1075,8 @@ void ASTDeclReader::VisitClassTemplateSpecializationDecl( llvm::SmallVector TemplArgs; Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); - D->TemplateArgs.init(C, TemplArgs.data(), TemplArgs.size()); + D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), + TemplArgs.size()); D->PointOfInstantiation = ReadSourceLocation(Record, Idx); D->SpecializationKind = (TemplateSpecializationKind)Record[Idx++]; diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index deb6c87efb..8fc60ced77 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -3180,8 +3180,8 @@ void ASTWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs, RecordDataImpl &Record) { assert(TemplateArgs && "No TemplateArgs!"); - Record.push_back(TemplateArgs->flat_size()); - for (int i=0, e = TemplateArgs->flat_size(); i != e; ++i) + Record.push_back(TemplateArgs->size()); + for (int i=0, e = TemplateArgs->size(); i != e; ++i) AddTemplateArgument(TemplateArgs->get(i), Record); } diff --git a/test/SemaTemplate/variadic-class-template-1.cpp b/test/SemaTemplate/variadic-class-template-1.cpp deleted file mode 100644 index 6da64fb55f..0000000000 --- a/test/SemaTemplate/variadic-class-template-1.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x - -template struct S1 { }; // expected-error{{template parameter pack cannot have a default argument}} -template struct S2 { }; // expected-error{{template parameter pack must be the last template parameter}} diff --git a/test/SemaTemplate/variadic-class-template-2.cpp b/test/SemaTemplate/variadic-class-template-2.cpp deleted file mode 100644 index 509977121f..0000000000 --- a/test/SemaTemplate/variadic-class-template-2.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x - -// Type parameters packs -template struct TS1 {}; // expected-note{{template parameter is declared here}} -template struct TS1<>; -template struct TS1; -template struct TS1; -template struct TS1; // expected-error{{template argument for template type parameter must be a type}} - -template struct TS2 {}; // expected-note{{template is declared here}} -template struct TS2<>; // expected-error{{too few template arguments for class template 'TS2'}} -template struct TS2; -template struct TS2; - -template struct TS3 {}; // expected-note{{template parameter is declared here}} -template struct TS3<>; // expected-note{{previous explicit instantiation is here}} -template struct TS3; // expected-error{{duplicate explicit instantiation of 'TS3}} -template struct TS3; -template struct TS3<10>; // expected-error{{template argument for template type parameter must be a type}} diff --git a/test/SemaTemplate/variadic-parse.cpp b/test/SemaTemplate/variadic-parse.cpp deleted file mode 100644 index d8b77b3f42..0000000000 --- a/test/SemaTemplate/variadic-parse.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x - -// Parsing type parameter packs. -template struct T1 {}; -template struct T2 {}; - diff --git a/test/SemaTemplate/variadic-unsupported.cpp b/test/SemaTemplate/variadic-unsupported.cpp deleted file mode 100644 index 9f2b0807d2..0000000000 --- a/test/SemaTemplate/variadic-unsupported.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -// Type parameter packs. -template struct T1 {}; // expected-error{{variadic templates are only allowed in C++0x}} - diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 9ecaa1f7be..3e6539234a 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -2720,8 +2720,8 @@ CXString clang_getCursorDisplayName(CXCursor C) { llvm::raw_svector_ostream OS(Str); OS << ClassSpec->getNameAsString(); OS << TemplateSpecializationType::PrintTemplateArgumentList( - ClassSpec->getTemplateArgs().getFlatArgumentList(), - ClassSpec->getTemplateArgs().flat_size(), + ClassSpec->getTemplateArgs().data(), + ClassSpec->getTemplateArgs().size(), Policy); return createCXString(OS.str()); }