clang: lib/Sema/SemaTemplateDeductionGuide.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
45#include "llvm/ADT/ArrayRef.h"
46#include "llvm/ADT/STLExtras.h"
47#include "llvm/ADT/SmallVector.h"
48#include "llvm/Support/Casting.h"
49#include "llvm/Support/ErrorHandling.h"
50#include
51#include
52#include
53
54using namespace clang;
55using namespace sema;
56
57namespace {
58
59
60class ExtractTypeForDeductionGuide
61 : public TreeTransform {
65 std::optional TypedefNameInstantiator;
66
67public:
69 ExtractTypeForDeductionGuide(
70 Sema &SemaRef,
74 : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs),
75 NestedPattern(NestedPattern),
76 OuterInstantiationArgs(OuterInstantiationArgs) {
77 if (OuterInstantiationArgs)
78 TypedefNameInstantiator.emplace(
80 *OuterInstantiationArgs);
81 }
82
84
85
86
87 bool mightReferToOuterTemplateParameters(TypedefNameDecl *Typedef) {
88 if (!NestedPattern)
89 return false;
90
92 if (DC->Equals(TargetDC))
93 return true;
95 if (DC->Equals(TargetDC))
96 return true;
98 }
99 return false;
100 };
101
103 return true;
105 return true;
106 return false;
107 }
108
113 if (!OuterInstantiationArgs ||
114 !isa_and_present(Template.getAsTemplateDecl()))
116 TemplateArgs);
117
118 auto *TATD = cast(Template.getAsTemplateDecl());
119 auto *Pattern = TATD;
120 while (Pattern->getInstantiatedFromMemberTemplate())
121 Pattern = Pattern->getInstantiatedFromMemberTemplate();
122 if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl()))
124 TemplateArgs);
125
127 TypedefNameInstantiator->InstantiateTypeAliasTemplateDecl(TATD);
128 if (!NewD)
130
131 auto *NewTATD = cast(NewD);
132 MaterializedTypedefs.push_back(NewTATD->getTemplatedDecl());
133
135 TemplateName(NewTATD), TemplateNameLoc, TemplateArgs);
136 }
137
142
143
145
146
147
148
149
150
151
152
153
154
155
156
157
158 if (OuterInstantiationArgs && InDependentContext &&
160 Decl = cast_if_present(
161 TypedefNameInstantiator->InstantiateTypedefNameDecl(
162 OrigDecl, isa(OrigDecl)));
165 MaterializedTypedefs.push_back(Decl);
166 } else if (InDependentContext) {
171 if (isa(OrigDecl))
175 else {
176 assert(isa(OrigDecl) && "Not a Type alias or typedef");
180 }
181 MaterializedTypedefs.push_back(Decl);
182 }
183
187
188 return TDTy;
189 }
190};
191
192
193
194
195
196
204 auto DeductionGuideName =
206 OriginalTemplate);
207
211
212
213 auto *Guide =
215 TInfo->getType(), TInfo, LocEnd, Ctor);
216 Guide->setImplicit(IsImplicit);
217 Guide->setParams(Params);
218
219 for (auto *Param : Params)
220 Param->setDeclContext(Guide);
221 for (auto *TD : MaterializedTypedefs)
222 TD->setDeclContext(Guide);
223 if (isa(DC))
225
226 if (!TemplateParams) {
228 return Guide;
229 }
230
232 SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide);
233 GuideTemplate->setImplicit(IsImplicit);
234 Guide->setDescribedFunctionTemplate(GuideTemplate);
235
236 if (isa(DC))
237 GuideTemplate->setAccess(AS_public);
238
239 DC->addDecl(GuideTemplate);
240 return GuideTemplate;
241}
242
243
247 bool EvaluateConstraint) {
248
249
256 : std::nullopt);
259 EvaluateConstraint);
265 NewTTP->setDefaultArgument(SemaRef.Context, InstantiatedDefaultArg);
266 }
268 return NewTTP;
269}
270
271template
272NonTypeTemplateOrTemplateTemplateParmDecl *
274 NonTypeTemplateOrTemplateTemplateParmDecl *OldParam,
276 unsigned NewDepth) {
277
278
279 auto *NewParam = cast(
280 SemaRef.SubstDecl(OldParam, DC, Args));
281 NewParam->setPosition(NewIndex);
282 NewParam->setDepth(NewDepth);
283 return NewParam;
284}
285
289 unsigned NewIndex, unsigned NewDepth,
290 bool EvaluateConstraint = true) {
291 if (auto *TTP = dyn_cast(TemplateParam))
292 return transformTemplateTypeParam(
293 SemaRef, DC, TTP, Args, NewDepth, NewIndex,
294 EvaluateConstraint);
295 if (auto *TTP = dyn_cast(TemplateParam))
296 return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex, NewDepth);
297 if (auto *NTTP = dyn_cast(TemplateParam))
298 return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, NewDepth);
299 llvm_unreachable("Unhandled template parameter types");
300}
301
302
303
304struct ConvertConstructorToDeductionGuideTransform {
305 ConvertConstructorToDeductionGuideTransform(Sema &S,
307 : SemaRef(S), Template(Template) {
308
309
313 break;
315 NestedPattern = Pattern;
316 }
317
318 if (NestedPattern)
320 }
321
322 Sema &SemaRef;
325
330
332
333
334
336
337
338
340
341
345
347
348
349
350
351
352
353
354
357 if (FTD) {
361 AllParams.reserve(TemplateParams->size() + InnerParams->size());
362 AllParams.insert(AllParams.begin(), TemplateParams->begin(),
363 TemplateParams->end());
364 SubstArgs.reserve(InnerParams->size());
365 Depth1Args.reserve(InnerParams->size());
366
367
368
369 for (NamedDecl *Param : *InnerParams) {
371 Args.setKind(TemplateSubstitutionKind::Rewrite);
374 if (NestedPattern)
377 NamedDecl *NewParam = transformTemplateParameter(
378 SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment, Depth - 1);
379 if (!NewParam)
380 return nullptr;
381
382
384
385 if (NestedPattern) {
387 NewParam = transformTemplateParameter(
388 SemaRef, DC, NewParam, OuterInstantiationArgs, Index,
390 false);
391 }
392
394 "Unexpected template parameter depth");
395
396 AllParams.push_back(NewParam);
398 }
399
400
401 Expr *RequiresClause = nullptr;
402 if (Expr *InnerRC = InnerParams->getRequiresClause()) {
404 Args.setKind(TemplateSubstitutionKind::Rewrite);
407 if (NestedPattern)
410 if (E.isInvalid())
411 return nullptr;
412 RequiresClause = E.getAs<Expr>();
413 }
414
415 TemplateParams = TemplateParameterList::Create(
416 SemaRef.Context, InnerParams->getTemplateLoc(),
417 InnerParams->getLAngleLoc(), AllParams, InnerParams->getRAngleLoc(),
418 RequiresClause);
419 }
420
421
422
423
425 Args.setKind(TemplateSubstitutionKind::Rewrite);
426 if (FTD) {
429 }
430
434 assert(FPTL && "no prototype for constructor declaration");
435
436
437
438
442 QualType NewType = transformFunctionProtoType(TLB, FPTL, Params, Args,
443 MaterializedTypedefs);
444 if (NewType.isNull())
445 return nullptr;
447
448 return buildDeductionGuide(
451 true, MaterializedTypedefs);
452 }
453
454
457
458
462 DeductionGuideName, EPI);
464 if (NestedPattern)
465 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
466 DeductionGuideName);
467
468 if (!TSI)
469 return nullptr;
470
473
474
476 for (auto T : ParamTypes) {
478 if (NestedPattern)
479 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
481 if (!TSI)
482 return nullptr;
483
488 FPTL.setParam(Params.size(), NewParam);
489 Params.push_back(NewParam);
490 }
491
492 return buildDeductionGuide(
495 }
496
497private:
498 QualType transformFunctionProtoType(
505
506
507 for (auto *OldParam : TL.getParams()) {
509
510
511
512
513
514
515
516
517
518 if (NestedPattern) {
519 NewParam = transformFunctionTypeParam(
520 NewParam, OuterInstantiationArgs, MaterializedTypedefs,
521 true);
522 if (!NewParam)
524 }
525
526
527
528 NewParam =
529 transformFunctionTypeParam(NewParam, Args, MaterializedTypedefs,
530 false);
531 if (!NewParam)
533 ParamTypes.push_back(NewParam->getType());
534 Params.push_back(NewParam);
535 }
536
537
538
539
540
541
542
543
544
545
548
549
550
554
556 ReturnType, ParamTypes, TL.getBeginLoc(), DeductionGuideName, EPI);
557 if (Result.isNull())
559
566 for (unsigned I = 0, E = NewTL.getNumParams(); I != E; ++I)
567 NewTL.setParam(I, Params[I]);
568
569 return Result;
570 }
571
575 bool TransformingOuterPatterns) {
579
581 NewDI =
582 SemaRef.SubstType(PackTL.getPatternLoc(), Args,
584 if (!NewDI)
585 return nullptr;
586 NewDI =
588 PackTL.getTypePtr()->getNumExpansions());
589 } else
592 if (!NewDI)
593 return nullptr;
594
595
596
597
598
599 NewDI = ExtractTypeForDeductionGuide(
600 SemaRef, MaterializedTypedefs, NestedPattern,
601 TransformingOuterPatterns ? &Args : nullptr)
602 .transform(NewDI);
603
604
605
608
609
611 NewDefArg = new (SemaRef.Context)
617 }
618
619 auto NewType = NewDI->getType();
622
630 return NewParam;
631 }
632};
633
634
635
641 llvm::BitVector ReferencedTemplateParams;
642
643 TemplateParamsReferencedFinder(
645 : TemplateParamList(TemplateParamList),
646 ReferencedTemplateParams(TemplateParamList->size()) {}
647
649
650
652 return true;
653 }
654
655 bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
657 return true;
658 }
659
662 MarkAppeared(TD);
664 }
665
666 void MarkAppeared(NamedDecl *ND) {
670 Mark(Depth, Index);
671 }
672 }
673 void Mark(unsigned Depth, unsigned Index) {
674 if (Index < TemplateParamList->size() &&
676 ReferencedTemplateParams.set(Index);
677 }
678 };
679 TemplateParamsReferencedFinder Finder(TemplateParamsList);
680 Finder.TraverseTemplateArguments(DeducedArgs);
681
683 for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
684 if (Finder.ReferencedTemplateParams[Index])
685 Results.push_back(Index);
686 }
687 return Results;
688}
689
691
692
693 assert(Name.getNameKind() ==
694 DeclarationName::NameKind::CXXDeductionGuideName &&
695 "name must be a deduction guide name");
696 auto Existing = DC->lookup(Name);
697 for (auto *D : Existing)
699 return true;
700 return false;
701}
702
703
704
705
706
707
708
709
710
715 unsigned FirstUndeducedParamIdx, Expr *IsDeducible) {
717 if (!RC)
718 return IsDeducible;
719
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740 unsigned AdjustDepth = 0;
741 if (auto *PrimaryTemplate =
742 AliasTemplate->getInstantiatedFromMemberTemplate())
743 AdjustDepth = PrimaryTemplate->getTemplateDepth();
744
745
746
748
749 for (auto *TP : *AliasTemplate->getTemplateParameters()) {
750
751
753 Args.setKind(TemplateSubstitutionKind::Rewrite);
755 NamedDecl *NewParam = transformTemplateParameter(
756 SemaRef, AliasTemplate->getDeclContext(), TP, Args,
757 AdjustedAliasTemplateArgs.size(),
759
762 AdjustedAliasTemplateArgs.push_back(NewTemplateArgument);
763 }
764
765
768
770 Args.setKind(TemplateSubstitutionKind::Rewrite);
772
773 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
774 const auto &D = DeduceResults[Index];
775 if (D.isNull()) {
778 Args.setKind(TemplateSubstitutionKind::Rewrite);
780
782 transformTemplateParameter(SemaRef, F->getDeclContext(), TP, Args,
783 FirstUndeducedParamIdx,
785 FirstUndeducedParamIdx += 1;
786 assert(TemplateArgsForBuildingRC[Index].isNull());
787 TemplateArgsForBuildingRC[Index] =
789 continue;
790 }
795 assert(TemplateArgsForBuildingRC[Index].isNull() &&
796 "InstantiatedArgs must be null before setting");
797 TemplateArgsForBuildingRC[Index] = Output.getArgument();
798 }
799 }
800
801
802
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
837 clang::Decl::ClassTemplateSpecialization) {
840 false, std::nullopt,
841 true,
842 nullptr,
843 true);
844 for (auto It : OuterLevelArgs)
846 }
847
849 if (E.isInvalid())
850 return nullptr;
851
852 auto Conjunction =
854 BinaryOperatorKind::BO_LAnd, E.get(), IsDeducible);
855 if (Conjunction.isInvalid())
856 return nullptr;
857 return Conjunction.getAs<Expr>();
858}
859
860
861
862
863Expr *buildIsDeducibleConstraint(Sema &SemaRef,
868
869 if (auto *PrimaryTemplate =
870 AliasTemplate->getInstantiatedFromMemberTemplate();
871 PrimaryTemplate && TemplateParams.size() > 0) {
873
874
875 unsigned AdjustDepth = PrimaryTemplate->getTemplateDepth();
877 for (auto *TP : TemplateParams) {
878
879
881 Args.setKind(TemplateSubstitutionKind::Rewrite);
883 NamedDecl *NewParam = transformTemplateParameter(
884 SemaRef, AliasTemplate->getDeclContext(), TP, Args,
885 TransformedTemplateArgs.size(),
887
890 TransformedTemplateArgs.push_back(NewTemplateArgument);
891 }
892
894 Args.setKind(TemplateSubstitutionKind::Rewrite);
899 };
900
905 true)),
906
908 ReturnType),
909 };
912 TypeTrait::BTT_IsDeducible, IsDeducibleTypeTraitArgs,
914}
915
916std::pair<TemplateDecl *, llvm::ArrayRef>
918
920 ->getUnderlyingType()
921 .getSingleStepDesugaredType(SemaRef.Context);
925
926
927
928 Template = TST->getTemplateName().getAsTemplateDecl();
929 AliasRhsTemplateArgs = TST->template_arguments();
930 } else if (const auto *RT = RhsType->getAs<RecordType>()) {
931
932
933
934 if (const auto *CTSD = llvm::dyn_cast(
935 RT->getAsCXXRecordDecl())) {
936 Template = CTSD->getSpecializedTemplate();
937 AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray();
938 }
939 } else {
940 assert(false && "unhandled RHS type of the alias");
941 }
942 return {Template, AliasRhsTemplateArgs};
943}
944
945
946
948BuildDeductionGuideForTypeAlias(Sema &SemaRef,
955 if (BuildingDeductionGuides.isInvalid())
956 return nullptr;
957
958 auto &Context = SemaRef.Context;
959 auto [Template, AliasRhsTemplateArgs] =
960 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
961
963
967
968 FReturnType = InjectedCNT->getInjectedTST();
969 else if (const auto *ET = RType->getAs<ElaboratedType>())
970
972 assert(FReturnType && "expected to see a return type");
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
994
997
998
999
1000
1001
1002
1005 AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
1006 false);
1007
1010
1011
1012 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1013 if (const auto &D = DeduceResults[Index]; .isNull())
1014 DeducedArgs.push_back(D);
1015 else
1016 NonDeducedTemplateParamsInFIndex.push_back(Index);
1017 }
1018 auto DeducedAliasTemplateParams =
1019 TemplateParamsReferencedInTemplateArgumentList(
1020 AliasTemplate->getTemplateParameters(), DeducedArgs);
1021
1024
1025
1026
1027
1028
1029
1030
1031
1033
1034
1036 AliasTemplate->getTemplateParameters()->size());
1037
1038 for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {
1039 auto *TP =
1040 AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx);
1041
1042
1044 Args.setKind(TemplateSubstitutionKind::Rewrite);
1046 NamedDecl *NewParam = transformTemplateParameter(
1047 SemaRef, AliasTemplate->getDeclContext(), TP, Args,
1048 FPrimeTemplateParams.size(), getDepthAndIndex(TP).first);
1049 FPrimeTemplateParams.push_back(NewParam);
1050
1053 TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument;
1054 }
1055 unsigned FirstUndeducedParamIdx = FPrimeTemplateParams.size();
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1073 Args.setKind(TemplateSubstitutionKind::Rewrite);
1075 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1076 const auto &D = DeduceResults[Index];
1077 if (D.isNull()) {
1078
1079 continue;
1080 }
1085 assert(TemplateArgsForBuildingFPrime[Index].isNull() &&
1086 "InstantiatedArgs must be null before setting");
1087 TemplateArgsForBuildingFPrime[Index] = Output.getArgument();
1088 }
1089 }
1090
1091
1092
1093
1094 for (unsigned FTemplateParamIdx : NonDeducedTemplateParamsInFIndex) {
1097 Args.setKind(TemplateSubstitutionKind::Rewrite);
1098
1099
1101 NamedDecl *NewParam = transformTemplateParameter(
1102 SemaRef, F->getDeclContext(), TP, Args, FPrimeTemplateParams.size(),
1104 FPrimeTemplateParams.push_back(NewParam);
1105
1106 assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&
1107 "The argument must be null before setting");
1108 TemplateArgsForBuildingFPrime[FTemplateParamIdx] =
1110 }
1111
1112 auto *TemplateArgListForBuildingFPrime =
1114
1116 F, TemplateArgListForBuildingFPrime, AliasTemplate->getLocation(),
1118 auto *GG = cast(FPrime);
1119
1120 Expr *IsDeducible = buildIsDeducibleConstraint(
1121 SemaRef, AliasTemplate, FPrime->getReturnType(), FPrimeTemplateParams);
1122 Expr *RequiresClause =
1123 buildAssociatedConstraints(SemaRef, F, AliasTemplate, DeduceResults,
1124 FirstUndeducedParamIdx, IsDeducible);
1125
1126 auto *FPrimeTemplateParamList = TemplateParameterList::Create(
1127 Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
1128 AliasTemplate->getTemplateParameters()->getLAngleLoc(),
1129 FPrimeTemplateParams,
1130 AliasTemplate->getTemplateParameters()->getRAngleLoc(),
1131 RequiresClause);
1132 auto *Result = cast(buildDeductionGuide(
1133 SemaRef, AliasTemplate, FPrimeTemplateParamList,
1134 GG->getCorrespondingConstructor(), GG->getExplicitSpecifier(),
1135 GG->getTypeSourceInfo(), AliasTemplate->getBeginLoc(),
1138 cast(Result->getTemplatedDecl())
1139 ->setDeductionCandidateKind(GG->getDeductionCandidateKind());
1140 return Result;
1141 }
1142 return nullptr;
1143}
1144
1145void DeclareImplicitDeductionGuidesForTypeAlias(
1148 return;
1149 auto &Context = SemaRef.Context;
1150
1151
1152
1153 if (hasDeclaredDeductionGuides(
1156 return;
1157 auto [Template, AliasRhsTemplateArgs] =
1158 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
1159 if (!Template)
1160 return;
1165 Guides.suppressDiagnostics();
1166
1167 for (auto *G : Guides) {
1168 if (auto *DG = dyn_cast(G)) {
1169
1174
1175
1176 for (unsigned I = 0, N = DG->getNumParams(); I != N; ++I) {
1177 const auto *P = DG->getParamDecl(I);
1180 SemaRef.Context, G->getDeclContext(),
1181 DG->getParamDecl(I)->getBeginLoc(), P->getLocation(), nullptr,
1185 }
1186 auto *Transformed = cast(buildDeductionGuide(
1187 SemaRef, AliasTemplate, nullptr,
1188 nullptr, DG->getExplicitSpecifier(), FunctionType,
1191
1192
1193
1194
1195 auto *Constraint = buildIsDeducibleConstraint(
1196 SemaRef, AliasTemplate, Transformed->getReturnType(), {});
1197 if (auto *RC = DG->getTrailingRequiresClause()) {
1198 auto Conjunction =
1200 BinaryOperatorKind::BO_LAnd, RC, Constraint);
1201 if (!Conjunction.isInvalid())
1202 Constraint = Conjunction.getAs<Expr>();
1203 }
1204 Transformed->setTrailingRequiresClause(Constraint);
1205 }
1207 if (!F)
1208 continue;
1209
1210
1211
1213 ->getDeductionCandidateKind() == DeductionCandidate::Aggregate)
1214 continue;
1215
1216 BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate, F, Loc);
1217 }
1218}
1219
1220
1225 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate).first;
1226 if (!RHSTemplate)
1227 return nullptr;
1228
1231 ExtractTypeForDeductionGuide TypeAliasTransformer(SemaRef, TypedefDecls);
1233 QualType Type = TypeAliasTransformer.TransformType(P);
1234 if (Type.isNull())
1235 return nullptr;
1236 NewParamTypes.push_back(Type);
1237 }
1238
1240 RHSTemplate, NewParamTypes, Loc);
1241 if (!RHSDeductionGuide)
1242 return nullptr;
1243
1245 TD->setDeclContext(RHSDeductionGuide->getTemplatedDecl());
1246
1247 return BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate,
1248 RHSDeductionGuide, Loc);
1249}
1250
1251}
1252
1256 llvm::FoldingSetNodeID ID;
1257 ID.AddPointer(Template);
1258 for (auto &T : ParamTypes)
1259 T.getCanonicalType().Profile(ID);
1260 unsigned Hash = ID.ComputeHash();
1261
1266 }
1267
1268 if (auto *AliasTemplate = llvm::dyn_cast(Template)) {
1269 if (auto *FTD = DeclareAggregateDeductionGuideForTypeAlias(
1271 auto *GD = cast(FTD->getTemplatedDecl());
1274 return FTD;
1275 }
1276 }
1277
1281 DefRecord->getDescribedClassTemplate())
1282 Template = DescribedTemplate;
1283 }
1284
1287 return nullptr;
1288
1289 ConvertConstructorToDeductionGuideTransform Transform(
1290 *this, cast(Template));
1292 return nullptr;
1293
1294
1295
1297 -1);
1298
1299
1301 *this, Loc, Template,
1303 if (BuildingDeductionGuides.isInvalid())
1304 return nullptr;
1305
1307 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
1309
1310 auto *FTD = cast(
1311 Transform.buildSimpleDeductionGuide(ParamTypes));
1312 SavedContext.pop();
1313 auto *GD = cast(FTD->getTemplatedDecl());
1316 return FTD;
1317}
1318
1321 if (auto *AliasTemplate = llvm::dyn_cast(Template)) {
1322 DeclareImplicitDeductionGuidesForTypeAlias(*this, AliasTemplate, Loc);
1323 return;
1324 }
1328 DefRecord->getDescribedClassTemplate())
1329 Template = DescribedTemplate;
1330 }
1331
1334 return;
1335
1336 ConvertConstructorToDeductionGuideTransform Transform(
1337 *this, cast(Template));
1339 return;
1340
1341 if (hasDeclaredDeductionGuides(Transform.DeductionGuideName, DC))
1342 return;
1343
1344
1345
1347
1348
1350 *this, Loc, Template,
1352 if (BuildingDeductionGuides.isInvalid())
1353 return;
1354
1355
1356
1357
1358
1360 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
1363 bool AddedAny = false;
1365 D = D->getUnderlyingDecl();
1367 continue;
1368
1370
1371
1372
1373
1374 if (ProcessedCtors.count(D))
1375 continue;
1376
1377 auto *FTD = dyn_cast(D);
1378 auto *CD =
1379 dyn_cast_or_null(FTD ? FTD->getTemplatedDecl() : D);
1380
1381
1383 continue;
1384
1385
1387 return !P || P->hasUnparsedDefaultArg();
1388 }))
1389 continue;
1390
1391 ProcessedCtors.insert(D);
1392 Transform.transformConstructor(FTD, CD);
1393 AddedAny = true;
1394 }
1395
1396
1397
1398
1399
1400 if (!AddedAny)
1401 Transform.buildSimpleDeductionGuide({});
1402
1403
1404
1405 cast(
1406 cast(
1407 Transform.buildSimpleDeductionGuide(Transform.DeducedType))
1408 ->getTemplatedDecl())
1410
1411 SavedContext.pop();
1412}
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
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
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
QualType getDeducedTemplateSpecializationType(TemplateName Template, QualType DeducedType, bool IsDependent) const
C++17 deduced class template specialization type.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const
QualType getLogicalOperationType() const
The result type of logical operations, '<', '>', '!=', etc.
QualType getTypedefType(const TypedefNameDecl *Decl, QualType Underlying=QualType()) const
Return the unique reference to the type for the specified typedef-name decl.
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, Expr *TrailingRequiresClause=nullptr)
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
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
A reference to a declared variable, function, enum, etc.
NamedDecl * getFoundDecl()
Get the NamedDecl through which this reference occurred.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
unsigned getTemplateDepth() const
Determine the number of levels of template parameter surrounding this declaration.
bool isInvalidDecl() const
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).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
The name of a declaration.
SourceLocation getInnerLocStart() const
Return start of source range ignoring outer template declarations.
SourceLocation getBeginLoc() const LLVM_READONLY
TypeSourceInfo * getTypeSourceInfo() const
Common base class for placeholders for types that get replaced by placeholder type deduction: C++11 a...
Recursive AST visitor that supports extension via dynamic dispatch.
virtual bool TraverseTemplateName(TemplateName Template)
Recursively visit a template name and dispatch to the appropriate method.
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
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
Represents a prototype with parameter type info, e.g.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
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
The injected class name of a C++ class template or class template partial specialization.
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)
unsigned getNumSubstitutedLevels() const
Determine the number of substituted levels in this template argument list.
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.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
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...
QualType BuildFunctionType(QualType T, MutableArrayRef< QualType > ParamTypes, SourceLocation Loc, DeclarationName Entity, const FunctionProtoType::ExtProtoInfo &EPI)
Build a function type.
ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
TypeSourceInfo * CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, std::optional< unsigned > NumExpansions)
Construct a pack expansion type from the pattern of the pack expansion.
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.
TemplateParameterList * GetTemplateParameterList(TemplateDecl *TD)
Returns the template parameter list with all default template argument information.
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={})
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef< TemplateArgument > TemplateArgs, sema::TemplateDeductionInfo &Info)
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class)
Look up the constructors for the given class.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
A convenient class for passing around template argument information.
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.
The base class of all kinds of template declarations (e.g., class, function, etc.).
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
Represents a type template specialization; the template must be a class template, a type alias templa...
ArrayRef< TemplateArgument > template_arguments() const
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
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).
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, std::optional< unsigned > NumExpanded=std::nullopt)
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool isExpandedParameterPack() const
Whether this parameter is a template type parameter pack that has a known list of different type-cons...
bool isParameterPack() const
Returns whether this is a parameter pack.
unsigned getNumExpansionParameters() const
Retrieves the number of parameters in an expanded parameter pack.
unsigned getIndex() const
unsigned getDepth() const
A semantic tree transformation that allows one to transform one abstract syntax tree into another.
QualType RebuildTemplateSpecializationType(TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &Args)
Build a new template specialization type.
QualType TransformType(QualType T)
Transforms the given type into another type.
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.
TypeSpecTypeLoc pushTypeSpec(QualType T)
Pushes space for a typespec TypeLoc.
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.
SourceLocation getNameLoc() const
void setNameLoc(SourceLocation Loc)
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.
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'.
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
Wrapper for source info for typedefs.
TypedefNameDecl * getTypedefNameDecl() 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...
The JSON file list parser is used to communicate input to InstallAPI.
@ Rewrite
We are substituting template parameters for (typically) other template parameters in order to rewrite...
std::pair< unsigned, unsigned > getDepthAndIndex(const NamedDecl *ND)
Retrieve the depth and index of a template parameter.
@ 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.
const FunctionProtoType * T
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
Extra information about a function prototype.
unsigned HasTrailingReturn
@ BuildingDeductionGuides
We are building deduction guides for a class.
A stack object to be created when performing template instantiation.