From: Anders Carlsson Date: Sat, 13 Jun 2009 00:08:58 +0000 (+0000) Subject: Improvements to TemplateArgumentListBuilder to make it work better with parameter... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=67e332009c6e349dc34700f539747afcff990336;p=clang Improvements to TemplateArgumentListBuilder to make it work better with parameter packs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73272 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index c061b85706..5c9fd342fa 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -298,9 +298,13 @@ public: static bool CollectingStats(bool Enable = false); static void PrintStats(); - /// isTemplateParameter - Determines whether this declartion is a + /// isTemplateParameter - Determines whether this declaration is a /// template parameter. bool isTemplateParameter() const; + + /// isTemplateParameter - Determines whether this declaration is a + /// template parameter pack. + bool isTemplateParameterPack() const; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *) { return true; } diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index c301d4608d..ca4758031d 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -592,17 +592,37 @@ public: /// \brief A helper class for making template argument lists. class TemplateArgumentListBuilder { + /// Args - contains the template arguments. llvm::SmallVector Args; + + llvm::SmallVector Indices; ASTContext &Context; + + /// isAddingFromParameterPack - Returns whether we're adding arguments from + /// a parameter pack. + bool isAddingFromParameterPack() const { return Indices.size() % 2; } + public: TemplateArgumentListBuilder(ASTContext &Context) : Context(Context) { } - // FIXME: Should use the index array size. - size_t size() const { return Args.size(); } + size_t size() const { + assert(!isAddingFromParameterPack() && + "Size is not valid when adding from a parameter pack"); + + return Args.size(); + } + size_t flatSize() const { return Args.size(); } void push_back(const TemplateArgument& Arg); + + /// BeginParameterPack - Start adding arguments from a parameter pack. + void BeginParameterPack(); + + /// EndParameterPack - Finish adding arguments from a parameter pack. + void EndParameterPack(); + TemplateArgument *getFlatArgumentList() { return Args.data(); } }; diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index fd7de715db..a39a506de0 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -95,6 +95,13 @@ void Decl::addDeclKind(Kind k) { } } +bool Decl::isTemplateParameterPack() const { + if (const TemplateTypeParmDecl *TTP = dyn_cast(this)) + return TTP->isParameterPack(); + + return false; +} + //===----------------------------------------------------------------------===// // PrettyStackTraceDecl Implementation //===----------------------------------------------------------------------===// diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index a0773f12d7..9526b48468 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -247,9 +247,27 @@ 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); } +void TemplateArgumentListBuilder::BeginParameterPack() { + assert(!isAddingFromParameterPack() && "Already adding to parameter pack!"); + + Indices.push_back(Args.size()); +} + +void TemplateArgumentListBuilder::EndParameterPack() { + assert(isAddingFromParameterPack() && "Not adding to parameter pack!"); + + Indices.push_back(Args.size()); +} + //===----------------------------------------------------------------------===// // TemplateArgumentList Implementation //===----------------------------------------------------------------------===//