clang: lib/Sema/SemaTemplateDeduction.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
46#include "llvm/ADT/APInt.h"
47#include "llvm/ADT/APSInt.h"
48#include "llvm/ADT/ArrayRef.h"
49#include "llvm/ADT/DenseMap.h"
50#include "llvm/ADT/FoldingSet.h"
51#include "llvm/ADT/SmallBitVector.h"
52#include "llvm/ADT/SmallPtrSet.h"
53#include "llvm/ADT/SmallVector.h"
54#include "llvm/Support/Casting.h"
55#include "llvm/Support/Compiler.h"
56#include "llvm/Support/ErrorHandling.h"
57#include "llvm/Support/SaveAndRestore.h"
58#include
59#include
60#include
61#include
62#include <type_traits>
63#include
64
66
67
68
69
71
72
73
75
76
77
78
80
81
82
84
85
86
87
89
90
91
92
94
95
96
98
99
100
101
102
103
104
105
107
108
109
110
112 };
113}
114
115using namespace clang;
116using namespace sema;
117
118
119
121
127 bool *HasDeducedAnyParam);
128
129
131
140
143 bool OnlyDeduced, unsigned Depth,
144 llvm::SmallBitVector &Used);
145
147 bool OnlyDeduced, unsigned Level,
148 llvm::SmallBitVector &Deduced);
149
151
152
153 while (true) {
154 if (const auto *IC = dyn_cast(E))
155 E = IC->getSubExpr();
156 else if (const auto *CE = dyn_cast(E))
157 E = CE->getSubExpr();
158 else if (const auto *Subst = dyn_cast(E))
159 E = Subst->getReplacement();
160 else if (const auto *CCE = dyn_cast(E)) {
161
162 if (CCE->getParenOrBraceRange().isValid())
163 break;
164
165 assert(CCE->getNumArgs() >= 1 && "implicit construct expr should have 1 arg");
166 E = CCE->getArg(0);
167 } else
168 break;
169 }
170 return E;
171}
172
174public:
184
186 if (const auto *NTTP = dyn_cast(Template))
187 return NTTP->getType();
191 }
192
194 if (const auto *NTTP = dyn_cast(Template))
195 return NTTP->getDepth();
197 }
198
200 if (const auto *NTTP = dyn_cast(Template))
201 return NTTP->getIndex();
203 }
204
208
212
214 if (const auto *NTTP = dyn_cast(Template))
217 }
218
220 if (const auto *NTTP = dyn_cast(Template))
221 return NTTP->isExpandedParameterPack();
223 }
224
226 if (const auto *NTTP = dyn_cast(Template))
227 return NTTP->getLocation();
229 }
230
231 operator bool() const { return Template; }
232
233private:
235};
236
237
238
239
242
243
245 if (const auto *DRE = dyn_cast(E))
246 if (const auto *NTTP = dyn_cast(DRE->getDecl()))
247 if (NTTP->getDepth() == Depth)
248 return NTTP;
249
250 if (const auto *ULE = dyn_cast(E);
251 ULE && (ULE->isConceptReference() || ULE->isVarDeclReference())) {
252 if (auto *TTP = ULE->getTemplateTemplateDecl()) {
253
254 if (TTP->getDepth() == Depth)
255 return TTP;
256 }
257 }
258 return nullptr;
259}
260
265
266
267
269 if (NamedDecl *NX = dyn_cast(X))
270 X = NX->getUnderlyingDecl();
271 if (NamedDecl *NY = dyn_cast(Y))
272 Y = NY->getUnderlyingDecl();
273
275}
276
277
278
279
280
285 bool AggregateCandidateDeduction = false) {
286
287 if (X.isNull())
288 return Y;
290 return X;
291
292
293
294
295
296
298 QualType XType = X.getNonTypeTemplateArgumentType();
299 if (!XType.isNull()) {
301 if (YType.isNull() || !Context.hasSameType(XType, YType))
303 }
304 }
305
306 switch (X.getKind()) {
308 llvm_unreachable("Non-deduced template arguments handled above");
309
311
315 X.wasDeducedFromArrayBound() ||
317
318
319
321 return X.wasDeducedFromArrayBound() ? Y : X;
322
323
325 }
326
328
329
330
334 llvm::APSInt::isSameValue(X.getAsIntegral(), Y.getAsIntegral())))
335 return X.wasDeducedFromArrayBound() ? Y : X;
336
337
339
341
344 X.structurallyEquals(Y)))
345 return X;
346
347
349
352 Context.hasSameTemplateName(X.getAsTemplate(), Y.getAsTemplate()))
353 return X;
354
355
357
360 Context.hasSameTemplateName(X.getAsTemplateOrTemplatePattern(),
362 return X;
363
364
366
370
371
372 llvm::FoldingSetNodeID ID1, ID2;
373 X.getAsExpr()->Profile(ID1, Context, true);
375 if (ID1 == ID2)
376 return X.wasDeducedFromArrayBound() ? Y : X;
377
378
380 }
381
383 assert(.wasDeducedFromArrayBound());
384
385
386
388 return X;
389
390
391
392
396 X.getParamTypeForDecl());
397 return Y;
398 }
399
400
401
404 return X;
405
406
408
410
411
415 true);
416
417
418
420 return Y;
421
422
425 Context.getCommonSugaredType(X.getNullPtrType(), Y.getNullPtrType()),
426 true);
427
428
430
433 (!AggregateCandidateDeduction && X.pack_size() != Y.pack_size()))
435
438 XA = X.pack_begin(),
440 XA != XAEnd; ++XA) {
441 if (YA != YAEnd) {
445 if (Merged.isNull() && !(XA->isNull() && YA->isNull()))
447 NewPack.push_back(Merged);
448 ++YA;
449 } else {
450 NewPack.push_back(*XA);
451 }
452 }
453
457 }
458 }
459
460 llvm_unreachable("Invalid TemplateArgument Kind!");
461}
462
463
464
465
473 bool *HasDeducedAnyParam) {
475 "deducing non-type template argument with wrong depth");
476
479 if (Result.isNull()) {
484 }
485 Deduced[NTTP.getIndex()] = Result;
488
490
491
492
493
495
496
497
499 if (auto *Expansion = dyn_cast(ParamType))
500 ParamType = Expansion->getPattern();
501
502
503
504
505
506 if (ParamType->isReferenceType() && !ValueType->isReferenceType()) {
509 else
511 }
512
514 S, TemplateParams, ParamType, ValueType, Info, Deduced,
519}
520
521
522
528 bool *HasDeducedAnyParam) {
530 S, TemplateParams, NTTP,
532 DeducedFromArrayBound),
533 ValueType, Info, PartialOrdering, Deduced, HasDeducedAnyParam);
534}
535
536
537
544 bool *HasDeducedAnyParam) {
548 NullPtrType,
550 : CK_NullToPointer)
555}
556
557
558
559
560
566 bool *HasDeducedAnyParam) {
570}
571
572
573
574
575
582 bool *HasDeducedAnyParam) {
587}
588
594 bool *HasDeducedAnyParam) {
595 TemplateDecl *ParamDecl = Param.getAsTemplateDecl();
596 if (!ParamDecl) {
597
598
600 }
601
602 if (auto *TempParam = dyn_cast(ParamDecl)) {
603
606
609 unsigned StartPos = 0;
610 for (unsigned I = 0, E = std::min(Params.size(), DefaultArguments.size());
611 I < E; ++I) {
614 break;
615 }
616 StartPos = I + 1;
617 }
618
619
620
621
622
626 Arg, {StartPos, DefaultArguments.drop_front(StartPos)}))
627 : Arg;
628
630 S.Context, Deduced[TempParam->getIndex()], NewDeduced);
631 if (Result.isNull()) {
632 Info.Param = TempParam;
633 Info.FirstArg = Deduced[TempParam->getIndex()];
636 }
637
638 Deduced[TempParam->getIndex()] = Result;
639 if (HasDeducedAnyParam)
640 *HasDeducedAnyParam = true;
642 }
643
644
648
649
653}
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
675 const TemplateSpecializationType *LastTST = nullptr;
677 const TemplateSpecializationType *TST =
678 T->getAs();
679 if (!TST)
680 return LastTST;
681 if (!TST->isSugared())
682 return TST;
683 LastTST = TST;
684 T = TST->desugar().getTypePtr();
685 }
686}
687
693 bool *HasDeducedAnyParam) {
698 TNP = TP->getTemplateName();
699
700
703
704
705
706 PResolved =
707 TP->castAsCanonical()->template_arguments();
708 } else {
709 const auto *TT = P->castAs();
710 TNP = TT->getTemplateName(S.Context);
711 PResolved = TT->getTemplateArgs(S.Context);
712 }
713
714
717
720
721
725
726
729
730
731
733 SA->getCanonicalTypeInternal()
734 ->castAs()
735 ->template_arguments();
736
737
739 AResolved,
741 HasDeducedAnyParam);
743 return Result;
744
745
746
747
749 S, TemplateParams, PResolved, AResolved, Info, Deduced,
752 }
753
754
755
756
757 const auto *TA = A->getAs();
759 if (TA) {
760
761
763 TNA = TST->getTemplateName();
764 else
765 TNA = TA->getTemplateName(S.Context);
766 }
767 if (TNA.isNull()) {
771 }
772
774
775 if (auto Result =
777 AResolved,
780 return Result;
781
782
784 S, TemplateParams, PResolved, AResolved, Info, Deduced,
787}
788
790 assert(T->isCanonicalUnqualified());
791
792 switch (T->getTypeClass()) {
793 case Type::TypeOfExpr:
794 case Type::TypeOf:
795 case Type::DependentName:
796 case Type::Decltype:
797 case Type::PackIndexing:
798 case Type::UnresolvedUsing:
799 case Type::TemplateTypeParm:
800 case Type::Auto:
801 return true;
802
803 case Type::ConstantArray:
804 case Type::IncompleteArray:
805 case Type::VariableArray:
806 case Type::DependentSizedArray:
809
810 default:
811 return false;
812 }
813}
814
815
816
819 T->getCanonicalTypeInternal().getTypePtr());
820}
821
822
823
832
833
835
837
838
840
841
842
844
845
847
848
850
852};
853
854namespace {
855
856
857class PackDeductionScope {
858public:
859
860
861
865 bool DeducePackIfNotAlreadyDeduced = false,
866 bool FinishingDeduction = false)
867 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info),
868 DeducePackIfNotAlreadyDeduced(DeducePackIfNotAlreadyDeduced),
869 FinishingDeduction(FinishingDeduction) {
870 unsigned NumNamedPacks = addPacks(Pattern);
871 finishConstruction(NumNamedPacks);
872 }
873
874
875 PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams,
876 SmallVectorImpl &Deduced,
877 TemplateDeductionInfo &Info, unsigned Index)
878 : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
879 addPack(Index);
880 finishConstruction(1);
881 }
882
883private:
884 void addPack(unsigned Index) {
885
886
887 DeducedFromEarlierParameter = !Deduced[Index].isNull();
888 DeducedPack Pack(Index);
889 if (!FinishingDeduction) {
890 Pack.Saved = Deduced[Index];
891 Deduced[Index] = TemplateArgument();
892 }
893
894
895
896
897 if (UnsignedOrNone ExpandedPackExpansions =
899 FixedNumExpansions = ExpandedPackExpansions;
900
901 Packs.push_back(Pack);
902 }
903
904 unsigned addPacks(TemplateArgument Pattern) {
905
906
907 llvm::SmallBitVector SawIndices(TemplateParams->size());
908 llvm::SmallVector<TemplateArgument, 4> ExtraDeductions;
909
910 auto AddPack = [&](unsigned Index) {
911 if (SawIndices[Index])
912 return;
913 SawIndices[Index] = true;
914 addPack(Index);
915
916
917
918
919
920 if (auto *NTTP = dyn_cast(
921 TemplateParams->getParam(Index))) {
922 if (!NTTP->isExpandedParameterPack())
923
924
925 if (auto *Expansion = dyn_cast(
926 S.Context.getUnconstrainedType(NTTP->getType())))
927 ExtraDeductions.push_back(Expansion->getPattern());
928 }
929
930
931 };
932
933 auto Collect = [&](TemplateArgument Pattern) {
934 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
935 S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
936 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
937 unsigned Depth, Index;
939 std::tie(Depth, Index) = *DI;
940 else
941 continue;
942
943 if (Depth == Info.getDeducedDepth())
944 AddPack(Index);
945 }
946 };
947
948
949 Collect(Pattern);
950
951 unsigned NumNamedPacks = Packs.size();
952
953
954
955 while (!ExtraDeductions.empty())
956 Collect(ExtraDeductions.pop_back_val());
957
958 return NumNamedPacks;
959 }
960
961 void finishConstruction(unsigned NumNamedPacks) {
962
963 const TemplateArgument *PartialPackArgs = nullptr;
964 unsigned NumPartialPackArgs = 0;
965 std::pair<unsigned, unsigned> PartialPackDepthIndex(-1u, -1u);
966 if (auto *Scope = S.CurrentInstantiationScope)
967 if (auto *Partial = Scope->getPartiallySubstitutedPack(
968 &PartialPackArgs, &NumPartialPackArgs))
970
971
972
973
974 bool IsExpanded = true;
975 for (unsigned I = 0; I != NumNamedPacks; ++I) {
976 if (Packs[I].Index >= Info.getNumExplicitArgs()) {
977 IsExpanded = false;
978 IsPartiallyExpanded = false;
979 break;
980 }
981 if (PartialPackDepthIndex ==
982 std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) {
983 IsPartiallyExpanded = true;
984 }
985 }
986
987
988
989
990
991 if (IsPartiallyExpanded)
992 PackElements += NumPartialPackArgs;
993 else if (IsExpanded && FixedNumExpansions)
994 PackElements += *FixedNumExpansions;
995
996 for (auto &Pack : Packs) {
997 if (Info.PendingDeducedPacks.size() > Pack.Index)
998 Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
999 else
1000 Info.PendingDeducedPacks.resize(Pack.Index + 1);
1001 Info.PendingDeducedPacks[Pack.Index] = &Pack;
1002
1003 if (PartialPackDepthIndex ==
1004 std::make_pair(Info.getDeducedDepth(), Pack.Index)) {
1005 Pack.New.append(PartialPackArgs, PartialPackArgs + NumPartialPackArgs);
1006
1007
1008
1009
1010
1011
1012
1013
1014 if (!FinishingDeduction && !IsPartiallyExpanded)
1015 Deduced[Pack.Index] = Pack.New[PackElements];
1016 }
1017 }
1018 }
1019
1020public:
1021 ~PackDeductionScope() {
1022 for (auto &Pack : Packs)
1023 Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
1024 }
1025
1026
1027 UnsignedOrNone getSavedPackSizeIfAllEqual() const {
1028 unsigned PackSize = Packs[0].Saved.pack_size();
1029
1030 if (std::all_of(Packs.begin() + 1, Packs.end(), [&PackSize](const auto &P) {
1031 return P.Saved.pack_size() == PackSize;
1032 }))
1033 return PackSize;
1034 return std::nullopt;
1035 }
1036
1037
1038
1039 bool isDeducedFromEarlierParameter() const {
1040 return DeducedFromEarlierParameter;
1041 }
1042
1043
1044
1045 bool isPartiallyExpanded() { return IsPartiallyExpanded; }
1046
1047
1048
1049
1050 bool hasFixedArity() { return static_cast<bool>(FixedNumExpansions); }
1051
1052
1053
1054
1055 bool hasNextElement() {
1056 return !FixedNumExpansions || *FixedNumExpansions > PackElements;
1057 }
1058
1059
1060 void nextPackElement() {
1061
1062
1063
1064 if (!FinishingDeduction) {
1065 for (auto &Pack : Packs) {
1066 DeducedTemplateArgument &DeducedArg = Deduced[Pack.Index];
1067 if (!Pack.New.empty() || !DeducedArg.isNull()) {
1068 while (Pack.New.size() < PackElements)
1069 Pack.New.push_back(DeducedTemplateArgument());
1070 if (Pack.New.size() == PackElements)
1071 Pack.New.push_back(DeducedArg);
1072 else
1073 Pack.New[PackElements] = DeducedArg;
1074 DeducedArg = Pack.New.size() > PackElements + 1
1075 ? Pack.New[PackElements + 1]
1076 : DeducedTemplateArgument();
1077 }
1078 }
1079 }
1080 ++PackElements;
1081 }
1082
1083
1084
1085
1087 if (FinishingDeduction)
1088 return TemplateDeductionResult::Success;
1089
1090
1091 for (auto &Pack : Packs) {
1092
1093 if (!FinishingDeduction)
1094 Deduced[Pack.Index] = Pack.Saved;
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109 Pack.New.resize(PackElements);
1110
1111
1112 DeducedTemplateArgument NewPack;
1113 if (Pack.New.empty()) {
1114
1116 } else {
1117 TemplateArgument *ArgumentPack =
1118 new (S.Context) TemplateArgument[Pack.New.size()];
1119 std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
1120 NewPack = DeducedTemplateArgument(
1121 TemplateArgument(llvm::ArrayRef(ArgumentPack, Pack.New.size())),
1122
1123
1124
1125
1126
1127 Pack.New[0].wasDeducedFromArrayBound());
1128 }
1129
1130
1131 DeducedTemplateArgument *Loc;
1132 if (Pack.Outer) {
1133 if (Pack.Outer->DeferredDeduction.isNull()) {
1134
1135
1136 Pack.Outer->DeferredDeduction = NewPack;
1137 continue;
1138 }
1139 Loc = &Pack.Outer->DeferredDeduction;
1140 } else {
1141 Loc = &Deduced[Pack.Index];
1142 }
1143
1144
1145 DeducedTemplateArgument OldPack = *Loc;
1147 S.Context, OldPack, NewPack, DeducePackIfNotAlreadyDeduced);
1148
1149 Info.AggregateDeductionCandidateHasMismatchedArity =
1153
1154
1155 if (.isNull() && !Pack.DeferredDeduction.isNull()) {
1157 NewPack = Pack.DeferredDeduction;
1159 }
1160
1161 NamedDecl *Param = TemplateParams->getParam(Pack.Index);
1162 if (Result.isNull()) {
1164 Info.FirstArg = OldPack;
1165 Info.SecondArg = NewPack;
1166 return TemplateDeductionResult::Inconsistent;
1167 }
1168
1169
1170
1172 if (*Expansions != PackElements) {
1174 Info.FirstArg = Result;
1175 return TemplateDeductionResult::IncompletePack;
1176 }
1177 }
1178
1180 }
1181
1182 return TemplateDeductionResult::Success;
1183 }
1184
1185private:
1186 Sema &S;
1187 TemplateParameterList *TemplateParams;
1188 SmallVectorImpl &Deduced;
1189 TemplateDeductionInfo &Info;
1190 unsigned PackElements = 0;
1191 bool IsPartiallyExpanded = false;
1192 bool DeducePackIfNotAlreadyDeduced = false;
1193 bool DeducedFromEarlierParameter = false;
1194 bool FinishingDeduction = false;
1195
1196 UnsignedOrNone FixedNumExpansions = std::nullopt;
1197
1198 SmallVector<DeducedPack, 2> Packs;
1199};
1200
1201}
1202
1203template
1208 bool FinishingDeduction, T &&DeductFunc) {
1209
1210
1211
1212
1213
1214 unsigned ArgIdx = 0, ParamIdx = 0;
1216
1217 const PackExpansionType *Expansion
1218 = dyn_cast(Params[ParamIdx]);
1219 if (!Expansion) {
1220
1221
1222
1223 if (ArgIdx >= Args.size())
1225
1227
1228
1229
1230
1232 }
1233
1235 DeductFunc(S, TemplateParams, ParamIdx, ArgIdx,
1236 Params[ParamIdx].getUnqualifiedType(),
1237 Args[ArgIdx].getUnqualifiedType(), Info, Deduced, POK);
1239 return Result;
1240
1241 ++ArgIdx;
1242 continue;
1243 }
1244
1245
1246
1247
1248
1249
1250
1251
1252 QualType Pattern = Expansion->getPattern();
1253 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern,
1254 false,
1255 FinishingDeduction);
1256
1257
1258
1259 if (ParamIdx + 1 == Params.size() || PackScope.hasFixedArity()) {
1260 for (; ArgIdx < Args.size() && PackScope.hasNextElement(); ++ArgIdx) {
1261
1263 S, TemplateParams, ParamIdx, ArgIdx,
1265 Info, Deduced, POK);
1267 return Result;
1268 PackScope.nextPackElement();
1269 }
1270 } else {
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288 UnsignedOrNone NumExpansions = Expansion->getNumExpansions();
1289 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
1290 for (unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
1291 ++I, ++ArgIdx)
1292 PackScope.nextPackElement();
1293 }
1294 }
1295
1296
1297
1298 if (auto Result = PackScope.finish();
1300 return Result;
1301 }
1302
1303
1304
1305
1306
1307
1308
1312
1313
1314 if (ArgIdx < Args.size())
1316
1318}
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1357 llvm::SmallBitVector *HasDeducedParam) {
1358 return ::DeduceForEachType(
1359 S, TemplateParams, Params, Args, Info, Deduced, POK,
1360 false,
1365 bool HasDeducedAnyParamCopy = false;
1367 S, TemplateParams, P, A, Info, Deduced, TDF, POK,
1368 false, &HasDeducedAnyParamCopy);
1369 if (HasDeducedAnyParam && HasDeducedAnyParamCopy)
1370 *HasDeducedAnyParam = true;
1371 if (HasDeducedParam && HasDeducedAnyParamCopy)
1372 (*HasDeducedParam)[ParamIdx] = true;
1373 return TDR;
1374 });
1375}
1376
1377
1378
1379
1380
1384 Qualifiers ArgQs = ArgType.getQualifiers();
1385
1386 if (ParamQs == ArgQs)
1387 return false;
1388
1389
1392 return true;
1393
1394
1397 return true;
1398
1399
1402 return true;
1403
1404
1406}
1407
1411
1412
1413 if (!PF || !AF)
1414 return Context.hasSameType(P, A);
1415
1416
1418 P = AdjustedParam;
1419
1420
1421 return Context.hasSameFunctionTypeIgnoringExceptionSpec(P, A);
1422}
1423
1424
1425
1426
1427
1429 auto *Guide = dyn_cast(FTD->getTemplatedDecl());
1430 if (!Guide || !Guide->isImplicit())
1431 return 0;
1432 return Guide->getDeducedTemplate()->getTemplateParameters()->size();
1433}
1434
1435
1437
1438
1439
1440
1442 if (ParamRef->getPointeeType().getQualifiers())
1443 return false;
1444 auto *TypeParm =
1445 ParamRef->getPointeeType()->getAsCanonical();
1446 return TypeParm && TypeParm->getIndex() >= FirstInnerIndex;
1447 }
1448 return false;
1449}
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1474 bool *HasDeducedAnyParam) {
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1496
1497
1498 struct MatchValue {
1500 bool HasDeducedAnyParam;
1501 };
1502 llvm::MapVector<const CXXRecordDecl *, MatchValue> Matches;
1503
1504 auto AddBases = [&Visited, &ToVisit](const CXXRecordDecl *RD) {
1505 for (const auto &Base : RD->bases()) {
1507 assert(T->isRecordType() && "Base class that isn't a record?");
1508 if (Visited.insert(T->getAsCXXRecordDecl()).second)
1509 ToVisit.push_back(T);
1510 }
1511 };
1512
1513
1514 AddBases(RD);
1515
1516
1517
1518 while (!ToVisit.empty()) {
1519 QualType NextT = ToVisit.pop_back_val();
1520
1522 Deduced.end());
1524 bool HasDeducedAnyParamCopy = false;
1526 S, TemplateParams, P, NextT, BaseInfo, PartialOrdering, DeducedCopy,
1527 &HasDeducedAnyParamCopy);
1528
1529
1530
1533 Matches.insert({RD, {DeducedCopy, HasDeducedAnyParamCopy}});
1534 else
1535 AddBases(RD);
1536 }
1537
1538
1539
1540
1541
1542
1543
1544 if (Matches.size() > 1) {
1545 Visited.clear();
1546 for (const auto &Match : Matches)
1547 AddBases(Match.first);
1548
1549
1550
1551 while (Matches.size() > 1 && !ToVisit.empty()) {
1552 const CXXRecordDecl *RD = ToVisit.pop_back_val()->getAsCXXRecordDecl();
1553 Matches.erase(RD);
1554
1555
1556
1557 AddBases(RD);
1558 }
1559 }
1560
1561 if (Matches.empty())
1563 if (Matches.size() > 1)
1565
1566 std::swap(Matches.front().second.Deduced, Deduced);
1567 if (bool HasDeducedAnyParamCopy = Matches.front().second.HasDeducedAnyParam;
1568 HasDeducedAnyParamCopy && HasDeducedAnyParam)
1569 *HasDeducedAnyParam = HasDeducedAnyParamCopy;
1571}
1572
1573
1574
1575
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1610 bool *HasDeducedAnyParam) {
1611
1612
1613
1614 if (const auto *AExp = dyn_cast(A))
1615 A = AExp->getPattern();
1617
1619
1620
1621
1622
1624 if (PRef)
1626
1627
1629 if (ARef)
1631
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1661 }
1662 }
1664
1665
1666
1667
1669
1670
1672 } else {
1673
1674
1675
1676
1682 }
1683
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1700 }
1701 }
1702
1703
1704
1705
1706
1707
1708
1709
1710 if (const auto *TTP = P->getAsCanonical()) {
1711
1712
1715
1716 unsigned Index = TTP->getIndex();
1717
1718
1719
1723 if (Quals)
1725 }
1726
1727
1728
1735 }
1736
1737
1738
1741
1743 "saw template type parameter with wrong depth");
1745 "Unresolved overloaded function");
1747
1748
1749
1759
1760
1761
1762
1769 }
1770
1771
1772
1773
1777
1778 DeducedType =
1780
1784 if (Result.isNull()) {
1785
1788 case Decl::TemplateTypeParm:
1790 break;
1791 case Decl::NonTypeTemplateParm:
1793 break;
1794 case Decl::TemplateTemplateParm:
1796 break;
1797 default:
1798 llvm_unreachable("unexpected kind");
1799 }
1800 Info.FirstArg = Deduced[Index];
1803 }
1804
1805 Deduced[Index] = Result;
1806 if (HasDeducedAnyParam)
1807 *HasDeducedAnyParam = true;
1809 }
1810
1811
1814
1815
1816
1817
1818
1819 if (P->getAs())
1821
1822
1828
1829
1830
1834
1835
1836
1843 }
1844 }
1845
1846
1858
1859
1860
1861 }
1862
1864
1865#define NON_CANONICAL_TYPE(Class, Base) \
1866 case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class);
1867#define TYPE(Class, Base)
1868#include "clang/AST/TypeNodes.inc"
1869
1870 case Type::TemplateTypeParm:
1871 case Type::SubstTemplateTypeParmPack:
1872 case Type::SubstBuiltinTemplatePack:
1873 llvm_unreachable("Type nodes handled above");
1874
1875 case Type::Auto:
1876
1877
1878
1879
1880
1883 [[fallthrough]];
1884 case Type::Builtin:
1885 case Type::VariableArray:
1886 case Type::Vector:
1887 case Type::FunctionNoProto:
1888 case Type::Record:
1889 case Type::Enum:
1890 case Type::ObjCObject:
1891 case Type::ObjCInterface:
1892 case Type::ObjCObjectPointer:
1893 case Type::BitInt:
1900
1901
1902 case Type::Complex: {
1904 if (!CA)
1907 S, TemplateParams, CP->getElementType(), CA->getElementType(), Info,
1909 false, HasDeducedAnyParam);
1910 }
1911
1912
1913 case Type::Atomic: {
1915 if (!AA)
1918 S, TemplateParams, PA->getValueType(), AA->getValueType(), Info,
1920 false, HasDeducedAnyParam);
1921 }
1922
1923
1924 case Type::Pointer: {
1930 } else {
1932 }
1935 PointeeType, Info, Deduced,
1938 false, HasDeducedAnyParam);
1939 }
1940
1941
1942 case Type::LValueReference: {
1945 if (!RA)
1947
1949 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1951 false, HasDeducedAnyParam);
1952 }
1953
1954
1955 case Type::RValueReference: {
1958 if (!RA)
1960
1962 S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info,
1964 false, HasDeducedAnyParam);
1965 }
1966
1967
1968 case Type::IncompleteArray: {
1970 if (!IAA)
1972
1974 assert(IAP && "Template parameter not of incomplete array type");
1975
1977 S, TemplateParams, IAP->getElementType(), IAA->getElementType(), Info,
1980 false, HasDeducedAnyParam);
1981 }
1982
1983
1984 case Type::ConstantArray: {
1987 assert(CAP);
1988 if (!CAA || CAA->getSize() != CAP->getSize())
1990
1992 S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info,
1995 false, HasDeducedAnyParam);
1996 }
1997
1998
1999 case Type::DependentSizedArray: {
2001 if (!AA)
2003
2004
2006 assert(DAP);
2008 S, TemplateParams, DAP->getElementType(), AA->getElementType(),
2011 false, HasDeducedAnyParam);
2013 return Result;
2014
2015
2018 if (!NTTP)
2020
2021
2022
2024 "saw non-type template parameter with wrong depth");
2025 if (const auto *CAA = dyn_cast(AA)) {
2026 llvm::APSInt Size(CAA->getSize());
2030 Deduced, HasDeducedAnyParam);
2031 }
2032 if (const auto *DAA = dyn_cast(AA))
2033 if (DAA->getSizeExpr())
2035 S, TemplateParams, NTTP, DAA->getSizeExpr(), Info,
2037
2038
2040 }
2041
2042
2043
2044
2045 case Type::FunctionProto: {
2048 if (!FPA)
2050
2051 if (FPP->getMethodQuals() != FPA->getMethodQuals() ||
2052 FPP->getRefQualifier() != FPA->getRefQualifier() ||
2053 FPP->isVariadic() != FPA->isVariadic())
2055
2056
2058 S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(),
2060 false, HasDeducedAnyParam);
2062 return Result;
2063
2064
2066 S, TemplateParams, FPP->param_types(), FPA->param_types(), Info,
2068 HasDeducedAnyParam,
2069 nullptr);
2071 return Result;
2072
2075
2076
2077
2078
2079 Expr *NoexceptExpr = FPP->getNoexceptExpr();
2082 : nullptr) {
2084 "saw non-type template parameter with wrong depth");
2085
2087 switch (FPA->canThrow()) {
2090 [[fallthrough]];
2091
2093
2094
2097 true, Info,
2099
2101 if (Expr *ArgNoexceptExpr = FPA->getNoexceptExpr())
2103 S, TemplateParams, NTTP, ArgNoexceptExpr, Info,
2105
2106 break;
2107 }
2108 }
2109
2110
2111
2112
2113
2115 }
2116
2117 case Type::InjectedClassName:
2118
2119
2120
2121
2122
2123
2124
2125
2126 case Type::TemplateSpecialization: {
2127
2128
2132 Deduced, HasDeducedAnyParam);
2133
2135 Deduced.end());
2136
2139 Deduced, HasDeducedAnyParam);
2141 return Result;
2142
2143
2144
2145
2147 return Result;
2148
2151 return Result;
2152
2153
2154 Deduced = DeducedOrig;
2155
2156
2159 Deduced, HasDeducedAnyParam);
2161 : Result;
2162 }
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173 case Type::MemberPointer: {
2176 if (!MPA)
2178
2182 false, Info.getLocation());
2186 false, Info.getLocation());
2187
2190 S, TemplateParams, PPT, APT, Info, Deduced, SubTDF,
2192 false, HasDeducedAnyParam);
2194 return Result;
2195
2197 MPP->isSugared()
2199 : QualType(MPP->getQualifier().getAsType(), 0);
2200 assert(!TP.isNull() && "member pointer with non-type class");
2201
2203 MPA->isSugared()
2205 : QualType(MPA->getQualifier().getAsType(), 0)
2207 assert(!TA.isNull() && "member pointer with non-type class");
2208
2210 S, TemplateParams, TP, TA, Info, Deduced, SubTDF,
2212 false, HasDeducedAnyParam);
2213 }
2214
2215
2216
2217
2218
2219
2220 case Type::BlockPointer: {
2223 if (!BPA)
2226 S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info,
2228 false, HasDeducedAnyParam);
2229 }
2230
2231
2232
2233
2234 case Type::ExtVector: {
2238
2239 if (VP->getNumElements() != VA->getNumElements())
2241 ElementType = VA->getElementType();
2243
2244
2245
2246 ElementType = VA->getElementType();
2247 } else {
2249 }
2250
2252 S, TemplateParams, VP->getElementType(), ElementType, Info, Deduced,
2254 false, HasDeducedAnyParam);
2255 }
2256
2257 case Type::DependentVector: {
2259
2261
2263 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2265 false, HasDeducedAnyParam);
2267 return Result;
2268
2269
2272 if (!NTTP)
2274
2276 ArgSize = VA->getNumElements();
2277
2278
2279
2283 HasDeducedAnyParam);
2284 }
2285
2287
2289 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2291 false, HasDeducedAnyParam);
2293 return Result;
2294
2295
2298 if (!NTTP)
2300
2302 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2304 }
2305
2307 }
2308
2309
2310
2311
2312 case Type::DependentSizedExtVector: {
2314
2316
2318 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2320 false, HasDeducedAnyParam);
2322 return Result;
2323
2324
2327 if (!NTTP)
2329
2331 ArgSize = VA->getNumElements();
2332
2333
2334
2336 S, TemplateParams, NTTP, ArgSize, S.Context.IntTy, true, Info,
2338 }
2339
2341
2343 S, TemplateParams, VP->getElementType(), VA->getElementType(),
2345 false, HasDeducedAnyParam);
2347 return Result;
2348
2349
2352 if (!NTTP)
2354
2356 S, TemplateParams, NTTP, VA->getSizeExpr(), Info,
2358 }
2359
2361 }
2362
2363
2364
2365
2366
2367 case Type::ConstantMatrix: {
2370 if (!MA)
2372
2373
2374 if (MP->getNumRows() != MA->getNumRows() ||
2375 MP->getNumColumns() != MA->getNumColumns()) {
2377 }
2378
2380 S, TemplateParams, MP->getElementType(), MA->getElementType(), Info,
2382 false, HasDeducedAnyParam);
2383 }
2384
2385 case Type::DependentSizedMatrix: {
2388 if (!MA)
2390
2391
2393 S, TemplateParams, MP->getElementType(), MA->getElementType(),
2395 false, HasDeducedAnyParam);
2397 return Result;
2398
2399
2400 auto DeduceMatrixArg =
2401 [&S, &Info, &Deduced, &TemplateParams, &HasDeducedAnyParam, POK](
2405 const auto *ACM = dyn_cast(A);
2406 const auto *ADM = dyn_cast(A);
2407 if (!ParamExpr->isValueDependent()) {
2408 std::optionalllvm::APSInt ParamConst =
2409 ParamExpr->getIntegerConstantExpr(S.Context);
2410 if (!ParamConst)
2412
2413 if (ACM) {
2414 if ((ACM->*GetArgDimension)() == *ParamConst)
2417 }
2418
2419 Expr *ArgExpr = (ADM->*GetArgDimensionExpr)();
2420 if (std::optionalllvm::APSInt ArgConst =
2422 if (*ArgConst == *ParamConst)
2425 }
2426
2429 if (!NTTP)
2431
2432 if (ACM) {
2433 llvm::APSInt ArgConst(
2435 ArgConst = (ACM->*GetArgDimension)();
2439 Deduced, HasDeducedAnyParam);
2440 }
2441
2443 S, TemplateParams, NTTP, (ADM->*GetArgDimensionExpr)(), Info,
2445 };
2446
2447 if (auto Result = DeduceMatrixArg(MP->getRowExpr(), MA,
2451 return Result;
2452
2453 return DeduceMatrixArg(MP->getColumnExpr(), MA,
2456 }
2457
2458
2459
2460
2461 case Type::DependentAddressSpace: {
2463
2465
2467 S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(),
2469 false, HasDeducedAnyParam);
2471 return Result;
2472
2473
2476 if (!NTTP)
2478
2480 S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info,
2482 }
2483
2486 false);
2488
2489
2491 S, TemplateParams, ASP->getPointeeType(),
2494 false, HasDeducedAnyParam);
2496 return Result;
2497
2498
2501 if (!NTTP)
2503
2505 S, TemplateParams, NTTP, ArgAddressSpace, S.Context.IntTy, true,
2507 HasDeducedAnyParam);
2508 }
2509
2511 }
2512 case Type::DependentBitInt: {
2514
2516 if (IP->isUnsigned() != IA->isUnsigned())
2518
2521 if (!NTTP)
2523
2525 ArgSize = IA->getNumBits();
2526
2528 S, TemplateParams, NTTP, ArgSize, S.Context.IntTy, true, Info,
2530 }
2531
2533 if (IP->isUnsigned() != IA->isUnsigned())
2536 }
2537
2539 }
2540
2541 case Type::TypeOfExpr:
2542 case Type::TypeOf:
2543 case Type::DependentName:
2544 case Type::UnresolvedUsing:
2545 case Type::Decltype:
2546 case Type::UnaryTransform:
2547 case Type::DeducedTemplateSpecialization:
2548 case Type::PackExpansion:
2549 case Type::Pipe:
2550 case Type::ArrayParameter:
2551 case Type::HLSLAttributedResource:
2552 case Type::HLSLInlineSpirv:
2553
2555
2556 case Type::PackIndexing: {
2557 const PackIndexingType *PIT = P->getAs();
2558 if (PIT->hasSelectedType()) {
2560 S, TemplateParams, PIT->getSelectedType(), A, Info, Deduced, TDF,
2562 false, HasDeducedAnyParam);
2563 }
2565 }
2566 }
2567
2568 llvm_unreachable("Invalid Type Class!");
2569}
2570
2576 bool *HasDeducedAnyParam) {
2577
2578
2579
2582
2585 llvm_unreachable("Null template argument in parameter list");
2586
2593 false, HasDeducedAnyParam);
2597
2599
2600
2604 {}, false, Deduced,
2605 HasDeducedAnyParam);
2609
2611 llvm_unreachable("caller should handle pack expansions");
2612
2617
2621
2623
2629
2634 }
2638
2640
2641
2645
2649
2655
2660 }
2666 HasDeducedAnyParam);
2667
2671 Deduced, HasDeducedAnyParam);
2672
2677
2686 }
2687 llvm_unreachable("Unknown template argument kind");
2688 }
2689
2692 llvm_unreachable("Argument packs should be expanded by the caller!");
2693 }
2694
2695 llvm_unreachable("Invalid TemplateArgument Kind!");
2696}
2697
2698
2699
2700
2701
2702
2703
2704
2705
2707 unsigned &ArgIdx) {
2708 if (ArgIdx == Args.size())
2709 return false;
2710
2713 return true;
2714
2715 assert(ArgIdx == Args.size() - 1 && "Pack not at the end of argument list?");
2717 ArgIdx = 0;
2718 return ArgIdx < Args.size();
2719}
2720
2721
2722
2724 bool FoundPackExpansion = false;
2725 for (const auto &A : Args) {
2726 if (FoundPackExpansion)
2727 return true;
2728
2731
2732
2733
2734 if (A.isPackExpansion())
2735 FoundPackExpansion = true;
2736 }
2737
2738 return false;
2739}
2740
2753
2754
2755
2756
2757
2760
2761
2762
2763
2764
2765 for (unsigned ArgIdx = 0, ParamIdx = 0; ; ) {
2770
2771 if (!Ps[ParamIdx].isPackExpansion()) {
2772
2773
2774
2776 return !FoldPackArgument && NumberOfArgumentsMustMatch
2779
2780 if (As[ArgIdx].isPackExpansion()) {
2781
2782
2783
2784
2785 if (!FoldPackArgument)
2787
2788 TemplateArgument Pattern = As[ArgIdx].getPackExpansionPattern();
2789 for (;;) {
2790
2792 S, TemplateParams, Ps[ParamIdx], Pattern, Info,
2795 return Result;
2796
2800 if (Ps[ParamIdx].isPackExpansion())
2801 break;
2802 }
2803 } else {
2804
2806 S, TemplateParams, Ps[ParamIdx], As[ArgIdx], Info,
2809 return Result;
2810
2811 ++ArgIdx;
2813 continue;
2814 }
2815 }
2816
2817
2818
2819
2820
2821
2822
2823
2825
2826
2827 PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
2828
2829
2830
2831
2833 PackScope.hasNextElement();
2834 ++ArgIdx) {
2835 if (!As[ArgIdx].isPackExpansion()) {
2836 if (!FoldPackParameter)
2838 if (FoldPackArgument)
2840 }
2841
2843 S, TemplateParams, Pattern, As[ArgIdx], Info, PartialOrdering,
2844 Deduced, HasDeducedAnyParam);
2846 return Result;
2847
2848 PackScope.nextPackElement();
2849 }
2850
2851
2852
2853 return PackScope.finish();
2854 }
2855}
2856
2861 bool NumberOfArgumentsMustMatch) {
2862 return ::DeduceTemplateArguments(
2863 *this, TemplateParams, Ps, As, Info, Deduced, NumberOfArgumentsMustMatch,
2865 nullptr);
2866}
2867
2872 switch (Arg.getKind()) {
2874 llvm_unreachable("Can't get a NULL template argument here");
2875
2878 Arg, Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc));
2879
2881 if (NTTPType.isNull())
2887 }
2888
2890 if (NTTPType.isNull())
2895 E);
2896 }
2897
2902 }
2903
2908 Builder.MakeTrivial(Context, Template.getQualifier(), Loc);
2910 Context, Arg, Loc, Builder.getWithLocInContext(Context), Loc,
2912 ? Loc
2914 }
2915
2918
2921 }
2922
2923 llvm_unreachable("Invalid TemplateArgument Kind!");
2924}
2925
2930 Context.getInjectedTemplateArg(TemplateParm), QualType(), Location);
2931}
2932
2933
2934
2935static bool
2941 unsigned ArgumentPackIndex) {
2942
2943
2944
2947
2950
2953 Template->getSourceRange().getEnd(), ArgumentPackIndex, CTAI,
2954 IsDeduced
2960 return Res;
2961 };
2962
2964
2965
2967 CanonicalPackedArgsBuilder;
2969
2970
2971
2975 "deduced nested pack");
2976 if (P.isNull()) {
2977
2978
2979
2980
2981 S.Diag(Param->getLocation(),
2982 diag::err_template_arg_deduced_incomplete_pack)
2983 << Arg << Param;
2984 return true;
2985 }
2986 if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size()))
2987 return true;
2988
2989
2990 SugaredPackedArgsBuilder.push_back(CTAI.SugaredConverted.pop_back_val());
2991 CanonicalPackedArgsBuilder.push_back(
2993 }
2994
2995
2996
2997 if (SugaredPackedArgsBuilder.empty()) {
3000 true);
3002
3003 if (auto *NTTP = dyn_cast(Param)) {
3006 Template->getSourceRange());
3008 S.SubstType(NTTP->getType(), Args, NTTP->getLocation(),
3009 NTTP->getDeclName()).isNull())
3010 return true;
3011 } else if (auto *TTP = dyn_cast(Param)) {
3014 Template->getSourceRange());
3016 return true;
3017 }
3018
3019 }
3020
3021
3025 S.Context, CanonicalPackedArgsBuilder));
3026 return false;
3027 }
3028
3029 return ConvertArg(Arg, 0);
3030}
3031
3032
3033
3034
3035
3041 unsigned NumAlreadyConverted, bool *IsIncomplete) {
3042 for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
3044
3045
3046
3047
3048
3049 if (Deduced[I].isNull() && Param->isTemplateParameterPack()) {
3050 if (auto Result =
3051 PackDeductionScope(S, TemplateParams, Deduced, Info, I).finish();
3053 return Result;
3054 }
3055
3056 if (!Deduced[I].isNull()) {
3057 if (I < NumAlreadyConverted) {
3058
3059
3060
3061 if (Param->isParameterPack() && CurrentInstantiationScope &&
3063
3064
3066
3067
3068 } else {
3069
3070
3071
3075 continue;
3076 }
3077 }
3078
3079
3080
3082 IsDeduced, CTAI)) {
3084
3090 }
3091
3092 continue;
3093 }
3094
3095
3096
3097
3098
3099
3100 if (IsIncomplete) {
3101 *IsIncomplete = true;
3104 continue;
3105 }
3106
3107
3108 bool HasDefaultArg = false;
3110 if (!TD) {
3114 }
3115
3117 {
3120 if (auto *Rec = dyn_cast(TD->getDeclContext()))
3121 if (Rec->isLambda())
3122 if (auto *Method = dyn_cast(Rec->getDeclContext())) {
3123 ThisContext = Method->getParent();
3124 ThisTypeQuals = Method->getMethodQualifiers();
3125 }
3126
3129
3134 }
3135
3136
3142
3145 }
3146
3150
3155
3160 }
3161
3162
3163 }
3164
3166}
3167
3169 if (auto *DC = dyn_cast(D))
3170 return DC;
3172}
3173
3175 static constexpr bool value = false;
3176};
3177template<>
3179 static constexpr bool value = true;
3180};
3181template<>
3183 static constexpr bool value = true;
3184};
3185
3192 bool DeducedArgsNeedReplacement = false;
3193 if (auto *TD = dyn_cast(Template)) {
3194 TD->getAssociatedConstraints(AssociatedConstraints);
3195 DeducedArgsNeedReplacement = !TD->isClassScopeExplicitSpecialization();
3196 } else if (auto *TD =
3197 dyn_cast(Template)) {
3198 TD->getAssociatedConstraints(AssociatedConstraints);
3199 DeducedArgsNeedReplacement = !TD->isClassScopeExplicitSpecialization();
3200 } else {
3202 AssociatedConstraints);
3203 }
3204
3205 std::optional<ArrayRef> Innermost;
3206
3207
3208 if (!DeducedArgsNeedReplacement)
3209 Innermost = SugaredDeducedArgs;
3210
3212 Template, Template->getDeclContext(), false, Innermost,
3213 true,
3214 nullptr, true);
3215
3216
3217
3218
3219
3220 if (!Innermost)
3222
3231 }
3233}
3234
3235
3243
3244
3245
3246
3249 S, Entity, EntityTPL, PartialOrdering, Deduced, Info,
3250 CTAI,
3251 nullptr,
3252 0U, nullptr);
3254 return Result;
3255
3256 if (CopyDeducedArgs) {
3257
3262 Info.reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3263 }
3264
3268 true);
3270
3272 unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx;
3275
3278 Info.FirstArg = Ps[ArgIdx].getArgument();
3280 }
3281
3285 {}, false, InstCTAI,
3286 true,
3291
3292
3294 AsStack{As};
3295 for (;;) {
3298 while (!Stack.empty()) {
3299 auto &Xs = Stack.back();
3300 if (Xs.empty()) {
3301 Stack.pop_back();
3302 continue;
3303 }
3304 auto &X = Xs.front();
3306 Stack.emplace_back(X.getPackAsArray());
3307 Xs = Xs.drop_front();
3308 continue;
3309 }
3310 assert(.isNull());
3311 return {Xs, X};
3312 }
3316 };
3317 auto [Ps, P] = take(PsStack);
3318 auto [As, A] = take(AsStack);
3319 if (P.isNull() && A.isNull())
3320 break;
3322 PA = A.isPackExpansion() ? A.getPackExpansionPattern() : A;
3324 if (!P.isPackExpansion() && !A.isPackExpansion()) {
3326 (AsStack.empty() ? As.end() : AsStack.back().begin()) -
3327 As.begin()));
3331 }
3332 if (P.isPackExpansion()) {
3333 Ps = Ps.drop_front();
3334 continue;
3335 }
3336 if (A.isPackExpansion()) {
3337 As = As.drop_front();
3338 continue;
3339 }
3340 }
3341 Ps = Ps.drop_front(P.isPackExpansion() ? 0 : 1);
3342 As = As.drop_front(A.isPackExpansion() && !P.isPackExpansion() ? 0 : 1);
3343 }
3344 assert(PsStack.empty());
3345 assert(AsStack.empty());
3346
3351 return Result;
3352 }
3353
3355}
3364 for (unsigned I = 0, N = Ps.size(); I != N; ++I)
3369 Info, CopyDeducedArgs);
3370}
3371
3372
3373
3374
3380
3381
3382
3383
3387 Info, CTAI,
3388 nullptr, 0,
3389 nullptr);
3391 return Result;
3392
3393 return ::CheckDeducedArgumentConstraints(S, TD, CTAI.SugaredConverted,
3395}
3396
3397
3398
3399
3400template
3401static std::enable_if_t<IsPartialSpecialization::value,
3406 if (Partial->isInvalidDecl())
3408
3409
3410
3411
3412
3413
3414
3415
3419
3420
3421
3423
3425 Deduced.resize(Partial->getTemplateParameters()->size());
3427 S, Partial->getTemplateParameters(),
3428 Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced,
3429 false, false,
3431 nullptr);
3433 return Result;
3434
3439
3442 Result = ::FinishTemplateArgumentDeduction(
3443 S, Partial, Partial->getTemplateParameters(),
3444 Partial->getSpecializedTemplate(),
3445 false,
3446 Partial->getTemplateArgsAsWritten()->arguments(), TemplateArgs, Deduced,
3447 Info, true);
3448 });
3449
3451 return Result;
3452
3455
3457}
3458
3463 return ::DeduceTemplateArguments(*this, Partial, TemplateArgs, Info);
3464}
3469 return ::DeduceTemplateArguments(*this, Partial, TemplateArgs, Info);
3470}
3471
3477
3479 if (const auto *CTD = dyn_cast(TD)) {
3480
3481 PType = Context.getCanonicalTagType(CTD->getTemplatedDecl());
3482 } else if (const auto *AliasTemplate = dyn_cast(TD)) {
3483 PType = AliasTemplate->getTemplatedDecl()->getUnderlyingType();
3484 } else {
3485 assert(false && "Expected a class or alias template");
3486 }
3487
3488
3492
3493
3494
3496
3504 return DeducedResult;
3505 }
3506
3511
3514 Result = ::FinishTemplateArgumentDeduction(*this, TD, Deduced, Info);
3515 });
3516
3519
3522
3524}
3525
3526
3528 if (const TemplateSpecializationType *Spec
3529 = T->getAs())
3530 return Spec->getTemplateName().getAsTemplateDecl() != nullptr;
3531
3532
3533
3534
3535
3536
3537
3538
3539
3541 return true;
3542
3543 return false;
3544}
3545
3554
3558
3559 if (ExplicitTemplateArgs.size() == 0) {
3560
3561
3562 for (auto *P : Function->parameters())
3563 ParamTypes.push_back(P->getType());
3564
3568 }
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3585
3588 ExplicitTemplateArgs, {},
3589 true, CTAI,
3590 false)) {
3592 if (Index >= TemplateParams->size())
3596 }
3597
3598
3599
3605 CanonicalExplicitArgumentList);
3606
3607
3608
3609
3610
3612
3613
3614
3615
3616
3617 unsigned PartiallySubstitutedPackIndex = -1u;
3622
3623
3625 if (!Expansions || Arg.pack_size() < *Expansions) {
3626 PartiallySubstitutedPackIndex = CTAI.SugaredConverted.size() - 1;
3629 }
3630 }
3631 }
3632
3635 assert(Proto && "Function template does not have a prototype?");
3636
3637
3639
3641
3643 SugaredExplicitArgumentList->asArray(),
3644 true);
3645
3646
3647
3648
3649
3653 nullptr, ExtParamInfos))
3655 }
3656
3657
3659 {
3660
3661
3662
3663
3664
3665
3669 ThisContext = Method->getParent();
3670 ThisTypeQuals = Method->getMethodQualifiers();
3671 }
3672
3673 CXXThisScopeRAII ThisScope(*this, ThisContext, ThisTypeQuals,
3675
3676 ResultType =
3679 if (ResultType.isNull())
3681
3683 if (Function->hasAttr() && !ResultType->isVoidType()) {
3684 Diag(Function->getLocation(), diag::err_kern_type_not_void_return)
3687 }
3688 }
3689
3690
3691
3695 nullptr, ExtParamInfos))
3697
3704 EPI);
3707 }
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719 Deduced.reserve(TemplateParams->size());
3720 for (unsigned I = 0, N = SugaredExplicitArgumentList->size(); I != N; ++I) {
3722 if (I == PartiallySubstitutedPackIndex)
3724 else
3725 Deduced.push_back(Arg);
3726 }
3727
3729}
3730
3731
3732
3738
3746 };
3747
3750
3751
3752 if (Context.hasSameUnqualifiedType(A, DeducedA))
3754
3755
3756
3761
3762
3763
3764
3765
3766
3769
3770 OriginalParamType = OriginalParamRef->getPointeeType();
3771
3772
3773
3774
3777
3780
3781
3782
3783
3784
3788 (DeducedAQuals.hasConst() &&
3791 }
3792
3793 if (AQuals == DeducedAQuals) {
3794
3796 return Failed();
3797 } else {
3798
3799
3800
3801 A = Context.getQualifiedType(A.getUnqualifiedType(), DeducedAQuals);
3802 }
3803 }
3804
3805
3806
3807
3808
3809
3810
3811 bool ObjCLifetimeConversion = false;
3814 ObjCLifetimeConversion) ||
3817
3818
3819
3820
3821
3822
3828 OriginalParamType = OriginalParamPtr->getPointeeType();
3831 }
3832 }
3833 }
3834 }
3835
3836 if (Context.hasSameUnqualifiedType(A, DeducedA))
3838
3842
3843 return Failed();
3844}
3845
3846
3847
3848
3849
3850
3851
3852
3853
3858 unsigned Idx = 0;
3859 for (auto *PD : FunctionTemplate->getTemplatedDecl()->parameters()) {
3860 if (PD->isParameterPack()) {
3863 unsigned NumExpansions = NumArgs ? *NumArgs : 1;
3864 if (Idx + NumExpansions > ParamIdx)
3866 Idx += NumExpansions;
3867 } else {
3869 return std::nullopt;
3870 ++Idx;
3871 }
3872 }
3873
3874 llvm_unreachable("parameter index would not be produced from template");
3875}
3876
3877
3878
3879
3885 auto GetExplicitSpecifier = [](FunctionDecl *D) {
3889 };
3894 };
3895
3898 if (!ExplicitExpr)
3902
3903
3904
3905
3917 }
3918 SetExplicitSpecifier(Specialization, InstantiatedES);
3920}
3921
3929 bool ForOverloadSetAddressResolution,
3930 llvm::function_ref<bool(bool)> CheckNonDependent) {
3931
3932
3939
3941
3942
3943
3944
3945 bool IsIncomplete = false;
3950 NumExplicitlySpecified, PartialOverloading ? &IsIncomplete : nullptr);
3953
3954
3959 Info.reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
3960
3961
3962
3967
3968 if (CheckNonDependent(true))
3970
3971
3972
3973
3974
3975
3976
3977
3978
3980 if (!IsLambda && !IsIncomplete) {
3991 }
3992 }
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002 if (CheckNonDependent(false))
4004
4007 false);
4009 SubstDecl(FD, Owner, SubstArgs));
4012
4015
4016
4017
4018 if (Specialization->getTemplateSpecializationArgs() ==
4019 CanonicalDeducedArgumentList)
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030 if (IsLambda && !IsIncomplete) {
4035
4040 }
4041 }
4042
4043
4044
4045
4050 DeducedArgs)) {
4052 }
4053 }
4054
4055 if (OriginalCallArgs) {
4056
4057
4058
4059
4060 llvm::SmallDenseMap<std::pair<unsigned, QualType>, QualType> DeducedATypes;
4061 for (unsigned I = 0, N = OriginalCallArgs->size(); I != N; ++I) {
4063
4065 unsigned ExplicitOffset =
4066 (Specialization->hasCXXExplicitFunctionObjectParameter() &&
4067 !ForOverloadSetAddressResolution)
4068 ? 1
4069 : 0;
4071
4072
4073
4074 continue;
4075
4078
4079
4080 DeducedA =
4082 } else {
4083
4084
4085
4088 if (CacheEntry.isNull()) {
4092 CacheEntry =
4096 }
4097 DeducedA = CacheEntry;
4098 }
4099
4100 if (auto TDK =
4103 return TDK;
4104 }
4105 }
4106
4107
4108
4109
4110
4112 auto [Pos, Inserted] =
4114 if (Inserted)
4116 }
4117
4119}
4120
4121
4122
4125
4126 if (S.getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() &&
4128 return {};
4129
4130 if (CXXMethodDecl *Method = dyn_cast(Fn))
4131 if (Method->isImplicitObjectMemberFunction()) {
4132
4133
4135 return {};
4136
4138 Fn->getType(), std::nullopt, Method->getParent());
4139 }
4140
4143}
4144
4145
4146
4147
4148
4152 bool ParamWasReference,
4154
4156
4158
4159
4160 unsigned TDF = 0;
4161 if (ParamWasReference)
4165
4166
4167
4168
4169
4174
4177 Ovl, false,
4178 nullptr, FailedTSC,
4179 true))
4181 }
4182
4187
4188 return {};
4189 }
4190
4191
4197 E = Ovl->decls_end(); I != E; ++I) {
4199
4201
4202
4203
4205 return {};
4206
4207
4213 continue;
4214
4216 }
4217
4220 if (ArgType.isNull()) continue;
4221
4222
4223 if (!ParamWasReference && ParamType->isPointerType() &&
4224 ArgType->isFunctionType())
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4240 Deduced(TemplateParams->size());
4243 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF,
4245 nullptr);
4247 continue;
4248
4249
4250
4251
4253 return {};
4254 Match = ArgType;
4255 }
4256
4258}
4259
4260
4261
4262
4263
4264
4265
4271
4272
4273
4276
4277
4278
4280 if (ParamRefType)
4282
4283
4284
4285
4287 assert(Arg && "expected a non-null arg expression");
4289 ParamRefType != nullptr, FailedTSC);
4290 if (ArgType.isNull())
4291 return true;
4292 }
4293
4294 if (ParamRefType) {
4295
4296 if (ArgType->isIncompleteArrayType()) {
4297 assert(Arg && "expected a non-null arg expression");
4299 }
4300
4301
4302
4303
4305 ArgClassification.isLValue()) {
4306 if (S.getLangOpts().OpenCL && !ArgType.hasAddressSpace())
4310 }
4311 } else {
4312
4313
4314
4315
4316
4317
4318
4319
4320 if (ArgType->canDecayToPointerType())
4322 else {
4323
4324
4325 ArgType = ArgType.getUnqualifiedType();
4326 }
4327 }
4328
4329
4330
4331
4332
4334
4335
4336
4337
4338 if (ParamRefType)
4340
4341
4342
4343 if (ArgType->isPointerType() || ArgType->isMemberPointerType() ||
4344 ArgType->isObjCObjectPointerType())
4346
4347
4348
4349
4350
4356
4357 return false;
4358}
4359
4360static bool
4363
4371 bool DecomposedParam, unsigned ArgIdx, unsigned TDF,
4373
4374
4375
4381 unsigned TDF) {
4382
4383
4384
4385
4386
4387
4388
4389
4392
4395 if (ArrTy)
4396 ElTy = ArrTy->getElementType();
4398
4399
4401 }
4402
4403
4404
4408
4409
4413 S, TemplateParams, 0, ElTy, E->getType(),
4414 E->Classify(S.getASTContext()), E, Info, Deduced,
4415 OriginalCallArgs, true, ArgIdx, TDF);
4417 return Result;
4418 }
4419 }
4420
4421
4422
4423 if (auto *DependentArrTy = dyn_cast_or_null(ArrTy)) {
4424
4426 Info, DependentArrTy->getSizeExpr())) {
4427
4428
4429
4430
4435 S, TemplateParams, NTTP, llvm::APSInt(Size), T,
4436 true, Info, false, Deduced,
4437 nullptr);
4439 return Result;
4440 }
4441 }
4442
4444}
4445
4446
4447
4455 bool DecomposedParam, unsigned ArgIdx, unsigned TDF,
4457
4458 QualType OrigParamType = ParamType;
4459
4460
4461
4463 S, TemplateParams, FirstInnerIndex, ParamType, ArgType,
4464 ArgClassification, Arg, TDF, FailedTSC))
4466
4467
4468 if (InitListExpr *ILE = dyn_cast_if_present(Arg))
4470 Deduced, OriginalCallArgs, ArgIdx, TDF);
4471
4472
4473
4474
4475
4476
4477 if (Arg)
4478 OriginalCallArgs.push_back(
4481 S, TemplateParams, ParamType, ArgType, Info, Deduced, TDF,
4483 nullptr);
4484}
4485
4490 bool PartialOverloading, bool AggregateDeductionCandidate,
4493 bool ForOverloadSetAddressResolution,
4494 llvm::function_ref<bool(ArrayRef, bool)> CheckNonDependent) {
4497
4499 unsigned NumParams = Function->getNumParams();
4500 bool HasExplicitObject = false;
4501 int ExplicitObjectOffset = 0;
4502
4503
4504
4505
4506
4507
4508
4509 if (!ForOverloadSetAddressResolution &&
4510 Function->hasCXXExplicitFunctionObjectParameter()) {
4511 HasExplicitObject = true;
4512 ExplicitObjectOffset = 1;
4513 }
4514
4516
4517
4518
4519
4520
4521 if (Args.size() < Function->getMinRequiredExplicitArguments() &&
4522 !PartialOverloading)
4524 else if (TooManyArguments(NumParams, Args.size() + ExplicitObjectOffset,
4525 PartialOverloading)) {
4527 if (Proto->isTemplateVariadic())
4528 ;
4529 else if (!Proto->isVariadic())
4531 }
4532
4536
4537
4538
4544 unsigned NumExplicitlySpecified = 0;
4545 if (ExplicitTemplateArgs) {
4548 Result = SubstituteExplicitTemplateArguments(
4549 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr,
4550 Info);
4551 });
4556
4557 NumExplicitlySpecified = Deduced.size();
4558 } else {
4559
4560 for (unsigned I = 0; I != NumParams; ++I)
4561 ParamTypes.push_back(Function->getParamDecl(I)->getType());
4562 }
4563
4565
4566
4567 auto DeduceCallArgument = [&](QualType ParamType, unsigned ArgIdx,
4568 bool ExplicitObjectArgument) {
4569
4570
4571
4572
4575
4576 if (ExplicitObjectArgument) {
4577
4579 *this, TemplateParams, FirstInnerIndex, ParamType, ObjectType,
4580 ObjectClassification,
4581 nullptr, Info, Deduced, OriginalCallArgs,
4582 false, ArgIdx, 0);
4583 }
4584
4585
4587 *this, TemplateParams, FirstInnerIndex, ParamType,
4589 Args[ArgIdx], Info, Deduced, OriginalCallArgs, false,
4590 ArgIdx, 0);
4591 };
4592
4593
4594 Deduced.resize(TemplateParams->size());
4596 for (unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0;
4599
4600 const PackExpansionType *ParamExpansion =
4601 dyn_cast(ParamType);
4602 if (!ParamExpansion) {
4603
4604 if (ArgIdx >= Args.size() && !(HasExplicitObject && ParamIdx == 0))
4605 break;
4606
4607 ParamTypesForArgChecking.push_back(ParamType);
4608
4609 if (ParamIdx == 0 && HasExplicitObject) {
4610 if (ObjectType.isNull())
4612
4613 if (auto Result = DeduceCallArgument(ParamType, 0,
4614 true);
4617 continue;
4618 }
4619
4620 if (auto Result = DeduceCallArgument(ParamType, ArgIdx++,
4621 false);
4624
4625 continue;
4626 }
4627
4628 bool IsTrailingPack = ParamIdx + 1 == NumParamTypes;
4629
4630 QualType ParamPattern = ParamExpansion->getPattern();
4631 PackDeductionScope PackScope(*this, TemplateParams, Deduced, Info,
4632 ParamPattern,
4633 AggregateDeductionCandidate && IsTrailingPack);
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651 if (IsTrailingPack || PackScope.hasFixedArity()) {
4652 for (; ArgIdx < Args.size() && PackScope.hasNextElement();
4653 PackScope.nextPackElement(), ++ArgIdx) {
4654 ParamTypesForArgChecking.push_back(ParamPattern);
4655 if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx,
4656 false);
4659 }
4660 } else {
4661
4662
4663
4664 UnsignedOrNone NumExpansions = ParamExpansion->getNumExpansions();
4665 if (NumExpansions && !PackScope.isPartiallyExpanded()) {
4666 for (unsigned I = 0; I != *NumExpansions && ArgIdx < Args.size();
4667 ++I, ++ArgIdx) {
4668 ParamTypesForArgChecking.push_back(ParamPattern);
4669
4670
4671 PackScope.nextPackElement();
4672 }
4673 } else if (!IsTrailingPack && !PackScope.isPartiallyExpanded() &&
4674 PackScope.isDeducedFromEarlierParameter()) {
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4688 PackScope.getSavedPackSizeIfAllEqual();
4689 if (!ArgPosAfterSubstitution)
4690 continue;
4691
4692 unsigned PackArgEnd = ArgIdx + *ArgPosAfterSubstitution;
4693 for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) {
4694 ParamTypesForArgChecking.push_back(ParamPattern);
4696 DeduceCallArgument(ParamPattern, ArgIdx,
4697 false);
4700
4701 PackScope.nextPackElement();
4702 }
4703 }
4704 }
4705
4706
4707
4708 if (auto Result = PackScope.finish();
4711 }
4712
4713
4714
4716
4719 Result = FinishTemplateArgumentDeduction(
4720 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4721 &OriginalCallArgs, PartialOverloading, PartialOrdering,
4722 ForOverloadSetAddressResolution,
4723 [&, CallingCtx](bool OnlyInitializeNonUserDefinedConversions) {
4724 ContextRAII SavedContext(*this, CallingCtx);
4725 return CheckNonDependent(ParamTypesForArgChecking,
4726 OnlyInitializeNonUserDefinedConversions);
4727 });
4728 });
4729 if (Trap.hasErrorOccurred()) {
4733 }
4734 return Result;
4735}
4736
4739 bool AdjustExceptionSpec) {
4740 if (ArgFunctionType.isNull())
4741 return ArgFunctionType;
4742
4746 bool Rebuild = false;
4747
4748 CallingConv CC = FunctionTypeP->getCallConv();
4749 if (EPI.ExtInfo.getCC() != CC) {
4750 EPI.ExtInfo = EPI.ExtInfo.withCallingConv(CC);
4751 Rebuild = true;
4752 }
4753
4754 bool NoReturn = FunctionTypeP->getNoReturnAttr();
4755 if (EPI.ExtInfo.getNoReturn() != NoReturn) {
4756 EPI.ExtInfo = EPI.ExtInfo.withNoReturn(NoReturn);
4757 Rebuild = true;
4758 }
4759
4760 if (AdjustExceptionSpec && (FunctionTypeP->hasExceptionSpec() ||
4762 EPI.ExceptionSpec = FunctionTypeP->getExtProtoInfo().ExceptionSpec;
4763 Rebuild = true;
4764 }
4765
4766 if (!Rebuild)
4767 return ArgFunctionType;
4768
4771}
4772
4777 bool IsAddressOfFunction) {
4780
4785
4788
4789
4793
4794
4797 unsigned NumExplicitlySpecified = 0;
4799 if (ExplicitTemplateArgs) {
4802 Result = SubstituteExplicitTemplateArguments(
4803 FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes,
4804 &FunctionType, Info);
4805 });
4810
4811 NumExplicitlySpecified = Deduced.size();
4812 }
4813
4814
4815
4816
4817 if (!IsAddressOfFunction)
4819 false);
4820
4821 Deduced.resize(TemplateParams->size());
4822
4823
4824
4825 bool HasDeducedReturnType = false;
4827 Function->getReturnType()->getContainedAutoType()) {
4829 HasDeducedReturnType = true;
4830 }
4831
4833 unsigned TDF =
4835
4837 *this, TemplateParams, FunctionType, ArgFunctionType, Info, Deduced,
4839 nullptr);
4842 }
4843
4846 Result = FinishTemplateArgumentDeduction(
4847 FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
4848 nullptr, false,
4849 true, IsAddressOfFunction);
4850 });
4853
4854
4855
4856 if (HasDeducedReturnType && IsAddressOfFunction &&
4857 Specialization->getReturnType()->isUndeducedType() &&
4860
4861
4862
4863
4864
4870
4871
4872
4873
4874
4876 if (!IsAddressOfFunction) {
4877 ArgFunctionType = adjustCCAndNoReturn(ArgFunctionType, SpecializationType,
4878 true);
4879
4880
4881
4882 if (HasDeducedReturnType) {
4885 }
4886 }
4887
4888
4889
4890
4891 if (!ArgFunctionType.isNull()) {
4893 SpecializationType, ArgFunctionType)
4894 : .hasSameFunctionTypeIgnoringExceptionSpec(
4895 SpecializationType, ArgFunctionType)) {
4899 }
4900 }
4901
4903}
4904
4911
4914
4918
4919
4920
4921
4924
4925
4926
4927
4930
4931
4932
4933 if (!IsReferenceP) {
4936 }
4937
4938
4939
4940
4941 } else {
4942 assert(!A->isReferenceType() && "Reference types were handled above");
4943
4944
4945
4946
4948 P = Context.getArrayDecayedType(P);
4949
4950
4951
4953 P = Context.getPointerType(P);
4954
4955
4956 else
4958
4959
4960
4961
4962
4964 }
4965
4966
4970
4971
4972
4973
4974
4975
4979 Deduced.resize(TemplateParams->size());
4980
4981
4982
4983
4984
4985 unsigned TDF = 0;
4986
4987
4988
4989 if (IsReferenceA)
4991
4992
4993
4994
4995
4996
4997
5001
5008 ParamType, ObjectType, ObjectClassification,
5009 nullptr, Info, Deduced, OriginalCallArgs,
5010 false, 0, 0);
5013 }
5014
5016 *this, TemplateParams, P, A, Info, Deduced, TDF,
5018 nullptr);
5021
5022
5024
5025 FunctionDecl *ConversionSpecialized = nullptr;
5028 Result = FinishTemplateArgumentDeduction(
5029 ConversionTemplate, Deduced, 0, ConversionSpecialized, Info,
5030 &OriginalCallArgs, false,
5031 false, false);
5032 });
5033 Specialization = cast_or_null(ConversionSpecialized);
5035}
5036
5042 bool IsAddressOfFunction) {
5045 IsAddressOfFunction);
5046}
5047
5048namespace {
5049 struct DependentAuto { bool IsPack; };
5050
5051
5052
5053 class SubstituteDeducedTypeTransform :
5054 public TreeTransform {
5056 bool ReplacementIsPack;
5057 bool UseTypeSugar;
5059
5060 public:
5061 SubstituteDeducedTypeTransform(Sema &SemaRef, DependentAuto DA)
5062 : TreeTransform(SemaRef),
5063 ReplacementIsPack(DA.IsPack), UseTypeSugar(true) {}
5064
5065 SubstituteDeducedTypeTransform(Sema &SemaRef, QualType Replacement,
5066 bool UseTypeSugar = true)
5067 : TreeTransform(SemaRef),
5068 Replacement(Replacement), ReplacementIsPack(false),
5069 UseTypeSugar(UseTypeSugar) {}
5070
5071 QualType TransformDesugared(TypeLocBuilder &TLB, DeducedTypeLoc TL) {
5073 "unexpected unsugared replacement kind");
5074 QualType Result = Replacement;
5075 TemplateTypeParmTypeLoc NewTL = TLB.push(Result);
5078 }
5079
5080 QualType TransformAutoType(TypeLocBuilder &TLB, AutoTypeLoc TL) {
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090 if (!UseTypeSugar)
5091 return TransformDesugared(TLB, TL);
5092
5093 QualType Result = SemaRef.Context.getAutoType(
5094 Replacement, TL.getTypePtr()->getKeyword(), Replacement.isNull(),
5095 ReplacementIsPack, TL.getTypePtr()->getTypeConstraintConcept(),
5096 TL.getTypePtr()->getTypeConstraintArguments());
5097 auto NewTL = TLB.push(Result);
5098 NewTL.copy(TL);
5100 }
5101
5102 QualType TransformDeducedTemplateSpecializationType(
5103 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
5104 if (!UseTypeSugar)
5105 return TransformDesugared(TLB, TL);
5106
5107 QualType Result = SemaRef.Context.getDeducedTemplateSpecializationType(
5109 Replacement, Replacement.isNull());
5110 auto NewTL = TLB.push(Result);
5115 }
5116
5118
5119 return E;
5120 }
5121 bool TransformExceptionSpec(SourceLocation Loc,
5122 FunctionProtoType::ExceptionSpecInfo &ESI,
5123 SmallVectorImpl &Exceptions,
5124 bool &Changed) {
5128 }
5129 return inherited::TransformExceptionSpec(Loc, ESI, Exceptions, Changed);
5130 }
5131
5132 QualType Apply(TypeLoc TL) {
5133
5134
5135 TypeLocBuilder TLB;
5137 return TransformType(TLB, TL);
5138 }
5139 };
5140
5141}
5142
5149 TypeLoc.getRAngleLoc());
5153 Deduced, TypeLoc.getNameLoc())));
5154 for (unsigned I = 0, C = TypeLoc.getNumArgs(); I != C; ++I)
5156
5159 {},
5160 false, CTAI))
5161 return true;
5163 true);
5164
5165
5166
5167
5168
5169
5170
5171
5172
5181 return true;
5183 std::string Buf;
5184 llvm::raw_string_ostream OS(Buf);
5185 OS << "'" << Concept->getName();
5186 if (TypeLoc.hasExplicitTemplateArgs()) {
5187 printTemplateArgumentList(
5189 Type.getTypeConstraintConcept()->getTemplateParameters());
5190 }
5191 OS << "'";
5193 diag::err_placeholder_constraints_not_satisfied)
5196 return true;
5197 }
5198 return false;
5199}
5200
5204 bool IgnoreConstraints,
5206 assert(DependentDeduction || Info.getDeducedDepth() == 0);
5207 if (Init->containsErrors())
5209
5211 assert(AT);
5212
5213 if (Init->getType()->isNonOverloadPlaceholderType() || AT->isDecltypeAuto()) {
5217 Init = NonPlaceholder.get();
5218 }
5219
5220 DependentAuto DependentResult = {
5222
5223 if (!DependentDeduction &&
5225 Init->containsUnexpandedParameterPack())) {
5226 Result = SubstituteDeducedTypeTransform(*this, DependentResult).Apply(Type);
5227 assert(.isNull() && "substituting DependentTy can't fail");
5229 }
5230
5231
5232 auto *String = dyn_cast(Init);
5234 Diag(Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5236 Result = SubstituteDeducedTypeTransform(*this, DependentResult).Apply(TL);
5237 assert(.isNull() && "substituting DependentTy can't fail");
5239 }
5240
5241
5243 Diag(Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier);
5244 }
5245
5246 auto *InitList = dyn_cast(Init);
5248 Diag(Init->getBeginLoc(), diag::err_auto_init_list_from_c)
5249 << (int)AT->getKeyword() << getLangOpts().C23;
5251 }
5252
5253
5255 Deduced.resize(1);
5256
5258
5260
5261 if (AT->isDecltypeAuto()) {
5262 if (InitList) {
5263 Diag(Init->getBeginLoc(), diag::err_decltype_auto_initializer_list);
5265 }
5266
5268 assert(!DeducedType.isNull());
5269 } else {
5271
5272
5276 nullptr, false, false, false);
5278 NamedDecl *TemplParamPtr = TemplParam;
5280 Context, Loc, Loc, TemplParamPtr, Loc, nullptr);
5281
5282 if (InitList) {
5283
5284
5285
5286 if (.getType().getNonReferenceType()->getAs())
5288
5290 for (Expr *Init : InitList->inits()) {
5291
5292
5296 *this, TemplateParamsSt.get(), 0, TemplArg, Init->getType(),
5298 OriginalCallArgs,
5299 true,
5300 0, 0);
5303 Diag(Info.getLocation(), diag::err_auto_inconsistent_deduction)
5305 << Init->getSourceRange();
5307 }
5308 return TDK;
5309 }
5310
5311 if (DeducedFromInitRange.isInvalid() &&
5313 DeducedFromInitRange = Init->getSourceRange();
5314 }
5315 } else {
5317 Diag(Loc, diag::err_auto_bitfield);
5319 }
5321 SubstituteDeducedTypeTransform(*this, TemplArg).Apply(Type);
5322 assert(!FuncParam.isNull() &&
5323 "substituting template parameter for 'auto' failed");
5325 *this, TemplateParamsSt.get(), 0, FuncParam, Init->getType(),
5327 OriginalCallArgs,
5328 false, 0, 0, FailedTSC);
5330 return TDK;
5331 }
5332
5333
5336 DeducedType = Deduced[0].getAsType();
5337
5338 if (InitList) {
5340 if (DeducedType.isNull())
5342 }
5343 }
5344
5345 if (.isNull()) {
5346 if (.hasSameType(DeducedType, Result)) {
5350 }
5351 DeducedType = Context.getCommonSugaredType(Result, DeducedType);
5352 }
5353
5354 if (AT->isConstrained() && !IgnoreConstraints &&
5356 *this, *AT, Type.getContainedAutoTypeLoc(), DeducedType))
5358
5359 Result = SubstituteDeducedTypeTransform(*this, DeducedType).Apply(Type);
5360 if (Result.isNull())
5362
5363
5364
5365 QualType DeducedA = InitList ? Deduced[0].getAsType() : Result;
5366 for (const OriginalCallArg &OriginalArg : OriginalCallArgs) {
5367 assert((bool)InitList == OriginalArg.DecomposedParam &&
5368 "decomposed non-init-list in auto deduction?");
5369 if (auto TDK =
5373 return TDK;
5374 }
5375 }
5376
5378}
5379
5381 QualType TypeToReplaceAuto) {
5382 assert(TypeToReplaceAuto != Context.DependentTy);
5383 return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto)
5384 .TransformType(TypeWithAuto);
5385}
5386
5388 QualType TypeToReplaceAuto) {
5389 assert(TypeToReplaceAuto != Context.DependentTy);
5390 return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto)
5391 .TransformType(TypeWithAuto);
5392}
5393
5395 return SubstituteDeducedTypeTransform(
5396 *this,
5398 .TransformType(TypeWithAuto);
5399}
5400
5403 return SubstituteDeducedTypeTransform(
5405 TypeWithAuto->getType())})
5406 .TransformType(TypeWithAuto);
5407}
5408
5410 QualType TypeToReplaceAuto) {
5411 return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto,
5412 false)
5413 .TransformType(TypeWithAuto);
5414}
5415
5417 QualType TypeToReplaceAuto) {
5418 return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto,
5419 false)
5420 .TransformType(TypeWithAuto);
5421}
5422
5428 ? diag::err_init_capture_deduction_failure_from_init_list
5429 : diag::err_auto_var_deduction_failure_from_init_list)
5431 else
5433 VDecl->isInitCapture() ? diag::err_init_capture_deduction_failure
5434 : diag::err_auto_var_deduction_failure)
5436 << Init->getSourceRange();
5437}
5438
5442
5443
5444
5448
5449
5452 CallOp->getDescribedFunctionTemplate(), Args, Loc);
5453 if (!CallOp || CallOp->isInvalidDecl())
5454 return true;
5455
5456
5457
5458 if (CallOp->getReturnType()->isUndeducedType()) {
5461 });
5462 }
5463 }
5464
5465 if (CallOp->isInvalidDecl())
5466 return true;
5467 assert(!CallOp->getReturnType()->isUndeducedType() &&
5468 "failed to deduce lambda return type");
5469
5470
5474 ->getCallConv();
5478 RetType = Context.getPointerType(RetType);
5479 else {
5481 RetType = Context.getBlockPointerType(RetType);
5482 }
5483 Context.adjustDeducedFunctionResultType(FD, RetType);
5484 return false;
5485 }
5486
5490 });
5491 }
5492
5495 Diag(Loc, diag::err_auto_fn_used_before_defined) << FD;
5497 }
5498
5499 return StillUndeduced;
5500}
5501
5505
5509
5510
5513 CallOp->getDescribedFunctionTemplate(), Args, Loc);
5514 if (!CallOp || CallOp->isInvalidDecl())
5515 return true;
5518 }
5520 }
5521
5525 }
5526 return false;
5527}
5528
5532 bool IsOtherRvr) {
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542 assert(Method && !Method->isExplicitObjectMemberFunction() &&
5543 "expected a member function with no explicit object parameter");
5544
5545 RawType = Context.getQualifiedType(RawType, Method->getMethodQualifiers());
5546 if (Method->getRefQualifier() == RQ_RValue ||
5547 (IsOtherRvr && Method->getRefQualifier() == RQ_None))
5548 return Context.getRValueReferenceType(RawType);
5549 return Context.getLValueReferenceType(RawType);
5550}
5551
5556 true);
5558 S,
5560 bool IsIncompleteSubstitution = false;
5561
5562
5563
5564
5565
5566
5567
5569 if (IsDeductionGuide) {
5570 if (auto *Injected = P->getAsCanonical())
5571 P = Injected->getDecl()->getCanonicalTemplateSpecializationType(
5573 }
5575 FTD->getDeclName(), &IsIncompleteSubstitution);
5576 if (InstP.isNull() && !IsIncompleteSubstitution)
5578 if (!CheckConsistency)
5580 if (IsIncompleteSubstitution)
5582
5583
5584
5585 if (auto *PA = dyn_cast(A);
5587 A = PA->getPattern();
5590 if (IsDeductionGuide) {
5591 if (auto *Injected = T1->getAsCanonical())
5592 T1 = Injected->getDecl()->getCanonicalTemplateSpecializationType(
5594 if (auto *Injected = T2->getAsCanonical())
5595 T2 = Injected->getDecl()->getCanonicalTemplateSpecializationType(
5597 }
5601}
5602
5603template
5609
5610
5611
5612
5613 bool IsIncomplete = false;
5617 Info, CTAI,
5618 nullptr,
5619 0, &IsIncomplete);
5621 return Result;
5622
5623
5628
5629 Info.reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
5630
5631
5632
5633
5636}
5637
5638
5639
5648 assert(Proto1 && Proto2 && "Function templates must have prototypes");
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5661
5662 assert(Proto1->getMethodQuals() == Proto2->getMethodQuals() &&
5663 Proto1->getRefQualifier() == Proto2->getRefQualifier() &&
5664 Proto1->isVariadic() == Proto2->isVariadic() &&
5665 "shouldn't partial order functions with different qualifiers in a "
5666 "context where the function type is used");
5667
5668 assert(Args1.empty() && Args2.empty() &&
5669 "Only call context should have arguments");
5671 Args2 = Proto2->getParamTypes();
5672 }
5673
5677
5678 bool HasDeducedAnyParamFromReturnType = false;
5681 S, TemplateParams, Proto2->getReturnType(), Proto1->getReturnType(),
5683 false,
5684 &HasDeducedAnyParamFromReturnType) !=
5686 return false;
5687 }
5688
5689 llvm::SmallBitVector HasDeducedParam;
5691 HasDeducedParam.resize(Args2.size());
5694 nullptr,
5695 &HasDeducedParam) !=
5697 return false;
5698 }
5699
5705 S, Info.getLocation(), FT2, DeducedArgs,
5708 return false;
5709
5710 bool AtLeastAsSpecialized;
5712 AtLeastAsSpecialized =
5713 ::FinishTemplateArgumentDeduction(
5714 S, FT2, Deduced, Info,
5715 [&](Sema &S, FunctionTemplateDecl *FTD,
5716 ArrayRef DeducedArgs) {
5717
5718
5719
5720
5721 if (TPOC != TPOC_Call) {
5722 if (auto TDR = ::CheckDeductionConsistency(
5723 S, FTD, std::nullopt,
5724 Proto2->getReturnType(), Proto1->getReturnType(),
5725 DeducedArgs,
5726 HasDeducedAnyParamFromReturnType);
5727 TDR != TemplateDeductionResult::Success)
5728 return TDR;
5729 }
5730
5731 if (TPOC == TPOC_Conversion)
5732 return TemplateDeductionResult::Success;
5733
5734 return ::DeduceForEachType(
5735 S, TemplateParams, Args2, Args1, Info, Deduced,
5736 PartialOrderingKind::Call, true,
5737 [&](Sema &S, TemplateParameterList *, int ParamIdx,
5738 UnsignedOrNone ArgIdx, QualType P, QualType A,
5739 TemplateDeductionInfo &Info,
5740 SmallVectorImpl &Deduced,
5741 PartialOrderingKind) {
5742 if (ArgIdx && *ArgIdx >= static_cast(Args1Offset))
5743 ArgIdx = *ArgIdx - Args1Offset;
5744 else
5745 ArgIdx = std::nullopt;
5746 return ::CheckDeductionConsistency(
5747 S, FTD, ArgIdx, P, A, DeducedArgs,
5748 HasDeducedParam[ParamIdx]);
5749 });
5751 });
5752 if (!AtLeastAsSpecialized || Trap.hasErrorOccurred())
5753 return false;
5754
5755
5756
5757
5758
5759
5760
5761 unsigned ArgIdx = 0, NumArgs = Deduced.size();
5762 for (; ArgIdx != NumArgs; ++ArgIdx)
5763 if (Deduced[ArgIdx].isNull())
5764 break;
5765
5766 if (ArgIdx == NumArgs) {
5767
5768
5769 return true;
5770 }
5771
5772
5773 llvm::SmallBitVector UsedParameters(TemplateParams->size());
5774 switch (TPOC) {
5776 for (unsigned I = 0, N = Args2.size(); I != N; ++I)
5778 TemplateParams->getDepth(), UsedParameters);
5779 break;
5780
5783 false,
5784 TemplateParams->getDepth(), UsedParameters);
5785 break;
5786
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5808 S.Context,
5809 S.Context.getFunctionTypeWithExceptionSpec(FD2->getType(), EST_None),
5810 false, TemplateParams->getDepth(), UsedParameters);
5811 break;
5812 }
5813
5814 for (; ArgIdx != NumArgs; ++ArgIdx)
5815
5816
5817 if (Deduced[ArgIdx].isNull() && UsedParameters[ArgIdx])
5818 return false;
5819
5820 return true;
5821}
5822
5824
5825
5826
5829 const TemplateSpecializationType *TST1,
5830 const TemplateSpecializationType *TST2) {
5832 As2 = TST2->template_arguments();
5833 const TemplateArgument &TA1 = As1.back(), &TA2 = As2.back();
5836 if (!IsPack)
5838 assert(As1.size() == As2.size());
5839
5840 unsigned PackSize1 = TA1.pack_size(), PackSize2 = TA2.pack_size();
5841 bool IsPackExpansion1 =
5842 PackSize1 && TA1.pack_elements().back().isPackExpansion();
5843 bool IsPackExpansion2 =
5844 PackSize2 && TA2.pack_elements().back().isPackExpansion();
5845 if (PackSize1 == PackSize2 && IsPackExpansion1 == IsPackExpansion2)
5847 if (PackSize1 > PackSize2 && IsPackExpansion1)
5849 if (PackSize1 < PackSize2 && IsPackExpansion2)
5852}
5853
5858 bool PartialOverloading) {
5863 bool ShouldConvert1 = false;
5864 bool ShouldConvert2 = false;
5865 bool Args1Offset = false;
5866 bool Args2Offset = false;
5874
5875
5876
5877 const CXXMethodDecl *Method1 = dyn_cast(FD1);
5878 const CXXMethodDecl *Method2 = dyn_cast(FD2);
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889 bool NonStaticMethod1 = Method1 && !Method1->isStatic(),
5890 NonStaticMethod2 = Method2 && !Method2->isStatic();
5891
5893 Params2Begin = Proto2->param_type_begin();
5894
5895 size_t NumComparedArguments = NumCallArguments1;
5896
5898 (NonStaticMethod1 && NonStaticMethod2) ||
5899 (OO != OO_None && OO != OO_Call && OO != OO_Subscript)) {
5900 ShouldConvert1 =
5901 NonStaticMethod1 && !Method1->hasCXXExplicitFunctionObjectParameter();
5902 ShouldConvert2 =
5904 NumComparedArguments += 1;
5905
5906 if (ShouldConvert1) {
5907 bool IsRValRef2 =
5908 ShouldConvert2
5910 : Proto2->param_type_begin()[0]->isRValueReferenceType();
5911
5913 RawObj1Ty, IsRValRef2);
5914 Args1.push_back(Obj1Ty);
5915 Args1Offset = true;
5916 }
5917 if (ShouldConvert2) {
5918 bool IsRValRef1 =
5919 ShouldConvert1
5920 ? Method1->getRefQualifier() == RQ_RValue
5922
5924 RawObj2Ty, IsRValRef1);
5925 Args2.push_back(Obj2Ty);
5926 Args2Offset = true;
5927 }
5928 } else {
5929 if (NonStaticMethod1 && Method1->hasCXXExplicitFunctionObjectParameter())
5930 Params1Begin += 1;
5932 Params2Begin += 1;
5933 }
5934 Args1.insert(Args1.end(), Params1Begin, Proto1->param_type_end());
5935 Args2.insert(Args2.end(), Params2Begin, Proto2->param_type_end());
5936
5937
5938
5939
5940 Args1.resize(std::min(Args1.size(), NumComparedArguments));
5941 Args2.resize(std::min(Args2.size(), NumComparedArguments));
5942
5944 std::reverse(Args2.begin(), Args2.end());
5945 } else {
5946 assert( && "Only call context could have reversed arguments");
5947 }
5949 Args2, Args2Offset);
5951 Args1, Args1Offset);
5952
5953
5954
5955 if (Better1 != Better2)
5956 return Better1 ? FT1 : FT2;
5957
5958 if (!Better1 && !Better2)
5959 return nullptr;
5960
5961
5962
5963
5964
5965
5967 Param1.reserve(FD1->param_size() + ShouldConvert1);
5968 if (ShouldConvert1)
5969 Param1.push_back(Obj1Ty);
5970 for (const auto &P : FD1->parameters())
5971 Param1.push_back(P->getType());
5972
5974 Param2.reserve(FD2->param_size() + ShouldConvert2);
5975 if (ShouldConvert2)
5976 Param2.push_back(Obj2Ty);
5977 for (const auto &P : FD2->parameters())
5978 Param2.push_back(P->getType());
5979
5980 unsigned NumParams1 = Param1.size();
5981 unsigned NumParams2 = Param2.size();
5982
5983 bool Variadic1 =
5985 bool Variadic2 =
5987 if (Variadic1 != Variadic2) {
5988 if (Variadic1 && NumParams1 > NumParams2)
5989 return FT2;
5990 if (Variadic2 && NumParams2 > NumParams1)
5991 return FT1;
5992 }
5993
5994
5995
5996
5997 for (int i = 0, e = std::min(NumParams1, NumParams2);
5998 !PartialOverloading && i < e; ++i) {
5999 QualType T1 = Param1[i].getCanonicalType();
6000 QualType T2 = Param2[i].getCanonicalType();
6001 auto *TST1 = dyn_cast(T1);
6002 auto *TST2 = dyn_cast(T2);
6003 if (!TST1 || !TST2)
6004 continue;
6007 return FT1;
6009 return FT2;
6011 continue;
6012 }
6013 llvm_unreachable(
6014 "unknown MoreSpecializedTrailingPackTieBreakerResult value");
6015 }
6016
6017 if (.getLangOpts().CPlusPlus20)
6018 return nullptr;
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6033 if (TPL1->size() != TPL2->size() || NumParams1 != NumParams2)
6034 return nullptr;
6035
6036
6037
6038
6039
6040
6041
6044 return nullptr;
6045
6046
6047
6048
6049 for (unsigned i = 0; i < NumParams1; ++i)
6050 if (.hasSameUnqualifiedType(Param1[i], Param2[i]))
6051 return nullptr;
6052
6053
6054
6055
6056
6057
6060 return nullptr;
6061
6065 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6067 return nullptr;
6069 return nullptr;
6070 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6071 return nullptr;
6072 return AtLeastAsConstrained1 ? FT1 : FT2;
6073}
6074
6080 bool Complain, QualType TargetType) {
6081 if (SpecBegin == SpecEnd) {
6082 if (Complain) {
6083 Diag(Loc, NoneDiag);
6085 }
6086 return SpecEnd;
6087 }
6088
6089 if (SpecBegin + 1 == SpecEnd)
6090 return SpecBegin;
6091
6092
6093
6097 assert(BestTemplate && "Not a function template specialization?");
6101 assert(Challenger && "Not a function template specialization?");
6104 Challenger)) {
6105 Best = I;
6106 BestTemplate = Challenger;
6107 }
6108 }
6109
6110
6111
6116 if (I != Best &&
6119 BestTemplate)) {
6121 break;
6122 }
6123 }
6124
6126
6127 return Best;
6128 }
6129
6130
6131 if (Complain) {
6132 Diag(Loc, AmbigDiag);
6133
6134
6139 FD->getPrimaryTemplate()->getTemplateParameters(),
6140 *FD->getTemplateSpecializationArgs());
6141 if (!TargetType.isNull())
6143 Diag((*I)->getLocation(), PD);
6144 }
6145 }
6146
6147 return SpecEnd;
6148}
6149
6153 "not for function templates");
6158
6161 F1 = P;
6162
6165 F2 = P;
6166
6170 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6172 return nullptr;
6174 return nullptr;
6175 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6176 return nullptr;
6177 return AtLeastAsConstrained1 ? FD1 : FD2;
6178}
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189template
6191 TemplateLikeDecl *P2,
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6219
6220
6221 Deduced.resize(P2->getTemplateParameters()->size());
6223 S, P2->getTemplateParameters(), T2, T1, Info, Deduced, TDF_None,
6226 return false;
6227
6234 return false;
6235
6239
6242 Result = ::FinishTemplateArgumentDeduction(
6243 S, P2, P2->getTemplateParameters(), Template,
6244 true, Ps, As, Deduced, Info,
6245 false);
6246 });
6248}
6249
6250namespace {
6251
6252
6253struct GetP2 {
6254 template <typename T1, typename T2,
6255 std::enable_if_t<std::is_same_v<T1, T2>, bool> = true>
6256 T2 *operator()(T1 *, T2 *P2) {
6257 return P2;
6258 }
6259 template <typename T1, typename T2,
6260 std::enable_if_t<!std::is_same_v<T1, T2>, bool> = true>
6261 T1 *operator()(T1 *, T2 *) {
6262 return nullptr;
6263 }
6264};
6265
6266
6267struct TemplateArgumentListAreEqual {
6268 ASTContext &Ctx;
6269 TemplateArgumentListAreEqual(ASTContext &Ctx) : Ctx(Ctx) {}
6270
6271 template <typename T1, typename T2,
6272 std::enable_if_t<std::is_same_v<T1, T2>, bool> = true>
6273 bool operator()(T1 *PS1, T2 *PS2) {
6274 ArrayRef Args1 = PS1->getTemplateArgs().asArray(),
6275 Args2 = PS2->getTemplateArgs().asArray();
6276
6277 for (unsigned I = 0, E = Args1.size(); I < E; ++I) {
6278
6279
6280
6281 llvm::FoldingSetNodeID IDA, IDB;
6282 Args1[I].Profile(IDA, Ctx);
6283 Args2[I].Profile(IDB, Ctx);
6284 if (IDA != IDB)
6285 return false;
6286 }
6287 return true;
6288 }
6289
6290 template <typename T1, typename T2,
6291 std::enable_if_t<!std::is_same_v<T1, T2>, bool> = true>
6292 bool operator()(T1 *Spec, T2 *Primary) {
6293 ArrayRef Args1 = Spec->getTemplateArgs().asArray(),
6294 Args2 = Primary->getInjectedTemplateArgs(Ctx);
6295
6296 for (unsigned I = 0, E = Args1.size(); I < E; ++I) {
6297
6298
6299
6300 llvm::FoldingSetNodeID IDA, IDB;
6301 Args1[I].Profile(IDA, Ctx);
6302
6303
6305 if (IDA != IDB)
6306 return false;
6307 }
6308 return true;
6309 }
6310};
6311}
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335template <typename TemplateLikeDecl, typename PrimaryDel>
6336static TemplateLikeDecl *
6339 constexpr bool IsMoreSpecialThanPrimaryCheck =
6340 !std::is_same_v<TemplateLikeDecl, PrimaryDel>;
6341
6343 if constexpr (IsMoreSpecialThanPrimaryCheck)
6344 P2T = P2;
6345 else
6346 P2T = P2->getSpecializedTemplate();
6347
6349 if (IsMoreSpecialThanPrimaryCheck && !Better1)
6350 return nullptr;
6351
6353 P1->getSpecializedTemplate(), Info);
6354 if (IsMoreSpecialThanPrimaryCheck && !Better2)
6355 return P1;
6356
6357
6358
6359
6360 if (Better1 != Better2)
6361 return Better1 ? P1 : GetP2()(P1, P2);
6362
6363 if (!Better1 && !Better2)
6364 return nullptr;
6365
6370 return P1;
6372 return GetP2()(P1, P2);
6374 break;
6375 }
6376
6378 return nullptr;
6379
6380
6381
6382
6383
6384
6385
6388 if (TPL1->size() != TPL2->size())
6389 return nullptr;
6390
6391
6392
6393
6394
6395
6396
6399 return nullptr;
6400
6401 if (!TemplateArgumentListAreEqual(S.getASTContext())(P1, P2))
6402 return nullptr;
6403
6405 P1->getAssociatedConstraints(AC1);
6406 P2->getAssociatedConstraints(AC2);
6407 bool AtLeastAsConstrained1, AtLeastAsConstrained2;
6409 (IsMoreSpecialThanPrimaryCheck && !AtLeastAsConstrained1))
6410 return nullptr;
6412 return nullptr;
6413 if (AtLeastAsConstrained1 == AtLeastAsConstrained2)
6414 return nullptr;
6415 return AtLeastAsConstrained1 ? P1 : GetP2()(P1, P2);
6416}
6417
6429
6435
6438 if (MaybeSpec)
6440 return MaybeSpec;
6441}
6442
6447
6448
6450 "the partial specializations being compared should specialize"
6451 " the same template.");
6453 QualType PT1 = Context.getCanonicalTemplateSpecializationType(
6455 QualType PT2 = Context.getCanonicalTemplateSpecializationType(
6457
6460}
6461
6466
6469 Context.canonicalizeTemplateArguments(PrimaryCanonArgs);
6470
6471 QualType PrimaryT = Context.getCanonicalTemplateSpecializationType(
6473 QualType PartialT = Context.getCanonicalTemplateSpecializationType(
6475
6478 if (MaybeSpec)
6480 return MaybeSpec;
6481}
6482
6487
6488
6489
6490
6491
6492
6493
6494
6495
6497
6502 return false;
6503
6504
6505
6506
6507
6508
6510
6511
6512
6513
6514
6516 {
6519 for (unsigned I = 0, N = P->size(); I != N; ++I) {
6520
6521
6526 }
6529 }
6530 PArgs.clear();
6531
6532
6533
6534
6536 false, true);
6539 false, CTAI,
6540 true,
6541 nullptr))
6542 return false;
6544 if (StrictPackMatch)
6546 }
6547
6548
6551 Deduced.resize(A->size());
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6565 *this, A, AArgs, PArgs, Info, Deduced,
6566 false, true,
6568 nullptr)) {
6571 *StrictPackMatch = true;
6572 break;
6573
6575 Diag(AArg->getLocation(), diag::err_template_param_list_different_arity)
6576 << (A->size() > P->size()) << true
6578 return false;
6580 Diag(AArg->getLocation(), diag::err_non_deduced_mismatch)
6582 return false;
6585 diag::err_inconsistent_deduction)
6587 return false;
6589 return false;
6590
6591
6606 llvm_unreachable("Unexpected Result");
6607 }
6608
6611 TDK = ::FinishTemplateArgumentDeduction(
6612 *this, AArg, AArg->getTemplateParameters(), AArg, PartialOrdering,
6613 AArgs, PArgs, Deduced, Info, false);
6614 });
6615 switch (TDK) {
6617 return true;
6618
6619
6620
6621
6623 assert(PArg->isInvalidDecl() && "Unexpected NonDeducedMismatch");
6624 return false;
6625
6626
6630 return false;
6631
6632
6647 llvm_unreachable("Unexpected Result");
6648 }
6649 llvm_unreachable("Unexpected TDK");
6650}
6651
6652namespace {
6654 llvm::SmallBitVector &Used;
6655 unsigned Depth;
6656 bool VisitDeclRefTypes = true;
6657
6658 MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &Used, unsigned Depth,
6659 bool VisitDeclRefTypes = true)
6660 : Used(Used), Depth(Depth), VisitDeclRefTypes(VisitDeclRefTypes) {}
6661
6662 bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override {
6663 if (T->getDepth() == Depth)
6664 Used[T->getIndex()] = true;
6665 return true;
6666 }
6667
6669 if (auto *TTP = llvm::dyn_cast_or_null(
6670 Template.getAsTemplateDecl()))
6671 if (TTP->getDepth() == Depth)
6672 Used[TTP->getIndex()] = true;
6674 return true;
6675 }
6676
6677 bool VisitDeclRefExpr(DeclRefExpr *E) override {
6678 if (auto *NTTP = dyn_cast(E->getDecl()))
6679 if (NTTP->getDepth() == Depth)
6680 Used[NTTP->getIndex()] = true;
6681 if (VisitDeclRefTypes)
6683 return true;
6684 }
6685
6686 bool VisitUnresolvedLookupExpr(UnresolvedLookupExpr *ULE) override {
6689 if (TTP->getDepth() == Depth)
6690 Used[TTP->getIndex()] = true;
6691 }
6694 }
6695 return true;
6696 }
6697
6698 bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE) override {
6699 return TraverseDecl(SOPE->getPack());
6700 }
6701};
6702}
6703
6704
6705
6706static void
6708 const Expr *E,
6709 bool OnlyDeduced,
6710 unsigned Depth,
6711 llvm::SmallBitVector &Used) {
6712 if (!OnlyDeduced) {
6713 MarkUsedTemplateParameterVisitor(Used, Depth)
6714 .TraverseStmt(const_cast<Expr *>(E));
6715 return;
6716 }
6717
6718
6719 if (const PackExpansionExpr *Expansion = dyn_cast(E))
6720 E = Expansion->getPattern();
6721
6723 if (const auto *ULE = dyn_cast(E);
6726 Used[TTP->getIndex()] = true;
6730 return;
6731 }
6732
6735 if (!NTTP)
6736 return;
6737 if (NTTP.getDepth() == Depth)
6739
6740
6741
6744}
6745
6746
6747
6749 bool OnlyDeduced, unsigned Depth,
6750 llvm::SmallBitVector &Used) {
6752 return;
6754 Depth, Used);
6755}
6756
6757
6758
6759static void
6762 bool OnlyDeduced,
6763 unsigned Depth,
6764 llvm::SmallBitVector &Used) {
6767 = dyn_cast(Template)) {
6768 if (TTP->getDepth() == Depth)
6769 Used[TTP->getIndex()] = true;
6770 }
6771 return;
6772 }
6773
6776 Depth, Used);
6779 Depth, Used);
6780}
6781
6782
6783
6784static void
6786 bool OnlyDeduced,
6787 unsigned Depth,
6788 llvm::SmallBitVector &Used) {
6789 if (T.isNull())
6790 return;
6791
6792
6793 if (->isDependentType())
6794 return;
6795
6797 switch (T->getTypeClass()) {
6798 case Type::Pointer:
6801 OnlyDeduced,
6802 Depth,
6804 break;
6805
6806 case Type::BlockPointer:
6809 OnlyDeduced,
6810 Depth,
6812 break;
6813
6814 case Type::LValueReference:
6815 case Type::RValueReference:
6818 OnlyDeduced,
6819 Depth,
6821 break;
6822
6823 case Type::MemberPointer: {
6826 Depth, Used);
6829 OnlyDeduced, Depth, Used);
6830 break;
6831 }
6832
6833 case Type::DependentSizedArray:
6836 OnlyDeduced, Depth, Used);
6837
6838 [[fallthrough]];
6839
6840 case Type::ConstantArray:
6841 case Type::IncompleteArray:
6842 case Type::ArrayParameter:
6845 OnlyDeduced, Depth, Used);
6846 break;
6847 case Type::Vector:
6848 case Type::ExtVector:
6851 OnlyDeduced, Depth, Used);
6852 break;
6853
6854 case Type::DependentVector: {
6857 Depth, Used);
6860 break;
6861 }
6862 case Type::DependentSizedExtVector: {
6866 Depth, Used);
6868 Depth, Used);
6869 break;
6870 }
6871
6872 case Type::DependentAddressSpace: {
6876 OnlyDeduced, Depth, Used);
6879 OnlyDeduced, Depth, Used);
6880 break;
6881 }
6882
6883 case Type::ConstantMatrix: {
6886 Depth, Used);
6887 break;
6888 }
6889
6890 case Type::DependentSizedMatrix: {
6893 Depth, Used);
6897 Depth, Used);
6898 break;
6899 }
6900
6901 case Type::FunctionProto: {
6905 for (unsigned I = 0, N = Proto->getNumParams(); I != N; ++I) {
6906
6907
6908
6909
6910 if (!OnlyDeduced || I + 1 == N ||
6913 Depth, Used);
6914 } else {
6915
6916
6917
6918
6919
6920
6921 }
6922 }
6925 break;
6926 }
6927
6928 case Type::TemplateTypeParm: {
6930 if (TTP->getDepth() == Depth)
6931 Used[TTP->getIndex()] = true;
6932 break;
6933 }
6934
6935 case Type::SubstTemplateTypeParmPack: {
6936 const SubstTemplateTypeParmPackType *Subst
6938 if (Subst->getReplacedParameter()->getDepth() == Depth)
6939 Used[Subst->getIndex()] = true;
6941 Depth, Used);
6942 break;
6943 }
6944 case Type::SubstBuiltinTemplatePack: {
6946 OnlyDeduced, Depth, Used);
6947 break;
6948 }
6949
6950 case Type::InjectedClassName:
6952 ->getDecl()
6953 ->getCanonicalTemplateSpecializationType(Ctx);
6954 [[fallthrough]];
6955
6956 case Type::TemplateSpecialization: {
6957 const TemplateSpecializationType *Spec
6959
6960 TemplateName Name = Spec->getTemplateName();
6962 break;
6963
6965
6966
6967
6968
6969
6970 if (OnlyDeduced &&
6972 break;
6973
6974 for (const auto &Arg : Spec->template_arguments())
6976 break;
6977 }
6978
6979 case Type::Complex:
6980 if (!OnlyDeduced)
6983 OnlyDeduced, Depth, Used);
6984 break;
6985
6986 case Type::Atomic:
6987 if (!OnlyDeduced)
6990 OnlyDeduced, Depth, Used);
6991 break;
6992
6993 case Type::DependentName:
6994 if (!OnlyDeduced)
6997 OnlyDeduced, Depth, Used);
6998 break;
6999
7000 case Type::TypeOf:
7001 if (!OnlyDeduced)
7003 OnlyDeduced, Depth, Used);
7004 break;
7005
7006 case Type::TypeOfExpr:
7007 if (!OnlyDeduced)
7010 OnlyDeduced, Depth, Used);
7011 break;
7012
7013 case Type::Decltype:
7014 if (!OnlyDeduced)
7017 OnlyDeduced, Depth, Used);
7018 break;
7019
7020 case Type::PackIndexing:
7021 if (!OnlyDeduced) {
7023 OnlyDeduced, Depth, Used);
7025 OnlyDeduced, Depth, Used);
7026 }
7027 break;
7028
7029 case Type::UnaryTransform:
7030 if (!OnlyDeduced) {
7032 auto Next = UTT->getUnderlyingType();
7033 if (Next.isNull())
7034 Next = UTT->getBaseType();
7036 }
7037 break;
7038
7039 case Type::PackExpansion:
7042 OnlyDeduced, Depth, Used);
7043 break;
7044
7045 case Type::Auto:
7046 case Type::DeducedTemplateSpecialization:
7049 OnlyDeduced, Depth, Used);
7050 break;
7051 case Type::DependentBitInt:
7054 OnlyDeduced, Depth, Used);
7055 break;
7056
7057 case Type::HLSLAttributedResource:
7060 Depth, Used);
7064 OnlyDeduced, Depth, Used);
7065 break;
7066
7067
7068 case Type::Builtin:
7069 case Type::VariableArray:
7070 case Type::FunctionNoProto:
7071 case Type::Record:
7072 case Type::Enum:
7073 case Type::ObjCInterface:
7074 case Type::ObjCObject:
7075 case Type::ObjCObjectPointer:
7076 case Type::UnresolvedUsing:
7077 case Type::Pipe:
7078 case Type::BitInt:
7079 case Type::HLSLInlineSpirv:
7080#define TYPE(Class, Base)
7081#define ABSTRACT_TYPE(Class, Base)
7082#define DEPENDENT_TYPE(Class, Base)
7083#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
7084#include "clang/AST/TypeNodes.inc"
7085 break;
7086 }
7087}
7088
7089
7090
7091static void
7094 bool OnlyDeduced,
7095 unsigned Depth,
7096 llvm::SmallBitVector &Used) {
7103 break;
7104
7107 Depth, Used);
7108 break;
7109
7113 TemplateArg.getAsTemplateOrTemplatePattern(),
7114 OnlyDeduced, Depth, Used);
7115 break;
7116
7119 Depth, Used);
7120 break;
7121
7123 for (const auto &P : TemplateArg.pack_elements())
7125 break;
7126 }
7127}
7128
7129void
7131 unsigned Depth,
7132 llvm::SmallBitVector &Used) {
7134}
7135
7137 const Expr *E, unsigned Depth, llvm::SmallBitVector &Used) {
7138 MarkUsedTemplateParameterVisitor(Used, Depth, false)
7139 .TraverseStmt(const_cast<Expr *>(E));
7140}
7141
7142void
7144 bool OnlyDeduced, unsigned Depth,
7145 llvm::SmallBitVector &Used) {
7146
7147
7148
7149
7150 if (OnlyDeduced &&
7152 return;
7153
7154 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
7156 Depth, Used);
7157}
7158
7160 unsigned Depth,
7161 llvm::SmallBitVector &Used) {
7162 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
7164 false, Depth, Used);
7165}
7166
7169 llvm::SmallBitVector &Used) {
7170 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
7172 false, Depth, Used);
7173}
7174
7177 llvm::SmallBitVector &Deduced) {
7180 Deduced.clear();
7181 Deduced.resize(TemplateParams->size());
7182
7184 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I)
7186 true, TemplateParams->getDepth(), Deduced);
7187}
7188
7192 if (->isDependentType())
7193 return false;
7194
7197 llvm::SmallBitVector Deduced(TemplateParams->size());
7199 Deduced);
7200
7201 return Deduced.any();
7202}
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Provides definitions for the various language-specific address spaces.
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::Expr interface and subclasses for C++ expressions.
TokenType getType() const
Returns the token's type, e.g.
FormatToken * Next
The next token in the unwrapped line.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static TemplateDeductionResult DeduceNullPtrTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, NonTypeOrVarTemplateParmDecl NTTP, QualType NullPtrType, TemplateDeductionInfo &Info, bool PartialOrdering, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool *HasDeducedAnyParam)
Deduce the value of the given non-type template parameter from the given null pointer template argume...
Definition SemaTemplateDeduction.cpp:539
static bool ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, DeducedTemplateArgument Arg, NamedDecl *Template, TemplateDeductionInfo &Info, bool IsDeduced, Sema::CheckTemplateArgumentInfo &CTAI)
Convert the given deduced template argument and add it to the set of fully-converted template argumen...
Definition SemaTemplateDeduction.cpp:2936
static TemplateDeductionResult DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, ArrayRef< TemplateArgument > Ps, ArrayRef< TemplateArgument > As, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool NumberOfArgumentsMustMatch, bool PartialOrdering, PackFold PackFold, bool *HasDeducedAnyParam)
Definition SemaTemplateDeduction.cpp:2742
static TemplateDeductionResult DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams, const QualType P, QualType A, TemplateDeductionInfo &Info, bool PartialOrdering, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool *HasDeducedAnyParam)
Definition SemaTemplateDeduction.cpp:689
static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(Sema &S, TemplateParameterList *TemplateParams, QualType Param, QualType Arg, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, unsigned TDF, PartialOrderingKind POK, bool DeducedFromArrayBound, bool *HasDeducedAnyParam)
Deduce the template arguments by comparing the parameter type and the argument type (C++ [temp....
Definition SemaTemplateDeduction.cpp:1605
static TemplateDeductionResult CheckDeductionConsistency(Sema &S, FunctionTemplateDecl *FTD, UnsignedOrNone ArgIdx, QualType P, QualType A, ArrayRef< TemplateArgument > DeducedArgs, bool CheckConsistency)
Definition SemaTemplateDeduction.cpp:5552
static PartialOrderingKind degradeCallPartialOrderingKind(PartialOrderingKind POK)
When propagating a partial ordering kind into a NonCall context, this is used to downgrade a 'Call' i...
Definition SemaTemplateDeduction.cpp:1577
static MoreSpecializedTrailingPackTieBreakerResult getMoreSpecializedTrailingPackTieBreaker(const TemplateSpecializationType *TST1, const TemplateSpecializationType *TST2)
Definition SemaTemplateDeduction.cpp:5828
static TemplateLikeDecl * getMoreSpecialized(Sema &S, QualType T1, QualType T2, TemplateLikeDecl *P1, PrimaryDel *P2, TemplateDeductionInfo &Info)
Returns the more specialized template specialization between T1/P1 and T2/P2.
Definition SemaTemplateDeduction.cpp:6337
static DeducedTemplateArgument checkDeducedTemplateArguments(ASTContext &Context, const DeducedTemplateArgument &X, const DeducedTemplateArgument &Y, bool AggregateCandidateDeduction=false)
Verify that the given, deduced template arguments are compatible.
Definition SemaTemplateDeduction.cpp:282
static const Expr * unwrapExpressionForDeduction(const Expr *E)
Definition SemaTemplateDeduction.cpp:150
static bool isSameDeclaration(Decl *X, Decl *Y)
Determine whether two declaration pointers refer to the same declaration.
Definition SemaTemplateDeduction.cpp:268
static NonTypeOrVarTemplateParmDecl getDeducedNTTParameterFromExpr(const Expr *E, unsigned Depth)
If the given expression is of a form that permits the deduction of a non-type template parameter,...
Definition SemaTemplateDeduction.cpp:241
static TemplateDeductionResult DeduceForEachType(Sema &S, TemplateParameterList *TemplateParams, ArrayRef< QualType > Params, ArrayRef< QualType > Args, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, PartialOrderingKind POK, bool FinishingDeduction, T &&DeductFunc)
Definition SemaTemplateDeduction.cpp:1204
static TemplateDeductionResult DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD, TemplateParameterList *TemplateParams, QualType P, TemplateDeductionInfo &Info, bool PartialOrdering, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool *HasDeducedAnyParam)
Attempt to deduce the template arguments by checking the base types according to (C++20 [temp....
Definition SemaTemplateDeduction.cpp:1470
static bool hasTemplateArgumentForDeduction(ArrayRef< TemplateArgument > &Args, unsigned &ArgIdx)
Determine whether there is a template argument to be used for deduction.
Definition SemaTemplateDeduction.cpp:2706
static DeclContext * getAsDeclContextOrEnclosing(Decl *D)
Definition SemaTemplateDeduction.cpp:3168
static bool hasInconsistentOrSupersetQualifiersOf(QualType ParamType, QualType ArgType)
Determine whether the parameter has qualifiers that the argument lacks.
Definition SemaTemplateDeduction.cpp:1381
static void MarkUsedTemplateParameters(ASTContext &Ctx, const TemplateArgument &TemplateArg, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark the template parameters that are used by this template argument.
Definition SemaTemplateDeduction.cpp:7092
static UnsignedOrNone getPackIndexForParam(Sema &S, FunctionTemplateDecl *FunctionTemplate, const MultiLevelTemplateArgumentList &Args, unsigned ParamIdx)
Find the pack index for a particular parameter index in an instantiation of a function template with ...
Definition SemaTemplateDeduction.cpp:3855
static QualType GetTypeOfFunction(Sema &S, const OverloadExpr::FindResult &R, FunctionDecl *Fn)
Gets the type of a function for template-argument-deducton purposes when it's considered as part of a...
Definition SemaTemplateDeduction.cpp:4123
static bool hasPackExpansionBeforeEnd(ArrayRef< TemplateArgument > Args)
Determine whether the given set of template arguments has a pack expansion that is not the last templ...
Definition SemaTemplateDeduction.cpp:2723
static bool isSimpleTemplateIdType(QualType T)
Determine whether the given type T is a simple-template-id type.
Definition SemaTemplateDeduction.cpp:3527
PartialOrderingKind
The kind of PartialOrdering we're performing template argument deduction for (C++11 [temp....
Definition SemaTemplateDeduction.cpp:120
@ None
Definition SemaTemplateDeduction.cpp:120
@ Call
Definition SemaTemplateDeduction.cpp:120
@ NonCall
Definition SemaTemplateDeduction.cpp:120
MoreSpecializedTrailingPackTieBreakerResult
Definition SemaTemplateDeduction.cpp:5823
@ Less
Definition SemaTemplateDeduction.cpp:5823
@ More
Definition SemaTemplateDeduction.cpp:5823
@ Equal
Definition SemaTemplateDeduction.cpp:5823
static TemplateParameter makeTemplateParameter(Decl *D)
Helper function to build a TemplateParameter when we don't know its type statically.
Definition SemaTemplateDeduction.cpp:824
static TemplateDeductionResult CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info, Sema::OriginalCallArg OriginalArg, QualType DeducedA)
Check whether the deduced argument type for a call to a function template matches the actual argument...
Definition SemaTemplateDeduction.cpp:3734
static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, QualType &ParamType, QualType &ArgType, Expr::Classification ArgClassification, Expr *Arg, unsigned &TDF, TemplateSpecCandidateSet *FailedTSC=nullptr)
Perform the adjustments to the parameter and argument types described in C++ [temp....
Definition SemaTemplateDeduction.cpp:4266
static TemplateDeductionResult DeduceTemplateArgumentsFromCallArgument(Sema &S, TemplateParameterList *TemplateParams, unsigned FirstInnerIndex, QualType ParamType, QualType ArgType, Expr::Classification ArgClassification, Expr *Arg, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, SmallVectorImpl< Sema::OriginalCallArg > &OriginalCallArgs, bool DecomposedParam, unsigned ArgIdx, unsigned TDF, TemplateSpecCandidateSet *FailedTSC=nullptr)
Perform template argument deduction per [temp.deduct.call] for a single parameter / argument pair.
Definition SemaTemplateDeduction.cpp:4448
static bool isAtLeastAsSpecializedAs(Sema &S, SourceLocation Loc, FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, TemplatePartialOrderingContext TPOC, ArrayRef< QualType > Args1, ArrayRef< QualType > Args2, bool Args1Offset)
Determine whether the function template FT1 is at least as specialized as FT2.
Definition SemaTemplateDeduction.cpp:5640
static QualType GetImplicitObjectParameterType(ASTContext &Context, const CXXMethodDecl *Method, QualType RawType, bool IsOtherRvr)
Definition SemaTemplateDeduction.cpp:5529
static TemplateDeductionResult DeduceFromInitializerList(Sema &S, TemplateParameterList *TemplateParams, QualType AdjustedParamType, InitListExpr *ILE, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, SmallVectorImpl< Sema::OriginalCallArg > &OriginalCallArgs, unsigned ArgIdx, unsigned TDF)
Attempt template argument deduction from an initializer list deemed to be an argument in a function c...
Definition SemaTemplateDeduction.cpp:4376
static unsigned getFirstInnerIndex(FunctionTemplateDecl *FTD)
Get the index of the first template parameter that was originally from the innermost template-paramet...
Definition SemaTemplateDeduction.cpp:1428
PackFold
What directions packs are allowed to match non-packs.
Definition SemaTemplateDeduction.cpp:130
@ Both
Definition SemaTemplateDeduction.cpp:130
@ ArgumentToParameter
Definition SemaTemplateDeduction.cpp:130
@ ParameterToArgument
Definition SemaTemplateDeduction.cpp:130
static TemplateDeductionResult ConvertDeducedTemplateArguments(Sema &S, NamedDecl *Template, TemplateParameterList *TemplateParams, bool IsDeduced, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info, Sema::CheckTemplateArgumentInfo &CTAI, LocalInstantiationScope *CurrentInstantiationScope, unsigned NumAlreadyConverted, bool *IsIncomplete)
Definition SemaTemplateDeduction.cpp:3036
static QualType ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, Expr *Arg, QualType ParamType, bool ParamWasReference, TemplateSpecCandidateSet *FailedTSC=nullptr)
Apply the deduction rules for overload sets.
Definition SemaTemplateDeduction.cpp:4150
static bool IsPossiblyOpaquelyQualifiedType(QualType T)
Determines whether the given type is an opaque type that might be more qualified when instantiated.
Definition SemaTemplateDeduction.cpp:817
static TemplateDeductionResult CheckDeducedArgumentConstraints(Sema &S, NamedDecl *Template, ArrayRef< TemplateArgument > SugaredDeducedArgs, ArrayRef< TemplateArgument > CanonicalDeducedArgs, TemplateDeductionInfo &Info)
Definition SemaTemplateDeduction.cpp:3187
static const TemplateSpecializationType * getLastTemplateSpecType(QualType QT)
Deduce the template arguments by comparing the template parameter type (which is a template-id) with ...
Definition SemaTemplateDeduction.cpp:674
static TemplateDeductionResult instantiateExplicitSpecifierDeferred(Sema &S, FunctionDecl *Specialization, const MultiLevelTemplateArgumentList &SubstArgs, TemplateDeductionInfo &Info, FunctionTemplateDecl *FunctionTemplate, ArrayRef< TemplateArgument > DeducedArgs)
Definition SemaTemplateDeduction.cpp:3880
static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, AutoTypeLoc TypeLoc, QualType Deduced)
Definition SemaTemplateDeduction.cpp:5143
static TemplateDeductionResult DeduceNonTypeTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, const NonTypeOrVarTemplateParmDecl NTTP, const DeducedTemplateArgument &NewDeduced, QualType ValueType, TemplateDeductionInfo &Info, bool PartialOrdering, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool *HasDeducedAnyParam)
Deduce the value of the given non-type template parameter as the given deduced template argument.
Definition SemaTemplateDeduction.cpp:467
static bool IsPossiblyOpaquelyQualifiedTypeInternal(const Type *T)
Definition SemaTemplateDeduction.cpp:789
static bool hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate, QualType T)
Definition SemaTemplateDeduction.cpp:7189
static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex)
Determine whether a type denotes a forwarding reference.
Definition SemaTemplateDeduction.cpp:1436
static TemplateDeductionResult FinishTemplateArgumentDeduction(Sema &S, NamedDecl *Entity, TemplateParameterList *EntityTPL, TemplateDecl *Template, bool PartialOrdering, ArrayRef< TemplateArgumentLoc > Ps, ArrayRef< TemplateArgument > As, SmallVectorImpl< DeducedTemplateArgument > &Deduced, TemplateDeductionInfo &Info, bool CopyDeducedArgs)
Complete template argument deduction.
Definition SemaTemplateDeduction.cpp:3236
static bool isParameterPack(Expr *PackExpression)
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
static QualType getPointeeType(const MemRegion *R)
Defines the clang::TemplateNameKind enum.
Defines the clang::TypeLoc interface and its subclasses.
Allows QualTypes to be sorted and hence used in maps and sets.
static const TemplateArgument & getArgument(const TemplateArgument &A)
C Language Family Type Representation.
SourceLocation getLocation() const
Definition SemaTemplateDeduction.cpp:225
QualType getType() const
Definition SemaTemplateDeduction.cpp:185
const TemplateTemplateParmDecl * getTemplate() const
Definition SemaTemplateDeduction.cpp:205
bool isExpandedParameterPack() const
Definition SemaTemplateDeduction.cpp:219
const NonTypeTemplateParmDecl * getNTTP() const
Definition SemaTemplateDeduction.cpp:209
unsigned getIndex() const
Definition SemaTemplateDeduction.cpp:199
NonTypeOrVarTemplateParmDecl(const NamedDecl *Template)
Definition SemaTemplateDeduction.cpp:175
TemplateParameter asTemplateParam() const
Definition SemaTemplateDeduction.cpp:213
unsigned getDepth() const
Definition SemaTemplateDeduction.cpp:193
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
unsigned getIntWidth(QualType T) const
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const IncompleteArrayType * getAsIncompleteArrayType(QualType T) const
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
const LangOptions & getLangOpts() const
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
LangAS getDefaultOpenCLPointeeAddrSpace()
Returns default address space based on OpenCL version and enabled features.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType UnsignedIntTy
QualType getMemberPointerType(QualType T, NestedNameSpecifier Qualifier, const CXXRecordDecl *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getAdjustedParameterType(QualType T) const
Perform adjustment on the parameter type of a function.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
bool hasSameTemplateName(const TemplateName &X, const TemplateName &Y, bool IgnoreDeduced=false) const
Determine whether the given template names refer to the same template.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
bool isSameTemplateArgument(const TemplateArgument &Arg1, const TemplateArgument &Arg2) const
Determine whether the given template arguments Arg1 and Arg2 are equivalent.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
TemplateName getDeducedTemplateName(TemplateName Underlying, DefaultArguments DefaultArgs) const
Represents a TemplateName which had some of its default arguments deduced.
const DependentSizedArrayType * getAsDependentSizedArrayType(QualType T) const
A fixed int type of a specified bitwidth.
Represents a C++ conversion function within a class.
QualType getConversionType() const
Returns the type that this conversion function is converting to.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this method.
The null pointer literal (C++11 [lex.nullptr])
Represents a C++ struct/union/class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Declaration of a class template.
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieve the canonical template specialization type of the injected-class-name for this class templat...
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieves the canonical injected specialization type for this partial specialization.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
Complex values, per C99 6.2.5p11.
Declaration of a C++20 concept.
const TypeClass * getTypePtr() const
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
A POD class for pairing a NamedDecl* with an access specifier.
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.
Decl - This represents one declaration (or definition), e.g.
TemplateDecl * getDescribedTemplate() const
If this is a declaration that describes some template, this method returns that template declaration.
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Captures a template argument whose value has been deduced via c++ template argument deduction.
void setDeducedFromArrayBound(bool Deduced)
Specify whether the given non-type template argument was deduced from an array bound.
bool wasDeducedFromArrayBound() const
For a non-type template argument, determine whether the template argument was deduced from an array b...
SourceLocation getElaboratedKeywordLoc() const
NestedNameSpecifierLoc getQualifierLoc() const
Represents an extended address space qualifier where the input address space value is dependent.
Expr * getAddrSpaceExpr() const
QualType getPointeeType() const
Represents an extended vector type where either the type or size is dependent.
Expr * getSizeExpr() const
QualType getElementType() const
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Expr * getColumnExpr() const
Expr * getRowExpr() const
Represents a vector type where either the type or size is dependent.
virtual bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc)
virtual bool TraverseTemplateName(TemplateName Template)
virtual bool TraverseType(QualType T, bool TraverseQualifier=true)
RAII object that enters a new expression evaluation context.
Store information needed for an explicit specifier.
bool isInvalid() const
Determine if the explicit specifier is invalid.
const Expr * getExpr() const
The return type of classify().
This represents one expression.
bool isValueDependent() const
Determines whether the value of this expression depends on.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
ExtVectorType - Extended vector type.
Stores a list of template parameters and the associated requires-clause (if any) for a TemplateDecl a...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
bool hasCXXExplicitFunctionObjectParameter() const
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const
Retrieve the function declaration from which this function could be instantiated, if it is an instant...
void getAssociatedConstraints(SmallVectorImpl< AssociatedConstraint > &ACs) const
Get the associated-constraints of this function declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isImmediateEscalating() const
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
size_t param_size() const
Represents a prototype with parameter type info, e.g.
param_type_iterator param_type_begin() const
const ExtParameterInfo * getExtParameterInfosOrNull() const
Return a pointer to the beginning of the array of extra parameter information, if present,...
unsigned getNumParams() const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Qualifiers getMethodQuals() const
QualType getParamType(unsigned i) const
bool hasExceptionSpec() const
Return whether this function has any kind of exception spec.
bool isVariadic() const
Whether this function prototype is variadic.
ExtProtoInfo getExtProtoInfo() const
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
param_type_iterator param_type_end() const
ArrayRef< QualType > getParamTypes() const
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Declaration of a template function.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
Describes an C or C++ initializer list.
unsigned getNumInits() const
unsigned getNumInitsWithEmbedExpanded() const
getNumInits but if the list has an EmbedExpr inside includes full length of embedded data.
ArrayRef< Expr * > inits()
An lvalue reference type, per C++11 [dcl.ref].
A stack-allocated class that identifies which local variable declaration instantiations are present i...
NamedDecl * getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs=nullptr, unsigned *NumExplicitArgs=nullptr) const
Retrieve the partially-substitued template parameter pack.
void ResetPartiallySubstitutedPack()
Reset the partially-substituted pack when it is no longer of interest.
Represents a matrix type, as defined in the Matrix Types clang extensions.
QualType getElementType() const
Returns type of the elements being stored in the matrix.
A pointer to member type per C++ 8.3.3 - Pointers to members.
NestedNameSpecifier getQualifier() const
QualType getPointeeType() const
Data structure that captures multiple levels of template argument lists for use in template instantia...
void addOuterRetainedLevels(unsigned Num)
void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final=false)
Replaces the current 'innermost' level with the provided argument list.
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Class that aids in the construction of nested-name-specifiers along with source-location information ...
Represents a C++ nested name specifier, such as "\::std::vector::".
const Type * getAsType() const
@ Type
A type, stored as a Type*.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Represents a pointer to an Objective C object.
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
bool isVarDeclReference() const
bool hasExplicitTemplateArgs() const
Determines whether this expression had explicit template arguments.
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
SourceLocation getNameLoc() const
Gets the location of the name.
decls_iterator decls_begin() const
TemplateTemplateParmDecl * getTemplateTemplateDecl() const
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const
Copies the template arguments into the given structure.
bool isConceptReference() const
decls_iterator decls_end() const
ArrayRef< TemplateArgumentLoc > template_arguments() const
Represents a C++11 pack expansion that produces a sequence of expressions.
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool hasQualifiers() const
Determine whether this type has any qualifiers.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
Represents a template name as written in source code.
The collection of all-type qualifiers we support.
unsigned getCVRQualifiers() const
void removeCVRQualifiers(unsigned mask)
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
void removeObjCLifetime()
bool isStrictSupersetOf(Qualifiers Other) const
Determine whether this set of qualifiers is a strict superset of another set of qualifiers,...
bool hasNonTrivialObjCLifetime() const
True if the lifetime is neither None or ExplicitNone.
bool compatiblyIncludes(Qualifiers other, const ASTContext &Ctx) const
Determines if these qualifiers compatibly include another set.
bool hasAddressSpace() const
void removeAddressSpace()
bool hasObjCGCAttr() const
void setCVRQualifiers(unsigned mask)
bool hasObjCLifetime() const
ObjCLifetime getObjCLifetime() const
Qualifiers withoutObjCLifetime() const
LangAS getAddressSpace() const
void setObjCLifetime(ObjCLifetime type)
An rvalue reference type, per C++11 [dcl.ref].
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
Base for LValueReferenceType and RValueReferenceType.
QualType getPointeeType() const
Scope - A scope is a transient data structure that is used while parsing the program.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
RAII object used to change the argument pack substitution index within a Sema object.
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
A helper class for building up ExtParameterInfos.
const FunctionProtoType::ExtParameterInfo * getPointerOrNull(unsigned numParams)
Return a pointer (suitable for setting in an ExtProtoInfo) to the ExtParameterInfo array we've built ...
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Sema - This implements semantic analysis and AST building for C.
bool TryFunctionConversion(QualType FromType, QualType ToType, QualType &ResultTy) const
Same as IsFunctionConversion, but if this would return true, it sets ResultTy to ToType.
QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement)
Substitute Replacement for auto in TypeWithAuto.
Definition SemaTemplateDeduction.cpp:5380
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.
Definition SemaTemplateDeduction.cpp:2869
TemplateDeductionResult DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType, sema::TemplateDeductionInfo &Info)
Deduce the template arguments of the given template from FromType.
Definition SemaTemplateDeduction.cpp:3473
QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement)
Completely replace the auto in TypeWithAuto by Replacement.
Definition SemaTemplateDeduction.cpp:5409
bool TemplateParameterListsAreEqual(const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc=SourceLocation())
Determine whether the given template parameter lists are equivalent.
ClassTemplatePartialSpecializationDecl * getMoreSpecializedPartialSpecialization(ClassTemplatePartialSpecializationDecl *PS1, ClassTemplatePartialSpecializationDecl *PS2, SourceLocation Loc)
Returns the more specialized class template partial specialization according to the rules of partial ...
Definition SemaTemplateDeduction.cpp:6419
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
FunctionDecl * getMoreConstrainedFunction(FunctionDecl *FD1, FunctionDecl *FD2)
Returns the more constrained function according to the rules of partial ordering by constraints (C++ ...
Definition SemaTemplateDeduction.cpp:6150
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 BuildStdInitializerList(QualType Element, SourceLocation Loc)
Looks for the std::initializer_list template and instantiates it with Element, or emits an error if i...
TemplateDeductionResult FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, SmallVectorImpl< DeducedTemplateArgument > &Deduced, unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, SmallVectorImpl< OriginalCallArg > const *OriginalCallArgs, bool PartialOverloading, bool PartialOrdering, bool ForOverloadSetAddressResolution, llvm::function_ref< bool(bool)> CheckNonDependent=[](bool) { return false;})
Finish template argument deduction for a function template, checking the deduced template arguments f...
Definition SemaTemplateDeduction.cpp:3922
@ CTAK_DeducedFromArrayBound
The template argument was deduced from an array bound via template argument deduction.
@ CTAK_Specified
The template argument was specified in the code or was instantiated with some deduced template argume...
@ CTAK_Deduced
The template argument was deduced via template argument deduction.
bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose=true)
Definition SemaTemplateDeduction.cpp:5439
bool IsQualificationConversion(QualType FromType, QualType ToType, bool CStyle, bool &ObjCLifetimeConversion)
IsQualificationConversion - Determines whether the conversion from an rvalue of type FromType to ToTy...
void MarkUsedTemplateParametersForSubsumptionParameterMapping(const Expr *E, unsigned Depth, llvm::SmallBitVector &Used)
Mark which template parameters are named in a given expression.
Definition SemaTemplateDeduction.cpp:7136
QualType BuildFunctionType(QualType T, MutableArrayRef< QualType > ParamTypes, SourceLocation Loc, DeclarationName Entity, const FunctionProtoType::ExtProtoInfo &EPI)
Build a function type.
ExprResult BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg, SourceLocation Loc)
ASTContext & getASTContext() const
UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd, TemplateSpecCandidateSet &FailedCandidates, SourceLocation Loc, const PartialDiagnostic &NoneDiag, const PartialDiagnostic &AmbigDiag, const PartialDiagnostic &CandidateDiag, bool Complain=true, QualType TargetType=QualType())
Retrieve the most specialized of the given function template specializations.
Definition SemaTemplateDeduction.cpp:6075
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.
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool isTemplateTemplateParameterAtLeastAsSpecializedAs(TemplateParameterList *PParam, TemplateDecl *PArg, TemplateDecl *AArg, const DefaultArguments &DefaultArgs, SourceLocation ArgLoc, bool PartialOrdering, bool *StrictPackMatch)
Definition SemaTemplateDeduction.cpp:6483
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
bool CheckConstraintSatisfaction(ConstrainedDeclOrNestedRequirement Entity, ArrayRef< AssociatedConstraint > AssociatedConstraints, const MultiLevelTemplateArgumentList &TemplateArgLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction, const ConceptReference *TopLevelConceptId=nullptr, Expr **ConvertedExpr=nullptr)
Check whether the given list of constraint expressions are satisfied (as if in a 'conjunction') given...
@ TPL_TemplateParamsEquivalent
We are determining whether the template-parameters are equivalent according to C++ [temp....
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.
bool isSameOrCompatibleFunctionType(QualType Param, QualType Arg)
Compare types for equality with respect to possibly compatible function types (noreturn adjustment,...
Definition SemaTemplateDeduction.cpp:1408
const LangOptions & getLangOpts() const
UnsignedOrNone getNumArgumentsInExpansion(QualType T, const MultiLevelTemplateArgumentList &TemplateArgs)
Determine the number of arguments in the given pack expansion type.
ExplicitSpecifier instantiateExplicitSpecifier(const MultiLevelTemplateArgumentList &TemplateArgs, ExplicitSpecifier ES)
TemplateDeductionResult SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate, TemplateArgumentListInfo &ExplicitTemplateArgs, SmallVectorImpl< DeducedTemplateArgument > &Deduced, SmallVectorImpl< QualType > &ParamTypes, QualType *FunctionType, sema::TemplateDeductionInfo &Info)
Substitute the explicitly-provided template arguments into the given function template according to C...
Definition SemaTemplateDeduction.cpp:3546
bool SubstParmTypes(SourceLocation Loc, ArrayRef< ParmVarDecl * > Params, const FunctionProtoType::ExtParameterInfo *ExtParamInfos, const MultiLevelTemplateArgumentList &TemplateArgs, SmallVectorImpl< QualType > &ParamTypes, SmallVectorImpl< ParmVarDecl * > *OutParams, ExtParameterInfoBuilder &ParamInfos)
Substitute the given template arguments into the given set of parameters, producing the set of parame...
FunctionDecl * resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &FoundResult)
Given an expression that refers to an overloaded function, try to resolve that function to a single f...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
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...
SuppressedDiagnosticsMap SuppressedDiagnostics
void DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, SourceLocation Loc={}, bool First=true)
Emit diagnostics explaining why a constraint expression was deemed unsatisfied.
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
FunctionDecl * ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain=false, DeclAccessPair *Found=nullptr, TemplateSpecCandidateSet *FailedTSC=nullptr, bool ForTypeDeduction=false)
Given an expression that refers to an overloaded function, try to resolve that overloaded function ex...
QualType getDecltypeForExpr(Expr *E)
getDecltypeForExpr - Given an expr, will return the decltype for that expression, according to the ru...
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Decl * SubstDecl(Decl *D, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs)
TemplateArgumentLoc SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc, SourceLocation RAngleLoc, Decl *Param, ArrayRef< TemplateArgument > SugaredConverted, ArrayRef< TemplateArgument > CanonicalConverted, bool &HasDefaultArg)
If the given template parameter has a default template argument, substitute into that default templat...
TypeSourceInfo * SubstAutoTypeSourceInfoDependent(TypeSourceInfo *TypeWithAuto)
Definition SemaTemplateDeduction.cpp:5402
TypeSourceInfo * ReplaceAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType Replacement)
Definition SemaTemplateDeduction.cpp:5416
bool isSFINAEContext() const
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
bool isStdInitializerList(QualType Ty, QualType *Element)
Tests whether Ty is an instance of std::initializer_list and, if it is and Element is not NULL,...
void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, FunctionDecl *Function, bool Recursive=false, bool DefinitionRequired=false, bool AtEndOfTU=false)
Instantiate the definition of the given function from its template.
void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark which template parameters are used in a given expression.
Definition SemaTemplateDeduction.cpp:7130
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
QualType getLambdaConversionFunctionResultType(const FunctionProtoType *CallOpType, CallingConv CC)
Get the return type to use for a lambda's conversion function(s) to function pointer type,...
QualType getCompletedType(Expr *E)
Get the type of expression E, triggering instantiation to complete the type if necessary – that is,...
TypeSourceInfo * SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType Replacement)
Substitute Replacement for auto in TypeWithAuto.
Definition SemaTemplateDeduction.cpp:5387
bool IsAtLeastAsConstrained(const NamedDecl *D1, MutableArrayRef< AssociatedConstraint > AC1, const NamedDecl *D2, MutableArrayRef< AssociatedConstraint > AC2, bool &Result)
Check whether the given declaration's associated constraints are at least as constrained than another...
void DiagnoseAutoDeductionFailure(const VarDecl *VDecl, const Expr *Init)
Definition SemaTemplateDeduction.cpp:5423
TemplateArgumentLoc getIdentityTemplateArgumentLoc(NamedDecl *Param, SourceLocation Location)
Get a template argument mapping the given template parameter to itself, e.g.
Definition SemaTemplateDeduction.cpp:2927
bool CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD, SourceLocation Loc)
Definition SemaTemplateDeduction.cpp:5502
QualType SubstAutoTypeDependent(QualType TypeWithAuto)
Definition SemaTemplateDeduction.cpp:5394
TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef< TemplateArgument > TemplateArgs, sema::TemplateDeductionInfo &Info)
Definition SemaTemplateDeduction.cpp:3460
bool CheckFunctionTemplateConstraints(SourceLocation PointOfInstantiation, FunctionDecl *Decl, ArrayRef< TemplateArgument > TemplateArgs, ConstraintSatisfaction &Satisfaction)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool isMoreSpecializedThanPrimary(ClassTemplatePartialSpecializationDecl *T, sema::TemplateDeductionInfo &Info)
Definition SemaTemplateDeduction.cpp:6430
bool IsFunctionConversion(QualType FromType, QualType ToType) const
Determine whether the conversion from FromType to ToType is a valid conversion of ExtInfo/ExtProtoInf...
std::string getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgumentList &Args)
Produces a formatted string that describes the binding of template parameters to template arguments.
bool CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, const DefaultArguments &DefaultArgs, bool PartialTemplateArgs, CheckTemplateArgumentInfo &CTAI, bool UpdateArgsWithConversions=true, bool *ConstraintsNotSatisfied=nullptr)
Check that the given template arguments can be provided to the given template, converting the argumen...
void adjustMemberFunctionCC(QualType &T, bool HasThisPointer, bool IsCtorOrDtor, SourceLocation Loc)
Adjust the calling convention of a method to be the ABI default if it wasn't specified explicitly.
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
ExprResult BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Given a non-type template argument that refers to a declaration and the type of its corresponding non...
TemplateDeductionResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *Initializer, QualType &Result, sema::TemplateDeductionInfo &Info, bool DependentDeduction=false, bool IgnoreConstraints=false, TemplateSpecCandidateSet *FailedTSC=nullptr)
Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
Definition SemaTemplateDeduction.cpp:5202
QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType, bool AdjustExceptionSpec=false)
Adjust the type ArgFunctionType to match the calling convention, noreturn, and optionally the excepti...
Definition SemaTemplateDeduction.cpp:4737
void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, QualType FromType, QualType ToType)
HandleFunctionTypeMismatch - Gives diagnostic information for differeing function types.
FunctionTemplateDecl * getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc, TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1, QualType RawObj1Ty={}, QualType RawObj2Ty={}, bool Reversed=false, bool PartialOverloading=false)
Returns the more specialized function template according to the rules of function template partial or...
Definition SemaTemplateDeduction.cpp:5854
void MarkDeducedTemplateParameters(const FunctionTemplateDecl *FunctionTemplate, llvm::SmallBitVector &Deduced)
NamedDecl * getPack() const
Retrieve the parameter pack.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
A convenient class for passing around template argument information.
void addArgument(const TemplateArgumentLoc &Loc)
A template argument list.
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Location wrapper for a TemplateArgument.
const TemplateArgument & getArgument() const
Represents a template argument.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
pack_iterator pack_end() const
Iterator referencing one past the last argument of a template argument pack.
const TemplateArgument * pack_iterator
Iterator that traverses the elements of a template argument pack.
pack_iterator pack_begin() const
Iterator referencing the first argument of a template argument pack.
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
Used to insert TemplateArguments into FoldingSets.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
static TemplateArgument CreatePackCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument pack by copying the given set of template arguments.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
TemplateArgument getPackExpansionPattern() const
When the template argument is a pack expansion, returns the pattern of the pack expansion.
bool isNull() const
Determine whether this template argument has no value.
static TemplateArgument getEmptyPack()
unsigned pack_size() const
The number of template arguments in the given template argument pack.
bool structurallyEquals(const TemplateArgument &Other) const
Determines whether two template arguments are superficially the same.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
bool isPackExpansion() const
Determine whether this template argument is a pack expansion.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
The base class of all kinds of template declarations (e.g., class, function, etc.).
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
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.
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)
Get the template argument list of the template parameter list.
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
SourceLocation getRAngleLoc() const
SourceLocation getLAngleLoc() const
ArrayRef< NamedDecl * > asArray()
SourceLocation getTemplateLoc() const
TemplateSpecCandidateSet - A set of generalized overload candidates, used in template specializations...
void NoteCandidates(Sema &S, SourceLocation Loc)
NoteCandidates - When no template specialization match is found, prints diagnostic messages containin...
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
TemplateNameKind templateParameterKind() const
unsigned getIndex() const
Get the index of the template parameter within its parameter list.
unsigned getDepth() const
Get the nesting depth of the template parameter.
bool isExpandedParameterPack() const
Whether this parameter is a template template parameter pack that has a known list of different templ...
Declaration of a template type parameter.
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)
A semantic tree transformation that allows one to transform one abstract syntax tree into another.
const Type * getTypeForDecl() const
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
void reserve(size_t Requested)
Ensures that this buffer has at least as much capacity as described.
Base wrapper for a particular "section" of type source info.
SourceRange getLocalSourceRange() const
Get the local source range.
unsigned getFullDataSize() const
Returns the size of the type source info data block.
void copy(TypeLoc other)
Copies the other type loc into this one.
A container of type source information.
QualType getType() const
Return the type wrapped by this type source info.
SourceLocation getNameLoc() const
void setNameLoc(SourceLocation Loc)
The base class of the type hierarchy.
const TemplateSpecializationType * getAsNonAliasTemplateSpecializationType() const
Look through sugar for an instance of TemplateSpecializationType which is not a type alias,...
bool isPlaceholderType() const
Test for a type which does not represent an actual type-system type but is instead used as a placehol...
bool isRValueReferenceType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isFunctionPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isLValueReferenceType() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
QualType getCanonicalTypeInternal() const
bool isMemberPointerType() const
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isFunctionType() const
bool isMemberFunctionPointerType() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs'.
bool isRecordType() const
The iterator over UnresolvedSets.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
Declaration of a variable template.
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
Represents a GCC generic vector type.
Provides information about an attempted template argument deduction, whose success or failure was des...
void setExplicitArgs(TemplateArgumentList *NewDeducedSugared, TemplateArgumentList *NewDeducedCanonical)
Provide an initial template argument list that contains the explicitly-specified arguments.
TemplateArgumentList * takeCanonical()
TemplateArgumentList * takeSugared()
Take ownership of the deduced template argument lists.
SourceLocation getLocation() const
Returns the location at which template argument is occurring.
void clearSFINAEDiagnostic()
Discard any SFINAE diagnostics.
TemplateArgument SecondArg
The second template argument to which the template argument deduction failure refers.
void setStrictPackMatch()
TemplateParameter Param
The template parameter to which a template argument deduction failure refers.
diag_iterator diag_end() const
Returns an iterator at the end of the sequence of suppressed diagnostics.
void reset(TemplateArgumentList *NewDeducedSugared, TemplateArgumentList *NewDeducedCanonical)
Provide a new template argument list that contains the results of template argument deduction.
unsigned getDeducedDepth() const
The depth of template parameters for which deduction is being performed.
diag_iterator diag_begin() const
Returns an iterator at the beginning of the sequence of suppressed diagnostics.
TemplateArgument FirstArg
The first template argument to which the template argument deduction failure refers.
ConstraintSatisfaction AssociatedConstraintsSatisfaction
The constraint satisfaction details resulting from the associated constraints satisfaction tests.
unsigned CallArgIndex
The index of the function argument that caused a deduction failure.
bool hasStrictPackMatch() const
__inline void unsigned int _2
The JSON file list parser is used to communicate input to InstallAPI.
@ OO_None
Not an overloaded operator.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
bool isTargetAddressSpace(LangAS AS)
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
@ Both
Look for allocation functions in both the global scope and in the scope of the allocated class.
@ RQ_None
No ref-qualifier was provided.
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
NamedDecl * getAsNamedDecl(TemplateParameter P)
bool isPackProducingBuiltinTemplateName(TemplateName N)
UnsignedOrNone getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
unsigned toTargetAddressSpace(LangAS AS)
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ 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.
ActionResult< CXXBaseSpecifier * > BaseResult
@ FunctionTemplate
The name was classified as a function template name.
@ Concept
The name was classified as a concept name.
bool isLambdaConversionOperator(CXXConversionDecl *C)
@ TNK_Var_template
The name refers to a variable template whose specialization produces a variable.
@ TNK_Concept_template
The name refers to a concept.
llvm::PointerUnion< TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, TemplateTemplateParmDecl * > TemplateParameter
Stores a template parameter of any kind.
TPOC
The context in which partial ordering of function templates occurs.
@ TPOC_Conversion
Partial ordering of function templates for a call to a conversion function.
@ TPOC_Other
Partial ordering of function templates in other contexts, e.g., taking the address of a function temp...
@ TPOC_Call
Partial ordering of function templates for a function call.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
TemplateDeductionResult
Describes the result of template argument deduction.
@ MiscellaneousDeductionFailure
Deduction failed; that's all we know.
@ NonDependentConversionFailure
Checking non-dependent argument conversions failed.
@ ConstraintsNotSatisfied
The deduced arguments did not satisfy the constraints associated with the template.
@ Underqualified
Template argument deduction failed due to inconsistent cv-qualifiers on a template parameter type tha...
@ InstantiationDepth
Template argument deduction exceeded the maximum template instantiation depth (which has already been...
@ InvalidExplicitArguments
The explicitly-specified template arguments were not valid template arguments for the given template.
@ CUDATargetMismatch
CUDA Target attributes do not match.
@ TooFewArguments
When performing template argument deduction for a function template, there were too few call argument...
@ Incomplete
Template argument deduction did not deduce a value for every template parameter.
@ Invalid
The declaration was invalid; do nothing.
@ Success
Template argument deduction was successful.
@ SubstitutionFailure
Substitution of the deduced template argument values resulted in an error.
@ IncompletePack
Template argument deduction did not deduce a value for every expansion of an expanded template parame...
@ DeducedMismatch
After substituting deduced template arguments, a dependent parameter type did not match the correspon...
@ Inconsistent
Template argument deduction produced inconsistent deduced values for the given template parameter.
@ TooManyArguments
When performing template argument deduction for a function template, there were too many call argumen...
@ AlreadyDiagnosed
Some error which was already diagnosed.
@ DeducedMismatchNested
After substituting deduced template arguments, an element of a dependent parameter type did not match...
@ NonDeducedMismatch
A non-depnedent component of the parameter did not match the corresponding component of the argument.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
@ Noexcept
Condition in a noexcept(bool) specifier.
@ None
No keyword precedes the qualified type name.
ActionResult< Expr * > ExprResult
@ EST_Uninstantiated
not instantiated yet
@ EST_None
no exception specification
TemplateDeductionFlags
Various flags that control template argument deduction.
Definition SemaTemplateDeduction.cpp:70
@ TDF_None
No template argument deduction flags, which indicates the strictest results for template argument ded...
Definition SemaTemplateDeduction.cpp:74
@ TDF_DerivedClass
Within template argument deduction from a function call, we are matching in a case where we can perfo...
Definition SemaTemplateDeduction.cpp:88
@ TDF_TopLevelParameterTypeList
Whether we are performing template argument deduction for parameters and arguments in a top-level tem...
Definition SemaTemplateDeduction.cpp:97
@ TDF_IgnoreQualifiers
Within template argument deduction from a function call, we are matching in a case where we ignore cv...
Definition SemaTemplateDeduction.cpp:83
@ TDF_ParamWithReferenceType
Within template argument deduction from a function call, we are matching with a parameter type for wh...
Definition SemaTemplateDeduction.cpp:79
@ TDF_SkipNonDependent
Allow non-dependent types to differ, e.g., when performing template argument deduction from a functio...
Definition SemaTemplateDeduction.cpp:93
@ TDF_AllowCompatibleFunctionType
Within template argument deduction from overload resolution per C++ [over.over] allow matching functi...
Definition SemaTemplateDeduction.cpp:106
@ TDF_ArgWithReferenceType
Within template argument deduction for a conversion function, we are matching with an argument type f...
Definition SemaTemplateDeduction.cpp:111
static constexpr bool value
Definition SemaTemplateDeduction.cpp:3179
static constexpr bool value
Definition SemaTemplateDeduction.cpp:3183
static constexpr bool value
Definition SemaTemplateDeduction.cpp:3175
A pack that we're currently deducing.
Definition SemaTemplateDeduction.cpp:834
DeducedPack(unsigned Index)
Definition SemaTemplateDeduction.cpp:851
DeducedPack * Outer
Definition SemaTemplateDeduction.cpp:849
unsigned Index
Definition SemaTemplateDeduction.cpp:836
SmallVector< DeducedTemplateArgument, 4 > New
Definition SemaTemplateDeduction.cpp:846
DeducedTemplateArgument Saved
Definition SemaTemplateDeduction.cpp:839
DeducedTemplateArgument DeferredDeduction
Definition SemaTemplateDeduction.cpp:843
ExceptionSpecificationType Type
The kind of exception specification this is.
Extra information about a function prototype.
const ExtParameterInfo * ExtParameterInfos
bool HasFormOfMemberPointer
OverloadExpr * Expression
bool StrictPackMatch
Is set to true when, in the context of TTP matching, a pack parameter matches non-pack arguments.
bool MatchingTTP
If true, assume these template arguments are the injected template arguments for a template template ...
bool PartialOrdering
The check is being performed in the context of partial ordering.
SmallVector< TemplateArgument, 4 > SugaredConverted
The checked, converted argument will be added to the end of these vectors.
SmallVector< TemplateArgument, 4 > CanonicalConverted
@ ExplicitTemplateArgumentSubstitution
We are substituting explicit template arguments provided for a function template.
@ DeducedTemplateArgumentSubstitution
We are substituting template argument determined as part of template argument deduction for either a ...
bool isPotentiallyEvaluated() const
A stack object to be created when performing template instantiation.
bool isInvalid() const
Determines whether we have exceeded the maximum recursive template instantiations.
brief A function argument from which we performed template argument
QualType OriginalParamType
Location information for a TemplateArgument.