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

1

2

3

4

5

6

7

8

9

10

11

12

13

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

22

23using namespace clang;

24using namespace sema;

25

28 bool FromInclude = false) {

30

31 if (auto *LSD = dyn_cast(DC)) {

32 switch (LSD->getLanguage()) {

35 ExternCLoc = LSD->getBeginLoc();

36 break;

38 break;

39 }

41 }

42

45

48 ? diag::ext_module_import_not_at_top_level_noop

49 : diag::err_module_import_not_at_top_level_fatal)

52 diag::note_module_import_not_at_top_level)

53 << DC;

55 S.Diag(ImportLoc, diag::ext_module_import_in_extern_c)

57 S.Diag(ExternCLoc, diag::note_extern_c_begins_here);

58 }

59}

60

61

62

63

64

66 std::string Name;

67 if (Path.empty())

68 return Name;

69

70 for (auto &Piece : Path) {

71 if (!Name.empty())

72 Name += ".";

73 Name += Piece.getIdentifierInfo()->getName();

74 }

75 return Name;

76}

77

78

79

80

81

82

83

84

85static bool

87 Module *CurrentModule,

88 Module *&FoundPrimaryModuleInterface) {

90 return false;

91

92

93

95 return true;

96

97

98

99 if (FoundPrimaryModuleInterface)

100 return Imported == FoundPrimaryModuleInterface;

101

102 if (!CurrentModule)

103 return false;

104

105

106

107

108

109

110

112 return false;

113

115 assert(!FoundPrimaryModuleInterface ||

116 FoundPrimaryModuleInterface == Imported);

117 FoundPrimaryModuleInterface = Imported;

118 return true;

119 }

120

121 return false;

122}

123

124

125

126

127

128

129

130static void

134 bool IsImportingPrimaryModuleInterface = false) {

136 "'makeTransitiveImportsVisible()' is intended for standard C++ named "

137 "modules only.");

138

141 Worklist.push_back(Imported);

142

143 Module *FoundPrimaryModuleInterface =

144 IsImportingPrimaryModuleInterface ? Imported : nullptr;

145

146 while (!Worklist.empty()) {

147 Module *Importing = Worklist.pop_back_val();

148

149 if (Visited.count(Importing))

150 continue;

151 Visited.insert(Importing);

152

153

154

155 VisibleModules.setVisible(Importing, ImportLoc);

156

158 FoundPrimaryModuleInterface)) {

160 Worklist.push_back(TransImported);

161

162 for (auto [Exports, _] : Importing->Exports)

163 Worklist.push_back(Exports);

164 }

165 }

166}

167

170

171 Module *GlobalModule =

172 PushGlobalModuleFragment(ModuleLoc);

173

174

175 auto *TU = Context.getTranslationUnitDecl();

176

177

178

179

180

181

182

184 TU->setLocalOwningModule(GlobalModule);

185

186

187 return nullptr;

188}

189

190void Sema::HandleStartOfHeaderUnit() {

192 "Header units are only valid for C++20 modules");

194 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());

195

197 if (HUName.empty()) {

198 HUName =

199 SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID())->getName();

201 }

202

203

204

205

206 auto F = SourceMgr.getFileManager().getOptionalFileRef(HUName);

207

208

209

210 if (!F)

211 F = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID());

212 assert(F && "failed to find the header unit source?");

214 auto &Map = PP.getHeaderSearchInfo().getModuleMap();

215 Module *Mod = Map.createHeaderUnit(StartOfTU, HUName, H);

216 assert(Mod && "module creation should not fail");

217 ModuleScopes.push_back({});

218 ModuleScopes.back().BeginLoc = StartOfTU;

219 ModuleScopes.back().Module = Mod;

220 VisibleModules.setVisible(Mod, StartOfTU);

221

222

223

224 auto *TU = Context.getTranslationUnitDecl();

226 TU->setLocalOwningModule(Mod);

227}

228

229

230

231

234 enum {

237 Reserved = 1,

238 } Reason = Valid;

239

240 if (II->isStr("module") || II->isStr("import"))

244 Reason = Reserved;

245

246

247

248

251

252 switch (Reason) {

254 return false;

256 return S.Diag(Loc, diag::err_invalid_module_name) << II;

257 case Reserved:

258 S.Diag(Loc, diag::warn_reserved_module_name) << II;

259 return false;

260 }

261 llvm_unreachable("fell off a fully covered switch");

262}

263

268 bool SeenNoTrivialPPDirective) {

270 "should only have module decl in standard C++ modules");

271

274

275

277

278 bool IsPartition = !Partition.empty();

279 if (IsPartition)

280 switch (MDK) {

283 break;

286 break;

287 default:

288 llvm_unreachable("how did we get a partition type set?");

289 }

290

291

292

293

294

295

296 switch (getLangOpts().getCompilingModule()) {

298

299 break;

300

303 break;

304

305

306

307 Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch)

310 break;

311

313 Diag(ModuleLoc, diag::err_module_decl_in_module_map_module);

314 return nullptr;

315

317 Diag(ModuleLoc, diag::err_module_decl_in_header_unit);

318 return nullptr;

319 }

320

321 assert(ModuleScopes.size() <= 1 && "expected to be at global module scope");

322

323

324

325

326

327 if (isCurrentModulePurview()) {

328 Diag(ModuleLoc, diag::err_module_redeclaration);

329 Diag(VisibleModules.getImportLoc(ModuleScopes.back().Module),

330 diag::note_prev_module_declaration);

331 return nullptr;

332 }

333

334 assert((getLangOpts().CPlusPlusModules ||

335 SeenGMF == (bool)this->TheGlobalModuleFragment) &&

336 "mismatched global module state");

337

338

339

341 (!IsFirstDecl || SeenNoTrivialPPDirective) && !SeenGMF) {

342 Diag(ModuleLoc, diag::err_module_decl_not_at_start);

344 Diag(BeginLoc, diag::note_global_module_introducer_missing)

346 }

347

348

349

350

351

352

353

354

355

356

357 StringRef FirstComponentName = Path[0].getIdentifierInfo()->getName();

358 if (getSourceManager().isInSystemHeader(Path[0].getLoc()) &&

359 (FirstComponentName == "std" ||

360 (FirstComponentName.starts_with("std") &&

361 llvm::all_of(FirstComponentName.drop_front(3), &llvm::isDigit))))

362 Diag(Path[0].getLoc(), diag::warn_reserved_module_name)

363 << Path[0].getIdentifierInfo();

364

365

366

367 for (auto Part : Path) {

369 return nullptr;

370 }

371

372

373

374

376 if (IsPartition) {

377 ModuleName += ":";

379 }

380

381

382 if (getLangOpts().CurrentModule.empty() &&

383 getLangOpts().CurrentModule != ModuleName) {

384 Diag(Path.front().getLoc(), diag::err_current_module_name_mismatch)

385 << SourceRange(Path.front().getLoc(), IsPartition

386 ? Partition.back().getLoc()

387 : Path.back().getLoc())

389 return nullptr;

390 }

392

393 auto &Map = PP.getHeaderSearchInfo().getModuleMap();

394 Module *Mod;

395 Module *Interface = nullptr;

396 switch (MDK) {

399

400

401 if (auto *M = Map.findOrLoadModule(ModuleName)) {

402 Diag(Path[0].getLoc(), diag::err_module_redefinition) << ModuleName;

403 if (M->DefinitionLoc.isValid())

404 Diag(M->DefinitionLoc, diag::note_prev_module_definition);

406 Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file)

407 << FE->getName();

408 Mod = M;

409 break;

410 }

411

412

413 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);

416 assert(Mod && "module creation should not fail");

417 break;

418 }

419

421

422

423

424

426 PP.getIdentifierInfo(ModuleName));

427

428

429

430

431

435 false);

437

439 Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;

440

441 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);

442 } else {

443 Mod = Map.createModuleForImplementationUnit(ModuleLoc, ModuleName);

444 }

445 } break;

446

448

449

450 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);

452 break;

453 }

454

455 if (!this->TheGlobalModuleFragment) {

456 ModuleScopes.push_back({});

457 if (getLangOpts().ModulesLocalVisibility)

458 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);

459 } else {

460

462 }

463

464

465 ModuleScopes.back().BeginLoc = StartLoc;

466 ModuleScopes.back().Module = Mod;

467 VisibleModules.setVisible(Mod, ModuleLoc);

468

469

470

471

472

473

474 auto *TU = Context.getTranslationUnitDecl();

476 TU->setLocalOwningModule(Mod);

477

478

479

481

483

485 Listener->EnteringModulePurview();

486

487

488

489

491 HadImportedNamedModules = true;

492

494 Mod, ModuleLoc,

495 true);

496

497

501

502

503

504 Context.addModuleInitializer(ModuleScopes.back().Module, Import);

506

508

509

511 }

512

513 return nullptr;

514}

515

519

520

521

523 : ModuleScopes.back().Module->Kind) {

530 Diag(PrivateLoc, diag::err_private_module_fragment_not_module);

531 return nullptr;

532

534 Diag(PrivateLoc, diag::err_private_module_fragment_redefined);

535 Diag(ModuleScopes.back().BeginLoc, diag::note_previous_definition);

536 return nullptr;

537

539 Diag(PrivateLoc, diag::err_private_module_fragment_not_module_interface);

540 Diag(ModuleScopes.back().BeginLoc,

541 diag::note_not_module_interface_add_export)

543 return nullptr;

544

546 break;

547 }

548

549

550

551

552

553

555

556 auto &Map = PP.getHeaderSearchInfo().getModuleMap();

557 Module *PrivateModuleFragment =

558 Map.createPrivateModuleFragmentForInterfaceUnit(

559 ModuleScopes.back().Module, PrivateLoc);

560 assert(PrivateModuleFragment && "module creation should not fail");

561

562

563 ModuleScopes.push_back({});

564 ModuleScopes.back().BeginLoc = ModuleLoc;

565 ModuleScopes.back().Module = PrivateModuleFragment;

566 VisibleModules.setVisible(PrivateModuleFragment, ModuleLoc);

567

568

569

570

571 auto *TU = Context.getTranslationUnitDecl();

573 TU->setLocalOwningModule(PrivateModuleFragment);

574

575

576 return nullptr;

577}

578

582 bool IsPartition) {

583 assert((!IsPartition || getLangOpts().CPlusPlusModules) &&

584 "partition seen in non-C++20 code?");

585

586

587

589

590 std::string ModuleName;

591 if (IsPartition) {

592

593 assert(!ModuleScopes.empty() && "in a module purview, but no module?");

594 Module *NamedMod = ModuleScopes.back().Module;

595

596

598 ModuleName += ":";

600 ModuleNameLoc =

601 IdentifierLoc(Path[0].getLoc(), PP.getIdentifierInfo(ModuleName));

603 } else if (getLangOpts().CPlusPlusModules) {

605 ModuleNameLoc =

606 IdentifierLoc(Path[0].getLoc(), PP.getIdentifierInfo(ModuleName));

608 }

609

610

611

612

613

614

615

616

617 if (getLangOpts().CPlusPlusModules && isCurrentModulePurview() &&

619 Diag(ImportLoc, diag::err_module_self_import_cxx20)

621 return true;

622 }

623

625 ImportLoc, Path, Module::AllVisible, false);

626 if (!Mod)

627 return true;

628

631 Diag(ImportLoc, diag::err_module_import_non_interface_nor_parition)

632 << ModuleName;

633 return true;

634 }

635

636 return ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, Mod, Path);

637}

638

639

642 if (auto *ED = dyn_cast(DC))

643 return ED;

644 return nullptr;

645}

646

652 Diag(ImportLoc, diag::warn_experimental_header_unit);

653

657 else

658 VisibleModules.setVisible(Mod, ImportLoc);

659

661 "We can only import a partition unit in a named module.");

664 Diag(ImportLoc,

665 diag::warn_import_implementation_partition_unit_in_interface_unit)

666 << Mod->Name;

667

669

670

671

672

673

676 ? diag::err_module_self_import

677 : diag::err_module_import_in_implementation)

679 }

680

682

683 if (Path.empty()) {

684

685

686

687 for (Module *ModCheck = Mod; ModCheck; ModCheck = ModCheck->Parent)

690

691 IdentifierLocs.push_back(Path[0].getLoc());

692 } else {

693 Module *ModCheck = Mod;

694 for (unsigned I = 0, N = Path.size(); I != N; ++I) {

695

696

697 if (!ModCheck)

698 break;

699 ModCheck = ModCheck->Parent;

700

701 IdentifierLocs.push_back(Path[I].getLoc());

702 }

703 }

704

706 Mod, IdentifierLocs);

708

709

710

711 if (!ModuleScopes.empty())

712 Context.addModuleInitializer(ModuleScopes.back().Module, Import);

713

714

717 Diag(ExportLoc, diag::err_export_partition_impl)

718 << SourceRange(ExportLoc, Path.back().getLoc());

719 } else if (ExportLoc.isValid() &&

721

722

723

724 Diag(ExportLoc, diag::err_export_not_in_module_interface);

725 } else if (!ModuleScopes.empty()) {

726

727

728

731 else

733 }

734

735 HadImportedNamedModules = true;

736

737 return Import;

738}

739

744

746

747

748

749

750

751 bool IsInModuleIncludes =

754

755

756

757 if (getLangOpts().Modules && !IsInModuleIncludes) {

760 DirectiveLoc, Mod,

761 DirectiveLoc);

762 if (!ModuleScopes.empty())

763 Context.addModuleInitializer(ModuleScopes.back().Module, ImportD);

765 Consumer.HandleImplicitImportDecl(ImportD);

766 }

767

769 VisibleModules.setVisible(Mod, DirectiveLoc);

770

772 Module *ThisModule = PP.getHeaderSearchInfo().lookupModule(

773 getLangOpts().CurrentModule, DirectiveLoc, false, false);

774 (void)ThisModule;

775

776

777 assert((getLangOpts().getCompilingModule() ==

779 ThisModule) &&

780 "was expecting a module if building a Clang module");

781 }

782}

783

786

787 ModuleScopes.push_back({});

788 ModuleScopes.back().Module = Mod;

789 if (getLangOpts().ModulesLocalVisibility)

790 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);

791

792 VisibleModules.setVisible(Mod, DirectiveLoc);

793

794

795

796

797 if (getLangOpts().trackLocalOwningModule()) {

798 for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {

799 cast(DC)->setModuleOwnershipKind(

803 cast(DC)->setLocalOwningModule(Mod);

804 }

805 }

806}

807

809 if (getLangOpts().ModulesLocalVisibility) {

810 VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);

811

812

814 }

815

816 assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&

817 "left the wrong module scope");

818 ModuleScopes.pop_back();

819

820

821

825

827 "end of submodule in main source file");

829 } else {

830

831 DirectiveLoc = EomLoc;

832 }

834

835

836 if (getLangOpts().trackLocalOwningModule()) {

837

838

839 for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {

842 cast(DC)->setModuleOwnershipKind(

844 }

845 }

846}

847

850

852 VisibleModules.isVisible(Mod))

853 return;

854

855

858 Loc, Mod, Loc);

860 Consumer.HandleImplicitImportDecl(ImportD);

861

862

864 VisibleModules.setVisible(Mod, Loc);

865}

866

870

871

873

876

877

878

879

880

882 if (!isCurrentModulePurview()) {

883 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0;

885 return D;

887 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1;

888 Diag(ModuleScopes.back().BeginLoc,

889 diag::note_not_module_interface_add_export)

892 return D;

893 } else if (ModuleScopes.back().Module->Kind ==

895 Diag(ExportLoc, diag::err_export_in_private_module_fragment);

896 Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment);

898 return D;

899 }

900 }

901

903 if (const auto *ND = dyn_cast(DC)) {

904

905

906 if (ND->isAnonymousNamespace()) {

907 Diag(ExportLoc, diag::err_export_within_anonymous_namespace);

908 Diag(ND->getLocation(), diag::note_anonymous_namespace);

909

911 return D;

912 }

913

914

915

916

917

918

919 if (getLangOpts().HLSL && !DeferredExportedNamespaces.insert(ND).second)

920 break;

921 }

922 }

923

924

925

927 Diag(ExportLoc, diag::err_export_within_export);

928 if (ED->hasBraces())

929 Diag(ED->getLocation(), diag::note_export);

931 return D;

932 }

933

936

937 return D;

938}

939

941

942

945 bool AllUnnamed = true;

946 for (auto *D : DC->decls())

948 return AllUnnamed;

949}

950

951

953

954

956

958 S.Diag(D->getBeginLoc(), diag::err_hlsl_export_not_on_function);

960 return false;

961 }

962 }

963

964

965

966 bool HasName = false;

967 if (auto *ND = dyn_cast(D)) {

968

969

970 HasName = (bool)ND->getDeclName();

972 S.Diag(ND->getLocation(), diag::err_export_internal) << ND;

973 if (BlockStart.isValid())

974 S.Diag(BlockStart, diag::note_export);

975 return false;

976 }

977 }

978

979

980

981

982 if (auto *USD = dyn_cast(D)) {

986 S.Diag(USD->getLocation(), diag::err_export_using_internal)

988 S.Diag(Target->getLocation(), diag::note_using_decl_target);

989 if (BlockStart.isValid())

990 S.Diag(BlockStart, diag::note_export);

991 return false;

992 }

993 }

994

995

996

997 if (auto *DC = dyn_cast(D)) {

999 return true;

1000

1001 if (auto *ND = dyn_cast(D)) {

1002 if (!ND->getDeclName()) {

1003 S.Diag(ND->getLocation(), diag::err_export_anon_ns_internal);

1004 if (BlockStart.isValid())

1005 S.Diag(BlockStart, diag::note_export);

1006 return false;

1007 } else if (!DC->decls().empty() &&

1008 DC->getRedeclContext()->isFileContext()) {

1010 }

1011 }

1012 }

1013 return true;

1014}

1015

1018 if (RBraceLoc.isValid())

1019 ED->setRBraceLoc(RBraceLoc);

1020

1022

1025 ED->hasBraces() ? ED->getBeginLoc() : SourceLocation();

1026 for (auto *Child : ED->decls()) {

1028 if (auto *FD = dyn_cast(Child)) {

1029

1030

1031

1032

1033

1034

1035

1036 if (FD->isInlineSpecified() && !FD->isDefined())

1037 PendingInlineFuncDecls.insert(FD);

1038 }

1039 }

1040 }

1041

1042

1043 for (auto *Exported : ED->decls())

1045

1046 return D;

1047}

1048

1050

1051

1052 if (!TheGlobalModuleFragment) {

1056 }

1057

1058 assert(TheGlobalModuleFragment && "module creation should not fail");

1059

1060

1061 ModuleScopes.push_back({BeginLoc, TheGlobalModuleFragment,

1062 {}});

1063 VisibleModules.setVisible(TheGlobalModuleFragment, BeginLoc);

1064

1065 return TheGlobalModuleFragment;

1066}

1067

1068void Sema::PopGlobalModuleFragment() {

1069 assert(!ModuleScopes.empty() &&

1071 "left the wrong module scope, which is not global module fragment");

1072 ModuleScopes.pop_back();

1073}

1074

1076 if (!TheImplicitGlobalModuleFragment) {

1077 ModuleMap &Map = PP.getHeaderSearchInfo().getModuleMap();

1078 TheImplicitGlobalModuleFragment =

1081 }

1082 assert(TheImplicitGlobalModuleFragment && "module creation should not fail");

1083

1084

1085 ModuleScopes.push_back({BeginLoc, TheImplicitGlobalModuleFragment,

1086 {}});

1087 VisibleModules.setVisible(TheImplicitGlobalModuleFragment, BeginLoc);

1088 return TheImplicitGlobalModuleFragment;

1089}

1090

1091void Sema::PopImplicitGlobalModuleFragment() {

1092 assert(!ModuleScopes.empty() &&

1094 "left the wrong module scope, which is not global module fragment");

1095 ModuleScopes.pop_back();

1096}

1097

1098bool Sema::isCurrentModulePurview() const {

1100 return false;

1101

1102

1103

1111 return true;

1112 default:

1113 return false;

1114 }

1115}

1116

1117

1118

1119

1120

1121namespace {

1122class ExposureChecker {

1123public:

1124 ExposureChecker(Sema &S) : SemaRef(S) {}

1125

1126 bool checkExposure(const VarDecl *D, bool Diag);

1127 bool checkExposure(const CXXRecordDecl *D, bool Diag);

1128 bool checkExposure(const Stmt *S, bool Diag);

1129 bool checkExposure(const FunctionDecl *D, bool Diag);

1130 bool checkExposure(const NamedDecl *D, bool Diag);

1131 void checkExposureInContext(const DeclContext *DC);

1132 bool isExposureCandidate(const NamedDecl *D);

1133

1134 bool isTULocal(QualType Ty);

1135 bool isTULocal(const NamedDecl *ND);

1136 bool isTULocal(const Expr *E);

1137

1138 Sema &SemaRef;

1139

1140private:

1141 llvm::DenseSet<const NamedDecl *> ExposureSet;

1142 llvm::DenseSet<const NamedDecl *> KnownNonExposureSet;

1143};

1144

1145bool ExposureChecker::isTULocal(QualType Ty) {

1146

1147

1148

1149

1150

1152

1153

1154

1155

1156

1157

1158}

1159

1160bool ExposureChecker::isTULocal(const NamedDecl *D) {

1161 if (!D)

1162 return false;

1163

1164

1165

1166

1167

1168

1170 return true;

1171

1173 return true;

1174

1175

1176

1177

1179 if (auto *ND = dyn_cast(D->getDeclContext());

1180 ND && isTULocal(ND))

1181 return true;

1182

1183

1184

1185

1187 NamedDecl *PrimaryTemplate = nullptr;

1188 if (auto *CTSD = dyn_cast(D)) {

1189 TemplateArgs = CTSD->getTemplateArgs().asArray();

1190 PrimaryTemplate = CTSD->getSpecializedTemplate();

1191 if (isTULocal(PrimaryTemplate))

1192 return true;

1193 } else if (auto *VTSD = dyn_cast(D)) {

1194 TemplateArgs = VTSD->getTemplateArgs().asArray();

1195 PrimaryTemplate = VTSD->getSpecializedTemplate();

1196 if (isTULocal(PrimaryTemplate))

1197 return true;

1198 } else if (auto *FD = dyn_cast(D)) {

1199 if (auto *TAList = FD->getTemplateSpecializationArgs())

1200 TemplateArgs = TAList->asArray();

1201

1202 PrimaryTemplate = FD->getPrimaryTemplate();

1203 if (isTULocal(PrimaryTemplate))

1204 return true;

1205 }

1206

1207 if (!PrimaryTemplate)

1208

1209 return false;

1210

1211 if (KnownNonExposureSet.count(D))

1212 return false;

1213

1214 for (auto &TA : TemplateArgs) {

1215 switch (TA.getKind()) {

1217 if (isTULocal(TA.getAsType()))

1218 return true;

1219 break;

1221 if (isTULocal(TA.getAsDecl()))

1222 return true;

1223 break;

1224 default:

1225 break;

1226 }

1227 }

1228

1229

1230

1231

1232 if (ExposureSet.count(PrimaryTemplate) ||

1233 checkExposure(PrimaryTemplate, false))

1234 return true;

1235

1236

1237 KnownNonExposureSet.insert(D);

1238 return false;

1239}

1240

1241bool ExposureChecker::isTULocal(const Expr *E) {

1242 if (!E)

1243 return false;

1244

1245

1246

1247

1248 if (isTULocal(E->getType()))

1249 return true;

1250

1252

1253

1254

1255

1256

1257

1258

1259 if (const auto *DRE = dyn_cast(E)) {

1260 if (auto *FD = dyn_cast_or_null(DRE->getFoundDecl()))

1261 return isTULocal(FD);

1262 else if (auto *VD = dyn_cast_or_null(DRE->getFoundDecl()))

1263 return isTULocal(VD);

1264 else if (auto *RD = dyn_cast_or_null(DRE->getFoundDecl()))

1265 return isTULocal(RD);

1266 }

1267

1268

1269

1270

1271

1272 return false;

1273}

1274

1275bool ExposureChecker::isExposureCandidate(const NamedDecl *D) {

1276 if (!D)

1277 return false;

1278

1279

1280

1281

1282

1283

1285 if (!M)

1286 return false;

1287

1288

1291 assert(M && "Implicit global module must have a parent");

1292 }

1293

1295 return false;

1296

1298 return false;

1299

1300

1301

1302

1303

1304

1307 return false;

1308

1309 return true;

1310}

1311

1312bool ExposureChecker::checkExposure(const NamedDecl *D, bool Diag) {

1313 if (!isExposureCandidate(D))

1314 return false;

1315

1316 if (auto *FD = dyn_cast(D))

1317 return checkExposure(FD, Diag);

1318 if (auto *FTD = dyn_cast(D))

1319 return checkExposure(FTD->getTemplatedDecl(), Diag);

1320

1321 if (auto *VD = dyn_cast(D))

1322 return checkExposure(VD, Diag);

1323 if (auto *VTD = dyn_cast(D))

1324 return checkExposure(VTD->getTemplatedDecl(), Diag);

1325

1326 if (auto *RD = dyn_cast(D))

1327 return checkExposure(RD, Diag);

1328

1329 if (auto *CTD = dyn_cast(D))

1330 return checkExposure(CTD->getTemplatedDecl(), Diag);

1331

1332 return false;

1333}

1334

1335bool ExposureChecker::checkExposure(const FunctionDecl *FD, bool Diag) {

1336 bool IsExposure = false;

1338 IsExposure = true;

1341 diag::warn_exposure)

1343 }

1344

1346 if (isTULocal(Parms->getType())) {

1347 IsExposure = true;

1349 SemaRef.Diag(Parms->getLocation(), diag::warn_exposure)

1350 << Parms->getType();

1351 }

1352

1353 bool IsImplicitInstantiation =

1355

1356

1357

1358

1359

1360

1361

1362

1363

1366

1367 IsExposure |= checkExposure(FD->getBody(), Diag);

1368 if (IsExposure)

1369 ExposureSet.insert(FD);

1370

1371 return IsExposure;

1372}

1373

1374bool ExposureChecker::checkExposure(const VarDecl *VD, bool Diag) {

1375 bool IsExposure = false;

1376

1377

1378

1379

1380

1381

1383 IsExposure = true;

1387 }

1388

1389 if (isTULocal(VD->getType())) {

1390 IsExposure = true;

1392 SemaRef.Diag(VD->getLocation(), diag::warn_exposure) << VD->getType();

1393 }

1394

1395

1396

1397

1398

1399

1400

1401

1402

1404 IsExposure |= checkExposure(VD->getInit(), Diag);

1405 if (IsExposure)

1406 ExposureSet.insert(VD);

1407

1408 return IsExposure;

1409}

1410

1411bool ExposureChecker::checkExposure(const CXXRecordDecl *RD, bool Diag) {

1413 return false;

1414

1415 bool IsExposure = false;

1417 IsExposure |= checkExposure(Method, Diag);

1418

1420 if (isTULocal(FD->getType())) {

1421 IsExposure = true;

1423 SemaRef.Diag(FD->getLocation(), diag::warn_exposure) << FD->getType();

1424 }

1425 }

1426

1428 if (isTULocal(Base.getType())) {

1429 IsExposure = true;

1431 SemaRef.Diag(Base.getBaseTypeLoc(), diag::warn_exposure)

1432 << Base.getType();

1433 }

1434 }

1435

1436 if (IsExposure)

1437 ExposureSet.insert(RD);

1438

1439 return IsExposure;

1440}

1441

1443public:

1444 using CallbackTy = std::function<void(DeclRefExpr *, ValueDecl *)>;

1445

1446 ReferenceTULocalChecker(ExposureChecker &C, CallbackTy &&Callback)

1447 : Checker(C), Callback(std::move(Callback)) {}

1448

1449 bool VisitDeclRefExpr(DeclRefExpr *DRE) override {

1450 ValueDecl *Referenced = DRE->getDecl();

1451 if (!Referenced)

1452 return true;

1453

1454 if (!Checker.isTULocal(Referenced))

1455

1456 return true;

1457

1459

1460

1461

1462

1463

1465 return true;

1466

1467

1468

1469

1470

1471

1472 ASTContext &Context = Referenced->getASTContext();

1474 if (DRE->isNonOdrUse() && (L == Linkage::Internal || L == Linkage::None))

1475 if (auto *VD = dyn_cast(Referenced);

1478 return true;

1479

1480 Callback(DRE, Referenced);

1481 return true;

1482 }

1483

1484 ExposureChecker &Checker;

1485 CallbackTy Callback;

1486};

1487

1488bool ExposureChecker::checkExposure(const Stmt *S, bool Diag) {

1489 if (!S)

1490 return false;

1491

1492 bool HasReferencedTULocals = false;

1493 ReferenceTULocalChecker Checker(

1494 *this, [this, &HasReferencedTULocals, Diag](DeclRefExpr *DRE,

1497 SemaRef.Diag(DRE->getExprLoc(), diag::warn_exposure) << Referenced;

1498 }

1499 HasReferencedTULocals = true;

1500 });

1501 Checker.TraverseStmt(const_cast<Stmt *>(S));

1502 return HasReferencedTULocals;

1503}

1504

1505void ExposureChecker::checkExposureInContext(const DeclContext *DC) {

1507 if (auto *Export = dyn_cast(TopD)) {

1508 checkExposureInContext(Export);

1509 continue;

1510 }

1511

1512 if (auto *LinkageSpec = dyn_cast(TopD)) {

1513 checkExposureInContext(LinkageSpec);

1514 continue;

1515 }

1516

1517 auto *TopND = dyn_cast(TopD);

1518 if (!TopND)

1519 continue;

1520

1521 if (auto *Namespace = dyn_cast(TopND)) {

1522 checkExposureInContext(Namespace);

1523 continue;

1524 }

1525

1526

1527

1528

1529

1530

1531 if (!TopND->isFromASTFile() && isExposureCandidate(TopND) &&

1532 !isTULocal(TopND))

1533 checkExposure(TopND, true);

1534 }

1535}

1536

1537}

1538

1540 if (!TU)

1541 return;

1542

1543 ExposureChecker Checker(*this);

1544

1547 Checker.checkExposureInContext(TU);

1548

1549

1550

1551

1552

1553 for (auto FDAndInstantiationLocPair : PendingCheckReferenceForTULocal) {

1554 FunctionDecl *FD = FDAndInstantiationLocPair.first;

1555 SourceLocation PointOfInstantiation = FDAndInstantiationLocPair.second;

1556

1558 continue;

1559

1560 ReferenceTULocalChecker(Checker, [&, this](DeclRefExpr *DRE,

1561 ValueDecl *Referenced) {

1562

1563

1564

1565

1566

1567

1569 return;

1570

1572 return;

1573

1574

1575

1576

1577

1580 return;

1581

1582 Diag(PointOfInstantiation,

1583 diag::warn_reference_tu_local_entity_in_other_tu)

1584 << FD << Referenced

1586 }).TraverseStmt(FD->getBody());

1587 }

1588}

1589

1590void Sema::checkReferenceToTULocalFromOtherTU(

1592

1593

1594 if (!FD || !HadImportedNamedModules)

1595 return;

1596

1597 PendingCheckReferenceForTULocal.push_back(

1598 std::make_pair(FD, PointOfInstantiation));

1599}

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

Produce a diagnostic highlighting some portion of a literal.

llvm::MachO::Target Target

Defines the clang::Preprocessor interface.

static void makeTransitiveImportsVisible(ASTContext &Ctx, VisibleModuleSet &VisibleModules, Module *Imported, Module *CurrentModule, SourceLocation ImportLoc, bool IsImportingPrimaryModuleInterface=false)

[module.import]p7: Additionally, when a module-import-declaration in a module unit of some module M i...

Definition SemaModule.cpp:131

static bool DiagReservedModuleName(Sema &S, const IdentifierInfo *II, SourceLocation Loc)

Tests whether the given identifier is reserved as a module name and diagnoses if it is.

Definition SemaModule.cpp:232

static const ExportDecl * getEnclosingExportDecl(const Decl *D)

Determine whether D is lexically within an export-declaration.

Definition SemaModule.cpp:640

static bool checkExportedDecl(Sema &, Decl *, SourceLocation)

Check that it's valid to export D.

Definition SemaModule.cpp:952

static std::string stringFromPath(ModuleIdPath Path)

Definition SemaModule.cpp:65

static void checkModuleImportContext(Sema &S, Module *M, SourceLocation ImportLoc, DeclContext *DC, bool FromInclude=false)

Definition SemaModule.cpp:26

static bool checkExportedDeclContext(Sema &S, DeclContext *DC, SourceLocation BlockStart)

Check that it's valid to export all the declarations in DC.

Definition SemaModule.cpp:943

static bool isImportingModuleUnitFromSameModule(ASTContext &Ctx, Module *Imported, Module *CurrentModule, Module *&FoundPrimaryModuleInterface)

Helper function for makeTransitiveImportsVisible to decide whether the.

Definition SemaModule.cpp:86

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

TranslationUnitDecl * getTranslationUnitDecl() const

void setCurrentNamedModule(Module *M)

Set the (C++20) module we are building.

bool isInSameModule(const Module *M1, const Module *M2) const

If the two module M1 and M2 are in the same module.

Represents a base class of a C++ class.

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

Represents a C++ struct/union/class.

method_range methods() const

bool hasDefinition() const

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

Determines whether this context is dependent on a template parameter.

DeclContext * getLexicalParent()

getLexicalParent - Returns the containing lexical DeclContext.

void addDecl(Decl *D)

Add the declaration D into this context.

decl_range noload_decls() const

noload_decls_begin/end - Iterate over the declarations stored in this context that are currently load...

decl_range decls() const

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

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

NonOdrUseReason isNonOdrUse() const

Is this expression a non-odr-use reference, and if so, why?

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

FriendObjectKind getFriendObjectKind() const

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

ASTContext & getASTContext() const LLVM_READONLY

bool isImplicit() const

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

void setInvalidDecl(bool Invalid=true)

setInvalidDecl - Indicates the Decl had a semantic error.

bool isInAnotherModuleUnit() const

Whether this declaration comes from another module unit.

Module * getOwningModule() const

Get the module that owns this declaration (for visibility purposes).

bool isFromASTFile() const

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

bool isInvalidDecl() const

SourceLocation getLocation() const

DeclContext * getDeclContext()

bool isInAnonymousNamespace() const

SourceLocation getBeginLoc() const LLVM_READONLY

DeclContext * getLexicalDeclContext()

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

@ VisibleWhenImported

This declaration has an owning module, and is visible when that module is imported.

@ Unowned

This declaration is not owned by a module.

@ ReachableWhenImported

This declaration has an owning module, and is visible to lookups that occurs within that module.

@ ModulePrivate

This declaration has an owning module, but is only visible to lookups that occur within that module.

@ Visible

This declaration has an owning module, but is globally visible (typically because its owning module i...

void setModuleOwnershipKind(ModuleOwnershipKind MOK)

Set whether this declaration is hidden from name lookup.

Represents a standard C++ module export declaration.

static ExportDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc)

void setRBraceLoc(SourceLocation L)

This represents one expression.

bool isValueDependent() const

Determines whether the value 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,...

SourceLocation getExprLoc() const LLVM_READONLY

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

Represents a member of a struct/union/class.

An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...

static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)

Create a code modification hint that inserts the given code string at a specific location.

Represents a function declaration or definition.

Stmt * getBody(const FunctionDecl *&Definition) const

Retrieve the body (definition) of the function.

SourceRange getReturnTypeSourceRange() const

Attempt to compute an informative source range covering the function return type.

bool isInlined() const

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

QualType getReturnType() const

ArrayRef< ParmVarDecl * > parameters() const

TemplateSpecializationKind getTemplateSpecializationKind() const

Determine what kind of template instantiation this function represents.

bool hasBody(const FunctionDecl *&Definition) const

Returns true if the function has a body.

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

ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const

Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....

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

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

A simple pair of identifier info and location.

Describes a module import declaration, which makes the contents of the named module visible in the cu...

static ImportDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef< SourceLocation > IdentifierLocs)

Create a new module import declaration.

static ImportDecl * CreateImplicit(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, Module *Imported, SourceLocation EndLoc)

Create a new module import declaration for an implicitly-generated import.

@ CMK_None

Not compiling a module interface at all.

@ CMK_HeaderUnit

Compiling a module header unit.

@ CMK_ModuleMap

Compiling a module from a module map.

@ CMK_ModuleInterface

Compiling a C++ modules interface unit.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

std::string CurrentModule

The name of the current module, of which the main source file is a part.

virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0

Attempt to load the given module.

virtual void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, SourceLocation ImportLoc)=0

Make the given module visible.

Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent=nullptr)

Create a global module fragment for a C++ module unit.

Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent)

Describes a module or submodule.

StringRef getTopLevelModuleName() const

Retrieve the name of the top-level module.

SmallVector< ExportDecl, 2 > Exports

The set of export declarations.

bool isForBuilding(const LangOptions &LangOpts) const

Determine whether this module can be built in this compilation.

bool isInterfaceOrPartition() const

bool isModulePartitionImplementation() const

Is this a module partition implementation unit.

@ AllVisible

All of the names in this module are visible.

Module(ModuleConstructorTag, StringRef Name, SourceLocation DefinitionLoc, Module *Parent, bool IsFramework, bool IsExplicit, unsigned VisibilityID)

Construct a new module or submodule.

Module * Parent

The parent of this module.

ModuleKind Kind

The kind of this module.

llvm::SmallSetVector< Module *, 2 > Imports

The set of modules imported by this module, and on which this module depends.

std::string Name

The name of this module.

unsigned IsExternC

Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...

StringRef getPrimaryModuleInterfaceName() const

Get the primary module interface name from a partition.

bool isModulePartition() const

Is this a module partition.

bool isExplicitGlobalModule() const

bool isImplicitGlobalModule() const

bool isHeaderUnit() const

Is this module a header unit.

@ ModuleImplementationUnit

This is a C++20 module implementation unit.

@ ModuleMapModule

This is a module that was defined by a module map and built out of header files.

@ ImplicitGlobalModuleFragment

This is an implicit fragment of the global module which contains only language linkage declarations (...

@ ModulePartitionInterface

This is a C++20 module partition interface.

@ ModuleInterfaceUnit

This is a C++20 module interface unit.

@ ModuleHeaderUnit

This is a C++20 header unit.

@ ModulePartitionImplementation

This is a C++20 module partition implementation.

@ PrivateModuleFragment

This is the private module fragment within some C++ module.

@ ExplicitGlobalModuleFragment

This is the explicit Global Module Fragment of a modular TU.

std::string getFullModuleName(bool AllowStringLiterals=false) const

Retrieve the full name of this module, including the path from its top-level module.

bool isNamedModule() const

Does this Module is a named module of a standard named module?

This represents a decl that may have a name.

Linkage getLinkageInternal() const

Determine what kind of linkage this entity has.

Represents a parameter to a function.

HeaderSearch & getHeaderSearchInfo() const

A (possibly-)qualified type.

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

field_range fields() const

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

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

Emit a diagnostic.

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

void ActOnAnnotModuleBegin(SourceLocation DirectiveLoc, Module *Mod)

The parsed has entered a submodule.

Definition SemaModule.cpp:784

void ActOnAnnotModuleInclude(SourceLocation DirectiveLoc, Module *Mod)

The parser has processed a module import translated from a include or similar preprocessing directive...

Definition SemaModule.cpp:740

const TranslationUnitKind TUKind

The kind of translation unit we are processing.

@ PartitionImplementation

'module X:Y;'

@ Interface

'export module X;'

@ Implementation

'module X;'

@ PartitionInterface

'export module X:Y;'

llvm::DenseMap< NamedDecl *, NamedDecl * > VisibleNamespaceCache

Map from the most recent declaration of a namespace to the most recent visible declaration of that na...

void ActOnAnnotModuleEnd(SourceLocation DirectiveLoc, Module *Mod)

The parser has left a submodule.

Definition SemaModule.cpp:808

bool currentModuleIsImplementation() const

Is the module scope we are an implementation unit?

DeclResult ActOnModuleImport(SourceLocation StartLoc, SourceLocation ExportLoc, SourceLocation ImportLoc, ModuleIdPath Path, bool IsPartition=false)

The parser has processed a module import declaration.

Definition SemaModule.cpp:579

DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)

ASTContext & getASTContext() const

Decl * ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, SourceLocation LBraceLoc)

We have parsed the start of an export declaration, including the '{' (if present).

Definition SemaModule.cpp:867

const LangOptions & getLangOpts() const

void ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind)

DeclGroupPtrTy ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc)

The parser has processed a global-module-fragment declaration that begins the definition of the globa...

Definition SemaModule.cpp:169

DeclGroupPtrTy ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, ModuleDeclKind MDK, ModuleIdPath Path, ModuleIdPath Partition, ModuleImportState &ImportState, bool SeenNoTrivialPPDirective)

The parser has processed a module-declaration that begins the definition of a module interface or imp...

Definition SemaModule.cpp:265

Module * getCurrentModule() const

Get the module unit whose scope we are currently within.

DeclContext * CurContext

CurContext - This is the current declaration context of parsing.

DeclGroupPtrTy ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc, SourceLocation PrivateLoc)

The parser has processed a private-module-fragment declaration that begins the definition of the priv...

Definition SemaModule.cpp:517

SourceManager & getSourceManager() const

void BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod)

Definition SemaModule.cpp:745

bool isModuleVisible(const Module *M, bool ModulePrivate=false)

bool isSFINAEContext() const

ModuleImportState

An enumeration to represent the transition of states in parsing module fragments and imports.

@ FirstDecl

Parsing the first decl in a TU.

@ GlobalFragment

after 'module;' but before 'module X;'

@ NotACXX20Module

Not a C++20 TU, or an invalid state was found.

@ ImportAllowed

after 'module X;' but before any non-import decl.

ModuleLoader & getModuleLoader() const

Retrieve the module loader associated with the preprocessor.

void PushDeclContext(Scope *S, DeclContext *DC)

Set the current declaration context until it gets popped.

Decl * ActOnFinishExportDecl(Scope *S, Decl *ExportDecl, SourceLocation RBraceLoc)

Complete the definition of an export declaration.

Definition SemaModule.cpp:1016

OpaquePtr< DeclGroupRef > DeclGroupPtrTy

ASTMutationListener * getASTMutationListener() const

void createImplicitModuleImportForErrorRecovery(SourceLocation Loc, Module *Mod)

Create an implicit import of the given module at the given source location, for error recovery,...

Definition SemaModule.cpp:848

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

FileID getFileID(SourceLocation SpellingLoc) const

Return the FileID for a SourceLocation.

SourceLocation getIncludeLoc(FileID FID) const

Returns the include location if FID is a #include'd file otherwise it returns an invalid location.

bool isInSystemHeader(SourceLocation Loc) const

Returns if a SourceLocation is in a system header.

bool isWrittenInMainFile(SourceLocation Loc) const

Returns true if the spelling location for the given location is in the main file buffer.

A trivial tuple used to represent a source range.

SourceLocation getBegin() const

Stmt - This represents one statement.

@ Declaration

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

@ Type

The template argument is a type.

The top declaration context.

Linkage getLinkage() const

Determine the linkage of this type.

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

Represents a variable declaration or definition.

bool isConstexpr() const

Whether this variable is (C++11) constexpr.

bool isInline() const

Whether this variable is (C++1z) inline.

const Expr * getInit() const

A set of visible modules.

void setVisible(Module *M, SourceLocation Loc, bool IncludeExports=true, VisibleCallback Vis=[](Module *) {}, ConflictCallback Cb=[](ArrayRef< Module * >, Module *, StringRef) {})

Make a specific module visible.

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

bool isa(CodeGen::Address addr)

CustomizableOptional< FileEntryRef > OptionalFileEntryRef

ArrayRef< IdentifierLoc > ModuleIdPath

A sequence of identifier/location pairs used to describe a particular module or submodule,...

ActionResult< Decl * > DeclResult

Linkage

Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.

@ None

No linkage, which means that the entity is unique and can only be referred to from within its scope.

@ Internal

Internal linkage, which indicates that the entity can be referred to from within the translation unit...

@ Module

Module linkage, which indicates that the entity can be referred to from other translation units withi...

@ Global

The global module fragment, between 'module;' and a module-declaration.

@ Normal

A normal translation unit fragment.

@ TU_ClangModule

The translation unit is a clang module.

DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor

@ TSK_ImplicitInstantiation

This template specialization was implicitly instantiated from a template.

U cast(CodeGen::Address addr)

int const char * function