Implement transformation of template names within the generic tree
transform, then use the result for template instantiation. The generic
transformation fixes a few issues:
- It copes better with template template parameters and member
templates (when they're implemented).
- The logic used to replace template template parameters with their
arguments is now centralized in TransformDecl, so that it will apply
for other declaration-instantiation steps.
- The error-recovery strategy is normalized now, so that any error
results in a NULL TemplateName.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78292 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 5f37899..8f877a8 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -324,9 +324,6 @@
/// this declaration.
Decl *TransformDecl(Decl *D);
- /// \brief Transform the given template name by instantiating it.
- TemplateName TransformTemplateName(TemplateName Template);
-
/// \brief Transforms a template type parameter type by performing
/// substitution of the corresponding template type argument.
QualType TransformTemplateTypeParmType(const TemplateTypeParmType *T);
@@ -338,15 +335,22 @@
}
Decl *TemplateInstantiator::TransformDecl(Decl *D) {
+ if (TemplateTemplateParmDecl *TTP
+ = dyn_cast_or_null<TemplateTemplateParmDecl>(D)) {
+ // FIXME: Depth reduction
+ assert(TTP->getDepth() == 0 &&
+ "Cannot reduce depth of a template template parameter");
+ assert(TemplateArgs[TTP->getPosition()].getAsDecl() &&
+ "Wrong kind of template template argument");
+ TemplateDecl *Template
+ = dyn_cast<TemplateDecl>(TemplateArgs[TTP->getPosition()].getAsDecl());
+ assert(Template && "Expected a template");
+ return Template;
+ }
+
return SemaRef.InstantiateCurrentDeclRef(cast_or_null<NamedDecl>(D));
}
-TemplateName
-TemplateInstantiator::TransformTemplateName(TemplateName Template) {
- return getSema().InstantiateTemplateName(Template, /*FIXME*/Loc,
- TemplateArgs);
-}
-
QualType
TemplateInstantiator::TransformTemplateTypeParmType(
const TemplateTypeParmType *T) {
@@ -720,66 +724,9 @@
TemplateName
Sema::InstantiateTemplateName(TemplateName Name, SourceLocation Loc,
const TemplateArgumentList &TemplateArgs) {
- if (TemplateTemplateParmDecl *TTP
- = dyn_cast_or_null<TemplateTemplateParmDecl>(
- Name.getAsTemplateDecl())) {
- assert(TTP->getDepth() == 0 &&
- "Cannot reduce depth of a template template parameter");
- assert(TemplateArgs[TTP->getPosition()].getAsDecl() &&
- "Wrong kind of template template argument");
- ClassTemplateDecl *ClassTemplate
- = dyn_cast<ClassTemplateDecl>(
- TemplateArgs[TTP->getPosition()].getAsDecl());
- assert(ClassTemplate && "Expected a class template");
- if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
- NestedNameSpecifier *NNS
- = InstantiateNestedNameSpecifier(QTN->getQualifier(),
- /*FIXME=*/SourceRange(Loc),
- TemplateArgs);
- if (NNS)
- return Context.getQualifiedTemplateName(NNS,
- QTN->hasTemplateKeyword(),
- ClassTemplate);
- }
-
- return TemplateName(ClassTemplate);
- } else if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
- NestedNameSpecifier *NNS
- = InstantiateNestedNameSpecifier(DTN->getQualifier(),
- /*FIXME=*/SourceRange(Loc),
- TemplateArgs);
-
- if (!NNS) // FIXME: Not the best recovery strategy.
- return Name;
-
- if (NNS->isDependent())
- return Context.getDependentTemplateName(NNS, DTN->getName());
-
- // Somewhat redundant with ActOnDependentTemplateName.
- CXXScopeSpec SS;
- SS.setRange(SourceRange(Loc));
- SS.setScopeRep(NNS);
- TemplateTy Template;
- TemplateNameKind TNK = isTemplateName(*DTN->getName(), 0, Template, &SS);
- if (TNK == TNK_Non_template) {
- Diag(Loc, diag::err_template_kw_refers_to_non_template)
- << DTN->getName();
- return Name;
- } else if (TNK == TNK_Function_template) {
- Diag(Loc, diag::err_template_kw_refers_to_non_template)
- << DTN->getName();
- return Name;
- }
-
- return Template.getAsVal<TemplateName>();
- }
-
-
-
- // FIXME: Even if we're referring to a Decl that isn't a template template
- // parameter, we may need to instantiate the outer contexts of that
- // Decl. However, this won't be needed until we implement member templates.
- return Name;
+ TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,
+ DeclarationName());
+ return Instantiator.TransformTemplateName(Name);
}
TemplateArgument Sema::Instantiate(TemplateArgument Arg,