diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 39236b07b89ed68bd0bc5d8880f43387d31a42c6..9d0469368f39e0f3fad65c5068faf1d6e9620766 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -601,7 +601,7 @@ public: QualType getTemplateTypeParmType(unsigned Depth, unsigned Index, bool ParameterPack, - TemplateTypeParmDecl *ParmDecl = 0); + IdentifierInfo *Name = 0); QualType getTemplateSpecializationType(TemplateName T, const TemplateArgument *Args, diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index 363e01033e381a63e2ee0e8073b915116970a067..19c9f83370720588e2b757a59204f916cede5925 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -640,6 +640,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(IdentifierInfo *, getName) }; template<> diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 4c899228e4dca6cd204a6c9961c9f0436f6d077c..74c579b6022e035305f7f4e45c3c0c1a95cdb19b 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -662,13 +662,18 @@ 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 L, IdentifierInfo *Id, - bool Typename) + bool Typename, QualType Type, bool ParameterPack) : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename), - InheritedDefault(false), DefaultArgument() { } + InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() { + TypeForDecl = Type.getTypePtr(); + } public: static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC, @@ -719,7 +724,7 @@ public: unsigned getIndex() const; /// \brief Returns whether this is a parameter pack. - bool isParameterPack() const; + bool isParameterPack() const { return ParameterPack; } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 6d6e1850fb833bfc4a44851d78152aec06495328..336166dd723462130ced5dfd49d97acc194ee3cf 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -2311,63 +2311,42 @@ public: }; class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { - // Helper data collector for canonical types. - struct CanonicalTTPTInfo { - unsigned Depth : 15; - unsigned Index : 16; - unsigned ParameterPack : 1; - }; - - union { - // Info for the canonical type. - CanonicalTTPTInfo CanTTPTInfo; - // Info for the non-canonical type. - TemplateTypeParmDecl *TTPDecl; - }; + unsigned Depth : 15; + unsigned Index : 16; + unsigned ParameterPack : 1; + IdentifierInfo *Name; - /// Build a non-canonical type. - TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) + TemplateTypeParmType(unsigned D, unsigned I, bool PP, IdentifierInfo *N, + QualType Canon) : Type(TemplateTypeParm, Canon, /*Dependent=*/true), - TTPDecl(TTPDecl) { } + Depth(D), Index(I), ParameterPack(PP), Name(N) { } - /// Build the canonical type. TemplateTypeParmType(unsigned D, unsigned I, bool PP) - : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true) { - CanTTPTInfo.Depth = D; - CanTTPTInfo.Index = I; - CanTTPTInfo.ParameterPack = PP; - } + : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true), + Depth(D), Index(I), ParameterPack(PP), Name(0) { } friend class ASTContext; // ASTContext creates these - const CanonicalTTPTInfo& getCanTTPTInfo() const { - QualType Can = getCanonicalTypeInternal(); - return Can->getAs<TemplateTypeParmType>()->CanTTPTInfo; - } - public: - 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; - } + unsigned getDepth() const { return Depth; } + unsigned getIndex() const { return Index; } + bool isParameterPack() const { return ParameterPack; } + IdentifierInfo *getName() const { return Name; } bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl()); + Profile(ID, Depth, Index, ParameterPack, Name); } static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth, unsigned Index, bool ParameterPack, - TemplateTypeParmDecl *TTPDecl) { + IdentifierInfo *Name) { ID.AddInteger(Depth); ID.AddInteger(Index); ID.AddBoolean(ParameterPack); - ID.AddPointer(TTPDecl); + ID.AddPointer(Name); } static bool classof(const Type *T) { @@ -2394,6 +2373,8 @@ 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 485247fb4115e95bed46add694a61ea40fab4413..fbf26ccca5ee402bb9eb3a0f0541b2be1d5285cc 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1728,9 +1728,9 @@ ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm, /// name. QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, bool ParameterPack, - TemplateTypeParmDecl *TTPDecl) { + IdentifierInfo *Name) { llvm::FoldingSetNodeID ID; - TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, TTPDecl); + TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, Name); void *InsertPos = 0; TemplateTypeParmType *TypeParm = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); @@ -1738,9 +1738,10 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, if (TypeParm) return QualType(TypeParm, 0); - if (TTPDecl) { + if (Name) { QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack); - TypeParm = new (*this, TypeAlignment) TemplateTypeParmType(TTPDecl, Canon); + TypeParm = new (*this, TypeAlignment) + TemplateTypeParmType(Depth, Index, ParameterPack, Name, Canon); TemplateTypeParmType *TypeCheck = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 21cfda19a281c5b6f88ae3db61645b111ac3acf9..2fb6cb1d311dd96f28d573a992e6a7a2c5c9bda3 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -623,7 +623,7 @@ void DeclPrinter::VisitTemplateDecl(TemplateDecl *D) { if (TTP->isParameterPack()) Out << "... "; - Out << TTP->getNameAsString(); + Out << ParamType.getAsString(Policy); if (TTP->hasDefaultArgument()) { Out << " = "; diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index 14d0604f9fa0d4e9f4255394e8adbc92b9e4f19a..85b796007548d6990163dec89ff06707f586f7cc 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -265,11 +265,8 @@ TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack) { - TemplateTypeParmDecl *TTPDecl - = new (C) TemplateTypeParmDecl(DC, L, Id, Typename); - QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl); - TTPDecl->TypeForDecl = TTPType.getTypePtr(); - return TTPDecl; + QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id); + return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack); } SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { @@ -284,10 +281,6 @@ 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/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index b3e2a442b228bbca062039db71a2a83a31212031..2fa84f350b20679838d4aa81795b8a8788e5a4fb 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -506,12 +506,12 @@ void TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T, std::string &S) { if (!S.empty()) // Prefix the basic type, e.g. 'parmname X'. S = ' ' + S; - - if (IdentifierInfo *Id = T->getDecl() ? T->getDecl()->getIdentifier() : 0) - S = Id->getName().str() + S; - else + + if (!T->getName()) 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 6843129002328b41e877520de6be81e23868a90f..f5f4853fb0f3cbd32ee71ba11e3f372836f40186 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -450,7 +450,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 -/// ParamNameLoc is the location of the parameter name (if any). +/// ParamName is the location of the parameter name (if any). /// If the type parameter has a default argument, it will be added /// later via ActOnTypeParameterDefault. Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 712f5c0e2b546f20d61c7f85151087cadf2a5db0..1adf594c1eff7e07cb11ca074f9bcda162c31087 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -896,17 +896,12 @@ 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(), - NewTTPDecl); + T->getName()); 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 a582b557c82805e2ebeb1a279b3fc0ec9a60272a..b7059e5752389adc9f4f79fa93df590ea658f6e7 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1442,12 +1442,14 @@ ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) { Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( TemplateTypeParmDecl *D) { // TODO: don't always clone when decls are refcounted. - assert(D->getTypeForDecl()->isTemplateTypeParmType()); + const Type* T = D->getTypeForDecl(); + assert(T->isTemplateTypeParmType()); + const TemplateTypeParmType *TTPT = T->getAs<TemplateTypeParmType>(); TemplateTypeParmDecl *Inst = TemplateTypeParmDecl::Create(SemaRef.Context, Owner, D->getLocation(), - D->getDepth() - 1, D->getIndex(), - D->getIdentifier(), + TTPT->getDepth() - 1, TTPT->getIndex(), + TTPT->getName(), D->wasDeclaredWithTypename(), D->isParameterPack());