From: Anders Carlsson Date: Tue, 16 Jun 2009 00:30:48 +0000 (+0000) Subject: Keep track of whether a type parameter type is a parameter pack. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=76e4ce42a30cee4dc40ce7c6014874fbc4f9baa7;p=clang Keep track of whether a type parameter type is a parameter pack. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73452 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index f4313f4dbf..2ab1adac7e 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -299,6 +299,7 @@ public: QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl); QualType getTemplateTypeParmType(unsigned Depth, unsigned Index, + bool ParameterPack, IdentifierInfo *Name = 0); QualType getTemplateSpecializationType(TemplateName T, diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 1b012385c9..5cbe26d523 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -1403,36 +1403,40 @@ public: }; class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { - unsigned Depth : 16; + unsigned Depth : 15; unsigned Index : 16; + unsigned ParameterPack : 1; IdentifierInfo *Name; - TemplateTypeParmType(unsigned D, unsigned I, IdentifierInfo *N, + TemplateTypeParmType(unsigned D, unsigned I, bool PP, IdentifierInfo *N, QualType Canon) : Type(TemplateTypeParm, Canon, /*Dependent=*/true), - Depth(D), Index(I), Name(N) { } + Depth(D), Index(I), ParameterPack(PP), Name(N) { } - TemplateTypeParmType(unsigned D, unsigned I) + TemplateTypeParmType(unsigned D, unsigned I, bool PP) : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true), - Depth(D), Index(I), Name(0) { } + Depth(D), Index(I), ParameterPack(PP), Name(0) { } friend class ASTContext; // ASTContext creates these public: unsigned getDepth() const { return Depth; } unsigned getIndex() const { return Index; } + bool isParameterPack() const { return ParameterPack; } IdentifierInfo *getName() const { return Name; } virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, Depth, Index, Name); + Profile(ID, Depth, Index, ParameterPack, Name); } static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth, - unsigned Index, IdentifierInfo *Name) { + unsigned Index, bool ParameterPack, + IdentifierInfo *Name) { ID.AddInteger(Depth); ID.AddInteger(Index); + ID.AddBoolean(ParameterPack); ID.AddPointer(Name); } diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 7ed9e45fce..d97d2155c0 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1414,11 +1414,13 @@ QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) { } /// \brief Retrieve the template type parameter type for a template -/// parameter with the given depth, index, and (optionally) name. +/// parameter or parameter pack with the given depth, index, and (optionally) +/// name. QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, + bool ParameterPack, IdentifierInfo *Name) { llvm::FoldingSetNodeID ID; - TemplateTypeParmType::Profile(ID, Depth, Index, Name); + TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, Name); void *InsertPos = 0; TemplateTypeParmType *TypeParm = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); @@ -1426,11 +1428,12 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, if (TypeParm) return QualType(TypeParm, 0); - if (Name) - TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index, Name, - getTemplateTypeParmType(Depth, Index)); - else - TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index); + if (Name) { + QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack); + TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index, ParameterPack, + Name, Canon); + } else + TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index, ParameterPack); Types.push_back(TypeParm); TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos); diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index ea8dd0d3c0..23c2637875 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -190,7 +190,7 @@ TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack) { - QualType Type = C.getTemplateTypeParmType(D, P, Id); + QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id); return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack); } diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 0a2934b1c8..31c048d74c 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -564,6 +564,7 @@ InstantiateTemplateTypeParmType(const TemplateTypeParmType *T, // parameter with the template "level" reduced by one. return SemaRef.Context.getTemplateTypeParmType(T->getDepth() - 1, T->getIndex(), + T->isParameterPack(), T->getName()) .getQualifiedType(Quals); }