diff options
author | John McCall <rjmccall@apple.com> | 2011-06-30 08:33:18 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-06-30 08:33:18 +0000 |
commit | d9dfe3a1f8af68fef298666e50685c30d6f6a974 (patch) | |
tree | 6b7b151ea8d1496c0bb3a2ea932212a5840c0a9e /clang/lib | |
parent | c91f09d73a82a270e2a6a8d19bf67aa4f71d01ee (diff) | |
download | bcm5719-llvm-d9dfe3a1f8af68fef298666e50685c30d6f6a974.tar.gz bcm5719-llvm-d9dfe3a1f8af68fef298666e50685c30d6f6a974.zip |
Preserve that a TemplateName was arrived at by substituting
for a template template parameter.
Uses to follow.
I've also made the uniquing of SubstTemplateTemplateParmPacks
use a ContextualFoldingSet as a minor space efficiency.
llvm-svn: 134137
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 101 | ||||
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 14 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 4 | ||||
-rw-r--r-- | clang/lib/AST/TemplateName.cpp | 31 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 8 |
9 files changed, 146 insertions, 29 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 544fc1ababf..ec064fc2f4f 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -219,6 +219,7 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM, FunctionProtoTypes(this_()), TemplateSpecializationTypes(this_()), DependentTemplateSpecializationTypes(this_()), + SubstTemplateTemplateParmPacks(this_()), GlobalNestedNameSpecifier(0), IsInt128Installed(false), CFConstantStringTypeDecl(0), NSConstantStringTypeDecl(0), ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0), @@ -3036,11 +3037,21 @@ bool ASTContext::UnwrapSimilarPointerTypes(QualType &T1, QualType &T2) { DeclarationNameInfo ASTContext::getNameForTemplate(TemplateName Name, SourceLocation NameLoc) const { - if (TemplateDecl *TD = Name.getAsTemplateDecl()) + switch (Name.getKind()) { + case TemplateName::QualifiedTemplate: + case TemplateName::Template: // DNInfo work in progress: CHECKME: what about DNLoc? - return DeclarationNameInfo(TD->getDeclName(), NameLoc); + return DeclarationNameInfo(Name.getAsTemplateDecl()->getDeclName(), + NameLoc); - if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) { + case TemplateName::OverloadedTemplate: { + OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate(); + // DNInfo work in progress: CHECKME: what about DNLoc? + return DeclarationNameInfo((*Storage->begin())->getDeclName(), NameLoc); + } + + case TemplateName::DependentTemplate: { + DependentTemplateName *DTN = Name.getAsDependentTemplateName(); DeclarationName DName; if (DTN->isIdentifier()) { DName = DeclarationNames.getIdentifier(DTN->getIdentifier()); @@ -3055,36 +3066,64 @@ ASTContext::getNameForTemplate(TemplateName Name, } } - OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate(); - assert(Storage); - // DNInfo work in progress: CHECKME: what about DNLoc? - return DeclarationNameInfo((*Storage->begin())->getDeclName(), NameLoc); + case TemplateName::SubstTemplateTemplateParm: { + SubstTemplateTemplateParmStorage *subst + = Name.getAsSubstTemplateTemplateParm(); + return DeclarationNameInfo(subst->getParameter()->getDeclName(), + NameLoc); + } + + case TemplateName::SubstTemplateTemplateParmPack: { + SubstTemplateTemplateParmPackStorage *subst + = Name.getAsSubstTemplateTemplateParmPack(); + return DeclarationNameInfo(subst->getParameterPack()->getDeclName(), + NameLoc); + } + } + + llvm_unreachable("bad template name kind!"); } TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) const { - if (TemplateDecl *Template = Name.getAsTemplateDecl()) { + switch (Name.getKind()) { + case TemplateName::QualifiedTemplate: + case TemplateName::Template: { + TemplateDecl *Template = Name.getAsTemplateDecl(); if (TemplateTemplateParmDecl *TTP - = dyn_cast<TemplateTemplateParmDecl>(Template)) + = dyn_cast<TemplateTemplateParmDecl>(Template)) Template = getCanonicalTemplateTemplateParmDecl(TTP); // The canonical template name is the canonical template declaration. return TemplateName(cast<TemplateDecl>(Template->getCanonicalDecl())); } - if (SubstTemplateTemplateParmPackStorage *SubstPack - = Name.getAsSubstTemplateTemplateParmPack()) { - TemplateTemplateParmDecl *CanonParam - = getCanonicalTemplateTemplateParmDecl(SubstPack->getParameterPack()); - TemplateArgument CanonArgPack - = getCanonicalTemplateArgument(SubstPack->getArgumentPack()); - return getSubstTemplateTemplateParmPack(CanonParam, CanonArgPack); + case TemplateName::OverloadedTemplate: + llvm_unreachable("cannot canonicalize overloaded template"); + + case TemplateName::DependentTemplate: { + DependentTemplateName *DTN = Name.getAsDependentTemplateName(); + assert(DTN && "Non-dependent template names must refer to template decls."); + return DTN->CanonicalTemplateName; + } + + case TemplateName::SubstTemplateTemplateParm: { + SubstTemplateTemplateParmStorage *subst + = Name.getAsSubstTemplateTemplateParm(); + return getCanonicalTemplateName(subst->getReplacement()); } - - assert(!Name.getAsOverloadedTemplate()); - DependentTemplateName *DTN = Name.getAsDependentTemplateName(); - assert(DTN && "Non-dependent template names must refer to template decls."); - return DTN->CanonicalTemplateName; + case TemplateName::SubstTemplateTemplateParmPack: { + SubstTemplateTemplateParmPackStorage *subst + = Name.getAsSubstTemplateTemplateParmPack(); + TemplateTemplateParmDecl *canonParameter + = getCanonicalTemplateTemplateParmDecl(subst->getParameterPack()); + TemplateArgument canonArgPack + = getCanonicalTemplateArgument(subst->getArgumentPack()); + return getSubstTemplateTemplateParmPack(canonParameter, canonArgPack); + } + } + + llvm_unreachable("bad template name!"); } bool ASTContext::hasSameTemplateName(TemplateName X, TemplateName Y) { @@ -4791,6 +4830,24 @@ ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS, } TemplateName +ASTContext::getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param, + TemplateName replacement) const { + llvm::FoldingSetNodeID ID; + SubstTemplateTemplateParmStorage::Profile(ID, param, replacement); + + void *insertPos = 0; + SubstTemplateTemplateParmStorage *subst + = SubstTemplateTemplateParms.FindNodeOrInsertPos(ID, insertPos); + + if (!subst) { + subst = new (*this) SubstTemplateTemplateParmStorage(param, replacement); + SubstTemplateTemplateParms.InsertNode(subst, insertPos); + } + + return TemplateName(subst); +} + +TemplateName ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param, const TemplateArgument &ArgPack) const { ASTContext &Self = const_cast<ASTContext &>(*this); @@ -4802,7 +4859,7 @@ ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param, = SubstTemplateTemplateParmPacks.FindNodeOrInsertPos(ID, InsertPos); if (!Subst) { - Subst = new (*this) SubstTemplateTemplateParmPackStorage(Self, Param, + Subst = new (*this) SubstTemplateTemplateParmPackStorage(Param, ArgPack.pack_size(), ArgPack.pack_begin()); SubstTemplateTemplateParmPacks.InsertNode(Subst, InsertPos); diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 100e604d1c4..9f5719f0293 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -4201,6 +4201,20 @@ TemplateName ASTImporter::Import(TemplateName From) { return ToContext.getDependentTemplateName(Qualifier, DTN->getOperator()); } + + case TemplateName::SubstTemplateTemplateParm: { + SubstTemplateTemplateParmStorage *subst + = From.getAsSubstTemplateTemplateParm(); + TemplateTemplateParmDecl *param + = cast_or_null<TemplateTemplateParmDecl>(Import(subst->getParameter())); + if (!param) + return TemplateName(); + + TemplateName replacement = Import(subst->getReplacement()); + if (replacement.isNull()) return TemplateName(); + + return ToContext.getSubstTemplateTemplateParm(param, replacement); + } case TemplateName::SubstTemplateTemplateParmPack: { SubstTemplateTemplateParmPackStorage *SubstPack diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 9f30f6e63a7..0cbf1f7bdf2 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -1369,6 +1369,10 @@ void CXXNameMangler::mangleType(TemplateName TN) { break; } + case TemplateName::SubstTemplateTemplateParm: + llvm_unreachable("mangling a substituted template name!"); + break; + case TemplateName::SubstTemplateTemplateParmPack: { SubstTemplateTemplateParmPackStorage *SubstPack = TN.getAsSubstTemplateTemplateParmPack(); diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp index ebd07f48678..b22e4b4c0d6 100644 --- a/clang/lib/AST/TemplateName.cpp +++ b/clang/lib/AST/TemplateName.cpp @@ -27,7 +27,19 @@ SubstTemplateTemplateParmPackStorage::getArgumentPack() const { return TemplateArgument(Arguments, size()); } -void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID) { +void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, Parameter, Replacement); +} + +void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID, + TemplateTemplateParmDecl *parameter, + TemplateName replacement) { + ID.AddPointer(parameter); + ID.AddPointer(replacement.getAsVoidPointer()); +} + +void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID, + ASTContext &Context) { Profile(ID, Context, Parameter, TemplateArgument(Arguments, size())); } @@ -46,9 +58,14 @@ TemplateName::NameKind TemplateName::getKind() const { return DependentTemplate; if (Storage.is<QualifiedTemplateName *>()) return QualifiedTemplate; - - return getAsOverloadedTemplate()? OverloadedTemplate - : SubstTemplateTemplateParmPack; + + UncommonTemplateNameStorage *uncommon + = Storage.get<UncommonTemplateNameStorage*>(); + if (uncommon->getAsOverloadedStorage()) + return OverloadedTemplate; + if (uncommon->getAsSubstTemplateTemplateParm()) + return SubstTemplateTemplateParm; + return SubstTemplateTemplateParmPack; } TemplateDecl *TemplateName::getAsTemplateDecl() const { @@ -58,6 +75,9 @@ TemplateDecl *TemplateName::getAsTemplateDecl() const { if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) return QTN->getTemplateDecl(); + if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm()) + return sub->getReplacement().getAsTemplateDecl(); + return 0; } @@ -115,6 +135,9 @@ TemplateName::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy, OS << DTN->getIdentifier()->getName(); else OS << "operator " << getOperatorSpelling(DTN->getOperator()); + } else if (SubstTemplateTemplateParmStorage *subst + = getAsSubstTemplateTemplateParm()) { + subst->getReplacement().print(OS, Policy, SuppressNNS); } else if (SubstTemplateTemplateParmPackStorage *SubstPack = getAsSubstTemplateTemplateParmPack()) OS << SubstPack->getParameterPack()->getNameAsString(); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 68c3eeb8920..1569173df7d 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1764,6 +1764,7 @@ TemplateSpecializationType(TemplateName T, assert(!T.getAsDependentTemplateName() && "Use DependentTemplateSpecializationType for dependent template-name"); assert((T.getKind() == TemplateName::Template || + T.getKind() == TemplateName::SubstTemplateTemplateParm || T.getKind() == TemplateName::SubstTemplateTemplateParmPack) && "Unexpected template name for TemplateSpecializationType"); assert((!Canon.isNull() || diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 3b4ccac416d..d88b7857624 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1861,7 +1861,8 @@ void Sema::NoteAllFoundTemplates(TemplateName Name) { QualType Sema::CheckTemplateIdType(TemplateName Name, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs) { - DependentTemplateName *DTN = Name.getAsDependentTemplateName(); + DependentTemplateName *DTN + = Name.getUnderlying().getAsDependentTemplateName(); if (DTN && DTN->isIdentifier()) // When building a template-id where the template-name is dependent, // assume the template is a type template. Either our assumption is diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 69e592ee253..c452e26a403 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -992,13 +992,14 @@ TemplateName TemplateInstantiator::TransformTemplateName(CXXScopeSpec &SS, TemplateName Template = Arg.getAsTemplate(); assert(!Template.isNull() && "Null template template argument"); - + // We don't ever want to substitute for a qualified template name, since // the qualifier is handled separately. So, look through the qualified // template name to its underlying declaration. if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) Template = TemplateName(QTN->getTemplateDecl()); - + + Template = getSema().Context.getSubstTemplateTemplateParm(TTP, Template); return Template; } } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 3e95df4d4d2..e8a5c41804e 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -4742,6 +4742,14 @@ ASTReader::ReadTemplateName(PerFileData &F, const RecordData &Record, return Context->getDependentTemplateName(NNS, (OverloadedOperatorKind)Record[Idx++]); } + + case TemplateName::SubstTemplateTemplateParm: { + TemplateTemplateParmDecl *param + = cast_or_null<TemplateTemplateParmDecl>(GetDecl(Record[Idx++])); + if (!param) return TemplateName(); + TemplateName replacement = ReadTemplateName(F, Record, Idx); + return Context->getSubstTemplateTemplateParm(param, replacement); + } case TemplateName::SubstTemplateTemplateParmPack: { TemplateTemplateParmDecl *Param diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index d616c840008..fb1795e6a45 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3694,6 +3694,14 @@ void ASTWriter::AddTemplateName(TemplateName Name, RecordDataImpl &Record) { Record.push_back(DepT->getOperator()); break; } + + case TemplateName::SubstTemplateTemplateParm: { + SubstTemplateTemplateParmStorage *subst + = Name.getAsSubstTemplateTemplateParm(); + AddDeclRef(subst->getParameter(), Record); + AddTemplateName(subst->getReplacement(), Record); + break; + } case TemplateName::SubstTemplateTemplateParmPack: { SubstTemplateTemplateParmPackStorage *SubstPack |