diff options
Diffstat (limited to 'lib/AST/DeclTemplate.cpp')
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 97 |
1 files changed, 59 insertions, 38 deletions
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index 1ef47b9158..fe7c9e2904 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -163,6 +163,49 @@ RedeclarableTemplateDecl::findSpecializationImpl( return Entry ? SETraits::getMostRecentDeclaration(Entry) : 0; } +/// \brief Generate the injected template arguments for the given template +/// parameter list, e.g., for the injected-class-name of a class template. +static void GenerateInjectedTemplateArgs(ASTContext &Context, + TemplateParameterList *Params, + TemplateArgument *Args) { + for (TemplateParameterList::iterator Param = Params->begin(), + ParamEnd = Params->end(); + Param != ParamEnd; ++Param) { + TemplateArgument Arg; + if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { + QualType ArgType = Context.getTypeDeclType(TTP); + if (TTP->isParameterPack()) + ArgType = Context.getPackExpansionType(ArgType, + llvm::Optional<unsigned>()); + + Arg = TemplateArgument(ArgType); + } else if (NonTypeTemplateParmDecl *NTTP = + dyn_cast<NonTypeTemplateParmDecl>(*Param)) { + Expr *E = new (Context) DeclRefExpr(NTTP, + NTTP->getType().getNonLValueExprType(Context), + Expr::getValueKindForType(NTTP->getType()), + NTTP->getLocation()); + + if (NTTP->isParameterPack()) + E = new (Context) PackExpansionExpr(Context.DependentTy, E, + NTTP->getLocation(), + llvm::Optional<unsigned>()); + Arg = TemplateArgument(E); + } else { + TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); + if (TTP->isParameterPack()) + Arg = TemplateArgument(TemplateName(TTP), llvm::Optional<unsigned>()); + else + Arg = TemplateArgument(TemplateName(TTP)); + } + + if ((*Param)->isTemplateParameterPack()) + Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1); + + *Args++ = Arg; + } +} + //===----------------------------------------------------------------------===// // FunctionTemplateDecl Implementation //===----------------------------------------------------------------------===// @@ -199,6 +242,20 @@ FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args, return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); } +std::pair<const TemplateArgument *, unsigned> +FunctionTemplateDecl::getInjectedTemplateArgs() { + TemplateParameterList *Params = getTemplateParameters(); + Common *CommonPtr = getCommonPtr(); + if (!CommonPtr->InjectedArgs) { + CommonPtr->InjectedArgs + = new (getASTContext()) TemplateArgument [Params->size()]; + GenerateInjectedTemplateArgs(getASTContext(), Params, + CommonPtr->InjectedArgs); + } + + return std::make_pair(CommonPtr->InjectedArgs, Params->size()); +} + //===----------------------------------------------------------------------===// // ClassTemplateDecl Implementation //===----------------------------------------------------------------------===// @@ -343,44 +400,8 @@ ClassTemplateDecl::getInjectedClassNameSpecialization() { ASTContext &Context = getASTContext(); TemplateParameterList *Params = getTemplateParameters(); llvm::SmallVector<TemplateArgument, 16> TemplateArgs; - TemplateArgs.reserve(Params->size()); - for (TemplateParameterList::iterator Param = Params->begin(), - ParamEnd = Params->end(); - Param != ParamEnd; ++Param) { - TemplateArgument Arg; - if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { - QualType ArgType = Context.getTypeDeclType(TTP); - if (TTP->isParameterPack()) - ArgType = Context.getPackExpansionType(ArgType, - llvm::Optional<unsigned>()); - - Arg = TemplateArgument(ArgType); - } else if (NonTypeTemplateParmDecl *NTTP = - dyn_cast<NonTypeTemplateParmDecl>(*Param)) { - Expr *E = new (Context) DeclRefExpr(NTTP, - NTTP->getType().getNonLValueExprType(Context), - Expr::getValueKindForType(NTTP->getType()), - NTTP->getLocation()); - - if (NTTP->isParameterPack()) - E = new (Context) PackExpansionExpr(Context.DependentTy, E, - NTTP->getLocation(), - llvm::Optional<unsigned>()); - Arg = TemplateArgument(E); - } else { - TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); - if (TTP->isParameterPack()) - Arg = TemplateArgument(TemplateName(TTP), llvm::Optional<unsigned>()); - else - Arg = TemplateArgument(TemplateName(TTP)); - } - - if ((*Param)->isTemplateParameterPack()) - Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1); - - TemplateArgs.push_back(Arg); - } - + TemplateArgs.resize(Params->size()); + GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data()); CommonPtr->InjectedClassNameType = Context.getTemplateSpecializationType(TemplateName(this), &TemplateArgs[0], |