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(X.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 (Result.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(X.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 : Context.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(Result.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(Result.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 (Type.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 (Result.isNull()) {

5346 if (Context.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(Reversed && "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 (Context.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 (Context.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 (T->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 (T->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.