aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTContext.cpp
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
commit146060435c3efce95c95a092c7a1eb651cfb9ae0 (patch)
tree8ee5c7bb0befa2fd813058ce94098c2ad9f6ffec /lib/AST/ASTContext.cpp
parenta8581b9ca06e6ad504af2e28c0798520364f7f1b (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134137 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r--lib/AST/ASTContext.cpp101
1 files changed, 79 insertions, 22 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 544fc1abab..ec064fc2f4 100644
--- a/lib/AST/ASTContext.cpp
+++ b/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);