[c++1z] Synthesize implicit deduction guides from constructors on demand. Rank
such guides below explicit ones, and ensure that references to the class's
template parameters are not treated as forwarding references.
We make a few tweaks to the wording in the current standard:
1) The constructor parameter list is copied faithfully to the deduction guide,
without losing default arguments or a varargs ellipsis (which the standard
wording loses by omission).
2) If the class template declares no constructors, we add a T() -> T<...> guide
(which will only ever work if T has default arguments for all non-pack
template parameters).
3) If the class template declares nothing that looks like a copy or move
constructor, we add a T(T<...>) -> T<...> guide.
#2 and #3 follow from the "pretend we had a class type with these constructors"
philosophy for deduction guides.
llvm-svn: 295007
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index a69d54c..a0e4d29 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3553,6 +3553,8 @@
if (Tmpl->isDeleted())
New->setDeletedAsWritten();
+ New->setImplicit(Tmpl->isImplicit());
+
// Forward the mangling number from the template to the instantiated decl.
SemaRef.Context.setManglingNumber(New,
SemaRef.Context.getManglingNumber(Tmpl));
@@ -4952,6 +4954,21 @@
DC = FD->getLexicalDeclContext();
continue;
}
+ // An implicit deduction guide acts as if it's within the class template
+ // specialization described by its name and first N template params.
+ if (FD->isDeductionGuide() && FD->isImplicit()) {
+ TemplateDecl *TD = FD->getDeclName().getCXXDeductionGuideTemplate();
+ TemplateArgumentListInfo Args(Loc, Loc);
+ for (auto Arg : TemplateArgs.getInnermost().take_front(
+ TD->getTemplateParameters()->size()))
+ Args.addArgument(
+ getTrivialTemplateArgumentLoc(Arg, QualType(), Loc));
+ QualType T = CheckTemplateIdType(TemplateName(TD), Loc, Args);
+ if (T.isNull())
+ return nullptr;
+ DC = T->getAsCXXRecordDecl();
+ continue;
+ }
}
DC = DC->getParent();