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

1

2

3

4

5

6

7

8

9

10

11

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

37#include

38

39using namespace clang;

40

44 return true;

45

47 return cast(DC)->isLocalClass();

48

49 return false;

50}

51

52template

53static bool SubstQualifier(Sema &SemaRef, const DeclT *OldDecl, DeclT *NewDecl,

55 if (!OldDecl->getQualifierLoc())

56 return false;

57

58 assert((NewDecl->getFriendObjectKind() ||

59 !OldDecl->getLexicalDeclContext()->isDependentContext()) &&

60 "non-friend with qualified name defined in dependent context");

62 SemaRef,

63 const_cast<DeclContext *>(NewDecl->getFriendObjectKind()

64 ? NewDecl->getLexicalDeclContext()

65 : OldDecl->getLexicalDeclContext()));

66

69 TemplateArgs);

70

71 if (!NewQualifierLoc)

72 return true;

73

74 NewDecl->setQualifierInfo(NewQualifierLoc);

75 return false;

76}

77

80 return ::SubstQualifier(SemaRef, OldDecl, NewDecl, TemplateArgs);

81}

82

85 return ::SubstQualifier(SemaRef, OldDecl, NewDecl, TemplateArgs);

86}

87

88

89#include "clang/Sema/AttrTemplateInstantiate.inc"

90

93 const AlignedAttr *Aligned, Decl *New, bool IsPackExpansion) {

94 if (Aligned->isAlignmentExpr()) {

95

99 if (Result.isInvalid())

101 } else {

103 S.SubstType(Aligned->getAlignmentType(), TemplateArgs,

106 Aligned->getLocation(),

107 Result->getTypeLoc().getSourceRange()))

109 }

110 }

111}

112

115 const AlignedAttr *Aligned, Decl *New) {

116 if (!Aligned->isPackExpansion()) {

118 return;

119 }

120

122 if (Aligned->isAlignmentExpr())

124 Unexpanded);

125 else

127 Unexpanded);

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

129

130

131 bool Expand = true, RetainExpansion = false;

132 std::optional NumExpansions;

133

136 Unexpanded, TemplateArgs, Expand,

137 RetainExpansion, NumExpansions))

138 return;

139

140 if (!Expand) {

143 } else {

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

147 }

148 }

149}

150

153 const AssumeAlignedAttr *Aligned, Decl *New) {

154

157

158 Expr *E, *OE = nullptr;

160 if (Result.isInvalid())

161 return;

163

164 if (Aligned->getOffset()) {

165 Result = S.SubstExpr(Aligned->getOffset(), TemplateArgs);

166 if (Result.isInvalid())

167 return;

169 }

170

172}

173

176 const AlignValueAttr *Aligned, Decl *New) {

177

181 if (Result.isInvalid())

183}

184

187 const AllocAlignAttr *Align, Decl *New) {

190 llvm::APInt(64, Align->getParamIndex().getSourceIndex()),

193}

194

197 const AnnotateAttr *Attr, Decl *New) {

200

201

202

203 bool HasDelayedArgs = Attr->delayedArgs_size();

204

206 HasDelayedArgs

209

212 false, TemplateArgs, Args))

213 return;

214

215 StringRef Str = Attr->getAnnotation();

216 if (HasDelayedArgs) {

217 if (Args.size() < 1) {

218 S.Diag(Attr->getLoc(), diag::err_attribute_too_few_arguments)

219 << Attr << 1;

220 return;

221 }

222

224 return;

225

227 ActualArgs.insert(ActualArgs.begin(), Args.begin() + 1, Args.end());

228 std::swap(Args, ActualArgs);

229 }

231 if (AA) {

233 }

234}

235

239 Expr *Cond = nullptr;

240 {

245 if (Result.isInvalid())

246 return nullptr;

248 }

252 return nullptr;

253 Cond = Converted.get();

254 }

255

259 S.Diag(A->getLocation(), diag::err_attr_cond_never_constant_expr) << A;

260 for (const auto &P : Diags)

261 S.Diag(P.first, P.second);

262 return nullptr;

263 }

264 return Cond;

265}

266

269 const EnableIfAttr *EIA, const Decl *Tmpl, FunctionDecl *New) {

271 S, TemplateArgs, EIA, EIA->getCond(), Tmpl, New);

272

273 if (Cond)

275 Cond, EIA->getMessage()));

276}

277

280 const DiagnoseIfAttr *DIA, const Decl *Tmpl, FunctionDecl *New) {

282 S, TemplateArgs, DIA, DIA->getCond(), Tmpl, New);

283

284 if (Cond)

286 S.getASTContext(), *DIA, Cond, DIA->getMessage(),

287 DIA->getDiagnosticType(), DIA->getArgDependent(), New));

288}

289

290

291

294 const CUDALaunchBoundsAttr &Attr, Decl *New) {

295

298

300 if (Result.isInvalid())

301 return;

303

304 Expr *MinBlocks = nullptr;

305 if (Attr.getMinBlocks()) {

307 if (Result.isInvalid())

308 return;

310 }

311

312 Expr *MaxBlocks = nullptr;

313 if (Attr.getMaxBlocks()) {

315 if (Result.isInvalid())

316 return;

318 }

319

321}

322

323static void

326 const ModeAttr &Attr, Decl *New) {

328 true);

329}

330

331

334 const OMPDeclareSimdDeclAttr &Attr, Decl *New) {

335

336 if (auto *FTD = dyn_cast(New))

337 New = FTD->getTemplatedDecl();

338 auto *FD = cast(New);

339 auto *ThisContext = dyn_cast_or_null(FD->getDeclContext());

342

345 if (auto *PVD = dyn_cast(DRE->getDecl())) {

348 if (FD->getNumParams() > PVD->getFunctionScopeIndex())

349 Local.InstantiatedLocal(

350 PVD, FD->getParamDecl(PVD->getFunctionScopeIndex()));

352 }

354 FD->isCXXInstanceMember());

356 };

357

358

359

365 return Res;

367 };

368

370 if (auto *E = Attr.getSimdlen())

371 Simdlen = Subst(E);

372

373 if (Attr.uniforms_size() > 0) {

374 for(auto *E : Attr.uniforms()) {

377 continue;

378 Uniforms.push_back(Inst.get());

379 }

380 }

381

382 auto AI = Attr.alignments_begin();

383 for (auto *E : Attr.aligneds()) {

386 continue;

387 Aligneds.push_back(Inst.get());

389 if (*AI)

390 Inst = S.SubstExpr(*AI, TemplateArgs);

391 Alignments.push_back(Inst.get());

392 ++AI;

393 }

394

395 auto SI = Attr.steps_begin();

396 for (auto *E : Attr.linears()) {

399 continue;

400 Linears.push_back(Inst.get());

402 if (*SI)

403 Inst = S.SubstExpr(*SI, TemplateArgs);

404 Steps.push_back(Inst.get());

405 ++SI;

406 }

407 LinModifiers.append(Attr.modifiers_begin(), Attr.modifiers_end());

410 Uniforms, Aligneds, Alignments, Linears, LinModifiers, Steps,

412}

413

414

417 const OMPDeclareVariantAttr &Attr, Decl *New) {

418

419 if (auto *FTD = dyn_cast(New))

420 New = FTD->getTemplatedDecl();

421 auto *FD = cast(New);

422 auto *ThisContext = dyn_cast_or_null(FD->getDeclContext());

423

424 auto &&SubstExpr = [FD, ThisContext, &S, &TemplateArgs](Expr *E) {

426 if (auto *PVD = dyn_cast(DRE->getDecl())) {

429 if (FD->getNumParams() > PVD->getFunctionScopeIndex())

430 Local.InstantiatedLocal(

431 PVD, FD->getParamDecl(PVD->getFunctionScopeIndex()));

433 }

435 FD->isCXXInstanceMember());

437 };

438

439

440

441 auto &&Subst = [&SubstExpr, &S](Expr *E) {

446 return Res;

448 };

449

451 if (Expr *E = Attr.getVariantFuncRef()) {

452

453

456 VariantFuncRef = Subst(E);

457 }

458

459

460

462 TI = *Attr.getTraitInfos();

463

464

465 auto SubstScoreOrConditionExpr = [&S, Subst](Expr *&E, bool) {

466 if (E) {

471 E = ER.get();

472 else

473 return true;

474 }

475 return false;

476 };

478 return;

479

480 Expr *E = VariantFuncRef.get();

481

482

483

484 std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =

488

489 if (!DeclVarData)

490 return;

491

492 E = DeclVarData->second;

493 FD = DeclVarData->first;

494

496 if (auto *VariantFD = dyn_cast(VariantDRE->getDecl())) {

497 if (auto *VariantFTD = VariantFD->getDescribedFunctionTemplate()) {

498 if (!VariantFTD->isThisDeclarationADefinition())

499 return;

503

506 if (!SubstFD)

507 return;

509 SubstFD->getType(), FD->getType(),

510 false,

511 false, true);

512 if (NewType.isNull())

513 return;

515 New->getLocation(), SubstFD, true,

516 false, false);

517 SubstFD->setInstantiationIsPending(!SubstFD->isDefined());

520 false,

521 SubstFD->getLocation(),

523 }

524 }

525 }

526

530

531 for (Expr *E : Attr.adjustArgsNothing()) {

534 continue;

535 NothingExprs.push_back(ER.get());

536 }

537 for (Expr *E : Attr.adjustArgsNeedDevicePtr()) {

540 continue;

541 NeedDevicePtrExprs.push_back(ER.get());

542 }

544

545 AppendArgs.emplace_back(II.IsTarget, II.IsTargetSync);

546 }

547

549 FD, E, TI, NothingExprs, NeedDevicePtrExprs, AppendArgs, SourceLocation(),

551}

552

555 const AMDGPUFlatWorkGroupSizeAttr &Attr, Decl *New) {

556

559

561 if (Result.isInvalid())

562 return;

564

566 if (Result.isInvalid())

567 return;

569

571}

572

576 return ES;

578 Expr *Cond = nullptr;

579 {

585 }

586 Cond = SubstResult.get();

587 }

592}

593

596 const AMDGPUWavesPerEUAttr &Attr, Decl *New) {

597

600

602 if (Result.isInvalid())

603 return;

605

606 Expr *MaxExpr = nullptr;

607 if (auto Max = Attr.getMax()) {

609 if (Result.isInvalid())

610 return;

612 }

613

615}

616

619 const AMDGPUMaxNumWorkGroupsAttr &Attr, Decl *New) {

622

625 return;

628 return;

631 return;

632

636

638}

639

640

641

642

645 const SYCLKernelAttr &Attr, Decl *New) {

647}

648

649

650

651

653

654

655 if (const auto *PNA = dyn_cast(A)) {

656 QualType T = PNA->getTypedefType();

657 const auto *RD = cast(D);

660 return false;

661 for (const auto *ExistingPNA : D->specific_attrs())

663 PNA->getTypedefType()))

664 return false;

665 return true;

666 }

667

668 if (const auto *BA = dyn_cast(A)) {

669 const FunctionDecl *FD = dyn_cast(D);

670 switch (BA->getID()) {

671 case Builtin::BIforward:

672

673

674

678 return false;

679 }

680 [[fallthrough]];

681 case Builtin::BImove:

682 case Builtin::BImove_if_noexcept:

683

684

685

686

688 return false;

689 break;

690 }

691 }

692

693 return true;

694}

695

698 const HLSLParamModifierAttr *Attr, Decl *New) {

702}

703

708 if (NamedDecl *ND = dyn_cast(New)) {

709

710

711

712 for (const auto *TmplAttr : Tmpl->attrs()) {

714 continue;

715

716

717

719 *this, dyn_cast_or_null(ND->getDeclContext()),

720 Qualifiers(), ND->isCXXInstanceMember());

721

723 TmplAttr, Context, *this, TemplateArgs);

726 }

727 }

728}

729

733 case clang::attr::CFConsumed:

735 case clang::attr::OSConsumed:

737 case clang::attr::NSConsumed:

739 default:

740 llvm_unreachable("Wrong argument supplied");

741 }

742}

743

748 for (const auto *TmplAttr : Tmpl->attrs()) {

750 continue;

751

752

753 const AlignedAttr *Aligned = dyn_cast(TmplAttr);

754 if (Aligned && Aligned->isAlignmentDependent()) {

756 continue;

757 }

758

759 if (const auto *AssumeAligned = dyn_cast(TmplAttr)) {

761 continue;

762 }

763

764 if (const auto *AlignValue = dyn_cast(TmplAttr)) {

766 continue;

767 }

768

769 if (const auto *AllocAlign = dyn_cast(TmplAttr)) {

771 continue;

772 }

773

774 if (const auto *Annotate = dyn_cast(TmplAttr)) {

776 continue;

777 }

778

779 if (const auto *EnableIf = dyn_cast(TmplAttr)) {

781 cast(New));

782 continue;

783 }

784

785 if (const auto *DiagnoseIf = dyn_cast(TmplAttr)) {

787 cast(New));

788 continue;

789 }

790

791 if (const auto *CUDALaunchBounds =

792 dyn_cast(TmplAttr)) {

794 *CUDALaunchBounds, New);

795 continue;

796 }

797

798 if (const auto *Mode = dyn_cast(TmplAttr)) {

800 continue;

801 }

802

803 if (const auto *OMPAttr = dyn_cast(TmplAttr)) {

805 continue;

806 }

807

808 if (const auto *OMPAttr = dyn_cast(TmplAttr)) {

810 continue;

811 }

812

813 if (const auto *AMDGPUFlatWorkGroupSize =

814 dyn_cast(TmplAttr)) {

816 *this, TemplateArgs, *AMDGPUFlatWorkGroupSize, New);

817 }

818

819 if (const auto *AMDGPUFlatWorkGroupSize =

820 dyn_cast(TmplAttr)) {

822 *AMDGPUFlatWorkGroupSize, New);

823 }

824

825 if (const auto *AMDGPUMaxNumWorkGroups =

826 dyn_cast(TmplAttr)) {

828 *this, TemplateArgs, *AMDGPUMaxNumWorkGroups, New);

829 }

830

831 if (const auto *ParamAttr = dyn_cast(TmplAttr)) {

833 New);

834 continue;

835 }

836

837

838 if (TmplAttr->getKind() == attr::DLLExport ||

839 TmplAttr->getKind() == attr::DLLImport) {

840 if (New->hasAttr() || New->hasAttr()) {

841 continue;

842 }

843 }

844

845 if (const auto *ABIAttr = dyn_cast(TmplAttr)) {

847 continue;

848 }

849

850 if (isa(TmplAttr) || isa(TmplAttr) ||

851 isa(TmplAttr)) {

854 true);

855 continue;

856 }

857

858 if (auto *A = dyn_cast(TmplAttr)) {

859 if (!New->hasAttr())

861 continue;

862 }

863

864 if (auto *A = dyn_cast(TmplAttr)) {

865 if (!New->hasAttr())

867 continue;

868 }

869

870 if (auto *A = dyn_cast(TmplAttr)) {

872 continue;

873 }

874

875 if (auto *A = dyn_cast(TmplAttr)) {

876 if (!New->hasAttr())

878 continue;

879 }

880

881 assert(!TmplAttr->isPackExpansion());

882 if (TmplAttr->isLateParsed() && LateAttrs) {

883

884

889 } else {

890

891 auto *ND = cast(New);

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

894 ND->isCXXInstanceMember());

895

897 *this, TemplateArgs);

900 }

901 }

902}

903

905 for (const auto *Attr : Pattern->attrs()) {

906 if (auto *A = dyn_cast(Attr)) {

907 if (!Inst->hasAttr())

909 continue;

910 }

911 }

912}

913

918 if (NumParams == 0)

919 return;

920 DLLExportAttr *Attr = Ctor->getAttr();

922 return;

923 for (unsigned I = 0; I != NumParams; ++I) {

927 }

928}

929

930

931

932

933

934template

937

938

939

940

943 return nullptr;

944

946}

947

950 llvm_unreachable("Translation units cannot be instantiated");

951}

952

954 llvm_unreachable("HLSL buffer declarations cannot be instantiated");

955}

956

958TemplateDeclInstantiator::VisitPragmaCommentDecl(PragmaCommentDecl *D) {

959 llvm_unreachable("pragma comment cannot be instantiated");

960}

961

962Decl *TemplateDeclInstantiator::VisitPragmaDetectMismatchDecl(

964 llvm_unreachable("pragma comment cannot be instantiated");

965}

966

968TemplateDeclInstantiator::VisitExternCContextDecl(ExternCContextDecl *D) {

969 llvm_unreachable("extern \"C\" context cannot be instantiated");

970}

971

972Decl *TemplateDeclInstantiator::VisitMSGuidDecl(MSGuidDecl *D) {

973 llvm_unreachable("GUID declaration cannot be instantiated");

974}

975

976Decl *TemplateDeclInstantiator::VisitUnnamedGlobalConstantDecl(

978 llvm_unreachable("UnnamedGlobalConstantDecl cannot be instantiated");

979}

980

981Decl *TemplateDeclInstantiator::VisitTemplateParamObjectDecl(

983 llvm_unreachable("template parameter objects cannot be instantiated");

984}

985

987TemplateDeclInstantiator::VisitLabelDecl(LabelDecl *D) {

989 D->getIdentifier());

990 SemaRef.InstantiateAttrs(TemplateArgs, D, Inst, LateAttrs, StartingScope);

992 return Inst;

993}

994

996TemplateDeclInstantiator::VisitNamespaceDecl(NamespaceDecl *D) {

997 llvm_unreachable("Namespaces cannot be instantiated");

998}

999

1001TemplateDeclInstantiator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {

1004 D->getNamespaceLoc(),

1005 D->getAliasLoc(),

1006 D->getIdentifier(),

1007 D->getQualifierLoc(),

1008 D->getTargetNameLoc(),

1009 D->getNamespace());

1011 return Inst;

1012}

1013

1015 bool IsTypeAlias) {

1020 DI = SemaRef.SubstType(DI, TemplateArgs,

1022 if (!DI) {

1025 }

1026 } else {

1028 }

1029

1030

1031

1032

1033

1034

1037 if (DT && RD && isa(DT->getUnderlyingExpr()) &&

1039 RD->getEnclosingNamespaceContext() == SemaRef.getStdNamespace() &&

1041 D->getIdentifier() && D->getIdentifier()->isStr("type") &&

1043

1046

1047

1049 if (IsTypeAlias)

1052 else

1057

1058

1059

1060 if (const TagType *oldTagType = D->getUnderlyingType()->getAs<TagType>()) {

1061 TagDecl *oldTag = oldTagType->getDecl();

1066 }

1067 }

1068

1071 TemplateArgs);

1072 if (!InstPrev)

1073 return nullptr;

1074

1075 TypedefNameDecl *InstPrevTypedef = cast(InstPrev);

1076

1077

1079

1081 }

1082

1084

1087

1090

1091 return Typedef;

1092}

1093

1094Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {

1096 if (Typedef)

1097 Owner->addDecl(Typedef);

1098 return Typedef;

1099}

1100

1101Decl *TemplateDeclInstantiator::VisitTypeAliasDecl(TypeAliasDecl *D) {

1103 if (Typedef)

1104 Owner->addDecl(Typedef);

1105 return Typedef;

1106}

1107

1110

1111

1113

1116 if (!InstParams)

1117 return nullptr;

1118

1126 ->Args);

1128 return nullptr;

1129

1131 if (getPreviousDeclForInstantiation(Pattern)) {

1133 if (Found.empty()) {

1134 PrevAliasTemplate = dyn_cast(Found.front());

1135 }

1136 }

1137

1138 TypeAliasDecl *AliasInst = cast_or_null(

1140 if (!AliasInst)

1141 return nullptr;

1142

1145 D->getDeclName(), InstParams, AliasInst);

1147 if (PrevAliasTemplate)

1149

1151

1152 if (!PrevAliasTemplate)

1154

1155 return Inst;

1156}

1157

1161 if (Inst)

1163

1164 return Inst;

1165}

1166

1167Decl *TemplateDeclInstantiator::VisitBindingDecl(BindingDecl *D) {

1169 D->getIdentifier());

1172 return NewBD;

1173}

1174

1176

1178 for (auto *OldBD : D->bindings())

1179 NewBindings.push_back(cast(VisitBindingDecl(OldBD)));

1181

1182 auto *NewDD = cast_or_null(

1183 VisitVarDecl(D, false, &NewBindingArray));

1184

1185 if (!NewDD || NewDD->isInvalidDecl())

1186 for (auto *NewBD : NewBindings)

1187 NewBD->setInvalidDecl();

1188

1189 return NewDD;

1190}

1191

1193 return VisitVarDecl(D, false);

1194}

1195

1197 bool InstantiatingVarTemplate,

1199

1200

1202 D->getTypeSourceInfo(), TemplateArgs, D->getTypeSpecStartLoc(),

1203 D->getDeclName(), true);

1204 if (!DI)

1205 return nullptr;

1206

1208 SemaRef.Diag(D->getLocation(), diag::err_variable_instantiates_to_function)

1209 << D->isStaticDataMember() << DI->getType();

1210 return nullptr;

1211 }

1212

1216

1217

1222 D->getStorageClass(), *Bindings);

1223 else

1226 DI, D->getStorageClass());

1227

1228

1229 if (SemaRef.getLangOpts().ObjCAutoRefCount &&

1232

1235

1236

1238 return nullptr;

1239

1241 StartingScope, InstantiatingVarTemplate);

1244 if (auto *F = dyn_cast(DC))

1245 RT = F->getReturnType();

1246 else if (isa(DC))

1248 ->getReturnType();

1249 else

1250 llvm_unreachable("Unknown context type");

1251

1252

1253

1254

1255

1256

1257

1258

1259

1260

1261

1262

1266 }

1267

1269

1272

1275

1276 return Var;

1277}

1278

1282 D->getAccessSpecifierLoc(), D->getColonLoc());

1284 return AD;

1285}

1286

1287Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {

1292 DI = SemaRef.SubstType(DI, TemplateArgs,

1294 if (!DI) {

1295 DI = D->getTypeSourceInfo();

1298

1299

1300

1301

1302

1303

1304 SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)

1307 }

1308 } else {

1310 }

1311

1312 Expr *BitWidth = D->getBitWidth();

1314 BitWidth = nullptr;

1315 else if (BitWidth) {

1316

1319

1321 = SemaRef.SubstExpr(BitWidth, TemplateArgs);

1322 if (InstantiatedBitWidth.isInvalid()) {

1324 BitWidth = nullptr;

1325 } else

1326 BitWidth = InstantiatedBitWidth.getAs<Expr>();

1327 }

1328

1331 cast(Owner),

1333 D->isMutable(),

1334 BitWidth,

1335 D->getInClassInitStyle(),

1336 D->getInnerLocStart(),

1338 nullptr);

1339 if (!Field) {

1341 return nullptr;

1342 }

1343

1344 SemaRef.InstantiateAttrs(TemplateArgs, D, Field, LateAttrs, StartingScope);

1345

1346 if (Field->hasAttrs())

1348

1350 Field->setInvalidDecl();

1351

1353

1355 }

1357 if (Parent->isAnonymousStructOrUnion() &&

1358 Parent->getRedeclContext()->isFunctionOrMethod())

1360 }

1361

1365

1367}

1368

1372

1374 SemaRef.Diag(D->getLocation(), diag::err_property_is_variably_modified)

1375 << D;

1378 DI = SemaRef.SubstType(DI, TemplateArgs,

1380 if (!DI) {

1381 DI = D->getTypeSourceInfo();

1384

1385

1386

1387

1388

1389

1390 SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)

1393 }

1394 } else {

1396 }

1397

1400 DI, D->getBeginLoc(), D->getGetterId(), D->getSetterId());

1401

1403 StartingScope);

1404

1407

1410

1412}

1413

1417

1418 int i = 0;

1419 for (auto *PI : D->chain()) {

1421 TemplateArgs);

1422 if (!Next)

1423 return nullptr;

1424

1425 NamedChain[i++] = Next;

1426 }

1427

1428 QualType T = cast(NamedChain[i-1])->getType();

1431 {NamedChain, D->getChainingSize()});

1432

1435

1438 Owner->addDecl(IndirectField);

1439 return IndirectField;

1440}

1441

1442Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) {

1443

1444

1447

1448

1449

1450

1451 if (D->isUnsupportedFriend()) {

1452 InstTy = Ty;

1453 } else {

1454 if (D->isPackExpansion()) {

1457 assert(!Unexpanded.empty() && "Pack expansion without packs");

1458

1459 bool ShouldExpand = true;

1460 bool RetainExpansion = false;

1461 std::optional NumExpansions;

1464 TemplateArgs, ShouldExpand, RetainExpansion, NumExpansions))

1465 return nullptr;

1466

1467 assert(!RetainExpansion &&

1468 "should never retain an expansion for a variadic friend decl");

1469

1470 if (ShouldExpand) {

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

1476 if (!TSI)

1477 return nullptr;

1478

1479 auto FD =

1481 TSI, D->getFriendLoc());

1482

1485 Decls.push_back(FD);

1486 }

1487

1488

1489 return nullptr;

1490 }

1491 }

1492

1495 }

1496 if (!InstTy)

1497 return nullptr;

1498

1504 return FD;

1505 }

1506

1508 assert(ND && "friend decl must be a decl or a type!");

1509

1510

1511

1512

1513

1515 if (!NewND) return nullptr;

1516

1519 cast(NewND), D->getFriendLoc());

1523 return FD;

1524}

1525

1527 Expr *AssertExpr = D->getAssertExpr();

1528

1529

1532

1534 = SemaRef.SubstExpr(AssertExpr, TemplateArgs);

1535 if (InstantiatedAssertExpr.isInvalid())

1536 return nullptr;

1537

1538 ExprResult InstantiatedMessageExpr =

1539 SemaRef.SubstExpr(D->getMessage(), TemplateArgs);

1540 if (InstantiatedMessageExpr.isInvalid())

1541 return nullptr;

1542

1545 InstantiatedMessageExpr.get(), D->getRParenLoc(), D->isFailed());

1546}

1547

1548Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {

1549 EnumDecl *PrevDecl = nullptr;

1552 PatternPrev,

1553 TemplateArgs);

1554 if (!Prev) return nullptr;

1555 PrevDecl = cast(Prev);

1556 }

1557

1561 D->isScoped(), D->isScopedUsingClassTag(), D->isFixed());

1562 if (D->isFixed()) {

1563 if (TypeSourceInfo *TI = D->getIntegerTypeSourceInfo()) {

1564

1565

1566

1567 SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc();

1572 else

1573 Enum->setIntegerTypeSourceInfo(NewTI);

1574

1575

1576

1577

1578

1579

1580

1581

1582 QualType UnderlyingType = Enum->getIntegerType();

1583 Enum->setPromotionType(

1586 : UnderlyingType);

1587 } else {

1588 assert(D->getIntegerType()->isDependentType()

1589 && "Dependent type without type source info");

1590 Enum->setIntegerType(D->getIntegerType());

1591 }

1592 }

1593

1595

1598

1600

1601

1604

1605

1610

1611 EnumDecl *Def = D->getDefinition();

1612 if (Def && Def != D) {

1613

1614

1615

1617 SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc();

1619 SemaRef.SubstType(TI->getType(), TemplateArgs,

1622 DefnUnderlying, true, Enum);

1623 }

1624 }

1625

1626

1627

1628

1629

1630

1631

1632

1636 }

1637

1638 return Enum;

1639}

1640

1643 Enum->startDefinition();

1644

1645

1647

1649

1651 for (auto *EC : Pattern->enumerators()) {

1652

1654 if (Expr *UninstValue = EC->getInitExpr()) {

1655

1658

1659 Value = SemaRef.SubstExpr(UninstValue, TemplateArgs);

1660 }

1661

1662

1664 if (Value.isInvalid()) {

1665 Value = nullptr;

1667 }

1668

1673

1675 if (EnumConst)

1677 Enum->setInvalidDecl();

1678 }

1679

1680 if (EnumConst) {

1682

1684 Enum->addDecl(EnumConst);

1685 Enumerators.push_back(EnumConst);

1686 LastEnumConst = EnumConst;

1687

1689 Enum->isScoped()) {

1690

1691

1693 }

1694 }

1695 }

1696

1699}

1700

1702 llvm_unreachable("EnumConstantDecls can only occur within EnumDecls.");

1703}

1704

1707 llvm_unreachable("BuiltinTemplateDecls cannot be instantiated.");

1708}

1709

1712

1713

1714

1718 if (!InstParams)

1719 return nullptr;

1720

1722

1723

1724

1725

1727 if (QualifierLoc) {

1729 TemplateArgs);

1730 if (!QualifierLoc)

1731 return nullptr;

1732 }

1733

1736

1739 if (Found.empty()) {

1740 PrevClassTemplate = dyn_cast(Found.front());

1741 if (PrevClassTemplate)

1743 }

1744 }

1745

1746

1747

1748

1749

1751 if (isFriend) {

1752 if (QualifierLoc) {

1754 SS.Adopt(QualifierLoc);

1756 if (!DC) return nullptr;

1757 } else {

1760 TemplateArgs);

1761 }

1762

1763

1764

1769

1770 if (R.isSingleResult()) {

1772 if (PrevClassTemplate)

1774 }

1775

1776 if (!PrevClassTemplate && QualifierLoc) {

1777 SemaRef.Diag(Pattern->getLocation(), diag::err_not_tag_in_scope)

1778 << llvm::to_underlying(D->getTemplatedDecl()->getTagKind())

1780 return nullptr;

1781 }

1782 }

1783

1787 true);

1788 if (QualifierLoc)

1790

1792 StartingScope);

1793

1796 D->getIdentifier(), InstParams, RecordInst);

1798

1799 if (isFriend) {

1804

1805 if (PrevClassTemplate) {

1813

1814

1816 RecordInst, InstParams, MostRecentPrevCT->getTemplatedDecl(),

1818 return nullptr;

1819

1820

1821

1824 return nullptr;

1825

1827 } else {

1829 }

1830

1832

1833

1834 } else {

1836 if (!PrevClassTemplate)

1838 }

1839

1841

1842

1845

1846

1847 if (isFriend) {

1849 return Inst;

1850 }

1851

1855 }

1856

1858

1859 if (!PrevClassTemplate) {

1860

1861

1862

1864 D->getPartialSpecializations(PartialSpecs);

1865 for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)

1866 if (PartialSpecs[I]->getFirstDecl()->isOutOfLine())

1867 OutOfLinePartialSpecs.push_back(std::make_pair(Inst, PartialSpecs[I]));

1868 }

1869

1870 return Inst;

1871}

1872

1874TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl(

1877

1878

1879

1882 if (Found.empty())

1883 return nullptr;

1884

1886 = dyn_cast(Found.front());

1887 if (!InstClassTemplate)

1888 return nullptr;

1889

1893

1895}

1896

1898 assert(D->getTemplatedDecl()->isStaticDataMember() &&

1899 "Only static data member templates are allowed.");

1900

1901

1902

1906 if (!InstParams)

1907 return nullptr;

1908

1909 VarDecl *Pattern = D->getTemplatedDecl();

1911

1914 if (Found.empty())

1915 PrevVarTemplate = dyn_cast(Found.front());

1916 }

1917

1920 true));

1921 if (!VarInst) return nullptr;

1922

1924

1927 VarInst);

1930

1932 if (!PrevVarTemplate)

1934

1938 }

1939

1941

1942 if (!PrevVarTemplate) {

1943

1944

1945

1947 D->getPartialSpecializations(PartialSpecs);

1948 for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)

1949 if (PartialSpecs[I]->getFirstDecl()->isOutOfLine())

1950 OutOfLineVarPartialSpecs.push_back(

1951 std::make_pair(Inst, PartialSpecs[I]));

1952 }

1953

1954 return Inst;

1955}

1956

1957Decl *TemplateDeclInstantiator::VisitVarTemplatePartialSpecializationDecl(

1959 assert(D->isStaticDataMember() &&

1960 "Only static data member templates are allowed.");

1961

1963

1964

1966 assert(Found.empty() && "Instantiation found nothing?");

1967

1968 VarTemplateDecl *InstVarTemplate = dyn_cast(Found.front());

1969 assert(InstVarTemplate && "Instantiation did not find a variable template?");

1970

1974

1976}

1977

1980

1981

1982

1983

1986

1989 if (!InstParams)

1990 return nullptr;

1991

1993 if (CXXMethodDecl *DMethod = dyn_cast(D->getTemplatedDecl()))

1994 Instantiated = cast_or_null(VisitCXXMethodDecl(DMethod,

1995 InstParams));

1996 else

1998 D->getTemplatedDecl(),

1999 InstParams));

2000

2001 if (!Instantiated)

2002 return nullptr;

2003

2004

2005

2009 assert(InstTemplate &&

2010 "VisitFunctionDecl/CXXMethodDecl didn't create a template!");

2011

2013

2014

2015

2017 !(isFriend && D->getTemplatedDecl()->isThisDeclarationADefinition()))

2019

2020

2021 if (!isFriend) {

2022 Owner->addDecl(InstTemplate);

2026 }

2027

2028 return InstTemplate;

2029}

2030

2031Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {

2035 PatternPrev,

2036 TemplateArgs);

2037 if (!Prev) return nullptr;

2038 PrevDecl = cast(Prev);

2039 }

2040

2042 bool IsInjectedClassName = D->isInjectedClassName();

2043 if (D->isLambda())

2046 D->getLambdaDependencyKind(), D->isGenericLambda(),

2047 D->getLambdaCaptureDefault());

2048 else

2051 D->getIdentifier(), PrevDecl,

2052 IsInjectedClassName);

2053

2054 if (IsInjectedClassName)

2056

2057

2059 return nullptr;

2060

2062 StartingScope);

2063

2065

2066

2067

2070 if (!IsInjectedClassName)

2072

2073

2074

2076 Record->setObjectOfFriendDecl();

2077

2078

2079 if (D->isAnonymousStructOrUnion())

2080 Record->setAnonymousStructOrUnion(true);

2081

2082 if (D->isLocalClass())

2084

2085

2088

2089

2090

2093

2094

2095

2098

2100

2101

2102

2103 if (D->isCompleteDefinition() && D->isLocalClass()) {

2105

2108 true);

2109

2110

2111

2112 if (D->isCXXClassMember())

2115

2116

2117

2118 LocalInstantiations.perform();

2119 }

2120

2122

2123 if (IsInjectedClassName)

2124 assert(Record->isInjectedClassName() && "Broken injected-class-name");

2125

2127}

2128

2129

2130

2131

2132

2133

2134

2142 if (OrigFunc->getExtInfo() == NewFunc->getExtInfo())

2143 return TInfo->getType();

2144

2147 return Context.getFunctionType(NewFunc->getReturnType(),

2148 NewFunc->getParamTypes(), NewEPI);

2149}

2150

2151

2152

2153

2154

2155

2159

2160

2162 bool isFriend;

2163 if (FunctionTemplate)

2165 else

2167

2168

2169

2170

2171 if (isFriend) {

2176 }

2177 }

2178

2179 if (FunctionTemplate && !TemplateParams) {

2181

2182 void *InsertPos = nullptr;

2185

2186

2187 if (SpecFunc)

2188 return SpecFunc;

2189 }

2190

2191 bool MergeWithParentScope = (TemplateParams != nullptr) ||

2193 !(isa(Owner) &&

2194 cast(Owner)->isDefinedOutsideFunctionOrMethod());

2196

2198 if (auto *DGuide = dyn_cast(D)) {

2200 TemplateArgs, DGuide->getExplicitSpecifier());

2201 if (InstantiatedExplicitSpecifier.isInvalid())

2202 return nullptr;

2203 }

2204

2207 if (!TInfo)

2208 return nullptr;

2210

2211 if (TemplateParams && TemplateParams->size()) {

2212 auto *LastParam =

2213 dyn_cast(TemplateParams->asArray().back());

2214 if (LastParam && LastParam->isImplicit() &&

2215 LastParam->hasTypeConstraint()) {

2216

2217

2218

2219

2220

2225 }

2226 }

2227

2229 if (QualifierLoc) {

2231 TemplateArgs);

2232 if (!QualifierLoc)

2233 return nullptr;

2234 }

2235

2236 Expr *TrailingRequiresClause = D->getTrailingRequiresClause();

2237

2238

2239

2240

2243 DC = Owner;

2245 } else if (isFriend && QualifierLoc) {

2247 SS.Adopt(QualifierLoc);

2249 if (!DC) return nullptr;

2250 } else {

2252 TemplateArgs);

2253 }

2254

2257

2260

2262 if (auto *DGuide = dyn_cast(D)) {

2264 SemaRef.Context, DC, D->getInnerLocStart(),

2265 InstantiatedExplicitSpecifier, NameInfo, T, TInfo,

2267 DGuide->getDeductionCandidateKind(), TrailingRequiresClause);

2269 } else {

2271 SemaRef.Context, DC, D->getInnerLocStart(), NameInfo, T, TInfo,

2273 D->isInlineSpecified(), D->hasWrittenPrototype(), D->getConstexprKind(),

2274 TrailingRequiresClause);

2275 Function->setFriendConstraintRefersToEnclosingTemplate(

2276 D->FriendConstraintRefersToEnclosingTemplate());

2278 }

2279

2280 if (D->isInlined())

2281 Function->setImplicitlyInline();

2282

2283 if (QualifierLoc)

2284 Function->setQualifierInfo(QualifierLoc);

2285

2287 Function->setLocalExternDecl();

2288

2293 }

2296 }

2297

2298 Function->setLexicalDeclContext(LexicalDC);

2299

2300

2301 for (unsigned P = 0; P < Params.size(); ++P)

2302 if (Params[P])

2303 Params[P]->setOwningFunction(Function);

2304 Function->setParams(Params);

2305

2306 if (TrailingRequiresClause)

2307 Function->setTrailingRequiresClause(TrailingRequiresClause);

2308

2309 if (TemplateParams) {

2310

2311

2312

2313

2314

2315

2316

2317

2318

2319

2320

2321

2322

2323

2328 Function->setDescribedFunctionTemplate(FunctionTemplate);

2329

2331

2332 if (isFriend && D->isThisDeclarationADefinition()) {

2334 D->getDescribedFunctionTemplate());

2335 }

2336 } else if (FunctionTemplate &&

2339

2341 Function->setFunctionTemplateSpecialization(FunctionTemplate,

2343 Innermost),

2344 nullptr);

2346 if (isFriend && D->isThisDeclarationADefinition()) {

2347

2348

2349

2351 } else if (!isFriend) {

2352

2353

2354

2355 Function->setInstantiatedFromDecl(D);

2356 }

2357 }

2358

2359 if (isFriend) {

2360 Function->setObjectOfFriendDecl();

2362 FT->setObjectOfFriendDecl();

2363 }

2364

2367

2368 bool IsExplicitSpecialization = false;

2369

2374 D->isLocalExternDecl() ? RedeclarationKind::ForExternalRedeclaration

2376

2378 D->getDependentSpecializationInfo()) {

2379 assert(isFriend && "dependent specialization info on "

2380 "non-member non-friend function?");

2381

2382

2384 if (const auto *ArgsWritten = DFTSI->TemplateArgumentsAsWritten) {

2385 ExplicitArgs.setLAngleLoc(ArgsWritten->getLAngleLoc());

2386 ExplicitArgs.setRAngleLoc(ArgsWritten->getRAngleLoc());

2388 ExplicitArgs))

2389 return nullptr;

2390 }

2391

2392

2397 else

2398 return nullptr;

2399 }

2400

2403 DFTSI->TemplateArgumentsAsWritten ? &ExplicitArgs : nullptr,

2406

2407 IsExplicitSpecialization = true;

2409 D->getTemplateSpecializationArgsAsWritten()) {

2410

2412

2413

2415 ArgsWritten->getRAngleLoc());

2417 ExplicitArgs))

2418 return nullptr;

2419

2421 &ExplicitArgs,

2424

2425 IsExplicitSpecialization = true;

2426 } else if (TemplateParams || !FunctionTemplate) {

2427

2428

2429

2431

2432

2433

2434

2435

2436 if (Previous.isSingleTagDecl())

2438

2439

2440

2441

2442 if (isFriend && !QualifierLoc) {

2444 true,

2446 }

2447 }

2448

2449

2450

2451

2452

2453

2454

2455

2456

2457

2458

2459

2460

2461

2462 if (Function->isLocalExternDecl()) {

2464 if (!PVD->hasDefaultArg())

2465 continue;

2467

2468

2469

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

2473 { UninstExpr }, UninstExpr->getType());

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

2476 }

2477 }

2478 }

2479

2481 IsExplicitSpecialization,

2482 Function->isThisDeclarationADefinition());

2483

2484

2485

2486

2487

2488 if (isFriend && TemplateParams && FunctionTemplate->getPreviousDecl()) {

2490 TemplateParams,

2492 Function->isThisDeclarationADefinition()

2495 }

2496

2497

2498

2499

2500

2501 if (isFriend && D->isThisDeclarationADefinition() && Function->isUsed(false)) {

2503 Function->getMemberSpecializationInfo()) {

2504 if (MSInfo->getPointOfInstantiation().isInvalid()) {

2506 MSInfo->setPointOfInstantiation(Loc);

2509 }

2510 }

2511 }

2512

2513 if (D->isExplicitlyDefaulted()) {

2515 return nullptr;

2516 }

2517 if (D->isDeleted())

2519

2521 (TemplateParams ? cast(FunctionTemplate) : Function);

2522

2523

2524

2525 if (isFriend ||

2526 (Function->isLocalExternDecl() && Function->getPreviousDecl()))

2528

2532

2534}

2535

2540 if (FunctionTemplate && !TemplateParams) {

2541

2542

2543

2545

2546 void *InsertPos = nullptr;

2549

2550

2551 if (SpecFunc)

2552 return SpecFunc;

2553 }

2554

2555 bool isFriend;

2556 if (FunctionTemplate)

2558 else

2560

2561 bool MergeWithParentScope = (TemplateParams != nullptr) ||

2562 !(isa(Owner) &&

2563 cast(Owner)->isDefinedOutsideFunctionOrMethod());

2565

2568

2569

2571 unsigned NumTempParamLists = 0;

2572 if (isFriend && (NumTempParamLists = D->getNumTemplateParameterLists())) {

2573 TempParamLists.resize(NumTempParamLists);

2574 for (unsigned I = 0; I != NumTempParamLists; ++I) {

2577 if (!InstParams)

2578 return nullptr;

2579 TempParamLists[I] = InstParams;

2580 }

2581 }

2582

2584

2585 const bool CouldInstantiate =

2586 InstantiatedExplicitSpecifier.getExpr() == nullptr ||

2587 !InstantiatedExplicitSpecifier.getExpr()->isValueDependent();

2588

2589

2590

2591 if (CouldInstantiate ||

2595 TemplateArgs, InstantiatedExplicitSpecifier);

2596

2597 if (InstantiatedExplicitSpecifier.isInvalid())

2598 return nullptr;

2599 } else {

2601 }

2602

2603

2604

2605

2606

2607

2608

2609 if (cast(D->getParent())->isLambda() &&

2610 D->getTypeSourceInfo() &&

2611 isa<CXXConstructorDecl, CXXDestructorDecl>(D)) {

2614 D->setTypeSourceInfo(TSI);

2615 }

2616

2619 if (!TInfo)

2620 return nullptr;

2622

2623 if (TemplateParams && TemplateParams->size()) {

2624 auto *LastParam =

2625 dyn_cast(TemplateParams->asArray().back());

2626 if (LastParam && LastParam->isImplicit() &&

2627 LastParam->hasTypeConstraint()) {

2628

2629

2630

2631

2632

2637 }

2638 }

2639

2641 if (QualifierLoc) {

2643 TemplateArgs);

2644 if (!QualifierLoc)

2645 return nullptr;

2646 }

2647

2649 if (isFriend) {

2650 if (QualifierLoc) {

2652 SS.Adopt(QualifierLoc);

2654

2656 return nullptr;

2657 } else {

2660 TemplateArgs);

2661 }

2662 if (!DC) return nullptr;

2663 }

2664

2666 Expr *TrailingRequiresClause = D->getTrailingRequiresClause();

2667

2670

2673

2674

2676

2678 if (CXXConstructorDecl *Constructor = dyn_cast(D)) {

2680 SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,

2681 InstantiatedExplicitSpecifier, Constructor->UsesFPIntrin(),

2682 Constructor->isInlineSpecified(), false,

2684 TrailingRequiresClause);

2685 Method->setRangeEnd(Constructor->getEndLoc());

2688 SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,

2690 Destructor->getConstexprKind(), TrailingRequiresClause);

2696 } else if (CXXConversionDecl *Conversion = dyn_cast(D)) {

2698 SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,

2699 Conversion->UsesFPIntrin(), Conversion->isInlineSpecified(),

2700 InstantiatedExplicitSpecifier, Conversion->getConstexprKind(),

2701 Conversion->getEndLoc(), TrailingRequiresClause);

2702 } else {

2705 SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, SC,

2706 D->UsesFPIntrin(), D->isInlineSpecified(), D->getConstexprKind(),

2707 D->getEndLoc(), TrailingRequiresClause);

2708 }

2709

2710 if (D->isInlined())

2712

2713 if (QualifierLoc)

2715

2716 if (TemplateParams) {

2717

2718

2719

2720

2721

2722

2723

2724

2725

2726

2727

2728

2729

2733 TemplateParams, Method);

2734 if (isFriend) {

2740 } else if (FunctionTemplate) {

2741

2745 Innermost),

2746 nullptr);

2747 } else if (!isFriend && FunctionRewriteKind == RewriteKind::None) {

2748

2750 }

2751

2752

2753

2754

2755 if (isFriend) {

2756 if (NumTempParamLists)

2759 llvm::ArrayRef(TempParamLists.data(), NumTempParamLists));

2760

2765

2766

2767 for (unsigned P = 0; P < Params.size(); ++P)

2768 Params[P]->setOwningFunction(Method);

2770

2773

2775 RedeclarationKind::ForExternalRedeclaration);

2776

2777 bool IsExplicitSpecialization = false;

2778

2779

2780

2782 D->getDependentSpecializationInfo()) {

2783

2785 if (const auto *ArgsWritten = DFTSI->TemplateArgumentsAsWritten) {

2786 ExplicitArgs.setLAngleLoc(ArgsWritten->getLAngleLoc());

2787 ExplicitArgs.setRAngleLoc(ArgsWritten->getRAngleLoc());

2789 ExplicitArgs))

2790 return nullptr;

2791 }

2792

2793

2798 else

2799 return nullptr;

2800 }

2801

2803 Method, DFTSI->TemplateArgumentsAsWritten ? &ExplicitArgs : nullptr,

2806

2807 IsExplicitSpecialization = true;

2809 D->getTemplateSpecializationArgsAsWritten()) {

2811

2813 ArgsWritten->getRAngleLoc());

2814

2816 ExplicitArgs))

2817 return nullptr;

2818

2820 &ExplicitArgs,

2823

2824 IsExplicitSpecialization = true;

2825 } else if (!FunctionTemplate || TemplateParams || isFriend) {

2827

2828

2829

2830

2831

2832 if (Previous.isSingleTagDecl())

2834 }

2835

2836

2837

2838

2839

2840

2841

2842

2843

2844

2845

2846

2847

2848

2849

2850

2852 for (unsigned P = 0; P < Params.size(); ++P) {

2853 if (!Params[P]->hasDefaultArg())

2854 continue;

2856

2857

2858

2859 Expr *UninstExpr = Params[P]->getUninstantiatedDefaultArg();

2862 { UninstExpr }, UninstExpr->getType());

2864 Params[P]->setDefaultArg(ErrorResult.get());

2865 }

2866 }

2867 }

2868

2870 IsExplicitSpecialization,

2872

2873 if (D->isPureVirtual())

2875

2876

2877

2878

2881 else

2883 if (FunctionTemplate)

2885

2887

2888

2889 if (D->isExplicitlyDefaulted()) {

2891 return nullptr;

2892 }

2893 if (D->isDeletedAsWritten())

2895 D->getDeletedMessage());

2896

2897

2898

2899

2900 if (IsExplicitSpecialization && !isFriend)

2902

2903

2904

2905

2906

2907

2908

2909

2910 if (auto *Constructor = dyn_cast(Method)) {

2911 if (Constructor->isDefaultConstructor() ||

2912 Constructor->isCopyOrMoveConstructor())

2917 }

2918

2919

2920 if (FunctionTemplate) {

2921

2922

2923

2925

2926

2927

2928 } else if (isFriend) {

2929

2930

2933

2934 Record->makeDeclVisibleInContext(Method);

2935

2936

2937

2938

2939 } else {

2941 }

2942

2943

2944

2945 if (Method->hasAttr()) {

2946 if (const auto *A = dyn_cast(Owner)) {

2949 A->getMemberSpecializationInfo())

2950 Loc = MSInfo->getPointOfInstantiation();

2951 else if (const auto *Spec = dyn_cast(A))

2952 Loc = Spec->getPointOfInstantiation();

2954 }

2955 }

2956

2957 return Method;

2958}

2959

2962}

2963

2966}

2967

2970}

2971

2972Decl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {

2973 return SemaRef.SubstParmVarDecl(D, TemplateArgs, 0,

2974 std::nullopt,

2975 false);

2976}

2977

2978Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(

2980 assert(D->getTypeForDecl()->isTemplateTypeParmType());

2981

2982 std::optional NumExpanded;

2983

2984 if (const TypeConstraint *TC = D->getTypeConstraint()) {

2985 if (D->isPackExpansion() && D->isExpandedParameterPack()) {

2986 assert(TC->getTemplateArgsAsWritten() &&

2987 "type parameter can only be an expansion when explicit arguments "

2988 "are specified");

2989

2990

2991

2993 for (auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())

2995

2996

2997

2998 bool Expand = true;

2999 bool RetainExpansion = false;

3001 cast(TC->getImmediatelyDeclaredConstraint())

3002 ->getEllipsisLoc(),

3004 TC->hasExplicitTemplateArgs() ?

3005 TC->getTemplateArgsAsWritten()->getRAngleLoc() :

3006 TC->getConceptNameInfo().getEndLoc()),

3007 Unexpanded, TemplateArgs, Expand, RetainExpansion, NumExpanded))

3008 return nullptr;

3009 }

3010 }

3011

3015 D->getIdentifier(), D->wasDeclaredWithTypename(), D->isParameterPack(),

3016 D->hasTypeConstraint(), NumExpanded);

3017

3020 if (auto *TC = D->getTypeConstraint()) {

3022

3023

3024

3026 EvaluateConstraints))

3027 return nullptr;

3028 }

3029 }

3030 if (D->hasDefaultArgument() && D->defaultArgumentWasInherited()) {

3033 Output))

3035 }

3036

3037

3038

3040

3041 return Inst;

3042}

3043

3044Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(

3046

3047 TypeLoc TL = D->getTypeSourceInfo()->getTypeLoc();

3050 bool IsExpandedParameterPack = false;

3054

3055 if (D->isExpandedParameterPack()) {

3056

3057

3058 ExpandedParameterPackTypes.reserve(D->getNumExpansionTypes());

3059 ExpandedParameterPackTypesAsWritten.reserve(D->getNumExpansionTypes());

3060 for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {

3062 SemaRef.SubstType(D->getExpansionTypeSourceInfo(I), TemplateArgs,

3064 if (!NewDI)

3065 return nullptr;

3066

3070 return nullptr;

3071

3072 ExpandedParameterPackTypesAsWritten.push_back(NewDI);

3073 ExpandedParameterPackTypes.push_back(NewT);

3074 }

3075

3076 IsExpandedParameterPack = true;

3077 DI = D->getTypeSourceInfo();

3079 } else if (D->isPackExpansion()) {

3080

3081

3082

3087

3088

3089

3090 bool Expand = true;

3091 bool RetainExpansion = false;

3092 std::optional OrigNumExpansions =

3094 std::optional NumExpansions = OrigNumExpansions;

3096 Pattern.getSourceRange(),

3097 Unexpanded,

3098 TemplateArgs,

3099 Expand, RetainExpansion,

3100 NumExpansions))

3101 return nullptr;

3102

3103 if (Expand) {

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

3108 D->getDeclName());

3109 if (!NewDI)

3110 return nullptr;

3111

3115 return nullptr;

3116

3117 ExpandedParameterPackTypesAsWritten.push_back(NewDI);

3118 ExpandedParameterPackTypes.push_back(NewT);

3119 }

3120

3121

3122

3123

3124 IsExpandedParameterPack = true;

3125 DI = D->getTypeSourceInfo();

3127 } else {

3128

3129

3133 D->getDeclName());

3134 if (!NewPattern)

3135 return nullptr;

3136

3139 NumExpansions);

3140 if (!DI)

3141 return nullptr;

3142

3144 }

3145 } else {

3146

3147 DI = SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs,

3149 if (!DI)

3150 return nullptr;

3151

3152

3154 if (T.isNull()) {

3157 }

3158 }

3159

3161 if (IsExpandedParameterPack)

3165 D->getPosition(), D->getIdentifier(), T, DI, ExpandedParameterPackTypes,

3166 ExpandedParameterPackTypesAsWritten);

3167 else

3172

3174 if (AutoLoc.isConstrained()) {

3176 if (IsExpandedParameterPack)

3177 EllipsisLoc =

3179 else if (auto *Constraint = dyn_cast_if_present(

3180 D->getPlaceholderTypeConstraint()))

3181 EllipsisLoc = Constraint->getEllipsisLoc();

3182

3183

3184

3186 D, EllipsisLoc))

3188 }

3189

3194

3195 if (D->hasDefaultArgument() && D->defaultArgumentWasInherited()) {

3202 }

3203

3204

3205

3207 return Param;

3208}

3209

3214 for (const auto &P : *Params) {

3215 if (P->isTemplateParameterPack())

3216 continue;

3219 Unexpanded);

3222 Unexpanded);

3223 }

3224}

3225

3227TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(

3229

3233

3234 bool IsExpandedParameterPack = false;

3235

3236 if (D->isExpandedParameterPack()) {

3237

3238

3239

3240 ExpandedParams.reserve(D->getNumExpansionTemplateParameters());

3241 for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();

3242 I != N; ++I) {

3246 if (!Expansion)

3247 return nullptr;

3248 ExpandedParams.push_back(Expansion);

3249 }

3250

3251 IsExpandedParameterPack = true;

3252 InstParams = TempParams;

3253 } else if (D->isPackExpansion()) {

3254

3255

3256

3259 Unexpanded);

3260

3261

3262

3263 bool Expand = true;

3264 bool RetainExpansion = false;

3265 std::optional NumExpansions;

3268 Unexpanded,

3269 TemplateArgs,

3270 Expand, RetainExpansion,

3271 NumExpansions))

3272 return nullptr;

3273

3274 if (Expand) {

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

3279 if (!Expansion)

3280 return nullptr;

3281 ExpandedParams.push_back(Expansion);

3282 }

3283

3284

3285

3286

3287 IsExpandedParameterPack = true;

3288 InstParams = TempParams;

3289 } else {

3290

3291

3293

3296 if (!InstParams)

3297 return nullptr;

3298 }

3299 } else {

3300

3301

3304 if (!InstParams)

3305 return nullptr;

3306 }

3307

3308

3310 if (IsExpandedParameterPack)

3314 D->getPosition(), D->getIdentifier(), D->wasDeclaredWithTypename(),

3315 InstParams, ExpandedParams);

3316 else

3321 D->wasDeclaredWithTypename(), InstParams);

3322 if (D->hasDefaultArgument() && D->defaultArgumentWasInherited()) {

3324 D->getDefaultArgument().getTemplateQualifierLoc();

3325 QualifierLoc =

3328 QualifierLoc, D->getDefaultArgument().getArgument().getAsTemplate(),

3329 D->getDefaultArgument().getTemplateNameLoc(), TemplateArgs);

3330 if (!TName.isNull())

3334 D->getDefaultArgument().getTemplateQualifierLoc(),

3335 D->getDefaultArgument().getTemplateNameLoc()));

3336 }

3339

3340

3341

3343

3344 return Param;

3345}

3346

3348

3349

3350

3353 D->getNamespaceKeyLocation(),

3354 D->getQualifierLoc(),

3355 D->getIdentLocation(),

3356 D->getNominatedNamespace(),

3357 D->getCommonAncestor());

3358

3359

3360

3363

3364 return Inst;

3365}

3366

3370

3372

3373 for (auto *Shadow : D->shadows()) {

3374

3375

3376

3377 NamedDecl *OldTarget = Shadow->getTargetDecl();

3378 if (auto *CUSD = dyn_cast(Shadow))

3379 if (auto *BaseShadow = CUSD->getNominatedBaseClassShadowDecl())

3380 OldTarget = BaseShadow;

3381

3382 NamedDecl *InstTarget = nullptr;

3383 if (auto *EmptyD =

3384 dyn_cast(Shadow->getTargetDecl())) {

3386 SemaRef.Context, Owner, EmptyD->getLocation(), EmptyD->getDeclName());

3387 } else {

3389 Shadow->getLocation(), OldTarget, TemplateArgs));

3390 }

3391 if (!InstTarget)

3392 return nullptr;

3393

3395 if (Lookup &&

3397 continue;

3398

3401 Shadow->getLocation(), OldPrev, TemplateArgs));

3402

3404 nullptr, Inst, InstTarget, PrevDecl);

3406

3407 if (isFunctionScope)

3409 }

3410

3411 return Inst;

3412}

3413

3414Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {

3415

3416

3417

3418

3419

3420

3421

3422

3423

3426 TemplateArgs);

3427 if (!QualifierLoc)

3428 return nullptr;

3429

3430

3431

3432

3435 if (auto *RD = dyn_cast(SemaRef.CurContext))

3438

3439

3440

3441 bool CheckRedeclaration = Owner->isRecord();

3443 RedeclarationKind::ForVisibleRedeclaration);

3444

3446 D->getUsingLoc(),

3447 QualifierLoc,

3448 NameInfo,

3449 D->hasTypename());

3450

3452 SS.Adopt(QualifierLoc);

3453 if (CheckRedeclaration) {

3454 Prev.setHideTags(false);

3456

3457

3459 D->hasTypename(), SS,

3462 }

3463

3468

3472

3473

3475 return NewUD;

3476

3477

3478

3481

3483}

3484

3485Decl *TemplateDeclInstantiator::VisitUsingEnumDecl(UsingEnumDecl *D) {

3486

3488 D->getLocation(), D->getEnumDecl(), TemplateArgs));

3489

3491 return nullptr;

3492

3495

3496 if (!TSI)

3497 return nullptr;

3498

3502

3506

3507

3509 return NewUD;

3510

3511

3512

3513

3514

3516}

3517

3519

3520 return nullptr;

3521}

3522

3523Decl *TemplateDeclInstantiator::VisitConstructorUsingShadowDecl(

3525

3526 return nullptr;

3527}

3528

3529template

3530Decl *TemplateDeclInstantiator::instantiateUnresolvedUsingDecl(

3531 T *D, bool InstantiatingPackElement) {

3532

3533 if (D->isPackExpansion() && !InstantiatingPackElement) {

3537

3538

3539

3540 bool Expand = true;

3541 bool RetainExpansion = false;

3542 std::optional NumExpansions;

3544 D->getEllipsisLoc(), D->getSourceRange(), Unexpanded, TemplateArgs,

3545 Expand, RetainExpansion, NumExpansions))

3546 return nullptr;

3547

3548

3549

3550 assert(!RetainExpansion &&

3551 "should never need to retain an expansion for UsingPackDecl");

3552

3553 if (!Expand) {

3554

3555

3557 return instantiateUnresolvedUsingDecl(D, true);

3558 }

3559

3560

3561

3562

3563

3564

3565

3566

3568 SemaRef.Diag(D->getEllipsisLoc(),

3569 diag::err_using_decl_redeclaration_expansion);

3570 return nullptr;

3571 }

3572

3573

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

3577 Decl *Slice = instantiateUnresolvedUsingDecl(D, true);

3578 if (!Slice)

3579 return nullptr;

3580

3581

3582

3583

3584 Expansions.push_back(cast(Slice));

3585 }

3586

3590 return NewD;

3591 }

3592

3595

3598 TemplateArgs);

3599 if (!QualifierLoc)

3600 return nullptr;

3601

3603 SS.Adopt(QualifierLoc);

3604

3607

3608

3609

3610 bool InstantiatingSlice = D->getEllipsisLoc().isValid() &&

3613 InstantiatingSlice ? SourceLocation() : D->getEllipsisLoc();

3614

3615 bool IsUsingIfExists = D->template hasAttr();

3617 nullptr, D->getAccess(), D->getUsingLoc(),

3618 TD, TypenameLoc, SS, NameInfo, EllipsisLoc,

3620 true, IsUsingIfExists);

3621 if (UD) {

3624 }

3625

3626 return UD;

3627}

3628

3629Decl *TemplateDeclInstantiator::VisitUnresolvedUsingTypenameDecl(

3631 return instantiateUnresolvedUsingDecl(D);

3632}

3633

3634Decl *TemplateDeclInstantiator::VisitUnresolvedUsingValueDecl(

3636 return instantiateUnresolvedUsingDecl(D);

3637}

3638

3639Decl *TemplateDeclInstantiator::VisitUnresolvedUsingIfExistsDecl(

3641 llvm_unreachable("referring to unresolved decl out of UsingShadowDecl");

3642}

3643

3644Decl *TemplateDeclInstantiator::VisitUsingPackDecl(UsingPackDecl *D) {

3646 for (auto *UD : D->expansions()) {

3649 Expansions.push_back(NewUD);

3650 else

3651 return nullptr;

3652 }

3653

3657 return NewD;

3658}

3659

3660Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl(

3663 for (auto *I : D->varlist()) {

3665 assert(isa(Var) && "threadprivate arg is not a DeclRefExpr");

3666 Vars.push_back(Var);

3667 }

3668

3671

3674

3675 return TD;

3676}

3677

3680 for (auto *I : D->varlist()) {

3682 assert(isa(Var) && "allocate arg is not a DeclRefExpr");

3683 Vars.push_back(Var);

3684 }

3686

3689 if (auto *AC = dyn_cast(C)) {

3692 continue;

3694 NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc());

3695 } else if (auto *AC = dyn_cast(C)) {

3698 continue;

3700 NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc());

3701

3702 if (!IC)

3703 continue;

3704 }

3705 Clauses.push_back(IC);

3706 }

3707

3710 if (Res.get().isNull())

3711 return nullptr;

3712 return Res.get().getSingleDecl();

3713}

3714

3716 llvm_unreachable(

3717 "Requires directive cannot be instantiated within a dependent context");

3718}

3719

3720Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(

3722

3723 const bool RequiresInstantiation =

3724 D->getType()->isDependentType() ||

3725 D->getType()->isInstantiationDependentType() ||

3726 D->getType()->containsUnexpandedParameterPack();

3727 QualType SubstReductionType;

3728 if (RequiresInstantiation) {

3733 } else {

3734 SubstReductionType = D->getType();

3735 }

3736 if (SubstReductionType.isNull())

3737 return nullptr;

3738 Expr *Combiner = D->getCombiner();

3739 Expr *Init = D->getInitializer();

3740 bool IsCorrect = true;

3741

3742 std::pair<QualType, SourceLocation> ReductionTypes[] = {

3743 std::make_pair(SubstReductionType, D->getLocation())};

3744 auto *PrevDeclInScope = D->getPrevDeclInScope();

3745 if (PrevDeclInScope && !PrevDeclInScope->isInvalidDecl()) {

3746 PrevDeclInScope = cast(

3748 PrevDeclInScope)));

3749 }

3751 nullptr, Owner, D->getDeclName(), ReductionTypes, D->getAccess(),

3752 PrevDeclInScope);

3753 auto *NewDRD = cast(DRD.get().getSingleDecl());

3755 Expr *SubstCombiner = nullptr;

3756 Expr *SubstInitializer = nullptr;

3757

3758 if (Combiner) {

3760 nullptr, NewDRD);

3762 cast(D->getCombinerIn())->getDecl(),

3763 cast(NewDRD->getCombinerIn())->getDecl());

3765 cast(D->getCombinerOut())->getDecl(),

3766 cast(NewDRD->getCombinerOut())->getDecl());

3767 auto *ThisContext = dyn_cast_or_null(Owner);

3769 ThisContext);

3770 SubstCombiner = SemaRef.SubstExpr(Combiner, TemplateArgs).get();

3772 SubstCombiner);

3773 }

3774

3778 nullptr, NewDRD);

3780 cast(D->getInitOrig())->getDecl(),

3781 cast(NewDRD->getInitOrig())->getDecl());

3783 cast(D->getInitPriv())->getDecl(),

3784 cast(NewDRD->getInitPriv())->getDecl());

3786 SubstInitializer = SemaRef.SubstExpr(Init, TemplateArgs).get();

3787 } else {

3788 auto *OldPrivParm =

3789 cast(cast(D->getInitPriv())->getDecl());

3790 IsCorrect = IsCorrect && OldPrivParm->hasInit();

3791 if (IsCorrect)

3793 TemplateArgs);

3794 }

3796 NewDRD, SubstInitializer, OmpPrivParm);

3797 }

3798 IsCorrect = IsCorrect && SubstCombiner &&

3801 SubstInitializer) ||

3803 !SubstInitializer));

3804

3806 nullptr, DRD, IsCorrect && D->isInvalidDecl());

3807

3808 return NewDRD;

3809}

3810

3813

3814 const bool RequiresInstantiation =

3815 D->getType()->isDependentType() ||

3816 D->getType()->isInstantiationDependentType() ||

3817 D->getType()->containsUnexpandedParameterPack();

3820 if (RequiresInstantiation) {

3825 } else {

3826 SubstMapperTy = D->getType();

3827 }

3828 if (SubstMapperTy.isNull())

3829 return nullptr;

3830

3831 auto *PrevDeclInScope = D->getPrevDeclInScope();

3832 if (PrevDeclInScope && !PrevDeclInScope->isInvalidDecl()) {

3833 PrevDeclInScope = cast(

3835 PrevDeclInScope)));

3836 }

3837 bool IsCorrect = true;

3839

3842 nullptr,

3843 (*D->clauselist_begin())->getBeginLoc());

3846 nullptr, SubstMapperTy, D->getLocation(), VN);

3848 cast(D->getMapperVarRef())->getDecl(),

3849 cast(MapperVarRef.get())->getDecl());

3850 auto *ThisContext = dyn_cast_or_null(Owner);

3852 ThisContext);

3853

3855 auto *OldC = cast(C);

3857 for (Expr *OE : OldC->varlist()) {

3859 if (!NE) {

3860 IsCorrect = false;

3861 break;

3862 }

3863 NewVars.push_back(NE);

3864 }

3865 if (!IsCorrect)

3866 break;

3869 TemplateArgs);

3871 SS.Adopt(NewQualifierLoc);

3874 OMPVarListLocTy Locs(OldC->getBeginLoc(), OldC->getLParenLoc(),

3875 OldC->getEndLoc());

3877 OldC->getIteratorModifier(), OldC->getMapTypeModifiers(),

3878 OldC->getMapTypeModifiersLoc(), SS, NewNameInfo, OldC->getMapType(),

3879 OldC->isImplicitMapType(), OldC->getMapLoc(), OldC->getColonLoc(),

3880 NewVars, Locs);

3881 Clauses.push_back(NewC);

3882 }

3884 if (!IsCorrect)

3885 return nullptr;

3887 nullptr, Owner, D->getDeclName(), SubstMapperTy, D->getLocation(),

3888 VN, D->getAccess(), MapperVarRef.get(), Clauses, PrevDeclInScope);

3889 Decl *NewDMD = DG.get().getSingleDecl();

3891 return NewDMD;

3892}

3893

3894Decl *TemplateDeclInstantiator::VisitOMPCapturedExprDecl(

3896 llvm_unreachable("Should not be met in templates");

3897}

3898

3901}

3902

3906 if (Inst && D->getDescribedFunctionTemplate())

3908 return Inst;

3909}

3910

3913}

3914

3915Decl *TemplateDeclInstantiator::VisitRecordDecl(RecordDecl *D) {

3916 llvm_unreachable("There are only CXXRecordDecls in C++");

3917}

3918

3920TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(

3922

3923

3927 "can only instantiate an explicit specialization "

3928 "for a member class template");

3929

3930

3931

3934 D->getLocation(), ClassTemplate, TemplateArgs));

3935 if (!InstClassTemplate)

3936 return nullptr;

3937

3938

3939

3942 D->getTemplateArgsAsWritten()) {

3943 InstTemplateArgs.setLAngleLoc(TemplateArgsInfo->getLAngleLoc());

3944 InstTemplateArgs.setRAngleLoc(TemplateArgsInfo->getRAngleLoc());

3945

3947 TemplateArgs, InstTemplateArgs))

3948 return nullptr;

3949 }

3950

3951

3952

3955 InstClassTemplate, D->getLocation(), InstTemplateArgs,

3956 {}, false, SugaredConverted, CanonicalConverted,

3957 true))

3958 return nullptr;

3959

3960

3961

3962 void *InsertPos = nullptr;

3964 InstClassTemplate->findSpecialization(CanonicalConverted, InsertPos);

3965

3966

3967

3969 if (PrevDecl &&

3971 D->getSpecializationKind(),

3972 PrevDecl,

3975 Ignored))

3976 return nullptr;

3977

3978

3979

3980

3981

3982

3983

3984

3985

3986

3987

3988

3989

3991 D->isThisDeclarationADefinition()) {

3992 SemaRef.Diag(D->getLocation(), diag::err_redefinition) << PrevDecl;

3994 diag::note_previous_definition);

3995 return nullptr;

3996 }

3997

3998

4002 D->getLocation(), InstClassTemplate, CanonicalConverted, PrevDecl);

4004

4005

4006

4007 if (!PrevDecl)

4009

4010

4012 return nullptr;

4013

4019

4021

4022

4023

4024

4025

4026 if (D->isThisDeclarationADefinition() &&

4029 true))

4030 return nullptr;

4031

4032 return InstD;

4033}

4034

4037

4040 assert(VarTemplate &&

4041 "A template specialization without specialized template?");

4042

4045 D->getLocation(), VarTemplate, TemplateArgs));

4046 if (!InstVarTemplate)

4047 return nullptr;

4048

4049

4051 D->getTemplateArgsAsWritten()) {

4052 VarTemplateArgsInfo.setLAngleLoc(TemplateArgsInfo->getLAngleLoc());

4053 VarTemplateArgsInfo.setRAngleLoc(TemplateArgsInfo->getRAngleLoc());

4054

4056 TemplateArgs, VarTemplateArgsInfo))

4057 return nullptr;

4058 }

4059

4060

4063 InstVarTemplate, D->getLocation(), VarTemplateArgsInfo,

4064 {}, false, SugaredConverted, CanonicalConverted,

4065 true))

4066 return nullptr;

4067

4068

4069 void *InsertPos = nullptr;

4072

4073

4074

4075 bool Ignored;

4077 D->getLocation(), D->getSpecializationKind(), PrevDecl,

4080 return nullptr;

4081

4083 InstVarTemplate, D, VarTemplateArgsInfo, CanonicalConverted, PrevDecl);

4084}

4085

4091

4092

4094 SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs,

4095 D->getTypeSpecStartLoc(), D->getDeclName());

4096 if (!DI)

4097 return nullptr;

4098

4100 SemaRef.Diag(D->getLocation(), diag::err_variable_instantiates_to_function)

4101 << D->isStaticDataMember() << DI->getType();

4102 return nullptr;

4103 }

4104

4105

4108 VarTemplate, DI->getType(), DI, D->getStorageClass(), Converted);

4110 if (!PrevDecl) {

4111 void *InsertPos = nullptr;

4114 }

4115

4118

4119

4121 return nullptr;

4122

4124 StartingScope, false, PrevDecl);

4125

4126 return Var;

4127}

4128

4130 llvm_unreachable("@defs is not supported in Objective-C++");

4131}

4132

4134

4137 "cannot instantiate %0 yet");

4140

4141 return nullptr;

4142}

4143

4144Decl *TemplateDeclInstantiator::VisitConceptDecl(ConceptDecl *D) {

4145 llvm_unreachable("Concept definitions cannot reside inside a template");

4146}

4147

4148Decl *TemplateDeclInstantiator::VisitImplicitConceptSpecializationDecl(

4150 llvm_unreachable("Concept specializations cannot reside inside a template");

4151}

4152

4157}

4158

4160 llvm_unreachable("Unexpected decl");

4161}

4162

4167 return nullptr;

4168

4169 Decl *SubstD;

4171 SubstD = Instantiator.Visit(D);

4172 });

4173 return SubstD;

4174}

4175

4181

4182

4183

4186 SemaRef.Context.BoolTy, FPT->getParamTypes(), FPT->getExtProtoInfo());

4187

4188

4189

4190

4191

4192

4193

4197 assert(OldLoc && "type of function is not a function type?");

4199 for (unsigned I = 0, N = OldLoc.getNumParams(); I != N; ++I)

4200 NewLoc.setParam(I, OldLoc.getParam(I));

4201 TInfo = NewTInfo;

4202

4203

4206}

4207

4210 if (Spaceship->isInvalidDecl())

4211 return nullptr;

4212

4213

4214

4215

4216

4222 if (auto *MD = dyn_cast(Spaceship)) {

4224 MD, nullptr,

4226 } else {

4227 assert(Spaceship->getFriendObjectKind() &&

4228 "defaulted spaceship is neither a member nor a friend");

4229

4231 Spaceship, nullptr,

4233 if (!R)

4234 return nullptr;

4235

4238 cast(R), Spaceship->getBeginLoc());

4241 }

4242 return cast_or_null(R);

4243}

4244

4245

4246

4247

4248

4249

4250

4253

4255

4256 unsigned N = L->size();

4258 ParamVector Params;

4259 Params.reserve(N);

4260 for (auto &P : *L) {

4262 Params.push_back(D);

4264 }

4265

4266

4268 return nullptr;

4269

4271

4276 return InstL;

4277}

4278

4282 bool EvaluateConstraints) {

4286}

4287

4288

4289

4290

4291

4292

4293

4294

4295

4296

4297

4298

4303

4304

4305

4307

4308

4309

4312 if (!InstParams)

4313 return nullptr;

4314

4315

4316

4322 InstTemplateArgs))

4323 return nullptr;

4324

4325

4326

4329 ClassTemplate, PartialSpec->getLocation(), InstTemplateArgs,

4330 {},

4331 false, SugaredConverted, CanonicalConverted))

4332 return nullptr;

4333

4334

4336 PartialSpec->getLocation(), ClassTemplate, InstTemplateArgs.size(),

4337 CanonicalConverted))

4338 return nullptr;

4339

4340

4341

4342 void *InsertPos = nullptr;

4345 InsertPos);

4346

4347

4348

4350 TemplateName(ClassTemplate), CanonicalConverted);

4351

4352

4357 ClassTemplate, CanonicalConverted, CanonType,

4358 nullptr);

4359

4361

4362

4364 return nullptr;

4365

4367

4368 if (PrevDecl) {

4369

4370

4371

4372

4373

4374

4375

4376

4377

4378

4379

4380

4381

4382

4383

4385 diag::err_partial_spec_redeclared)

4386 << InstPartialSpec;

4387 SemaRef.Diag(PrevDecl->getLocation(), diag::note_prev_partial_spec_here)

4389 return nullptr;

4390 }

4391

4392

4394

4395

4396

4398 nullptr);

4399 return InstPartialSpec;

4400}

4401

4402

4403

4404

4405

4406

4407

4408

4409

4410

4411

4412

4417

4418

4419

4421

4422

4423

4426 if (!InstParams)

4427 return nullptr;

4428

4429

4430

4436 InstTemplateArgs))

4437 return nullptr;

4438

4439

4440

4443 InstTemplateArgs, {},

4444 false,

4445 SugaredConverted, CanonicalConverted))

4446 return nullptr;

4447

4448

4450 PartialSpec->getLocation(), VarTemplate, InstTemplateArgs.size(),

4451 CanonicalConverted))

4452 return nullptr;

4453

4454

4455

4456 void *InsertPos = nullptr;

4459 InsertPos);

4460

4461

4465 if (!DI)

4466 return nullptr;

4467

4470 diag::err_variable_instantiates_to_function)

4472 return nullptr;

4473 }

4474

4475

4480 DI, PartialSpec->getStorageClass(), CanonicalConverted);

4481

4483

4484

4486 return nullptr;

4487

4489

4490 if (PrevDecl) {

4491

4492

4493

4494

4495

4496

4497

4498

4499

4500

4501

4502

4503

4504

4505

4507 diag::err_var_partial_spec_redeclared)

4508 << InstPartialSpec;

4510 diag::note_var_prev_partial_spec_here);

4511 return nullptr;

4512 }

4513

4515

4516

4517

4519

4521 LateAttrs, Owner, StartingScope);

4522

4523 return InstPartialSpec;

4524}

4525

4530 assert(OldTInfo && "substituting function without type source info");

4531 assert(Params.empty() && "parameter vector is non-empty at start");

4532

4535 if (CXXMethodDecl *Method = dyn_cast(D)) {

4536 ThisContext = cast(Owner);

4537 ThisTypeQuals = Method->getFunctionObjectParameterType().getQualifiers();

4538 }

4539

4541 OldTInfo, TemplateArgs, D->getTypeSpecStartLoc(), D->getDeclName(),

4542 ThisContext, ThisTypeQuals, EvaluateConstraints);

4543 if (!NewTInfo)

4544 return nullptr;

4545

4548 if (NewTInfo != OldTInfo) {

4549

4552 unsigned NewIdx = 0;

4553 for (unsigned OldIdx = 0, NumOldParams = OldProtoLoc.getNumParams();

4554 OldIdx != NumOldParams; ++OldIdx) {

4555 ParmVarDecl *OldParam = OldProtoLoc.getParam(OldIdx);

4556 if (!OldParam)

4557 return nullptr;

4558

4560

4561 std::optional NumArgumentsInExpansion;

4563 NumArgumentsInExpansion =

4565 TemplateArgs);

4566 if (!NumArgumentsInExpansion) {

4567

4568

4570 Params.push_back(NewParam);

4571 Scope->InstantiatedLocal(OldParam, NewParam);

4572 } else {

4573

4574 Scope->MakeInstantiatedLocalArgPack(OldParam);

4575 for (unsigned I = 0; I != *NumArgumentsInExpansion; ++I) {

4577 Params.push_back(NewParam);

4578 Scope->InstantiatedLocalPackArg(OldParam, NewParam);

4579 }

4580 }

4581 }

4582 } else {

4583

4584

4585

4587 cast(OldProtoLoc.getType());

4588 for (unsigned i = 0, i_end = OldProtoLoc.getNumParams(); i != i_end;

4589 ++i) {

4590 ParmVarDecl *OldParam = OldProtoLoc.getParam(i);

4591 if (!OldParam) {

4594 continue;

4595 }

4596

4598 cast_or_null(VisitParmVarDecl(OldParam));

4599 if (!Parm)

4600 return nullptr;

4601 Params.push_back(Parm);

4602 }

4603 }

4604 } else {

4605

4606

4607

4608

4609

4610

4611

4612

4613

4614

4618 TemplateArgs, ParamTypes, &Params,

4619 ExtParamInfos))

4620 return nullptr;

4621 }

4622

4623 return NewTInfo;

4624}

4625

4630

4631 for (auto *decl : PatternDecl->decls()) {

4632 if (!isa(decl) || isa(decl))

4633 continue;

4634

4637

4638 auto it = llvm::find_if(Function->decls(), [&](Decl *inst) {

4639 VarDecl *InstVD = dyn_cast(inst);

4640 return InstVD && InstVD->isLocalVarDecl() &&

4641 InstVD->getIdentifier() == II;

4642 });

4643

4644 if (it == Function->decls().end())

4645 continue;

4646

4647 Scope.InstantiatedLocal(VD, *it);

4648 LSI->addCapture(cast(*it), false, false,

4650 VD->getType(), false);

4651 }

4652}

4653

4654bool Sema::addInstantiatedParametersToScope(

4658 unsigned FParamIdx = 0;

4659 for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I) {

4662

4663 assert(FParamIdx < Function->getNumParams());

4666

4667

4668

4669

4670

4671

4676 if (T.isNull())

4677 return true;

4679 }

4680

4681 Scope.InstantiatedLocal(PatternParam, FunctionParam);

4682 ++FParamIdx;

4683 continue;

4684 }

4685

4686

4687 Scope.MakeInstantiatedLocalArgPack(PatternParam);

4688 std::optional NumArgumentsInExpansion =

4690 if (NumArgumentsInExpansion) {

4693 for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) {

4701 if (T.isNull())

4702 return true;

4704 }

4705

4706 Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam);

4707 ++FParamIdx;

4708 }

4709 }

4710 }

4711

4712 return false;

4713}

4714

4718

4719

4720

4721

4722

4723

4724

4725

4728 return true;

4729

4730

4731

4732

4733

4734

4735

4736

4737

4738

4739

4740

4741

4742

4743

4744

4745

4746

4749 false, std::nullopt,

4750 true, nullptr,

4751 false, false,

4752 true);

4753

4754 if (SubstDefaultArgument(CallLoc, Param, TemplateArgs, true))

4755 return true;

4756

4758 L->DefaultArgumentInstantiated(Param);

4759

4760 return false;

4761}

4762

4767 return;

4768

4772

4773

4775 return;

4776 }

4778

4779

4780 Diag(PointOfInstantiation, diag::err_exception_spec_cycle) << Decl;

4782 return;

4783 }

4784

4785

4786

4789

4792 false, std::nullopt,

4793 true);

4794

4795

4796

4797

4798

4800 if (addInstantiatedParametersToScope(Decl, Template, Scope, TemplateArgs)) {

4802 return;

4803 }

4804

4805

4806

4808 *this, Decl, TemplateArgs, Scope,

4809 false);

4810

4812 TemplateArgs);

4813}

4814

4815

4816

4817

4818

4819bool

4823

4824

4827

4828

4829

4830

4831

4832

4833

4834

4835

4836

4837

4840 if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution ||

4841 ActiveInst.Kind == ActiveInstType::DeducedTemplateArgumentSubstitution) {

4842 if (isa(ActiveInst.Entity)) {

4844 {ActiveInst.Entity->getCanonicalDecl(), ActiveInst.Kind});

4846 ActiveInst.Kind = ActiveInstType::TemplateInstantiation;

4847 ActiveInst.Entity = New;

4849 }

4850 }

4851

4853 assert(Proto && "Function template without prototype?");

4854

4857

4858

4859

4860

4861

4862 if (SemaRef.getLangOpts().CPlusPlus11 &&

4873

4874

4877 assert(NewProto && "Template instantiation without function prototype?");

4884 } else {

4887 }

4888 }

4889

4890

4893

4895 LateAttrs, StartingScope);

4896

4897 return false;

4898}

4899

4900

4901

4902

4903

4904

4905bool

4909 return true;

4910

4911 if (isa(New) && SemaRef.getLangOpts().CPlusPlus11)

4913

4917

4918

4919 return false;

4920}

4921

4924

4927 Lookups.reserve(DFI->getUnqualifiedLookups().size());

4928 bool AnyChanged = false;

4929 for (DeclAccessPair DA : DFI->getUnqualifiedLookups()) {

4931 DA.getDecl(), TemplateArgs);

4932 if (D)

4933 return true;

4934 AnyChanged |= (D != DA.getDecl());

4936 }

4937

4938

4939

4942 SemaRef.Context, Lookups)

4943 : DFI);

4944 }

4945

4947 return false;

4948}

4949

4954

4958 return nullptr;

4959

4962 false);

4963

4964 return cast_or_null(SubstDecl(FD, FD->getParent(), MArgs));

4965}

4966

4969 bool Recursive,

4970 bool DefinitionRequired,

4971 bool AtEndOfTU) {

4972 if (Function->isInvalidDecl() || isa(Function))

4973 return;

4974

4975

4976

4978 Function->getTemplateSpecializationKindForInstantiation();

4980 return;

4981

4982

4983

4985 !DefinitionRequired)

4986 return;

4987

4988

4990 if (Function->isDefined(ExistingDefn,

4991 true)) {

4993 return;

4994

4995

4996

4997

5000 }

5001

5002

5003 const FunctionDecl *PatternDecl = Function->getTemplateInstantiationPattern();

5004 assert(PatternDecl && "instantiating a non-template");

5005

5007 Stmt *Pattern = nullptr;

5008 if (PatternDef) {

5009 Pattern = PatternDef->getBody(PatternDef);

5010 PatternDecl = PatternDef;

5012 PatternDef = nullptr;

5013 }

5014

5015

5016

5018 Function->getInstantiatedFromMemberFunction(),

5019 PatternDecl, PatternDef, TSK,

5020 DefinitionRequired)) {

5021 if (DefinitionRequired)

5024 (Function->isConstexpr() && !Recursive)) {

5025

5026

5027 assert(!Recursive);

5028 Function->setInstantiationIsPending(true);

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

5031

5032 if (llvm::isTimeTraceVerbose()) {

5033 llvm::timeTraceAddInstantEvent("DeferInstantiation", [&] {

5034 std::string Name;

5035 llvm::raw_string_ostream OS(Name);

5037 true);

5038 return Name;

5039 });

5040 }

5044 Diag(PointOfInstantiation, diag::warn_func_template_missing)

5046 Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);

5048 Diag(PointOfInstantiation, diag::note_inst_declaration_hint)

5050 }

5051 }

5052

5053 return;

5054 }

5055

5056

5059 Function->setInstantiationIsPending(true);

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

5062 return;

5063 }

5064

5065 llvm::TimeTraceScope TimeScope("InstantiateFunction", [&]() {

5066 llvm::TimeTraceMetadata M;

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

5069 true);

5070 if (llvm::isTimeTraceVerbose()) {

5074 }

5075 return M;

5076 });

5077

5078

5079

5080

5081

5082

5084 Recursive);

5086

5087

5088

5091

5094

5097 "missing LateParsedTemplate");

5099 Pattern = PatternDecl->getBody(PatternDecl);

5101 }

5102

5103

5104 assert((Pattern || PatternDecl->isDefaulted() ||

5106 "unexpected kind of function template definition");

5107

5108

5109

5110

5111

5112

5116 return;

5117

5119

5120

5121 for (auto *D = Function->getMostRecentDecl(); ;

5123 D->setImplicitlyInline();

5125 break;

5126 }

5127 }

5128

5131 return;

5133 "instantiating function definition");

5134

5135

5136

5137 Function->setVisibleDespiteOwningModule();

5138

5139

5144

5147

5151 ThisContext = Method->getParent();

5152 ThisTypeQuals = Method->getMethodQualifiers();

5153 }

5154 CXXThisScopeRAII ThisScope(*this, ThisContext, ThisTypeQuals);

5155

5156

5157

5158

5159

5160

5161

5162 bool MergeWithParentScope = false;

5164 MergeWithParentScope =

5165 Rec->isLocalClass() && Function->isFunctionTemplateSpecialization();

5166

5168 auto RebuildTypeSourceInfoForDefaultSpecialMembers = [&]() {

5169

5170

5171

5172

5174 "Special member needs to be defaulted");

5180 return;

5181

5182 auto *NewRec = dyn_cast(Function->getDeclContext());

5183 const auto *PatternRec =

5184 dyn_cast(PatternDecl->getDeclContext());

5185 if (!NewRec || !PatternRec)

5186 return;

5187 if (!PatternRec->isLambda())

5188 return;

5189

5190 struct SpecialMemberTypeInfoRebuilder

5191 : TreeTransform {

5195

5196 SpecialMemberTypeInfoRebuilder(Sema &SemaRef, const CXXRecordDecl *O,

5198 : TreeTransform(SemaRef), OldDecl(O), NewDecl(N) {}

5199

5203 bool &Changed) {

5204 return false;

5205 }

5206

5210 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));

5211 if (Record != OldDecl)

5212 return Base::TransformRecordType(TLB, TL);

5213

5214 QualType Result = getDerived().RebuildRecordType(NewDecl);

5215 if (Result.isNull())

5217

5220 return Result;

5221 }

5222 } IR{*this, PatternRec, NewRec};

5223

5225 assert(NewSI && "Type Transform failed?");

5227 Function->setTypeSourceInfo(NewSI);

5228

5231 assert(NewParmSI && "Type transformation failed.");

5234 };

5235

5237 RebuildTypeSourceInfoForDefaultSpecialMembers();

5239 } else {

5241 Function, Function->getLexicalDeclContext(), false,

5242 std::nullopt, false, PatternDecl);

5243

5244

5245

5246

5247

5249

5251

5252

5253

5255

5259

5260 if (addInstantiatedParametersToScope(Function, PatternDecl, Scope,

5261 TemplateArgs))

5262 return;

5263

5267 Body = nullptr;

5268 } else {

5270

5272 TemplateArgs);

5273

5274

5275

5277 Ctor->isDefaultConstructor()) {

5279 }

5280 }

5281

5282

5283 Body = SubstStmt(Pattern, TemplateArgs);

5284

5287 }

5288

5289

5291

5293

5295 Listener->FunctionDefinitionInstantiated(Function);

5296

5297 savedContext.pop();

5298 }

5299

5302

5303

5304

5305 LocalInstantiations.perform();

5307 GlobalInstantiations.perform();

5308}

5309

5318 return nullptr;

5319

5322 return nullptr;

5323

5324

5325

5326

5327

5328

5329

5330

5331

5332

5333 bool IsMemberSpec = false;

5335 if (auto *PartialSpec =

5336 dyn_cast(FromVar)) {

5337 assert(PartialSpecArgs);

5338 IsMemberSpec = PartialSpec->isMemberSpecialization();

5340 PartialSpec, PartialSpecArgs->asArray(), false);

5341 } else {

5343 IsMemberSpec = VarTemplate->isMemberSpecialization();

5345 false);

5346 }

5347 if (!IsMemberSpec)

5349

5351 MultiLevelList);

5352

5353

5354

5355 return cast_or_null(

5357 VarTemplate, FromVar, TemplateArgsInfo, Converted));

5358}

5359

5364 "don't have a definition to instantiate from");

5365

5366

5370 if (!DI)

5371 return nullptr;

5372

5373

5375

5376

5378

5379

5381

5384

5385 return VarSpec;

5386}

5387

5393 bool InstantiatingVarTemplate,

5395

5396

5397 bool InstantiatingVarTemplatePartialSpec =

5398 isa(OldVar) &&

5399 isa(NewVar);

5400

5401

5402 bool InstantiatingSpecFromTemplate =

5403 isa(NewVar) &&

5405 isa(OldVar));

5406

5407

5408

5409

5410

5411

5426

5428 if (OldVar->isUsed(false))

5431 }

5432

5433 InstantiateAttrs(TemplateArgs, OldVar, NewVar, LateAttrs, StartingScope);

5434

5439 NewVar->isLocalExternDecl() ? RedeclarationKind::ForExternalRedeclaration

5441

5445

5446

5450 } else if (!isa(NewVar) &&

5453 } else if (PrevDeclForVarTemplateSpecialization) {

5454 Previous.addDecl(PrevDeclForVarTemplateSpecialization);

5455 }

5457

5458 if (!InstantiatingVarTemplate) {

5462 }

5463

5467 }

5468

5469

5470

5471

5472

5473

5474

5476 !InstantiatingSpecFromTemplate)

5479

5480

5481

5483 dyn_cast(OldVar)) {

5485 !isa(OldVTSD))

5486 cast(NewVar)->setSpecializationKind(

5488 }

5489

5490

5493

5494

5495 if (InstantiatingVarTemplate || InstantiatingVarTemplatePartialSpec) {

5496

5498

5500 } else if (InstantiatingSpecFromTemplate ||

5503

5504

5505

5506 } else {

5508 }

5509

5510

5511

5516}

5517

5522 L->VariableDefinitionInstantiated(Var);

5523

5524

5525

5526

5529 else if (OldVar->isInline())

5531

5532 if (OldVar->getInit()) {

5535

5540

5542

5543 {

5547 }

5548

5549 if (Init.isInvalid()) {

5550 Expr *InitExpr = Init.get();

5551

5552 if (Var->hasAttr() &&

5553 (!InitExpr ||

5555

5556 } else if (InitExpr) {

5559 } else

5561 } else {

5562

5563

5565 }

5566 } else {

5567

5568

5571 return;

5572

5573

5574

5576 return;

5577 }

5578

5579

5581 return;

5582

5584 }

5585

5588}

5589

5591 VarDecl *Var, bool Recursive,

5592 bool DefinitionRequired, bool AtEndOfTU) {

5594 return;

5595

5596

5600 return;

5601

5602

5604 assert(PatternDecl && "no pattern for templated variable");

5607

5609 dyn_cast(Var);

5610 if (VarSpec) {

5611

5612

5613

5614

5615

5616

5617

5618

5620 (PatternDecl = PatternDecl->getFirstDecl())->hasInit() &&

5622

5623

5626 return;

5628 "instantiating variable initializer");

5629

5630

5631

5633

5634

5635

5636

5638 Recursive);

5641

5642

5643

5646 PreviousContext.pop();

5647

5648

5649

5650 LocalInstantiations.perform();

5651 Local.Exit();

5652 GlobalInstantiations.perform();

5653 }

5654 } else {

5656 "not a static data member?");

5657 }

5658

5660

5661

5662

5663

5664

5665 if (!Def && !DefinitionRequired) {

5668 std::make_pair(Var, PointOfInstantiation));

5670

5671 if (AtEndOfTU && getDiagnostics().hasErrorOccurred() &&

5673 Diag(PointOfInstantiation, diag::warn_var_template_missing)

5674 << Var;

5675 Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);

5677 Diag(PointOfInstantiation, diag::note_inst_declaration_hint) << Var;

5678 }

5679 return;

5680 }

5681 }

5682

5683

5684

5685

5687 false,

5688 PatternDecl, Def, TSK,

5689 DefinitionRequired))

5690 return;

5691

5692

5693

5694

5695

5696

5697

5698

5699

5700

5703 return;

5704

5705

5706 struct PassToConsumerRAII {

5709

5711 : Consumer(Consumer), Var(Var) { }

5712

5713 ~PassToConsumerRAII() {

5715 }

5716 } PassToConsumerRAII(Consumer, Var);

5717

5718

5720

5721

5723 PointOfInstantiation);

5724 return;

5725 }

5726

5729 return;

5731 "instantiating variable definition");

5732

5733

5734

5735

5737 Recursive);

5738

5739

5740

5743

5745

5748

5749

5751 } else if (!VarSpec) {

5753 TemplateArgs));

5756

5757

5758

5760 TemplateArgs);

5761

5765 TemplateArgInfo.setLAngleLoc(ArgInfo->getLAngleLoc());

5766 TemplateArgInfo.setRAngleLoc(ArgInfo->getRAngleLoc());

5769 }

5770

5774 if (Var) {

5780 cast(Var)->setInstantiationOf(

5782

5783

5785 }

5786 } else

5787

5788

5790

5791 PreviousContext.pop();

5792

5793 if (Var) {

5794 PassToConsumerRAII.Var = Var;

5797 }

5798

5799

5800

5801 LocalInstantiations.perform();

5802 Local.Exit();

5803 GlobalInstantiations.perform();

5804}

5805

5806void

5810

5813

5814

5815 for (const auto *Init : Tmpl->inits()) {

5816

5817

5818 if (Init->isWritten())

5819 continue;

5820

5822

5823 if (Init->isPackExpansion()) {

5824

5825 TypeLoc BaseTL = Init->getTypeSourceInfo()->getTypeLoc();

5829 bool ShouldExpand = false;

5830 bool RetainExpansion = false;

5831 std::optional NumExpansions;

5834 Unexpanded,

5835 TemplateArgs, ShouldExpand,

5836 RetainExpansion,

5837 NumExpansions)) {

5838 AnyErrors = true;

5840 continue;

5841 }

5842 assert(ShouldExpand && "Partial instantiation of base initializer?");

5843

5844

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

5847

5848

5850 true);

5852 AnyErrors = true;

5853 break;

5854 }

5855

5856

5858 TemplateArgs,

5859 Init->getSourceLocation(),

5861 if (!BaseTInfo) {

5862 AnyErrors = true;

5863 break;

5864 }

5865

5866

5868 BaseTInfo, TempInit.get(),

5872 AnyErrors = true;

5873 break;

5874 }

5875

5876 NewInits.push_back(NewInit.get());

5877 }

5878

5879 continue;

5880 }

5881

5882

5884 true);

5886 AnyErrors = true;

5887 continue;

5888 }

5889

5891 if (Init->isDelegatingInitializer() || Init->isBaseInitializer()) {

5893 TemplateArgs,

5894 Init->getSourceLocation(),

5896 if (!TInfo) {

5897 AnyErrors = true;

5899 continue;

5900 }

5901

5902 if (Init->isBaseInitializer())

5905 else

5908 } else if (Init->isMemberInitializer()) {

5910 Init->getMemberLocation(),

5911 Init->getMember(),

5912 TemplateArgs));

5914 AnyErrors = true;

5916 continue;

5917 }

5918

5920 Init->getSourceLocation());

5921 } else if (Init->isIndirectMemberInitializer()) {

5924 Init->getMemberLocation(),

5925 Init->getIndirectMember(), TemplateArgs));

5926

5927 if (!IndirectMember) {

5928 AnyErrors = true;

5930 continue;

5931 }

5932

5934 Init->getSourceLocation());

5935 }

5936

5938 AnyErrors = true;

5940 } else {

5941 NewInits.push_back(NewInit.get());

5942 }

5943 }

5944

5945

5947

5949 NewInits,

5950 AnyErrors);

5951}

5952

5953

5954

5958

5959 do {

5960 Instance = Instance->getCanonicalDecl();

5961 if (Pattern == Instance) return true;

5962 Instance = Instance->getInstantiatedFromMemberTemplate();

5963 } while (Instance);

5964

5965 return false;

5966}

5967

5971

5972 do {

5973 Instance = Instance->getCanonicalDecl();

5974 if (Pattern == Instance) return true;

5975 Instance = Instance->getInstantiatedFromMemberTemplate();

5976 } while (Instance);

5977

5978 return false;

5979}

5980

5981static bool

5984 Pattern

5985 = cast(Pattern->getCanonicalDecl());

5986 do {

5987 Instance = cast(

5988 Instance->getCanonicalDecl());

5989 if (Pattern == Instance)

5990 return true;

5991 Instance = Instance->getInstantiatedFromMember();

5992 } while (Instance);

5993

5994 return false;

5995}

5996

6000

6001 do {

6002 Instance = Instance->getCanonicalDecl();

6003 if (Pattern == Instance) return true;

6004 Instance = Instance->getInstantiatedFromMemberClass();

6005 } while (Instance);

6006

6007 return false;

6008}

6009

6013

6014 do {

6015 Instance = Instance->getCanonicalDecl();

6016 if (Pattern == Instance) return true;

6017 Instance = Instance->getInstantiatedFromMemberFunction();

6018 } while (Instance);

6019

6020 return false;

6021}

6022

6026

6027 do {

6028 Instance = Instance->getCanonicalDecl();

6029 if (Pattern == Instance) return true;

6030 Instance = Instance->getInstantiatedFromMemberEnum();

6031 } while (Instance);

6032

6033 return false;

6034}

6035

6039 return declaresSameEntity(C.getInstantiatedFromUsingShadowDecl(Instance),

6040 Pattern);

6041}

6042

6045 return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);

6046}

6047

6048template

6051

6052

6053

6054

6055

6056

6057 bool OtherIsPackExpansion;

6059 if (auto *OtherUUD = dyn_cast(Other)) {

6060 OtherIsPackExpansion = OtherUUD->isPackExpansion();

6062 } else if (auto *OtherUPD = dyn_cast(Other)) {

6063 OtherIsPackExpansion = true;

6064 OtherFrom = OtherUPD->getInstantiatedFromUsingDecl();

6065 } else if (auto *OtherUD = dyn_cast(Other)) {

6066 OtherIsPackExpansion = false;

6068 } else {

6069 return false;

6070 }

6071 return Pattern->isPackExpansion() == OtherIsPackExpansion &&

6073}

6074

6077 assert(Instance->isStaticDataMember());

6078

6080

6081 do {

6082 Instance = Instance->getCanonicalDecl();

6083 if (Pattern == Instance) return true;

6084 Instance = Instance->getInstantiatedFromStaticDataMember();

6085 } while (Instance);

6086

6087 return false;

6088}

6089

6090

6091

6093 if (auto *UUD = dyn_cast(D))

6095

6096 if (auto *UUD = dyn_cast(D))

6098

6100 return false;

6101

6102 if (auto *Record = dyn_cast(Other))

6104

6105 if (auto *Function = dyn_cast(Other))

6107

6108 if (auto *Enum = dyn_cast(Other))

6110

6111 if (auto *Var = dyn_cast(Other))

6114

6115 if (auto *Temp = dyn_cast(Other))

6117

6118 if (auto *Temp = dyn_cast(Other))

6120

6121 if (auto *PartialSpec =

6122 dyn_cast(Other))

6123 return isInstantiationOf(cast(D),

6124 PartialSpec);

6125

6126 if (auto *Field = dyn_cast(Other)) {

6127 if (!Field->getDeclName()) {

6128

6130 cast(D));

6131 }

6132 }

6133

6134 if (auto *Using = dyn_cast(Other))

6136

6137 if (auto *Shadow = dyn_cast(Other))

6139

6140 return D->getDeclName() &&

6141 D->getDeclName() == cast(Other)->getDeclName();

6142}

6143

6144template

6147 ForwardIterator first,

6148 ForwardIterator last) {

6149 for (; first != last; ++first)

6151 return cast(*first);

6152

6153 return nullptr;

6154}

6155

6158 if (NamedDecl *D = dyn_cast(DC)) {

6160 return cast_or_null(ID);

6161 } else return DC;

6162}

6163

6164

6165

6166

6167

6168

6169

6172 return false;

6173 if (!Level)

6174 return true;

6175 return cast(DC)->getTemplateDepth() > Level;

6176}

6177

6180 bool FindingInstantiatedContext) {

6182

6183

6186

6187

6188

6189

6190

6191

6192

6193

6194

6195

6196

6197

6198

6199

6200

6201

6202 if (isa(D) && !ParentDependsOnArgs &&

6203 !cast(D)->getType()->isInstantiationDependentType())

6204 return D;

6205 if (isa(D) || isa(D) ||

6206 isa(D) || isa(D) ||

6208 isa(ParentDC) ||

6209 isa(ParentDC))) ||

6210 (isa(D) && cast(D)->isLambda() &&

6211 cast(D)->getTemplateDepth() >

6213

6214

6218 return cast(FD);

6219

6221 assert(PackIdx != -1 &&

6222 "found declaration pack but not pack expanding");

6224 return cast((*cast<DeclArgumentPack *>(*Found))[PackIdx]);

6225 }

6226 }

6227

6228

6229

6230

6231 if (isa(D) || isa(D) ||

6232 isa(D))

6233 return D;

6234

6236 return nullptr;

6237

6238

6239

6240

6241

6242

6243

6244

6245

6246

6247

6248

6249

6250

6251 bool NeedInstantiate = false;

6253 NeedInstantiate = RD->isLocalClass();

6254 else if (isa(D) &&

6256 NeedInstantiate = true;

6257 else

6258 NeedInstantiate = isa(D);

6259 if (NeedInstantiate) {

6262 return cast(Inst);

6263 }

6264

6265

6266

6267 assert(isa(D));

6268

6270 assert(Inst && "Failed to instantiate label??");

6271

6273 return cast(Inst);

6274 }

6275

6277 if (Record->isDependentContext())

6278 return D;

6279

6280

6281

6286 dyn_cast(Record))

6287 ClassTemplate = Spec->getSpecializedTemplate()->getCanonicalDecl();

6288

6289

6290

6293

6294

6297

6298 if (CXXRecordDecl *InstRecord = dyn_cast(DC)) {

6299

6300

6302 = dyn_cast(InstRecord)){

6303 ClassTemplateDecl *SpecTemplate = InstSpec->getSpecializedTemplate();

6305 return InstRecord;

6306 }

6307

6308

6310 return InstRecord;

6311 }

6312

6313

6314 if (FunctionDecl *FD = dyn_cast(DC)) {

6318 continue;

6319 }

6320

6321

6322 auto *Guide = dyn_cast(FD);

6323 if (Guide && Guide->isImplicit()) {

6324 TemplateDecl *TD = Guide->getDeducedTemplate();

6325

6331 Unpacked = Arg.pack_elements();

6335 }

6337

6338

6339

6340

6341

6343 return nullptr;

6345

6346 if (!SubstRecord) {

6347

6348

6349

6350

6351

6355

6356

6357

6358 return nullptr;

6359 }

6360

6361

6362

6363

6364

6365 if (FindingInstantiatedContext &&

6367 Loc, cast(SubstRecord))) {

6368 Diag(Loc, diag::err_specialization_not_primary_template)

6371 return nullptr;

6372 }

6373 DC = SubstRecord;

6374 continue;

6375 }

6376 }

6377

6379 }

6380

6381

6382

6383 }

6384

6385 if (!ParentDependsOnArgs)

6386 return D;

6387

6389 if (!ParentDC)

6390 return nullptr;

6391

6393

6394

6395

6396

6397

6398

6399 bool IsBeingInstantiated = false;

6400 if (CXXRecordDecl *Spec = dyn_cast(ParentDC)) {

6401 if (!Spec->isDependentContext()) {

6404 assert(Tag && "type of non-dependent record is not a RecordType");

6405 if (Tag->isBeingDefined())

6406 IsBeingInstantiated = true;

6407 if (!Tag->isBeingDefined() &&

6409 return nullptr;

6410

6411 ParentDC = Tag->getDecl();

6412 }

6413 }

6414

6416

6417

6418 if (auto Name = D->getDeclName()) {

6422 Name = NewNameInfo.getName();

6423 if (!Name)

6424 return nullptr;

6426

6428 } else {

6429

6430

6431

6432

6433

6434

6435

6436

6440 }

6441

6443 if (isa(D)) {

6444

6446

6447

6448

6449

6450 } else if (IsBeingInstantiated) {

6451

6452

6453

6454

6455

6456 Diag(Loc, diag::err_member_not_yet_instantiated)

6457 << D->getDeclName()

6459 Diag(D->getLocation(), diag::note_non_instantiated_member_here);

6460 } else if (EnumConstantDecl *ED = dyn_cast(D)) {

6461

6462

6463

6464 EnumDecl *Enum = cast(ED->getLexicalDeclContext());

6466 TemplateArgs));

6469 Diag(Loc, diag::err_enumerator_does_not_exist)

6470 << D->getDeclName()

6472 Diag(Spec->getLocation(), diag::note_enum_specialized_here)

6474 } else {

6475

6476 llvm_unreachable("Unable to find instantiation of declaration!");

6477 }

6478 }

6479

6481 }

6482

6483 return D;

6484}

6485

6487 std::deque delayedPCHInstantiations;

6491

6495 } else {

6498 }

6499

6500

6502 bool DefinitionRequired = Function->getTemplateSpecializationKind() ==

6504 if (Function->isMultiVersion()) {

6508 DefinitionRequired, true);

6511 });

6512 } else {

6514 DefinitionRequired, true);

6516 Function->setInstantiationIsPending(false);

6517 }

6518

6519 if (!LocalOnly && LangOpts.PCHInstantiateTemplates &&

6521 delayedPCHInstantiations.push_back(Inst);

6522 continue;

6523 }

6524

6525

6526 VarDecl *Var = cast(Inst.first);

6527

6529 isa(Var)) &&

6530 "Not a static data member, nor a variable template"

6531 " specialization?");

6532

6533

6534

6536 continue;

6537

6538

6539

6543 llvm_unreachable("Cannot instantitiate an undeclared specialization.");

6546 continue;

6548

6549

6551 continue;

6552 break;

6554 break;

6555 }

6556

6558 "instantiating variable definition");

6561

6562

6563

6565 DefinitionRequired, true);

6566 }

6567

6568 if (!LocalOnly && LangOpts.PCHInstantiateTemplates)

6570}

6571

6574 for (auto *DD : Pattern->ddiags()) {

6575 switch (DD->getKind()) {

6578 break;

6579 }

6580 }

6581}

Defines the clang::ASTContext interface.

Defines the C++ template declaration subclasses.

Defines the clang::Expr interface and subclasses for C++ expressions.

llvm::MachO::Record Record

This file declares semantic analysis functions specific to AMDGPU.

This file declares semantic analysis for CUDA constructs.

This file declares semantic analysis for HLSL constructs.

This file declares semantic analysis for Objective-C.

This file declares semantic analysis for OpenMP constructs and clauses.

This file declares semantic analysis functions specific to Swift.

static void instantiateDependentAMDGPUWavesPerEUAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const AMDGPUWavesPerEUAttr &Attr, Decl *New)

static NamedDecl * findInstantiationOf(ASTContext &Ctx, NamedDecl *D, ForwardIterator first, ForwardIterator last)

static void instantiateDependentAMDGPUMaxNumWorkGroupsAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const AMDGPUMaxNumWorkGroupsAttr &Attr, Decl *New)

static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const AMDGPUFlatWorkGroupSizeAttr &Attr, Decl *New)

static void instantiateDependentDiagnoseIfAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const DiagnoseIfAttr *DIA, const Decl *Tmpl, FunctionDecl *New)

static QualType adjustFunctionTypeForInstantiation(ASTContext &Context, FunctionDecl *D, TypeSourceInfo *TInfo)

Adjust the given function type for an instantiation of the given declaration, to cope with modificati...

static bool isRelevantAttr(Sema &S, const Decl *D, const Attr *A)

Determine whether the attribute A might be relevant to the declaration D.

static bool isDependentContextAtLevel(DeclContext *DC, unsigned Level)

Determine whether the given context is dependent on template parameters at level Level or below.

static void instantiateDependentModeAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const ModeAttr &Attr, Decl *New)

static void instantiateDependentCUDALaunchBoundsAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const CUDALaunchBoundsAttr &Attr, Decl *New)

static bool isDeclWithinFunction(const Decl *D)

static void instantiateDependentAssumeAlignedAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const AssumeAlignedAttr *Aligned, Decl *New)

static bool SubstQualifier(Sema &SemaRef, const DeclT *OldDecl, DeclT *NewDecl, const MultiLevelTemplateArgumentList &TemplateArgs)

static void collectUnexpandedParameterPacks(Sema &S, TemplateParameterList *Params, SmallVectorImpl< UnexpandedParameterPack > &Unexpanded)

static DeclT * getPreviousDeclForInstantiation(DeclT *D)

Get the previous declaration of a declaration for the purposes of template instantiation.

static Expr * instantiateDependentFunctionAttrCondition(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const Attr *A, Expr *OldCond, const Decl *Tmpl, FunctionDecl *New)

static bool isInstantiationOf(ClassTemplateDecl *Pattern, ClassTemplateDecl *Instance)

static void instantiateDependentHLSLParamModifierAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const HLSLParamModifierAttr *Attr, Decl *New)

static void instantiateDependentAllocAlignAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const AllocAlignAttr *Align, Decl *New)

static bool isInstantiationOfStaticDataMember(VarDecl *Pattern, VarDecl *Instance)

static void instantiateOMPDeclareSimdDeclAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const OMPDeclareSimdDeclAttr &Attr, Decl *New)

Instantiation of 'declare simd' attribute and its arguments.

static void instantiateDependentSYCLKernelAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const SYCLKernelAttr &Attr, Decl *New)

static void instantiateDependentAlignValueAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const AlignValueAttr *Aligned, Decl *New)

static void instantiateDependentAlignedAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const AlignedAttr *Aligned, Decl *New, bool IsPackExpansion)

static void instantiateOMPDeclareVariantAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const OMPDeclareVariantAttr &Attr, Decl *New)

Instantiation of 'declare variant' attribute and its arguments.

static void instantiateDependentEnableIfAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const EnableIfAttr *EIA, const Decl *Tmpl, FunctionDecl *New)

static void instantiateDependentAnnotationAttr(Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const AnnotateAttr *Attr, Decl *New)

static Sema::RetainOwnershipKind attrToRetainOwnershipKind(const Attr *A)

static bool isInstantiationOfUnresolvedUsingDecl(T *Pattern, Decl *Other, ASTContext &Ctx)

static bool isInvalid(LocType Loc, bool *Invalid)

Defines the SourceManager interface.

Defines the clang::TypeLoc interface and its subclasses.

ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.

virtual bool HandleTopLevelDecl(DeclGroupRef D)

HandleTopLevelDecl - Handle the specified top-level declaration.

virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D)

HandleCXXStaticMemberVarInstantiation - Tell the consumer that this.

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

unsigned getManglingNumber(const NamedDecl *ND, bool ForAuxTarget=false) const

TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)

void setInstantiatedFromUsingDecl(NamedDecl *Inst, NamedDecl *Pattern)

Remember that the using decl Inst is an instantiation of the using decl Pattern of a class template.

QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified=false, bool AllowCXX=false, bool IsConditionalOperator=false)

NamedDecl * getInstantiatedFromUsingDecl(NamedDecl *Inst)

If the given using decl Inst is an instantiation of another (possibly unresolved) using decl,...

DeclarationNameTable DeclarationNames

QualType getTemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon=QualType()) const

QualType getRecordType(const RecordDecl *Decl) const

QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const

getInjectedClassNameType - Return the unique reference to the injected class name type for the specif...

CanQualType getCanonicalType(QualType T) const

Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...

bool hasSameType(QualType T1, QualType T2) const

Determine whether the given types T1 and T2 are equivalent.

void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst, UsingShadowDecl *Pattern)

unsigned getStaticLocalNumber(const VarDecl *VD) const

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

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

void forEachMultiversionedFunctionVersion(const FunctionDecl *FD, llvm::function_ref< void(FunctionDecl *)> Pred) const

Visits all versions of a multiversioned function with the passed predicate.

void setInstantiatedFromUsingEnumDecl(UsingEnumDecl *Inst, UsingEnumDecl *Pattern)

Remember that the using enum decl Inst is an instantiation of the using enum decl Pattern of a class ...

void setStaticLocalNumber(const VarDecl *VD, unsigned Number)

OMPTraitInfo & getNewOMPTraitInfo()

Return a new OMPTraitInfo object owned by this context.

TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const

Allocate a TypeSourceInfo where all locations have been initialized to a given location,...

void setManglingNumber(const NamedDecl *ND, unsigned Number)

void addDeclaratorForUnnamedTagDecl(TagDecl *TD, DeclaratorDecl *DD)

FieldDecl * getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) const

DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)

CanQualType UnsignedLongLongTy

QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const

Return a normal function type with a typed argument list.

QualType getPromotedIntegerType(QualType PromotableType) const

Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...

const TargetInfo & getTargetInfo() const

void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl)

bool isPromotableIntegerType(QualType T) const

More type predicates useful for type checking/promotion.

void addTypedefNameForUnnamedTagDecl(TagDecl *TD, TypedefNameDecl *TND)

An abstract interface that should be implemented by listeners that want to be notified when an AST en...

Represents an access specifier followed by colon ':'.

static AccessSpecDecl * Create(ASTContext &C, AccessSpecifier AS, DeclContext *DC, SourceLocation ASLoc, SourceLocation ColonLoc)

Attr - This represents one attribute.

attr::Kind getKind() const

Attr * clone(ASTContext &C) const

SourceLocation getLocation() const

SourceRange getRange() const

SourceLocation getLoc() const

Represents a C++ declaration that introduces decls from somewhere else.

A binding in a decomposition declaration.

static BindingDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id)

Represents the builtin template declaration which is used to implement __make_integer_seq and other b...

Represents a C++ constructor within a class.

bool isDefaultConstructor() const

Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...

static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited=InheritedConstructor(), Expr *TrailingRequiresClause=nullptr)

Represents a C++ conversion function within a class.

static CXXConversionDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause=nullptr)

Represents a C++ deduction guide declaration.

static CXXDeductionGuideDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor=nullptr, DeductionCandidate Kind=DeductionCandidate::Normal, Expr *TrailingRequiresClause=nullptr)

Represents a C++ destructor within a class.

static CXXDestructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause=nullptr)

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

const CXXRecordDecl * getParent() const

Return the parent of this method declaration, which is the class in which this method is defined.

bool isMoveAssignmentOperator() const

Determine whether this is a move assignment operator.

static CXXMethodDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin, bool isInline, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause=nullptr)

bool isCopyAssignmentOperator() const

Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...

Represents a C++ struct/union/class.

CXXRecordDecl * getDefinition() const

static CXXRecordDecl * CreateLambda(const ASTContext &C, DeclContext *DC, TypeSourceInfo *Info, SourceLocation Loc, unsigned DependencyKind, bool IsGeneric, LambdaCaptureDefault CaptureDefault)

static CXXRecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl=nullptr, bool DelayTypeCreation=false)

TemplateSpecializationKind getTemplateSpecializationKind() const

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

void setInstantiationOfMemberClass(CXXRecordDecl *RD, TemplateSpecializationKind TSK)

Specify that this record is an instantiation of the member class RD.

void setDescribedClassTemplate(ClassTemplateDecl *Template)

CXXRecordDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

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.

void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos)

Insert the specified partial specialization knowing that it is not already in.

ClassTemplateDecl * getMostRecentDecl()

CXXRecordDecl * getTemplatedDecl() const

Get the underlying class declarations of the template.

ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)

Return the partial specialization with the provided arguments if it exists, otherwise return the inse...

static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)

Create a class template node.

ClassTemplateDecl * getCanonicalDecl() override

Retrieves the canonical declaration of this template.

ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)

Find a class template partial specialization which was instantiated from the given member partial spe...

void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos)

Insert the specified specialization knowing that it is not already in.

void setCommonPtr(Common *C)

QualType getInjectedClassNameSpecialization()

Retrieve the template specialization type of the injected-class-name for this class template.

Common * getCommonPtr() const

ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)

Return the specialization with the provided arguments if it exists, otherwise return the insertion po...

void setInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *PartialSpec)

static ClassTemplatePartialSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl)

TemplateParameterList * getTemplateParameters() const

Get the list of template parameters.

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.

const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const

Retrieve the template argument list as written in the sources, if any.

SourceLocation getPointOfInstantiation() const

Get the point of instantiation (if any), or null if none.

void setExternKeywordLoc(SourceLocation Loc)

Sets the location of the extern keyword.

void setSpecializationKind(TemplateSpecializationKind TSK)

void setTemplateKeywordLoc(SourceLocation Loc)

Sets the location of the template keyword.

static ClassTemplateSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, ClassTemplateSpecializationDecl *PrevDecl)

void setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten)

Set the template argument list as written in the sources.

Declaration of a C++20 concept.

const TypeClass * getTypePtr() const

Represents a shadow constructor declaration introduced into a class by a C++11 using-declaration that...

A POD class for pairing a NamedDecl* with an access specifier.

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

DeclContext * getParent()

getParent - Returns the containing DeclContext.

bool Equals(const DeclContext *DC) const

Determine whether this declaration context is equivalent to the declaration context DC.

bool isFileContext() const

void makeDeclVisibleInContext(NamedDecl *D)

Makes a declaration visible within this context.

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.

DeclContext * getRedeclContext()

getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...

void addDecl(Decl *D)

Add the declaration D into this context.

decl_iterator decls_end() const

ddiag_range ddiags() const

decl_range decls() const

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

bool isFunctionOrMethod() const

void addHiddenDecl(Decl *D)

Add the declaration D to this context without modifying any lookup tables.

decl_iterator decls_begin() const

static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)

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

Decl * getPreviousDecl()

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

SourceLocation getEndLoc() const LLVM_READONLY

FriendObjectKind getFriendObjectKind() const

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

bool isImplicit() const

isImplicit - Indicates whether the declaration was implicitly generated by the implementation.

void setLocalExternDecl()

Changes the namespace of this declaration to reflect that it's a function-local extern declaration.

virtual bool isOutOfLine() const

Determine whether this declaration is declared out of line (outside its semantic context).

bool isParameterPack() const

Whether this declaration is a parameter pack.

void setInvalidDecl(bool Invalid=true)

setInvalidDecl - Indicates the Decl had a semantic error.

bool isInIdentifierNamespace(unsigned NS) const

@ FOK_None

Not a friend object.

bool isReferenced() const

Whether any declaration of this entity was referenced.

unsigned getTemplateDepth() const

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

void setObjectOfFriendDecl(bool PerformFriendInjection=false)

Changes the namespace of this declaration to reflect that it's the object of a friend declaration.

bool isFromASTFile() const

Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...

bool isInLocalScopeForInstantiation() const

Determine whether a substitution into this declaration would occur as part of a substitution into a d...

DeclContext * getNonTransparentDeclContext()

Return the non transparent context.

virtual bool hasBody() const

Returns true if this Decl represents a declaration for a body of code, such as a function or method d...

bool isInvalidDecl() const

bool isLocalExternDecl() const

Determine whether this is a block-scope declaration with linkage.

llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const

void setAccess(AccessSpecifier AS)

SourceLocation getLocation() const

const char * getDeclKindName() const

@ IDNS_Ordinary

Ordinary names.

void setImplicit(bool I=true)

void setReferenced(bool R=true)

void setIsUsed()

Set whether the declaration is used, in the sense of odr-use.

bool isUsed(bool CheckUsedAttr=true) const

Whether any (re-)declaration of the entity was used, meaning that a definition is required.

DeclContext * getDeclContext()

AccessSpecifier getAccess() const

SourceLocation getBeginLoc() const LLVM_READONLY

DeclContext * getLexicalDeclContext()

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

void setNonMemberOperator()

Specifies that this declaration is a C++ overloaded non-member.

void setLexicalDeclContext(DeclContext *DC)

virtual Decl * getCanonicalDecl()

Retrieves the "canonical" declaration of the given declaration.

virtual SourceRange getSourceRange() const LLVM_READONLY

Source range that this declaration covers.

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.

NameKind getNameKind() const

Determine what kind of name this is.

Represents a ValueDecl that came out of a declarator.

SourceLocation getInnerLocStart() const

Return start of source range ignoring outer template declarations.

SourceLocation getTypeSpecStartLoc() const

SourceLocation getBeginLoc() const LLVM_READONLY

void setTypeSourceInfo(TypeSourceInfo *TI)

void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc)

TypeSourceInfo * getTypeSourceInfo() const

void setTemplateParameterListsInfo(ASTContext &Context, ArrayRef< TemplateParameterList * > TPLists)

Represents the type decltype(expr) (C++11).

Expr * getUnderlyingExpr() const

A decomposition declaration.

static DecompositionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation LSquareLoc, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< BindingDecl * > Bindings)

Provides information about a dependent function-template specialization declaration.

Represents a qualified type name for which the type name is dependent.

unsigned getCustomDiagID(Level L, const char(&FormatString)[N])

Return an ID for a diagnostic with the specified format string and level.

bool hasErrorOccurred() const

RAII object that enters a new expression evaluation context.

An instance of this object exists for each enum constant that is defined.

enumerator_range enumerators() const

bool isScoped() const

Returns true if this is a C++11 scoped enumeration.

static EnumDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl, bool IsScoped, bool IsScopedUsingClassTag, bool IsFixed)

TypeSourceInfo * getIntegerTypeSourceInfo() const

Return the type source info for the underlying integer type, if no type source info exists,...

EnumDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

TemplateSpecializationKind getTemplateSpecializationKind() const

If this enumeration is a member of a specialization of a templated class, determine what kind of temp...

Store information needed for an explicit specifier.

ExplicitSpecKind getKind() const

bool isInvalid() const

Determine if the explicit specifier is invalid.

static ExplicitSpecifier Invalid()

const Expr * getExpr() const

void setKind(ExplicitSpecKind Kind)

static ExplicitSpecifier getFromDecl(FunctionDecl *Function)

This represents one expression.

static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)

isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...

bool isValueDependent() const

Determines whether the value of this expression depends on.

bool isTypeDependent() const

Determines whether the type of this expression depends on.

Expr * IgnoreParenImpCasts() LLVM_READONLY

Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...

bool isConstantInitializer(ASTContext &Ctx, bool ForRef, const Expr **Culprit=nullptr) const

isConstantInitializer - Returns true if this expression can be emitted to IR as a constant,...

Declaration context for names declared as extern "C" in C++.

Represents difference between two FPOptions values.

Represents a member of a struct/union/class.

FriendDecl - Represents the declaration of a friend entity, which can be a function,...

static FriendDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, SourceLocation FriendL, SourceLocation EllipsisLoc={}, ArrayRef< TemplateParameterList * > FriendTypeTPLists={})

void setUnsupportedFriend(bool Unsupported)

Declaration of a friend template.

static DefaultedOrDeletedFunctionInfo * Create(ASTContext &Context, ArrayRef< DeclAccessPair > Lookups, StringLiteral *DeletedMessage=nullptr)

Represents a function declaration or definition.

void setInstantiationIsPending(bool IC)

State that the instantiation of this function is pending.

const ParmVarDecl * getParamDecl(unsigned i) const

Stmt * getBody(const FunctionDecl *&Definition) const

Retrieve the body (definition) of the function.

void setDescribedFunctionTemplate(FunctionTemplateDecl *Template)

FunctionTemplateDecl * getDescribedFunctionTemplate() const

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

bool isThisDeclarationADefinition() const

Returns whether this specific declaration of the function is also a definition that does not contain ...

void setDefaultedOrDeletedInfo(DefaultedOrDeletedFunctionInfo *Info)

bool isInlined() const

Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...

void setInstantiationOfMemberFunction(FunctionDecl *FD, TemplateSpecializationKind TSK)

Specify that this record is an instantiation of the member function FD.

QualType getReturnType() const

FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const

Retrieve the function declaration from which this function could be instantiated, if it is an instant...

FunctionDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

bool isLateTemplateParsed() const

Whether this templated function will be late parsed.

void setVirtualAsWritten(bool V)

State that this function is marked as virtual explicitly.

bool hasSkippedBody() const

True if the function was a definition but its body was skipped.

FunctionDecl * getDefinition()

Get the definition for this declaration.

void setImplicitlyInline(bool I=true)

Flag that this function is implicitly inline.

static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, Expr *TrailingRequiresClause=nullptr)

bool isThisDeclarationInstantiatedFromAFriendDefinition() const

Determine whether this specific declaration of the function is a friend declaration that was instanti...

void setRangeEnd(SourceLocation E)

bool isDefaulted() const

Whether this function is defaulted.

void setIneligibleOrNotSelected(bool II)

bool isVirtualAsWritten() const

Whether this function is marked as virtual explicitly.

void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, TemplateArgumentList *TemplateArgs, void *InsertPos, TemplateSpecializationKind TSK=TSK_ImplicitInstantiation, TemplateArgumentListInfo *TemplateArgsAsWritten=nullptr, SourceLocation PointOfInstantiation=SourceLocation())

Specify that this function declaration is actually a function template specialization.

unsigned getNumParams() const

Return the number of parameters this function must have based on its FunctionType.

DeclarationNameInfo getNameInfo() const

bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const

Returns true if the function has a definition that does not need to be instantiated.

DefaultedOrDeletedFunctionInfo * getDefalutedOrDeletedInfo() const

void setParams(ArrayRef< ParmVarDecl * > NewParamInfo)

bool willHaveBody() const

True if this function will eventually have a body, once it's fully parsed.

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

ExceptionSpecificationType getExceptionSpecType() const

Get the kind of exception specification on this function.

QualType getParamType(unsigned i) const

bool hasExceptionSpec() const

Return whether this function has any kind of exception spec.

ExtProtoInfo getExtProtoInfo() const

FunctionDecl * getExceptionSpecTemplate() const

If this function type has an uninstantiated exception specification, this is the function whose excep...

ArrayRef< QualType > getParamTypes() const

Declaration of a template function.

FunctionTemplateDecl * getCanonicalDecl() override

Retrieves the canonical declaration of this template.

FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)

Return the specialization with the provided arguments if it exists, otherwise return the insertion po...

FunctionDecl * getTemplatedDecl() const

Get the underlying function declaration of the template.

FunctionTemplateDecl * getInstantiatedFromMemberTemplate() const

FunctionTemplateDecl * getPreviousDecl()

Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...

static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)

Create a function template node.

ParmVarDecl * getParam(unsigned i) const

void setParam(unsigned i, ParmVarDecl *VD)

ExtInfo getExtInfo() const

bool getNoReturnAttr() const

Determine whether this function type includes the GNU noreturn attribute.

QualType getReturnType() const

HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.

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

bool isStr(const char(&Str)[StrLen]) const

Return true if this is the identifier for the specified string.

Represents a field injected from an anonymous union/struct into the parent scope.

static IndirectFieldDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, QualType T, llvm::MutableArrayRef< NamedDecl * > CH)

Description of a constructor that was inherited from a base class.

const TypeClass * getTypePtr() const

static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)

Returns a new integer literal with value 'V' and type 'type'.

Represents the declaration of a label.

static LabelDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II)

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

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

LocalInstantiationScope * cloneScopes(LocalInstantiationScope *Outermost)

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

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

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

Represents the results of name lookup.

An instance of this class represents the declaration of a property member.

static MSPropertyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL, IdentifierInfo *Getter, IdentifierInfo *Setter)

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

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

const ArgList & getInnermost() const

Retrieve the innermost template argument list.

void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final)

Add a new outmost level to the multi-level template argument list.

unsigned getNumLevels() const

Determine the number of levels in this template argument list.

void setKind(TemplateSubstitutionKind K)

unsigned getNumSubstitutedLevels() const

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

void addOuterRetainedLevels(unsigned Num)

unsigned getNumRetainedOuterLevels() const

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

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

DeclarationName getDeclName() const

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

bool hasLinkage() const

Determine whether this declaration has linkage.

void setDeclName(DeclarationName N)

Set the name of this declaration.

Represents a C++ namespace alias.

static NamespaceAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation NamespaceLoc, SourceLocation AliasLoc, IdentifierInfo *Alias, NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc, NamedDecl *Namespace)

Represent a C++ namespace.

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

bool hasQualifier() const

Evaluates true when this nested-name-specifier location is non-empty.

SourceRange getSourceRange() const LLVM_READONLY

Retrieve the source range covering the entirety of this nested-name-specifier.

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

static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)

void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)

Set the default argument for this template parameter, and whether that default argument was inherited...

This represents '#pragma omp allocate ...' directive.

Pseudo declaration for capturing expressions.

This is a basic class for representing single OpenMP clause.

This represents '#pragma omp declare mapper ...' directive.

This represents '#pragma omp declare reduction ...' directive.

This represents '#pragma omp requires...' directive.

This represents '#pragma omp threadprivate ...' directive.

Helper data structure representing the traits in a match clause of an declare variant or metadirectiv...

bool anyScoreOrCondition(llvm::function_ref< bool(Expr *&, bool)> Cond)

Represents a field declaration created by an @defs(...).

Wrapper for void* pointer.

static OpaquePtr make(QualType P)

SourceLocation getEllipsisLoc() const

TypeLoc getPatternLoc() const

Represents a pack expansion of types.

std::optional< unsigned > getNumExpansions() const

Retrieve the number of expansions that this pack expansion will generate, if known.

Represents a parameter to a function.

bool hasUninstantiatedDefaultArg() const

Represents a #pragma detect_mismatch line.

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

A (possibly-)qualified type.

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.

Represents a struct/union/class.

Wrapper for source info for record types.

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

void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD)

decl_type * getFirstDecl()

Return the first declaration of this declaration or itself if this is the only declaration.

decl_type * getPreviousDecl()

Return the previous declaration of this declaration or NULL if this is the first declaration.

decl_type * getMostRecentDecl()

Returns the most recent (re)declaration of this declaration.

void setPreviousDecl(decl_type *PrevDecl)

Set the previous declaration.

Represents the body of a requires-expression.

static RequiresExprBodyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc)

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

void addAMDGPUFlatWorkGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI, Expr *Min, Expr *Max)

addAMDGPUFlatWorkGroupSizeAttr - Adds an amdgpu_flat_work_group_size attribute to a particular declar...

void addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, Expr *Min, Expr *Max)

addAMDGPUWavePersEUAttr - Adds an amdgpu_waves_per_eu attribute to a particular declaration.

void addAMDGPUMaxNumWorkGroupsAttr(Decl *D, const AttributeCommonInfo &CI, Expr *XExpr, Expr *YExpr, Expr *ZExpr)

addAMDGPUMaxNumWorkGroupsAttr - Adds an amdgpu_max_num_work_groups attribute to a particular declarat...

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

Emit a diagnostic.

void checkAllowedInitializer(VarDecl *VD)

QualType getInoutParameterType(QualType Ty)

bool inferObjCARCLifetime(ValueDecl *decl)

void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI, Sema::RetainOwnershipKind K, bool IsTemplateInstantiation)

DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)

Called at the end of '#pragma omp declare reduction'.

void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)

Finish current declare reduction construct initializer.

ExprResult ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, SourceLocation StartLoc, DeclarationName VN)

Build the mapper variable of '#pragma omp declare mapper'.

VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)

Initialize declare reduction construct initializer.

QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)

Check if the specified type is allowed to be used in 'omp declare reduction' construct.

DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList, ArrayRef< OMPClause * > Clauses, DeclContext *Owner=nullptr)

Called on well-formed '#pragma omp allocate'.

DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation > > ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)

Called on start of '#pragma omp declare reduction'.

OMPClause * ActOnOpenMPAllocatorClause(Expr *Allocator, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)

Called on well-formed 'allocator' clause.

void EndOpenMPDSABlock(Stmt *CurDirective)

Called on end of data sharing attribute block.

QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, TypeResult ParsedType)

Check if the specified type is allowed to be used in 'omp declare mapper' construct.

std::optional< std::pair< FunctionDecl *, Expr * > > checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, OMPTraitInfo &TI, unsigned NumAppendArgs, SourceRange SR)

Checks '#pragma omp declare variant' variant function and original functions after parsing of the ass...

void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)

Initialize declare reduction construct initializer.

OMPClause * ActOnOpenMPMapClause(Expr *IteratorModifier, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, bool NoDiagnose=false, ArrayRef< Expr * > UnresolvedMappers={})

Called on well-formed 'map' clause.

void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)

Called on start of new data sharing attribute block.

OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr * > VarList)

Builds a new OpenMPThreadPrivateDecl and checks its correctness.

void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, ArrayRef< Expr * > AdjustArgsNothing, ArrayRef< Expr * > AdjustArgsNeedDevicePtr, ArrayRef< OMPInteropInfo > AppendArgs, SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, SourceRange SR)

Called on well-formed '#pragma omp declare variant' after parsing of the associated method/function.

void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)

Finish current declare reduction construct initializer.

DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr * > Uniforms, ArrayRef< Expr * > Aligneds, ArrayRef< Expr * > Alignments, ArrayRef< Expr * > Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr * > Steps, SourceRange SR)

Called on well-formed '#pragma omp declare simd' after parsing of the associated method/function.

OMPClause * ActOnOpenMPAlignClause(Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)

Called on well-formed 'align' clause.

DeclGroupPtrTy ActOnOpenMPDeclareMapperDirective(Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, Expr *MapperVarRef, ArrayRef< OMPClause * > Clauses, Decl *PrevDeclInScope=nullptr)

Called on start of '#pragma omp declare mapper'.

void AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI, ParameterABI abi)

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

CXXSpecialMemberKind asSpecialMember() const

A helper class for building up ExtParameterInfos.

Records and restores the CurFPFeatures state on entry/exit of compound statements.

RAII class used to indicate that we are performing provisional semantic analysis to determine the val...

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

MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init, CXXRecordDecl *ClassDecl)

VarTemplateSpecializationDecl * BuildVarTemplateInstantiation(VarTemplateDecl *VarTemplate, VarDecl *FromVar, const TemplateArgumentList *PartialSpecArgs, const TemplateArgumentListInfo &TemplateArgsInfo, SmallVectorImpl< TemplateArgument > &Converted, SourceLocation PointOfInstantiation, LateInstantiatedAttrVec *LateAttrs=nullptr, LocalInstantiationScope *StartingScope=nullptr)

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.

bool CheckUsingDeclQualifier(SourceLocation UsingLoc, bool HasTypename, const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, SourceLocation NameLoc, const LookupResult *R=nullptr, const UsingDecl *UD=nullptr)

Checks that the given nested-name qualifier used in a using decl in the current context is appropriat...

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

@ LookupOrdinaryName

Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....

@ LookupUsingDeclName

Look up all declarations in a scope with the given name, including resolved using declarations.

@ LookupRedeclarationWithLinkage

Look up an ordinary name that is going to be redeclared as a name with linkage.

Decl * ActOnSkippedFunctionBody(Decl *Decl)

Decl * BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *AssertMessageExpr, SourceLocation RParenLoc, bool Failed)

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)

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

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

MemInitResult BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, Expr *Init, CXXRecordDecl *ClassDecl, SourceLocation EllipsisLoc)

bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD, ParmVarDecl *Param)

void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E, bool IsPackExpansion)

AddAlignedAttr - Adds an aligned attribute to a particular declaration.

AccessResult CheckFriendAccess(NamedDecl *D)

Checks access to the target of a friend declaration.

const TranslationUnitKind TUKind

The kind of translation unit we are processing.

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 InstantiateExceptionSpec(SourceLocation PointOfInstantiation, FunctionDecl *Function)

void AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E, Expr *OE)

AddAssumeAlignedAttr - Adds an assume_aligned attribute to a particular declaration.

bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC)

Require that the context specified by SS be complete.

bool TemplateParameterListsAreEqual(const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc=SourceLocation())

Determine whether the given template parameter lists are equivalent.

void CheckOverrideControl(NamedDecl *D)

CheckOverrideControl - Check C++11 override control semantics.

const ExpressionEvaluationContextRecord & currentEvaluationContext() const

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

Specializations whose definitions are currently being instantiated.

void deduceOpenCLAddressSpace(ValueDecl *decl)

PragmaStack< FPOptionsOverride > FpPragmaStack

FunctionDecl * InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, const TemplateArgumentList *Args, SourceLocation Loc, CodeSynthesisContext::SynthesisKind CSC=CodeSynthesisContext::ExplicitTemplateArgumentSubstitution)

Instantiate (or find existing instantiation of) a function template with a given set of template argu...

bool tryResolveExplicitSpecifier(ExplicitSpecifier &ExplicitSpec)

tryResolveExplicitSpecifier - Attempt to resolve the explict specifier.

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

MemInitResult BuildMemberInitializer(ValueDecl *Member, Expr *Init, SourceLocation IdLoc)

UsingShadowDecl * BuildUsingShadowDecl(Scope *S, BaseUsingDecl *BUD, NamedDecl *Target, UsingShadowDecl *PrevDecl)

Builds a shadow declaration corresponding to a 'using' declaration.

void CheckThreadLocalForLargeAlignment(VarDecl *VD)

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

ExpressionEvaluationContextRecord & parentEvaluationContext()

LateParsedTemplateMapT LateParsedTemplateMap

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

void CheckTemplatePartialSpecialization(ClassTemplatePartialSpecializationDecl *Partial)

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

ParmVarDecl * BuildParmVarDeclForTypedef(DeclContext *DC, SourceLocation Loc, QualType T)

Synthesizes a variable for a parameter arising from a typedef.

bool CheckTemplatePartialSpecializationArgs(SourceLocation Loc, TemplateDecl *PrimaryTemplate, unsigned NumExplicitArgs, ArrayRef< TemplateArgument > Args)

Check the non-type template arguments of a class template partial specialization according to C++ [te...

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.

DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)

void InstantiateMemInitializers(CXXConstructorDecl *New, const CXXConstructorDecl *Tmpl, const MultiLevelTemplateArgumentList &TemplateArgs)

void CleanupVarDeclMarking()

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 inferGslPointerAttribute(NamedDecl *ND, CXXRecordDecl *UnderlyingRecord)

Add gsl::Pointer attribute to std:🫙:iterator.

NamedDecl * BuildUsingDeclaration(Scope *S, AccessSpecifier AS, SourceLocation UsingLoc, bool HasTypenameKeyword, SourceLocation TypenameLoc, CXXScopeSpec &SS, DeclarationNameInfo NameInfo, SourceLocation EllipsisLoc, const ParsedAttributesView &AttrList, bool IsInstantiation, bool IsUsingIfExists)

Builds a using declaration.

PrintingPolicy getPrintingPolicy() const

Retrieve a suitable printing policy for diagnostics.

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

void HandleDependentAccessCheck(const DependentDiagnostic &DD, const MultiLevelTemplateArgumentList &TemplateArgs)

@ TPL_TemplateMatch

We are matching the template parameter lists of two templates that might be redeclarations.

bool CheckFunctionTemplateSpecialization(FunctionDecl *FD, TemplateArgumentListInfo *ExplicitTemplateArgs, LookupResult &Previous, bool QualifiedFriend=false)

Perform semantic analysis for the given function template specialization.

void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc)

NamedReturnInfo getNamedReturnInfo(Expr *&E, SimplerImplicitMoveMode Mode=SimplerImplicitMoveMode::Normal)

Determine whether the given expression might be move-eligible or copy-elidable in either a (co_)retur...

bool CheckEnumUnderlyingType(TypeSourceInfo *TI)

Check that this is a valid underlying type for an enum declaration.

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 AddModeAttr(Decl *D, const AttributeCommonInfo &CI, IdentifierInfo *Name, bool InInstantiation=false)

AddModeAttr - Adds a mode attribute to a particular declaration.

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

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

const LangOptions & LangOpts

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 PerformPendingInstantiations(bool LocalOnly=false)

Performs template instantiation for all implicit template instantiations we have seen until this poin...

Decl * ActOnStartOfFunctionDef(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, SkipBodyInfo *SkipBody=nullptr, FnBodyKind BodyKind=FnBodyKind::Other)

VarTemplateSpecializationDecl * CompleteVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl, const MultiLevelTemplateArgumentList &TemplateArgs)

Instantiates a variable template specialization by completing it with appropriate type information an...

bool CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, LookupResult &Previous, bool IsMemberSpecialization, bool DeclIsDefn)

Perform semantic checking of a new function declaration.

FieldDecl * CheckFieldDecl(DeclarationName Name, QualType T, TypeSourceInfo *TInfo, RecordDecl *Record, SourceLocation Loc, bool Mutable, Expr *BitfieldWidth, InClassInitStyle InitStyle, SourceLocation TSSL, AccessSpecifier AS, NamedDecl *PrevDecl, Declarator *D=nullptr)

Build a new FieldDecl and check its well-formedness.

void updateAttrsForLateParsedTemplate(const Decl *Pattern, Decl *Inst)

Update instantiation attributes after template was late parsed.

bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange)

Mark the given method pure.

void InstantiateVariableInitializer(VarDecl *Var, VarDecl *OldVar, const MultiLevelTemplateArgumentList &TemplateArgs)

Instantiate the initializer of a variable.

SmallVector< PendingImplicitInstantiation, 1 > LateParsedInstantiations

Queue of implicit template instantiations that cannot be performed eagerly.

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

Do template substitution on declaration name info.

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

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

const VarDecl * getCopyElisionCandidate(NamedReturnInfo &Info, QualType ReturnType)

Updates given NamedReturnInfo's move-eligible and copy-elidable statuses, considering the function re...

bool RequireCompleteEnumDecl(EnumDecl *D, SourceLocation L, CXXScopeSpec *SS=nullptr)

Require that the EnumDecl is completed with its enumerators defined or instantiated.

void AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI, Expr *ParamExpr)

AddAllocAlignAttr - Adds an alloc_align attribute to a particular declaration.

bool usesPartialOrExplicitSpecialization(SourceLocation Loc, ClassTemplateSpecializationDecl *ClassTemplateSpec)

std::optional< unsigned > getNumArgumentsInExpansion(QualType T, const MultiLevelTemplateArgumentList &TemplateArgs)

Determine the number of arguments in the given pack expansion type.

ExplicitSpecifier instantiateExplicitSpecifier(const MultiLevelTemplateArgumentList &TemplateArgs, ExplicitSpecifier ES)

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

bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous)

Perform semantic checking on a newly-created variable declaration.

int ArgumentPackSubstitutionIndex

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

bool CheckUsingShadowDecl(BaseUsingDecl *BUD, NamedDecl *Target, const LookupResult &PreviousDecls, UsingShadowDecl *&PrevShadow)

Determines whether to create a using shadow decl for a particular decl, given the set of decls existi...

sema::BlockScopeInfo * getCurBlock()

Retrieve the current block, if any.

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

void CompleteMemberSpecialization(NamedDecl *Member, LookupResult &Previous)

ExprResult PerformContextuallyConvertToBool(Expr *From)

PerformContextuallyConvertToBool - Perform a contextual conversion of the expression From to bool (C+...

void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T)

Mark all of the declarations referenced within a particular AST node as referenced.

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

SourceManager & getSourceManager() const

FunctionDecl * SubstSpaceshipAsEqualEqual(CXXRecordDecl *RD, FunctionDecl *Spaceship)

Substitute the name and return type of a defaulted 'operator<=>' to form an implicit 'operator=='.

void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, Decl *EnumDecl, ArrayRef< Decl * > Elements, Scope *S, const ParsedAttributesView &Attr)

Decl * SubstDecl(Decl *D, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs)

DeclContext * computeDeclContext(QualType T)

Compute the DeclContext that is associated with the given type.

QualType CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, SourceLocation Loc)

Check that the type of a non-type template parameter is well-formed.

QualType CheckTemplateIdType(TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs)

Decl * ActOnFinishFunctionBody(Decl *Decl, Stmt *Body)

void ActOnMemInitializers(Decl *ConstructorDecl, SourceLocation ColonLoc, ArrayRef< CXXCtorInitializer * > MemInits, bool AnyErrors)

ActOnMemInitializers - Handle the member initializers for a constructor.

TemplateParameterList * SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs, bool EvaluateConstraints=true)

void AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI, Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks)

AddLaunchBoundsAttr - Adds a launch_bounds attribute to a particular declaration.

void AdjustDestructorExceptionSpec(CXXDestructorDecl *Destructor)

Build an exception spec for destructors that don't have one.

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.

void InstantiateDefaultCtorDefaultArgs(CXXConstructorDecl *Ctor)

In the MS ABI, we need to instantiate default arguments of dllexported default constructors along wit...

RedeclarationKind forRedeclarationInCurContext() const

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 CheckUsingDeclRedeclaration(SourceLocation UsingLoc, bool HasTypenameKeyword, const CXXScopeSpec &SS, SourceLocation NameLoc, const LookupResult &Previous)

Checks that the given using declaration is not an invalid redeclaration.

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

Substitute the given template arguments into the default argument.

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

EnumConstantDecl * CheckEnumConstant(EnumDecl *Enum, EnumConstantDecl *LastEnumConst, SourceLocation IdLoc, IdentifierInfo *Id, Expr *val)

void DiagnoseUnusedNestedTypedefs(const RecordDecl *D)

bool hasUncompilableErrorOccurred() const

Whether uncompilable error has occurred.

std::deque< PendingImplicitInstantiation > PendingInstantiations

The queue of implicit template instantiations that are required but have not yet been performed.

bool CheckInheritingConstructorUsingDecl(UsingDecl *UD)

Additional checks for a using declaration referring to a constructor name.

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

@ Unevaluated

The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...

void CheckStaticLocalForDllExport(VarDecl *VD)

Check if VD needs to be dllexport/dllimport due to being in a dllexport/import function.

NestedNameSpecifierLoc SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const MultiLevelTemplateArgumentList &TemplateArgs)

bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)

Ensure that the type T is a complete type.

LateTemplateParserCB * LateTemplateParser

bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)

Perform qualified name lookup into a given context.

bool CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, const DefaultArguments &DefaultArgs, bool PartialTemplateArgs, SmallVectorImpl< TemplateArgument > &SugaredConverted, SmallVectorImpl< TemplateArgument > &CanonicalConverted, bool UpdateArgsWithConversions=true, bool *ConstraintsNotSatisfied=nullptr, bool PartialOrderingTTP=false)

Check that the given template arguments can be provided to the given template, converting the argumen...

bool RebuildingImmediateInvocation

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

SourceManager & SourceMgr

bool CheckAlignasTypeArgument(StringRef KWName, TypeSourceInfo *TInfo, SourceLocation OpLoc, SourceRange R)

NamedDecl * BuildUsingPackDecl(NamedDecl *InstantiatedFrom, ArrayRef< NamedDecl * > Expansions)

void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc, StringLiteral *Message=nullptr)

NamespaceDecl * getStdNamespace() const

static bool adjustContextForLocalExternDecl(DeclContext *&DC)

Adjust the DeclContext for a function or variable that might be a function-local external declaration...

Attr * CreateAnnotationAttr(const AttributeCommonInfo &CI, StringRef Annot, MutableArrayRef< Expr * > Args)

CreateAnnotationAttr - Creates an annotation Annot with Args arguments.

@ TPC_FriendFunctionTemplate

@ TPC_FriendFunctionTemplateDefinition

void DiagnoseUnusedDecl(const NamedDecl *ND)

void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, bool ConsiderLinkage, bool AllowInlineNamespace)

Filters out lookup results that don't fall within the given scope as determined by isDeclInScope.

void ActOnUninitializedDecl(Decl *dcl)

void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)

AddInitializerToDecl - Adds the initializer Init to the declaration dcl.

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

Run some code with "sufficient" stack space.

void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)

Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...

void BuildVariableInstantiation(VarDecl *NewVar, VarDecl *OldVar, const MultiLevelTemplateArgumentList &TemplateArgs, LateInstantiatedAttrVec *LateAttrs, DeclContext *Owner, LocalInstantiationScope *StartingScope, bool InstantiatingVarTemplate=false, VarTemplateSpecializationDecl *PrevVTSD=nullptr)

BuildVariableInstantiation - Used after a new variable has been created.

bool CheckTemplateParameterList(TemplateParameterList *NewParams, TemplateParameterList *OldParams, TemplateParamListContext TPC, SkipBodyInfo *SkipBody=nullptr)

Checks the validity of a template parameter list, possibly considering the template parameter list fr...

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

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

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

void CheckAlignasUnderalignment(Decl *D)

std::pair< ValueDecl *, SourceLocation > PendingImplicitInstantiation

An entity for which implicit template instantiation is required.

DeclContext * FindInstantiatedContext(SourceLocation Loc, DeclContext *DC, const MultiLevelTemplateArgumentList &TemplateArgs)

Finds the instantiation of the given declaration context within the current instantiation.

bool isIncompatibleTypedef(const TypeDecl *Old, TypedefNameDecl *New)

void AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E)

AddAlignValueAttr - Adds an align_value attribute to a particular declaration.

ArrayRef< sema::FunctionScopeInfo * > getFunctionScopes() const

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

bool checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI, const Expr *E, StringRef &Str, SourceLocation *ArgLocation=nullptr)

Check if the argument E is a ASCII string literal.

bool CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, QualType EnumUnderlyingTy, bool IsFixed, const EnumDecl *Prev)

Check whether this is a valid redeclaration of a previous enumeration.

bool CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, ParmVarDecl *Param, Expr *Init=nullptr, bool SkipImmediateInvocations=true)

Instantiate or parse a C++ default argument expression as necessary.

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.

Encodes a location in the source.

bool isInSystemHeader(SourceLocation Loc) const

Returns if a SourceLocation is in a system header.

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.

SourceLocation getEnd() const

Represents a C++11 static_assert declaration.

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

SourceLocation getBeginLoc() const LLVM_READONLY

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

NestedNameSpecifierLoc getQualifierLoc() const

Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...

TypedefNameDecl * getTypedefNameForAnonDecl() const

void setTypedefNameForAnonDecl(TypedefNameDecl *TDD)

void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc)

bool hasNameForLinkage() const

Is this tag type named, either directly or via being defined in a typedef of this type?

TagKind getTagKind() const

bool isMicrosoft() const

Is this ABI an MSVC-compatible ABI?

TargetCXXABI getCXXABI() const

Get the C++ ABI currently in use.

A convenient class for passing around template argument information.

void setLAngleLoc(SourceLocation Loc)

void setRAngleLoc(SourceLocation Loc)

void addArgument(const TemplateArgumentLoc &Loc)

A template argument list.

static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)

Create a new template argument list that copies the given set of template arguments.

ArrayRef< TemplateArgument > asArray() const

Produce this as an array ref.

Location wrapper for a TemplateArgument.

Represents a template argument.

@ Pack

The template argument is actually a parameter pack.

@ RewriteSpaceshipAsEqualEqual

void setEvaluateConstraints(bool B)

Decl * VisitDecl(Decl *D)

Decl * VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate, ArrayRef< BindingDecl * > *Bindings=nullptr)

bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl)

Initializes common fields of an instantiated method declaration (New) from the corresponding fields o...

bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl)

Initializes the common fields of an instantiation function declaration (New) from the corresponding f...

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

Instantiate the declaration of a variable template partial specialization.

void adjustForRewrite(RewriteKind RK, FunctionDecl *Orig, QualType &T, TypeSourceInfo *&TInfo, DeclarationNameInfo &NameInfo)

TypeSourceInfo * SubstFunctionType(FunctionDecl *D, SmallVectorImpl< ParmVarDecl * > &Params)

Decl * VisitVarTemplateSpecializationDecl(VarTemplateDecl *VarTemplate, VarDecl *FromVar, const TemplateArgumentListInfo &TemplateArgsInfo, ArrayRef< TemplateArgument > Converted, VarTemplateSpecializationDecl *PrevDecl=nullptr)

void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern)

Decl * VisitFunctionDecl(FunctionDecl *D, TemplateParameterList *TemplateParams, RewriteKind RK=RewriteKind::None)

Normal class members are of more specific types and therefore don't make it here.

Decl * VisitCXXMethodDecl(CXXMethodDecl *D, TemplateParameterList *TemplateParams, RewriteKind RK=RewriteKind::None)

Decl * InstantiateTypeAliasTemplateDecl(TypeAliasTemplateDecl *D)

Decl * VisitBaseUsingDecls(BaseUsingDecl *D, BaseUsingDecl *Inst, LookupResult *Lookup)

bool SubstQualifier(const DeclaratorDecl *OldDecl, DeclaratorDecl *NewDecl)

TemplateParameterList * SubstTemplateParams(TemplateParameterList *List)

Instantiates a nested template parameter list in the current instantiation context.

Decl * InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias)

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

Instantiate the declaration of a class template partial specialization.

bool SubstDefaultedFunction(FunctionDecl *New, FunctionDecl *Tmpl)

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.

bool isNull() const

Determine whether this template name is NULL.

A template parameter object.

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

SourceRange getSourceRange() const LLVM_READONLY

static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)

Expr * getRequiresClause()

The constraint-expression of the associated requires-clause.

SourceLocation getRAngleLoc() const

SourceLocation getLAngleLoc() const

ArrayRef< NamedDecl * > asArray()

SourceLocation getTemplateLoc() const

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

void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)

Set the default argument for this template parameter, and whether that default argument was inherited...

static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, bool Typename, TemplateParameterList *Params)

Declaration of a template type parameter.

static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, std::optional< unsigned > NumExpanded=std::nullopt)

void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)

Set the default argument for this template parameter.

The top declaration context.

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

Represents the declaration of a typedef-name via a C++11 alias-declaration.

static TypeAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)

void setDescribedAliasTemplate(TypeAliasTemplateDecl *TAT)

Declaration of an alias template.

static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)

Create a function template node.

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

void setTypeForDecl(const Type *TD)

const Type * getTypeForDecl() const

SourceLocation getBeginLoc() const LLVM_READONLY

TyLocType push(QualType T)

Pushes space for a new TypeLoc of the given type.

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

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.

AutoTypeLoc getContainedAutoTypeLoc() const

Get the typeloc of an AutoType whose type will be deduced for a variable with an initializer of this ...

T getAsAdjusted() const

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

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)

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

bool isRValueReferenceType() const

const T * castAs() const

Member-template castAs.

bool isReferenceType() const

AutoType * getContainedAutoType() const

Get the AutoType whose type will be deduced for a variable with an initializer of this type.

bool isInstantiationDependentType() const

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

bool isLValueReferenceType() const

bool isDependentType() const

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

bool containsErrors() const

Whether this type is an error type.

bool isVariablyModifiedType() const

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

bool isUndeducedType() const

Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...

bool isFunctionType() const

const T * getAs() const

Member-template getAs'.

Represents the declaration of a typedef-name via the 'typedef' type specifier.

static TypedefDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)

Base class for declarations which introduce a typedef-name.

An artificial decl, representing a global anonymous constant value which is uniquified by value withi...

This node is generated when a using-declaration that was annotated with attribute((using_if_exists)) ...

static UnresolvedUsingIfExistsDecl * Create(ASTContext &Ctx, DeclContext *DC, SourceLocation Loc, DeclarationName Name)

Represents a dependent using declaration which was marked with typename.

SourceLocation getTypenameLoc() const

Returns the source location of the 'typename' keyword.

Represents a dependent using declaration which was not marked with typename.

Represents a C++ using-declaration.

static UsingDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword)

Represents C++ using-directive.

static UsingDirectiveDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, SourceLocation NamespaceLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor)

Represents a C++ using-enum-declaration.

static UsingEnumDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingL, SourceLocation EnumL, SourceLocation NameL, TypeSourceInfo *EnumType)

Represents a pack of using declarations that a single using-declarator pack-expanded into.

Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...

void setType(QualType newType)

Represents a variable declaration or definition.

VarTemplateDecl * getDescribedVarTemplate() const

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

void setObjCForDecl(bool FRD)

static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)

void setCXXForRangeDecl(bool FRD)

bool isConstexpr() const

Whether this variable is (C++11) constexpr.

void setInstantiationOfStaticDataMember(VarDecl *VD, TemplateSpecializationKind TSK)

Specify that this variable is an instantiation of the static data member VD.

TLSKind getTLSKind() const

void setInitStyle(InitializationStyle Style)

InitializationStyle getInitStyle() const

The style of initialization for this declaration.

void setInitCapture(bool IC)

DefinitionKind isThisDeclarationADefinition(ASTContext &) const

Check whether this declaration is a definition.

bool isOutOfLine() const override

Determine whether this is or was instantiated from an out-of-line definition of a static data member.

VarDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

bool isInitCapture() const

Whether this variable is the implicit variable for a lambda init-capture.

@ CallInit

Call-style initialization (C++98)

bool isObjCForDecl() const

Determine whether this variable is a for-loop declaration for a for-in statement in Objective-C.

void setPreviousDeclInSameBlockScope(bool Same)

bool isInlineSpecified() const

bool isStaticDataMember() const

Determines whether this is a static data member.

VarDecl * getTemplateInstantiationPattern() const

Retrieve the variable declaration from which this variable could be instantiated, if it is an instant...

bool isCXXForRangeDecl() const

Determine whether this variable is the for-range-declaration in a C++0x for-range statement.

VarDecl * getDefinition(ASTContext &)

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

bool mightBeUsableInConstantExpressions(const ASTContext &C) const

Determine whether this variable's value might be usable in a constant expression, according to the re...

void setInlineSpecified()

bool isStaticLocal() const

Returns true if a variable with function scope is a static local variable.

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

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

void setTSCSpec(ThreadStorageClassSpecifier TSC)

void setNRVOVariable(bool NRVO)

bool isInline() const

Whether this variable is (C++1z) inline.

ThreadStorageClassSpecifier getTSCSpec() const

const Expr * getInit() const

void setConstexpr(bool IC)

void setDescribedVarTemplate(VarTemplateDecl *Template)

bool isDirectInit() const

Whether the initializer is a direct-initializer (list or call).

StorageClass getStorageClass() const

Returns the storage class as written in the source.

void setImplicitlyInline()

bool isPreviousDeclInSameBlockScope() const

Whether this local extern variable declaration's previous declaration was declared in the same block ...

SourceLocation getPointOfInstantiation() const

If this variable is an instantiation of a variable template or a static data member of a class templa...

TemplateSpecializationKind getTemplateSpecializationKindForInstantiation() const

Get the template specialization kind of this variable for the purposes of template instantiation.

TemplateSpecializationKind getTemplateSpecializationKind() const

If this variable is an instantiation of a variable template or a static data member of a class templa...

bool isParameterPack() const

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

Declaration of a variable template.

void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, void *InsertPos)

Insert the specified partial specialization knowing that it is not already in.

VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)

Return the partial specialization with the provided arguments if it exists, otherwise return the inse...

void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos)

Insert the specified specialization knowing that it is not already in.

static VarTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, VarDecl *Decl)

Create a variable template node.

VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)

Return the specialization with the provided arguments if it exists, otherwise return the insertion po...

VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)

Find a variable template partial specialization which was instantiated from the given member partial ...

static VarTemplatePartialSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)

TemplateParameterList * getTemplateParameters() const

Get the list of template parameters.

void setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec)

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

SourceLocation getPointOfInstantiation() const

Get the point of instantiation (if any), or null if none.

void setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten)

Set the template argument list as written in the sources.

const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const

Retrieve the template argument list as written in the sources, if any.

const TemplateArgumentList & getTemplateArgs() const

Retrieve the template arguments of the variable template specialization.

const TemplateArgumentList & getTemplateInstantiationArgs() const

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

static VarTemplateSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)

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.

void setCompleteDefinition()

QualType FunctionType

BlockType - The function type of the block, if one was given.

void addCapture(ValueDecl *Var, bool isBlock, bool isByref, bool isNested, SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType, bool Invalid)

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

Defines the clang::TargetInfo interface.

const internal::VariadicAllOfMatcher< Decl > decl

Matches declarations.

bool NE(InterpState &S, CodePtr OpPC)

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)

@ Rewrite

We are substituting template parameters for (typically) other template parameters in order to rewrite...

StorageClass

Storage classes.

@ Property

The type of a property.

@ Result

The result type of a method or function.

@ TU_Prefix

The translation unit is a prefix to a translation unit, and is not complete.

@ VK_PRValue

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

const FunctionProtoType * T

bool declaresSameEntity(const Decl *D1, const Decl *D2)

Determine whether two declarations declare the same entity.

TemplateSpecializationKind

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

@ TSK_ExplicitInstantiationDefinition

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

@ TSK_ExplicitInstantiationDeclaration

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

@ TSK_ExplicitSpecialization

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

@ TSK_ImplicitInstantiation

This template specialization was implicitly instantiated from a template.

@ TSK_Undeclared

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

@ Enum

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

@ Other

Other implicit parameter.

ExceptionSpecificationType

The various types of exception specifications that exist in C++11.

@ EST_Uninstantiated

not instantiated yet

@ EST_None

no exception specification

@ EST_BasicNoexcept

noexcept

@ EST_Unevaluated

not evaluated yet, for special member function

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

DeclarationName getName() const

getName - Returns the embedded declaration name.

void setName(DeclarationName N)

setName - Sets the embedded declaration name.

const DeclarationNameLoc & getInfo() const

Holds information about the various types of exception specification.

FunctionDecl * SourceDecl

The function whose exception specification this is, for EST_Unevaluated and EST_Uninstantiated.

FunctionDecl * SourceTemplate

The function template whose exception specification this is instantiated from, for EST_Uninstantiated...

ExceptionSpecificationType Type

The kind of exception specification this is.

Extra information about a function prototype.

ExceptionSpecInfo ExceptionSpec

FunctionType::ExtInfo ExtInfo

This structure contains most locations needed for by an OMPVarListClause.

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

SynthesisKind

The kind of template instantiation we are performing.

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

bool InLifetimeExtendingContext

Whether we are currently in a context in which all temporaries must be lifetime-extended,...

bool RebuildDefaultArgOrDefaultInit

Whether we should rebuild CXXDefaultArgExpr and CXXDefaultInitExpr.

A stack object to be created when performing template instantiation.

bool isInvalid() const

Determines whether we have exceeded the maximum recursive template instantiations.

bool isAlreadyInstantiating() const

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