summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-02-21 06:30:38 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-02-21 06:30:38 +0000
commitb4f9625a7bd5601534952b478040e6836e37eb47 (patch)
tree4cfa08c4839e2e7be37102ccd5797a78beb1f18e /clang/lib/Sema
parent16d9730b8673741e4b2b18caa087f71c2318be98 (diff)
downloadbcm5719-llvm-b4f9625a7bd5601534952b478040e6836e37eb47.tar.gz
bcm5719-llvm-b4f9625a7bd5601534952b478040e6836e37eb47.zip
PR32010: Fix template argument depth mixup when forming implicit constructor
template deduction guides for class template argument deduction. Ensure that we have a local instantiation scope for tracking the instantiated parameters. Additionally, unusually, we're substituting at depth 1 and leaving depth 0 alone; make sure that we don't reduce template parameter depth by 2 for inner parameters in the process. (This is probably also broken for alias templates in the case where they're expanded within a dependent context, but this patch doesn't fix that.) llvm-svn: 295696
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp8
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp26
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp46
3 files changed, 44 insertions, 36 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 4b4a47d63c8..ad7b9e54f90 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1442,6 +1442,8 @@ struct ConvertConstructorToDeductionGuideTransform {
CXXConstructorDecl *CD) {
SmallVector<TemplateArgument, 16> SubstArgs;
+ LocalInstantiationScope Scope(SemaRef);
+
// C++ [over.match.class.deduct]p1:
// -- For each constructor of the class template designated by the
// template-name, a function template with the following properties:
@@ -1463,7 +1465,7 @@ struct ConvertConstructorToDeductionGuideTransform {
for (NamedDecl *Param : *InnerParams) {
MultiLevelTemplateArgumentList Args;
Args.addOuterTemplateArguments(SubstArgs);
- Args.addOuterTemplateArguments(None);
+ Args.addOuterRetainedLevel();
NamedDecl *NewParam = transformTemplateParameter(Param, Args);
if (!NewParam)
return nullptr;
@@ -1483,7 +1485,7 @@ struct ConvertConstructorToDeductionGuideTransform {
MultiLevelTemplateArgumentList Args;
if (FTD) {
Args.addOuterTemplateArguments(SubstArgs);
- Args.addOuterTemplateArguments(None);
+ Args.addOuterRetainedLevel();
}
FunctionProtoTypeLoc FPTL = CD->getTypeSourceInfo()->getTypeLoc()
@@ -1555,6 +1557,8 @@ private:
if (InstantiatedDefaultArg)
NewTTP->setDefaultArgument(InstantiatedDefaultArg);
}
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(TemplateParam,
+ NewTTP);
return NewTTP;
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 723a6c0e4de..f7535e6d242 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1121,6 +1121,23 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
return E;
TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition());
+
+ if (TemplateArgs.getNumLevels() != TemplateArgs.getNumSubstitutedLevels()) {
+ // We're performing a partial substitution, so the substituted argument
+ // could be dependent. As a result we can't create a SubstNonType*Expr
+ // node now, since that represents a fully-substituted argument.
+ // FIXME: We should have some AST representation for this.
+ if (Arg.getKind() == TemplateArgument::Pack) {
+ // FIXME: This won't work for alias templates.
+ assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
+ "unexpected pack arguments in partial substitution");
+ Arg = Arg.pack_begin()->getPackExpansionPattern();
+ }
+ assert(Arg.getKind() == TemplateArgument::Expression &&
+ "unexpected nontype template argument kind in partial substitution");
+ return Arg.getAsExpr();
+ }
+
if (NTTP->isParameterPack()) {
assert(Arg.getKind() == TemplateArgument::Pack &&
"Missing argument pack");
@@ -1429,12 +1446,9 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
TransformDecl(TL.getNameLoc(), OldTTPDecl));
- QualType Result
- = getSema().Context.getTemplateTypeParmType(T->getDepth()
- - TemplateArgs.getNumLevels(),
- T->getIndex(),
- T->isParameterPack(),
- NewTTPDecl);
+ QualType Result = getSema().Context.getTemplateTypeParmType(
+ T->getDepth() - TemplateArgs.getNumSubstitutedLevels(), T->getIndex(),
+ T->isParameterPack(), NewTTPDecl);
TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc());
return Result;
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 63c10c0c712..b285d4f3814 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2074,13 +2074,10 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
// TODO: don't always clone when decls are refcounted.
assert(D->getTypeForDecl()->isTemplateTypeParmType());
- TemplateTypeParmDecl *Inst =
- TemplateTypeParmDecl::Create(SemaRef.Context, Owner,
- D->getLocStart(), D->getLocation(),
- D->getDepth() - TemplateArgs.getNumLevels(),
- D->getIndex(), D->getIdentifier(),
- D->wasDeclaredWithTypename(),
- D->isParameterPack());
+ TemplateTypeParmDecl *Inst = TemplateTypeParmDecl::Create(
+ SemaRef.Context, Owner, D->getLocStart(), D->getLocation(),
+ D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), D->getIndex(),
+ D->getIdentifier(), D->wasDeclaredWithTypename(), D->isParameterPack());
Inst->setAccess(AS_public);
if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
@@ -2218,17 +2215,14 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
if (IsExpandedParameterPack)
Param = NonTypeTemplateParmDecl::Create(
SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
- D->getDepth() - TemplateArgs.getNumLevels(), D->getPosition(),
- D->getIdentifier(), T, DI, ExpandedParameterPackTypes,
+ D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
+ D->getPosition(), D->getIdentifier(), T, DI, ExpandedParameterPackTypes,
ExpandedParameterPackTypesAsWritten);
else
- Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner,
- D->getInnerLocStart(),
- D->getLocation(),
- D->getDepth() - TemplateArgs.getNumLevels(),
- D->getPosition(),
- D->getIdentifier(), T,
- D->isParameterPack(), DI);
+ Param = NonTypeTemplateParmDecl::Create(
+ SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
+ D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
+ D->getPosition(), D->getIdentifier(), T, D->isParameterPack(), DI);
Param->setAccess(AS_public);
if (Invalid)
@@ -2349,19 +2343,15 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
// Build the template template parameter.
TemplateTemplateParmDecl *Param;
if (IsExpandedParameterPack)
- Param = TemplateTemplateParmDecl::Create(SemaRef.Context, Owner,
- D->getLocation(),
- D->getDepth() - TemplateArgs.getNumLevels(),
- D->getPosition(),
- D->getIdentifier(), InstParams,
- ExpandedParams);
+ Param = TemplateTemplateParmDecl::Create(
+ SemaRef.Context, Owner, D->getLocation(),
+ D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
+ D->getPosition(), D->getIdentifier(), InstParams, ExpandedParams);
else
- Param = TemplateTemplateParmDecl::Create(SemaRef.Context, Owner,
- D->getLocation(),
- D->getDepth() - TemplateArgs.getNumLevels(),
- D->getPosition(),
- D->isParameterPack(),
- D->getIdentifier(), InstParams);
+ Param = TemplateTemplateParmDecl::Create(
+ SemaRef.Context, Owner, D->getLocation(),
+ D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
+ D->getPosition(), D->isParameterPack(), D->getIdentifier(), InstParams);
if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
NestedNameSpecifierLoc QualifierLoc =
D->getDefaultArgument().getTemplateQualifierLoc();
OpenPOWER on IntegriCloud