[clang] [clang] WIP: Implement CTAD for type alias template. (PR #77890)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 12 00:20:53 PST 2024
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff 98c6aa72299caeff6b188e1ff2fc1b39c5b893b6 ccf08bb5e209c98bddcb39b28256cd85cecd93cd -- clang/test/SemaCXX/cxx20-ctad-type-alias.cpp clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaInit.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/lib/Sema/SemaTemplateInstantiate.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
``````````
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6a6a30fc52..2bfc387175 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9251,13 +9251,11 @@ public:
const TemplateArgumentList &TemplateArgs,
sema::TemplateDeductionInfo &Info);
- TemplateDeductionResult
- DeduceTemplateArguments(TemplateParameterList *TemplateParams,
- ArrayRef<TemplateArgument> Ps,
- ArrayRef<TemplateArgument> As,
- sema::TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- bool NumberOfArgumentsMustMatch);
+ TemplateDeductionResult DeduceTemplateArguments(
+ TemplateParameterList *TemplateParams, ArrayRef<TemplateArgument> Ps,
+ ArrayRef<TemplateArgument> As, sema::TemplateDeductionInfo &Info,
+ SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ bool NumberOfArgumentsMustMatch);
TemplateDeductionResult SubstituteExplicitTemplateArguments(
FunctionTemplateDecl *FunctionTemplate,
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index d247fa74d5..28d103b8d8 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -10577,12 +10577,11 @@ static bool isOrIsDerivedFromSpecializationOf(CXXRecordDecl *RD,
return !(NotSpecialization(RD) && RD->forallBases(NotSpecialization));
}
-
/// FIXME: this is a copy-paste from SemaTemplate.cpp
/// Tree transform to "extract" a transformed type from a class template's
/// constructor to a deduction guide.
class ExtractTypeForDeductionGuide
- : public TreeTransform<ExtractTypeForDeductionGuide> {
+ : public TreeTransform<ExtractTypeForDeductionGuide> {
llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs;
public:
@@ -10626,7 +10625,8 @@ public:
}
};
-// Transform to form a corresponding deduction guide for type alias template decl.
+// Transform to form a corresponding deduction guide for type alias template
+// decl.
//
// This class implements the C++ [over.match.class.deduct]p3:
// ... Let g denote the result of substituting these deductions into f. If
@@ -10684,7 +10684,7 @@ struct AliasTemplateDeductionGuideTransform {
int Index = 0;
TemplateParameterList *TemplateParams = nullptr;
- for (TemplateTypeParmDecl* Param : DeducedTemplateTypeParDecls) {
+ for (TemplateTypeParmDecl *Param : DeducedTemplateTypeParDecls) {
MultiLevelTemplateArgumentList Args;
Args.setKind(TemplateSubstitutionKind::Rewrite);
@@ -10706,7 +10706,7 @@ struct AliasTemplateDeductionGuideTransform {
TemplateParams = TemplateParameterList::Create(
SemaRef.Context, SourceLocation(), SourceLocation(), AllParams,
- SourceLocation(), /*requiresClause */nullptr);
+ SourceLocation(), /*requiresClause */ nullptr);
MultiLevelTemplateArgumentList Args;
Args.setKind(TemplateSubstitutionKind::Rewrite);
@@ -10722,7 +10722,7 @@ struct AliasTemplateDeductionGuideTransform {
// replacing references to the old parameters with references to the
// new ones.
TypeLocBuilder TLB;
- SmallVector<ParmVarDecl*, 8> Params;
+ SmallVector<ParmVarDecl *, 8> Params;
SmallVector<TypedefNameDecl *, 4> MaterializedTypedefs;
QualType NewType = transformFunctionProtoType(
TLB, FPTL, Params, Args, UnderlyingCDGD->getReturnType(),
@@ -10745,16 +10745,16 @@ private:
/// to earlier parameters and renumbering as we go.
NamedDecl *transformTemplateParameter(NamedDecl *TemplateParam,
MultiLevelTemplateArgumentList &Args,
- int Index ) {
+ int Index) {
if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam)) {
// TemplateTypeParmDecl's index cannot be changed after creation, so
// substitute it directly.
auto *NewTTP = TemplateTypeParmDecl::Create(
SemaRef.Context, DC, TTP->getBeginLoc(), TTP->getLocation(),
// FIXME: is the depth/index right?
- TTP->getDepth(), Index,
- TTP->getIdentifier(), TTP->wasDeclaredWithTypename(),
- TTP->isParameterPack(), TTP->hasTypeConstraint(),
+ TTP->getDepth(), Index, TTP->getIdentifier(),
+ TTP->wasDeclaredWithTypename(), TTP->isParameterPack(),
+ TTP->hasTypeConstraint(),
TTP->isExpandedParameterPack()
? std::optional<unsigned>(TTP->getNumExpansionParameters())
: std::nullopt);
@@ -10779,7 +10779,7 @@ private:
return transformTemplateParameterImpl(
cast<NonTypeTemplateParmDecl>(TemplateParam), Args);
}
- template<typename TemplateParmDecl>
+ template <typename TemplateParmDecl>
TemplateParmDecl *
transformTemplateParameterImpl(TemplateParmDecl *OldParam,
MultiLevelTemplateArgumentList &Args) {
@@ -10794,12 +10794,10 @@ private:
return NewParam;
}
-
QualType transformFunctionProtoType(
TypeLocBuilder &TLB, FunctionProtoTypeLoc TL,
SmallVectorImpl<ParmVarDecl *> &Params,
- MultiLevelTemplateArgumentList &Args,
- QualType ReturnType,
+ MultiLevelTemplateArgumentList &Args, QualType ReturnType,
SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs) {
SmallVector<QualType, 4> ParamTypes;
const FunctionProtoType *T = TL.getTypePtr();
@@ -10817,8 +10815,8 @@ private:
Params.push_back(NewParam);
}
- // The return type of the deduction guide f is InjectedClassNameType, transform
- // it to a TemplateSpecializationType.
+ // The return type of the deduction guide f is InjectedClassNameType,
+ // transform it to a TemplateSpecializationType.
if (const auto *ET = ReturnType->getAs<InjectedClassNameType>()) {
ReturnType = ET->getInjectedSpecializationType();
}
@@ -10898,14 +10896,10 @@ private:
: VK_PRValue);
}
- ParmVarDecl *NewParam = ParmVarDecl::Create(SemaRef.Context, DC,
- OldParam->getInnerLocStart(),
- OldParam->getLocation(),
- OldParam->getIdentifier(),
- NewDI->getType(),
- NewDI,
- OldParam->getStorageClass(),
- NewDefArg.get());
+ ParmVarDecl *NewParam = ParmVarDecl::Create(
+ SemaRef.Context, DC, OldParam->getInnerLocStart(),
+ OldParam->getLocation(), OldParam->getIdentifier(), NewDI->getType(),
+ NewDI, OldParam->getStorageClass(), NewDefArg.get());
NewParam->setScopeInfo(OldParam->getFunctionScopeDepth(),
OldParam->getFunctionScopeIndex());
SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);
@@ -10967,7 +10961,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
auto *Template =
dyn_cast_or_null<ClassTemplateDecl>(TemplateName.getAsTemplateDecl());
- TypeAliasTemplateDecl* AliasTemplate = nullptr;
+ TypeAliasTemplateDecl *AliasTemplate = nullptr;
if (!Template) {
if ((AliasTemplate = dyn_cast_or_null<TypeAliasTemplateDecl>(
TemplateName.getAsTemplateDecl()))) {
@@ -11022,14 +11016,14 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
SmallVector<DeclAccessPair> GuidesCandidates;
if (AliasTemplate) {
- for (auto* Guide : Guides) {
+ for (auto *Guide : Guides) {
if (!dyn_cast_or_null<FunctionTemplateDecl>(Guide))
continue;
auto RType = dyn_cast<FunctionTemplateDecl>(Guide)
->getTemplatedDecl()
->getReturnType();
// The (trailing) return type of the deduction guide.
- const TemplateSpecializationType * ReturnTST = nullptr;
+ const TemplateSpecializationType *ReturnTST = nullptr;
if (const auto *InjectedCNT = RType->getAs<InjectedClassNameType>()) {
// for implicitly-generated deduction guide.
ReturnTST = InjectedCNT->getInjectedTST();
@@ -11039,89 +11033,87 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
}
assert(ReturnTST);
if (ReturnTST) {
- SmallVector<DeducedTemplateArgument> DeduceResults;
- SmallVector<TemplateArgument> DeducedArgs;
- DeduceResults.resize(ReturnTST->template_arguments().size());
- sema::TemplateDeductionInfo TDeduceInfo({});
- // Deduce template arguments of the deduction guide from the RHS of
- // the alias.
- //
- // C++ [over.match.class.deduct]p3: ...For each function or function
- // template f in the guides of the template named by the
- // simple-template-id of the defining-type-id, the template arguments
- // of the return type of f are deduced from the defining-type-id of A
- // according to the process in [temp.deduct.type] with the exception
- // that deduction does not fail if not all template arguments are
- // deduced.
- //
- //
- // template<typename X, typename Y>
- // f(X, Y) -> f<Y, X>
+ SmallVector<DeducedTemplateArgument> DeduceResults;
+ SmallVector<TemplateArgument> DeducedArgs;
+ DeduceResults.resize(ReturnTST->template_arguments().size());
+ sema::TemplateDeductionInfo TDeduceInfo({});
+ // Deduce template arguments of the deduction guide from the RHS of
+ // the alias.
+ //
+ // C++ [over.match.class.deduct]p3: ...For each function or function
+ // template f in the guides of the template named by the
+ // simple-template-id of the defining-type-id, the template arguments
+ // of the return type of f are deduced from the defining-type-id of A
+ // according to the process in [temp.deduct.type] with the exception
+ // that deduction does not fail if not all template arguments are
+ // deduced.
+ //
+ //
+ // template<typename X, typename Y>
+ // f(X, Y) -> f<Y, X>
+ //
+ // template<typename U>
+ // using alias = f<int, U>;
+ //
+ // The RHS of alias is f<int, U>, we deduced the template arguments of
+ // the return type of the deduction guide from it: Y->int, X -> U
+ const auto *AliasRhsTST = AliasTemplate->getTemplatedDecl()
+ ->getUnderlyingType()
+ .getDesugaredType(this->Context)
+ ->getAs<TemplateSpecializationType>();
+ assert(AliasRhsTST);
+
+ if (DeduceTemplateArguments(AliasTemplate->getTemplateParameters(),
+ ReturnTST->template_arguments(),
+ AliasRhsTST->template_arguments(),
+ TDeduceInfo, DeduceResults,
+ /*NumberOfArgumentsMustMatch*/ false)) {
+ // FIXME: not all template arguments are deduced, we should continue
+ // to proceed with all deduced results.
+ } else {
+ // Happy case, all template arguments are deduced.
+ for (auto D : DeduceResults)
+ DeducedArgs.push_back(D);
+
+ auto *DeducedArgList =
+ TemplateArgumentList::CreateCopy(this->Context, DeducedArgs);
+
+ AliasTemplateDeductionGuideTransform Transform(*this, AliasTemplate);
+
+ // Substitute all above deduced template arguments into the
+ // deduction guide f.
//
- // template<typename U>
- // using alias = f<int, U>;
+ // FIXME: is using the InstantiateFunctionDeclaration API a right
+ // implement choice? It has some side effects which creates a
+ // specialization for the deduction guide function template, and
+ // the specialization is added to the the FunctionTemplateDecl, this
+ // is not specified by C++ standard.
//
- // The RHS of alias is f<int, U>, we deduced the template arguments of
- // the return type of the deduction guide from it: Y->int, X -> U
- const auto* AliasRhsTST = AliasTemplate->getTemplatedDecl()
- ->getUnderlyingType()
- .getDesugaredType(this->Context)
- ->getAs<TemplateSpecializationType>();
- assert(AliasRhsTST);
-
- if (DeduceTemplateArguments(AliasTemplate->getTemplateParameters(),
- ReturnTST->template_arguments(),
- AliasRhsTST->template_arguments(),
- TDeduceInfo, DeduceResults,
- /*NumberOfArgumentsMustMatch*/ false)) {
- // FIXME: not all template arguments are deduced, we should continue
- // to proceed with all deduced results.
- } else {
- // Happy case, all template arguments are deduced.
- for (auto D : DeduceResults)
- DeducedArgs.push_back(D);
-
- auto *DeducedArgList =
- TemplateArgumentList::CreateCopy(this->Context, DeducedArgs);
-
- AliasTemplateDeductionGuideTransform Transform(
- *this, AliasTemplate);
-
- // Substitute all above deduced template arguments into the
- // deduction guide f.
- //
- // FIXME: is using the InstantiateFunctionDeclaration API a right
- // implement choice? It has some side effects which creates a
- // specialization for the deduction guide function template, and
- // the specialization is added to the the FunctionTemplateDecl, this
- // is not specified by C++ standard.
- //
- // FIXME: Should we cache the result?
- if (auto *K = InstantiateFunctionDeclaration(
- dyn_cast<FunctionTemplateDecl>(Guide), DeducedArgList,
- SourceLocation(),
- Sema::CodeSynthesisContext::BuildingDeductionGuides)) {
- InstantiatingTemplate BuildingDeductionGuides(
- *this, SourceLocation(), AliasTemplate,
- Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
- auto *D = Transform.transformUnderlyingFunctionTemplate(
- dyn_cast<CXXDeductionGuideDecl>(K), DeducedArgs);
- // FIXME: implement the assoicated constraint per C++
- // [over.match.class.deduct]p3.3:
- // The associated constraints ([temp.constr.decl]) are the
- // conjunction of the associated constraints of g and a
- // constraint that is satisfied if and only if the arguments of
- // A are deducible (see below) from the return type.
- // This could be implemented as part of function overload
- // resolution below.
- GuidesCandidates.push_back(
- DeclAccessPair::make(D, AccessSpecifier::AS_public));
- }
+ // FIXME: Should we cache the result?
+ if (auto *K = InstantiateFunctionDeclaration(
+ dyn_cast<FunctionTemplateDecl>(Guide), DeducedArgList,
+ SourceLocation(),
+ Sema::CodeSynthesisContext::BuildingDeductionGuides)) {
+ InstantiatingTemplate BuildingDeductionGuides(
+ *this, SourceLocation(), AliasTemplate,
+ Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
+ auto *D = Transform.transformUnderlyingFunctionTemplate(
+ dyn_cast<CXXDeductionGuideDecl>(K), DeducedArgs);
+ // FIXME: implement the assoicated constraint per C++
+ // [over.match.class.deduct]p3.3:
+ // The associated constraints ([temp.constr.decl]) are the
+ // conjunction of the associated constraints of g and a
+ // constraint that is satisfied if and only if the arguments of
+ // A are deducible (see below) from the return type.
+ // This could be implemented as part of function overload
+ // resolution below.
+ GuidesCandidates.push_back(
+ DeclAccessPair::make(D, AccessSpecifier::AS_public));
}
+ }
}
}
- }
- else {
+ } else {
for (auto I = Guides.begin(), E = Guides.end(); I != E; ++I) {
GuidesCandidates.push_back(I.getPair());
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 2f548b1a9f..5129a9cfce 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -517,10 +517,9 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
: InstantiatingTemplate(SemaRef, Kind, PointOfInstantiation,
InstantiationRange, FunctionTemplate, nullptr,
TemplateArgs, &DeductionInfo) {
- assert(
- Kind == CodeSynthesisContext::ExplicitTemplateArgumentSubstitution ||
- Kind == CodeSynthesisContext::DeducedTemplateArgumentSubstitution ||
- Kind == CodeSynthesisContext::BuildingDeductionGuides);
+ assert(Kind == CodeSynthesisContext::ExplicitTemplateArgumentSubstitution ||
+ Kind == CodeSynthesisContext::DeducedTemplateArgumentSubstitution ||
+ Kind == CodeSynthesisContext::BuildingDeductionGuides);
}
Sema::InstantiatingTemplate::InstantiatingTemplate(
@@ -1420,8 +1419,7 @@ namespace {
QualType TransformInjectedClassNameType(TypeLocBuilder &TLB,
InjectedClassNameTypeLoc TL) {
// Return a TemplateSpecializationType for building deduction guides
- Decl *D = TransformDecl(TL.getNameLoc(),
- TL.getTypePtr()->getDecl());
+ Decl *D = TransformDecl(TL.getNameLoc(), TL.getTypePtr()->getDecl());
if (!D) {
if (SemaRef.CodeSynthesisContexts.back().Kind !=
Sema::CodeSynthesisContext::BuildingDeductionGuides)
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 71c014b650..086d8de385 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4849,16 +4849,13 @@ bool TemplateDeclInstantiator::SubstDefaultedFunction(FunctionDecl *New,
///
/// Usually this should not be used, and template argument deduction should be
/// used in its place.
-FunctionDecl *
-Sema::InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD,
- const TemplateArgumentList *Args,
- SourceLocation Loc, CodeSynthesisContext::SynthesisKind CSC) {
+FunctionDecl *Sema::InstantiateFunctionDeclaration(
+ FunctionTemplateDecl *FTD, const TemplateArgumentList *Args,
+ SourceLocation Loc, CodeSynthesisContext::SynthesisKind CSC) {
FunctionDecl *FD = FTD->getTemplatedDecl();
sema::TemplateDeductionInfo Info(Loc);
- InstantiatingTemplate Inst(
- *this, Loc, FTD, Args->asArray(),
- CSC, Info);
+ InstantiatingTemplate Inst(*this, Loc, FTD, Args->asArray(), CSC, Info);
if (Inst.isInvalid())
return nullptr;
``````````
</details>
https://github.com/llvm/llvm-project/pull/77890
More information about the cfe-commits
mailing list