From: Anders Carlsson Date: Mon, 15 Jun 2009 17:56:45 +0000 (+0000) Subject: More parameter pack work. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3b36b66a00b7d5bab71b486a54694f0ae397bddb;p=clang More parameter pack work. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73395 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 7d5dc06f23..58325908f0 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -470,14 +470,18 @@ public: /// \brief Construct a template argument pack. TemplateArgument(SourceLocation Loc, TemplateArgument *Args, - unsigned NumArgs, bool OwnsArgs); + unsigned NumArgs, bool CopyArgs); /// \brief Copy constructor for a template argument. TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) { - assert(Kind != Pack && "FIXME: Handle packs"); if (Kind == Integral) { new (Integer.Value) llvm::APSInt(*Other.getAsIntegral()); Integer.Type = Other.Integer.Type; + } else if (Kind == Pack) { + Args.NumArgs = Other.Args.NumArgs; + Args.Args = new TemplateArgument[Args.NumArgs]; + for (unsigned I = 0; I != Args.NumArgs; ++I) + Args.Args[I] = Other.Args.Args[I]; } else TypeOrValue = Other.TypeOrValue; @@ -617,28 +621,33 @@ public: /// \brief A helper class for making template argument lists. class TemplateArgumentListBuilder { - /// Args - contains the template arguments. - llvm::SmallVector Args; + /// FlatArgs - contains the template arguments in flat form. + llvm::SmallVector FlatArgs; - llvm::SmallVector Indices; + llvm::SmallVector StructuredArgs; ASTContext &Context; + unsigned PackBeginIndex; + /// isAddingFromParameterPack - Returns whether we're adding arguments from /// a parameter pack. - bool isAddingFromParameterPack() const { return Indices.size() % 2; } + bool isAddingFromParameterPack() const { + return PackBeginIndex != std::numeric_limits::max(); + } public: - TemplateArgumentListBuilder(ASTContext &Context) : Context(Context) { } + TemplateArgumentListBuilder(ASTContext &Context) : Context(Context), + PackBeginIndex(std::numeric_limits::max()) { } - size_t size() const { + size_t structuredSize() const { assert(!isAddingFromParameterPack() && "Size is not valid when adding from a parameter pack"); - return Indices.size() / 2; + return StructuredArgs.size(); } - size_t flatSize() const { return Args.size(); } + size_t flatSize() const { return FlatArgs.size(); } void push_back(const TemplateArgument& Arg); @@ -648,8 +657,12 @@ public: /// EndParameterPack - Finish adding arguments from a parameter pack. void EndParameterPack(); - const TemplateArgument *getFlatArgumentList() const { return Args.data(); } - TemplateArgument *getFlatArgumentList() { return Args.data(); } + const TemplateArgument *getFlatArgumentList() const { + return FlatArgs.data(); + } + TemplateArgument *getFlatArgumentList() { + return FlatArgs.data(); + } }; /// \brief A template argument list. diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index d57a43040f..ea8dd0d3c0 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -265,25 +265,28 @@ void TemplateArgumentListBuilder::push_back(const TemplateArgument& Arg) { break; } - if (!isAddingFromParameterPack()) { - // Add begin and end indicies. - Indices.push_back(Args.size()); - Indices.push_back(Args.size()); - } - - Args.push_back(Arg); + FlatArgs.push_back(Arg); + + if (!isAddingFromParameterPack()) + StructuredArgs.push_back(Arg); } void TemplateArgumentListBuilder::BeginParameterPack() { assert(!isAddingFromParameterPack() && "Already adding to parameter pack!"); - - Indices.push_back(Args.size()); + + PackBeginIndex = FlatArgs.size(); } void TemplateArgumentListBuilder::EndParameterPack() { assert(isAddingFromParameterPack() && "Not adding to parameter pack!"); + + unsigned NumArgs = FlatArgs.size() - PackBeginIndex; + TemplateArgument *Args = NumArgs ? &FlatArgs[PackBeginIndex] : 0; + + StructuredArgs.push_back(TemplateArgument(SourceLocation(), Args, NumArgs, + /*CopyArgs=*/false)); - Indices.push_back(Args.size()); + PackBeginIndex = std::numeric_limits::max(); } //===----------------------------------------------------------------------===// diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 2b2272d999..d7a8a727f8 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -850,7 +850,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, ConvertedTemplateArgs)) return QualType(); - assert((ConvertedTemplateArgs.size() == + assert((ConvertedTemplateArgs.structuredSize() == Template->getTemplateParameters()->size()) && "Converted template argument list is too short!"); @@ -2301,7 +2301,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, RAngleLoc, ConvertedTemplateArgs)) return true; - assert((ConvertedTemplateArgs.size() == + assert((ConvertedTemplateArgs.structuredSize() == ClassTemplate->getTemplateParameters()->size()) && "Converted template argument list is too short!"); @@ -2562,7 +2562,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, RAngleLoc, ConvertedTemplateArgs)) return true; - assert((ConvertedTemplateArgs.size() == + assert((ConvertedTemplateArgs.structuredSize() == ClassTemplate->getTemplateParameters()->size()) && "Converted template argument list is too short!");