aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/ASTContext.h2
-rw-r--r--include/clang/AST/CanonicalType.h1
-rw-r--r--include/clang/AST/DeclTemplate.h14
-rw-r--r--include/clang/AST/Type.h60
-rw-r--r--lib/AST/ASTContext.cpp9
-rw-r--r--lib/AST/DeclPrinter.cpp2
-rw-r--r--lib/AST/DeclTemplate.cpp14
-rw-r--r--lib/AST/Type.cpp4
-rw-r--r--lib/AST/TypePrinter.cpp8
-rw-r--r--lib/Sema/SemaTemplate.cpp2
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp9
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp7
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp24
-rw-r--r--lib/Serialization/ASTReader.cpp5
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp1
-rw-r--r--lib/Serialization/ASTWriter.cpp2
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp1
17 files changed, 100 insertions, 65 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index ad02aac360..3ca3c3b8a2 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -699,7 +699,7 @@ public:
QualType getTemplateTypeParmType(unsigned Depth, unsigned Index,
bool ParameterPack,
- IdentifierInfo *Name = 0) const;
+ TemplateTypeParmDecl *ParmDecl = 0) const;
QualType getTemplateSpecializationType(TemplateName T,
const TemplateArgument *Args,
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 4d7fcfd1d1..ce2b3cdea4 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -655,6 +655,7 @@ struct CanProxyAdaptor<TemplateTypeParmType>
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getName)
};
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 823bd84b38..ddbe344cdf 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -945,19 +945,14 @@ class TemplateTypeParmDecl : public TypeDecl {
/// default argument.
bool InheritedDefault : 1;
- /// \brief Whether this is a parameter pack.
- bool ParameterPack : 1;
-
/// \brief The default template argument, if any.
TypeSourceInfo *DefaultArgument;
TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
- bool Typename, QualType Type, bool ParameterPack)
+ bool Typename)
: TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
- InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
- TypeForDecl = Type.getTypePtrOrNull();
- }
+ InheritedDefault(false), DefaultArgument() { }
/// Sema creates these on the stack during auto type deduction.
friend class Sema;
@@ -1011,9 +1006,6 @@ public:
/// the 'typename' or 'class' keyword.
void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
- /// \brief Set whether this is a parameter pack.
- void setParameterPack(bool isParamPack) { ParameterPack = isParamPack; }
-
/// \brief Retrieve the depth of the template parameter.
unsigned getDepth() const;
@@ -1021,7 +1013,7 @@ public:
unsigned getIndex() const;
/// \brief Returns whether this is a parameter pack.
- bool isParameterPack() const { return ParameterPack; }
+ bool isParameterPack() const;
SourceRange getSourceRange() const;
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index f01e2351ab..cd7138de69 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -2969,44 +2969,68 @@ public:
};
class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
- unsigned Depth : 15;
- unsigned ParameterPack : 1;
- unsigned Index : 16;
- IdentifierInfo *Name;
+ // Helper data collector for canonical types.
+ struct CanonicalTTPTInfo {
+ unsigned Depth : 15;
+ unsigned ParameterPack : 1;
+ unsigned Index : 16;
+ };
+
+ union {
+ // Info for the canonical type.
+ CanonicalTTPTInfo CanTTPTInfo;
+ // Info for the non-canonical type.
+ TemplateTypeParmDecl *TTPDecl;
+ };
- TemplateTypeParmType(unsigned D, unsigned I, bool PP, IdentifierInfo *N,
- QualType Canon)
+ /// Build a non-canonical type.
+ TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
: Type(TemplateTypeParm, Canon, /*Dependent=*/true,
- /*VariablyModified=*/false, PP),
- Depth(D), ParameterPack(PP), Index(I), Name(N) { }
+ /*VariablyModified=*/false,
+ Canon->getAs<TemplateTypeParmType>()->CanTTPTInfo.ParameterPack),
+ TTPDecl(TTPDecl) { }
+ /// Build the canonical type.
TemplateTypeParmType(unsigned D, unsigned I, bool PP)
: Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true,
- /*VariablyModified=*/false, PP),
- Depth(D), ParameterPack(PP), Index(I), Name(0) { }
+ /*VariablyModified=*/false, PP) {
+ CanTTPTInfo.Depth = D;
+ CanTTPTInfo.Index = I;
+ CanTTPTInfo.ParameterPack = PP;
+ }
friend class ASTContext; // ASTContext creates these
+ const CanonicalTTPTInfo& getCanTTPTInfo() const {
+ QualType Can = getCanonicalTypeInternal();
+ return Can->getAs<TemplateTypeParmType>()->CanTTPTInfo;
+ }
+
public:
- unsigned getDepth() const { return Depth; }
- unsigned getIndex() const { return Index; }
- bool isParameterPack() const { return ParameterPack; }
- IdentifierInfo *getName() const { return Name; }
+ unsigned getDepth() const { return getCanTTPTInfo().Depth; }
+ unsigned getIndex() const { return getCanTTPTInfo().Index; }
+ bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; }
+
+ TemplateTypeParmDecl *getDecl() const {
+ return isCanonicalUnqualified() ? 0 : TTPDecl;
+ }
+
+ IdentifierInfo *getName() const;
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Depth, Index, ParameterPack, Name);
+ Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl());
}
static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
unsigned Index, bool ParameterPack,
- IdentifierInfo *Name) {
+ TemplateTypeParmDecl *TTPDecl) {
ID.AddInteger(Depth);
ID.AddInteger(Index);
ID.AddBoolean(ParameterPack);
- ID.AddPointer(Name);
+ ID.AddPointer(TTPDecl);
}
static bool classof(const Type *T) {
@@ -3035,8 +3059,6 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
public:
- IdentifierInfo *getName() const { return Replaced->getName(); }
-
/// Gets the template parameter that was substituted for.
const TemplateTypeParmType *getReplacedParameter() const {
return Replaced;
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index de8c26bd70..1f4d9a3718 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2196,9 +2196,9 @@ QualType ASTContext::getSubstTemplateTypeParmPackType(
/// name.
QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
bool ParameterPack,
- IdentifierInfo *Name) const {
+ TemplateTypeParmDecl *TTPDecl) const {
llvm::FoldingSetNodeID ID;
- TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, Name);
+ TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, TTPDecl);
void *InsertPos = 0;
TemplateTypeParmType *TypeParm
= TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -2206,10 +2206,9 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
if (TypeParm)
return QualType(TypeParm, 0);
- if (Name) {
+ if (TTPDecl) {
QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack);
- TypeParm = new (*this, TypeAlignment)
- TemplateTypeParmType(Depth, Index, ParameterPack, Name, Canon);
+ TypeParm = new (*this, TypeAlignment) TemplateTypeParmType(TTPDecl, Canon);
TemplateTypeParmType *TypeCheck
= TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 556fc72cec..bc1e899a61 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -706,7 +706,7 @@ void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
if (TTP->isParameterPack())
Out << "... ";
- Out << ParamType.getAsString(Policy);
+ Out << TTP->getNameAsString();
if (TTP->hasDefaultArgument()) {
Out << " = ";
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 73c91dbd72..6272340691 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -425,15 +425,17 @@ TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
SourceLocation KeyLoc, SourceLocation NameLoc,
unsigned D, unsigned P, IdentifierInfo *Id,
bool Typename, bool ParameterPack) {
- QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id);
- return new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
- Type, ParameterPack);
+ TemplateTypeParmDecl *TTPDecl =
+ new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
+ QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
+ TTPDecl->TypeForDecl = TTPType.getTypePtr();
+ return TTPDecl;
}
TemplateTypeParmDecl *
TemplateTypeParmDecl::Create(const ASTContext &C, EmptyShell Empty) {
return new (C) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
- 0, false, QualType(), false);
+ 0, false);
}
SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
@@ -458,6 +460,10 @@ unsigned TemplateTypeParmDecl::getIndex() const {
return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
}
+bool TemplateTypeParmDecl::isParameterPack() const {
+ return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
+}
+
//===----------------------------------------------------------------------===//
// NonTypeTemplateParmDecl Method Implementations
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index f0737400fc..1ed1770426 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1504,6 +1504,10 @@ bool EnumType::classof(const TagType *TT) {
return isa<EnumDecl>(TT->getDecl());
}
+IdentifierInfo *TemplateTypeParmType::getName() const {
+ return isCanonicalUnqualified() ? 0 : getDecl()->getIdentifier();
+}
+
SubstTemplateTypeParmPackType::
SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
QualType Canon,
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index a8f9559b29..a0d40e14d7 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -652,12 +652,12 @@ void TypePrinter::printTemplateTypeParm(const TemplateTypeParmType *T,
std::string &S) {
if (!S.empty()) // Prefix the basic type, e.g. 'parmname X'.
S = ' ' + S;
-
- if (!T->getName())
+
+ if (IdentifierInfo *Id = T->getDecl() ? T->getDecl()->getIdentifier() : 0)
+ S = Id->getName().str() + S;
+ else
S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' +
llvm::utostr_32(T->getIndex()) + S;
- else
- S = T->getName()->getName().str() + S;
}
void TypePrinter::printSubstTemplateTypeParm(const SubstTemplateTypeParmType *T,
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 677b6f3560..ef0912485b 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -503,7 +503,7 @@ void Sema::translateTemplateArguments(const ASTTemplateArgsPtr &TemplateArgsIn,
/// (otherwise, "class" was used), and KeyLoc is the location of the
/// "class" or "typename" keyword. ParamName is the name of the
/// parameter (NULL indicates an unnamed template parameter) and
-/// ParamName is the location of the parameter name (if any).
+/// ParamNameLoc is the location of the parameter name (if any).
/// If the type parameter has a default argument, it will be added
/// later via ActOnTypeParameterDefault.
Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 7df6de4a30..235af049cf 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -3059,10 +3059,11 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *Init,
LocalInstantiationScope InstScope(*this);
// Build template<class TemplParam> void Func(FuncParam);
- QualType TemplArg = Context.getTemplateTypeParmType(0, 0, false);
- TemplateTypeParmDecl TemplParam(0, SourceLocation(), Loc, 0, false,
- TemplArg, false);
- NamedDecl *TemplParamPtr = &TemplParam;
+ TemplateTypeParmDecl *TemplParam =
+ TemplateTypeParmDecl::Create(Context, 0, SourceLocation(), Loc, 0, 0, 0,
+ false, false);
+ QualType TemplArg = QualType(TemplParam->getTypeForDecl(), 0);
+ NamedDecl *TemplParamPtr = TemplParam;
FixedSizeTemplateParameterList<1> TemplateParams(Loc, Loc, &TemplParamPtr,
Loc);
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 749c4a18a4..dbe51a8252 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1238,12 +1238,17 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
// the template parameter list of a member template inside the
// template we are instantiating). Create a new template type
// parameter with the template "level" reduced by one.
+ TemplateTypeParmDecl *NewTTPDecl = 0;
+ if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
+ NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
+ TransformDecl(TL.getNameLoc(), OldTTPDecl));
+
QualType Result
= getSema().Context.getTemplateTypeParmType(T->getDepth()
- TemplateArgs.getNumLevels(),
T->getIndex(),
T->isParameterPack(),
- T->getName());
+ NewTTPDecl);
TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc());
return Result;
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index c4e171e637..e38ecd43b1 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -495,10 +495,18 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) {
// Handle friend type expressions by simply substituting template
// parameters into the pattern type and checking the result.
if (TypeSourceInfo *Ty = D->getFriendType()) {
- TypeSourceInfo *InstTy =
- SemaRef.SubstType(Ty, TemplateArgs,
- D->getLocation(), DeclarationName());
- if (!InstTy)
+ TypeSourceInfo *InstTy;
+ // If this is an unsupported friend, don't bother substituting template
+ // arguments into it. The actual type referred to won't be used by any
+ // parts of Clang, and may not be valid for instantiating. Just use the
+ // same info for the instantiated friend.
+ if (D->isUnsupportedFriend()) {
+ InstTy = Ty;
+ } else {
+ InstTy = SemaRef.SubstType(Ty, TemplateArgs,
+ D->getLocation(), DeclarationName());
+ }
+ if (!InstTy)
return 0;
FriendDecl *FD = SemaRef.CheckFriendTypeDecl(D->getFriendLoc(), InstTy);
@@ -1466,15 +1474,13 @@ ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
TemplateTypeParmDecl *D) {
// TODO: don't always clone when decls are refcounted.
- const Type* T = D->getTypeForDecl();
- assert(T->isTemplateTypeParmType());
- const TemplateTypeParmType *TTPT = T->getAs<TemplateTypeParmType>();
+ assert(D->getTypeForDecl()->isTemplateTypeParmType());
TemplateTypeParmDecl *Inst =
TemplateTypeParmDecl::Create(SemaRef.Context, Owner,
D->getLocStart(), D->getLocation(),
- TTPT->getDepth() - TemplateArgs.getNumLevels(),
- TTPT->getIndex(), D->getIdentifier(),
+ D->getDepth() - TemplateArgs.getNumLevels(),
+ D->getIndex(), D->getIdentifier(),
D->wasDeclaredWithTypename(),
D->isParameterPack());
Inst->setAccess(AS_public);
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index b362aa43be..d2e41a96c9 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -3303,8 +3303,9 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
unsigned Depth = Record[Idx++];
unsigned Index = Record[Idx++];
bool Pack = Record[Idx++];
- IdentifierInfo *Name = GetIdentifierInfo(Record, Idx);
- return Context->getTemplateTypeParmType(Depth, Index, Pack, Name);
+ TemplateTypeParmDecl *D =
+ cast_or_null<TemplateTypeParmDecl>(GetDecl(Record[Idx++]));
+ return Context->getTemplateTypeParmType(Depth, Index, Pack, D);
}
case TYPE_DEPENDENT_NAME: {
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 481763e91a..b79d07631f 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1216,7 +1216,6 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
VisitTypeDecl(D);
D->setDeclaredWithTypename(Record[Idx++]);
- D->setParameterPack(Record[Idx++]);
bool Inherited = Record[Idx++];
TypeSourceInfo *DefArg = GetTypeSourceInfo(Record, Idx);
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 52c28ff6e8..6d44fb63e5 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -303,7 +303,7 @@ ASTTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
Record.push_back(T->getDepth());
Record.push_back(T->getIndex());
Record.push_back(T->isParameterPack());
- Writer.AddIdentifierRef(T->getName(), Record);
+ Writer.AddDeclRef(T->getDecl(), Record);
Code = TYPE_TEMPLATE_TYPE_PARM;
}
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index df83f2f694..31eb003d00 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -1029,7 +1029,6 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
VisitTypeDecl(D);
Record.push_back(D->wasDeclaredWithTypename());
- Record.push_back(D->isParameterPack());
Record.push_back(D->defaultArgumentWasInherited());
Writer.AddTypeSourceInfo(D->getDefaultArgumentInfo(), Record);