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

1

2

3

4

5

6

7

8

9

10

11

12

13

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

20

21using namespace clang;

22using namespace sema;

23

26 bool FromInclude = false) {

28

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

30 switch (LSD->getLanguage()) {

31 case LinkageSpecLanguageIDs::C:

33 ExternCLoc = LSD->getBeginLoc();

34 break;

35 case LinkageSpecLanguageIDs::CXX:

36 break;

37 }

39 }

40

41 while (isa(DC) || isa(DC))

43

44 if (!isa(DC)) {

46 ? diag::ext_module_import_not_at_top_level_noop

47 : diag::err_module_import_not_at_top_level_fatal)

49 S.Diag(cast(DC)->getBeginLoc(),

50 diag::note_module_import_not_at_top_level)

51 << DC;

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

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

56 }

57}

58

59

60

61

62

64 std::string Name;

65 if (Path.empty())

66 return Name;

67

68 for (auto &Piece : Path) {

69 if (!Name.empty())

70 Name += ".";

71 Name += Piece.first->getName();

72 }

73 return Name;

74}

75

76

77

78

79

80

81

82

83static bool

85 Module *CurrentModule,

86 Module *&FoundPrimaryModuleInterface) {

88 return false;

89

90

91

93 return true;

94

95

96

97 if (FoundPrimaryModuleInterface)

98 return Imported == FoundPrimaryModuleInterface;

99

100 if (!CurrentModule)

101 return false;

102

103

104

105

106

107

108

110 return false;

111

113 assert(!FoundPrimaryModuleInterface ||

114 FoundPrimaryModuleInterface == Imported);

115 FoundPrimaryModuleInterface = Imported;

116 return true;

117 }

118

119 return false;

120}

121

122

123

124

125

126

127

128static void

132 bool IsImportingPrimaryModuleInterface = false) {

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

135 "modules only.");

136

138 Worklist.push_back(Imported);

139

140 Module *FoundPrimaryModuleInterface =

141 IsImportingPrimaryModuleInterface ? Imported : nullptr;

142

143 while (!Worklist.empty()) {

144 Module *Importing = Worklist.pop_back_val();

145

146 if (VisibleModules.isVisible(Importing))

147 continue;

148

149

150

151 VisibleModules.setVisible(Importing, ImportLoc);

152

154 FoundPrimaryModuleInterface))

156 if (!VisibleModules.isVisible(TransImported))

157 Worklist.push_back(TransImported);

158 }

159}

160

163

164 Module *GlobalModule =

165 PushGlobalModuleFragment(ModuleLoc);

166

167

169

170

171

172

173

174

175

177 TU->setLocalOwningModule(GlobalModule);

178

179

180 return nullptr;

181}

182

183void Sema::HandleStartOfHeaderUnit() {

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

188

190 if (HUName.empty()) {

191 HUName =

194 }

195

196

197

198

200

201

202

203 if (!F)

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

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

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

210 ModuleScopes.push_back({});

211 ModuleScopes.back().BeginLoc = StartOfTU;

212 ModuleScopes.back().Module = Mod;

213 VisibleModules.setVisible(Mod, StartOfTU);

214

215

216

219 TU->setLocalOwningModule(Mod);

220}

221

222

223

224

227 enum {

228 Valid = -1,

230 Reserved = 1,

231 } Reason = Valid;

232

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

237 Reason = Reserved;

238

239

240

241

243 Reason = Valid;

244

245 switch (Reason) {

246 case Valid:

247 return false;

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

250 case Reserved:

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

252 return false;

253 }

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

255}

256

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

263

266

267

269

270 bool IsPartition = !Partition.empty();

271 if (IsPartition)

272 switch (MDK) {

275 break;

278 break;

279 default:

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

281 }

282

283

284

285

286

287

288 switch (getLangOpts().getCompilingModule()) {

290

291 break;

292

295 break;

296

297

298

299 Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch)

302 break;

303

305 Diag(ModuleLoc, diag::err_module_decl_in_module_map_module);

306 return nullptr;

307

309 Diag(ModuleLoc, diag::err_module_decl_in_header_unit);

310 return nullptr;

311 }

312

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

314

315

316

317

318

319 if (isCurrentModulePurview()) {

320 Diag(ModuleLoc, diag::err_module_redeclaration);

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

322 diag::note_prev_module_declaration);

323 return nullptr;

324 }

325

326 assert((getLangOpts().CPlusPlusModules ||

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

328 "mismatched global module state");

329

330

331

332 if (getLangOpts().CPlusPlusModules && !IsFirstDecl && !SeenGMF) {

333 Diag(ModuleLoc, diag::err_module_decl_not_at_start);

335 ModuleScopes.empty()

337 : ModuleScopes.back().BeginLoc;

338 if (BeginLoc.isValid()) {

339 Diag(BeginLoc, diag::note_global_module_introducer_missing)

341 }

342 }

343

344

345

346

347

348

349

350

351

352

353 StringRef FirstComponentName = Path[0].first->getName();

355 (FirstComponentName == "std" ||

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

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

358 Diag(Path[0].second, diag::warn_reserved_module_name) << Path[0].first;

359

360

361

362 for (auto Part : Path) {

364 return nullptr;

365 }

366

367

368

369

371 if (IsPartition) {

372 ModuleName += ":";

374 }

375

376

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

378 getLangOpts().CurrentModule != ModuleName) {

379 Diag(Path.front().second, diag::err_current_module_name_mismatch)

381 ? Partition.back().second

382 : Path.back().second)

384 return nullptr;

385 }

387

389 Module *Mod;

390 Module *Interface = nullptr;

391 switch (MDK) {

394

395

396 if (auto *M = Map.findModule(ModuleName)) {

397 Diag(Path[0].second, diag::err_module_redefinition) << ModuleName;

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

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

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

402 << FE->getName();

403 Mod = M;

404 break;

405 }

406

407

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

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

412 break;

413 }

414

416

417

418

419

420 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc(

422

423

424

425

426

430 false);

432

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

435

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

437 } else {

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

439 }

440 } break;

441

443

444

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

447 break;

448 }

449

450 if (!this->TheGlobalModuleFragment) {

451 ModuleScopes.push_back({});

452 if (getLangOpts().ModulesLocalVisibility)

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

454 } else {

455

457 }

458

459

460 ModuleScopes.back().BeginLoc = StartLoc;

461 ModuleScopes.back().Module = Mod;

462 VisibleModules.setVisible(Mod, ModuleLoc);

463

464

465

466

467

468

471 TU->setLocalOwningModule(Mod);

472

473

474

476

478

480 Listener->EnteringModulePurview();

481

482

483

484

486

488 Mod, ModuleLoc,

489 true);

490

491

495

496

497

500

502

503

505 }

506

507 return nullptr;

508}

509

513

514

515

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

524 Diag(PrivateLoc, diag::err_private_module_fragment_not_module);

525 return nullptr;

526

528 Diag(PrivateLoc, diag::err_private_module_fragment_redefined);

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

530 return nullptr;

531

533 Diag(PrivateLoc, diag::err_private_module_fragment_not_module_interface);

534 Diag(ModuleScopes.back().BeginLoc,

535 diag::note_not_module_interface_add_export)

537 return nullptr;

538

540 break;

541 }

542

543

544

545

546

547

549

551 Module *PrivateModuleFragment =

552 Map.createPrivateModuleFragmentForInterfaceUnit(

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

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

555

556

557 ModuleScopes.push_back({});

558 ModuleScopes.back().BeginLoc = ModuleLoc;

559 ModuleScopes.back().Module = PrivateModuleFragment;

560 VisibleModules.setVisible(PrivateModuleFragment, ModuleLoc);

561

562

563

564

567 TU->setLocalOwningModule(PrivateModuleFragment);

568

569

570 return nullptr;

571}

572

576 bool IsPartition) {

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

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

579

580

581

582 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;

583

584 std::string ModuleName;

585 if (IsPartition) {

586

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

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

589

590

592 ModuleName += ":";

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

600 }

601

602

603

604

605

606

607

608

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

611 Diag(ImportLoc, diag::err_module_self_import_cxx20)

613 return true;

614 }

615

618 if (!Mod)

619 return true;

620

623 Diag(ImportLoc, diag::err_module_import_non_interface_nor_parition)

624 << ModuleName;

625 return true;

626 }

627

629}

630

631

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

635 return ED;

636 return nullptr;

637}

638

644 Diag(ImportLoc, diag::warn_experimental_header_unit);

645

649 else

650 VisibleModules.setVisible(Mod, ImportLoc);

651

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

656 Diag(ImportLoc,

657 diag::warn_import_implementation_partition_unit_in_interface_unit)

658 << Mod->Name;

659

661

662

663

664

665

668 ? diag::err_module_self_import

669 : diag::err_module_import_in_implementation)

671 }

672

674

675 if (Path.empty()) {

676

677

678

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

682

683 IdentifierLocs.push_back(Path[0].second);

684 } else {

685 Module *ModCheck = Mod;

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

687

688

689 if (!ModCheck)

690 break;

691 ModCheck = ModCheck->Parent;

692

693 IdentifierLocs.push_back(Path[I].second);

694 }

695 }

696

698 Mod, IdentifierLocs);

700

701

702

703 if (!ModuleScopes.empty())

705

706

709 Diag(ExportLoc, diag::err_export_partition_impl)

712

713

714

717 else

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

720

721

722

723 Diag(ExportLoc, diag::err_export_not_in_module_interface);

724 }

725

726 return Import;

727}

728

732}

733

735

736

737

738

739

740 bool IsInModuleIncludes =

743

744

745

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

749 DirectiveLoc, Mod,

750 DirectiveLoc);

751 if (!ModuleScopes.empty())

755 }

756

758 VisibleModules.setVisible(Mod, DirectiveLoc);

759

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

763 (void)ThisModule;

764 assert(ThisModule && "was expecting a module if building one");

765 }

766}

767

770

771 ModuleScopes.push_back({});

772 ModuleScopes.back().Module = Mod;

773 if (getLangOpts().ModulesLocalVisibility)

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

775

776 VisibleModules.setVisible(Mod, DirectiveLoc);

777

778

779

780

781 if (getLangOpts().trackLocalOwningModule()) {

783 cast(DC)->setModuleOwnershipKind(

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

788 }

789 }

790}

791

793 if (getLangOpts().ModulesLocalVisibility) {

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

795

796

798 }

799

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

801 "left the wrong module scope");

802 ModuleScopes.pop_back();

803

804

805

809

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

813 } else {

814

815 DirectiveLoc = EomLoc;

816 }

818

819

820 if (getLangOpts().trackLocalOwningModule()) {

821

822

826 cast(DC)->setModuleOwnershipKind(

828 }

829 }

830}

831

834

837 return;

838

839

845

846

849}

850

854

855

856 D->setRBraceLoc(LBraceLoc);

857

860

861

862

863

864

866 if (!isCurrentModulePurview()) {

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

869 return D;

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

872 Diag(ModuleScopes.back().BeginLoc,

873 diag::note_not_module_interface_add_export)

876 return D;

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

879 Diag(ExportLoc, diag::err_export_in_private_module_fragment);

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

882 return D;

883 }

884 }

885

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

888

889

890 if (ND->isAnonymousNamespace()) {

891 Diag(ExportLoc, diag::err_export_within_anonymous_namespace);

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

893

895 return D;

896 }

897

898

899

900

901

902

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

904 break;

905 }

906 }

907

908

909

911 Diag(ExportLoc, diag::err_export_within_export);

912 if (ED->hasBraces())

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

915 return D;

916 }

917

920

921 return D;

922}

923

925

926

929 bool AllUnnamed = true;

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

932 return AllUnnamed;

933}

934

935

937

938

940

941 if (!dyn_cast(D) && !dyn_cast(D)) {

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

944 return false;

945 }

946 }

947

948

949

950 bool HasName = false;

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

952

953

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

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

957 if (BlockStart.isValid())

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

959 return false;

960 }

961 }

962

963

964

965

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

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

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

973 if (BlockStart.isValid())

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

975 return false;

976 }

977 }

978

979

980

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

982 if (!isa(D))

983 return true;

984

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

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

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

988 if (BlockStart.isValid())

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

990 return false;

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

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

994 }

995 }

996 }

997 return true;

998}

999

1001 auto *ED = cast(D);

1002 if (RBraceLoc.isValid())

1003 ED->setRBraceLoc(RBraceLoc);

1004

1006

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

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

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

1013

1014

1015

1016

1017

1018

1019

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

1021 PendingInlineFuncDecls.insert(FD);

1022 }

1023 }

1024 }

1025

1026

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

1029

1030 return D;

1031}

1032

1034

1035

1036 if (!TheGlobalModuleFragment) {

1040 }

1041

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

1043

1044

1045 ModuleScopes.push_back({BeginLoc, TheGlobalModuleFragment,

1046 {}});

1047 VisibleModules.setVisible(TheGlobalModuleFragment, BeginLoc);

1048

1049 return TheGlobalModuleFragment;

1050}

1051

1052void Sema::PopGlobalModuleFragment() {

1053 assert(!ModuleScopes.empty() &&

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

1056 ModuleScopes.pop_back();

1057}

1058

1060 if (!TheImplicitGlobalModuleFragment) {

1062 TheImplicitGlobalModuleFragment =

1065 }

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

1067

1068

1069 ModuleScopes.push_back({BeginLoc, TheImplicitGlobalModuleFragment,

1070 {}});

1071 VisibleModules.setVisible(TheImplicitGlobalModuleFragment, BeginLoc);

1072 return TheImplicitGlobalModuleFragment;

1073}

1074

1075void Sema::PopImplicitGlobalModuleFragment() {

1076 assert(!ModuleScopes.empty() &&

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

1079 ModuleScopes.pop_back();

1080}

1081

1082bool Sema::isCurrentModulePurview() const {

1084 return false;

1085

1086

1087

1095 return true;

1096 default:

1097 return false;

1098 }

1099}

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

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.

static const ExportDecl * getEnclosingExportDecl(const Decl *D)

Determine whether D is lexically within an export-declaration.

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

Check that it's valid to export D.

static std::string stringFromPath(ModuleIdPath Path)

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

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

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

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

Helper function for makeTransitiveImportsVisible to decide whether the.

virtual void HandleImplicitImportDecl(ImportDecl *D)

Handle an ImportDecl that was implicitly created due to an inclusion directive.

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.

void addModuleInitializer(Module *M, Decl *Init)

Add a declaration to the list of declarations that are initialized for a module.

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

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

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

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.

DeclContext * getLexicalParent()

getLexicalParent - Returns the containing lexical DeclContext.

void addDecl(Decl *D)

Add the declaration D into this context.

decl_range decls() const

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

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

void setInvalidDecl(bool Invalid=true)

setInvalidDecl - Indicates the Decl had a semantic error.

bool isInvalidDecl() 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)

StringRef getName() const

The name of this FileEntry.

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

OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)

Get a FileEntryRef if it exists, without doing anything on error.

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.

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.

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.

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

NamedDecl * getUnderlyingDecl()

Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.

Linkage getFormalLinkage() const

Get the linkage from a semantic point of view.

Wrapper for void* pointer.

IdentifierInfo * getIdentifierInfo(StringRef Name) const

Return information about the specified preprocessor identifier token.

HeaderSearch & getHeaderSearchInfo() const

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

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

Emit a diagnostic.

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

void ActOnAnnotModuleBegin(SourceLocation DirectiveLoc, Module *Mod)

The parsed has entered a submodule.

void ActOnAnnotModuleInclude(SourceLocation DirectiveLoc, Module *Mod)

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

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

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

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

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.

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.

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

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

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

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

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

SourceManager & getSourceManager() const

void BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod)

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

@ Global

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

@ Normal

A normal translation unit fragment.

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.

SourceManager & SourceMgr

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

Complete the definition of an export declaration.

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

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.

OptionalFileEntryRef getFileEntryRefForID(FileID FID) const

Returns the FileEntryRef for the provided FileID.

FileManager & getFileManager() const

FileID getMainFileID() const

Returns the FileID of the main source file.

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.

SourceLocation getLocForStartOfFile(FileID FID) const

Return the source location corresponding to the first byte of the specified file.

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.

The top declaration context.

A set of visible modules.

SourceLocation getImportLoc(const Module *M) const

Get the location at which the import of a module was triggered.

bool isVisible(const Module *M) const

Determine whether a module is visible.

void setVisible(Module *M, SourceLocation Loc, 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.

ArrayRef< std::pair< IdentifierInfo *, SourceLocation > > ModuleIdPath

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

Linkage

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

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

@ TU_ClangModule

The translation unit is a clang module.