summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-06-30 08:33:18 +0000
committerJohn McCall <rjmccall@apple.com>2011-06-30 08:33:18 +0000
commitd9dfe3a1f8af68fef298666e50685c30d6f6a974 (patch)
tree6b7b151ea8d1496c0bb3a2ea932212a5840c0a9e /clang/lib
parentc91f09d73a82a270e2a6a8d19bf67aa4f71d01ee (diff)
downloadbcm5719-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.cpp101
-rw-r--r--clang/lib/AST/ASTImporter.cpp14
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp4
-rw-r--r--clang/lib/AST/TemplateName.cpp31
-rw-r--r--clang/lib/AST/Type.cpp1
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp3
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp5
-rw-r--r--clang/lib/Serialization/ASTReader.cpp8
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp8
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
OpenPOWER on IntegriCloud