forked from OSchip/llvm-project
Move generation of injected template arguments for a template parameter list
out of an internal function and into ASTContext; this is needed in template argument deduction for P0522R0. llvm-svn: 290405
This commit is contained in:
parent
eb119ece4a
commit
43e14d271c
|
@ -1355,6 +1355,12 @@ public:
|
|||
ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
|
||||
const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const;
|
||||
|
||||
/// Get a template argument list with one argument per template parameter
|
||||
/// in a template parameter list, such as for the injected class name of
|
||||
/// a class template.
|
||||
void getInjectedTemplateArgs(const TemplateParameterList *Params,
|
||||
SmallVectorImpl<TemplateArgument> &Args);
|
||||
|
||||
QualType getPackExpansionType(QualType Pattern,
|
||||
Optional<unsigned> NumExpansions);
|
||||
|
||||
|
|
|
@ -3872,6 +3872,44 @@ ASTContext::getDependentTemplateSpecializationType(
|
|||
return QualType(T, 0);
|
||||
}
|
||||
|
||||
void
|
||||
ASTContext::getInjectedTemplateArgs(const TemplateParameterList *Params,
|
||||
SmallVectorImpl<TemplateArgument> &Args) {
|
||||
Args.reserve(Args.size() + Params->size());
|
||||
|
||||
for (NamedDecl *Param : *Params) {
|
||||
TemplateArgument Arg;
|
||||
if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
|
||||
QualType ArgType = getTypeDeclType(TTP);
|
||||
if (TTP->isParameterPack())
|
||||
ArgType = getPackExpansionType(ArgType, None);
|
||||
|
||||
Arg = TemplateArgument(ArgType);
|
||||
} else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
|
||||
Expr *E = new (*this) DeclRefExpr(
|
||||
NTTP, /*enclosing*/false,
|
||||
NTTP->getType().getNonLValueExprType(*this),
|
||||
Expr::getValueKindForType(NTTP->getType()), NTTP->getLocation());
|
||||
|
||||
if (NTTP->isParameterPack())
|
||||
E = new (*this) PackExpansionExpr(DependentTy, E, NTTP->getLocation(),
|
||||
None);
|
||||
Arg = TemplateArgument(E);
|
||||
} else {
|
||||
auto *TTP = cast<TemplateTemplateParmDecl>(Param);
|
||||
if (TTP->isParameterPack())
|
||||
Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
|
||||
else
|
||||
Arg = TemplateArgument(TemplateName(TTP));
|
||||
}
|
||||
|
||||
if (Param->isTemplateParameterPack())
|
||||
Arg = TemplateArgument::CreatePackCopy(*this, Arg);
|
||||
|
||||
Args.push_back(Arg);
|
||||
}
|
||||
}
|
||||
|
||||
QualType ASTContext::getPackExpansionType(QualType Pattern,
|
||||
Optional<unsigned> NumExpansions) {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
|
|
|
@ -204,44 +204,6 @@ void RedeclarableTemplateDecl::addSpecializationImpl(
|
|||
SETraits::getDecl(Entry));
|
||||
}
|
||||
|
||||
/// \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 (NamedDecl *Param : *Params) {
|
||||
TemplateArgument Arg;
|
||||
if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
|
||||
QualType ArgType = Context.getTypeDeclType(TTP);
|
||||
if (TTP->isParameterPack())
|
||||
ArgType = Context.getPackExpansionType(ArgType, None);
|
||||
|
||||
Arg = TemplateArgument(ArgType);
|
||||
} else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
|
||||
Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
|
||||
NTTP->getType().getNonLValueExprType(Context),
|
||||
Expr::getValueKindForType(NTTP->getType()),
|
||||
NTTP->getLocation());
|
||||
|
||||
if (NTTP->isParameterPack())
|
||||
E = new (Context) PackExpansionExpr(Context.DependentTy, E,
|
||||
NTTP->getLocation(), None);
|
||||
Arg = TemplateArgument(E);
|
||||
} else {
|
||||
auto *TTP = cast<TemplateTemplateParmDecl>(Param);
|
||||
if (TTP->isParameterPack())
|
||||
Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
|
||||
else
|
||||
Arg = TemplateArgument(TemplateName(TTP));
|
||||
}
|
||||
|
||||
if (Param->isTemplateParameterPack())
|
||||
Arg = TemplateArgument::CreatePackCopy(Context, Arg);
|
||||
|
||||
*Args++ = Arg;
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// FunctionTemplateDecl Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -310,10 +272,13 @@ ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
|
|||
TemplateParameterList *Params = getTemplateParameters();
|
||||
Common *CommonPtr = getCommonPtr();
|
||||
if (!CommonPtr->InjectedArgs) {
|
||||
CommonPtr->InjectedArgs
|
||||
= new (getASTContext()) TemplateArgument[Params->size()];
|
||||
GenerateInjectedTemplateArgs(getASTContext(), Params,
|
||||
CommonPtr->InjectedArgs);
|
||||
auto &Context = getASTContext();
|
||||
SmallVector<TemplateArgument, 16> TemplateArgs;
|
||||
Context.getInjectedTemplateArgs(Params, TemplateArgs);
|
||||
CommonPtr->InjectedArgs =
|
||||
new (Context) TemplateArgument[TemplateArgs.size()];
|
||||
std::copy(TemplateArgs.begin(), TemplateArgs.end(),
|
||||
CommonPtr->InjectedArgs);
|
||||
}
|
||||
|
||||
return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
|
||||
|
@ -464,8 +429,7 @@ ClassTemplateDecl::getInjectedClassNameSpecialization() {
|
|||
ASTContext &Context = getASTContext();
|
||||
TemplateParameterList *Params = getTemplateParameters();
|
||||
SmallVector<TemplateArgument, 16> TemplateArgs;
|
||||
TemplateArgs.resize(Params->size());
|
||||
GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
|
||||
Context.getInjectedTemplateArgs(Params, TemplateArgs);
|
||||
CommonPtr->InjectedClassNameType
|
||||
= Context.getTemplateSpecializationType(TemplateName(this),
|
||||
TemplateArgs);
|
||||
|
|
Loading…
Reference in New Issue