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#include

34

35using namespace clang;

36

39 bool IsExplicit, unsigned VisibilityID)

40 : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),

41 VisibilityID(VisibilityID), IsUnimportable(false),

42 HasIncompatibleModuleFile(false), IsAvailable(true),

43 IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),

45 InferSubmodules(false), InferExplicitSubmodules(false),

46 InferExportWildcard(false), ConfigMacrosExhaustive(false),

47 NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),

48 NamedModuleHasInit(true), NameVisibility(Hidden) {

56

57 Parent->SubModules.push_back(this);

58 }

59}

60

62

64 StringRef Platform = Target.getPlatformName();

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

66

67

68 if (Platform == Feature || Target.getTriple().getOSName() == Feature ||

69 Env == Feature)

70 return true;

71

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

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

74 if (Pos == StringRef::npos)

75 return false;

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

78 return NewLHS == RHS;

79 };

80

82

83

84

85

86

87

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

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

90

91 return PlatformEnv == Feature;

92}

93

94

95

98 bool HasFeature = llvm::StringSwitch(Feature)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

120 .Default(Target.hasFeature(Feature) ||

125}

126

129 Module *&ShadowingModule) const {

131 return false;

132

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

134 if (Current->ShadowingModule) {

136 return true;

137 }

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

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

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

141 Req = Current->Requirements[I];

142 return true;

143 }

144 }

145 }

146

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

148}

149

150

151

152

153

154

155

158 StringRef CurrentModule = LangOpts.CurrentModule;

159

160

161

162

164 CurrentModule == LangOpts.ModuleName &&

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

166 TopLevelName.ends_with("_Private"))

167 TopLevelName = TopLevelName.drop_back(8);

168

169 return TopLevelName == CurrentModule;

170}

171

175 Module *&ShadowingModule) const {

177 return true;

178

180 return false;

181

182

183

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

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

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

187 return false;

188 }

189 }

190

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

192}

193

197 return true;

198 }

199 return false;

200}

201

204 while (Result->Parent)

206

208}

209

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

212 return IdComponent.first;

213}

214

216

217template

219 bool AllowStringLiterals = true) {

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

222 OS << ".";

223

226 OS << Name;

227 else {

228 OS << '"';

229 OS.write_escaped(Name);

230 OS << '"';

231 }

232 }

233}

234

235template

238}

239

242

243

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

245 Names.push_back(M->Name);

246

248

249 llvm::raw_string_ostream Out(Result);

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

251

253}

254

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

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

258 return false;

259 nameParts = nameParts.drop_back();

260 }

261 return nameParts.empty();

262}

263

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

266 return Hdr->getDir();

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

268 return *Dir;

269 return std::nullopt;

270}

271

273 assert(File);

274 TopHeaders.insert(File);

275}

276

278 if (!TopHeaderNames.empty()) {

279 for (StringRef TopHeaderName : TopHeaderNames)

281 TopHeaders.insert(*FE);

282 TopHeaderNames.clear();

283 }

284

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

286}

287

290

291

293 return true;

294

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

297 return true;

298

299

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

302 return true;

303

304

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

306 return true;

307

310

311 return false;

312}

313

318

319

321 return;

322

324}

325

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

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

329 };

330

331 if (!needUpdate(this))

332 return;

333

335 Stack.push_back(this);

336 while (!Stack.empty()) {

337 Module *Current = Stack.back();

338 Stack.pop_back();

339

340 if (!needUpdate(Current))

341 continue;

342

343 Current->IsAvailable = false;

344 Current->IsUnimportable |= Unimportable;

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

346 if (needUpdate(Submodule))

347 Stack.push_back(Submodule);

348 }

349 }

350}

351

353

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

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

356

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

358 return SubModules[It->second];

359

360 return nullptr;

361}

362

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

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

366

367 for (auto *SubModule : SubModules)

368 if (SubModule->isExplicitGlobalModule())

369 return SubModule;

370

371 return nullptr;

372}

373

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

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

377

378 for (auto *SubModule : SubModules)

379 if (SubModule->isPrivateModule())

380 return SubModule;

381

382 return nullptr;

383}

384

386

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

388 E = SubModules.end();

389 I != E; ++I) {

392 Exported.push_back(Mod);

393 }

394

395

396 bool AnyWildcard = false;

397 bool UnrestrictedWildcard = false;

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

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

402

403 Exported.push_back(Mod);

404

405 continue;

406 }

407

408

409

410 AnyWildcard = true;

411 if (UnrestrictedWildcard)

412 continue;

413

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

415 WildcardRestrictions.push_back(Restriction);

416 else {

417 WildcardRestrictions.clear();

418 UnrestrictedWildcard = true;

419 }

420 }

421

422

423

424 if (!AnyWildcard)

425 return;

426

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

429 bool Acceptable = UnrestrictedWildcard;

430 if (!Acceptable) {

431

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

433 Module *Restriction = WildcardRestrictions[R];

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

435 Acceptable = true;

436 break;

437 }

438 }

439 }

440

441 if (!Acceptable)

442 continue;

443

444 Exported.push_back(Mod);

445 }

446}

447

448void Module::buildVisibleModulesCache() const {

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

450

451

452 VisibleModulesCache.insert(this);

453

454

456 while (!Stack.empty()) {

457 Module *CurrModule = Stack.pop_back_val();

458

459

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

462 }

463}

464

465void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {

466 OS.indent(Indent);

468 OS << "framework ";

470 OS << "explicit ";

471 OS << "module ";

473

475 OS.indent(Indent + 2);

477 OS << " [system]";

479 OS << " [extern_c]";

480 }

481

482 OS << " {\n";

483

485 OS.indent(Indent + 2);

486 OS << "requires ";

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

488 if (I)

489 OS << ", ";

491 OS << "!";

493 }

494 OS << "\n";

495 }

496

498 OS.indent(Indent + 2);

499 OS << "umbrella header \"";

500 OS.write_escaped(H->NameAsWritten);

501 OS << "\"\n";

503 OS.indent(Indent + 2);

504 OS << "umbrella \"";

505 OS.write_escaped(D->NameAsWritten);

506 OS << "\"\n";

507 }

508

510 OS.indent(Indent + 2);

511 OS << "config_macros ";

513 OS << "[exhaustive]";

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

515 if (I)

516 OS << ", ";

518 }

519 OS << "\n";

520 }

521

522 struct {

523 StringRef Prefix;

530

531 for (auto &K : Kinds) {

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

534 OS.indent(Indent + 2);

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

536 OS.write_escaped(H.NameAsWritten);

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

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

539 }

540 }

543 OS.indent(Indent + 2);

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

545 OS.write_escaped(U.FileName);

546 OS << "\"";

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

548 OS << " {";

549 if (U.Size)

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

551 if (U.ModTime)

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

553 OS << " }";

554 }

555 OS << "\n";

556 }

557 }

558

560 OS.indent(Indent + 2);

562 }

563

565

566

567

568

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

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

571

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

573 OS.indent(Indent + 2);

574 OS << "export ";

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

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

578 OS << ".*";

579 } else {

580 OS << "*";

581 }

582 OS << "\n";

583 }

584

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

586 OS.indent(Indent + 2);

587 OS << "export ";

591 OS << "\n";

592 }

593

594 if (Dump) {

596 OS.indent(Indent + 2);

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

598 }

599 }

600

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

602 OS.indent(Indent + 2);

603 OS << "use ";

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

605 OS << "\n";

606 }

607

609 OS.indent(Indent + 2);

610 OS << "use ";

612 OS << "\n";

613 }

614

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

616 OS.indent(Indent + 2);

617 OS << "link ";

619 OS << "framework ";

620 OS << "\"";

622 OS << "\"";

623 }

624

626 OS.indent(Indent + 2);

627 OS << "conflict ";

629 OS << ", \"";

631 OS << "\"\n";

632 }

633

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

635 OS.indent(Indent + 2);

636 OS << "conflict ";

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

638 OS << ", \"";

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

640 OS << "\"\n";

641 }

642

644 OS.indent(Indent + 2);

646 OS << "explicit ";

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

649 OS.indent(Indent + 4);

650 OS << "export *\n";

651 }

652 OS.indent(Indent + 2);

653 OS << "}\n";

654 }

655

656 OS.indent(Indent);

657 OS << "}\n";

658}

659

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

662}

663

666

668 "setVisible expects a valid import location");

670 return;

671

672 ++Generation;

673

674 struct Visiting {

676 Visiting *ExportedBy;

677 };

678

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

680

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

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

683 ImportLocs.resize(ID + 1);

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

685 return;

686

687 ImportLocs[ID] = Loc;

688 Vis(V.M);

689

690

692 V.M->getExportedModules(Exports);

693 for (Module *E : Exports) {

694

695 if (E->isUnimportable())

696 VisitModule({E, &V});

697 }

698

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

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

703 Path.push_back(I->M);

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

705 }

706 }

707 };

708 VisitModule({M, nullptr});

709}

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)

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.

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

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

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.

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

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

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.

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.

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.

bool directlyUses(const Module *Requested)

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

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

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

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

bool isNamedModuleUnit() const

Is this a C++20 named module unit.

SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders

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

Module * Parent

The parent of this module.

void markUnavailable(bool Unimportable)

Mark this module and all of its submodules as unavailable.

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.

Module * getPrivateModuleFragment() const

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

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.

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

std::vector< UnresolvedConflict > UnresolvedConflicts

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

bool isSubModuleOf(const Module *Other) const

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

ArrayRef< FileEntryRef > getTopHeaders(FileManager &FileMgr)

The top-level headers associated with this module.

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.

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.

void addTopHeader(FileEntryRef File)

Add a top-level header associated with this module.

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

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.

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

A callback to call when a module conflict is found.

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.

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.

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.

@ Result

The result type of a method or function.

@ Other

Other implicit parameter.