clang: lib/Sema/SemaTemplateInstantiate.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

38#include "llvm/ADT/SmallVectorExtras.h"

39#include "llvm/ADT/StringExtras.h"

40#include "llvm/Support/ErrorHandling.h"

41#include "llvm/Support/SaveAndRestore.h"

42#include "llvm/Support/TimeProfiler.h"

43#include

44

45using namespace clang;

46using namespace sema;

47

48

49

50

51

52namespace {

54struct Response {

55 const Decl *NextDecl = nullptr;

56 bool IsDone = false;

57 bool ClearRelativeToPrimary = true;

58 static Response Done() {

59 Response R;

60 R.IsDone = true;

61 return R;

62 }

63 static Response ChangeDecl(const Decl *ND) {

64 Response R;

65 R.NextDecl = ND;

66 return R;

67 }

68 static Response ChangeDecl(const DeclContext *Ctx) {

69 Response R;

71 return R;

72 }

73

74 static Response UseNextDecl(const Decl *CurDecl) {

76 }

77

78 static Response DontClearRelativeToPrimaryNextDecl(const Decl *CurDecl) {

79 Response R = Response::UseNextDecl(CurDecl);

80 R.ClearRelativeToPrimary = false;

81 return R;

82 }

83};

84

85

86

87

89getPrimaryTemplateOfGenericLambda(const FunctionDecl *LambdaCallOperator) {

91 return LambdaCallOperator;

92 while (true) {

93 if (auto *FTD = dyn_cast_if_present(

95 FTD && FTD->getInstantiatedFromMemberTemplate()) {

96 LambdaCallOperator =

97 FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();

99

100

101 LambdaCallOperator =

104 ->getInstantiatedFromMemberFunction())

105 LambdaCallOperator = Prev;

106 else

107 break;

108 }

109 return LambdaCallOperator;

110}

111

112struct EnclosingTypeAliasTemplateDetails {

116

117 explicit operator bool() noexcept { return Template; }

118};

119

120

121

122EnclosingTypeAliasTemplateDetails

123getEnclosingTypeAliasTemplateDecl(Sema &SemaRef) {

126 TypeAliasTemplateInstantiation)

127 continue;

128 EnclosingTypeAliasTemplateDetails Result;

130 *Next = TATD->getInstantiatedFromMemberTemplate();

131 Result = {

132 TATD,

133 TATD,

134 CSC.template_arguments(),

135 };

136 while (Next) {

137 Result.PrimaryTypeAliasDecl = Next;

138 Next = Next->getInstantiatedFromMemberTemplate();

139 }

140 return Result;

141 }

142 return {};

143}

144

145

146

147

148

149

150

151bool isLambdaEnclosedByTypeAliasDecl(

155 Visitor(const FunctionDecl *CallOperator) : CallOperator(CallOperator) {}

156 bool VisitLambdaExpr(LambdaExpr *LE) override {

157

158

159 return getPrimaryTemplateOfGenericLambda(LE->getCallOperator()) !=

160 CallOperator;

161 }

163 };

164

167

168 return !Visitor(getPrimaryTemplateOfGenericLambda(LambdaCallOperator))

169 .TraverseType(Underlying);

170}

171

172

173Response

176 bool SkipForSpecialization) {

177

178

180 return Response::DontClearRelativeToPrimaryNextDecl(VarTemplSpec);

181

182

185 return Response::Done();

186

187

188

190 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>

193 dyn_cast<VarTemplatePartialSpecializationDecl *>(Specialized)) {

194 if (!SkipForSpecialization)

195 Result.addOuterTemplateArguments(

197 false);

198 if (Partial->isMemberSpecialization())

199 return Response::Done();

200 } else {

202 if (!SkipForSpecialization)

203 Result.addOuterTemplateArguments(

205 false);

207 return Response::Done();

208 }

209 return Response::DontClearRelativeToPrimaryNextDecl(VarTemplSpec);

210}

211

212

213

214

215

216

217

218Response

221 for (unsigned I = 0, N = TTP->getDepth() + 1; I != N; ++I)

222 Result.addOuterTemplateArguments(std::nullopt);

223 return Response::Done();

224}

225

226Response HandlePartialClassTemplateSpec(

229 if (!SkipForSpecialization)

230 Result.addOuterRetainedLevels(PartialClassTemplSpec->getTemplateDepth());

231 return Response::Done();

232}

233

234

235Response

238 bool SkipForSpecialization) {

240

243 return Response::Done();

244

245 if (!SkipForSpecialization)

246 Result.addOuterTemplateArguments(

249 false);

250

251

252

255 return Response::Done();

256

257

258

259

260

261 if (auto *InstFromPartialTempl =

264 return Response::ChangeDecl(

265 InstFromPartialTempl->getLexicalDeclContext());

266 }

267 return Response::UseNextDecl(ClassTemplSpec);

268}

269

270Response HandleFunction(Sema &SemaRef, const FunctionDecl *Function,

272 const FunctionDecl *Pattern, bool RelativeToPrimary,

273 bool ForConstraintInstantiation,

274 bool ForDefaultArgumentSubstitution) {

275

276 if (!RelativeToPrimary &&

277 Function->getTemplateSpecializationKindForInstantiation() ==

279 return Response::Done();

280

281 if (!RelativeToPrimary &&

283

284

285

286 return Response::UseNextDecl(Function);

288 Function->getTemplateSpecializationArgs()) {

289

290 Result.addOuterTemplateArguments(const_cast<FunctionDecl *>(Function),

291 TemplateArgs->asArray(),

292 false);

293

294 if (RelativeToPrimary &&

295 (Function->getTemplateSpecializationKind() ==

297 (Function->getFriendObjectKind() &&

298 !Function->getPrimaryTemplate()->getFriendObjectKind())))

299 return Response::UseNextDecl(Function);

300

301

302

303 assert(Function->getPrimaryTemplate() && "No function template?");

304 if (!ForDefaultArgumentSubstitution &&

305 Function->getPrimaryTemplate()->isMemberSpecialization())

306 return Response::Done();

307

308

309 if (!ForConstraintInstantiation &&

311 return Response::Done();

312

313 } else if (auto *Template = Function->getDescribedFunctionTemplate()) {

314 assert(

315 (ForConstraintInstantiation || Result.getNumSubstitutedLevels() == 0) &&

316 "Outer template not instantiated?");

317 if (ForConstraintInstantiation) {

321

322

323

324

325 Result.addOuterTemplateArguments(Template, Inst.template_arguments(),

326 false);

327 break;

328 }

329 }

330 }

331 }

332

333

334

335

336 if ((Function->getFriendObjectKind() || Function->isLocalExternDecl()) &&

337 Function->getNonTransparentDeclContext()->isFileContext() &&

339 return Response::ChangeDecl(Function->getLexicalDeclContext());

340 }

341

342 if (ForConstraintInstantiation && Function->getFriendObjectKind())

343 return Response::ChangeDecl(Function->getLexicalDeclContext());

344 return Response::UseNextDecl(Function);

345}

346

347Response HandleFunctionTemplateDecl(Sema &SemaRef,

351 Result.addOuterTemplateArguments(

355 false);

356

358

361 : nullptr,

362 *NextTy = nullptr;

364 Ty = std::exchange(NextTy, nullptr)) {

367 NextTy = P.getAsType();

368 const auto *TSTy = dyn_cast(Ty);

369 if (!TSTy)

370 continue;

371

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390 if (TSTy->isCurrentInstantiation()) {

391 auto *RD = TSTy->getCanonicalTypeInternal()->getAsCXXRecordDecl();

393 Arguments = CTD->getInjectedTemplateArgs(SemaRef.Context);

395 dyn_cast(RD))

396 Arguments = Specialization->getTemplateInstantiationArgs().asArray();

397 }

398 Result.addOuterTemplateArguments(

399 TSTy->getTemplateName().getAsTemplateDecl(), Arguments,

400 false);

401 }

402 }

403

405}

406

407Response HandleRecordDecl(Sema &SemaRef, const CXXRecordDecl *Rec,

410 bool ForConstraintInstantiation) {

412 assert(

413 (ForConstraintInstantiation || Result.getNumSubstitutedLevels() == 0) &&

414 "Outer template not instantiated?");

415 if (ClassTemplate->isMemberSpecialization())

416 return Response::Done();

417 if (ForConstraintInstantiation)

418 Result.addOuterTemplateArguments(

420 ClassTemplate->getInjectedTemplateArgs(SemaRef.Context),

421 false);

422 }

423

427 return Response::Done();

428

432 if (ForConstraintInstantiation && IsFriend &&

435 }

436

437

438

441 return Response::ChangeDecl(LCD);

442

443

444

445 if (auto TypeAlias = getEnclosingTypeAliasTemplateDecl(SemaRef);

446 ForConstraintInstantiation && TypeAlias) {

448 TypeAlias.PrimaryTypeAliasDecl)) {

449 Result.addOuterTemplateArguments(TypeAlias.Template,

450 TypeAlias.AssociatedTemplateArguments,

451 false);

452

453

454

455

456

457

458

459

460

461

462

463

464

465 return Response::ChangeDecl(TypeAlias.Template->getDeclContext());

466 }

467 }

468 }

469

470 return Response::UseNextDecl(Rec);

471}

472

473Response HandleImplicitConceptSpecializationDecl(

476 Result.addOuterTemplateArguments(

479 false);

480 return Response::UseNextDecl(CSD);

481}

482

483Response HandleGenericDeclContext(const Decl *CurDecl) {

484 return Response::UseNextDecl(CurDecl);

485}

486}

487}

488

492 const FunctionDecl *Pattern, bool ForConstraintInstantiation,

493 bool SkipForSpecialization, bool ForDefaultArgumentSubstitution) {

494 assert((ND || DC) && "Can't find arguments for a decl if one isn't provided");

495

497

499 const Decl *CurDecl = ND;

500

501 if (Innermost) {

502 Result.addOuterTemplateArguments(const_cast<NamedDecl *>(ND), *Innermost,

503 Final);

504

505

506

507

508

509

510

511

512 if (const auto *TTP = dyn_cast(CurDecl))

513 HandleDefaultTempArgIntoTempTempParam(TTP, Result);

515 : Response::UseNextDecl(CurDecl).NextDecl;

516 } else if (!CurDecl)

518

520 Response R;

521 if (const auto *VarTemplSpec =

522 dyn_cast(CurDecl)) {

523 R = HandleVarTemplateSpec(VarTemplSpec, Result, SkipForSpecialization);

524 } else if (const auto *PartialClassTemplSpec =

525 dyn_cast(CurDecl)) {

526 R = HandlePartialClassTemplateSpec(PartialClassTemplSpec, Result,

527 SkipForSpecialization);

528 } else if (const auto *ClassTemplSpec =

529 dyn_cast(CurDecl)) {

530 R = HandleClassTemplateSpec(ClassTemplSpec, Result,

531 SkipForSpecialization);

532 } else if (const auto *Function = dyn_cast(CurDecl)) {

533 R = HandleFunction(*this, Function, Result, Pattern, RelativeToPrimary,

534 ForConstraintInstantiation,

535 ForDefaultArgumentSubstitution);

536 } else if (const auto *Rec = dyn_cast(CurDecl)) {

537 R = HandleRecordDecl(*this, Rec, Result, Context,

538 ForConstraintInstantiation);

539 } else if (const auto *CSD =

540 dyn_cast(CurDecl)) {

541 R = HandleImplicitConceptSpecializationDecl(CSD, Result);

542 } else if (const auto *FTD = dyn_cast(CurDecl)) {

543 R = HandleFunctionTemplateDecl(*this, FTD, Result);

544 } else if (const auto *CTD = dyn_cast(CurDecl)) {

545 R = Response::ChangeDecl(CTD->getLexicalDeclContext());

547 R = Response::DontClearRelativeToPrimaryNextDecl(CurDecl);

548 if (const auto *TTP = dyn_cast(CurDecl)) {

549 R = HandleDefaultTempArgIntoTempTempParam(TTP, Result);

550 }

551 } else {

552 R = HandleGenericDeclContext(CurDecl);

553 }

554

555 if (R.IsDone)

557 if (R.ClearRelativeToPrimary)

558 RelativeToPrimary = false;

559 assert(R.NextDecl);

560 CurDecl = R.NextDecl;

561 }

563}

564

566 switch (Kind) {

576 return true;

577

596 return false;

597

598

600 break;

601 }

602

603 llvm_unreachable("Invalid SynthesisKind!");

604}

605

611

612

613

614 if (SemaRef.Diags.hasFatalErrorOccurred() &&

615 SemaRef.hasUncompilableErrorOccurred()) {

616 Invalid = true;

617 return;

618 }

619

621 Inst.Kind = Kind;

623 Inst.Entity = Entity;

628 Inst.InConstraintSubstitution =

630 Inst.InParameterMappingSubstitution =

632 if (SemaRef.CodeSynthesisContexts.empty()) {

633 Inst.InConstraintSubstitution |=

634 SemaRef.CodeSynthesisContexts.back().InConstraintSubstitution;

635 Inst.InParameterMappingSubstitution |=

636 SemaRef.CodeSynthesisContexts.back().InParameterMappingSubstitution;

637 }

638

642}

643

649 PointOfInstantiation, InstantiationRange, Entity) {}

650

656 PointOfInstantiation, InstantiationRange, Entity) {}

657

663 SemaRef,

665 PointOfInstantiation, InstantiationRange, getAsNamedDecl(Param),

667

680

686 PointOfInstantiation, InstantiationRange, Template, nullptr,

687 TemplateArgs) {}

688

695 PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,

696 TemplateArgs) {}

697

704 PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,

705 TemplateArgs) {}

706

711 SemaRef,

713 PointOfInstantiation, InstantiationRange, Param, nullptr,

714 TemplateArgs) {}

715

721 SemaRef,

723 PointOfInstantiation, InstantiationRange, Param, Template,

724 TemplateArgs) {}

725

731 SemaRef,

733 PointOfInstantiation, InstantiationRange, Param, Template,

734 TemplateArgs) {}

735

742 PointOfInstantiation, InstantiationRange, Entity,

743 nullptr, TemplateArgs) {}

744

751 PointOfInstantiation, InstantiationRange, Param, Template,

752 TemplateArgs) {}

753

759 PointOfInstantiation, InstantiationRange, nullptr,

760 nullptr, {}) {}

761

768 PointOfInstantiation, InstantiationRange, nullptr,

769 nullptr, {}) {}

770

776 PointOfInstantiation, InstantiationRange, nullptr,

777 nullptr, {}) {}

778

785 PointOfInstantiation, InstantiationRange, Template, nullptr,

786 TemplateArgs) {}

787

794

801 PointOfInstantiation, InstantiationRange, Template) {}

802

809 PointOfInstantiation, InstantiationRange, Template) {}

810

816 PointOfInstantiation, InstantiationRange, Entity) {}

817

822 ArgLoc, InstantiationRange, PArg) {}

823

827 } else {

828 assert(SemaRef.NonInstantiationEntries <=

829 SemaRef.CodeSynthesisContexts.size());

830 if ((SemaRef.CodeSynthesisContexts.size() -

831 SemaRef.NonInstantiationEntries) >

832 SemaRef.getLangOpts().InstantiationDepth) {

834 diag::err_template_recursion_depth_exceeded)

837 diag::note_template_recursion_depth)

838 << SemaRef.getLangOpts().InstantiationDepth;

839 return true;

840 }

841 }

842

844

845

846

848 return false;

849}

850

853 if (!Active.isInstantiationRecord()) {

856 }

857

858

861 "forgot to remove a lookup module for a template instantiation");

867 }

868

869

870

874

876}

877

879 if (!Invalid) {

880 atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef,

881 SemaRef.CodeSynthesisContexts.back());

882

883 SemaRef.popCodeSynthesisContext();

884 Invalid = true;

885 }

886}

887

890 std::string Result;

891 llvm::raw_string_ostream OS(Result);

892 llvm::ListSeparator Comma;

893 for (const Expr *Arg : Args) {

894 OS << Comma;

895 Arg->IgnoreParens()->printPretty(OS, nullptr,

897 }

898 return Result;

899}

900

902

904 unsigned Limit = Diags.getTemplateBacktraceLimit();

906 SkipStart = Limit / 2 + Limit % 2;

908 }

909

910

911 unsigned InstantiationIdx = 0;

915 Active != ActiveEnd;

916 ++Active, ++InstantiationIdx) {

917

918 if (InstantiationIdx >= SkipStart && InstantiationIdx < SkipEnd) {

919 if (InstantiationIdx == SkipStart) {

920

921 DiagFunc(Active->PointOfInstantiation,

922 PDiag(diag::note_instantiation_contexts_suppressed)

924 }

925 continue;

926 }

927

928 switch (Active->Kind) {

930 Decl *D = Active->Entity;

932 unsigned DiagID = diag::note_template_member_class_here;

934 DiagID = diag::note_template_class_instantiation_here;

935 DiagFunc(Active->PointOfInstantiation,

936 PDiag(DiagID) << Record << Active->InstantiationRange);

938 unsigned DiagID;

939 if (Function->getPrimaryTemplate())

940 DiagID = diag::note_function_template_spec_here;

941 else

942 DiagID = diag::note_template_member_function_here;

943 DiagFunc(Active->PointOfInstantiation,

944 PDiag(DiagID) << Function << Active->InstantiationRange);

945 } else if (VarDecl *VD = dyn_cast(D)) {

946 DiagFunc(Active->PointOfInstantiation,

947 PDiag(VD->isStaticDataMember()

948 ? diag::note_template_static_data_member_def_here

949 : diag::note_template_variable_def_here)

950 << VD << Active->InstantiationRange);

951 } else if (EnumDecl *ED = dyn_cast(D)) {

952 DiagFunc(Active->PointOfInstantiation,

953 PDiag(diag::note_template_enum_def_here)

954 << ED << Active->InstantiationRange);

955 } else if (FieldDecl *FD = dyn_cast(D)) {

956 DiagFunc(Active->PointOfInstantiation,

957 PDiag(diag::note_template_nsdmi_here)

958 << FD << Active->InstantiationRange);

959 } else if (ClassTemplateDecl *CTD = dyn_cast(D)) {

960 DiagFunc(Active->PointOfInstantiation,

961 PDiag(diag::note_template_class_instantiation_here)

962 << CTD << Active->InstantiationRange);

963 }

964 break;

965 }

966

970 llvm::raw_svector_ostream OS(TemplateArgsStr);

972 printTemplateArgumentList(OS, Active->template_arguments(),

974 DiagFunc(Active->PointOfInstantiation,

975 PDiag(diag::note_default_arg_instantiation_here)

976 << OS.str() << Active->InstantiationRange);

977 break;

978 }

979

982 DiagFunc(Active->PointOfInstantiation,

983 PDiag(diag::note_explicit_template_arg_substitution_here)

984 << FnTmpl

987 Active->NumTemplateArgs)

988 << Active->InstantiationRange);

989 break;

990 }

991

994 dyn_cast(Active->Entity)) {

995 DiagFunc(

996 Active->PointOfInstantiation,

997 PDiag(diag::note_function_template_deduction_instantiation_here)

998 << FnTmpl

1000 FnTmpl->getTemplateParameters(), Active->TemplateArgs,

1001 Active->NumTemplateArgs)

1002 << Active->InstantiationRange);

1003 } else {

1006 bool IsTemplate = false;

1008 if (auto *D = dyn_cast(Active->Entity)) {

1009 IsTemplate = true;

1010 Params = D->getTemplateParameters();

1011 } else if (auto *D = dyn_cast(

1012 Active->Entity)) {

1013 Params = D->getTemplateParameters();

1014 } else if (auto *D = dyn_cast(

1015 Active->Entity)) {

1016 Params = D->getTemplateParameters();

1017 } else {

1018 llvm_unreachable("unexpected template kind");

1019 }

1020

1021 DiagFunc(Active->PointOfInstantiation,

1022 PDiag(diag::note_deduced_template_arg_substitution_here)

1023 << IsVar << IsTemplate << cast(Active->Entity)

1025 Active->TemplateArgs,

1026 Active->NumTemplateArgs)

1027 << Active->InstantiationRange);

1028 }

1029 break;

1030 }

1031

1035

1037 llvm::raw_svector_ostream OS(TemplateArgsStr);

1039 printTemplateArgumentList(OS, Active->template_arguments(),

1041 DiagFunc(Active->PointOfInstantiation,

1042 PDiag(diag::note_default_function_arg_instantiation_here)

1043 << OS.str() << Active->InstantiationRange);

1044 break;

1045 }

1046

1049 std::string Name;

1050 if (!Parm->getName().empty())

1051 Name = std::string(" '") + Parm->getName().str() + "'";

1052

1055 TemplateParams = Template->getTemplateParameters();

1056 else

1057 TemplateParams =

1059 ->getTemplateParameters();

1060 DiagFunc(Active->PointOfInstantiation,

1061 PDiag(diag::note_prior_template_arg_substitution)

1064 Active->TemplateArgs,

1065 Active->NumTemplateArgs)

1066 << Active->InstantiationRange);

1067 break;

1068 }

1069

1073 TemplateParams = Template->getTemplateParameters();

1074 else

1075 TemplateParams =

1077 ->getTemplateParameters();

1078

1079 DiagFunc(Active->PointOfInstantiation,

1080 PDiag(diag::note_template_default_arg_checking)

1082 Active->TemplateArgs,

1083 Active->NumTemplateArgs)

1084 << Active->InstantiationRange);

1085 break;

1086 }

1087

1089 DiagFunc(Active->PointOfInstantiation,

1090 PDiag(diag::note_evaluating_exception_spec_here)

1092 break;

1093

1095 DiagFunc(Active->PointOfInstantiation,

1096 PDiag(diag::note_template_exception_spec_instantiation_here)

1098 << Active->InstantiationRange);

1099 break;

1100

1102 DiagFunc(Active->PointOfInstantiation,

1103 PDiag(diag::note_template_requirement_instantiation_here)

1104 << Active->InstantiationRange);

1105 break;

1107 DiagFunc(Active->PointOfInstantiation,

1108 PDiag(diag::note_template_requirement_params_instantiation_here)

1109 << Active->InstantiationRange);

1110 break;

1111

1113 DiagFunc(Active->PointOfInstantiation,

1114 PDiag(diag::note_nested_requirement_here)

1115 << Active->InstantiationRange);

1116 break;

1117

1119 DiagFunc(Active->PointOfInstantiation,

1120 PDiag(diag::note_in_declaration_of_implicit_special_member)

1122 << Active->SpecialMember);

1123 break;

1124

1126 DiagFunc(

1127 Active->Entity->getLocation(),

1128 PDiag(diag::note_in_declaration_of_implicit_equality_comparison));

1129 break;

1130

1132

1133

1134 auto *FD = dyn_cast(Active->Entity);

1135

1136

1137

1142 DiagFunc(Active->PointOfInstantiation,

1143 PDiag(diag::note_member_synthesized_at)

1145 << Context.getCanonicalTagType(MD->getParent()));

1147 QualType RecordType = FD->getParamDecl(0)

1148 ->getType()

1149 .getNonReferenceType()

1150 .getUnqualifiedType();

1151 DiagFunc(Active->PointOfInstantiation,

1152 PDiag(diag::note_comparison_synthesized_at)

1154 }

1155 break;

1156 }

1157

1159 DiagFunc(Active->Entity->getLocation(),

1160 PDiag(diag::note_rewriting_operator_as_spaceship));

1161 break;

1162

1164 DiagFunc(Active->PointOfInstantiation,

1165 PDiag(diag::note_in_binding_decl_init)

1167 break;

1168

1170 DiagFunc(Active->PointOfInstantiation,

1171 PDiag(diag::note_due_to_dllexported_class)

1174 break;

1175

1177 DiagFunc(Active->PointOfInstantiation,

1178 PDiag(diag::note_building_builtin_dump_struct_call)

1181 Active->NumCallArgs)));

1182 break;

1183

1185 break;

1186

1188 DiagFunc(Active->PointOfInstantiation,

1189 PDiag(diag::note_lambda_substitution_here));

1190 break;

1192 unsigned DiagID = 0;

1193 if (!Active->Entity) {

1194 DiagFunc(Active->PointOfInstantiation,

1195 PDiag(diag::note_nested_requirement_here)

1196 << Active->InstantiationRange);

1197 break;

1198 }

1200 DiagID = diag::note_concept_specialization_here;

1202 DiagID = diag::note_checking_constraints_for_template_id_here;

1204 DiagID = diag::note_checking_constraints_for_var_spec_id_here;

1206 DiagID = diag::note_checking_constraints_for_class_spec_id_here;

1207 else {

1209 DiagID = diag::note_checking_constraints_for_function_here;

1210 }

1212 llvm::raw_svector_ostream OS(TemplateArgsStr);

1215 printTemplateArgumentList(OS, Active->template_arguments(),

1217 }

1218 DiagFunc(Active->PointOfInstantiation,

1219 PDiag(DiagID) << OS.str() << Active->InstantiationRange);

1220 break;

1221 }

1223 DiagFunc(Active->PointOfInstantiation,

1224 PDiag(diag::note_constraint_substitution_here)

1225 << Active->InstantiationRange);

1226 break;

1228 DiagFunc(Active->PointOfInstantiation,

1229 PDiag(diag::note_constraint_normalization_here)

1231 << Active->InstantiationRange);

1232 break;

1234 DiagFunc(Active->PointOfInstantiation,

1235 PDiag(diag::note_parameter_mapping_substitution_here)

1236 << Active->InstantiationRange);

1237 break;

1239 DiagFunc(Active->PointOfInstantiation,

1240 PDiag(diag::note_building_deduction_guide_here));

1241 break;

1243

1244

1245

1246

1247 if (Active->NumTemplateArgs == 0)

1248 break;

1249 DiagFunc(Active->PointOfInstantiation,

1250 PDiag(diag::note_template_type_alias_instantiation_here)

1252 << Active->InstantiationRange);

1253 break;

1255 DiagFunc(Active->PointOfInstantiation,

1256 PDiag(diag::note_template_arg_template_params_mismatch));

1257 if (SourceLocation ParamLoc = Active->Entity->getLocation();

1259 DiagFunc(ParamLoc, PDiag(diag::note_template_prev_declaration)

1260 << true

1261 << Active->InstantiationRange);

1262 break;

1263 }

1264 }

1265}

1266

1267

1268

1269

1270namespace {

1271

1272 class TemplateInstantiator : public TreeTransform {

1276

1277 bool EvaluateConstraints = true;

1278

1279

1280 bool IsIncomplete = false;

1281

1282 bool BailOutOnIncomplete;

1283

1284

1285

1286

1287 bool BuildPackExpansionTypes = true;

1288

1289

1290

1291

1292 bool maybeInstantiateFunctionParameterToScope(ParmVarDecl *OldParm);

1293

1294 public:

1296

1297 TemplateInstantiator(Sema &SemaRef,

1300 bool BailOutOnIncomplete = false)

1301 : inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),

1302 Entity(Entity), BailOutOnIncomplete(BailOutOnIncomplete) {}

1303

1304 void setEvaluateConstraints(bool B) {

1305 EvaluateConstraints = B;

1306 }

1307 bool getEvaluateConstraints() {

1308 return EvaluateConstraints;

1309 }

1310

1311 inline static struct ForParameterMappingSubstitution_t {

1312 } ForParameterMappingSubstitution;

1313

1314 TemplateInstantiator(ForParameterMappingSubstitution_t, Sema &SemaRef,

1315 SourceLocation Loc,

1316 const MultiLevelTemplateArgumentList &TemplateArgs,

1317 bool BuildPackExpansionTypes)

1318 : inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),

1319 BailOutOnIncomplete(false),

1320 BuildPackExpansionTypes(BuildPackExpansionTypes) {}

1321

1322

1323

1324

1325

1326

1327 bool AlreadyTransformed(QualType T);

1328

1329

1330 SourceLocation getBaseLocation() { return Loc; }

1331

1332

1333 DeclarationName getBaseEntity() { return Entity; }

1334

1335

1336 bool getIsIncomplete() const { return IsIncomplete; }

1337

1338

1339

1340 void setBase(SourceLocation Loc, DeclarationName Entity) {

1341 this->Loc = Loc;

1342 this->Entity = Entity;

1343 }

1344

1345 unsigned TransformTemplateDepth(unsigned Depth) {

1347 }

1348

1349 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,

1350 SourceRange PatternRange,

1351 ArrayRef Unexpanded,

1352 bool FailOnPackProducingTemplates,

1353 bool &ShouldExpand, bool &RetainExpansion,

1354 UnsignedOrNone &NumExpansions) {

1359 NamedDecl *VD = ParmPack.first.dyn_cast<NamedDecl *>();

1360 if (auto *PVD = dyn_cast_if_present(VD);

1361 PVD && maybeInstantiateFunctionParameterToScope(PVD))

1362 return true;

1363 }

1364 }

1365

1366 return getSema().CheckParameterPacksForExpansion(

1367 EllipsisLoc, PatternRange, Unexpanded, TemplateArgs,

1368 FailOnPackProducingTemplates, ShouldExpand, RetainExpansion,

1369 NumExpansions);

1370 }

1371

1372 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) {

1374 }

1375

1376 TemplateArgument ForgetPartiallySubstitutedPack() {

1377 TemplateArgument Result;

1380 MultiLevelTemplateArgumentList &TemplateArgs =

1381 const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);

1382 unsigned Depth, Index;

1385 Result = TemplateArgs(Depth, Index);

1386 TemplateArgs.setArgument(Depth, Index, TemplateArgument());

1387 } else {

1388 IsIncomplete = true;

1389 if (BailOutOnIncomplete)

1390 return TemplateArgument();

1391 }

1392 }

1393

1395 }

1396

1397 void RememberPartiallySubstitutedPack(TemplateArgument Arg) {

1399 return;

1400

1403 MultiLevelTemplateArgumentList &TemplateArgs =

1404 const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);

1405 unsigned Depth, Index;

1407 TemplateArgs.setArgument(Depth, Index, Arg);

1408 }

1409 }

1410

1411 MultiLevelTemplateArgumentList ForgetSubstitution() {

1412 MultiLevelTemplateArgumentList New;

1413 New.addOuterRetainedLevels(this->TemplateArgs.getNumLevels());

1414

1415 MultiLevelTemplateArgumentList Old =

1416 const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);

1417 const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs) =

1418 std::move(New);

1419 return Old;

1420 }

1421

1422 void RememberSubstitution(MultiLevelTemplateArgumentList Old) {

1423 const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs) = Old;

1424 }

1425

1426 TemplateArgument

1427 getTemplateArgumentPackPatternForRewrite(const TemplateArgument &TA) {

1429 return TA;

1433 "unexpected pack arguments in template rewrite");

1434 TemplateArgument Arg = *TA.pack_begin();

1437 return Arg;

1438 }

1439

1440

1441

1442 Decl *TransformDecl(SourceLocation Loc, Decl *D);

1443

1444 void transformAttrs(Decl *Old, Decl *New) {

1446 }

1447

1448 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> NewDecls) {

1450 (NewDecls.size() != 1 || !NewDecls.front()->isParameterPack())) {

1452 for (auto *New : NewDecls)

1455 return;

1456 }

1457

1458 assert(NewDecls.size() == 1 &&

1459 "should only have multiple expansions for a pack");

1460 Decl *New = NewDecls.front();

1461

1462

1463

1464

1465 auto *NewMD = dyn_cast(New);

1467 auto *OldMD = dyn_cast(Old);

1468 if (auto *NewTD = NewMD->getDescribedFunctionTemplate())

1469 NewTD->setInstantiatedFromMemberTemplate(

1470 OldMD->getDescribedFunctionTemplate());

1471 else

1472 NewMD->setInstantiationOfMemberFunction(OldMD,

1474 }

1475

1477

1478

1479

1480 if (auto *DC = dyn_cast(Old);

1481 DC && DC->isDependentContext() && DC->isFunctionOrMethod())

1483 }

1484

1485

1486

1487 Decl *TransformDefinition(SourceLocation Loc, Decl *D);

1488

1489

1490

1491 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc);

1492

1493 bool TransformExceptionSpec(SourceLocation Loc,

1494 FunctionProtoType::ExceptionSpecInfo &ESI,

1495 SmallVectorImpl &Exceptions,

1496 bool &Changed);

1497

1498

1499

1500 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,

1501 TypeSourceInfo *Declarator,

1502 SourceLocation StartLoc,

1503 SourceLocation NameLoc,

1504 IdentifierInfo *Name);

1505

1506

1507

1508 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,

1509 TypeSourceInfo *TSInfo, QualType T);

1510

1512 TransformTemplateName(NestedNameSpecifierLoc &QualifierLoc,

1513 SourceLocation TemplateKWLoc, TemplateName Name,

1514 SourceLocation NameLoc,

1515 QualType ObjectType = QualType(),

1516 NamedDecl *FirstQualifierInScope = nullptr,

1517 bool AllowInjectedClassName = false);

1518

1519 const AnnotateAttr *TransformAnnotateAttr(const AnnotateAttr *AA);

1520 const CXXAssumeAttr *TransformCXXAssumeAttr(const CXXAssumeAttr *AA);

1521 const LoopHintAttr *TransformLoopHintAttr(const LoopHintAttr *LH);

1522 const NoInlineAttr *TransformStmtNoInlineAttr(const Stmt *OrigS,

1523 const Stmt *InstS,

1524 const NoInlineAttr *A);

1525 const AlwaysInlineAttr *

1526 TransformStmtAlwaysInlineAttr(const Stmt *OrigS, const Stmt *InstS,

1527 const AlwaysInlineAttr *A);

1528 const CodeAlignAttr *TransformCodeAlignAttr(const CodeAlignAttr *CA);

1529 const OpenACCRoutineDeclAttr *

1530 TransformOpenACCRoutineDeclAttr(const OpenACCRoutineDeclAttr *A);

1531 ExprResult TransformPredefinedExpr(PredefinedExpr *E);

1532 ExprResult TransformDeclRefExpr(DeclRefExpr *E);

1533 ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);

1534

1535 ExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,

1536 NonTypeTemplateParmDecl *D);

1537

1538

1539 ExprResult RebuildVarDeclRefExpr(ValueDecl *PD, SourceLocation Loc);

1540

1541

1542 ExprResult TransformFunctionParmPackRefExpr(DeclRefExpr *E, ValueDecl *PD);

1543

1544

1545

1546

1547 ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E);

1548

1549 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,

1550 FunctionProtoTypeLoc TL) {

1551

1552 return inherited::TransformFunctionProtoType(TLB, TL);

1553 }

1554

1555 QualType TransformTagType(TypeLocBuilder &TLB, TagTypeLoc TL) {

1556 auto Type = inherited::TransformTagType(TLB, TL);

1557 if (Type.isNull())

1558 return Type;

1559

1560

1561

1562 if (const auto *ICNT = dyn_cast(TL.getTypePtr());

1565 Type = inherited::TransformType(

1566 ICNT->getDecl()->getCanonicalTemplateSpecializationType(

1569 }

1570 return Type;

1571 }

1572

1573

1574 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,

1575 TemplateArgumentLoc &Output,

1576 bool Uneval = false) {

1577 const TemplateArgument &Arg = Input.getArgument();

1578 std::vector TArgs;

1579 switch (Arg.getKind()) {

1584

1585

1588 pack, QualType(), SourceLocation{});

1589 TemplateArgumentLoc Output;

1590 if (TransformTemplateArgument(Input, Output, Uneval))

1591 return true;

1593 }

1595 TemplateArgument(llvm::ArrayRef(TArgs).copy(SemaRef.Context)),

1596 QualType(), SourceLocation{});

1597 return false;

1598 default:

1599 break;

1600 }

1601 return inherited::TransformTemplateArgument(Input, Output, Uneval);

1602 }

1603

1604

1605 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,

1606 UnsignedOrNone NumExpansions) {

1607 return inherited::RebuildPackExpansion(Pattern, EllipsisLoc,

1608 NumExpansions);

1609 }

1610

1611 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,

1612 SourceLocation EllipsisLoc,

1613 UnsignedOrNone NumExpansions) {

1614

1615

1616 if (BuildPackExpansionTypes)

1617 return inherited::RebuildPackExpansion(Pattern, EllipsisLoc,

1618 NumExpansions);

1619 return Pattern;

1620 }

1621

1623 QualType

1624 TransformTemplateSpecializationType(TypeLocBuilder &TLB,

1625 TemplateSpecializationTypeLoc TL) {

1627 if (!getSema().ArgPackSubstIndex || T->isSugared() ||

1630

1631

1632

1633

1634

1635

1636

1637 QualType R = TransformType(T->desugar());

1639 return R;

1640 }

1641

1642 UnsignedOrNone ComputeSizeOfPackExprWithoutSubstitution(

1643 ArrayRef PackArgs) {

1644

1645

1646

1647

1648

1649

1650

1651

1652

1654 return std::nullopt;

1655

1656 return inherited::ComputeSizeOfPackExprWithoutSubstitution(PackArgs);

1657 }

1658

1659 template

1660 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,

1661 FunctionProtoTypeLoc TL,

1662 CXXRecordDecl *ThisContext,

1663 Qualifiers ThisTypeQuals,

1664 Fn TransformExceptionSpec);

1665

1666 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,

1667 int indexAdjustment,

1668 UnsignedOrNone NumExpansions,

1669 bool ExpectParameterPack);

1670

1671 using inherited::TransformTemplateTypeParmType;

1672

1673

1674 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,

1675 TemplateTypeParmTypeLoc TL,

1676 bool SuppressObjCLifetime);

1677

1678 QualType BuildSubstTemplateTypeParmType(

1679 TypeLocBuilder &TLB, bool SuppressObjCLifetime, bool Final,

1680 Decl *AssociatedDecl, unsigned Index, UnsignedOrNone PackIndex,

1681 TemplateArgument Arg, SourceLocation NameLoc);

1682

1683

1684

1685

1686 using inherited::TransformSubstTemplateTypeParmPackType;

1687 QualType

1688 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,

1689 SubstTemplateTypeParmPackTypeLoc TL,

1690 bool SuppressObjCLifetime);

1691 QualType

1692 TransformSubstBuiltinTemplatePackType(TypeLocBuilder &TLB,

1693 SubstBuiltinTemplatePackTypeLoc TL);

1694

1696 ComputeLambdaDependency(LambdaScopeInfo *LSI) {

1698 TemplateInstArgsHelpers::getEnclosingTypeAliasTemplateDecl(

1699 getSema());

1700 TypeAlias && TemplateInstArgsHelpers::isLambdaEnclosedByTypeAliasDecl(

1702 unsigned TypeAliasDeclDepth = TypeAlias.Template->getTemplateDepth();

1704 return CXXRecordDecl::LambdaDependencyKind::LDK_AlwaysDependent;

1705 for (const TemplateArgument &TA : TypeAlias.AssociatedTemplateArguments)

1707 return CXXRecordDecl::LambdaDependencyKind::LDK_AlwaysDependent;

1708 }

1709 return inherited::ComputeLambdaDependency(LSI);

1710 }

1711

1713

1714

1716 return E;

1717 LocalInstantiationScope Scope(SemaRef, true,

1718 true);

1719 Sema::ConstraintEvalRAII RAII(*this);

1720

1721 return inherited::TransformLambdaExpr(E);

1722 }

1723

1724 ExprResult TransformBlockExpr(BlockExpr *E) {

1725 LocalInstantiationScope Scope(SemaRef, true,

1726 true);

1727 return inherited::TransformBlockExpr(E);

1728 }

1729

1730 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,

1731 LambdaScopeInfo *LSI) {

1733 for (ParmVarDecl *PVD : MD->parameters()) {

1734 assert(PVD && "null in a parameter list");

1735 if (!PVD->hasDefaultArg())

1736 continue;

1737 Expr *UninstExpr = PVD->getUninstantiatedDefaultArg();

1738

1739 SourceLocation EqualLoc = UninstExpr->getBeginLoc();

1741

1742

1743

1748 PVD->setDefaultArg(ErrorResult.get());

1749 }

1750 }

1751 return inherited::RebuildLambdaExpr(StartLoc, EndLoc, LSI);

1752 }

1753

1755

1756

1757

1758

1759

1760

1761

1762

1763

1764 llvm::SaveAndRestore _(EvaluateConstraints, true);

1765 return inherited::TransformLambdaBody(E, Body);

1766 }

1767

1769 LocalInstantiationScope Scope(SemaRef, true);

1770 ExprResult TransReq = inherited::TransformRequiresExpr(E);

1772 return TransReq;

1773 assert(TransReq.get() != E &&

1774 "Do not change value of isSatisfied for the existing expression. "

1775 "Create a new expression instead.");

1777 Sema::SFINAETrap Trap(SemaRef);

1778

1779

1781

1782 if (Trap.hasErrorOccurred())

1784 }

1785 return TransReq;

1786 }

1787

1788 bool TransformRequiresExprRequirements(

1789 ArrayRef<concepts::Requirement *> Reqs,

1790 SmallVectorImpl<concepts::Requirement *> &Transformed) {

1791 bool SatisfactionDetermined = false;

1792 for (concepts::Requirement *Req : Reqs) {

1793 concepts::Requirement *TransReq = nullptr;

1794 if (!SatisfactionDetermined) {

1795 if (auto *TypeReq = dyn_castconcepts::TypeRequirement(Req))

1796 TransReq = TransformTypeRequirement(TypeReq);

1797 else if (auto *ExprReq = dyn_castconcepts::ExprRequirement(Req))

1798 TransReq = TransformExprRequirement(ExprReq);

1799 else

1800 TransReq = TransformNestedRequirement(

1802 if (!TransReq)

1803 return true;

1805

1806

1807

1808

1809

1810 SatisfactionDetermined = true;

1811 } else

1812 TransReq = Req;

1813 Transformed.push_back(TransReq);

1814 }

1815 return false;

1816 }

1817

1818 TemplateParameterList *TransformTemplateParameterList(

1819 TemplateParameterList *OrigTPL) {

1820 if (!OrigTPL || !OrigTPL->size()) return OrigTPL;

1821

1823 TemplateDeclInstantiator DeclInstantiator(getSema(),

1824 Owner, TemplateArgs);

1825 DeclInstantiator.setEvaluateConstraints(EvaluateConstraints);

1826 return DeclInstantiator.SubstTemplateParams(OrigTPL);

1827 }

1828

1829 concepts::TypeRequirement *

1830 TransformTypeRequirement(concepts::TypeRequirement *Req);

1831 concepts::ExprRequirement *

1832 TransformExprRequirement(concepts::ExprRequirement *Req);

1833 concepts::NestedRequirement *

1834 TransformNestedRequirement(concepts::NestedRequirement *Req);

1835 ExprResult TransformRequiresTypeParams(

1836 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,

1837 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,

1838 SmallVectorImpl &PTypes,

1839 SmallVectorImpl<ParmVarDecl *> &TransParams,

1840 Sema::ExtParameterInfoBuilder &PInfos);

1841 };

1842}

1843

1844bool TemplateInstantiator::AlreadyTransformed(QualType T) {

1845 if (T.isNull())

1846 return true;

1847

1850 return false;

1851

1852 getSema().MarkDeclarationsReferencedInType(Loc, T);

1853 return true;

1854}

1855

1856Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {

1857 if (!D)

1858 return nullptr;

1859

1860 if (TemplateTemplateParmDecl *TTP = dyn_cast(D)) {

1861 if (TTP->getDepth() < TemplateArgs.getNumLevels()) {

1862

1863

1864

1865

1867 TTP->getPosition())) {

1868 IsIncomplete = true;

1869 return BailOutOnIncomplete ? nullptr : D;

1870 }

1871

1872 TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());

1873

1874 if (TTP->isParameterPack()) {

1876 "Missing argument pack");

1877 Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg);

1878 }

1879

1881 assert(Template.isNull() && Template.getAsTemplateDecl() &&

1882 "Wrong kind of template template argument");

1883 return Template.getAsTemplateDecl();

1884 }

1885

1886

1887

1888 }

1889

1890 if (ParmVarDecl *PVD = dyn_cast(D);

1891 PVD && SemaRef.CurrentInstantiationScope &&

1892 (SemaRef.inConstraintSubstitution() ||

1893 SemaRef.inParameterMappingSubstitution()) &&

1894 maybeInstantiateFunctionParameterToScope(PVD))

1895 return nullptr;

1896

1898}

1899

1900bool TemplateInstantiator::maybeInstantiateFunctionParameterToScope(

1901 ParmVarDecl *OldParm) {

1902 if (SemaRef.CurrentInstantiationScope->getInstantiationOfIfExists(OldParm))

1903 return false;

1904

1906 return !TransformFunctionTypeParam(OldParm, 0,

1907 std::nullopt,

1908 false);

1909

1910 SmallVector<UnexpandedParameterPack, 2> Unexpanded;

1911

1912

1914 PackExpansionTypeLoc ExpansionTL = TL.castAs();

1916 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);

1917 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");

1918

1919 bool ShouldExpand = false;

1920 bool RetainExpansion = false;

1921 UnsignedOrNone OrigNumExpansions =

1922 ExpansionTL.getTypePtr()->getNumExpansions();

1923 UnsignedOrNone NumExpansions = OrigNumExpansions;

1924 if (TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),

1925 Pattern.getSourceRange(), Unexpanded,

1926 true,

1927 ShouldExpand, RetainExpansion, NumExpansions))

1928 return true;

1929

1930 assert(ShouldExpand && !RetainExpansion &&

1931 "Shouldn't preserve pack expansion when evaluating constraints");

1932 ExpandingFunctionParameterPack(OldParm);

1933 for (unsigned I = 0; I != *NumExpansions; ++I) {

1934 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);

1935 if (!TransformFunctionTypeParam(OldParm, 0,

1936 OrigNumExpansions,

1937 false))

1938 return true;

1939 }

1940 return false;

1941}

1942

1943Decl *TemplateInstantiator::TransformDefinition(SourceLocation Loc, Decl *D) {

1944 Decl *Inst = getSema().SubstDecl(D, getSema().CurContext, TemplateArgs);

1945 if (!Inst)

1946 return nullptr;

1947

1948 getSema().CurrentInstantiationScope->InstantiatedLocal(D, Inst);

1949 return Inst;

1950}

1951

1952bool TemplateInstantiator::TransformExceptionSpec(

1953 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,

1954 SmallVectorImpl &Exceptions, bool &Changed) {

1958 }

1959 return inherited::TransformExceptionSpec(Loc, ESI, Exceptions, Changed);

1960}

1961

1962NamedDecl *

1963TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D,

1964 SourceLocation Loc) {

1965

1966

1967 if (TemplateTypeParmDecl *TTPD = dyn_cast_or_null(D)) {

1968 const TemplateTypeParmType *TTP

1970

1971 if (TTP->getDepth() < TemplateArgs.getNumLevels()) {

1972

1973 TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getIndex());

1974

1975 if (TTP->isParameterPack()) {

1977 "Missing argument pack");

1978

1980 return nullptr;

1981

1982 Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg);

1983 }

1984

1986 if (T.isNull())

1987 return cast_or_null(TransformDecl(Loc, D));

1988

1989 if (const TagType *Tag = T->getAs())

1990 return Tag->getDecl();

1991

1992

1993 getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T;

1994 return nullptr;

1995 }

1996 }

1997

1998 return cast_or_null(TransformDecl(Loc, D));

1999}

2000

2001VarDecl *

2002TemplateInstantiator::RebuildExceptionDecl(VarDecl *ExceptionDecl,

2003 TypeSourceInfo *Declarator,

2004 SourceLocation StartLoc,

2005 SourceLocation NameLoc,

2006 IdentifierInfo *Name) {

2007 VarDecl *Var = inherited::RebuildExceptionDecl(ExceptionDecl, Declarator,

2008 StartLoc, NameLoc, Name);

2009 if (Var)

2010 getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);

2011 return Var;

2012}

2013

2014VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,

2015 TypeSourceInfo *TSInfo,

2016 QualType T) {

2017 VarDecl *Var = inherited::RebuildObjCExceptionDecl(ExceptionDecl, TSInfo, T);

2018 if (Var)

2019 getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);

2020 return Var;

2021}

2022

2023TemplateName TemplateInstantiator::TransformTemplateName(

2024 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,

2025 TemplateName Name, SourceLocation NameLoc, QualType ObjectType,

2026 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {

2028 assert(!QualifierLoc && "Unexpected qualifier");

2029 if (auto *TTP =

2031 TTP && TTP->getDepth() < TemplateArgs.getNumLevels()) {

2032

2033

2034

2035

2037 TTP->getPosition())) {

2038 IsIncomplete = true;

2039 return BailOutOnIncomplete ? TemplateName() : Name;

2040 }

2041

2042 TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());

2043

2045

2046

2047 Arg = getTemplateArgumentPackPatternForRewrite(Arg);

2049 "unexpected nontype template argument kind in template rewrite");

2051 }

2052

2053 auto [AssociatedDecl, Final] =

2055 UnsignedOrNone PackIndex = std::nullopt;

2056 if (TTP->isParameterPack()) {

2058 "Missing argument pack");

2059

2061

2062

2063

2064 return getSema().Context.getSubstTemplateTemplateParmPack(

2065 Arg, AssociatedDecl, TTP->getIndex(), Final);

2066 }

2067

2068 PackIndex = SemaRef.getPackIndex(Arg);

2069 Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg);

2070 }

2071

2073 assert(Template.isNull() && "Null template template argument");

2074 return getSema().Context.getSubstTemplateTemplateParm(

2075 Template, AssociatedDecl, TTP->getIndex(), PackIndex, Final);

2076 }

2077 }

2078

2079 if (SubstTemplateTemplateParmPackStorage *SubstPack

2082 return Name;

2083

2084 TemplateArgument Pack = SubstPack->getArgumentPack();

2086 SemaRef.getPackSubstitutedTemplateArgument(Pack).getAsTemplate();

2087 return getSema().Context.getSubstTemplateTemplateParm(

2088 Template, SubstPack->getAssociatedDecl(), SubstPack->getIndex(),

2089 SemaRef.getPackIndex(Pack), SubstPack->getFinal());

2090 }

2091

2092 return inherited::TransformTemplateName(

2093 QualifierLoc, TemplateKWLoc, Name, NameLoc, ObjectType,

2094 FirstQualifierInScope, AllowInjectedClassName);

2095}

2096

2098TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {

2100 return E;

2101

2103}

2104

2106TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,

2107 NonTypeTemplateParmDecl *NTTP) {

2108

2109

2110

2111

2114 IsIncomplete = true;

2115 return BailOutOnIncomplete ? ExprError() : E;

2116 }

2117

2118 TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition());

2119

2121

2122

2123 Arg = getTemplateArgumentPackPatternForRewrite(Arg);

2125 "unexpected nontype template argument kind in template rewrite");

2126

2127

2129 }

2130

2131 auto [AssociatedDecl, Final] =

2133 UnsignedOrNone PackIndex = std::nullopt;

2136 "Missing argument pack");

2137

2139

2140

2141

2142 QualType TargetType = SemaRef.SubstType(NTTP->getType(), TemplateArgs,

2145 if (TargetType.isNull())

2147

2151 return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(

2154 }

2155 PackIndex = SemaRef.getPackIndex(Arg);

2156 Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg);

2157 }

2158 return SemaRef.BuildSubstNonTypeTemplateParmExpr(

2159 AssociatedDecl, NTTP, E->getLocation(), Arg, PackIndex, Final);

2160}

2161

2162const AnnotateAttr *

2163TemplateInstantiator::TransformAnnotateAttr(const AnnotateAttr *AA) {

2164 SmallVector<Expr *> Args;

2165 for (Expr *Arg : AA->args()) {

2166 ExprResult Res = getDerived().TransformExpr(Arg);

2168 Args.push_back(Res.get());

2169 }

2170 return AnnotateAttr::CreateImplicit(getSema().Context, AA->getAnnotation(),

2171 Args.data(), Args.size(), AA->getRange());

2172}

2173

2174const CXXAssumeAttr *

2175TemplateInstantiator::TransformCXXAssumeAttr(const CXXAssumeAttr *AA) {

2176 ExprResult Res = getDerived().TransformExpr(AA->getAssumption());

2178 return AA;

2179

2180 if (!(Res.get()->getDependence() & ExprDependence::TypeValueInstantiation)) {

2181 Res = getSema().BuildCXXAssumeExpr(Res.get(), AA->getAttrName(),

2182 AA->getRange());

2184 return AA;

2185 }

2186

2187 return CXXAssumeAttr::CreateImplicit(getSema().Context, Res.get(),

2188 AA->getRange());

2189}

2190

2191const LoopHintAttr *

2192TemplateInstantiator::TransformLoopHintAttr(const LoopHintAttr *LH) {

2193 Expr *TransformedExpr = getDerived().TransformExpr(LH->getValue()).get();

2194

2195 if (TransformedExpr == LH->getValue())

2196 return LH;

2197

2198

2199 if (getSema().CheckLoopHintExpr(TransformedExpr, LH->getLocation(),

2200 LH->getSemanticSpelling() ==

2201 LoopHintAttr::Pragma_unroll))

2202 return LH;

2203

2204 LoopHintAttr::OptionType Option = LH->getOption();

2205 LoopHintAttr::LoopHintState State = LH->getState();

2206

2207 llvm::APSInt ValueAPS =

2209

2210 if (ValueAPS.isZero() || ValueAPS.isOne()) {

2211 Option = LoopHintAttr::Unroll;

2212 State = LoopHintAttr::Disable;

2213 }

2214

2215

2216

2217 return LoopHintAttr::CreateImplicit(getSema().Context, Option, State,

2218 TransformedExpr, *LH);

2219}

2220const NoInlineAttr *TemplateInstantiator::TransformStmtNoInlineAttr(

2221 const Stmt *OrigS, const Stmt *InstS, const NoInlineAttr *A) {

2223 return nullptr;

2224

2225 return A;

2226}

2227const AlwaysInlineAttr *TemplateInstantiator::TransformStmtAlwaysInlineAttr(

2228 const Stmt *OrigS, const Stmt *InstS, const AlwaysInlineAttr *A) {

2230 return nullptr;

2231

2232 return A;

2233}

2234

2235const CodeAlignAttr *

2236TemplateInstantiator::TransformCodeAlignAttr(const CodeAlignAttr *CA) {

2237 Expr *TransformedExpr = getDerived().TransformExpr(CA->getAlignment()).get();

2238 return getSema().BuildCodeAlignAttr(*CA, TransformedExpr);

2239}

2240const OpenACCRoutineDeclAttr *

2241TemplateInstantiator::TransformOpenACCRoutineDeclAttr(

2242 const OpenACCRoutineDeclAttr *A) {

2243 llvm_unreachable("RoutineDecl should only be a declaration attribute, as it "

2244 "applies to a Function Decl (and a few places for VarDecl)");

2245}

2246

2247ExprResult TemplateInstantiator::RebuildVarDeclRefExpr(ValueDecl *PD,

2248 SourceLocation Loc) {

2249 DeclarationNameInfo NameInfo(PD->getDeclName(), Loc);

2250 return getSema().BuildDeclarationNameExpr(CXXScopeSpec(), NameInfo, PD);

2251}

2252

2254TemplateInstantiator::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {

2256

2258 ValueDecl *VD = cast_or_null(TransformDecl(E->getExprLoc(), D));

2259 if (!VD)

2261 return RebuildVarDeclRefExpr(VD, E->getExprLoc());

2262 }

2263

2264 QualType T = TransformType(E->getType());

2265 if (T.isNull())

2267

2268

2269

2270 SmallVector<ValueDecl *, 8> Vars;

2273 I != End; ++I) {

2274 ValueDecl *D = cast_or_null(TransformDecl(E->getExprLoc(), *I));

2275 if (!D)

2277 Vars.push_back(D);

2278 }

2279

2280 auto *PackExpr =

2283 getSema().MarkFunctionParmPackReferenced(PackExpr);

2284 return PackExpr;

2285}

2286

2288TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E,

2289 ValueDecl *PD) {

2291 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Found

2292 = getSema().CurrentInstantiationScope->findInstantiationOf(PD);

2293 assert(Found && "no instantiation for parameter pack");

2294

2295 Decl *TransformedDecl;

2296 if (DeclArgumentPack *Pack = dyn_cast<DeclArgumentPack *>(*Found)) {

2297

2298

2300 QualType T = TransformType(E->getType());

2301 if (T.isNull())

2305 getSema().MarkFunctionParmPackReferenced(PackExpr);

2306 return PackExpr;

2307 }

2308

2309 TransformedDecl = (*Pack)[*getSema().ArgPackSubstIndex];

2310 } else {

2312 }

2313

2314

2315 return RebuildVarDeclRefExpr(cast(TransformedDecl),

2317}

2318

2320TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {

2321 NamedDecl *D = E->getDecl();

2322

2323

2324

2325 if (NonTypeTemplateParmDecl *NTTP = dyn_cast(D)) {

2327 return TransformTemplateParmRefExpr(E, NTTP);

2328

2329

2330

2331 }

2332

2333

2334 if (VarDecl *PD = dyn_cast(D))

2336 return TransformFunctionParmPackRefExpr(E, PD);

2337

2338 return inherited::TransformDeclRefExpr(E);

2339}

2340

2341ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(

2342 CXXDefaultArgExpr *E) {

2344 getDescribedFunctionTemplate() &&

2345 "Default arg expressions are never formed in dependent cases.");

2346 return SemaRef.BuildCXXDefaultArgExpr(

2349}

2350

2351template

2352QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,

2353 FunctionProtoTypeLoc TL,

2354 CXXRecordDecl *ThisContext,

2355 Qualifiers ThisTypeQuals,

2356 Fn TransformExceptionSpec) {

2357

2358

2359

2360

2361

2362

2363

2364 LocalInstantiationScope *Current = getSema().CurrentInstantiationScope;

2365 std::optional Scope;

2367 Scope.emplace(SemaRef, true);

2368

2369 return inherited::TransformFunctionProtoType(

2370 TLB, TL, ThisContext, ThisTypeQuals, TransformExceptionSpec);

2371}

2372

2373ParmVarDecl *TemplateInstantiator::TransformFunctionTypeParam(

2374 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,

2375 bool ExpectParameterPack) {

2376 auto NewParm = SemaRef.SubstParmVarDecl(

2377 OldParm, TemplateArgs, indexAdjustment, NumExpansions,

2378 ExpectParameterPack, EvaluateConstraints);

2379 if (NewParm && SemaRef.getLangOpts().OpenCL)

2380 SemaRef.deduceOpenCLAddressSpace(NewParm);

2381 return NewParm;

2382}

2383

2384QualType TemplateInstantiator::BuildSubstTemplateTypeParmType(

2385 TypeLocBuilder &TLB, bool SuppressObjCLifetime, bool Final,

2386 Decl *AssociatedDecl, unsigned Index, UnsignedOrNone PackIndex,

2387 TemplateArgument Arg, SourceLocation NameLoc) {

2388 QualType Replacement = Arg.getAsType();

2389

2390

2391

2392 if (SuppressObjCLifetime) {

2393 Qualifiers RQs;

2394 RQs = Replacement.getQualifiers();

2396 Replacement =

2397 SemaRef.Context.getQualifiedType(Replacement.getUnqualifiedType(), RQs);

2398 }

2399

2400

2401 QualType Result = getSema().Context.getSubstTemplateTypeParmType(

2402 Replacement, AssociatedDecl, Index, PackIndex, Final);

2403 SubstTemplateTypeParmTypeLoc NewTL =

2404 TLB.push(Result);

2407}

2408

2409QualType

2410TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,

2411 TemplateTypeParmTypeLoc TL,

2412 bool SuppressObjCLifetime) {

2413 const TemplateTypeParmType *T = TL.getTypePtr();

2414 if (T->getDepth() < TemplateArgs.getNumLevels()) {

2415

2416

2417

2418

2419

2420

2421

2423 IsIncomplete = true;

2424 if (BailOutOnIncomplete)

2425 return QualType();

2426

2427 TemplateTypeParmTypeLoc NewTL

2428 = TLB.push(TL.getType());

2431 }

2432

2433 TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex());

2434

2436

2437

2438 Arg = getTemplateArgumentPackPatternForRewrite(Arg);

2440 "unexpected nontype template argument kind in template rewrite");

2441 QualType NewT = Arg.getAsType();

2443 return NewT;

2444 }

2445

2446 auto [AssociatedDecl, Final] =

2448 UnsignedOrNone PackIndex = std::nullopt;

2449 if (T->isParameterPack()) {

2451 "Missing argument pack");

2452

2454

2455

2456

2457 QualType Result = getSema().Context.getSubstTemplateTypeParmPackType(

2458 AssociatedDecl, T->getIndex(), Final, Arg);

2459 SubstTemplateTypeParmPackTypeLoc NewTL

2460 = TLB.push(Result);

2463 }

2464

2465

2466 PackIndex = SemaRef.getPackIndex(Arg);

2467 Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg);

2468 }

2469

2471 "Template argument kind mismatch");

2472

2473 return BuildSubstTemplateTypeParmType(TLB, SuppressObjCLifetime, Final,

2474 AssociatedDecl, T->getIndex(),

2476 }

2477

2478

2479

2480

2481

2482 TemplateTypeParmDecl *NewTTPDecl = nullptr;

2483 if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())

2484 NewTTPDecl = cast_or_null(

2485 TransformDecl(TL.getNameLoc(), OldTTPDecl));

2486 QualType Result = getSema().Context.getTemplateTypeParmType(

2488 T->isParameterPack(), NewTTPDecl);

2489 TemplateTypeParmTypeLoc NewTL = TLB.push(Result);

2492}

2493

2494QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType(

2495 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL,

2496 bool SuppressObjCLifetime) {

2497 const SubstTemplateTypeParmPackType *T = TL.getTypePtr();

2498

2499 Decl *NewReplaced = TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());

2500

2502

2504 if (NewReplaced != T->getAssociatedDecl())

2505 Result = getSema().Context.getSubstTemplateTypeParmPackType(

2506 NewReplaced, T->getIndex(), T->getFinal(), T->getArgumentPack());

2507 SubstTemplateTypeParmPackTypeLoc NewTL =

2508 TLB.push(Result);

2511 }

2512

2513 TemplateArgument Pack = T->getArgumentPack();

2514 TemplateArgument Arg = SemaRef.getPackSubstitutedTemplateArgument(Pack);

2515 return BuildSubstTemplateTypeParmType(

2516 TLB, SuppressObjCLifetime, T->getFinal(), NewReplaced, T->getIndex(),

2518}

2519

2520QualType TemplateInstantiator::TransformSubstBuiltinTemplatePackType(

2521 TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {

2523 return TreeTransform::TransformSubstBuiltinTemplatePackType(TLB, TL);

2524 TemplateArgument Result = SemaRef.getPackSubstitutedTemplateArgument(

2525 TL.getTypePtr()->getArgumentPack());

2528 return Result.getAsType();

2529}

2530

2531static concepts::Requirement::SubstitutionDiagnostic *

2540 PDA.second.EmitToString(S.getDiagnostics(), Message);

2541 ErrorLoc = PDA.first;

2542 } else {

2544 }

2546 llvm::raw_svector_ostream OS(Entity);

2547 Printer(OS);

2550 C.backupStr(Entity), ErrorLoc, C.backupStr(Message)};

2551}

2552

2553concepts::Requirement::SubstitutionDiagnostic *

2556 llvm::raw_svector_ostream OS(Entity);

2557 Printer(OS);

2560 C.backupStr(Entity),

2561 Location, StringRef()};

2562}

2563

2564ExprResult TemplateInstantiator::TransformRequiresTypeParams(

2570

2575

2576 unsigned ErrorIdx;

2577 if (getDerived().TransformFunctionTypeParams(

2578 KWLoc, Params, nullptr, nullptr, PTypes,

2579 &TransParams, PInfos, &ErrorIdx) ||

2580 Trap.hasErrorOccurred()) {

2582 ParmVarDecl *FailedDecl = Params[ErrorIdx];

2583

2584

2585 TransReqs.push_back(RebuildTypeRequirement(createSubstDiag(

2586 SemaRef, Info, [&](llvm::raw_ostream &OS) { OS << *FailedDecl; })));

2587 return getDerived().RebuildRequiresExpr(KWLoc, Body, RE->getLParenLoc(),

2589 TransReqs, RBraceLoc);

2590 }

2591

2593}

2594

2595concepts::TypeRequirement *

2596TemplateInstantiator::TransformTypeRequirement(concepts::TypeRequirement *Req) {

2597 if (!Req->isDependent() && !AlwaysRebuild())

2598 return Req;

2600 if (AlwaysRebuild())

2601 return RebuildTypeRequirement(

2603 return Req;

2604 }

2605

2607 Sema::SFINAETrap Trap(SemaRef, Info);

2608 Sema::InstantiatingTemplate TypeInst(

2611 if (TypeInst.isInvalid())

2612 return nullptr;

2613 TypeSourceInfo *TransType = TransformType(Req->getType());

2614 if (!TransType || Trap.hasErrorOccurred())

2616 [&] (llvm::raw_ostream& OS) {

2618 }));

2619 return RebuildTypeRequirement(TransType);

2620}

2621

2622concepts::ExprRequirement *

2623TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {

2624 if (!Req->isDependent() && !AlwaysRebuild())

2625 return Req;

2626

2627 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *>

2628 TransExpr;

2631 else {

2632 Expr *E = Req->getExpr();

2633 TemplateDeductionInfo Info(E->getBeginLoc());

2634 Sema::SFINAETrap Trap(SemaRef, Info);

2635 Sema::InstantiatingTemplate ExprInst(SemaRef, E->getBeginLoc(), Req,

2637 if (ExprInst.isInvalid())

2638 return nullptr;

2639 ExprResult TransExprRes = TransformExpr(E);

2640 if (!TransExprRes.isInvalid() && !Trap.hasErrorOccurred() &&

2642 TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());

2643 if (TransExprRes.isInvalid() || Trap.hasErrorOccurred())

2646 });

2647 else

2648 TransExpr = TransExprRes.get();

2649 }

2650

2651 std::optionalconcepts::ExprRequirement::ReturnTypeRequirement TransRetReq;

2653 if (RetReq.isEmpty())

2654 TransRetReq.emplace();

2655 else if (RetReq.isSubstitutionFailure())

2656 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());

2657 else if (RetReq.isTypeConstraint()) {

2658 TemplateParameterList *OrigTPL =

2659 RetReq.getTypeConstraintTemplateParameterList();

2660 TemplateDeductionInfo Info(OrigTPL->getTemplateLoc());

2661 Sema::SFINAETrap Trap(SemaRef, Info);

2664 if (TPLInst.isInvalid())

2665 return nullptr;

2666 TemplateParameterList *TPL = TransformTemplateParameterList(OrigTPL);

2667 if (!TPL || Trap.hasErrorOccurred())

2669 [&] (llvm::raw_ostream& OS) {

2670 RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint()

2671 ->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());

2672 }));

2673 else {

2674 TPLInst.Clear();

2675 TransRetReq.emplace(TPL);

2676 }

2677 }

2678 assert(TransRetReq && "All code paths leading here must set TransRetReq");

2679 if (Expr *E = TransExpr.dyn_cast<Expr *>())

2681 std::move(*TransRetReq));

2682 return RebuildExprRequirement(

2685}

2686

2687concepts::NestedRequirement *

2688TemplateInstantiator::TransformNestedRequirement(

2689 concepts::NestedRequirement *Req) {

2690

2691 ASTContext &C = SemaRef.Context;

2692

2694 ConstraintSatisfaction Satisfaction;

2695

2696 auto NestedReqWithDiag = [&C, this](Expr *E,

2697 ConstraintSatisfaction Satisfaction) {

2699 SmallString<128> Entity;

2700 llvm::raw_svector_ostream OS(Entity);

2701 E->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());

2702 return new (C) concepts::NestedRequirement(

2703 SemaRef.Context, C.backupStr(Entity), std::move(Satisfaction));

2704 };

2705

2707 if (AlwaysRebuild())

2710 return Req;

2711 }

2712

2713 if (!getEvaluateConstraints()) {

2715 if (TransConstraint.isInvalid() || !TransConstraint.get())

2716 return nullptr;

2718 return new (SemaRef.Context)

2719 concepts::NestedRequirement(TransConstraint.get());

2720 ConstraintSatisfaction Satisfaction;

2721 return new (SemaRef.Context) concepts::NestedRequirement(

2722 SemaRef.Context, TransConstraint.get(), Satisfaction);

2723 }

2724

2726 Expr *NewConstraint;

2727 {

2728 EnterExpressionEvaluationContext ContextRAII(

2730 Sema::InstantiatingTemplate ConstrInst(

2732 Sema::InstantiatingTemplate::ConstraintsCheck(),

2734

2735 if (ConstrInst.isInvalid())

2736 return nullptr;

2737

2739 Req, AssociatedConstraint(Constraint, SemaRef.ArgPackSubstIndex),

2740 TemplateArgs, Constraint->getSourceRange(), Satisfaction,

2741 nullptr, &NewConstraint);

2742 }

2743

2745 return NestedReqWithDiag(Constraint, Satisfaction);

2746

2747

2748

2749 if (!NewConstraint) {

2751 return NestedReqWithDiag(Constraint, Satisfaction);

2752

2753 NewConstraint = Constraint;

2754 }

2755 return new (C) concepts::NestedRequirement(C, NewConstraint, Satisfaction);

2756}

2757

2762 bool AllowDeducedTST) {

2764 "Cannot perform an instantiation without some context on the "

2765 "instantiation stack");

2766

2767 if (T->getType()->isInstantiationDependentType() &&

2768 T->getType()->isVariablyModifiedType())

2769 return T;

2770

2771 TemplateInstantiator Instantiator(*this, Args, Loc, Entity);

2772 return AllowDeducedTST ? Instantiator.TransformTypeWithDeducedTST(T)

2773 : Instantiator.TransformType(T);

2774}

2775

2781 "Cannot perform an instantiation without some context on the "

2782 "instantiation stack");

2783

2785 return nullptr;

2786

2789

2790

2794 }

2795

2796 TemplateInstantiator Instantiator(*this, Args, Loc, Entity);

2799 QualType Result = Instantiator.TransformType(TLB, TL);

2800 if (Result.isNull())

2801 return nullptr;

2802

2804}

2805

2806

2810 bool *IsIncompleteSubstitution) {

2812 "Cannot perform an instantiation without some context on the "

2813 "instantiation stack");

2814

2815

2816

2817 if (T->isInstantiationDependentType() && T->isVariablyModifiedType())

2818 return T;

2819

2820 TemplateInstantiator Instantiator(

2821 *this, TemplateArgs, Loc, Entity,

2822 IsIncompleteSubstitution != nullptr);

2823 QualType QT = Instantiator.TransformType(T);

2824 if (IsIncompleteSubstitution && Instantiator.getIsIncomplete())

2825 *IsIncompleteSubstitution = true;

2826 return QT;

2827}

2828

2830 if (T->getType()->isInstantiationDependentType() ||

2831 T->getType()->isVariablyModifiedType())

2832 return true;

2833

2834 TypeLoc TL = T->getTypeLoc().IgnoreParens();

2836 return false;

2837

2840

2841 if (!P) continue;

2842

2843

2844

2845 return true;

2846 }

2847

2848 return false;

2849}

2850

2857 bool EvaluateConstraints) {

2859 "Cannot perform an instantiation without some context on the "

2860 "instantiation stack");

2861

2863 return T;

2864

2865 TemplateInstantiator Instantiator(*this, Args, Loc, Entity);

2866 Instantiator.setEvaluateConstraints(EvaluateConstraints);

2867

2869

2870 TypeLoc TL = T->getTypeLoc();

2872

2874

2877

2878

2879

2880

2881

2882 Result = Instantiator.TransformFunctionProtoType(

2883 TLB, Proto, ThisContext, ThisTypeQuals,

2885 bool &Changed) { return false; });

2886 } else {

2887 Result = Instantiator.TransformType(TLB, TL);

2888 }

2889

2890

2891 if (Result.isNull() || Result->isFunctionType())

2892 return nullptr;

2893

2895}

2896

2901 bool Changed = false;

2902 TemplateInstantiator Instantiator(*this, Args, Loc, DeclarationName());

2903 return Instantiator.TransformExceptionSpec(Loc, ESI, ExceptionStorage,

2904 Changed);

2905}

2906

2911

2914 ESI, ExceptionStorage, Args))

2915

2917

2919}

2920

2921namespace {

2922

2923 struct GetContainedInventedTypeParmVisitor :

2924 public TypeVisitor<GetContainedInventedTypeParmVisitor,

2925 TemplateTypeParmDecl *> {

2926 using TypeVisitor<GetContainedInventedTypeParmVisitor,

2928

2930 if (T.isNull())

2931 return nullptr;

2932 return Visit(T.getTypePtr());

2933 }

2934

2936 const TemplateTypeParmType *T) {

2937 if (T->getDecl() || T->getDecl()->isImplicit())

2938 return nullptr;

2939 return T->getDecl();

2940 }

2941

2942

2943

2944

2945 TemplateTypeParmDecl *VisitPointerType(const PointerType *T) {

2947 }

2948

2949 TemplateTypeParmDecl *VisitBlockPointerType(const BlockPointerType *T) {

2951 }

2952

2953 TemplateTypeParmDecl *VisitReferenceType(const ReferenceType *T) {

2954 return Visit(T->getPointeeTypeAsWritten());

2955 }

2956

2957 TemplateTypeParmDecl *VisitMemberPointerType(const MemberPointerType *T) {

2959 }

2960

2961 TemplateTypeParmDecl *VisitArrayType(const ArrayType *T) {

2962 return Visit(T->getElementType());

2963 }

2964

2965 TemplateTypeParmDecl *VisitDependentSizedExtVectorType(

2966 const DependentSizedExtVectorType *T) {

2967 return Visit(T->getElementType());

2968 }

2969

2970 TemplateTypeParmDecl *VisitVectorType(const VectorType *T) {

2971 return Visit(T->getElementType());

2972 }

2973

2974 TemplateTypeParmDecl *VisitFunctionProtoType(const FunctionProtoType *T) {

2975 return VisitFunctionType(T);

2976 }

2977

2978 TemplateTypeParmDecl *VisitFunctionType(const FunctionType *T) {

2980 }

2981

2982 TemplateTypeParmDecl *VisitParenType(const ParenType *T) {

2983 return Visit(T->getInnerType());

2984 }

2985

2986 TemplateTypeParmDecl *VisitAttributedType(const AttributedType *T) {

2987 return Visit(T->getModifiedType());

2988 }

2989

2990 TemplateTypeParmDecl *VisitMacroQualifiedType(const MacroQualifiedType *T) {

2991 return Visit(T->getUnderlyingType());

2992 }

2993

2994 TemplateTypeParmDecl *VisitAdjustedType(const AdjustedType *T) {

2995 return Visit(T->getOriginalType());

2996 }

2997

2998 TemplateTypeParmDecl *VisitPackExpansionType(const PackExpansionType *T) {

2999 return Visit(T->getPattern());

3000 }

3001 };

3002

3003}

3004

3008 bool EvaluateConstraints) {

3011

3014 if (!Index)

3015 Index = SemaRef.ArgPackSubstIndex;

3018 return false;

3019 }

3020

3022

3023 if (TemplArgInfo) {

3027 InstArgs))

3028 return true;

3029 }

3036 ->getEllipsisLoc()

3038}

3039

3044 bool ExpectParameterPack, bool EvaluateConstraint) {

3047

3050

3051

3052

3055 if (!NewTSI)

3056 return nullptr;

3057

3059

3060

3061

3063 NumExpansions);

3064 } else if (ExpectParameterPack) {

3065

3066

3067

3068

3070 diag::err_function_parameter_pack_without_parameter_packs)

3072 return nullptr;

3073 }

3074 } else {

3077 }

3078

3079 if (!NewTSI)

3080 return nullptr;

3081

3083 Diag(OldParm->getLocation(), diag::err_param_with_void_type);

3084 return nullptr;

3085 }

3086

3087

3088

3089

3090

3091

3092

3094 GetContainedInventedTypeParmVisitor().Visit(OldTSI->getType())) {

3095 if (const TypeConstraint *TC = TTP->getTypeConstraint()) {

3096 auto *Inst = cast_or_null(

3098

3099

3100

3101 if (Inst && !Inst->getTypeConstraint()) {

3103 return nullptr;

3104 }

3105 }

3106 }

3107

3112 if (!NewParm)

3113 return nullptr;

3114

3115

3123

3124

3125

3126

3127

3128

3129

3130

3131

3132

3134 }

3135

3139

3141

3143 } else {

3144

3146 }

3147

3148

3149

3151

3154

3156

3157 return NewParm;

3158}

3159

3168 "Cannot perform an instantiation without some context on the "

3169 "instantiation stack");

3170

3171 TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,

3173 return Instantiator.TransformFunctionTypeParams(

3174 Loc, Params, nullptr, ExtParamInfos, ParamTypes, OutParams, ParamInfos);

3175}

3176

3181 bool ForCallExpr) {

3183 Expr *PatternExpr = Param->getUninstantiatedDefaultArg();

3184

3187 if (AlreadyInstantiating) {

3188 Param->setInvalidDecl();

3189 return Diag(Param->getBeginLoc(), diag::err_recursive_default_argument)

3191 }

3192

3198 return true;

3199

3201

3202

3203

3204

3206 {

3207 std::optional LIS;

3208

3209 if (ForCallExpr) {

3210

3211

3212

3213

3214

3215 LIS.emplace(*this);

3217 false);

3218 if (addInstantiatedParametersToScope(FD, PatternFD, *LIS, TemplateArgs))

3219 return true;

3220 }

3221

3224 false);

3225 });

3226 }

3227 if (Result.isInvalid())

3228 return true;

3229

3230 if (ForCallExpr) {

3231

3235 Param->getLocation(),

3236 PatternExpr->getBeginLoc());

3238

3240 Result = InitSeq.Perform(*this, Entity, Kind, ResultE);

3241 if (Result.isInvalid())

3242 return true;

3243

3246 false);

3247 } else {

3248

3251 }

3252 if (Result.isInvalid())

3253 return true;

3254

3255

3256 Param->setDefaultArg(Result.getAs<Expr>());

3257

3258 return false;

3259}

3260

3261

3262

3263static bool

3270 auto ComputeInfo = [&S, &TemplateArgs, BaseSourceRange, BaseEllipsisLoc](

3272 bool IsLateExpansionAttempt, UnexpandedInfo &Info) {

3273

3274

3277 if (IsLateExpansionAttempt) {

3278

3279

3280 bool SawPackTypes =

3282 return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();

3283 });

3284 if (!SawPackTypes) {

3285 Info.Expand = false;

3286 return false;

3287 }

3288 }

3289

3290

3291

3292 Info.Expand = false;

3296 BaseEllipsisLoc, BaseSourceRange, Unexpanded, TemplateArgs,

3297 false, Info.Expand,

3299 };

3300

3301 if (ComputeInfo(Base.getTypeSourceInfo(), false, Info))

3302 return true;

3303

3305 Out = Base.getTypeSourceInfo();

3306 return false;

3307 }

3308

3309

3310 {

3312 Out = S.SubstType(Base.getTypeSourceInfo(), TemplateArgs,

3314 }

3315 if (!Out->getType()->containsUnexpandedParameterPack())

3316 return false;

3317

3318

3319

3320 if (ComputeInfo(Out, true, Info))

3321 return true;

3324 return false;

3325}

3326

3327bool

3333 for (const auto &Base : Pattern->bases()) {

3334 if (Base.getType()->isDependentType()) {

3335 if (const CXXRecordDecl *RD = Base.getType()->getAsCXXRecordDecl()) {

3336 if (RD->isInvalidDecl())

3338 }

3340 continue;

3341 }

3342

3345 if (Base.isPackExpansion()) {

3348 Info)) {

3350 continue;

3351 }

3352

3353

3357 ArgsForSubst = &EmptyList;

3358

3360 for (unsigned I = 0; I != *Info.NumExpansions; ++I) {

3362

3364 SubstType(BaseTypeLoc, *ArgsForSubst,

3366 if (!Expanded) {

3368 continue;

3369 }

3370

3372 Instantiation, Base.getSourceRange(), Base.isVirtual(),

3373 Base.getAccessSpecifierAsWritten(), Expanded,

3375 InstantiatedBases.push_back(InstantiatedBase);

3376 else

3378 }

3379

3380 continue;

3381 }

3382

3383

3384 EllipsisLoc = Base.getEllipsisLoc();

3386 BaseTypeLoc =

3387 SubstType(BaseTypeLoc, *ArgsForSubst,

3389 } else {

3390 BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),

3391 TemplateArgs,

3392 Base.getSourceRange().getBegin(),

3394 }

3395

3396 if (!BaseTypeLoc) {

3398 continue;

3399 }

3400

3403 Base.getSourceRange(),

3404 Base.isVirtual(),

3405 Base.getAccessSpecifierAsWritten(),

3406 BaseTypeLoc,

3407 EllipsisLoc))

3408 InstantiatedBases.push_back(InstantiatedBase);

3409 else

3411 }

3412

3415

3417}

3418

3419

3420namespace clang {

3421 namespace sema {

3427 }

3428}

3429

3435#ifndef NDEBUG

3438 assert(!AlreadyInstantiating && "should have been caught by caller");

3439#endif

3440

3441 return InstantiateClassImpl(PointOfInstantiation, Instantiation, Pattern,

3442 TemplateArgs, TSK, Complain);

3443}

3444

3445bool Sema::InstantiateClassImpl(

3449

3451 = cast_or_null(Pattern->getDefinition());

3452 if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Instantiation,

3454 Pattern, PatternDef, TSK, Complain))

3455 return true;

3456

3457 llvm::TimeTraceScope TimeScope("InstantiateClass", [&]() {

3458 llvm::TimeTraceMetadata M;

3459 llvm::raw_string_ostream OS(M.Detail);

3461 true);

3462 if (llvm::isTimeTraceVerbose()) {

3463 auto Loc = SourceMgr.getExpansionLoc(Instantiation->getLocation());

3464 M.File = SourceMgr.getFilename(Loc);

3465 M.Line = SourceMgr.getExpansionLineNumber(Loc);

3466 }

3467 return M;

3468 });

3469

3470 Pattern = PatternDef;

3471

3472

3473 if (MemberSpecializationInfo *MSInfo

3475 MSInfo->setTemplateSpecializationKind(TSK);

3476 MSInfo->setPointOfInstantiation(PointOfInstantiation);

3477 } else if (ClassTemplateSpecializationDecl *Spec

3478 = dyn_cast(Instantiation)) {

3479 Spec->setTemplateSpecializationKind(TSK);

3480 Spec->setPointOfInstantiation(PointOfInstantiation);

3481 }

3482

3483 NonSFINAEContext _(*this);

3484 InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);

3485 if (Inst.isInvalid())

3486 return true;

3487 PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(),

3488 "instantiating class definition");

3489

3490

3491

3492 ContextRAII SavedContext(*this, Instantiation);

3493 EnterExpressionEvaluationContext EvalContext(

3494 *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);

3495

3496

3497

3498

3500 LocalInstantiationScope Scope(*this, MergeWithParentScope);

3501

3502

3503

3504

3505

3506 SavePendingParsedClassStateRAII SavedPendingParsedClassState(*this);

3507

3508

3509 InstantiateAttrs(TemplateArgs, Pattern, Instantiation);

3510

3511

3513

3514

3515

3517

3518

3519 Instantiation->setTagKind(Pattern->getTagKind());

3520

3521

3522 if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))

3524

3525 TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);

3526 Instantiator.setEvaluateConstraints(false);

3527 SmallVector<Decl*, 4> Fields;

3528

3529 LateInstantiatedAttrVec LateAttrs;

3530 Instantiator.enableLateAttributeInstantiation(&LateAttrs);

3531

3532 bool MightHaveConstexprVirtualFunctions = false;

3533 for (auto *Member : Pattern->decls()) {

3534

3535

3536

3537

3538

3539

3540

3541

3542

3543 if (Member->getDeclContext() != Pattern)

3544 continue;

3545

3546

3547

3548

3549

3552 continue;

3553

3554 if (Member->isInvalidDecl()) {

3556 continue;

3557 }

3558

3559 Decl *NewMember = Instantiator.Visit(Member);

3560 if (NewMember) {

3561 if (FieldDecl *Field = dyn_cast(NewMember)) {

3562 Fields.push_back(Field);

3563 } else if (EnumDecl *Enum = dyn_cast(NewMember)) {

3564

3565

3566

3567

3569 Enum->isCompleteDefinition()) {

3570 MemberSpecializationInfo *MSInfo =Enum->getMemberSpecializationInfo();

3571 assert(MSInfo && "no spec info for member enum specialization");

3574 }

3575 } else if (StaticAssertDecl *SA = dyn_cast(NewMember)) {

3576 if (SA->isFailed()) {

3577

3578

3580 break;

3581 }

3582 } else if (CXXMethodDecl *MD = dyn_cast(NewMember)) {

3585 MightHaveConstexprVirtualFunctions = true;

3586 }

3587

3590 } else {

3591

3592

3593

3594

3595 }

3596 }

3597

3598

3599 ActOnFields(nullptr, Instantiation->getLocation(), Instantiation, Fields,

3600 SourceLocation(), SourceLocation(), ParsedAttributesView());

3601 CheckCompletedCXXClass(nullptr, Instantiation);

3602

3603

3604

3605

3606 if (ParsingClassDepth == 0)

3607 ActOnFinishCXXNonNestedClass();

3608

3609

3610

3611 for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(),

3612 E = LateAttrs.end(); I != E; ++I) {

3613 assert(CurrentInstantiationScope == Instantiator.getStartingScope());

3614 CurrentInstantiationScope = I->Scope;

3615

3616

3618 auto *ThisContext = dyn_cast_or_null(ND->getDeclContext());

3619 CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(),

3620 ND->isCXXInstanceMember());

3621

3622 Attr *NewAttr =

3624 if (NewAttr)

3625 I->NewDecl->addAttr(NewAttr);

3627 Instantiator.getStartingScope());

3628 }

3629 Instantiator.disableLateAttributeInstantiation();

3630 LateAttrs.clear();

3631

3632 ActOnFinishDelayedMemberInitializers(Instantiation);

3633

3634

3635

3637 Instantiation->setLocation(Pattern->getLocation());

3638 Instantiation->setLocStart(Pattern->getInnerLocStart());

3639 Instantiation->setBraceRange(Pattern->getBraceRange());

3640 }

3641

3643

3644 if (Pattern->isDependentContext())

3645 PerformDependentDiagnostics(Pattern, TemplateArgs);

3646

3647

3648

3650 P = Instantiator.delayed_partial_spec_begin(),

3651 PEnd = Instantiator.delayed_partial_spec_end();

3652 P != PEnd; ++P) {

3653 if (!Instantiator.InstantiateClassTemplatePartialSpecialization(

3654 P->first, P->second)) {

3656 break;

3657 }

3658 }

3659

3660

3661

3663 P = Instantiator.delayed_var_partial_spec_begin(),

3664 PEnd = Instantiator.delayed_var_partial_spec_end();

3665 P != PEnd; ++P) {

3666 if (!Instantiator.InstantiateVarTemplatePartialSpecialization(

3667 P->first, P->second)) {

3669 break;

3670 }

3671 }

3672 }

3673

3674

3675 SavedContext.pop();

3676

3678

3679

3680

3681

3683 MarkVTableUsed(PointOfInstantiation, Instantiation, true);

3684 else if (MightHaveConstexprVirtualFunctions)

3685 MarkVirtualMembersReferenced(PointOfInstantiation, Instantiation,

3686 true);

3687 }

3688

3689 Consumer.HandleTagDeclDefinition(Instantiation);

3690

3692}

3693

3698#ifndef NDEBUG

3701 assert(!AlreadyInstantiating && "should have been caught by caller");

3702#endif

3703

3707 Pattern, PatternDef, TSK,true))

3708 return true;

3709 Pattern = PatternDef;

3710

3711

3716 }

3717

3721 return true;

3723 "instantiating enum definition");

3724

3725

3726

3728

3729

3730

3731 ContextRAII SavedContext(*this, Instantiation);

3734

3736

3737

3739

3742

3743

3744 SavedContext.pop();

3745

3747}

3748

3752

3754 return false;

3755

3758 "pattern and instantiation disagree about init style");

3759

3762 if (AlreadyInstantiating)

3763

3764 return Diag(PointOfInstantiation,

3765 diag::err_default_member_initializer_cycle)

3766 << Instantiation;

3767

3768

3769

3771 if (!OldInit) {

3774 Diag(PointOfInstantiation,

3775 diag::err_default_member_initializer_not_yet_parsed)

3776 << OutermostClass << Pattern;

3777 Diag(Pattern->getEndLoc(),

3778 diag::note_default_member_initializer_not_yet_parsed);

3780 return true;

3781 }

3782

3786 return true;

3788 "instantiating default member init");

3789

3790

3791

3795 ExprEvalContexts.back().DelayedDefaultInitializationContext = {

3796 PointOfInstantiation, Instantiation, CurContext};

3797

3799

3800

3803

3805 false);

3810

3812 L->DefaultMemberInitializerInstantiated(Instantiation);

3813

3814

3816}

3817

3818namespace {

3819

3820

3821 struct PartialSpecMatchResult {

3824 };

3825}

3826

3831 return true;

3832

3837

3838

3839

3840

3841

3842

3843

3844

3845

3847 !CTPSD->getMostRecentDecl()->isMemberSpecialization())

3848 continue;

3849

3854 return true;

3855 }

3856

3857 return false;

3858}

3859

3860

3861

3862

3867 std::optionalSema::NonSFINAEContext NSC(S);

3870 return {true};

3871

3876

3878

3879

3880

3881

3882

3883

3884

3885

3886

3887 typedef PartialSpecMatchResult MatchResult;

3890 Template->getPartialSpecializations(PartialSpecs);

3893

3894

3895

3896

3897

3898

3899

3900

3901

3902

3903 if (Template->getMostRecentDecl()->isMemberSpecialization() &&

3904 !Partial->getMostRecentDecl()->isMemberSpecialization())

3905 continue;

3906

3911

3912

3916 (void)Result;

3917 } else {

3919 List.push_back(MatchResult{Partial, Info.takeCanonical()});

3920 }

3921 }

3922 if (Matched.empty() && PrimaryStrictPackMatch)

3923 Matched = std::move(ExtraMatched);

3924

3925

3926

3927

3928

3929 if (Matched.size() >= 1) {

3931 if (Matched.size() == 1) {

3932

3933

3934

3935 } else {

3936

3937

3938

3939

3940

3941

3942

3944 PEnd = Matched.end();

3945 P != PEnd; ++P) {

3947 P->Partial, Best->Partial, PointOfInstantiation) ==

3948 P->Partial)

3949 Best = P;

3950 }

3951

3952

3953

3956 PEnd = Matched.end();

3957 P != PEnd; ++P) {

3959 P->Partial, Best->Partial,

3960 PointOfInstantiation) != Best->Partial) {

3962 break;

3963 }

3964 }

3965

3967

3969 NSC.reset();

3970 S.Diag(PointOfInstantiation,

3971 diag::err_partial_spec_ordering_ambiguous)

3972 << ClassTemplateSpec;

3973

3974

3976 PEnd = Matched.end();

3977 P != PEnd; ++P)

3978 S.Diag(P->Partial->getLocation(), diag::note_partial_spec_match)

3980 P->Partial->getTemplateParameters(), *P->Args);

3981

3982 return {true};

3983 }

3984 }

3985

3987 } else {

3988

3989

3990 }

3991 }

3992

3995 if (auto *PartialSpec =

3997

3998 while (PartialSpec->getInstantiatedFromMember()) {

3999

4000

4001 if (PartialSpec->isMemberSpecialization())

4002 break;

4003

4004 PartialSpec = PartialSpec->getInstantiatedFromMember();

4005 }

4006 Pattern = PartialSpec;

4007 } else {

4009 while (Template->getInstantiatedFromMemberTemplate()) {

4010

4011

4012 if (Template->isMemberSpecialization())

4013 break;

4014

4016 }

4017 Pattern = Template->getTemplatedDecl();

4018 }

4019

4020 return Pattern;

4021}

4022

4027 bool PrimaryStrictPackMatch) {

4028

4032 return true;

4033

4036 if (AlreadyInstantiating)

4037 return false;

4038

4039 bool HadAvaibilityWarning =

4042

4045 ClassTemplateSpec, TSK,

4046 PrimaryStrictPackMatch);

4047

4050

4051 bool Err = InstantiateClassImpl(

4052 PointOfInstantiation, ClassTemplateSpec, Pattern.get(),

4054

4055

4056

4057

4058

4059 if (!Err && !HadAvaibilityWarning) {

4063 }

4064 return Err;

4065}

4066

4067void

4072

4073

4074

4075 assert(

4079 "Unexpected template specialization kind!");

4080 for (auto *D : Instantiation->decls()) {

4081 bool SuppressNew = false;

4082 if (auto *Function = dyn_cast(D)) {

4084 Function->getInstantiatedFromMemberFunction()) {

4085

4086 if (Function->getTrailingRequiresClause()) {

4090 continue;

4091 }

4092 }

4093

4094 if (Function->hasAttr())

4095 continue;

4096

4098 Function->getTemplateSpecializationKind();

4100 continue;

4101

4103 PointOfInstantiation, TSK, Function, PrevTSK,

4104 Function->getPointOfInstantiation(), SuppressNew) ||

4105 SuppressNew)

4106 continue;

4107

4108

4109

4110

4111

4112

4113

4115 continue;

4116

4117 Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);

4118

4119 if (Function->isDefined()) {

4120

4121

4127 std::make_pair(Function, PointOfInstantiation));

4128 }

4129 }

4130 } else if (auto *Var = dyn_cast(D)) {

4132 continue;

4133

4135 if (Var->hasAttr())

4136 continue;

4137

4139 assert(MSInfo && "No member specialization information?");

4142 continue;

4143

4145 Var,

4148 SuppressNew) ||

4149 SuppressNew)

4150 continue;

4151

4153

4154

4155

4156

4157

4158

4160 continue;

4161

4164 } else {

4166 }

4167 }

4168 } else if (auto *Record = dyn_cast(D)) {

4169 if (Record->hasAttr())

4170 continue;

4171

4172

4173

4174

4175

4176

4177 if (Record->isInjectedClassName() || Record->getPreviousDecl() ||

4179 continue;

4180

4182 assert(MSInfo && "No member specialization information?");

4183

4186 continue;

4187

4188 if (Context.getTargetInfo().getTriple().isOSWindows() &&

4190

4191

4192

4193

4194

4195

4196 continue;

4197 }

4198

4203 SuppressNew) ||

4204 SuppressNew)

4205 continue;

4206

4208 assert(Pattern && "Missing instantiated-from-template information");

4209

4210 if (Record->getDefinition()) {

4212

4213

4214

4215

4216

4217

4221 }

4222

4223 continue;

4224 }

4225

4227 TemplateArgs,

4228 TSK);

4229 } else {

4231 Record->getTemplateSpecializationKind() ==

4233 Record->setTemplateSpecializationKind(TSK);

4235 }

4236 }

4237

4238 Pattern = cast_or_null(Record->getDefinition());

4239 if (Pattern)

4241 TSK);

4242 } else if (auto *Enum = dyn_cast(D)) {

4244 assert(MSInfo && "No member specialization information?");

4245

4248 continue;

4249

4251 PointOfInstantiation, TSK, Enum,

4254 SuppressNew)

4255 continue;

4256

4257 if (Enum->getDefinition())

4258 continue;

4259

4260 EnumDecl *Pattern = Enum->getTemplateInstantiationPattern();

4261 assert(Pattern && "Missing instantiated-from-template information");

4262

4265 continue;

4266

4267 InstantiateEnum(PointOfInstantiation, Enum, Pattern, TemplateArgs, TSK);

4268 } else {

4271 }

4272 } else if (auto *Field = dyn_cast(D)) {

4273

4274

4276

4281

4283 ClassPattern->lookup(Field->getDeclName());

4285 assert(Pattern);

4287 TemplateArgs);

4288 }

4289 }

4290 }

4291}

4292

4293void

4298

4299

4300

4301

4302

4303

4304

4305

4308 TSK);

4309}

4310

4313 if (!S)

4314 return S;

4315

4316 TemplateInstantiator Instantiator(*this, TemplateArgs,

4319 return Instantiator.TransformStmt(S);

4320}

4321

4327 TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity);

4328 return Instantiator.TransformTemplateArgument(Input, Output);

4329}

4330

4335 TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),

4337 return Instantiator.TransformTemplateArguments(Args.begin(), Args.end(), Out);

4338}

4339

4344 TemplateInstantiator Instantiator(

4345 TemplateInstantiator::ForParameterMappingSubstitution, *this, BaseLoc,

4346 TemplateArgs, BuildPackExpansionTypes);

4347 return Instantiator.TransformTemplateArguments(Args.begin(), Args.end(), Out);

4348}

4349

4352 if (!E)

4353 return E;

4354

4355 TemplateInstantiator Instantiator(*this, TemplateArgs,

4358 return Instantiator.TransformExpr(E);

4359}

4360

4364 if (!E)

4365 return E;

4366

4367 TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),

4369 return Instantiator.TransformAddressOfOperand(E);

4370}

4371

4375

4376

4377 return SubstExpr(E, TemplateArgs);

4378}

4379

4382 if (!E)

4383 return E;

4384

4385 TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),

4387 Instantiator.setEvaluateConstraints(false);

4388 return Instantiator.TransformExpr(E);

4389}

4390

4394 TemplateInstantiator Instantiator(*this, MLTAL, SourceLocation(),

4400

4403 *this, ArgsAsWritten->arguments().front().getSourceRange().getBegin(),

4406 ArgsAsWritten->arguments().front().getSourceRange());

4407

4410

4411 if (Instantiator.TransformConceptTemplateArguments(

4415 SubstArgs))

4416 return true;

4417

4421

4426 false,

4427 NewArgList,

4428 true,

4429 nullptr,

4430 true);

4431

4432

4433

4434

4435

4436 struct ConstraintExprTransformer : TreeTransform {

4439

4440 ConstraintExprTransformer(Sema &SemaRef,

4443

4445 if (!E)

4446 return E;

4448 case Stmt::BinaryOperatorClass:

4449 case Stmt::ConceptSpecializationExprClass:

4450 case Stmt::ParenExprClass:

4451 case Stmt::UnresolvedLookupExprClass:

4452 return Base::TransformExpr(E);

4453 default:

4454 break;

4455 }

4456 return E;

4457 }

4458

4459

4460

4461

4463 if (!(E->getOpcode() == BinaryOperatorKind::BO_LAnd ||

4464 E->getOpcode() == BinaryOperatorKind::BO_LOr))

4465 return E;

4466

4469

4471 return E;

4472

4477 }

4478

4481 bool Uneval = false) {

4483 return Base::TransformTemplateArgument(Input, Output, Uneval);

4484

4485 Output = Input;

4486 return false;

4487 }

4488

4490 bool IsAddressOfOperand = false) {

4491 if (E->isConceptReference()) {

4493 return Res;

4494 }

4495 return E;

4496 }

4497 };

4498

4499 ConstraintExprTransformer Transformer(*this, MLTALForConstraint);

4501 Transformer.TransformExpr(const_cast<Expr *>(ConstraintExpr));

4502 return Res;

4503}

4504

4507 bool CXXDirectInit) {

4508 TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),

4510 return Instantiator.TransformInitializer(Init, CXXDirectInit);

4511}

4512

4516 if (Exprs.empty())

4517 return false;

4518

4519 TemplateInstantiator Instantiator(*this, TemplateArgs,

4522 return Instantiator.TransformExprs(Exprs.data(), Exprs.size(),

4523 IsCall, Outputs);

4524}

4525

4529 if (!NNS)

4531

4532 TemplateInstantiator Instantiator(*this, TemplateArgs, NNS.getBeginLoc(),

4534 return Instantiator.TransformNestedNameSpecifierLoc(NNS);

4535}

4536

4540 TemplateInstantiator Instantiator(*this, TemplateArgs, NameInfo.getLoc(),

4542 return Instantiator.TransformDeclarationNameInfo(NameInfo);

4543}

4544

4550 TemplateInstantiator Instantiator(*this, TemplateArgs, NameLoc,

4552 return Instantiator.TransformTemplateName(QualifierLoc, TemplateKWLoc, Name,

4553 NameLoc);

4554}

4555

4557

4558

4559

4560

4561 if (const ParmVarDecl *PV = dyn_cast(D)) {

4562 if (const FunctionDecl *FD = dyn_cast(PV->getDeclContext())) {

4563 unsigned i = PV->getFunctionScopeIndex();

4564

4565

4566 if (i < FD->getNumParams() && FD->getParamDecl(i) == PV)

4567 return FD->getCanonicalDecl()->getParamDecl(i);

4568 }

4569 }

4570 return D;

4571}

4572

4573llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *> *

4577 Current = Current->Outer) {

4578

4579

4580 const Decl *CheckD = D;

4581 do {

4582 LocalDeclsMap::iterator Found = Current->LocalDecls.find(CheckD);

4583 if (Found != Current->LocalDecls.end())

4584 return &Found->second;

4585

4586

4587

4588 if (const TagDecl *Tag = dyn_cast(CheckD))

4590 else

4591 CheckD = nullptr;

4592 } while (CheckD);

4593

4594

4595 if (!Current->CombineWithOuterScope)

4596 break;

4597 }

4598

4599 return nullptr;

4600}

4601

4602llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *> *

4607

4608

4611 return nullptr;

4612

4613

4614 if (const CXXRecordDecl *RD = dyn_cast(D))

4615 if (RD->isLocalClass())

4616 return nullptr;

4617

4618

4619

4621 return nullptr;

4622

4623

4624

4627 return nullptr;

4628

4629

4630

4631

4632 assert(isa(D) && "declaration not instantiated in this scope");

4633 return nullptr;

4634}

4635

4638 llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];

4639 if (Stored.isNull()) {

4640#ifndef NDEBUG

4641

4643 while (Current->CombineWithOuterScope && Current->Outer) {

4644 Current = Current->Outer;

4645 assert(!Current->LocalDecls.contains(D) &&

4646 "Instantiated local in inner and outer scopes");

4647 }

4648#endif

4649 Stored = Inst;

4650 } else if (DeclArgumentPack *Pack = dyn_cast<DeclArgumentPack *>(Stored)) {

4652 } else {

4653 assert(cast<Decl *>(Stored) == Inst && "Already instantiated this local");

4654 }

4655}

4656

4661 Pack->push_back(Inst);

4662}

4663

4665#ifndef NDEBUG

4666

4668 Current && Current->CombineWithOuterScope; Current = Current->Outer)

4669 assert(!Current->LocalDecls.contains(D) &&

4670 "Creating local pack after instantiation of local");

4671#endif

4672

4674 llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];

4676 Stored = Pack;

4677 ArgumentPacks.push_back(Pack);

4678}

4679

4682 if (llvm::is_contained(*Pack, D))

4683 return true;

4684 return false;

4685}

4686

4689 unsigned NumExplicitArgs) {

4690 assert((!PartiallySubstitutedPack || PartiallySubstitutedPack == Pack) &&

4691 "Already have a partially-substituted pack");

4692 assert((!PartiallySubstitutedPack

4693 || NumArgsInPartiallySubstitutedPack == NumExplicitArgs) &&

4694 "Wrong number of arguments in partially-substituted pack");

4695 PartiallySubstitutedPack = Pack;

4696 ArgsInPartiallySubstitutedPack = ExplicitArgs;

4697 NumArgsInPartiallySubstitutedPack = NumExplicitArgs;

4698}

4699

4702 unsigned *NumExplicitArgs) const {

4703 if (ExplicitArgs)

4704 *ExplicitArgs = nullptr;

4705 if (NumExplicitArgs)

4706 *NumExplicitArgs = 0;

4707

4709 Current = Current->Outer) {

4710 if (Current->PartiallySubstitutedPack) {

4711 if (ExplicitArgs)

4712 *ExplicitArgs = Current->ArgsInPartiallySubstitutedPack;

4713 if (NumExplicitArgs)

4714 *NumExplicitArgs = Current->NumArgsInPartiallySubstitutedPack;

4715

4716 return Current->PartiallySubstitutedPack;

4717 }

4718

4719 if (!Current->CombineWithOuterScope)

4720 break;

4721 }

4722

4723 return nullptr;

4724}

This file provides AST data structures related to concepts.

Defines the clang::ASTContext interface.

This file provides some common utility functions for processing Lambda related AST Constructs.

This file defines the classes used to store parsed information about declaration-specifiers and decla...

Defines the C++ template declaration subclasses.

Defines Expressions and AST nodes for C++2a concepts.

FormatToken * Next

The next token in the unwrapped line.

Defines the clang::LangOptions interface.

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

llvm::MachO::Record Record

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)

static bool PreparePackForExpansion(Sema &S, const CXXBaseSpecifier &Base, const MultiLevelTemplateArgumentList &TemplateArgs, TypeSourceInfo *&Out, UnexpandedInfo &Info)

Definition SemaTemplateInstantiate.cpp:3264

static const Decl * getCanonicalParmVarDecl(const Decl *D)

Definition SemaTemplateInstantiate.cpp:4556

static ActionResult< CXXRecordDecl * > getPatternForClassTemplateSpecialization(Sema &S, SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, TemplateSpecializationKind TSK, bool PrimaryStrictPackMatch)

Get the instantiation pattern to use to instantiate the definition of a given ClassTemplateSpecializa...

Definition SemaTemplateInstantiate.cpp:3863

static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T)

Definition SemaTemplateInstantiate.cpp:2829

static concepts::Requirement::SubstitutionDiagnostic * createSubstDiag(Sema &S, TemplateDeductionInfo &Info, Sema::EntityPrinter Printer)

Definition SemaTemplateInstantiate.cpp:2532

static std::string convertCallArgsToString(Sema &S, llvm::ArrayRef< const Expr * > Args)

Definition SemaTemplateInstantiate.cpp:888

Defines the clang::TypeLoc interface and its subclasses.

C Language Family Type Representation.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

const clang::PrintingPolicy & getPrintingPolicy() const

The result of parsing/analyzing an expression, statement etc.

Attr - This represents one attribute.

A builtin binary operation expression such as "x + y" or "x <= y".

SourceLocation getOperatorLoc() const

static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)

Represents a base class of a C++ class.

SourceLocation getUsedLocation() const

Retrieve the location where this default argument was actually used.

const ParmVarDecl * getParam() const

Represents a C++ struct/union/class.

Decl * getLambdaContextDecl() const

Retrieve the declaration that provides additional context for a lambda, when the normal declaration c...

const FunctionDecl * isLocalClass() const

If the class is a local class [class.local], returns the enclosing function declaration.

CXXRecordDecl * getInstantiatedFromMemberClass() const

If this record is an instantiation of a member class, retrieves the member class from which it was in...

bool isLambda() const

Determine whether this class describes a lambda function object.

CXXRecordDecl * getDefinition() const

unsigned getNumBases() const

Retrieves the number of base classes of this class.

const CXXRecordDecl * getTemplateInstantiationPattern() const

Retrieve the record declaration from which this record could be instantiated.

TemplateSpecializationKind getTemplateSpecializationKind() const

Determine whether this particular class is a specialization or instantiation of a class template or m...

ClassTemplateDecl * getDescribedClassTemplate() const

Retrieves the class template that is described by this class declaration.

MemberSpecializationInfo * getMemberSpecializationInfo() const

If this class is an instantiation of a member class of a class template specialization,...

CXXMethodDecl * getLambdaCallOperator() const

Retrieve the lambda call operator of the closure type if this is a closure type.

CXXRecordDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

Declaration of a class template.

ClassTemplateDecl * getMostRecentDecl()

llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations() const

Retrieve the set of partial specializations of this class template.

Represents a class template specialization, which refers to a class template with a given set of temp...

TemplateSpecializationKind getSpecializationKind() const

Determine the kind of specialization that this declaration represents.

ClassTemplateDecl * getSpecializedTemplate() const

Retrieve the template that this specialization specializes.

bool isClassScopeExplicitSpecialization() const

Is this an explicit specialization at class scope (within the class that owns the primary template)?

llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const

Retrieve the class template or class template partial specialization which was specialized by this.

const TemplateArgumentList & getTemplateArgs() const

Retrieve the template arguments of the class template specialization.

const TemplateArgumentList & getTemplateInstantiationArgs() const

Retrieve the set of template arguments that should be used to instantiate members of the class templa...

void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs)

Note that this class template specialization is actually an instantiation of the given class template...

NamedDecl * getFoundDecl() const

Represents the specialization of a concept - evaluates to a prvalue of type bool.

const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const

ConceptDecl * getNamedConcept() const

const TypeClass * getTypePtr() const

The result of a constraint satisfaction check, containing the necessary information to diagnose an un...

bool HasSubstitutionFailure()

static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

bool isFileContext() const

DeclContextLookupResult lookup_result

bool isDependentContext() const

Determines whether this context is dependent on a template parameter.

lookup_result lookup(DeclarationName Name) const

lookup - Find the declarations (if any) with the given Name in this context.

RecordDecl * getOuterLexicalRecordContext()

Retrieve the outermost lexically enclosing record context.

decl_range decls() const

decls_begin/decls_end - Iterate over the declarations stored in this context.

SourceLocation getLocation() const

Decl - This represents one declaration (or definition), e.g.

Decl * getPreviousDecl()

Retrieve the previous declaration that declares the same entity as this declaration,...

TemplateDecl * getDescribedTemplate() const

If this is a declaration that describes some template, this method returns that template declaration.

FriendObjectKind getFriendObjectKind() const

Determines whether this declaration is the object of a friend declaration and, if so,...

bool isParameterPack() const

Whether this declaration is a parameter pack.

void setInvalidDecl(bool Invalid=true)

setInvalidDecl - Indicates the Decl had a semantic error.

bool isFileContextDecl() const

static Decl * castFromDeclContext(const DeclContext *)

unsigned getTemplateDepth() const

Determine the number of levels of template parameter surrounding this declaration.

DeclContext * getNonTransparentDeclContext()

Return the non transparent context.

bool isInvalidDecl() const

SourceLocation getLocation() const

void setLocation(SourceLocation L)

bool isDefinedOutsideFunctionOrMethod() const

isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...

DeclContext * getDeclContext()

void setDeclContext(DeclContext *DC)

setDeclContext - Set both the semantic and lexical DeclContext to DC.

DeclContext * getLexicalDeclContext()

getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).

void setVisibleDespiteOwningModule()

Set that this declaration is globally visible, even if it came from a module that is not visible.

The name of a declaration.

SourceLocation getInnerLocStart() const

Return start of source range ignoring outer template declarations.

NestedNameSpecifier getQualifier() const

Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...

TypeSourceInfo * getTypeSourceInfo() const

RAII object that enters a new expression evaluation context.

MemberSpecializationInfo * getMemberSpecializationInfo() const

If this enumeration is an instantiation of a member enumeration of a class template specialization,...

EnumDecl * getInstantiatedFromMemberEnum() const

Returns the enumeration (declared within the template) from which this enumeration type was instantia...

EnumDecl * getDefinition() const

This represents one expression.

bool isTypeDependent() const

Determines whether the type of this expression depends on.

llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const

EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.

bool isInstantiationDependent() const

Whether this expression is instantiation-dependent, meaning that it depends in some way on.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

bool hasPlaceholderType() const

Returns whether this expression has a placeholder type.

ExprDependence getDependence() const

Represents difference between two FPOptions values.

Represents a member of a struct/union/class.

Expr * getInClassInitializer() const

Get the C++11 default member initializer for this member, or null if one has not been set.

bool hasInClassInitializer() const

Determine whether this member has a C++11 default member initializer.

InClassInitStyle getInClassInitStyle() const

Get the kind of (C++11) default member initializer that this field has.

const RecordDecl * getParent() const

Returns the parent of this field declaration, which is the struct in which this field is defined.

Represents a function declaration or definition.

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...

FunctionTemplateDecl * getPrimaryTemplate() const

Retrieve the primary template that this function template specialization either specializes or was in...

bool isConstexpr() const

Whether this is a (C++11) constexpr function or constexpr constructor.

bool isVirtualAsWritten() const

Whether this function is marked as virtual explicitly.

static FunctionParmPackExpr * Create(const ASTContext &Context, QualType T, ValueDecl *ParamPack, SourceLocation NameLoc, ArrayRef< ValueDecl * > Params)

ValueDecl * getExpansion(unsigned I) const

Get an expansion of the parameter pack by index.

ValueDecl *const * iterator

Iterators over the parameters which the parameter pack expanded into.

ValueDecl * getParameterPack() const

Get the parameter pack which this expression refers to.

unsigned getNumExpansions() const

Get the number of parameters in this parameter pack.

SourceLocation getParameterPackLocation() const

Get the location of the parameter pack.

Represents a prototype with parameter type info, e.g.

ExtProtoInfo getExtProtoInfo() const

Declaration of a template function.

FunctionDecl * getTemplatedDecl() const

Get the underlying function declaration of the template.

ArrayRef< ParmVarDecl * > getParams() const

Interesting information about a specific parameter that can't simply be reflected in parameter's type...

QualType getReturnType() const

ArrayRef< TemplateArgument > getTemplateArguments() const

const TypeClass * getTypePtr() const

Describes the kind of initialization being performed, along with location information for tokens rela...

static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)

Create a copy initialization.

Describes an entity that is being initialized.

static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)

Create the initialization entity for a parameter.

A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...

A stack-allocated class that identifies which local variable declaration instantiations are present i...

LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope=false, bool InstantiatingLambdaOrBlock=false)

void SetPartiallySubstitutedPack(NamedDecl *Pack, const TemplateArgument *ExplicitArgs, unsigned NumExplicitArgs)

Note that the given parameter pack has been partially substituted via explicit specification of templ...

Definition SemaTemplateInstantiate.cpp:4687

NamedDecl * getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs=nullptr, unsigned *NumExplicitArgs=nullptr) const

Retrieve the partially-substitued template parameter pack.

Definition SemaTemplateInstantiate.cpp:4700

bool isLocalPackExpansion(const Decl *D)

Determine whether D is a pack expansion created in this scope.

Definition SemaTemplateInstantiate.cpp:4680

SmallVector< ValueDecl *, 4 > DeclArgumentPack

A set of declarations.

llvm::PointerUnion< Decl *, DeclArgumentPack * > * getInstantiationOfIfExists(const Decl *D)

Similar to findInstantiationOf(), but it wouldn't assert if the instantiation was not found within th...

Definition SemaTemplateInstantiate.cpp:4574

static void deleteScopes(LocalInstantiationScope *Scope, LocalInstantiationScope *Outermost)

deletes the given scope, and all outer scopes, down to the given outermost scope.

void InstantiatedLocal(const Decl *D, Decl *Inst)

Definition SemaTemplateInstantiate.cpp:4636

void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst)

Definition SemaTemplateInstantiate.cpp:4657

bool isLambdaOrBlock() const

Determine whether this scope is for instantiating a lambda or block.

void MakeInstantiatedLocalArgPack(const Decl *D)

Definition SemaTemplateInstantiate.cpp:4664

llvm::PointerUnion< Decl *, DeclArgumentPack * > * findInstantiationOf(const Decl *D)

Find the instantiation of the declaration D within the current instantiation scope.

Definition SemaTemplateInstantiate.cpp:4603

Provides information a specialization of a member of a class template, which may be a member function...

void setTemplateSpecializationKind(TemplateSpecializationKind TSK)

Set the template specialization kind.

TemplateSpecializationKind getTemplateSpecializationKind() const

Determine what kind of template specialization this is.

SourceLocation getPointOfInstantiation() const

Retrieve the first point of instantiation of this member.

void setPointOfInstantiation(SourceLocation POI)

Set the first point of instantiation.

Describes a module or submodule.

Data structure that captures multiple levels of template argument lists for use in template instantia...

bool hasTemplateArgument(unsigned Depth, unsigned Index) const

Determine whether there is a non-NULL template argument at the given depth and index.

const ArgList & getInnermost() const

Retrieve the innermost template argument list.

std::pair< Decl *, bool > getAssociatedDecl(unsigned Depth) const

A template-like entity which owns the whole pattern being substituted.

unsigned getNumLevels() const

Determine the number of levels in this template argument list.

unsigned getNumSubstitutedLevels() const

Determine the number of substituted levels in this template argument list.

unsigned getNewDepth(unsigned OldDepth) const

Determine how many of the OldDepth outermost template parameter lists would be removed by substitutin...

void setArgument(unsigned Depth, unsigned Index, TemplateArgument Arg)

Clear out a specific template argument.

bool isRewrite() const

Determine whether we are rewriting template parameters rather than substituting for them.

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const

Appends a human-readable name for this declaration into the given stream.

virtual void printName(raw_ostream &OS, const PrintingPolicy &Policy) const

Pretty-print the unqualified name of this declaration.

A C++ nested-name-specifier augmented with source location information.

SourceLocation getBeginLoc() const

Retrieve the location of the beginning of this nested-name-specifier.

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.

unsigned getPosition() const

Get the position of the template parameter within its parameter list.

bool isParameterPack() const

Whether this parameter is a non-type template parameter pack.

unsigned getDepth() const

Get the nesting depth of the template parameter.

SourceLocation getEllipsisLoc() const

TypeLoc getPatternLoc() const

Represents a parameter to a function.

unsigned getFunctionScopeIndex() const

Returns the index of this parameter in its prototype or method scope.

SourceLocation getExplicitObjectParamThisLoc() const

void setUnparsedDefaultArg()

Specify that this parameter has an unparsed default argument.

bool hasUnparsedDefaultArg() const

Determines whether this parameter has a default argument that has not yet been parsed.

void setUninstantiatedDefaultArg(Expr *arg)

void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)

bool hasUninstantiatedDefaultArg() const

bool hasInheritedDefaultArg() const

void setExplicitObjectParameterLoc(SourceLocation Loc)

Expr * getUninstantiatedDefaultArg()

unsigned getFunctionScopeDepth() const

void setHasInheritedDefaultArg(bool I=true)

PredefinedIdentKind getIdentKind() const

SourceLocation getLocation() const

PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...

A (possibly-)qualified type.

QualType getNonLValueExprType(const ASTContext &Context) const

Determine the type of a (typically non-lvalue) expression with the specified result type.

void addConst()

Add the const type qualifier to this QualType.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const

The collection of all-type qualifiers we support.

void removeObjCLifetime()

Represents a struct/union/class.

bool isMemberSpecialization() const

Determines whether this template was a specialization of a member template.

Represents the body of a requires-expression.

C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...

SourceLocation getLParenLoc() const

SourceLocation getRParenLoc() const

RequiresExprBodyDecl * getBody() const

Scope - A scope is a transient data structure that is used while parsing the program.

PartialDiagnostic PDiag(unsigned DiagID=0)

Build a partial diagnostic.

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...

For a defaulted function, the kind of defaulted function that it is.

DefaultedComparisonKind asComparison() const

bool isSpecialMember() const

bool isComparison() const

CXXSpecialMemberKind asSpecialMember() const

A helper class for building up ExtParameterInfos.

RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...

Sema - This implements semantic analysis and AST building for C.

llvm::DenseSet< Module * > LookupModulesCache

Cache of additional modules that should be used for name lookup within the current template instantia...

bool SubstTypeConstraint(TemplateTypeParmDecl *Inst, const TypeConstraint *TC, const MultiLevelTemplateArgumentList &TemplateArgs, bool EvaluateConstraint)

Definition SemaTemplateInstantiate.cpp:3005

SmallVector< CodeSynthesisContext, 16 > CodeSynthesisContexts

List of active code synthesis contexts.

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.

DefaultedFunctionKind getDefaultedFunctionKind(const FunctionDecl *FD)

Determine the kind of defaulting that would be done for a given function.

ExprResult SubstConceptTemplateArguments(const ConceptSpecializationExpr *CSE, const Expr *ConstraintExpr, const MultiLevelTemplateArgumentList &MLTAL)

Substitute concept template arguments in the constraint expression of a concept-id.

Definition SemaTemplateInstantiate.cpp:4391

NamedDecl * FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext=false)

Find the instantiation of the given declaration within the current instantiation.

llvm::function_ref< void(SourceLocation, PartialDiagnostic)> InstantiationContextDiagFuncRef

TemplateName SubstTemplateName(SourceLocation TemplateKWLoc, NestedNameSpecifierLoc &QualifierLoc, TemplateName Name, SourceLocation NameLoc, const MultiLevelTemplateArgumentList &TemplateArgs)

Definition SemaTemplateInstantiate.cpp:4546

ParmVarDecl * SubstParmVarDecl(ParmVarDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, int indexAdjustment, UnsignedOrNone NumExpansions, bool ExpectParameterPack, bool EvaluateConstraints=true)

Definition SemaTemplateInstantiate.cpp:3041

void InstantiateClassTemplateSpecializationMembers(SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, TemplateSpecializationKind TSK)

Instantiate the definitions of all of the members of the given class template specialization,...

Definition SemaTemplateInstantiate.cpp:4294

ClassTemplatePartialSpecializationDecl * getMoreSpecializedPartialSpecialization(ClassTemplatePartialSpecializationDecl *PS1, ClassTemplatePartialSpecializationDecl *PS2, SourceLocation Loc)

Returns the more specialized class template partial specialization according to the rules of partial ...

ExprResult SubstInitializer(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs, bool CXXDirectInit)

Definition SemaTemplateInstantiate.cpp:4505

llvm::function_ref< void(llvm::raw_ostream &)> EntityPrinter

void SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, const MultiLevelTemplateArgumentList &Args)

Definition SemaTemplateInstantiate.cpp:2907

concepts::Requirement::SubstitutionDiagnostic * createSubstDiagAt(SourceLocation Location, EntityPrinter Printer)

create a Requirement::SubstitutionDiagnostic with only a SubstitutedEntity and DiagLoc using ASTConte...

Definition SemaTemplateInstantiate.cpp:2554

bool SubstExprs(ArrayRef< Expr * > Exprs, bool IsCall, const MultiLevelTemplateArgumentList &TemplateArgs, SmallVectorImpl< Expr * > &Outputs)

Substitute the given template arguments into a list of expressions, expanding pack expansions if requ...

Definition SemaTemplateInstantiate.cpp:4513

StmtResult SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs)

Definition SemaTemplateInstantiate.cpp:4312

bool InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, TemplateSpecializationKind TSK, bool Complain, bool PrimaryStrictPackMatch)

Definition SemaTemplateInstantiate.cpp:4023

ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)

Definition SemaTemplateInstantiate.cpp:4351

DiagnosticsEngine & getDiagnostics() const

bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef< UnexpandedParameterPack > Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs, bool FailOnPackProducingTemplates, bool &ShouldExpand, bool &RetainExpansion, UnsignedOrNone &NumExpansions, bool Diagnose=true)

Determine whether we could expand a pack expansion with the given set of parameter packs into separat...

ExprResult SubstConstraintExprWithoutSatisfaction(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)

Definition SemaTemplateInstantiate.cpp:4380

void PrintInstantiationStack()

ASTContext & getASTContext() const

TypeSourceInfo * SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, bool AllowDeducedTST=false)

Perform substitution on the type T with a given set of template arguments.

Definition SemaTemplateInstantiate.cpp:2758

void InstantiateVariableDefinition(SourceLocation PointOfInstantiation, VarDecl *Var, bool Recursive=false, bool DefinitionRequired=false, bool AtEndOfTU=false)

Instantiate the definition of the given variable from its template.

void ActOnStartCXXInClassMemberInitializer()

Enter a new C++ default initializer scope.

PrintingPolicy getPrintingPolicy() const

Retrieve a suitable printing policy for diagnostics.

bool pushCodeSynthesisContext(CodeSynthesisContext Ctx)

Definition SemaTemplateInstantiate.cpp:824

bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)

Definition SemaTemplateInstantiate.cpp:4331

Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, TranslationUnitKind TUKind=TU_Complete, CodeCompleteConsumer *CompletionConsumer=nullptr)

void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Pattern, Decl *Inst, LateInstantiatedAttrVec *LateAttrs=nullptr, LocalInstantiationScope *OuterMostScope=nullptr)

const LangOptions & getLangOpts() const

void collectUnexpandedParameterPacks(TemplateArgument Arg, SmallVectorImpl< UnexpandedParameterPack > &Unexpanded)

Collect the set of unexpanded parameter packs within the given template argument.

void InstantiateClassMembers(SourceLocation PointOfInstantiation, CXXRecordDecl *Instantiation, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateSpecializationKind TSK)

Instantiates the definitions of all of the member of the given class, which is an instantiation of a ...

Definition SemaTemplateInstantiate.cpp:4068

DeclarationNameInfo SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo, const MultiLevelTemplateArgumentList &TemplateArgs)

Do template substitution on declaration name info.

Definition SemaTemplateInstantiate.cpp:4538

void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class, bool DefinitionRequired=false)

Note that the vtable for the given class was used at the given location.

TemplateArgument getPackSubstitutedTemplateArgument(TemplateArgument Arg) const

void popCodeSynthesisContext()

Definition SemaTemplateInstantiate.cpp:851

bool usesPartialOrExplicitSpecialization(SourceLocation Loc, ClassTemplateSpecializationDecl *ClassTemplateSpec)

Definition SemaTemplateInstantiate.cpp:3827

bool CheckLoopHintExpr(Expr *E, SourceLocation Loc, bool AllowZero)

CXXBaseSpecifier * CheckBaseSpecifier(CXXRecordDecl *Class, SourceRange SpecifierRange, bool Virtual, AccessSpecifier Access, TypeSourceInfo *TInfo, SourceLocation EllipsisLoc)

Check the validity of a C++ base class specifier.

UnparsedDefaultArgInstantiationsMap UnparsedDefaultArgInstantiations

A mapping from parameters with unparsed default arguments to the set of instantiations of each parame...

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...

Definition SemaTemplateInstantiate.cpp:3160

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...

Definition SemaTemplateInstantiate.cpp:489

std::deque< PendingImplicitInstantiation > PendingLocalImplicitInstantiations

The queue of implicit template instantiations that are required and must be performed within the curr...

ParmVarDecl * CheckParameter(DeclContext *DC, SourceLocation StartLoc, SourceLocation NameLoc, const IdentifierInfo *Name, QualType T, TypeSourceInfo *TSInfo, StorageClass SC)

bool CheckFunctionConstraints(const FunctionDecl *FD, ConstraintSatisfaction &Satisfaction, SourceLocation UsageLoc=SourceLocation(), bool ForOverloadResolution=false)

Check whether the given function decl's trailing requires clause is satisfied, if any.

bool CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, TemplateSpecializationKind ActOnExplicitInstantiationNewTSK, NamedDecl *PrevDecl, TemplateSpecializationKind PrevTSK, SourceLocation PrevPtOfInstantiation, bool &SuppressNew)

Diagnose cases where we have an explicit template specialization before/after an explicit template in...

unsigned NonInstantiationEntries

The number of CodeSynthesisContexts that are not template instantiations and, therefore,...

bool CheckNoInlineAttr(const Stmt *OrigSt, const Stmt *CurSt, const AttributeCommonInfo &A)

void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc, ExprResult Init)

This is invoked after parsing an in-class initializer for a non-static C++ class member,...

bool inConstraintSubstitution() const

Determine whether we are currently performing constraint substitution.

bool CheckAlwaysInlineAttr(const Stmt *OrigSt, const Stmt *CurSt, const AttributeCommonInfo &A)

void DiagnoseAvailabilityOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass, bool ObjCPropertyAccess, bool AvoidPartialAvailabilityChecks, ObjCInterfaceDecl *ClassReceiver)

bool AttachTypeConstraint(NestedNameSpecifierLoc NS, DeclarationNameInfo NameInfo, TemplateDecl *NamedConcept, NamedDecl *FoundDecl, const TemplateArgumentListInfo *TemplateArgs, TemplateTypeParmDecl *ConstrainedParameter, SourceLocation EllipsisLoc)

Attach a type-constraint to a template parameter.

std::pair< AvailabilityResult, const NamedDecl * > ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message, ObjCInterfaceDecl *ClassReceiver)

The diagnostic we should emit for D, and the declaration that originated it, or AR_Available.

bool InstantiateInClassInitializer(SourceLocation PointOfInstantiation, FieldDecl *Instantiation, FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs)

Instantiate the definition of a field from the given pattern.

Definition SemaTemplateInstantiate.cpp:3749

UnsignedOrNone ArgPackSubstIndex

The current index into pack expansion arguments that will be used for substitution of parameter packs...

bool InstantiateClass(SourceLocation PointOfInstantiation, CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateSpecializationKind TSK, bool Complain=true)

Instantiate the definition of a class from a given pattern.

Definition SemaTemplateInstantiate.cpp:3430

bool SubstTemplateArgument(const TemplateArgumentLoc &Input, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentLoc &Output, SourceLocation Loc={}, const DeclarationName &Entity={})

Definition SemaTemplateInstantiate.cpp:4322

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.

bool SubstDefaultArgument(SourceLocation Loc, ParmVarDecl *Param, const MultiLevelTemplateArgumentList &TemplateArgs, bool ForCallExpr=false)

Substitute the given template arguments into the default argument.

Definition SemaTemplateInstantiate.cpp:3177

ExprResult SubstConstraintExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)

Definition SemaTemplateInstantiate.cpp:4373

@ ConstantEvaluated

The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...

@ PotentiallyEvaluated

The current expression is potentially evaluated at run time, which means that code may be generated t...

unsigned LastEmittedCodeSynthesisContextDepth

The depth of the context stack at the point when the most recent error or warning was produced.

bool inParameterMappingSubstitution() const

NestedNameSpecifierLoc SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const MultiLevelTemplateArgumentList &TemplateArgs)

Definition SemaTemplateInstantiate.cpp:4527

bool RebuildingImmediateInvocation

Whether the AST is currently being rebuilt to correct immediate invocations.

SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts

A stack of expression evaluation contexts.

bool DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation, NamedDecl *Instantiation, bool InstantiatedFromMember, const NamedDecl *Pattern, const NamedDecl *PatternDef, TemplateSpecializationKind TSK, bool Complain=true, bool *Unreachable=nullptr)

Determine whether we would be unable to instantiate this template (because it either has no definitio...

DiagnosticsEngine & Diags

bool AttachBaseSpecifiers(CXXRecordDecl *Class, MutableArrayRef< CXXBaseSpecifier * > Bases)

Performs the actual work of attaching the given base class specifiers to a C++ class.

friend class InitializationSequence

SmallVector< Module *, 16 > CodeSynthesisContextLookupModules

Extra modules inspected when performing a lookup during a template instantiation.

ExprResult ConvertParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc)

TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef< TemplateArgument > TemplateArgs, sema::TemplateDeductionInfo &Info)

void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)

Run some code with "sufficient" stack space.

bool SubstTemplateArgumentsInParameterMapping(ArrayRef< TemplateArgumentLoc > Args, SourceLocation BaseLoc, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Out, bool BuildPackExpansionTypes)

Definition SemaTemplateInstantiate.cpp:4340

ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())

Attempts to produce a RecoveryExpr after some AST node cannot be created.

bool InstantiateEnum(SourceLocation PointOfInstantiation, EnumDecl *Instantiation, EnumDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateSpecializationKind TSK)

Instantiate the definition of an enum from a given pattern.

Definition SemaTemplateInstantiate.cpp:3694

void UpdateExceptionSpec(FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI)

ExprResult SubstCXXIdExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)

Substitute an expression as if it is a address-of-operand, which makes it act like a CXXIdExpression ...

Definition SemaTemplateInstantiate.cpp:4362

std::string getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgumentList &Args)

Produces a formatted string that describes the binding of template parameters to template arguments.

bool SubstBaseSpecifiers(CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs)

Perform substitution on the base class specifiers of the given class template specialization.

Definition SemaTemplateInstantiate.cpp:3328

void PerformDependentDiagnostics(const DeclContext *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs)

TypeSourceInfo * CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, UnsignedOrNone NumExpansions)

Construct a pack expansion type from the pattern of the pack expansion.

ASTMutationListener * getASTMutationListener() const

ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)

TypeSourceInfo * SubstFunctionDeclType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, CXXRecordDecl *ThisContext, Qualifiers ThisTypeQuals, bool EvaluateConstraints=true)

A form of SubstType intended specifically for instantiating the type of a FunctionDecl.

Definition SemaTemplateInstantiate.cpp:2851

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

A trivial tuple used to represent a source range.

SourceLocation getBegin() const

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const

StmtClass getStmtClass() const

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

SourceLocation getBeginLoc() const LLVM_READONLY

Represents the declaration of a struct/union/class/enum.

void setTagKind(TagKind TK)

void startDefinition()

Starts the definition of this tag declaration.

void setBraceRange(SourceRange R)

SourceLocation getNameLoc() const

A convenient class for passing around template argument information.

void setLAngleLoc(SourceLocation Loc)

void setRAngleLoc(SourceLocation Loc)

ArrayRef< TemplateArgumentLoc > arguments() const

A template argument list.

ArrayRef< TemplateArgument > asArray() const

Produce this as an array ref.

Location wrapper for a TemplateArgument.

const TemplateArgument & getArgument() const

Represents a template argument.

ArrayRef< TemplateArgument > getPackAsArray() const

Return the array of arguments in this template argument pack.

Expr * getAsExpr() const

Retrieve the template argument as an expression.

bool isDependent() const

Whether this template argument is dependent on a template parameter such that its result can change f...

pack_iterator pack_begin() const

Iterator referencing the first argument of a template argument pack.

bool isConceptOrConceptTemplateParameter() const

QualType getAsType() const

Retrieve the type for a type template argument.

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.

unsigned pack_size() const

The number of template arguments in the given template argument pack.

@ Template

The template argument is a template name that was provided for a template template parameter.

@ Pack

The template argument is actually a parameter pack.

@ Type

The template argument is a type.

@ 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.

SmallVectorImpl< std::pair< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > >::iterator delayed_partial_spec_iterator

void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern)

SmallVectorImpl< std::pair< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > >::iterator delayed_var_partial_spec_iterator

The base class of all kinds of template declarations (e.g., class, function, etc.).

TemplateParameterList * getTemplateParameters() const

Get the list of template parameters.

Represents a C++ template name within the type system.

TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const

Retrieve the underlying template declaration that this template name refers to, if known.

@ Template

A single template declaration.

SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const

Retrieve the substituted template template parameter pack, if known.

Stores a list of template parameters for a TemplateDecl and its derived classes.

NamedDecl * getParam(unsigned Idx)

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation getTemplateLoc() const

TemplateSpecCandidateSet - A set of generalized overload candidates, used in template specializations...

SourceLocation getLocation() const

TemplateSpecCandidate & addCandidate()

Add a new candidate with NumConversions conversion sequence slots to the overload set.

TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.

unsigned getDepth() const

Get the nesting depth of the template parameter.

Declaration of a template type parameter.

void setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint, UnsignedOrNone ArgPackSubstIndex)

bool isParameterPack() const

Returns whether this is a parameter pack.

A semantic tree transformation that allows one to transform one abstract syntax tree into another.

QualType TransformTemplateSpecializationType(TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, QualType ObjectType, NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName)

Declaration of an alias template.

TypeAliasDecl * getTemplatedDecl() const

Get the underlying function declaration of the template.

Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...

const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const

UnsignedOrNone getArgPackSubstIndex() const

Expr * getImmediatelyDeclaredConstraint() const

Get the immediately-declared constraint expression introduced by this type-constraint,...

const NestedNameSpecifierLoc & getNestedNameSpecifierLoc() const

TemplateDecl * getNamedConcept() const

const DeclarationNameInfo & getConceptNameInfo() const

ConceptReference * getConceptReference() const

void setLocStart(SourceLocation L)

TyLocType push(QualType T)

Pushes space for a new TypeLoc of the given type.

void pushFullCopy(TypeLoc L)

Pushes a copy of the given TypeLoc onto this builder.

void reserve(size_t Requested)

Ensures that this buffer has at least as much capacity as described.

TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)

Creates a TypeSourceInfo for the given type.

void pushTrivial(ASTContext &Context, QualType T, SourceLocation Loc)

Pushes 'T' with all locations pointing to 'Loc'.

Base wrapper for a particular "section" of type source info.

QualType getType() const

Get the type for which this source info wrapper provides information.

T getAs() const

Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...

TypeLoc IgnoreParens() const

T castAs() const

Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.

SourceRange getSourceRange() const LLVM_READONLY

Get the full source range.

unsigned getFullDataSize() const

Returns the size of the type source info data block.

SourceLocation getBeginLoc() const

Get the begin source location.

A container of type source information.

TypeLoc getTypeLoc() const

Return the TypeLoc wrapper for the type source info.

QualType getType() const

Return the type wrapped by this type source info.

SourceLocation getNameLoc() const

void setNameLoc(SourceLocation Loc)

The base class of the type hierarchy.

bool isReferenceType() const

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool isInstantiationDependentType() const

Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...

bool containsUnexpandedParameterPack() const

Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...

bool isVariablyModifiedType() const

Whether this type is a variably-modified type (C99 6.7.5).

const T * getAs() const

Member-template getAs'.

bool isRecordType() const

QualType getUnderlyingType() const

A reference to a name which we were able to look up during parsing but could not resolve to a specifi...

bool isParameterPack() const

Determine whether this value is actually a function parameter pack, init-capture pack,...

Represents a variable declaration or definition.

bool isStaticDataMember() const

Determines whether this is a static data member.

VarDecl * getDefinition(ASTContext &)

Get the real (not just tentative) definition for this declaration.

VarDecl * getInstantiatedFromStaticDataMember() const

If this variable is an instantiated static data member of a class template specialization,...

void setTemplateSpecializationKind(TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation=SourceLocation())

For a static data member that was instantiated from a static data member of a class template,...

StorageClass getStorageClass() const

Returns the storage class as written in the source.

MemberSpecializationInfo * getMemberSpecializationInfo() const

If this variable is an instantiation of a static data member of a class template specialization,...

Declaration of a variable template.

Represents a variable template specialization, which refers to a variable template with a given set o...

const TemplateArgumentList & getTemplateInstantiationArgs() const

Retrieve the set of template arguments that should be used to instantiate the initializer of the vari...

bool isClassScopeExplicitSpecialization() const

llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const

Retrieve the variable template or variable template partial specialization which was specialized by t...

TemplateSpecializationKind getSpecializationKind() const

Determine the kind of specialization that this declaration represents.

VarTemplateDecl * getSpecializedTemplate() const

Retrieve the template that this specialization specializes.

SubstitutionDiagnostic * getExprSubstitutionDiagnostic() const

bool isExprSubstitutionFailure() const

const ReturnTypeRequirement & getReturnTypeRequirement() const

SourceLocation getNoexceptLoc() const

A requires-expression requirement which is satisfied when a general constraint expression is satisfie...

const ASTConstraintSatisfaction & getConstraintSatisfaction() const

bool hasInvalidConstraint() const

Expr * getConstraintExpr() const

StringRef getInvalidConstraintEntity()

A static requirement that can be used in a requires-expression to check properties of types and expre...

bool isSubstitutionFailure() const

SubstitutionDiagnostic * getSubstitutionDiagnostic() const

TypeSourceInfo * getType() const

CXXMethodDecl * CallOperator

The lambda's compiler-generated operator().

Provides information about an attempted template argument deduction, whose success or failure was des...

TemplateArgumentList * takeCanonical()

SourceLocation getLocation() const

Returns the location at which template argument is occurring.

bool hasSFINAEDiagnostic() const

Is a SFINAE diagnostic available?

void takeSFINAEDiagnostic(PartialDiagnosticAt &PD)

Take ownership of the SFINAE diagnostic.

bool hasStrictPackMatch() const

Defines the clang::TargetInfo interface.

std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl

All declarations that can appear in a module declaration.

Attr * instantiateTemplateAttribute(const Attr *At, ASTContext &C, Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs)

Attr * instantiateTemplateAttributeForDecl(const Attr *At, ASTContext &C, Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs)

The JSON file list parser is used to communicate input to InstallAPI.

void atTemplateEnd(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema, const Sema::CodeSynthesisContext &Inst)

bool isa(CodeGen::Address addr)

void atTemplateBegin(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema, const Sema::CodeSynthesisContext &Inst)

if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))

@ Specialization

We are substituting template parameters for template arguments in order to form a template specializa...

@ Ambiguous

Name lookup results in an ambiguity; use getAmbiguityKind to figure out what kind of ambiguity we hav...

@ TemplateName

The identifier is a template name. FIXME: Add an annotation for that.

NamedDecl * getAsNamedDecl(TemplateParameter P)

@ OK_Ordinary

An ordinary object is located at an address in memory.

std::pair< llvm::PointerUnion< const TemplateTypeParmType *, NamedDecl *, const TemplateSpecializationType *, const SubstBuiltinTemplatePackType * >, SourceLocation > UnexpandedParameterPack

bool isPackProducingBuiltinTemplateName(TemplateName N)

nullptr

This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...

bool isGenericLambdaCallOperatorOrStaticInvokerSpecialization(const DeclContext *DC)

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.

DeductionFailureInfo MakeDeductionFailureInfo(ASTContext &Context, TemplateDeductionResult TDK, sema::TemplateDeductionInfo &Info)

Convert from Sema's representation of template deduction information to the form used in overload-can...

@ Type

The name was classified as a type.

std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt

A partial diagnostic along with the source location where this diagnostic occurs.

@ VK_PRValue

A pr-value expression (in the C++11 taxonomy) produces a temporary value.

@ VK_LValue

An l-value expression is a reference to an object with independent storage.

llvm::PointerUnion< TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, TemplateTemplateParmDecl * > TemplateParameter

Stores a template parameter of any kind.

DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor

TemplateDeductionResult

Describes the result of template argument deduction.

@ Success

Template argument deduction was successful.

TemplateSpecializationKind

Describes the kind of template specialization that a particular template specialization declaration r...

@ TSK_ExplicitInstantiationDefinition

This template specialization was instantiated from a template due to an explicit instantiation defini...

@ TSK_ExplicitInstantiationDeclaration

This template specialization was instantiated from a template due to an explicit instantiation declar...

@ TSK_ExplicitSpecialization

This template specialization was declared or defined by an explicit specialization (C++ [temp....

@ TSK_ImplicitInstantiation

This template specialization was implicitly instantiated from a template.

@ TSK_Undeclared

This template specialization was formed from a template-id but has not yet been declared,...

U cast(CodeGen::Address addr)

@ Enum

The "enum" keyword introduces the elaborated-type-specifier.

ActionResult< Expr * > ExprResult

@ EST_Uninstantiated

not instantiated yet

@ EST_None

no exception specification

ActionResult< Stmt * > StmtResult

Represents an explicit template argument list in C++, e.g., the "" in "sort".

SourceLocation RAngleLoc

The source location of the right angle bracket ('>').

const TemplateArgumentLoc * getTemplateArgs() const

Retrieve the template arguments.

SourceLocation LAngleLoc

The source location of the left angle bracket ('<').

SourceLocation getLAngleLoc() const

ArrayRef< TemplateArgumentLoc > arguments() const

unsigned getNumTemplateArgs() const

SourceLocation getRAngleLoc() const

DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...

SourceLocation getLoc() const

getLoc - Returns the main location of the declaration name.

DeclarationName getName() const

getName - Returns the embedded declaration name.

Holds information about the various types of exception specification.

ExceptionSpecificationType Type

The kind of exception specification this is.

ExceptionSpecInfo ExceptionSpec

A context in which code is being synthesized (where a source location alone is not sufficient to iden...

SourceRange InstantiationRange

The source range that covers the construct that cause the instantiation, e.g., the template-id that c...

enum clang::Sema::CodeSynthesisContext::SynthesisKind Kind

const TemplateArgument * TemplateArgs

The list of template arguments we are substituting, if they are not part of the entity.

SourceLocation PointOfInstantiation

The point of instantiation or synthesis within the source code.

SynthesisKind

The kind of template instantiation we are performing.

@ MarkingClassDllexported

We are marking a class as __dllexport.

@ RequirementParameterInstantiation

@ DefaultTemplateArgumentInstantiation

We are instantiating a default argument for a template parameter.

@ ExplicitTemplateArgumentSubstitution

We are substituting explicit template arguments provided for a function template.

@ DefaultTemplateArgumentChecking

We are checking the validity of a default template argument that has been used when naming a template...

@ InitializingStructuredBinding

We are initializing a structured binding.

@ ExceptionSpecInstantiation

We are instantiating the exception specification for a function template which was deferred until it ...

@ NestedRequirementConstraintsCheck

We are checking the satisfaction of a nested requirement of a requires expression.

@ BuildingBuiltinDumpStructCall

We are building an implied call from __builtin_dump_struct.

@ ParameterMappingSubstitution

@ DefiningSynthesizedFunction

We are defining a synthesized function (such as a defaulted special member).

@ Memoization

Added for Template instantiation observation.

@ ConstraintNormalization

@ LambdaExpressionSubstitution

We are substituting into a lambda expression.

@ TypeAliasTemplateInstantiation

We are instantiating a type alias template declaration.

@ BuildingDeductionGuides

We are building deduction guides for a class.

@ PartialOrderingTTP

We are performing partial ordering for template template parameters.

@ DeducedTemplateArgumentSubstitution

We are substituting template argument determined as part of template argument deduction for either a ...

@ PriorTemplateArgumentSubstitution

We are substituting prior template arguments into a new template parameter.

@ ExceptionSpecEvaluation

We are computing the exception specification for a defaulted special member function.

@ TemplateInstantiation

We are instantiating a template declaration.

@ DeclaringSpecialMember

We are declaring an implicit special member function.

@ DeclaringImplicitEqualityComparison

We are declaring an implicit 'operator==' for a defaulted 'operator<=>'.

@ DefaultFunctionArgumentInstantiation

We are instantiating a default argument for a function.

@ RewritingOperatorAsSpaceship

We are rewriting a comparison operator in terms of an operator<=>.

@ RequirementInstantiation

We are instantiating a requirement of a requires expression.

Decl * Entity

The entity that is being synthesized.

bool isInstantiationRecord() const

Determines whether this template is an actual instantiation that should be counted toward the maximum...

Definition SemaTemplateInstantiate.cpp:565

A stack object to be created when performing template instantiation.

bool isInvalid() const

Determines whether we have exceeded the maximum recursive template instantiations.

InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, Decl *Entity, SourceRange InstantiationRange=SourceRange())

Note that we are instantiating a class template, function template, variable template,...

Definition SemaTemplateInstantiate.cpp:644

void Clear()

Note that we have finished instantiating this template.

Definition SemaTemplateInstantiate.cpp:878

void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info)

bool ExpandUnderForgetSubstitions

UnsignedOrNone NumExpansions