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 f4313f4..2ab1ada 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -299,6 +299,7 @@
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 1b01238..5cbe26d 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1403,36 +1403,40 @@
};
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 7ed9e45..d97d215 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1414,11 +1414,13 @@
}
/// \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 @@
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 ea8dd0d..23c2637 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -190,7 +190,7 @@
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 0a2934b..31c048d 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -564,6 +564,7 @@
// parameter with the template "level" reduced by one.
return SemaRef.Context.getTemplateTypeParmType(T->getDepth() - 1,
T->getIndex(),
+ T->isParameterPack(),
T->getName())
.getQualifiedType(Quals);
}