diff options
Diffstat (limited to 'lib/AST/DeclTemplate.cpp')
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 59 |
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 //===----------------------------------------------------------------------===// |