aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/DeclTemplate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/DeclTemplate.cpp')
-rw-r--r--lib/AST/DeclTemplate.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 7389b83d20..4f64f8bd50 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -120,6 +120,65 @@ void ClassTemplateDecl::Destroy(ASTContext& C) {
C.Deallocate((void*)this);
}
+QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
+ if (!CommonPtr->InjectedClassNameType.isNull())
+ return CommonPtr->InjectedClassNameType;
+
+ // FIXME: n2800 14.6.1p1 should say how the template arguments
+ // corresponding to template parameter packs should be pack
+ // expansions. We already say that in 14.6.2.1p2, so it would be
+ // better to fix that redundancy.
+
+ TemplateParameterList *Params = getTemplateParameters();
+
+ llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+ llvm::SmallVector<TemplateArgument, 16> CanonTemplateArgs;
+ TemplateArgs.reserve(Params->size());
+ CanonTemplateArgs.reserve(Params->size());
+
+ for (TemplateParameterList::iterator
+ Param = Params->begin(), ParamEnd = Params->end();
+ Param != ParamEnd; ++Param) {
+ if (isa<TemplateTypeParmDecl>(*Param)) {
+ QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
+ TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(),
+ ParamType));
+ CanonTemplateArgs.push_back(
+ TemplateArgument((*Param)->getLocation(),
+ Context.getCanonicalType(ParamType)));
+ } else if (NonTypeTemplateParmDecl *NTTP =
+ dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
+ // FIXME: Build canonical expression, too!
+ Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
+ NTTP->getLocation(),
+ NTTP->getType()->isDependentType(),
+ /*Value-dependent=*/true);
+ TemplateArgs.push_back(TemplateArgument(E));
+ CanonTemplateArgs.push_back(TemplateArgument(E));
+ } else {
+ TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
+ TemplateArgs.push_back(TemplateArgument(TTP->getLocation(), TTP));
+ CanonTemplateArgs.push_back(TemplateArgument(TTP->getLocation(),
+ Context.getCanonicalDecl(TTP)));
+ }
+ }
+
+ // FIXME: I should really move the "build-the-canonical-type" logic
+ // into ASTContext::getTemplateSpecializationType.
+ TemplateName Name = TemplateName(this);
+ QualType CanonType = Context.getTemplateSpecializationType(
+ Context.getCanonicalTemplateName(Name),
+ &CanonTemplateArgs[0],
+ CanonTemplateArgs.size());
+
+ CommonPtr->InjectedClassNameType
+ = Context.getTemplateSpecializationType(Name,
+ &TemplateArgs[0],
+ TemplateArgs.size(),
+ CanonType);
+ return CommonPtr->InjectedClassNameType;
+}
+
//===----------------------------------------------------------------------===//
// TemplateTypeParm Allocation/Deallocation Method Implementations
//===----------------------------------------------------------------------===//