clang: lib/Basic/Module.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

20#include "llvm/ADT/ArrayRef.h"

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

22#include "llvm/ADT/StringMap.h"

23#include "llvm/ADT/StringRef.h"

24#include "llvm/ADT/StringSwitch.h"

25#include "llvm/Support/Compiler.h"

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

27#include "llvm/Support/raw_ostream.h"

28#include

29#include

30#include

31#include

32#include

33

34using namespace clang;

35

38 bool IsExplicit, unsigned VisibilityID)

55

56 Parent->SubModules.push_back(this);

57 }

58}

59

61

63 StringRef Platform = Target.getPlatformName();

64 StringRef Env = Target.getTriple().getEnvironmentName();

65

66

69 return true;

70

71 auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {

72 auto Pos = LHS.find('-');

73 if (Pos == StringRef::npos)

74 return false;

76 NewLHS += LHS.slice(Pos+1, LHS.size());

77 return NewLHS == RHS;

78 };

79

81

82

83

84

85

86

87 if (Target.getTriple().isOSDarwin() && PlatformEnv.ends_with("simulator"))

88 return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);

89

90 return PlatformEnv == Feature;

91}

92

93

94

98 .Case("altivec", LangOpts.AltiVec)

99 .Case("blocks", LangOpts.Blocks)

100 .Case("coroutines", LangOpts.Coroutines)

101 .Case("cplusplus", LangOpts.CPlusPlus)

102 .Case("cplusplus11", LangOpts.CPlusPlus11)

103 .Case("cplusplus14", LangOpts.CPlusPlus14)

104 .Case("cplusplus17", LangOpts.CPlusPlus17)

105 .Case("cplusplus20", LangOpts.CPlusPlus20)

106 .Case("cplusplus23", LangOpts.CPlusPlus23)

107 .Case("cplusplus26", LangOpts.CPlusPlus26)

108 .Case("c99", LangOpts.C99)

109 .Case("c11", LangOpts.C11)

110 .Case("c17", LangOpts.C17)

111 .Case("c23", LangOpts.C23)

112 .Case("freestanding", LangOpts.Freestanding)

113 .Case("gnuinlineasm", LangOpts.GNUAsm)

114 .Case("objc", LangOpts.ObjC)

115 .Case("objc_arc", LangOpts.ObjCAutoRefCount)

116 .Case("opencl", LangOpts.OpenCL)

117 .Case("tls", Target.isTLSSupported())

118 .Case("zvector", LangOpts.ZVector)

124}

125

130 return false;

131

132 for (const Module *Current = this; Current; Current = Current->Parent) {

133 if (Current->ShadowingModule) {

135 return true;

136 }

137 for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {

138 if (hasFeature(Current->Requirements[I].FeatureName, LangOpts, Target) !=

139 Current->Requirements[I].RequiredState) {

140 Req = Current->Requirements[I];

141 return true;

142 }

143 }

144 }

145

146 llvm_unreachable("could not find a reason why module is unimportable");

147}

148

149

150

151

152

153

154

157 StringRef CurrentModule = LangOpts.CurrentModule;

158

159

160

161

163 CurrentModule == LangOpts.ModuleName &&

164 !CurrentModule.ends_with("_Private") &&

165 TopLevelName.ends_with("_Private"))

166 TopLevelName = TopLevelName.drop_back(8);

167

168 return TopLevelName == CurrentModule;

169}

170

176 return true;

177

179 return false;

180

181

182

183 for (const Module *Current = this; Current; Current = Current->Parent) {

184 if (!Current->MissingHeaders.empty()) {

185 MissingHeader = Current->MissingHeaders.front();

186 return false;

187 }

188 }

189

190 llvm_unreachable("could not find a reason why module is unavailable");

191}

192

196 return true;

197 }

198 return false;

199}

200

203 while (Result->Parent)

205

207}

208

210 const std::pair<std::string, SourceLocation> &IdComponent) {

211 return IdComponent.first;

212}

213

215

216template

217static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,

218 bool AllowStringLiterals = true) {

219 for (InputIter It = Begin; It != End; ++It) {

220 if (It != Begin)

221 OS << ".";

222

225 OS << Name;

226 else {

227 OS << '"';

228 OS.write_escaped(Name);

229 OS << '"';

230 }

231 }

232}

233

234template

238

241

242

243 for (const Module *M = this; M; M = M->Parent)

244 Names.push_back(M->Name);

245

247

248 llvm::raw_string_ostream Out(Result);

249 printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);

250

252}

253

255 for (const Module *M = this; M; M = M->Parent) {

256 if (nameParts.empty() || M->Name != nameParts.back())

257 return false;

258 nameParts = nameParts.drop_back();

259 }

260 return nameParts.empty();

261}

262

264 if (const auto *Hdr = std::get_if(&Umbrella))

265 return Hdr->getDir();

266 if (const auto *Dir = std::get_if(&Umbrella))

267 return *Dir;

268 return std::nullopt;

269}

270

272 assert(File);

273 TopHeaders.insert(File);

274}

275

277 if (!TopHeaderNames.empty()) {

278 for (StringRef TopHeaderName : TopHeaderNames)

279 if (auto FE = FileMgr.getOptionalFileRef(TopHeaderName))

280 TopHeaders.insert(*FE);

281 TopHeaderNames.clear();

282 }

283

284 return llvm::ArrayRef(TopHeaders.begin(), TopHeaders.end());

285}

286

289

290

292 return true;

293

294 for (auto *Use : Top->DirectUses)

296 return true;

297

298

299 if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) ||

301 return true;

302

303

304 if (!Requested->Parent && Requested->Name == "ptrauth")

305 return true;

306

309

310 return false;

311}

312

317

318

320 return;

321

323}

324

326 auto needUpdate = [Unimportable](Module *M) {

327 return M->IsAvailable || (!M->IsUnimportable && Unimportable);

328 };

329

330 if (!needUpdate(this))

331 return;

332

334 Stack.push_back(this);

335 while (!Stack.empty()) {

336 Module *Current = Stack.pop_back_val();

337

338 if (!needUpdate(Current))

339 continue;

340

343 for (auto *Submodule : Current->submodules()) {

344 if (needUpdate(Submodule))

345 Stack.push_back(Submodule);

346 }

347 }

348}

349

351

352 for (unsigned I = SubModuleIndex.size(), E = SubModules.size(); I != E; ++I)

353 SubModuleIndex[SubModules[I]->Name] = I;

354

355 if (auto It = SubModuleIndex.find(Name); It != SubModuleIndex.end())

356 return SubModules[It->second];

357

358 return nullptr;

359}

360

362 assert(isNamedModuleUnit() && "We should only query the global module "

363 "fragment from the C++20 Named modules");

364

365 for (auto *SubModule : SubModules)

366 if (SubModule->isExplicitGlobalModule())

367 return SubModule;

368

369 return nullptr;

370}

371

373 assert(isNamedModuleUnit() && "We should only query the private module "

374 "fragment from the C++20 Named modules");

375

376 for (auto *SubModule : SubModules)

377 if (SubModule->isPrivateModule())

378 return SubModule;

379

380 return nullptr;

381}

382

384

385 for (std::vector<Module *>::const_iterator I = SubModules.begin(),

386 E = SubModules.end();

387 I != E; ++I) {

390 Exported.push_back(Mod);

391 }

392

393

394 bool AnyWildcard = false;

395 bool UnrestrictedWildcard = false;

397 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {

399 if (Exports[I].getInt()) {

400

401 Exported.push_back(Mod);

402

403 continue;

404 }

405

406

407

408 AnyWildcard = true;

409 if (UnrestrictedWildcard)

410 continue;

411

412 if (Module *Restriction = Exports[I].getPointer())

413 WildcardRestrictions.push_back(Restriction);

414 else {

415 WildcardRestrictions.clear();

416 UnrestrictedWildcard = true;

417 }

418 }

419

420

421

422 if (!AnyWildcard)

423 return;

424

425 for (unsigned I = 0, N = Imports.size(); I != N; ++I) {

427 bool Acceptable = UnrestrictedWildcard;

428 if (!Acceptable) {

429

430 for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {

431 Module *Restriction = WildcardRestrictions[R];

432 if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {

433 Acceptable = true;

434 break;

435 }

436 }

437 }

438

439 if (!Acceptable)

440 continue;

441

442 Exported.push_back(Mod);

443 }

444}

445

446void Module::buildVisibleModulesCache() const {

447 assert(VisibleModulesCache.empty() && "cache does not need building");

448

449

450 VisibleModulesCache.insert(this);

451

452

454 while (!Stack.empty()) {

455 Module *CurrModule = Stack.pop_back_val();

456

457

458 if (VisibleModulesCache.insert(CurrModule).second)

460 }

461}

462

466 OS << "framework ";

468 OS << "explicit ";

469 OS << "module ";

471

473 OS.indent(Indent + 2);

475 OS << " [system]";

477 OS << " [extern_c]";

478 }

479

480 OS << " {\n";

481

483 OS.indent(Indent + 2);

484 OS << "requires ";

485 for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {

486 if (I)

487 OS << ", ";

489 OS << "!";

491 }

492 OS << "\n";

493 }

494

496 OS.indent(Indent + 2);

497 OS << "umbrella header \"";

498 OS.write_escaped(H->NameAsWritten);

499 OS << "\"\n";

501 OS.indent(Indent + 2);

502 OS << "umbrella \"";

503 OS.write_escaped(D->NameAsWritten);

504 OS << "\"\n";

505 }

506

508 OS.indent(Indent + 2);

509 OS << "config_macros ";

511 OS << "[exhaustive]";

512 for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {

513 if (I)

514 OS << ", ";

516 }

517 OS << "\n";

518 }

519

520 struct {

521 StringRef Prefix;

528

529 for (auto &K : Kinds) {

530 assert(&K == &Kinds[K.Kind] && "kinds in wrong order");

532 OS.indent(Indent + 2);

533 OS << K.Prefix << "header \"";

534 OS.write_escaped(H.NameAsWritten);

535 OS << "\" { size " << H.Entry.getSize()

536 << " mtime " << H.Entry.getModificationTime() << " }\n";

537 }

538 }

541 OS.indent(Indent + 2);

542 OS << Kinds[U.Kind].Prefix << "header \"";

543 OS.write_escaped(U.FileName);

544 OS << "\"";

545 if (U.Size || U.ModTime) {

546 OS << " {";

547 if (U.Size)

548 OS << " size " << *U.Size;

549 if (U.ModTime)

550 OS << " mtime " << *U.ModTime;

551 OS << " }";

552 }

553 OS << "\n";

554 }

555 }

556

558 OS.indent(Indent + 2);

560 }

561

563

564

565

566

567 if (!Submodule->IsInferred || Submodule->IsFramework)

568 Submodule->print(OS, Indent + 2, Dump);

569

570 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {

571 OS.indent(Indent + 2);

572 OS << "export ";

573 if (Module *Restriction = Exports[I].getPointer()) {

574 OS << Restriction->getFullModuleName(true);

576 OS << ".*";

577 } else {

578 OS << "*";

579 }

580 OS << "\n";

581 }

582

583 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {

584 OS.indent(Indent + 2);

585 OS << "export ";

589 OS << "\n";

590 }

591

592 if (Dump) {

594 OS.indent(Indent + 2);

595 llvm::errs() << "import " << M->getFullModuleName() << "\n";

596 }

597 }

598

599 for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {

600 OS.indent(Indent + 2);

601 OS << "use ";

602 OS << DirectUses[I]->getFullModuleName(true);

603 OS << "\n";

604 }

605

607 OS.indent(Indent + 2);

608 OS << "use ";

610 OS << "\n";

611 }

612

613 for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {

614 OS.indent(Indent + 2);

615 OS << "link ";

617 OS << "framework ";

618 OS << "\"";

620 OS << "\"";

621 }

622

624 OS.indent(Indent + 2);

625 OS << "conflict ";

627 OS << ", \"";

629 OS << "\"\n";

630 }

631

632 for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {

633 OS.indent(Indent + 2);

634 OS << "conflict ";

635 OS << Conflicts[I].Other->getFullModuleName(true);

636 OS << ", \"";

637 OS.write_escaped(Conflicts[I].Message);

638 OS << "\"\n";

639 }

640

642 OS.indent(Indent + 2);

644 OS << "explicit ";

645 OS << "module * {\n";

647 OS.indent(Indent + 4);

648 OS << "export *\n";

649 }

650 OS.indent(Indent + 2);

651 OS << "}\n";

652 }

653

655 OS << "}\n";

656}

657

659 print(llvm::errs(), 0, true);

660}

661

665

667 "setVisible expects a valid import location");

669 return;

670

671 ++Generation;

672

673 struct Visiting {

675 Visiting *ExportedBy;

676 };

677

678 std::function<void(Visiting)> VisitModule = [&](Visiting V) {

679

680 unsigned ID = V.M->getVisibilityID();

681 if (ImportLocs.size() <= ID)

682 ImportLocs.resize(ID + 1);

683 else if (ImportLocs[ID].isValid())

684 return;

685

686 ImportLocs[ID] = Loc;

687 Vis(V.M);

688

689

690 if (IncludeExports) {

692 V.M->getExportedModules(Exports);

693 for (Module *E : Exports) {

694

695 if (!E->isUnimportable())

696 VisitModule({E, &V});

697 }

698 }

699

700 for (auto &C : V.M->Conflicts) {

703 for (Visiting *I = &V; I; I = I->ExportedBy)

704 Path.push_back(I->M);

705 Cb(Path, C.Other, C.Message);

706 }

707 }

708 };

709 VisitModule({M, nullptr});

710}

Defines the clang::FileManager interface and associated types.

Defines the clang::LangOptions interface.

llvm::MachO::Target Target

static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature)

Definition Module.cpp:62

static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target)

Determine whether a translation unit built using the current language options has the given feature.

Definition Module.cpp:95

static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, bool AllowStringLiterals=true)

Definition Module.cpp:217

static StringRef getModuleNameFromComponent(const std::pair< std::string, SourceLocation > &IdComponent)

Definition Module.cpp:209

Defines the clang::Module class, which describes a module in the source code.

static bool HasFeature(const Preprocessor &PP, StringRef Feature)

HasFeature - Return true if we recognize and implement the feature specified by the identifier as a s...

Defines the clang::SourceLocation class and associated facilities.

A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...

Implements support for file system lookup, file system caching, and directory search management.

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

std::string ModuleName

The module currently being compiled as specified by -fmodule-name.

bool isCompilingModule() const

Are we compiling a module?

std::string CurrentModule

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

std::vector< std::string > ModuleFeatures

The names of any features to enable in module 'requires' decls in addition to the hard-coded list in ...

Required to construct a Module.

Describes a module or submodule.

StringRef getTopLevelModuleName() const

Retrieve the name of the top-level module.

void addRequirement(StringRef Feature, bool RequiredState, const LangOptions &LangOpts, const TargetInfo &Target)

Add the given feature requirement to the list of features required by this module.

Definition Module.cpp:313

unsigned IsExplicit

Whether this is an explicit 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.

Definition Module.cpp:155

std::variant< std::monostate, FileEntryRef, DirectoryEntryRef > Umbrella

The umbrella header or directory.

unsigned InferSubmodules

Whether we should infer submodules for this module based on the headers.

Module * findSubmodule(StringRef Name) const

Find the submodule with the given name.

Definition Module.cpp:350

bool directlyUses(const Module *Requested)

Determine whether this module has declared its intention to directly use another module.

Definition Module.cpp:287

std::vector< std::string > ConfigMacros

The set of "configuration macros", which are macros that (intentionally) change how this module is bu...

unsigned IsUnimportable

Whether this module has declared itself unimportable, either because it's missing a requirement from ...

NameVisibilityKind NameVisibility

The visibility of names within this particular module.

@ Hidden

All of the names in this module are hidden.

void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const

Print the module map for this module to the given stream.

Definition Module.cpp:463

bool isNamedModuleUnit() const

Is this a C++20 named module unit.

SourceLocation DefinitionLoc

The location of the module definition.

SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders

Headers that are mentioned in the module map file but could not be found on the file system.

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

Construct a new module or submodule.

Definition Module.cpp:36

Module * Parent

The parent of this module.

void markUnavailable(bool Unimportable)

Mark this module and all of its submodules as unavailable.

Definition Module.cpp:325

SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders

Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...

ModuleKind Kind

The kind of this module.

bool isUnimportable() const

Determine whether this module has been declared unimportable.

bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const

Whether the full name of this module is equal to joining nameParts with "."s.

Definition Module.cpp:254

Module * getPrivateModuleFragment() const

Get the Private Module Fragment (sub-module) for this module, it there is one.

Definition Module.cpp:372

unsigned IsInferred

Whether this is an inferred submodule (module * { ... }).

llvm::SmallSetVector< Module *, 2 > Imports

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

unsigned IsSystem

Whether this is a "system" module (which assumes that all headers in it are system headers).

std::string Name

The name of this module.

Module * getGlobalModuleFragment() const

Get the Global Module Fragment (sub-module) for this module, it there is one.

Definition Module.cpp:361

llvm::iterator_range< submodule_iterator > submodules()

unsigned IsExternC

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

unsigned ModuleMapIsPrivate

Whether this module came from a "private" module map, found next to a regular (public) module map.

llvm::SmallVector< LinkLibrary, 2 > LinkLibraries

The set of libraries or frameworks to link against when an entity from this module is used.

SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports

The set of export declarations that have yet to be resolved.

std::optional< Header > getUmbrellaHeaderAsWritten() const

Retrieve the umbrella header as written.

SmallVector< Requirement, 2 > Requirements

The set of language features required to use this module.

llvm::SmallSetVector< const Module *, 2 > UndeclaredUses

When NoUndeclaredIncludes is true, the set of modules this module tried to import but didn't because ...

SmallVector< ModuleId, 2 > UnresolvedDirectUses

The set of use declarations that have yet to be resolved.

unsigned NamedModuleHasInit

Whether this C++20 named modules doesn't need an initializer.

unsigned NoUndeclaredIncludes

Whether files in this module can only include non-modular headers and headers from used modules.

SmallVector< Module *, 2 > DirectUses

The directly used modules.

unsigned ConfigMacrosExhaustive

Whether the set of configuration macros is exhaustive.

ArrayRef< Header > getHeaders(HeaderKind HK) const

bool isGlobalModule() const

Does this Module scope describe a fragment of the global module within some C++ module.

unsigned InferExportWildcard

Whether, when inferring submodules, the inferr submodules should export all modules they import (e....

void getExportedModules(SmallVectorImpl< Module * > &Exported) const

Appends this module's list of exported modules to Exported.

Definition Module.cpp:383

std::vector< UnresolvedConflict > UnresolvedConflicts

The list of conflicts for which the module-id has not yet been resolved.

unsigned IsFromModuleFile

Whether this module was loaded from a module file.

bool isSubModuleOf(const Module *Other) const

Check if this module is a (possibly transitive) submodule of Other.

Definition Module.cpp:193

ArrayRef< FileEntryRef > getTopHeaders(FileManager &FileMgr)

The top-level headers associated with this module.

Definition Module.cpp:276

bool isAvailable() const

Determine whether this module is available for use within the current translation unit.

std::optional< DirectoryName > getUmbrellaDirAsWritten() const

Retrieve the umbrella directory as written.

unsigned HasIncompatibleModuleFile

Whether we tried and failed to load a module file for this module.

void dump() const

Dump the contents of this module to the given output stream.

Module * ShadowingModule

A module with the same name that shadows this module.

unsigned IsFramework

Whether this is a framework module.

std::string ExportAsModule

The module through which entities defined in this module will eventually be exposed,...

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

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

Definition Module.cpp:239

void addTopHeader(FileEntryRef File)

Add a top-level header associated with this module.

Definition Module.cpp:271

unsigned IsAvailable

Whether this module is available in the current translation unit.

unsigned InferExplicitSubmodules

Whether, when inferring submodules, the inferred submodules should be explicit.

Module * getTopLevelModule()

Retrieve the top-level module for this (sub)module, which may be this module.

OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const

Get the effective umbrella directory for this module: either the one explicitly written in the module...

Definition Module.cpp:263

std::vector< Conflict > Conflicts

The list of conflicts.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

Exposes information about the current target.

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

Make a specific module visible.

Definition Module.cpp:662

llvm::function_ref< void(Module *M)> VisibleCallback

A callback to call when a module is made visible (directly or indirectly) by a call to setVisible.

llvm::function_ref< void(ArrayRef< Module * > Path, Module *Conflict, StringRef Message)> ConflictCallback

A callback to call when a module conflict is found.

bool isVisible(const Module *M) const

Determine whether a module is visible.

Defines the clang::TargetInfo interface.

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

LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)

Return true if this is a valid ASCII identifier.

raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)

@ Result

The result type of a method or function.

CustomizableOptional< DirectoryEntryRef > OptionalDirectoryEntryRef

@ Other

Other implicit parameter.

int const char * function