44#include "llvm/ADT/ArrayRef.h"
45#include "llvm/ADT/STLExtras.h"
46#include "llvm/ADT/SmallVector.h"
47#include "llvm/Support/Casting.h"
48#include "llvm/Support/ErrorHandling.h"
59class ExtractTypeForDeductionGuide
61 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs;
62 ClassTemplateDecl *NestedPattern;
63 const MultiLevelTemplateArgumentList *OuterInstantiationArgs;
64 std::optional<TemplateDeclInstantiator> TypedefNameInstantiator;
67 typedef TreeTransform<ExtractTypeForDeductionGuide> Base;
68 ExtractTypeForDeductionGuide(
70 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs,
71 ClassTemplateDecl *NestedPattern =
nullptr,
72 const MultiLevelTemplateArgumentList *OuterInstantiationArgs =
nullptr)
73 : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs),
74 NestedPattern(NestedPattern),
75 OuterInstantiationArgs(OuterInstantiationArgs) {
76 if (OuterInstantiationArgs)
77 TypedefNameInstantiator.emplace(
79 *OuterInstantiationArgs);
82 TypeSourceInfo *transform(TypeSourceInfo *TSI) {
return TransformType(TSI); }
86 bool mightReferToOuterTemplateParameters(TypedefNameDecl *
Typedef) {
90 static auto WalkUp = [](DeclContext *DC, DeclContext *TargetDC) {
101 if (WalkUp(
Typedef->getDeclContext(), NestedPattern->getTemplatedDecl()))
103 if (WalkUp(NestedPattern->getTemplatedDecl(),
Typedef->getDeclContext()))
108 QualType RebuildTemplateSpecializationType(
110 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
111 if (!OuterInstantiationArgs ||
112 !isa_and_present<TypeAliasTemplateDecl>(
Template.getAsTemplateDecl()))
117 auto *Pattern = TATD;
118 while (Pattern->getInstantiatedFromMemberTemplate())
119 Pattern = Pattern->getInstantiatedFromMemberTemplate();
120 if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl()))
125 TypedefNameInstantiator->InstantiateTypeAliasTemplateDecl(TATD);
130 MaterializedTypedefs.push_back(NewTATD->getTemplatedDecl());
136 QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) {
138 TypedefNameDecl *OrigDecl = TL.
getDecl();
139 TypedefNameDecl *
Decl = OrigDecl;
157 if (OuterInstantiationArgs && InDependentContext &&
159 Decl = cast_if_present<TypedefNameDecl>(
160 TypedefNameInstantiator->InstantiateTypedefNameDecl(
164 MaterializedTypedefs.push_back(Decl);
165 }
else if (InDependentContext) {
166 TypeLocBuilder InnerTLB;
167 QualType Transformed =
180 MaterializedTypedefs.push_back(Decl);
185 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
212 auto DeductionGuideName =
222 SemaRef.
Context, DC, LocStart, ES, Name, TInfo->
getType(), TInfo, LocEnd,
224 Guide->setImplicit(IsImplicit);
225 Guide->setParams(Params);
227 for (
auto *Param : Params)
228 Param->setDeclContext(Guide);
229 for (
auto *TD : MaterializedTypedefs)
230 TD->setDeclContext(Guide);
234 if (!TemplateParams) {
240 SemaRef.
Context, DC, Loc, DeductionGuideName, TemplateParams, Guide);
241 GuideTemplate->setImplicit(IsImplicit);
242 Guide->setDescribedFunctionTemplate(GuideTemplate);
248 return GuideTemplate;
255 bool EvaluateConstraint) {
271 NewTTP->setDefaultArgument(SemaRef.
Context, InstantiatedDefaultArg);
277template <
typename NonTypeTemplateOrTemplateTemplateParmDecl>
278NonTypeTemplateOrTemplateTemplateParmDecl *
280 NonTypeTemplateOrTemplateTemplateParmDecl *OldParam,
287 NewParam->setPosition(NewIndex);
288 NewParam->setDepth(NewDepth);
295 unsigned NewIndex,
unsigned NewDepth,
296 bool EvaluateConstraint =
true) {
297 if (
auto *TTP = dyn_cast<TemplateTypeParmDecl>(
TemplateParam))
298 return transformTemplateTypeParam(
299 SemaRef, DC, TTP, Args, NewDepth, NewIndex,
301 if (
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(
TemplateParam))
302 return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex, NewDepth);
303 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
TemplateParam))
304 return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, NewDepth);
305 llvm_unreachable(
"Unhandled template parameter types");
310struct ConvertConstructorToDeductionGuideTransform {
311 ConvertConstructorToDeductionGuideTransform(Sema &S,
312 ClassTemplateDecl *Template)
313 : SemaRef(S), Template(Template) {
316 ClassTemplateDecl *Pattern = Template;
318 if (Pattern->isMemberSpecialization())
320 Pattern = Pattern->getInstantiatedFromMemberTemplate();
321 NestedPattern = Pattern;
325 OuterInstantiationArgs = SemaRef.getTemplateInstantiationArgs(Template);
329 ClassTemplateDecl *Template;
330 ClassTemplateDecl *NestedPattern =
nullptr;
332 DeclContext *DC = Template->getDeclContext();
333 CXXRecordDecl *Primary = Template->getTemplatedDecl();
334 DeclarationName DeductionGuideName =
335 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(Template);
337 QualType DeducedType = SemaRef.Context.getCanonicalTagType(Primary);
341 unsigned Depth1IndexAdjustment = Template->getTemplateParameters()->size();
345 MultiLevelTemplateArgumentList OuterInstantiationArgs;
348 NamedDecl *transformConstructor(FunctionTemplateDecl *FTD,
349 CXXConstructorDecl *CD) {
350 SmallVector<TemplateArgument, 16> SubstArgs;
352 LocalInstantiationScope Scope(SemaRef);
361 TemplateParameterList *TemplateParams =
362 SemaRef.GetTemplateParameterList(Template);
363 SmallVector<TemplateArgument, 16> Depth1Args;
367 SmallVector<NamedDecl *, 16> AllParams;
368 AllParams.reserve(TemplateParams->
size() + InnerParams->
size());
369 AllParams.insert(AllParams.begin(), TemplateParams->
begin(),
370 TemplateParams->
end());
371 SubstArgs.reserve(InnerParams->
size());
372 Depth1Args.reserve(InnerParams->
size());
376 for (NamedDecl *Param : *InnerParams) {
377 MultiLevelTemplateArgumentList Args;
378 Args.
setKind(TemplateSubstitutionKind::Rewrite);
388 NamedDecl *NewParam = transformTemplateParameter(
389 SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment,
390 Depth ? Depth - 1 : 0);
395 Depth1Args.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
399 NewParam = transformTemplateParameter(
400 SemaRef, DC, NewParam, OuterInstantiationArgs, Index,
401 Depth - OuterInstantiationArgs.getNumSubstitutedLevels(),
406 "Unexpected template parameter depth");
408 AllParams.push_back(NewParam);
409 SubstArgs.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
413 Expr *RequiresClause =
nullptr;
414 if (Expr *InnerRC = InnerParams->getRequiresClause()) {
415 MultiLevelTemplateArgumentList Args;
416 Args.
setKind(TemplateSubstitutionKind::Rewrite);
422 SemaRef.SubstConstraintExprWithoutSatisfaction(InnerRC, Args);
425 RequiresClause = E.
get();
428 TemplateParams = TemplateParameterList::Create(
429 SemaRef.Context, InnerParams->getTemplateLoc(),
430 InnerParams->getLAngleLoc(), AllParams, InnerParams->getRAngleLoc(),
437 MultiLevelTemplateArgumentList Args;
438 Args.
setKind(TemplateSubstitutionKind::Rewrite);
447 assert(FPTL &&
"no prototype for constructor declaration");
453 SmallVector<ParmVarDecl *, 8> Params;
454 SmallVector<TypedefNameDecl *, 4> MaterializedTypedefs;
455 QualType NewType = transformFunctionProtoType(TLB, FPTL, Params, Args,
456 MaterializedTypedefs);
464 AssociatedConstraint FunctionTrailingRC;
466 MultiLevelTemplateArgumentList Args;
467 Args.
setKind(TemplateSubstitutionKind::Rewrite);
472 ExprResult E = SemaRef.SubstConstraintExprWithoutSatisfaction(
473 const_cast<Expr *
>(RC.ConstraintExpr), Args);
476 FunctionTrailingRC = AssociatedConstraint(E.
get(), RC.ArgPackSubstIndex);
491 if (!FunctionTrailingRC)
492 FunctionTrailingRC = OuterRC;
494 FunctionTrailingRC = AssociatedConstraint(
497 const_cast<Expr *
>(OuterRC.ConstraintExpr),
504 return buildDeductionGuide(
507 true, MaterializedTypedefs, FunctionTrailingRC);
511 NamedDecl *buildSimpleDeductionGuide(MutableArrayRef<QualType> ParamTypes) {
512 SourceLocation Loc = Template->getLocation();
515 FunctionProtoType::ExtProtoInfo EPI;
517 QualType
Result = SemaRef.BuildFunctionType(DeducedType, ParamTypes, Loc,
518 DeductionGuideName, EPI);
519 TypeSourceInfo *TSI = SemaRef.Context.getTrivialTypeSourceInfo(
Result, Loc);
521 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
527 FunctionProtoTypeLoc FPTL =
531 SmallVector<ParmVarDecl *, 4> Params;
532 for (
auto T : ParamTypes) {
533 auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(
T, Loc);
535 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
540 ParmVarDecl *NewParam =
544 FPTL.
setParam(Params.size(), NewParam);
545 Params.push_back(NewParam);
548 return buildDeductionGuide(
549 SemaRef, Template, SemaRef.GetTemplateParameterList(Template),
nullptr,
550 ExplicitSpecifier(), TSI, Loc, Loc, Loc,
true);
554 QualType transformFunctionProtoType(
555 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL,
556 SmallVectorImpl<ParmVarDecl *> &Params,
557 MultiLevelTemplateArgumentList &Args,
558 SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs) {
559 SmallVector<QualType, 4> ParamTypes;
564 ParmVarDecl *NewParam = OldParam;
575 NewParam = transformFunctionTypeParam(
576 NewParam, OuterInstantiationArgs, MaterializedTypedefs,
585 transformFunctionTypeParam(NewParam, Args, MaterializedTypedefs,
589 ParamTypes.push_back(NewParam->
getType());
590 Params.push_back(NewParam);
602 QualType ReturnType = DeducedType;
603 auto TTL = TLB.
push<TagTypeLoc>(ReturnType);
604 TTL.setElaboratedKeywordLoc(SourceLocation());
605 TTL.setQualifierLoc(NestedNameSpecifierLoc());
606 TTL.setNameLoc(Primary->getLocation());
610 FunctionProtoType::ExtProtoInfo EPI;
614 QualType
Result = SemaRef.BuildFunctionType(
615 ReturnType, ParamTypes, TL.
getBeginLoc(), DeductionGuideName, EPI);
619 FunctionProtoTypeLoc NewTL = TLB.
push<FunctionProtoTypeLoc>(
Result);
625 for (
unsigned I = 0, E = NewTL.
getNumParams(); I != E; ++I)
631 ParmVarDecl *transformFunctionTypeParam(
632 ParmVarDecl *OldParam, MultiLevelTemplateArgumentList &Args,
633 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs,
634 bool TransformingOuterPatterns) {
636 TypeSourceInfo *NewTSI;
637 if (
auto PackTL = OldTSI->
getTypeLoc().
getAs<PackExpansionTypeLoc>()) {
639 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, 0u);
641 SemaRef.SubstType(PackTL.getPatternLoc(), Args,
646 SemaRef.CheckPackExpansion(NewTSI, PackTL.getEllipsisLoc(),
647 PackTL.getTypePtr()->getNumExpansions());
649 NewTSI = SemaRef.SubstType(OldTSI, Args, OldParam->
getLocation(),
658 NewTSI = ExtractTypeForDeductionGuide(
659 SemaRef, MaterializedTypedefs, NestedPattern,
660 TransformingOuterPatterns ? &Args :
nullptr)
670 QualType ParamTy = NewTSI->
getType();
671 NewDefArg =
new (SemaRef.Context)
679 auto NewType = NewTSI->
getType();
681 NewType = SemaRef.Context.getDecayedType(NewType);
689 SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);
700 llvm::SmallBitVector ReferencedTemplateParams(TemplateParamsList->
size());
702 DeducedArgs, TemplateParamsList->
getDepth(), ReferencedTemplateParams);
704 auto MarkDefaultArgs = [&](
auto *Param) {
705 if (!Param->hasDefaultArgument())
708 Param->getDefaultArgument().getArgument(),
709 TemplateParamsList->
getDepth(), ReferencedTemplateParams);
712 for (
unsigned Index = 0; Index < TemplateParamsList->
size(); ++Index) {
713 if (!ReferencedTemplateParams[Index])
715 auto *Param = TemplateParamsList->
getParam(Index);
716 if (
auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param))
717 MarkDefaultArgs(TTPD);
718 else if (
auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param))
719 MarkDefaultArgs(NTTPD);
725 for (
unsigned Index = 0; Index < TemplateParamsList->
size(); ++Index) {
726 if (ReferencedTemplateParams[Index])
727 Results.push_back(Index);
737 "name must be a deduction guide name");
738 auto Existing = DC->
lookup(Name);
739 for (
auto *D : Existing)
747llvm::DenseSet<const NamedDecl *> getSourceDeductionGuides(
DeclarationName Name,
751 "name must be a deduction guide name");
752 llvm::DenseSet<const NamedDecl *> Result;
753 for (
auto *D : DC->
lookup(Name)) {
754 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
757 if (
const auto *GD = dyn_cast<CXXDeductionGuideDecl>(D)) {
758 assert(GD->getSourceDeductionGuide() &&
759 "deduction guide for alias template must have a source deduction "
761 Result.insert(GD->getSourceDeductionGuide());
779 unsigned FirstUndeducedParamIdx,
Expr *IsDeducible) {
804 unsigned AdjustDepth = 0;
805 if (
auto *PrimaryTemplate =
807 AdjustDepth = PrimaryTemplate->getTemplateDepth();
819 NamedDecl *NewParam = transformTemplateParameter(
821 AdjustedAliasTemplateArgs.size(),
825 Context.getInjectedTemplateArg(NewParam);
826 AdjustedAliasTemplateArgs.push_back(NewTemplateArgument);
837 for (
unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
838 const auto &D = DeduceResults[Index];
846 transformTemplateParameter(SemaRef, F->
getDeclContext(), TP, Args,
847 FirstUndeducedParamIdx,
849 FirstUndeducedParamIdx += 1;
850 assert(TemplateArgsForBuildingRC[Index].isNull());
851 TemplateArgsForBuildingRC[Index] =
852 Context.getInjectedTemplateArg(NewParam);
859 assert(TemplateArgsForBuildingRC[Index].isNull() &&
860 "InstantiatedArgs must be null before setting");
861 TemplateArgsForBuildingRC[Index] = Output.
getArgument();
901 clang::Decl::ClassTemplateSpecialization) {
908 for (
auto It : OuterLevelArgs)
918 BinaryOperatorKind::BO_LAnd, E.
get(), IsDeducible);
919 if (Conjunction.isInvalid())
927Expr *buildIsDeducibleConstraint(
Sema &SemaRef,
933 if (
auto *PrimaryTemplate =
935 PrimaryTemplate && TemplateParams.size() > 0) {
939 unsigned AdjustDepth = PrimaryTemplate->getTemplateDepth();
941 for (
auto *TP : TemplateParams) {
947 NamedDecl *NewParam = transformTemplateParameter(
949 TransformedTemplateArgs.size(),
953 Context.getInjectedTemplateArg(NewParam);
954 TransformedTemplateArgs.push_back(NewTemplateArgument);
962 Context.DeclarationNames.getCXXDeductionGuideName(
AliasTemplate));
966 Context.getTrivialTypeSourceInfo(
967 Context.getDeducedTemplateSpecializationType(
973 Context.getTrivialTypeSourceInfo(
978 Context, Context.getLogicalOperationType(),
AliasTemplate->getLocation(),
979 TypeTrait::BTT_IsDeducible, IsDeducibleTypeTraitArgs,
983std::pair<TemplateDecl *, llvm::ArrayRef<TemplateArgument>>
985 auto RhsType =
AliasTemplate->getTemplatedDecl()->getUnderlyingType();
988 if (
const auto *TST = RhsType->getAs<TemplateSpecializationType>()) {
992 Template = TST->getTemplateName().getAsTemplateDecl();
993 AliasRhsTemplateArgs =
994 TST->getAsNonAliasTemplateSpecializationType()->template_arguments();
995 }
else if (
const auto *RT = RhsType->getAs<RecordType>()) {
999 if (
const auto *CTSD =
1000 dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl())) {
1001 Template = CTSD->getSpecializedTemplate();
1002 AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray();
1005 return {
Template, AliasRhsTemplateArgs};
1024BuildDeductionGuideForTypeAlias(
Sema &SemaRef,
1032 if (BuildingDeductionGuides.isInvalid())
1035 auto &Context = SemaRef.
Context;
1036 auto [
Template, AliasRhsTemplateArgs] =
1059 const auto *FReturnType = RType->
getAs<TemplateSpecializationType>();
1060 if (
const auto *ICNT = RType->getAsCanonical<InjectedClassNameType>())
1063 ICNT->getDecl()->getCanonicalTemplateSpecializationType(
1065 assert(FReturnType &&
"expected to see a return type");
1098 AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
1105 for (
unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1106 const auto &D = DeduceResults[Index];
1107 if (!IsNonDeducedArgument(D))
1108 DeducedArgs.push_back(D);
1110 NonDeducedTemplateParamsInFIndex.push_back(Index);
1112 auto DeducedAliasTemplateParams =
1113 TemplateParamsReferencedInTemplateArgumentList(
1114 SemaRef,
AliasTemplate->getTemplateParameters(), DeducedArgs);
1136 for (
unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {
1138 AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx);
1144 NamedDecl *NewParam = transformTemplateParameter(
1147 FPrimeTemplateParams.push_back(NewParam);
1150 Context.getInjectedTemplateArg(NewParam);
1151 TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument;
1153 unsigned FirstUndeducedParamIdx = FPrimeTemplateParams.size();
1173 for (
unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1174 const auto &D = DeduceResults[Index];
1176 if (IsNonDeducedArgument(D)) {
1185 assert(TemplateArgsForBuildingFPrime[Index].isNull() &&
1186 "InstantiatedArgs must be null before setting");
1203 TemplateArgsForBuildingFPrime[Index] =
1214 for (
unsigned FTemplateParamIdx : NonDeducedTemplateParamsInFIndex) {
1221 NamedDecl *NewParam = transformTemplateParameter(
1222 SemaRef, F->
getDeclContext(), TP, Args, FPrimeTemplateParams.size(),
1224 FPrimeTemplateParams.push_back(NewParam);
1226 assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&
1227 "The argument must be null before setting");
1228 TemplateArgsForBuildingFPrime[FTemplateParamIdx] =
1229 Context.getInjectedTemplateArg(NewParam);
1232 auto *TemplateArgListForBuildingFPrime =
1236 F, TemplateArgListForBuildingFPrime,
AliasTemplate->getLocation(),
1240 Expr *IsDeducible = buildIsDeducibleConstraint(
1241 SemaRef,
AliasTemplate, FPrime->getReturnType(), FPrimeTemplateParams);
1242 Expr *RequiresClause =
1243 buildAssociatedConstraints(SemaRef, F,
AliasTemplate, DeduceResults,
1244 FirstUndeducedParamIdx, IsDeducible);
1247 Context,
AliasTemplate->getTemplateParameters()->getTemplateLoc(),
1249 FPrimeTemplateParams,
1254 GG->getCorrespondingConstructor(), GG->getExplicitSpecifier(),
1259 DGuide->setDeductionCandidateKind(GG->getDeductionCandidateKind());
1260 DGuide->setSourceDeductionGuide(
1262 DGuide->setSourceDeductionGuideKind(
1269void DeclareImplicitDeductionGuidesForTypeAlias(
1273 auto &Context = SemaRef.
Context;
1274 auto [
Template, AliasRhsTemplateArgs] =
1278 auto SourceDeductionGuides = getSourceDeductionGuides(
1279 Context.DeclarationNames.getCXXDeductionGuideName(
AliasTemplate),
1283 Context.DeclarationNames.getCXXDeductionGuideName(
Template), Loc);
1286 Guides.suppressDiagnostics();
1288 for (
auto *G : Guides) {
1289 if (
auto *DG = dyn_cast<CXXDeductionGuideDecl>(G)) {
1290 if (SourceDeductionGuides.contains(DG))
1299 for (
unsigned I = 0, N = DG->getNumParams(); I != N; ++I) {
1300 const auto *P = DG->getParamDecl(I);
1303 SemaRef.
Context, G->getDeclContext(),
1304 DG->getParamDecl(I)->getBeginLoc(), P->getLocation(),
nullptr,
1314 Transformed->setSourceDeductionGuide(DG);
1315 Transformed->setSourceDeductionGuideKind(
1326 BinaryOperatorKind::BO_LAnd,
const_cast<Expr *
>(RC.ConstraintExpr),
1327 const_cast<Expr *
>(Constraint.ConstraintExpr));
1328 if (!Conjunction.isInvalid()) {
1329 Constraint.ConstraintExpr = Conjunction.getAs<
Expr>();
1330 Constraint.ArgPackSubstIndex = RC.ArgPackSubstIndex;
1333 Transformed->setTrailingRequiresClause(Constraint);
1346 BuildDeductionGuideForTypeAlias(SemaRef,
AliasTemplate, F, Loc);
1361 ExtractTypeForDeductionGuide TypeAliasTransformer(SemaRef, TypedefDecls);
1366 NewParamTypes.push_back(
Type);
1370 RHSTemplate, NewParamTypes, Loc);
1371 if (!RHSDeductionGuide)
1377 return BuildDeductionGuideForTypeAlias(SemaRef,
AliasTemplate,
1378 RHSDeductionGuide, Loc);
1386 llvm::FoldingSetNodeID ID;
1388 for (
auto &
T : ParamTypes)
1389 T.getCanonicalType().Profile(ID);
1390 unsigned Hash = ID.ComputeHash();
1399 if (
auto *FTD = DeclareAggregateDeductionGuideForTypeAlias(
1411 DefRecord->getDescribedClassTemplate())
1419 ConvertConstructorToDeductionGuideTransform Transform(
1432 if (BuildingDeductionGuides.isInvalid())
1436 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
1440 Transform.buildSimpleDeductionGuide(ParamTypes));
1451 DeclareImplicitDeductionGuidesForTypeAlias(*
this,
AliasTemplate, Loc);
1455 dyn_cast_or_null<CXXRecordDecl>(
Template->getTemplatedDecl());
1468 ConvertConstructorToDeductionGuideTransform Transform(
1473 if (hasDeclaredDeductionGuides(Transform.DeductionGuideName, DC))
1484 if (BuildingDeductionGuides.isInvalid())
1492 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
1495 bool AddedAny =
false;
1497 D = D->getUnderlyingDecl();
1498 if (D->isInvalidDecl() || D->isImplicit())
1506 if (ProcessedCtors.count(D))
1509 auto *FTD = dyn_cast<FunctionTemplateDecl>(D);
1519 return !P || P->hasUnparsedDefaultArg();
1523 ProcessedCtors.insert(D);
1524 Transform.transformConstructor(FTD, CD);
1533 Transform.buildSimpleDeductionGuide({});
1539 Transform.buildSimpleDeductionGuide(Transform.DeducedType))
1540 ->getTemplatedDecl())
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines the classes used to store parsed information about declaration-specifiers and decla...
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
Defines the clang::TypeLoc interface and its subclasses.
Defines enumerations for the type traits support.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
DeclarationNameTable DeclarationNames
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
Represents a C++ constructor within a class.
ExplicitSpecifier getExplicitSpecifier()
Represents a C++ deduction guide declaration.
static CXXDeductionGuideDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor=nullptr, DeductionCandidate Kind=DeductionCandidate::Normal, const AssociatedConstraint &TrailingRequiresClause={}, const CXXDeductionGuideDecl *SourceDG=nullptr, SourceDeductionGuideKind SK=SourceDeductionGuideKind::None)
Represents a C++ struct/union/class.
CXXRecordDecl * getDefinition() const
Declaration of a class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
ClassTemplateDecl * getInstantiatedFromMemberTemplate() const
const TypeClass * getTypePtr() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
void addDecl(Decl *D)
Add the declaration D into this context.
Decl::Kind getDeclKind() const
SourceLocation getEndLoc() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
SourceLocation getLocation() const
DeclContext * getDeclContext()
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
The name of a declaration.
NameKind getNameKind() const
Determine what kind of name this is.
SourceLocation getInnerLocStart() const
Return start of source range ignoring outer template declarations.
SourceLocation getBeginLoc() const LLVM_READONLY
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
TypeSourceInfo * getTypeSourceInfo() const
SourceLocation getElaboratedKeywordLoc() const
SourceLocation getNameLoc() const
NestedNameSpecifierLoc getQualifierLoc() const
Store information needed for an explicit specifier.
This represents one expression.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool isVariadic() const
Whether this function prototype is variadic.
Declaration of a template function.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
unsigned getNumParams() const
SourceLocation getLocalRangeEnd() const
void setLocalRangeBegin(SourceLocation L)
void setLParenLoc(SourceLocation Loc)
void setParam(unsigned i, ParmVarDecl *VD)
ArrayRef< ParmVarDecl * > getParams() const
void setRParenLoc(SourceLocation Loc)
void setLocalRangeEnd(SourceLocation L)
void setExceptionSpecRange(SourceRange R)
SourceLocation getLocalRangeBegin() const
SourceLocation getLParenLoc() const
SourceLocation getRParenLoc() const
FunctionType - C99 6.7.5.3 - Function Declarators.
const TypeClass * getTypePtr() const
A stack-allocated class that identifies which local variable declaration instantiations are present i...
void InstantiatedLocal(const Decl *D, Decl *Inst)
Represents the results of name lookup.
Data structure that captures multiple levels of template argument lists for use in template instantia...
void addOuterRetainedLevel()
Add an outermost level that we are not substituting.
void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final)
Add a new outmost level to the multi-level template argument list.
void setKind(TemplateSubstitutionKind K)
void addOuterRetainedLevels(unsigned Num)
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
SourceRange getDefaultArgRange() const
Retrieve the source range that covers the entire default argument.
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
bool hasDefaultArg() const
Determines whether this parameter has a default argument, either parsed or not.
unsigned getFunctionScopeDepth() const
A (possibly-)qualified type.
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Scope - A scope is a transient data structure that is used while parsing the program.
RAII object used to change the argument pack substitution index within a Sema object.
Sema - This implements semantic analysis and AST building for C.
bool SubstTypeConstraint(TemplateTypeParmDecl *Inst, const TypeConstraint *TC, const MultiLevelTemplateArgumentList &TemplateArgs, bool EvaluateConstraint)
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
Scope * getCurScope() const
Retrieve the parser's current scope.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
FunctionTemplateDecl * DeclareAggregateDeductionGuideFromInitList(TemplateDecl *Template, MutableArrayRef< QualType > ParamTypes, SourceLocation Loc)
FunctionDecl * InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, const TemplateArgumentList *Args, SourceLocation Loc, CodeSynthesisContext::SynthesisKind CSC=CodeSynthesisContext::ExplicitTemplateArgumentSubstitution)
Instantiate (or find existing instantiation of) a function template with a given set of template argu...
@ CTAK_Specified
The template argument was specified in the code or was instantiated with some deduced template argume...
ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
ASTContext & getASTContext() const
TypeSourceInfo * SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, bool AllowDeducedTST=false)
Perform substitution on the type T with a given set of template arguments.
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
bool CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg, NamedDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, unsigned ArgumentPackIndex, CheckTemplateArgumentInfo &CTAI, CheckTemplateArgumentKind CTAK)
Check that the given template argument corresponds to the given template parameter.
llvm::DenseMap< unsigned, CXXDeductionGuideDecl * > AggregateDeductionCandidates
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(const NamedDecl *D, const DeclContext *DC=nullptr, bool Final=false, std::optional< ArrayRef< TemplateArgument > > Innermost=std::nullopt, bool RelativeToPrimary=false, const FunctionDecl *Pattern=nullptr, bool ForConstraintInstantiation=false, bool SkipForSpecialization=false, bool ForDefaultArgumentSubstitution=false)
Retrieve the template argument list(s) that should be used to instantiate the definition of the given...
void DeclareImplicitDeductionGuides(TemplateDecl *Template, SourceLocation Loc)
Declare implicit deduction guides for a class template if we've not already done so.
Decl * SubstDecl(Decl *D, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs)
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
bool SubstTemplateArgument(const TemplateArgumentLoc &Input, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentLoc &Output, SourceLocation Loc={}, const DeclarationName &Entity={})
void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark which template parameters are used in a given expression.
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr, bool ForFoldExpression=false)
TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef< TemplateArgument > TemplateArgs, sema::TemplateDeductionInfo &Info)
DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class)
Look up the constructors for the given class.
Encodes a location in the source.
SourceLocation getBegin() const
A convenient class for passing around template argument information.
ArrayRef< TemplateArgumentLoc > arguments() const
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
Location wrapper for a TemplateArgument.
const TemplateArgument & getArgument() const
Represents a template argument.
static TemplateArgument CreatePackCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument pack by copying the given set of template arguments.
bool isNull() const
Determine whether this template argument has no value.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Pack
The template argument is actually a parameter pack.
ArgKind getKind() const
Return the kind of stored template argument.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
SourceLocation getTemplateLoc() const
Declaration of a template type parameter.
bool wasDeclaredWithTypename() const
Whether this template type parameter was declared with the 'typename' keyword.
SourceLocation getDefaultArgumentLoc() const
Retrieves the location of the default argument declaration.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool hasTypeConstraint() const
Determine whether this template parameter has a type-constraint.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
UnsignedOrNone getNumExpansionParameters() const
Whether this parameter is a template type parameter pack that has a known list of different type-cons...
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool isParameterPack() const
Returns whether this is a parameter pack.
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)
static TypeAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)
Declaration of an alias template.
SourceLocation getBeginLoc() const LLVM_READONLY
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)
Creates a TypeSourceInfo for the given type.
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
T castAs() const
Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
static TypeTraitExpr * Create(const ASTContext &C, QualType T, SourceLocation Loc, TypeTrait Kind, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool Value)
Create a new type trait expression.
The base class of the type hierarchy.
bool isRValueReferenceType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
bool isLValueReferenceType() const
bool isFunctionType() const
const T * getAs() const
Member-template getAs<specific type>'.
static TypedefDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)
Base class for declarations which introduce a typedef-name.
TypeSourceInfo * getTypeSourceInfo() const
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Provides information about an attempted template argument deduction, whose success or failure was des...
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ Rewrite
We are substituting template parameters for (typically) other template parameters in order to rewrite...
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Result
The result type of a method or function.
std::pair< unsigned, unsigned > getDepthAndIndex(const NamedDecl *ND)
Retrieve the depth and index of a template parameter.
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
@ Keyword
The name has been typo-corrected to a keyword.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
U cast(CodeGen::Address addr)
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
@ None
No keyword precedes the qualified type name.
ActionResult< Expr * > ExprResult
const Expr * ConstraintExpr
UnsignedOrNone ArgPackSubstIndex
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
unsigned HasTrailingReturn
SmallVector< TemplateArgument, 4 > SugaredConverted
The checked, converted argument will be added to the end of these vectors.
@ BuildingDeductionGuides
We are building deduction guides for a class.
A stack object to be created when performing template instantiation.