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

1

2

3

4

5

6

7

8

9

10

11

38#include "llvm/ADT/STLForwardCompat.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 =

103 } else if (auto *Prev = cast(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;

129 auto *TATD = cast(CSC.Entity),

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

184 !isa(VarTemplSpec))

185 return Response::Done();

186

187

188

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

194 if (!SkipForSpecialization)

195 Result.addOuterTemplateArguments(

197 false);

198 if (Partial->isMemberSpecialization())

199 return Response::Done();

200 } else {

201 VarTemplateDecl *Tmpl = cast<VarTemplateDecl *>(Specialized);

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

242 !isa(ClassTemplSpec))

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

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

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 (Function->getDescribedFunctionTemplate()) {

314 assert(

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

316 "Outer template not instantiated?");

317 }

318

319

320

321

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

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

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

326 }

327

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

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

330 return Response::UseNextDecl(Function);

331}

332

333Response HandleFunctionTemplateDecl(Sema &SemaRef,

336 if (!isa(FTD->getDeclContext())) {

337 Result.addOuterTemplateArguments(

341 false);

342

344

345 while (const Type *Ty = NNS ? NNS->getAsType() : nullptr) {

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366 if (TSTy->isCurrentInstantiation()) {

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

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

371 dyn_cast(RD))

372 Arguments =

373 Specialization->getTemplateInstantiationArgs().asArray();

374 }

375 Result.addOuterTemplateArguments(

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

377 false);

378 }

379 }

380

382 }

383 }

384

386}

387

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

391 bool ForConstraintInstantiation) {

393 assert(

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

395 "Outer template not instantiated?");

396 if (ClassTemplate->isMemberSpecialization())

397 return Response::Done();

398 if (ForConstraintInstantiation)

399 Result.addOuterTemplateArguments(

401 ClassTemplate->getInjectedTemplateArgs(SemaRef.Context),

402 false);

403 }

404

408 return Response::Done();

409

413 if (ForConstraintInstantiation && IsFriend &&

416 }

417

418

419

422 return Response::ChangeDecl(LCD);

423

424

425

426 if (auto TypeAlias = getEnclosingTypeAliasTemplateDecl(SemaRef);

427 ForConstraintInstantiation && TypeAlias) {

429 TypeAlias.PrimaryTypeAliasDecl)) {

430 Result.addOuterTemplateArguments(TypeAlias.Template,

431 TypeAlias.AssociatedTemplateArguments,

432 false);

433

434

435

436

437

438

439

440

441

442

443

444

445

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

447 }

448 }

449 }

450

451 return Response::UseNextDecl(Rec);

452}

453

454Response HandleImplicitConceptSpecializationDecl(

457 Result.addOuterTemplateArguments(

460 false);

461 return Response::UseNextDecl(CSD);

462}

463

464Response HandleGenericDeclContext(const Decl *CurDecl) {

465 return Response::UseNextDecl(CurDecl);

466}

467}

468}

469

473 const FunctionDecl *Pattern, bool ForConstraintInstantiation,

474 bool SkipForSpecialization, bool ForDefaultArgumentSubstitution) {

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

476

478

480 const Decl *CurDecl = ND;

481

482 if (!CurDecl)

484

485 if (Innermost) {

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

487 Final);

488

489

490

491

492

493

494

495

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

497 HandleDefaultTempArgIntoTempTempParam(TTP, Result);

498 CurDecl = Response::UseNextDecl(CurDecl).NextDecl;

499 }

500

502 Response R;

503 if (const auto *VarTemplSpec =

504 dyn_cast(CurDecl)) {

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

506 } else if (const auto *PartialClassTemplSpec =

507 dyn_cast(CurDecl)) {

508 R = HandlePartialClassTemplateSpec(PartialClassTemplSpec, Result,

509 SkipForSpecialization);

510 } else if (const auto *ClassTemplSpec =

511 dyn_cast(CurDecl)) {

512 R = HandleClassTemplateSpec(ClassTemplSpec, Result,

513 SkipForSpecialization);

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

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

516 ForConstraintInstantiation,

517 ForDefaultArgumentSubstitution);

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

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

520 ForConstraintInstantiation);

521 } else if (const auto *CSD =

522 dyn_cast(CurDecl)) {

523 R = HandleImplicitConceptSpecializationDecl(CSD, Result);

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

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

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

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

528 } else if (!isa(CurDecl)) {

529 R = Response::DontClearRelativeToPrimaryNextDecl(CurDecl);

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

531 R = HandleDefaultTempArgIntoTempTempParam(TTP, Result);

532 }

533 } else {

534 R = HandleGenericDeclContext(CurDecl);

535 }

536

537 if (R.IsDone)

539 if (R.ClearRelativeToPrimary)

540 RelativeToPrimary = false;

541 assert(R.NextDecl);

542 CurDecl = R.NextDecl;

543 }

544

546}

547

549 switch (Kind) {

559 return true;

560

578 return false;

579

580

582 break;

583 }

584

585 llvm_unreachable("Invalid SynthesisKind!");

586}

587

594

595

596

600 return;

601 }

605 Inst.Kind = Kind;

607 Inst.Entity = Entity;

614

615 AlreadyInstantiating = !Inst.Entity ? false :

617 .insert({Inst.Entity->getCanonicalDecl(), Inst.Kind})

618 .second;

620 }

621}

622

628 PointOfInstantiation, InstantiationRange, Entity) {}

629

635 PointOfInstantiation, InstantiationRange, Entity) {}

636

644 PointOfInstantiation, InstantiationRange, getAsNamedDecl(Param),

645 Template, TemplateArgs) {}

646

655 TemplateArgs, &DeductionInfo) {

659}

660

669 PointOfInstantiation, InstantiationRange, Template, nullptr,

670 TemplateArgs, &DeductionInfo) {}

671

680 PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,

681 TemplateArgs, &DeductionInfo) {}

682

691 PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,

692 TemplateArgs, &DeductionInfo) {}

693

700 PointOfInstantiation, InstantiationRange, Param, nullptr,

701 TemplateArgs) {}

702

710 PointOfInstantiation, InstantiationRange, Param, Template,

711 TemplateArgs) {}

712

720 PointOfInstantiation, InstantiationRange, Param, Template,

721 TemplateArgs) {}

722

729 PointOfInstantiation, InstantiationRange, Entity,

730 nullptr, TemplateArgs) {}

731

738 PointOfInstantiation, InstantiationRange, Param, Template,

739 TemplateArgs) {}

740

747 PointOfInstantiation, InstantiationRange, nullptr,

748 nullptr, {}, &DeductionInfo) {}

749

756 PointOfInstantiation, InstantiationRange, nullptr,

757 nullptr, {}) {}

758

764 PointOfInstantiation, InstantiationRange, nullptr,

765 nullptr, {}, &DeductionInfo) {}

766

773 PointOfInstantiation, InstantiationRange, Template, nullptr,

774 TemplateArgs) {}

775

782 PointOfInstantiation, InstantiationRange, Template, nullptr,

783 {}, &DeductionInfo) {}

784

791 PointOfInstantiation, InstantiationRange, Template) {}

792

799 PointOfInstantiation, InstantiationRange, Template) {}

800

806 PointOfInstantiation, InstantiationRange, Entity) {}

807

808

812

814

817

818

819

821}

822

825 if (!Active.isInstantiationRecord()) {

828 }

829

831

832

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

841 }

842

843

844

848

850}

851

854 if (!AlreadyInstantiating) {

856 if (Active.Entity)

858 {Active.Entity->getCanonicalDecl(), Active.Kind});

859 }

860

863

866 }

867}

868

872 llvm::raw_string_ostream OS(Result);

873 llvm::ListSeparator Comma;

874 for (const Expr *Arg : Args) {

875 OS << Comma;

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

878 }

880}

881

882bool Sema::InstantiatingTemplate::CheckInstantiationDepth(

890 return false;

891

893 diag::err_template_recursion_depth_exceeded)

895 << InstantiationRange;

896 SemaRef.Diag(PointOfInstantiation, diag::note_template_recursion_depth)

898 return true;

899}

900

902

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 Diags.Report(Active->PointOfInstantiation,

922 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;

933 if (isa(Record))

934 DiagID = diag::note_template_class_instantiation_here;

935 Diags.Report(Active->PointOfInstantiation, DiagID)

936 << 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 Diags.Report(Active->PointOfInstantiation, DiagID)

945 << Active->InstantiationRange;

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

947 Diags.Report(Active->PointOfInstantiation,

948 VD->isStaticDataMember()?

949 diag::note_template_static_data_member_def_here

950 : diag::note_template_variable_def_here)

951 << VD

952 << Active->InstantiationRange;

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

954 Diags.Report(Active->PointOfInstantiation,

955 diag::note_template_enum_def_here)

956 << ED

957 << Active->InstantiationRange;

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

959 Diags.Report(Active->PointOfInstantiation,

960 diag::note_template_nsdmi_here)

961 << FD << Active->InstantiationRange;

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

963 Diags.Report(Active->PointOfInstantiation,

964 diag::note_template_class_instantiation_here)

965 << CTD << Active->InstantiationRange;

966 }

967 break;

968 }

969

971 TemplateDecl *Template = cast(Active->Template);

973 llvm::raw_svector_ostream OS(TemplateArgsStr);

977 Diags.Report(Active->PointOfInstantiation,

978 diag::note_default_arg_instantiation_here)

979 << OS.str()

980 << Active->InstantiationRange;

981 break;

982 }

983

986 Diags.Report(Active->PointOfInstantiation,

987 diag::note_explicit_template_arg_substitution_here)

988 << FnTmpl

990 Active->TemplateArgs,

991 Active->NumTemplateArgs)

992 << Active->InstantiationRange;

993 break;

994 }

995

998 dyn_cast(Active->Entity)) {

999 Diags.Report(Active->PointOfInstantiation,

1000 diag::note_function_template_deduction_instantiation_here)

1001 << FnTmpl

1003 Active->TemplateArgs,

1004 Active->NumTemplateArgs)

1005 << Active->InstantiationRange;

1006 } else {

1007 bool IsVar = isa(Active->Entity) ||

1008 isa(Active->Entity);

1009 bool IsTemplate = false;

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

1012 IsTemplate = true;

1013 Params = D->getTemplateParameters();

1014 } else if (auto *D = dyn_cast(

1015 Active->Entity)) {

1016 Params = D->getTemplateParameters();

1017 } else if (auto *D = dyn_cast(

1018 Active->Entity)) {

1019 Params = D->getTemplateParameters();

1020 } else {

1021 llvm_unreachable("unexpected template kind");

1022 }

1023

1024 Diags.Report(Active->PointOfInstantiation,

1025 diag::note_deduced_template_arg_substitution_here)

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

1028 Active->NumTemplateArgs)

1029 << Active->InstantiationRange;

1030 }

1031 break;

1032 }

1033

1035 ParmVarDecl *Param = cast(Active->Entity);

1037

1039 llvm::raw_svector_ostream OS(TemplateArgsStr);

1043 Diags.Report(Active->PointOfInstantiation,

1044 diag::note_default_function_arg_instantiation_here)

1045 << OS.str()

1046 << Active->InstantiationRange;

1047 break;

1048 }

1049

1051 NamedDecl *Parm = cast(Active->Entity);

1052 std::string Name;

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

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

1055

1057 if (TemplateDecl *Template = dyn_cast(Active->Template))

1058 TemplateParams = Template->getTemplateParameters();

1059 else

1060 TemplateParams =

1061 cast(Active->Template)

1062 ->getTemplateParameters();

1063 Diags.Report(Active->PointOfInstantiation,

1064 diag::note_prior_template_arg_substitution)

1065 << isa(Parm)

1066 << Name

1068 Active->TemplateArgs,

1069 Active->NumTemplateArgs)

1070 << Active->InstantiationRange;

1071 break;

1072 }

1073

1076 if (TemplateDecl *Template = dyn_cast(Active->Template))

1077 TemplateParams = Template->getTemplateParameters();

1078 else

1079 TemplateParams =

1080 cast(Active->Template)

1081 ->getTemplateParameters();

1082

1083 Diags.Report(Active->PointOfInstantiation,

1084 diag::note_template_default_arg_checking)

1086 Active->TemplateArgs,

1087 Active->NumTemplateArgs)

1088 << Active->InstantiationRange;

1089 break;

1090 }

1091

1093 Diags.Report(Active->PointOfInstantiation,

1094 diag::note_evaluating_exception_spec_here)

1095 << cast(Active->Entity);

1096 break;

1097

1099 Diags.Report(Active->PointOfInstantiation,

1100 diag::note_template_exception_spec_instantiation_here)

1101 << cast(Active->Entity)

1102 << Active->InstantiationRange;

1103 break;

1104

1106 Diags.Report(Active->PointOfInstantiation,

1107 diag::note_template_requirement_instantiation_here)

1108 << Active->InstantiationRange;

1109 break;

1111 Diags.Report(Active->PointOfInstantiation,

1112 diag::note_template_requirement_params_instantiation_here)

1113 << Active->InstantiationRange;

1114 break;

1115

1117 Diags.Report(Active->PointOfInstantiation,

1118 diag::note_nested_requirement_here)

1119 << Active->InstantiationRange;

1120 break;

1121

1123 Diags.Report(Active->PointOfInstantiation,

1124 diag::note_in_declaration_of_implicit_special_member)

1125 << cast(Active->Entity)

1126 << llvm::to_underlying(Active->SpecialMember);

1127 break;

1128

1130 Diags.Report(Active->Entity->getLocation(),

1131 diag::note_in_declaration_of_implicit_equality_comparison);

1132 break;

1133

1135

1136

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

1141 auto *MD = cast(FD);

1142 Diags.Report(Active->PointOfInstantiation,

1143 diag::note_member_synthesized_at)

1144 << MD->isExplicitlyDefaulted()

1149 ->getType()

1150 .getNonReferenceType()

1151 .getUnqualifiedType();

1152 Diags.Report(Active->PointOfInstantiation,

1153 diag::note_comparison_synthesized_at)

1155 }

1156 break;

1157 }

1158

1160 Diags.Report(Active->Entity->getLocation(),

1161 diag::note_rewriting_operator_as_spaceship);

1162 break;

1163

1165 Diags.Report(Active->PointOfInstantiation,

1166 diag::note_in_binding_decl_init)

1167 << cast(Active->Entity);

1168 break;

1169

1171 Diags.Report(Active->PointOfInstantiation,

1172 diag::note_due_to_dllexported_class)

1173 << cast(Active->Entity) << getLangOpts().CPlusPlus11;

1174 break;

1175

1177 Diags.Report(Active->PointOfInstantiation,

1178 diag::note_building_builtin_dump_struct_call)

1180 *this, llvm::ArrayRef(Active->CallArgs, Active->NumCallArgs));

1181 break;

1182

1184 break;

1185

1187 Diags.Report(Active->PointOfInstantiation,

1188 diag::note_lambda_substitution_here);

1189 break;

1191 unsigned DiagID = 0;

1192 if (!Active->Entity) {

1193 Diags.Report(Active->PointOfInstantiation,

1194 diag::note_nested_requirement_here)

1195 << Active->InstantiationRange;

1196 break;

1197 }

1198 if (isa(Active->Entity))

1199 DiagID = diag::note_concept_specialization_here;

1200 else if (isa(Active->Entity))

1201 DiagID = diag::note_checking_constraints_for_template_id_here;

1202 else if (isa(Active->Entity))

1203 DiagID = diag::note_checking_constraints_for_var_spec_id_here;

1204 else if (isa(Active->Entity))

1205 DiagID = diag::note_checking_constraints_for_class_spec_id_here;

1206 else {

1207 assert(isa(Active->Entity));

1208 DiagID = diag::note_checking_constraints_for_function_here;

1209 }

1211 llvm::raw_svector_ostream OS(TemplateArgsStr);

1213 if (!isa(Active->Entity)) {

1216 }

1217 Diags.Report(Active->PointOfInstantiation, DiagID) << OS.str()

1218 << Active->InstantiationRange;

1219 break;

1220 }

1222 Diags.Report(Active->PointOfInstantiation,

1223 diag::note_constraint_substitution_here)

1224 << Active->InstantiationRange;

1225 break;

1227 Diags.Report(Active->PointOfInstantiation,

1228 diag::note_constraint_normalization_here)

1229 << cast(Active->Entity) << Active->InstantiationRange;

1230 break;

1232 Diags.Report(Active->PointOfInstantiation,

1233 diag::note_parameter_mapping_substitution_here)

1234 << Active->InstantiationRange;

1235 break;

1237 Diags.Report(Active->PointOfInstantiation,

1238 diag::note_building_deduction_guide_here);

1239 break;

1241 Diags.Report(Active->PointOfInstantiation,

1242 diag::note_template_type_alias_instantiation_here)

1243 << cast(Active->Entity)

1244 << Active->InstantiationRange;

1245 break;

1246 }

1247 }

1248}

1249

1252 return std::optional<TemplateDeductionInfo *>(nullptr);

1253

1257 Active != ActiveEnd;

1258 ++Active)

1259 {

1260 switch (Active->Kind) {

1262

1263

1264 if (isa(Active->Entity))

1265 break;

1266 [[fallthrough]];

1274

1275 return std::nullopt;

1277

1278

1279

1280

1281

1282 return std::nullopt;

1283

1288

1289

1290

1291 break;

1292

1295

1296

1297

1301

1302

1303 assert(Active->DeductionInfo && "Missing deduction info pointer");

1304 return Active->DeductionInfo;

1305

1313

1314

1315 return std::nullopt;

1316

1318

1319

1320

1321 break;

1322

1324 break;

1325 }

1326

1327

1328

1329 if (Active->SavedInNonInstantiationSFINAEContext)

1330 return std::optional<TemplateDeductionInfo *>(nullptr);

1331 }

1332

1333 return std::nullopt;

1334}

1335

1336

1337

1338

1339namespace {

1340 class TemplateInstantiator : public TreeTransform {

1344

1345 bool EvaluateConstraints = true;

1346

1347

1348 bool IsIncomplete = false;

1349

1350 bool BailOutOnIncomplete;

1351

1352 public:

1354

1355 TemplateInstantiator(Sema &SemaRef,

1358 bool BailOutOnIncomplete = false)

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

1360 Entity(Entity), BailOutOnIncomplete(BailOutOnIncomplete) {}

1361

1362 void setEvaluateConstraints(bool B) {

1363 EvaluateConstraints = B;

1364 }

1365 bool getEvaluateConstraints() {

1366 return EvaluateConstraints;

1367 }

1368

1369

1370

1371

1372

1373

1374 bool AlreadyTransformed(QualType T);

1375

1376

1378

1379

1381

1382

1383 bool getIsIncomplete() const { return IsIncomplete; }

1384

1385

1386

1388 this->Loc = Loc;

1389 this->Entity = Entity;

1390 }

1391

1392 unsigned TransformTemplateDepth(unsigned Depth) {

1394 }

1395

1396 std::optional getPackIndex(TemplateArgument Pack) {

1397 int Index = getSema().ArgumentPackSubstitutionIndex;

1398 if (Index == -1)

1399 return std::nullopt;

1400 return Pack.pack_size() - 1 - Index;

1401 }

1402

1403 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,

1406 bool &ShouldExpand, bool &RetainExpansion,

1407 std::optional &NumExpansions) {

1408 return getSema().CheckParameterPacksForExpansion(EllipsisLoc,

1409 PatternRange, Unexpanded,

1410 TemplateArgs,

1411 ShouldExpand,

1412 RetainExpansion,

1413 NumExpansions);

1414 }

1415

1416 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) {

1418 }

1419

1426 unsigned Depth, Index;

1429 Result = TemplateArgs(Depth, Index);

1431 } else {

1432 IsIncomplete = true;

1433 if (BailOutOnIncomplete)

1435 }

1436 }

1437

1438 return Result;

1439 }

1440

1441 void RememberPartiallySubstitutedPack(TemplateArgument Arg) {

1443 return;

1444

1449 unsigned Depth, Index;

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

1452 }

1453 }

1454

1455

1456

1458

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

1461 }

1462

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

1467 for (auto *New : NewDecls)

1469 Old, cast(New));

1470 return;

1471 }

1472

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

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

1475 Decl *New = NewDecls.front();

1476

1477

1478

1479

1480 auto *NewMD = dyn_cast(New);

1482 auto *OldMD = dyn_cast(Old);

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

1484 NewTD->setInstantiatedFromMemberTemplate(

1485 OldMD->getDescribedFunctionTemplate());

1486 else

1487 NewMD->setInstantiationOfMemberFunction(OldMD,

1489 }

1490

1492

1493

1494

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

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

1498 }

1499

1500

1501

1503

1504

1505

1507

1511 bool &Changed);

1512

1513

1514

1515 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,

1520

1521

1522

1523 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,

1525

1526

1527

1532

1537 NamedDecl *FirstQualifierInScope = nullptr,

1538 bool AllowInjectedClassName = false);

1539

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

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

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

1543 const NoInlineAttr *TransformStmtNoInlineAttr(const Stmt *OrigS,

1544 const Stmt *InstS,

1545 const NoInlineAttr *A);

1546 const AlwaysInlineAttr *

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

1548 const AlwaysInlineAttr *A);

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

1553

1556 ExprResult TransformSubstNonTypeTemplateParmPackExpr(

1558 ExprResult TransformSubstNonTypeTemplateParmExpr(

1560

1561

1563

1564

1566

1567

1568

1569

1571

1574

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

1576 }

1577

1580 auto Type = inherited::TransformInjectedClassNameType(TLB, TL);

1581

1582

1583 if (Type.isNull() &&

1586

1587

1590 inherited::TransformType(ICT->getInjectedSpecializationType());

1592 return Type;

1593 }

1594 }

1595 return Type;

1596 }

1597

1598

1601 bool Uneval = false) {

1603 std::vector TArgs;

1604 switch (Arg.getKind()) {

1606

1607

1613 return true;

1615 }

1619 return false;

1620 default:

1621 break;

1622 }

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

1624 }

1625

1626 template

1631 Fn TransformExceptionSpec);

1632

1634 TransformFunctionTypeParam(ParmVarDecl *OldParm, int indexAdjustment,

1635 std::optional NumExpansions,

1636 bool ExpectParameterPack);

1637

1638 using inherited::TransformTemplateTypeParmType;

1639

1640

1643 bool SuppressObjCLifetime);

1644

1645 QualType BuildSubstTemplateTypeParmType(

1646 TypeLocBuilder &TLB, bool SuppressObjCLifetime, bool Final,

1647 Decl *AssociatedDecl, unsigned Index, std::optional PackIndex,

1649

1650

1651

1652

1653 using inherited::TransformSubstTemplateTypeParmPackType;

1655 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,

1657 bool SuppressObjCLifetime);

1658

1660 TransformSubstTemplateTypeParmType(TypeLocBuilder &TLB,

1663 if (Type->getSubstitutionFlag() !=

1664 SubstTemplateTypeParmTypeFlag::ExpandPacksInPlace)

1665 return inherited::TransformSubstTemplateTypeParmType(TLB, TL);

1666

1667 assert(Type->getPackIndex());

1669 Type->getReplacedParameter()->getDepth(), Type->getIndex());

1670 assert(*Type->getPackIndex() + 1 <= TA.pack_size());

1672 SemaRef, TA.pack_size() - 1 - *Type->getPackIndex());

1673

1674 return inherited::TransformSubstTemplateTypeParmType(TLB, TL);

1675 }

1676

1679 if (auto TypeAlias =

1680 TemplateInstArgsHelpers::getEnclosingTypeAliasTemplateDecl(

1681 getSema());

1682 TypeAlias && TemplateInstArgsHelpers::isLambdaEnclosedByTypeAliasDecl(

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

1686 return CXXRecordDecl::LambdaDependencyKind::LDK_AlwaysDependent;

1689 return CXXRecordDecl::LambdaDependencyKind::LDK_AlwaysDependent;

1690 }

1691 return inherited::ComputeLambdaDependency(LSI);

1692 }

1693

1695

1696

1698 return E;

1700 true);

1702

1703 return inherited::TransformLambdaExpr(E);

1704 }

1705

1708 true);

1709 return inherited::TransformBlockExpr(E);

1710 }

1711

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

1717 if (!PVD->hasDefaultArg())

1718 continue;

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

1720

1723

1724

1725

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

1731 }

1732 }

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

1734 }

1735

1737

1738

1739

1740

1741

1742

1743

1744

1745

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

1748 }

1749

1751 ExprResult Transformed = inherited::TransformSizeOfPackExpr(E);

1752 if (!Transformed.isUsable())

1753 return Transformed;

1754 auto *TransformedExpr = cast(Transformed.get());

1757 TransformedExpr->getPack() == E->getPack()) {

1758 Decl *NewPack =

1759 TransformDecl(E->getPackLoc(), TransformedExpr->getPack());

1760 if (!NewPack)

1762 TransformedExpr->setPack(cast(NewPack));

1763 }

1764 return TransformedExpr;

1765 }

1766

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

1771 return TransReq;

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

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

1774 "Create a new expression instead.");

1775 if (E->getBody()->isDependentContext()) {

1777

1778

1780

1781 if (Trap.hasErrorOccurred())

1783 }

1784 return TransReq;

1785 }

1786

1787 bool TransformRequiresExprRequirements(

1790 bool SatisfactionDetermined = false;

1793 if (!SatisfactionDetermined) {

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

1795 TransReq = TransformTypeRequirement(TypeReq);

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

1797 TransReq = TransformExprRequirement(ExprReq);

1798 else

1799 TransReq = TransformNestedRequirement(

1800 castconcepts::NestedRequirement(Req));

1801 if (!TransReq)

1802 return true;

1804

1805

1806

1807

1808

1809 SatisfactionDetermined = true;

1810 } else

1811 TransReq = Req;

1812 Transformed.push_back(TransReq);

1813 }

1814 return false;

1815 }

1816

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

1820

1823 Owner, TemplateArgs);

1824 DeclInstantiator.setEvaluateConstraints(EvaluateConstraints);

1825 return DeclInstantiator.SubstTemplateParams(OrigTPL);

1826 }

1827

1834 ExprResult TransformRequiresTypeParams(

1840

1841 private:

1843 transformNonTypeTemplateParmRef(Decl *AssociatedDecl,

1846 std::optional PackIndex);

1847 };

1848}

1849

1850bool TemplateInstantiator::AlreadyTransformed(QualType T) {

1851 if (T.isNull())

1852 return true;

1853

1855 return false;

1856

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

1858 return true;

1859}

1860

1868 return Arg;

1869}

1870

1872 if (D)

1873 return nullptr;

1874

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

1877

1878

1879

1880

1882 TTP->getPosition())) {

1883 IsIncomplete = true;

1884 return BailOutOnIncomplete ? nullptr : D;

1885 }

1886

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

1888

1889 if (TTP->isParameterPack()) {

1890

1891

1892

1897 TemplateArgs);

1898 }

1900 "Missing argument pack");

1902 }

1903

1906 "Wrong kind of template template argument");

1908 }

1909

1910

1911

1912 }

1913

1915}

1916

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

1919 if (!Inst)

1920 return nullptr;

1921

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

1923 return Inst;

1924}

1925

1926bool TemplateInstantiator::TransformExceptionSpec(

1932 }

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

1934}

1935

1937TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D,

1939

1940

1944

1946

1948

1951 "Missing argument pack");

1952

1954 return nullptr;

1955

1957 }

1958

1960 if (T.isNull())

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

1962

1964 return Tag->getDecl();

1965

1966

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

1968 return nullptr;

1969 }

1970 }

1971

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

1973}

1974

1976TemplateInstantiator::RebuildExceptionDecl(VarDecl *ExceptionDecl,

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

1982 StartLoc, NameLoc, Name);

1983 if (Var)

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

1985 return Var;

1986}

1987

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

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

1992 if (Var)

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

1994 return Var;

1995}

1996

1998TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,

2003 TagDecl* TD = TT->getDecl();

2004

2006

2008

2009

2010

2015 TagLocation, Id)) {

2016 SemaRef.Diag(TagLocation, diag::err_use_with_wrong_tag)

2017 << Id

2021 }

2022 }

2023 }

2024

2025 return inherited::RebuildElaboratedType(KeywordLoc, Keyword, QualifierLoc, T);

2026}

2027

2028TemplateName TemplateInstantiator::TransformTemplateName(

2031 bool AllowInjectedClassName) {

2033 = dyn_cast_or_null(Name.getAsTemplateDecl())) {

2035

2036

2037

2038

2040 TTP->getPosition())) {

2041 IsIncomplete = true;

2042 return BailOutOnIncomplete ? TemplateName() : Name;

2043 }

2044

2046

2048

2049

2052 "unexpected pack arguments in template rewrite");

2054 }

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

2058 }

2059

2060 auto [AssociatedDecl, Final] =

2062 std::optional PackIndex;

2065 "Missing argument pack");

2066

2068

2069

2070

2071 return getSema().Context.getSubstTemplateTemplateParmPack(

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

2073 }

2074

2075 PackIndex = getPackIndex(Arg);

2077 }

2078

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

2081

2082 if (Final)

2083 return Template;

2084 return getSema().Context.getSubstTemplateTemplateParm(

2085 Template, AssociatedDecl, TTP->getIndex(), PackIndex);

2086 }

2087 }

2088

2090 = Name.getAsSubstTemplateTemplateParmPack()) {

2092 return Name;

2093

2097 if (SubstPack->getFinal())

2098 return Template;

2099 return getSema().Context.getSubstTemplateTemplateParm(

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

2101 getPackIndex(Pack));

2102 }

2103

2104 return inherited::TransformTemplateName(SS, Name, NameLoc, ObjectType,

2105 FirstQualifierInScope,

2106 AllowInjectedClassName);

2107}

2108

2110TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {

2112 return E;

2113

2114 return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentKind());

2115}

2116

2118TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,

2120

2121

2122

2123

2126 IsIncomplete = true;

2127 return BailOutOnIncomplete ? ExprError() : E;

2128 }

2129

2131

2133

2134

2137 "unexpected pack arguments in template rewrite");

2139 }

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

2142

2143

2145 }

2146

2148 std::optional PackIndex;

2151 "Missing argument pack");

2152

2154

2155

2156

2158 E->getLocation(),

2160 if (TargetType.isNull())

2162

2166

2169 E->getLocation(), Arg, AssociatedDecl, NTTP->getPosition());

2170 }

2171 PackIndex = getPackIndex(Arg);

2173 }

2174

2175 return transformNonTypeTemplateParmRef(AssociatedDecl, NTTP, E->getLocation(),

2176 Arg, PackIndex);

2177}

2178

2179const AnnotateAttr *

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

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

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

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

2186 }

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

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

2189}

2190

2191const CXXAssumeAttr *

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

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

2195 return AA;

2196

2197 Res = getSema().ActOnFinishFullExpr(Res.get(),

2198 false);

2200 return AA;

2201

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

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

2204 AA->getRange());

2206 return AA;

2207 }

2208

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

2210 AA->getRange());

2211}

2212

2213const LoopHintAttr *

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

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

2216

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

2218 return LH;

2219

2220

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

2222 LH->getSemanticSpelling() ==

2223 LoopHintAttr::Pragma_unroll))

2224 return LH;

2225

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

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

2228

2229 llvm::APSInt ValueAPS =

2231

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

2233 Option = LoopHintAttr::Unroll;

2234 State = LoopHintAttr::Disable;

2235 }

2236

2237

2238

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

2240 TransformedExpr, *LH);

2241}

2242const NoInlineAttr *TemplateInstantiator::TransformStmtNoInlineAttr(

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

2245 return nullptr;

2246

2247 return A;

2248}

2249const AlwaysInlineAttr *TemplateInstantiator::TransformStmtAlwaysInlineAttr(

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

2252 return nullptr;

2253

2254 return A;

2255}

2256

2257const CodeAlignAttr *

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

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

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

2261}

2262

2263ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(

2266 std::optional PackIndex) {

2268

2269

2270

2271 auto SubstParamType = [&] {

2275 else

2278 T = cast(T)->getPattern();

2280 };

2281

2282 bool refParam = false;

2283

2284

2285

2286

2288 Expr *argExpr = arg.getAsExpr();

2289 result = argExpr;

2292

2293 QualType paramType = SubstParamType();

2294 if (paramType.isNull())

2297 } else {

2298 refParam = true;

2299 }

2300 }

2305

2306

2307

2308 VD = cast_or_null(

2310 if (!VD)

2312 }

2313

2314 QualType paramType = arg.getNonTypeTemplateArgumentType();

2315 assert(!paramType.isNull() && "type substitution failed for param type");

2316 assert(!paramType->isDependentType() && "param type still dependent");

2319 } else {

2320 QualType paramType = arg.getNonTypeTemplateArgumentType();

2326 }

2327

2330

2331 Expr *resultExpr = result.get();

2332

2335 AssociatedDecl, parm->getIndex(), PackIndex, refParam);

2336}

2337

2339TemplateInstantiator::TransformSubstNonTypeTemplateParmPackExpr(

2342

2343 return E;

2344 }

2345

2348

2349 return transformNonTypeTemplateParmRef(

2350 E->getAssociatedDecl(), E->getParameterPack(),

2351 E->getParameterPackLocation(), Arg, getPackIndex(Pack));

2352}

2353

2355TemplateInstantiator::TransformSubstNonTypeTemplateParmExpr(

2357 ExprResult SubstReplacement = E->getReplacement();

2358 if (!isa(SubstReplacement.get()))

2359 SubstReplacement = TransformExpr(E->getReplacement());

2360 if (SubstReplacement.isInvalid())

2361 return true;

2364 return true;

2365

2366

2367

2368

2369

2370

2371

2372

2373

2374

2375

2376

2377

2378

2379

2380

2381

2382

2383

2384

2388 SubstReplacement.get(), SugaredConverted,

2390 .isInvalid())

2391 return true;

2392 return transformNonTypeTemplateParmRef(E->getAssociatedDecl(),

2394 SugaredConverted, E->getPackIndex());

2395}

2396

2397ExprResult TemplateInstantiator::RebuildVarDeclRefExpr(VarDecl *PD,

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

2401}

2402

2406

2409 if (!VD)

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

2412 }

2413

2415 if (T.isNull())

2417

2418

2419

2421 Vars.reserve(E->getNumExpansions());

2423 I != End; ++I) {

2425 if (D)

2427 Vars.push_back(D);

2428 }

2429

2430 auto *PackExpr =

2432 E->getParameterPackLocation(), Vars);

2433 getSema().MarkFunctionParmPackReferenced(PackExpr);

2434 return PackExpr;

2435}

2436

2438TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E,

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

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

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

2444

2445 Decl *TransformedDecl;

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

2447

2448

2451 if (T.isNull())

2455 getSema().MarkFunctionParmPackReferenced(PackExpr);

2456 return PackExpr;

2457 }

2458

2459 TransformedDecl = (*Pack)[getSema().ArgumentPackSubstitutionIndex];

2460 } else {

2461 TransformedDecl = cast<Decl *>(*Found);

2462 }

2463

2464

2465 return RebuildVarDeclRefExpr(cast(TransformedDecl), E->getExprLoc());

2466}

2467

2469TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {

2471

2472

2473

2476 return TransformTemplateParmRefExpr(E, NTTP);

2477

2478

2479

2480 }

2481

2482

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

2485 return TransformFunctionParmPackRefExpr(E, PD);

2486

2487 return inherited::TransformDeclRefExpr(E);

2488}

2489

2490ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(

2492 assert(!cast(E->getParam()->getDeclContext())->

2493 getDescribedFunctionTemplate() &&

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

2496 E->getUsedLocation(), cast(E->getParam()->getDeclContext()),

2497 E->getParam());

2498}

2499

2500template

2505 Fn TransformExceptionSpec) {

2506

2507

2508

2509

2510

2511

2512

2514 std::optional Scope;

2515 if (!Current || !Current->isLambdaOrBlock())

2516 Scope.emplace(SemaRef, true);

2517

2518 return inherited::TransformFunctionProtoType(

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

2520}

2521

2522ParmVarDecl *TemplateInstantiator::TransformFunctionTypeParam(

2523 ParmVarDecl *OldParm, int indexAdjustment,

2524 std::optional NumExpansions, bool ExpectParameterPack) {

2526 OldParm, TemplateArgs, indexAdjustment, NumExpansions,

2527 ExpectParameterPack, EvaluateConstraints);

2530 return NewParm;

2531}

2532

2533QualType TemplateInstantiator::BuildSubstTemplateTypeParmType(

2534 TypeLocBuilder &TLB, bool SuppressObjCLifetime, bool Final,

2535 Decl *AssociatedDecl, unsigned Index, std::optional PackIndex,

2538

2539

2540

2541 if (SuppressObjCLifetime) {

2543 RQs = Replacement.getQualifiers();

2545 Replacement =

2547 }

2548

2549 if (Final) {

2551 return Replacement;

2552 }

2553

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

2555 Replacement, AssociatedDecl, Index, PackIndex);

2560}

2561

2563TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,

2565 bool SuppressObjCLifetime) {

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

2568

2569

2570

2571

2572

2573

2574

2576 IsIncomplete = true;

2577 if (BailOutOnIncomplete)

2579

2584 }

2585

2587

2589

2590

2593 "unexpected pack arguments in template rewrite");

2595 }

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

2600 return NewT;

2601 }

2602

2603 auto [AssociatedDecl, Final] =

2605 std::optional PackIndex;

2606 if (T->isParameterPack()) {

2608 "Missing argument pack");

2609

2611

2612

2613

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

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

2620 }

2621

2622

2623 PackIndex = getPackIndex(Arg);

2625 }

2626

2628 "Template argument kind mismatch");

2629

2630 return BuildSubstTemplateTypeParmType(TLB, SuppressObjCLifetime, Final,

2631 AssociatedDecl, T->getIndex(),

2633 }

2634

2635

2636

2637

2638

2641 NewTTPDecl = cast_or_null(

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

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

2645 T->isParameterPack(), NewTTPDecl);

2649}

2650

2651QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType(

2653 bool SuppressObjCLifetime) {

2655

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

2657

2659

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

2662 Result = getSema().Context.getSubstTemplateTypeParmPackType(

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

2668 }

2669

2672 return BuildSubstTemplateTypeParmType(

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

2674 getPackIndex(Pack), Arg, TL.getNameLoc());

2675}

2676

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

2687 ErrorLoc = PDA.first;

2688 } else {

2690 }

2692 llvm::raw_svector_ostream OS(Entity);

2693 Printer(OS);

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

2697}

2698

2702 llvm::raw_svector_ostream OS(Entity);

2703 Printer(OS);

2706 C.backupStr(Entity),

2707 Location, StringRef()};

2708}

2709

2710ExprResult TemplateInstantiator::TransformRequiresTypeParams(

2716

2719 RE, Info,

2722

2723 unsigned ErrorIdx;

2724 if (getDerived().TransformFunctionTypeParams(

2725 KWLoc, Params, nullptr, nullptr, PTypes,

2726 &TransParams, PInfos, &ErrorIdx) ||

2727 Trap.hasErrorOccurred()) {

2729 ParmVarDecl *FailedDecl = Params[ErrorIdx];

2730

2731

2732 TransReqs.push_back(RebuildTypeRequirement(createSubstDiag(

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

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

2736 TransReqs, RBraceLoc);

2737 }

2738

2740}

2741

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

2745 return Req;

2747 if (AlwaysRebuild())

2748 return RebuildTypeRequirement(

2750 return Req;

2751 }

2752

2758 if (TypeInst.isInvalid())

2759 return nullptr;

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

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

2765 }));

2766 return RebuildTypeRequirement(TransType);

2767}

2768

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

2772 return Req;

2773

2775

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

2777 TransExpr;

2780 else {

2785 if (ExprInst.isInvalid())

2786 return nullptr;

2787 ExprResult TransExprRes = TransformExpr(E);

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

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

2794 });

2795 else

2796 TransExpr = TransExprRes.get();

2797 }

2798

2799 std::optionalconcepts::ExprRequirement::ReturnTypeRequirement TransRetReq;

2801 if (RetReq.isEmpty())

2802 TransRetReq.emplace();

2803 else if (RetReq.isSubstitutionFailure())

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

2805 else if (RetReq.isTypeConstraint()) {

2807 RetReq.getTypeConstraintTemplateParameterList();

2811 if (TPLInst.isInvalid())

2812 return nullptr;

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

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

2817 RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint()

2819 }));

2820 else {

2821 TPLInst.Clear();

2822 TransRetReq.emplace(TPL);

2823 }

2824 }

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

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

2828 std::move(*TransRetReq));

2829 return RebuildExprRequirement(

2830 cast<concepts::Requirement::SubstitutionDiagnostic *>(TransExpr),

2832}

2833

2835TemplateInstantiator::TransformNestedRequirement(

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

2838 return Req;

2840 if (AlwaysRebuild())

2843 return Req;

2844 }

2849 if (!getEvaluateConstraints()) {

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

2852 return nullptr;

2859 }

2860

2864 {

2871 if (ConstrInst.isInvalid())

2872 return nullptr;

2875 nullptr, {Req->getConstraintExpr()}, Result, TemplateArgs,

2878 TransConstraint = Result[0];

2879 assert(!Trap.hasErrorOccurred() && "Substitution failures must be handled "

2880 "by CheckConstraintSatisfaction.");

2881 }

2883 if (TransConstraint.isUsable() &&

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

2889 llvm::raw_svector_ostream OS(Entity);

2894 }

2895 return new (C)

2897}

2898

2903 bool AllowDeducedTST) {

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

2906 "instantiation stack");

2907

2910 return T;

2911

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

2913 return AllowDeducedTST ? Instantiator.TransformTypeWithDeducedTST(T)

2914 : Instantiator.TransformType(T);

2915}

2916

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

2923 "instantiation stack");

2924

2926 return nullptr;

2927

2930

2931

2935 }

2936

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

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

2941 if (Result.isNull())

2942 return nullptr;

2943

2945}

2946

2947

2951 bool *IsIncompleteSubstitution) {

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

2954 "instantiation stack");

2955

2956

2957

2959 return T;

2960

2961 TemplateInstantiator Instantiator(

2962 *this, TemplateArgs, Loc, Entity,

2963 IsIncompleteSubstitution != nullptr);

2964 QualType QT = Instantiator.TransformType(T);

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

2966 *IsIncompleteSubstitution = true;

2967 return QT;

2968}

2969

2973 return true;

2974

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

2977 return false;

2978

2981

2982 if (P) continue;

2983

2984

2985

2986 return true;

2987 }

2988

2989 return false;

2990}

2991

2998 bool EvaluateConstraints) {

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

3001 "instantiation stack");

3002

3004 return T;

3005

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

3007 Instantiator.setEvaluateConstraints(EvaluateConstraints);

3008

3010

3011 TypeLoc TL = T->getTypeLoc();

3013

3015

3018

3019

3020

3021

3022

3023 Result = Instantiator.TransformFunctionProtoType(

3024 TLB, Proto, ThisContext, ThisTypeQuals,

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

3027 } else {

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

3029 }

3030

3031

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

3033 return nullptr;

3034

3036}

3037

3042 bool Changed = false;

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

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

3045 Changed);

3046}

3047

3052

3055 ESI, ExceptionStorage, Args))

3056

3058

3060}

3061

3062namespace {

3063

3064 struct GetContainedInventedTypeParmVisitor :

3065 public TypeVisitor<GetContainedInventedTypeParmVisitor,

3066 TemplateTypeParmDecl *> {

3067 using TypeVisitor<GetContainedInventedTypeParmVisitor,

3069

3071 if (T.isNull())

3072 return nullptr;

3073 return Visit(T.getTypePtr());

3074 }

3075

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

3079 return nullptr;

3080 return T->getDecl();

3081 }

3082

3083

3084

3085

3087 return Visit(T->getNamedType());

3088 }

3089

3092 }

3093

3096 }

3097

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

3100 }

3101

3104 }

3105

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

3108 }

3109

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

3113 }

3114

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

3117 }

3118

3120 return VisitFunctionType(T);

3121 }

3122

3125 }

3126

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

3129 }

3130

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

3133 }

3134

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

3137 }

3138

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

3141 }

3142

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

3145 }

3146 };

3147

3148}

3149

3150namespace {

3151

3152struct ExpandPackedTypeConstraints

3154

3156

3158

3159 ExpandPackedTypeConstraints(

3161 : inherited(SemaRef), TemplateArgs(TemplateArgs) {}

3162

3163 using inherited::TransformTemplateTypeParmType;

3164

3168 if (T->isParameterPack()) {

3173 }

3174

3176

3178

3179 std::optional PackIndex;

3182

3184 TL.getType(), T->getDecl(), T->getIndex(), PackIndex,

3185 SubstTemplateTypeParmTypeFlag::ExpandPacksInPlace);

3189 return Result;

3190 }

3191

3195 if (T->getPackIndex()) {

3200 }

3201 return inherited::TransformSubstTemplateTypeParmType(TLB, TL);

3202 }

3203

3206 return inherited::TransformTemplateArguments(Args.begin(), Args.end(), Out);

3207 }

3208};

3209

3210}

3211

3215 bool EvaluateConstraints) {

3218

3219 if (!EvaluateConstraints) {

3220 bool ShouldExpandExplicitTemplateArgs =

3222 llvm::any_of(TemplArgInfo->arguments(), [](auto &Arg) {

3223 return Arg.getArgument().containsUnexpandedParameterPack();

3224 });

3225

3226

3227

3228

3229

3230

3231

3232

3233

3234

3235

3236

3237

3238

3239

3240 if (ShouldExpandExplicitTemplateArgs) {

3244 if (ExpandPackedTypeConstraints(*this, TemplateArgs)

3246 return true;

3247

3248

3251

3252 if (auto *FE = dyn_cast(ConstraintExpr)) {

3253 assert(FE->getLHS());

3254 ConstraintExpr = FE->getLHS();

3255 }

3256 auto *CSE = cast(ConstraintExpr);

3257 assert(!CSE->getTemplateArguments().empty() &&

3258 "Empty template arguments?");

3259 ConstrainedType = CSE->getTemplateArguments()[0].getAsType();

3260 assert(!ConstrainedType.isNull() &&

3261 "Failed to extract the original ConstrainedType?");

3262

3267 Inst, ConstrainedType,

3270 ->getEllipsisLoc()

3272 }

3275 return false;

3276 }

3277

3279

3280 if (TemplArgInfo) {

3284 InstArgs))

3285 return true;

3286 }

3294 ->getEllipsisLoc()

3296}

3297

3300 int indexAdjustment, std::optional NumExpansions,

3301 bool ExpectParameterPack, bool EvaluateConstraint) {

3304

3307

3308

3309

3310 NewDI = SubstType(ExpansionTL.getPatternLoc(), TemplateArgs,

3312 if (!NewDI)

3313 return nullptr;

3314

3316

3317

3318

3320 NumExpansions);

3321 } else if (ExpectParameterPack) {

3322

3323

3324

3325

3327 diag::err_function_parameter_pack_without_parameter_packs)

3329 return nullptr;

3330 }

3331 } else {

3334 }

3335

3336 if (!NewDI)

3337 return nullptr;

3338

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

3341 return nullptr;

3342 }

3343

3344

3345

3346

3347

3348

3349

3351 GetContainedInventedTypeParmVisitor().Visit(OldDI->getType())) {

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

3353 auto *Inst = cast_or_null(

3355

3356

3357

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

3360 return nullptr;

3361 }

3362 }

3363 }

3364

3369 NewDI->getType(), NewDI,

3371 if (!NewParm)

3372 return nullptr;

3373

3374

3382

3383

3384

3385

3386

3387

3388

3389

3390

3391

3393 }

3394

3398

3400

3402 } else {

3403

3405 }

3406

3407

3408

3410

3413

3415

3416 return NewParm;

3417}

3418

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

3428 "instantiation stack");

3429

3430 TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,

3432 return Instantiator.TransformFunctionTypeParams(

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

3434}

3435

3440 bool ForCallExpr) {

3443

3446

3449 return true;

3451 Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD;

3453 return true;

3454 }

3455

3457 {

3458

3459

3460

3461

3463 std::unique_ptr LIS;

3464

3465 if (ForCallExpr) {

3466

3467

3468

3469

3470

3471 LIS = std::make_unique(*this);

3473 false);

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

3475 return true;

3476 }

3477

3480 false);

3481 });

3482 }

3483 if (Result.isInvalid())

3484 return true;

3485

3486 if (ForCallExpr) {

3487

3492 PatternExpr->getBeginLoc());

3494

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

3497 if (Result.isInvalid())

3498 return true;

3499

3502 false);

3503 } else {

3504

3507 }

3508 if (Result.isInvalid())

3509 return true;

3510

3511

3513

3514 return false;

3515}

3516

3517bool

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

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

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

3526 if (RD->isInvalidDecl())

3528 }

3530 continue;

3531 }

3532

3535 if (Base.isPackExpansion()) {

3536

3537

3540 Unexpanded);

3541 bool ShouldExpand = false;

3542 bool RetainExpansion = false;

3543 std::optional NumExpansions;

3545 Base.getSourceRange(),

3546 Unexpanded,

3547 TemplateArgs, ShouldExpand,

3548 RetainExpansion,

3549 NumExpansions)) {

3551 continue;

3552 }

3553

3554

3555 if (ShouldExpand) {

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

3558

3560 TemplateArgs,

3561 Base.getSourceRange().getBegin(),

3563 if (!BaseTypeLoc) {

3565 continue;

3566 }

3567

3570 Base.getSourceRange(),

3571 Base.isVirtual(),

3572 Base.getAccessSpecifierAsWritten(),

3573 BaseTypeLoc,

3575 InstantiatedBases.push_back(InstantiatedBase);

3576 else

3578 }

3579

3580 continue;

3581 }

3582

3583

3584 EllipsisLoc = Base.getEllipsisLoc();

3586 BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),

3587 TemplateArgs,

3588 Base.getSourceRange().getBegin(),

3590 } else {

3591 BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),

3592 TemplateArgs,

3593 Base.getSourceRange().getBegin(),

3595 }

3596

3597 if (!BaseTypeLoc) {

3599 continue;

3600 }

3601

3604 Base.getSourceRange(),

3605 Base.isVirtual(),

3606 Base.getAccessSpecifierAsWritten(),

3607 BaseTypeLoc,

3608 EllipsisLoc))

3609 InstantiatedBases.push_back(InstantiatedBase);

3610 else

3612 }

3613

3616

3618}

3619

3620

3621namespace clang {

3622 namespace sema {

3628 }

3629}

3630

3631bool

3636 bool Complain) {

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

3641 Pattern, PatternDef, TSK, Complain))

3642 return true;

3643

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

3645 llvm::TimeTraceMetadata M;

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

3648 true);

3649 if (llvm::isTimeTraceVerbose()) {

3653 }

3654 return M;

3655 });

3656

3657 Pattern = PatternDef;

3658

3659

3663 MSInfo->setPointOfInstantiation(PointOfInstantiation);

3665 = dyn_cast(Instantiation)) {

3666 Spec->setTemplateSpecializationKind(TSK);

3667 Spec->setPointOfInstantiation(PointOfInstantiation);

3668 }

3669

3672 return true;

3675 "instantiating class definition");

3676

3677

3678

3679 ContextRAII SavedContext(*this, Instantiation);

3682

3683

3684

3685

3688

3689

3690

3691

3692

3693 SavePendingParsedClassStateRAII SavedPendingParsedClassState(*this);

3694

3695

3697

3698

3700

3701

3702

3704

3705

3707

3708

3711

3715

3718

3719 bool MightHaveConstexprVirtualFunctions = false;

3721

3722

3723

3724

3725

3726

3727

3728

3729

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

3731 continue;

3732

3733

3734

3735

3736

3737 if (isa(Member) ||

3738 (isa(Member) && cast(Member)->isLambda()))

3739 continue;

3740

3741 if (Member->isInvalidDecl()) {

3743 continue;

3744 }

3745

3747 if (NewMember) {

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

3749 Fields.push_back(Field);

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

3751

3752

3753

3754

3756 Enum->isCompleteDefinition()) {

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

3761 }

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

3763 if (SA->isFailed()) {

3764

3765

3767 break;

3768 }

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

3772 MightHaveConstexprVirtualFunctions = true;

3773 }

3774

3777 } else {

3778

3779

3780

3781

3782 }

3783 }

3784

3785

3789

3790

3791

3792

3793 if (ParsingClassDepth == 0)

3795

3796

3797

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

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

3802

3803

3804 auto *ND = cast(I->NewDecl);

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

3807 ND->isCXXInstanceMember());

3808

3809 Attr *NewAttr =

3811 if (NewAttr)

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

3815 }

3817 LateAttrs.clear();

3818

3820

3821

3822

3827 }

3828

3830

3833

3834

3835

3839 P != PEnd; ++P) {

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

3843 break;

3844 }

3845 }

3846

3847

3848

3852 P != PEnd; ++P) {

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

3856 break;

3857 }

3858 }

3859 }

3860

3861

3862 SavedContext.pop();

3863

3865

3866

3867

3868

3870 MarkVTableUsed(PointOfInstantiation, Instantiation, true);

3871 else if (MightHaveConstexprVirtualFunctions)

3873 true);

3874 }

3875

3877

3879}

3880

3888 Pattern, PatternDef, TSK,true))

3889 return true;

3890 Pattern = PatternDef;

3891

3892

3896 MSInfo->setPointOfInstantiation(PointOfInstantiation);

3897 }

3898

3901 return true;

3903 return false;

3905 "instantiating enum definition");

3906

3907

3908

3910

3911

3912

3913 ContextRAII SavedContext(*this, Instantiation);

3916

3918

3919

3921

3924

3925

3926 SavedContext.pop();

3927

3929}

3930

3934

3936 return false;

3937

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

3941

3942

3943

3945 if (!OldInit) {

3948 Diag(PointOfInstantiation,

3949 diag::err_default_member_initializer_not_yet_parsed)

3950 << OutermostClass << Pattern;

3951 Diag(Pattern->getEndLoc(),

3952 diag::note_default_member_initializer_not_yet_parsed);

3954 return true;

3955 }

3956

3959 return true;

3961

3962 Diag(PointOfInstantiation, diag::err_default_member_initializer_cycle)

3963 << Instantiation;

3964 return true;

3965 }

3967 "instantiating default member init");

3968

3969

3970

3974 ExprEvalContexts.back().DelayedDefaultInitializationContext = {

3975 PointOfInstantiation, Instantiation, CurContext};

3976

3978

3979

3982

3984 false);

3986 assert((Init || !isa(Init)) && "call-style init in class");

3989

3991 L->DefaultMemberInitializerInstantiated(Instantiation);

3992

3993

3995}

3996

3997namespace {

3998

3999

4000 struct PartialSpecMatchResult {

4003 };

4004}

4005

4010 return true;

4011

4016

4017

4018

4019

4020

4021

4022

4023

4024

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

4027 continue;

4028

4033 return true;

4034 }

4035

4036 return false;

4037}

4038

4039

4040

4041

4049 return {true};

4051 return {false};

4052

4056 if (!isa<ClassTemplatePartialSpecializationDecl *>(Specialized)) {

4057

4059

4060

4061

4062

4063

4064

4065

4066

4067

4068 typedef PartialSpecMatchResult MatchResult;

4074

4075

4076

4077

4078

4079

4080

4081

4082

4083

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

4086 continue;

4087

4092

4093

4098 } else {

4099 Matched.push_back(PartialSpecMatchResult());

4100 Matched.back().Partial = Partial;

4102 }

4103 }

4104

4105

4106

4107

4108

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

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

4112

4113

4114

4115 } else {

4116

4117

4118

4119

4120

4121

4122

4124 PEnd = Matched.end();

4125 P != PEnd; ++P) {

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

4128 P->Partial)

4129 Best = P;

4130 }

4131

4132

4133

4134 bool Ambiguous = false;

4136 PEnd = Matched.end();

4137 P != PEnd; ++P) {

4139 P->Partial, Best->Partial,

4140 PointOfInstantiation) != Best->Partial) {

4141 Ambiguous = true;

4142 break;

4143 }

4144 }

4145

4146 if (Ambiguous) {

4147

4150 S.Diag(PointOfInstantiation,

4151 diag::err_partial_spec_ordering_ambiguous)

4152 << ClassTemplateSpec;

4153

4154

4156 PEnd = Matched.end();

4157 P != PEnd; ++P)

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

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

4161

4162 return {true};

4163 }

4164 }

4165

4167 } else {

4168

4169

4170 }

4171 }

4172

4175 if (auto *PartialSpec =

4177

4178 while (PartialSpec->getInstantiatedFromMember()) {

4179

4180

4181 if (PartialSpec->isMemberSpecialization())

4182 break;

4183

4184 PartialSpec = PartialSpec->getInstantiatedFromMember();

4185 }

4186 Pattern = PartialSpec;

4187 } else {

4190

4191

4193 break;

4194

4196 }

4198 }

4199

4200 return Pattern;

4201}

4202

4207

4208 ClassTemplateSpec = cast(

4211 return true;

4212

4215 ClassTemplateSpec, TSK);

4218

4220 PointOfInstantiation, ClassTemplateSpec, Pattern.get(),

4222}

4223

4224void

4229

4230

4231

4232 assert(

4236 "Unexpected template specialization kind!");

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

4238 bool SuppressNew = false;

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

4241 Function->getInstantiatedFromMemberFunction()) {

4242

4243 if (Function->isIneligibleOrNotSelected())

4244 continue;

4245

4246 if (Function->getTrailingRequiresClause()) {

4250 continue;

4251 }

4252 }

4253

4254 if (Function->hasAttr())

4255 continue;

4256

4258 Function->getTemplateSpecializationKind();

4260 continue;

4261

4263 PointOfInstantiation, TSK, Function, PrevTSK,

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

4265 SuppressNew)

4266 continue;

4267

4268

4269

4270

4271

4272

4273

4275 continue;

4276

4277 Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);

4278

4279 if (Function->isDefined()) {

4280

4281

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

4288 }

4289 }

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

4291 if (isa(Var))

4292 continue;

4293

4295 if (Var->hasAttr())

4296 continue;

4297

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

4302 continue;

4303

4305 Var,

4308 SuppressNew) ||

4309 SuppressNew)

4310 continue;

4311

4313

4314

4315

4316

4317

4318

4320 continue;

4321

4324 } else {

4326 }

4327 }

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

4329 if (Record->hasAttr())

4330 continue;

4331

4332

4333

4334

4335

4336

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

4339 continue;

4340

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

4343

4346 continue;

4347

4350

4351

4352

4353

4354

4355

4356 continue;

4357 }

4358

4363 SuppressNew) ||

4364 SuppressNew)

4365 continue;

4366

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

4369

4370 if (Record->getDefinition()) {

4372

4373

4374

4375

4376

4377

4381 }

4382

4383 continue;

4384 }

4385

4387 TemplateArgs,

4388 TSK);

4389 } else {

4391 Record->getTemplateSpecializationKind() ==

4393 Record->setTemplateSpecializationKind(TSK);

4395 }

4396 }

4397

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

4399 if (Pattern)

4401 TSK);

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

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

4405

4408 continue;

4409

4411 PointOfInstantiation, TSK, Enum,

4414 SuppressNew)

4415 continue;

4416

4417 if (Enum->getDefinition())

4418 continue;

4419

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

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

4422

4425 continue;

4426

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

4428 } else {

4431 }

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

4433

4434

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

4441 assert(Pattern);

4443 TemplateArgs);

4444 }

4445 }

4446 }

4447}

4448

4449void

4454

4455

4456

4457

4458

4459

4460

4461

4464 TSK);

4465}

4466

4469 if (!S)

4470 return S;

4471

4472 TemplateInstantiator Instantiator(*this, TemplateArgs,

4475 return Instantiator.TransformStmt(S);

4476}

4477

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

4484 return Instantiator.TransformTemplateArgument(Input, Output);

4485}

4486

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

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

4494}

4495

4498 if (E)

4499 return E;

4500

4501 TemplateInstantiator Instantiator(*this, TemplateArgs,

4504 return Instantiator.TransformExpr(E);

4505}

4506

4510

4511

4513}

4514

4517 if (E)

4518 return E;

4519

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

4522 Instantiator.setEvaluateConstraints(false);

4523 return Instantiator.TransformExpr(E);

4524}

4525

4528 bool CXXDirectInit) {

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

4531 return Instantiator.TransformInitializer(Init, CXXDirectInit);

4532}

4533

4537 if (Exprs.empty())

4538 return false;

4539

4540 TemplateInstantiator Instantiator(*this, TemplateArgs,

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

4544 IsCall, Outputs);

4545}

4546

4550 if (!NNS)

4552

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

4555 return Instantiator.TransformNestedNameSpecifierLoc(NNS);

4556}

4557

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

4563 return Instantiator.TransformDeclarationNameInfo(NameInfo);

4564}

4565

4570 TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,

4573 SS.Adopt(QualifierLoc);

4574 return Instantiator.TransformTemplateName(SS, Name, Loc);

4575}

4576

4578

4579

4580

4581

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

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

4584 unsigned i = PV->getFunctionScopeIndex();

4585

4586

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

4589 }

4590 }

4591 return D;

4592}

4593

4594

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

4599 Current = Current->Outer) {

4600

4601

4602 const Decl *CheckD = D;

4603 do {

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

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

4606 return &Found->second;

4607

4608

4609

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

4611 CheckD = Tag->getPreviousDecl();

4612 else

4613 CheckD = nullptr;

4614 } while (CheckD);

4615

4616

4617 if (!Current->CombineWithOuterScope)

4618 break;

4619 }

4620

4621

4622

4623 if (isa(D) || isa(D) ||

4624 isa(D))

4625 return nullptr;

4626

4627

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

4629 if (RD->isLocalClass())

4630 return nullptr;

4631

4632

4633

4634 if (isa(D))

4635 return nullptr;

4636

4637

4638

4639 if (isa(D) &&

4641 return nullptr;

4642

4643

4644

4645

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

4647 return nullptr;

4648}

4649

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

4653 if (Stored.isNull()) {

4654#ifndef NDEBUG

4655

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

4658 Current = Current->Outer;

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

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

4661 }

4662#endif

4663 Stored = Inst;

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

4665 Pack->push_back(cast(Inst));

4666 } else {

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

4668 }

4669}

4670

4674 DeclArgumentPack *Pack = cast<DeclArgumentPack *>(LocalDecls[D]);

4675 Pack->push_back(Inst);

4676}

4677

4679#ifndef NDEBUG

4680

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

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

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

4685#endif

4686

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

4690 Stored = Pack;

4691 ArgumentPacks.push_back(Pack);

4692}

4693

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

4697 return true;

4698 return false;

4699}

4700

4703 unsigned NumExplicitArgs) {

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

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

4706 assert((!PartiallySubstitutedPack

4707 || NumArgsInPartiallySubstitutedPack == NumExplicitArgs) &&

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

4709 PartiallySubstitutedPack = Pack;

4710 ArgsInPartiallySubstitutedPack = ExplicitArgs;

4711 NumArgsInPartiallySubstitutedPack = NumExplicitArgs;

4712}

4713

4716 unsigned *NumExplicitArgs) const {

4717 if (ExplicitArgs)

4718 *ExplicitArgs = nullptr;

4719 if (NumExplicitArgs)

4720 *NumExplicitArgs = 0;

4721

4723 Current = Current->Outer) {

4724 if (Current->PartiallySubstitutedPack) {

4725 if (ExplicitArgs)

4726 *ExplicitArgs = Current->ArgsInPartiallySubstitutedPack;

4727 if (NumExplicitArgs)

4728 *NumExplicitArgs = Current->NumArgsInPartiallySubstitutedPack;

4729

4730 return Current->PartiallySubstitutedPack;

4731 }

4732

4733 if (!Current->CombineWithOuterScope)

4734 break;

4735 }

4736

4737 return nullptr;

4738}

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.

Defines the C++ template declaration subclasses.

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

static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, QualType Ty)

Defines the clang::LangOptions interface.

llvm::MachO::Record Record

MatchFinder::MatchResult MatchResult

static const Decl * getCanonicalParmVarDecl(const Decl *D)

static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T)

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

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

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

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

static TemplateArgument getPackSubstitutedTemplateArgument(Sema &S, TemplateArgument Arg)

Defines the clang::TypeLoc interface and its subclasses.

C Language Family Type Representation.

virtual void HandleTagDeclDefinition(TagDecl *D)

HandleTagDeclDefinition - This callback is invoked each time a TagDecl (e.g.

virtual bool HandleTopLevelDecl(DeclGroupRef D)

HandleTopLevelDecl - Handle the specified top-level declaration.

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

TranslationUnitDecl * getTranslationUnitDecl() const

QualType getTagDeclType(const TagDecl *Decl) const

Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl.

bool hasSameType(QualType T1, QualType T2) const

Determine whether the given types T1 and T2 are equivalent.

QualType getSubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl, unsigned Index, std::optional< unsigned > PackIndex, SubstTemplateTypeParmTypeFlag Flag=SubstTemplateTypeParmTypeFlag::None) const

Retrieve a substitution-result type.

QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const

Return the unique reference to the type for the specified type declaration.

QualType getQualifiedType(SplitQualType split) const

Un-split a SplitQualType.

const clang::PrintingPolicy & getPrintingPolicy() const

const TargetInfo & getTargetInfo() const

Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.

Represents an array type, per C99 6.7.5.2 - Array Declarators.

Attr - This represents one attribute.

An attributed type is a type to which a type attribute has been applied.

BlockExpr - Adaptor class for mixing a BlockDecl with expressions.

Represents a base class of a C++ class.

A default argument (C++ [dcl.fct.default]).

Represents a static or instance method of a struct/union/class.

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.

void setTemplateSpecializationKind(TemplateSpecializationKind TSK)

Set the kind of specialization or template instantiation this is.

Represents a C++ nested-name-specifier or a global scope specifier.

void Adopt(NestedNameSpecifierLoc Other)

Adopt an existing nested-name-specifier (with source-range information).

Declaration of a class template.

ClassTemplateDecl * getMostRecentDecl()

CXXRecordDecl * getTemplatedDecl() const

Get the underlying class declarations of the template.

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

Retrieve the set of partial specializations of this class template.

ClassTemplateDecl * getInstantiatedFromMemberTemplate() const

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

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

bool HasSubstitutionFailure()

static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)

The results of name lookup within a DeclContext.

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

bool isFileContext() const

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.

A reference to a declared variable, function, enum, etc.

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

TemplateDecl * getDescribedTemplate() const

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

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

virtual Decl * getCanonicalDecl()

Retrieves the "canonical" declaration of the given declaration.

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.

NestedNameSpecifier * getQualifier() const

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

SourceLocation getInnerLocStart() const

Return start of source range ignoring outer template declarations.

SourceLocation getOuterLocStart() const

Return start of source range taking into account any outer template declarations.

SourceLocation getBeginLoc() const LLVM_READONLY

TypeSourceInfo * getTypeSourceInfo() const

Information about one declarator, including the parsed type information and the identifier.

Represents an extended vector type where either the type or size is dependent.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

bool hasFatalErrorOccurred() const

unsigned getTemplateBacktraceLimit() const

Retrieve the maximum number of template instantiation notes to emit along with a given diagnostic.

Recursive AST visitor that supports extension via dynamic dispatch.

Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...

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

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

For an enumeration member that was instantiated from a member enumeration of a templated class,...

EnumDecl * getInstantiatedFromMemberEnum() const

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

EnumDecl * getDefinition() const

This represents one expression.

ExprValueKind getValueKind() const

getValueKind - The value kind that this expression produces.

bool isTypeDependent() const

Determines whether the type of this expression depends on.

llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const

EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.

bool isLValue() const

isLValue - True if this expression is an "l-value" according to the rules of the current language.

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

static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)

Create a code modification hint that replaces the given source range with the given code string.

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.

Represents a reference to a function parameter pack or init-capture pack that has been substituted bu...

VarDecl *const * iterator

Iterators over the parameters which the parameter pack expanded into.

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

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

FunctionType - C99 6.7.5.3 - Function Declarators.

QualType getReturnType() const

One of these records is kept for each identifier that is lexed.

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 the sequence of initializations required to initialize a given object or reference with a s...

Describes an entity that is being initialized.

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

Create the initialization entity for a parameter.

Wrapper for source info for injected class names of class templates.

The injected class name of a C++ class template or class template partial specialization.

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

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

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

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

Retrieve the partially-substitued template parameter pack.

bool isLocalPackExpansion(const Decl *D)

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

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)

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

void MakeInstantiatedLocalArgPack(const Decl *D)

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

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

Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.

A pointer to member type per C++ 8.3.3 - Pointers to members.

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

bool isInstantiationDependent() const

Whether this nested name specifier involves a template parameter.

NestedNameSpecifier * getPrefix() const

Return the prefix of this nested name specifier.

const Type * getAsType() const

Retrieve the type stored in this nested name specifier.

NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.

QualType getExpansionType(unsigned I) const

Retrieve a particular expansion type within an expanded parameter pack.

unsigned getPosition() const

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

bool isExpandedParameterPack() const

Whether this parameter is a non-type template parameter pack that has a known list of different types...

bool isParameterPack() const

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

unsigned getIndex() const

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

unsigned getDepth() const

Get the nesting depth of the template parameter.

Represents a pack expansion of types.

Sugar for parentheses used when specifying types.

Represents a parameter to a function.

unsigned getFunctionScopeIndex() const

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

void setDefaultArg(Expr *defarg)

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)

PointerType - C99 6.7.5.1 - Pointer Declarators.

[C99 6.4.2.2] - A predefined identifier such as func.

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.

QualType getNonReferenceType() const

If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...

The collection of all-type qualifiers we support.

void removeObjCLifetime()

Represents a struct/union/class.

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

bool isMemberSpecialization() const

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

Base for LValueReferenceType and RValueReferenceType.

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

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

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)

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)

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.

bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef< UnexpandedParameterPack > Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, bool &RetainExpansion, std::optional< unsigned > &NumExpansions)

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

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

ParmVarDecl * SubstParmVarDecl(ParmVarDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, int indexAdjustment, std::optional< unsigned > NumExpansions, bool ExpectParameterPack, bool EvaluateConstraints=true)

void ActOnFinishCXXNonNestedClass()

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

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

void ActOnFinishDelayedMemberInitializers(Decl *Record)

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

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

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

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

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

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

llvm::DenseSet< std::pair< Decl *, unsigned > > InstantiatingSpecializations

Specializations whose definitions are currently being instantiated.

void deduceOpenCLAddressSpace(ValueDecl *decl)

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

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

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

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

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

@ CTAK_Specified

The template argument was specified in the code or was instantiated with some deduced template argume...

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

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

bool InNonInstantiationSFINAEContext

Whether we are in a SFINAE context that is not associated with template instantiation.

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

DiagnosticsEngine & getDiagnostics() const

TypeSourceInfo * CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, std::optional< unsigned > NumExpansions)

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

ExprResult BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg, SourceLocation Loc)

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

ASTContext & getASTContext() const

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

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

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 SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)

bool isAcceptableTagRedeclaration(const TagDecl *Previous, TagTypeKind NewTag, bool isDefinition, SourceLocation NewTagLoc, const IdentifierInfo *Name)

Determine whether a tag with a given kind is acceptable as a redeclaration of the given tag declarati...

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

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

const LangOptions & getLangOpts() const

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

Attach a type-constraint to a template parameter.

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

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

bool CheckConstraintSatisfaction(const NamedDecl *Template, ArrayRef< const Expr * > ConstraintExprs, const MultiLevelTemplateArgumentList &TemplateArgLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction)

Check whether the given list of constraint expressions are satisfied (as if in a 'conjunction') given...

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

void MarkVirtualMembersReferenced(SourceLocation Loc, const CXXRecordDecl *RD, bool ConstexprOnly=false)

MarkVirtualMembersReferenced - Will mark all members of the given CXXRecordDecl referenced.

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

Do template substitution on declaration name info.

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

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

std::vector< std::unique_ptr< TemplateInstantiationCallback > > TemplateInstCallbacks

The template instantiation callbacks to trace or track instantiations (objects can be chained).

void PrintInstantiationStack()

Prints the current instantiation stack through a series of notes.

void popCodeSynthesisContext()

bool usesPartialOrExplicitSpecialization(SourceLocation Loc, ClassTemplateSpecializationDecl *ClassTemplateSpec)

void pushCodeSynthesisContext(CodeSynthesisContext Ctx)

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

std::optional< sema::TemplateDeductionInfo * > isSFINAEContext() const

Determines whether we are currently in a context where template argument substitution failures are no...

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

int ArgumentPackSubstitutionIndex

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

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

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

ExprResult CheckPlaceholderExpr(Expr *E)

Check for operands with placeholder types and complain if found.

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 CheckAlwaysInlineAttr(const Stmt *OrigSt, const Stmt *CurSt, const AttributeCommonInfo &A)

ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, ParmVarDecl *Param, Expr *Init=nullptr)

BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating the default expr if needed.

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

Instantiate the definition of a field from the given pattern.

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.

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

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.

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

bool hasUncompilableErrorOccurred() const

Whether uncompilable error has occurred.

@ 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 CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg, NamedDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, unsigned ArgumentPackIndex, SmallVectorImpl< TemplateArgument > &SugaredConverted, SmallVectorImpl< TemplateArgument > &CanonicalConverted, CheckTemplateArgumentKind CTAK)

Check that the given template argument corresponds to the given template parameter.

NestedNameSpecifierLoc SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const MultiLevelTemplateArgumentList &TemplateArgs)

void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)

bool RebuildingImmediateInvocation

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

void CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record)

Perform semantic checks on a class definition that has been completing, introducing implicitly-declar...

SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts

A stack of expression evaluation contexts.

SourceManager & SourceMgr

DiagnosticsEngine & Diags

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

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

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.

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.

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

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

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

ExprResult BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)

Given a non-type template argument that refers to a declaration and the type of its corresponding non...

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

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

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

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.

Represents an expression that computes the length of a parameter pack.

Encodes a location in the source.

unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const

StringRef getFilename(SourceLocation SpellingLoc) const

Return the filename of the file containing a SourceLocation.

SourceLocation getExpansionLoc(SourceLocation Loc) const

Given a SourceLocation object Loc, return the expansion location referenced by the ID.

A trivial tuple used to represent a source range.

void warnOnStackNearlyExhausted(SourceLocation Loc)

Check to see if we're low on stack space and produce a warning if we're low on stack space (Currently...

Represents a C++11 static_assert declaration.

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

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 a reference to a non-type template parameter that has been substituted with a template arg...

Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...

A structure for storing an already-substituted template template parameter pack.

Wrapper for substituted template type parameters.

Represents the result of substituting a set of types for a template type parameter pack.

Wrapper for substituted template type parameters.

Represents the result of substituting a type for a template type parameter.

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

void setTagKind(TagKind TK)

SourceRange getBraceRange() const

SourceLocation getInnerLocStart() const

Return SourceLocation representing start of source range ignoring outer template declarations.

StringRef getKindName() const

void startDefinition()

Starts the definition of this tag declaration.

TagKind getTagKind() const

void setBraceRange(SourceRange R)

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

A convenient class for passing around template argument information.

void setLAngleLoc(SourceLocation Loc)

void setRAngleLoc(SourceLocation Loc)

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.

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.

@ Declaration

The template argument is a declaration that was provided for a pointer, reference,...

@ Template

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

@ Pack

The template argument is actually a parameter pack.

@ NullPtr

The template argument is a null pointer or null pointer to member that was provided for a non-type te...

@ Type

The template argument is a type.

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

void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA)

void disableLateAttributeInstantiation()

delayed_var_partial_spec_iterator delayed_var_partial_spec_end()

delayed_partial_spec_iterator delayed_partial_spec_begin()

Return an iterator to the beginning of the set of "delayed" partial specializations,...

void setEvaluateConstraints(bool B)

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

LocalInstantiationScope * getStartingScope() const

VarTemplatePartialSpecializationDecl * InstantiateVarTemplatePartialSpecialization(VarTemplateDecl *VarTemplate, VarTemplatePartialSpecializationDecl *PartialSpec)

Instantiate the declaration of a variable template partial specialization.

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

void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern)

delayed_partial_spec_iterator delayed_partial_spec_end()

Return an iterator to the end of the set of "delayed" partial specializations, which must be passed t...

delayed_var_partial_spec_iterator delayed_var_partial_spec_begin()

ClassTemplatePartialSpecializationDecl * InstantiateClassTemplatePartialSpecialization(ClassTemplateDecl *ClassTemplate, ClassTemplatePartialSpecializationDecl *PartialSpec)

Instantiate the declaration of a class template partial specialization.

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.

bool isNull() const

Determine whether this template name is NULL.

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.

Represents a type template specialization; the template must be a class template, a type alias templa...

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.

bool isParameterPack() const

Returns whether this is a parameter pack.

void setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint)

Wrapper for template type parameters.

bool isParameterPack() const

unsigned getIndex() const

unsigned getDepth() const

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

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

ConceptDecl * getNamedConcept() const

Expr * getImmediatelyDeclaredConstraint() const

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

const NestedNameSpecifierLoc & getNestedNameSpecifierLoc() 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 getEndLoc() const

Get the end source location.

SourceLocation getBeginLoc() const

Get the begin source location.

A container of type source information.

TypeLoc getTypeLoc() const

Return the TypeLoc wrapper for the type source info.

QualType getType() const

Return the type wrapped by this type source info.

SourceLocation getNameLoc() const

void setNameLoc(SourceLocation Loc)

static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword)

Converts an elaborated type keyword into a TagTypeKind.

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 isDependentType() const

Whether this type is a dependent type, meaning that its definition somehow depends on a template para...

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

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Represents a variable declaration or definition.

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

bool isParameterPack() const

Determine whether this variable is actually a function parameter pack or init-capture pack.

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.

Represents a GCC generic vector type.

A requires-expression requirement which queries the validity and properties of an expression ('simple...

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

A requires-expression requirement which queries the existence of a type name or type template special...

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.

Defines the clang::TargetInfo interface.

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)

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

@ Specialization

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

NamedDecl * getAsNamedDecl(TemplateParameter P)

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.

TagTypeKind

The kind of a tag type.

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

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

Stores a template parameter of any kind.

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

const FunctionProtoType * T

void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)

Print a template argument list, including the '<' and '>' enclosing the template arguments.

std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt

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

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.

ElaboratedTypeKeyword

The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...

@ None

No keyword precedes the qualified type name.

@ Enum

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

@ Typename

The "typename" keyword precedes the qualified type name, e.g., typename T::type.

@ EST_Uninstantiated

not instantiated yet

@ EST_None

no exception specification

__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)

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

SourceLocation RAngleLoc

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

SourceLocation LAngleLoc

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

llvm::ArrayRef< TemplateArgumentLoc > arguments() 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

bool SavedInNonInstantiationSFINAEContext

Was the enclosing context a non-instantiation SFINAE context?

const TemplateArgument * TemplateArgs

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

sema::TemplateDeductionInfo * DeductionInfo

The template deduction info object associated with the substitution or checking of explicit or deduce...

NamedDecl * Template

The template (or partial specialization) in which we are performing the instantiation,...

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.

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

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

void Clear()

Note that we have finished instantiating this template.

bool isAlreadyInstantiating() const

Determine whether we are already instantiating this specialization in some surrounding active instant...

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