1 //===- Module.cpp - Describe a module -------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file defines the Module class, which describes a module in the source
12 //===----------------------------------------------------------------------===//
14 #include "clang/Basic/Module.h"
15 #include "clang/Basic/CharInfo.h"
16 #include "clang/Basic/FileManager.h"
17 #include "clang/Basic/LangOptions.h"
18 #include "clang/Basic/SourceLocation.h"
19 #include "clang/Basic/TargetInfo.h"
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"
35 using namespace clang;
37 Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
38 bool IsFramework, bool IsExplicit, unsigned VisibilityID)
39 : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
40 VisibilityID(VisibilityID), IsMissingRequirement(false),
41 HasIncompatibleModuleFile(false), IsAvailable(true),
42 IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
43 IsSystem(false), IsExternC(false), IsInferred(false),
44 InferSubmodules(false), InferExplicitSubmodules(false),
45 InferExportWildcard(false), ConfigMacrosExhaustive(false),
46 NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
47 NameVisibility(Hidden) {
49 if (!Parent->isAvailable())
53 if (Parent->IsExternC)
55 if (Parent->NoUndeclaredIncludes)
56 NoUndeclaredIncludes = true;
57 if (Parent->ModuleMapIsPrivate)
58 ModuleMapIsPrivate = true;
59 IsMissingRequirement = Parent->IsMissingRequirement;
61 Parent->SubModuleIndex[Name] = Parent->SubModules.size();
62 Parent->SubModules.push_back(this);
67 for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
73 static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
74 StringRef Platform = Target.getPlatformName();
75 StringRef Env = Target.getTriple().getEnvironmentName();
77 // Attempt to match platform and environment.
78 if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
82 auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
83 auto Pos = LHS.find("-");
84 if (Pos == StringRef::npos)
86 SmallString<128> NewLHS = LHS.slice(0, Pos);
87 NewLHS += LHS.slice(Pos+1, LHS.size());
91 SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
92 // Darwin has different but equivalent variants for simulators, example:
93 // 1. x86_64-apple-ios-simulator
94 // 2. x86_64-apple-iossimulator
95 // where both are valid examples of the same platform+environment but in the
96 // variant (2) the simulator is hardcoded as part of the platform name. Both
97 // forms above should match for "iossimulator" requirement.
98 if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator"))
99 return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
101 return PlatformEnv == Feature;
104 /// Determine whether a translation unit built using the current
105 /// language options has the given feature.
106 static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
107 const TargetInfo &Target) {
108 bool HasFeature = llvm::StringSwitch<bool>(Feature)
109 .Case("altivec", LangOpts.AltiVec)
110 .Case("blocks", LangOpts.Blocks)
111 .Case("coroutines", LangOpts.Coroutines)
112 .Case("cplusplus", LangOpts.CPlusPlus)
113 .Case("cplusplus11", LangOpts.CPlusPlus11)
114 .Case("cplusplus14", LangOpts.CPlusPlus14)
115 .Case("cplusplus17", LangOpts.CPlusPlus17)
116 .Case("c99", LangOpts.C99)
117 .Case("c11", LangOpts.C11)
118 .Case("c17", LangOpts.C17)
119 .Case("freestanding", LangOpts.Freestanding)
120 .Case("gnuinlineasm", LangOpts.GNUAsm)
121 .Case("objc", LangOpts.ObjC)
122 .Case("objc_arc", LangOpts.ObjCAutoRefCount)
123 .Case("opencl", LangOpts.OpenCL)
124 .Case("tls", Target.isTLSSupported())
125 .Case("zvector", LangOpts.ZVector)
126 .Default(Target.hasFeature(Feature) ||
127 isPlatformEnvironment(Target, Feature));
129 HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
130 LangOpts.ModuleFeatures.end(),
131 Feature) != LangOpts.ModuleFeatures.end();
135 bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
137 UnresolvedHeaderDirective &MissingHeader,
138 Module *&ShadowingModule) const {
142 for (const Module *Current = this; Current; Current = Current->Parent) {
143 if (Current->ShadowingModule) {
144 ShadowingModule = Current->ShadowingModule;
147 for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
148 if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
149 Current->Requirements[I].second) {
150 Req = Current->Requirements[I];
154 if (!Current->MissingHeaders.empty()) {
155 MissingHeader = Current->MissingHeaders.front();
160 llvm_unreachable("could not find a reason why module is unavailable");
163 bool Module::isSubModuleOf(const Module *Other) const {
164 const Module *This = this;
175 const Module *Module::getTopLevelModule() const {
176 const Module *Result = this;
177 while (Result->Parent)
178 Result = Result->Parent;
183 static StringRef getModuleNameFromComponent(
184 const std::pair<std::string, SourceLocation> &IdComponent) {
185 return IdComponent.first;
188 static StringRef getModuleNameFromComponent(StringRef R) { return R; }
190 template<typename InputIter>
191 static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
192 bool AllowStringLiterals = true) {
193 for (InputIter It = Begin; It != End; ++It) {
197 StringRef Name = getModuleNameFromComponent(*It);
198 if (!AllowStringLiterals || isValidIdentifier(Name))
202 OS.write_escaped(Name);
208 template<typename Container>
209 static void printModuleId(raw_ostream &OS, const Container &C) {
210 return printModuleId(OS, C.begin(), C.end());
213 std::string Module::getFullModuleName(bool AllowStringLiterals) const {
214 SmallVector<StringRef, 2> Names;
216 // Build up the set of module names (from innermost to outermost).
217 for (const Module *M = this; M; M = M->Parent)
218 Names.push_back(M->Name);
222 llvm::raw_string_ostream Out(Result);
223 printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
229 bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
230 for (const Module *M = this; M; M = M->Parent) {
231 if (nameParts.empty() || M->Name != nameParts.back())
233 nameParts = nameParts.drop_back();
235 return nameParts.empty();
238 Module::DirectoryName Module::getUmbrellaDir() const {
239 if (Header U = getUmbrellaHeader())
240 return {"", U.Entry->getDir()};
242 return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
245 ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
246 if (!TopHeaderNames.empty()) {
247 for (std::vector<std::string>::iterator
248 I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
249 if (auto FE = FileMgr.getFile(*I))
250 TopHeaders.insert(*FE);
252 TopHeaderNames.clear();
255 return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
258 bool Module::directlyUses(const Module *Requested) const {
259 auto *Top = getTopLevelModule();
261 // A top-level module implicitly uses itself.
262 if (Requested->isSubModuleOf(Top))
265 for (auto *Use : Top->DirectUses)
266 if (Requested->isSubModuleOf(Use))
269 // Anyone is allowed to use our builtin stddef.h and its accompanying module.
270 if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
276 void Module::addRequirement(StringRef Feature, bool RequiredState,
277 const LangOptions &LangOpts,
278 const TargetInfo &Target) {
279 Requirements.push_back(Requirement(Feature, RequiredState));
281 // If this feature is currently available, we're done.
282 if (hasFeature(Feature, LangOpts, Target) == RequiredState)
285 markUnavailable(/*MissingRequirement*/true);
288 void Module::markUnavailable(bool MissingRequirement) {
289 auto needUpdate = [MissingRequirement](Module *M) {
290 return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
293 if (!needUpdate(this))
296 SmallVector<Module *, 2> Stack;
297 Stack.push_back(this);
298 while (!Stack.empty()) {
299 Module *Current = Stack.back();
302 if (!needUpdate(Current))
305 Current->IsAvailable = false;
306 Current->IsMissingRequirement |= MissingRequirement;
307 for (submodule_iterator Sub = Current->submodule_begin(),
308 SubEnd = Current->submodule_end();
309 Sub != SubEnd; ++Sub) {
310 if (needUpdate(*Sub))
311 Stack.push_back(*Sub);
316 Module *Module::findSubmodule(StringRef Name) const {
317 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
318 if (Pos == SubModuleIndex.end())
321 return SubModules[Pos->getValue()];
324 Module *Module::findOrInferSubmodule(StringRef Name) {
325 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
326 if (Pos != SubModuleIndex.end())
327 return SubModules[Pos->getValue()];
328 if (!InferSubmodules)
330 Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
331 Result->InferExplicitSubmodules = InferExplicitSubmodules;
332 Result->InferSubmodules = InferSubmodules;
333 Result->InferExportWildcard = InferExportWildcard;
334 if (Result->InferExportWildcard)
335 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
339 void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
340 // All non-explicit submodules are exported.
341 for (std::vector<Module *>::const_iterator I = SubModules.begin(),
342 E = SubModules.end();
345 if (!Mod->IsExplicit)
346 Exported.push_back(Mod);
349 // Find re-exported modules by filtering the list of imported modules.
350 bool AnyWildcard = false;
351 bool UnrestrictedWildcard = false;
352 SmallVector<Module *, 4> WildcardRestrictions;
353 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
354 Module *Mod = Exports[I].getPointer();
355 if (!Exports[I].getInt()) {
356 // Export a named module directly; no wildcards involved.
357 Exported.push_back(Mod);
362 // Wildcard export: export all of the imported modules that match
363 // the given pattern.
365 if (UnrestrictedWildcard)
368 if (Module *Restriction = Exports[I].getPointer())
369 WildcardRestrictions.push_back(Restriction);
371 WildcardRestrictions.clear();
372 UnrestrictedWildcard = true;
376 // If there were any wildcards, push any imported modules that were
377 // re-exported by the wildcard restriction.
381 for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
382 Module *Mod = Imports[I];
383 bool Acceptable = UnrestrictedWildcard;
385 // Check whether this module meets one of the restrictions.
386 for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
387 Module *Restriction = WildcardRestrictions[R];
388 if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
398 Exported.push_back(Mod);
402 void Module::buildVisibleModulesCache() const {
403 assert(VisibleModulesCache.empty() && "cache does not need building");
405 // This module is visible to itself.
406 VisibleModulesCache.insert(this);
408 // Every imported module is visible.
409 SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
410 while (!Stack.empty()) {
411 Module *CurrModule = Stack.pop_back_val();
413 // Every module transitively exported by an imported module is visible.
414 if (VisibleModulesCache.insert(CurrModule).second)
415 CurrModule->getExportedModules(Stack);
419 void Module::print(raw_ostream &OS, unsigned Indent) const {
426 printModuleId(OS, &Name, &Name + 1);
428 if (IsSystem || IsExternC) {
429 OS.indent(Indent + 2);
438 if (!Requirements.empty()) {
439 OS.indent(Indent + 2);
441 for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
444 if (!Requirements[I].second)
446 OS << Requirements[I].first;
451 if (Header H = getUmbrellaHeader()) {
452 OS.indent(Indent + 2);
453 OS << "umbrella header \"";
454 OS.write_escaped(H.NameAsWritten);
456 } else if (DirectoryName D = getUmbrellaDir()) {
457 OS.indent(Indent + 2);
459 OS.write_escaped(D.NameAsWritten);
463 if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
464 OS.indent(Indent + 2);
465 OS << "config_macros ";
466 if (ConfigMacrosExhaustive)
467 OS << "[exhaustive]";
468 for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
471 OS << ConfigMacros[I];
479 } Kinds[] = {{"", HK_Normal},
480 {"textual ", HK_Textual},
481 {"private ", HK_Private},
482 {"private textual ", HK_PrivateTextual},
483 {"exclude ", HK_Excluded}};
485 for (auto &K : Kinds) {
486 assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
487 for (auto &H : Headers[K.Kind]) {
488 OS.indent(Indent + 2);
489 OS << K.Prefix << "header \"";
490 OS.write_escaped(H.NameAsWritten);
491 OS << "\" { size " << H.Entry->getSize()
492 << " mtime " << H.Entry->getModificationTime() << " }\n";
495 for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
496 for (auto &U : *Unresolved) {
497 OS.indent(Indent + 2);
498 OS << Kinds[U.Kind].Prefix << "header \"";
499 OS.write_escaped(U.FileName);
501 if (U.Size || U.ModTime) {
504 OS << " size " << *U.Size;
506 OS << " mtime " << *U.ModTime;
513 if (!ExportAsModule.empty()) {
514 OS.indent(Indent + 2);
515 OS << "export_as" << ExportAsModule << "\n";
518 for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
520 // Print inferred subframework modules so that we don't need to re-infer
521 // them (requires expensive directory iteration + stat calls) when we build
522 // the module. Regular inferred submodules are OK, as we need to look at all
523 // those header files anyway.
524 if (!(*MI)->IsInferred || (*MI)->IsFramework)
525 (*MI)->print(OS, Indent + 2);
527 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
528 OS.indent(Indent + 2);
530 if (Module *Restriction = Exports[I].getPointer()) {
531 OS << Restriction->getFullModuleName(true);
532 if (Exports[I].getInt())
540 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
541 OS.indent(Indent + 2);
543 printModuleId(OS, UnresolvedExports[I].Id);
544 if (UnresolvedExports[I].Wildcard)
545 OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
549 for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
550 OS.indent(Indent + 2);
552 OS << DirectUses[I]->getFullModuleName(true);
556 for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
557 OS.indent(Indent + 2);
559 printModuleId(OS, UnresolvedDirectUses[I]);
563 for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
564 OS.indent(Indent + 2);
566 if (LinkLibraries[I].IsFramework)
569 OS.write_escaped(LinkLibraries[I].Library);
573 for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
574 OS.indent(Indent + 2);
576 printModuleId(OS, UnresolvedConflicts[I].Id);
578 OS.write_escaped(UnresolvedConflicts[I].Message);
582 for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
583 OS.indent(Indent + 2);
585 OS << Conflicts[I].Other->getFullModuleName(true);
587 OS.write_escaped(Conflicts[I].Message);
591 if (InferSubmodules) {
592 OS.indent(Indent + 2);
593 if (InferExplicitSubmodules)
595 OS << "module * {\n";
596 if (InferExportWildcard) {
597 OS.indent(Indent + 4);
600 OS.indent(Indent + 2);
608 LLVM_DUMP_METHOD void Module::dump() const {
612 void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
613 VisibleCallback Vis, ConflictCallback Cb) {
614 assert(Loc.isValid() && "setVisible expects a valid import location");
622 Visiting *ExportedBy;
625 std::function<void(Visiting)> VisitModule = [&](Visiting V) {
626 // Nothing to do for a module that's already visible.
627 unsigned ID = V.M->getVisibilityID();
628 if (ImportLocs.size() <= ID)
629 ImportLocs.resize(ID + 1);
630 else if (ImportLocs[ID].isValid())
633 ImportLocs[ID] = Loc;
636 // Make any exported modules visible.
637 SmallVector<Module *, 16> Exports;
638 V.M->getExportedModules(Exports);
639 for (Module *E : Exports) {
640 // Don't recurse to unavailable submodules.
641 if (E->isAvailable())
642 VisitModule({E, &V});
645 for (auto &C : V.M->Conflicts) {
646 if (isVisible(C.Other)) {
647 llvm::SmallVector<Module*, 8> Path;
648 for (Visiting *I = &V; I; I = I->ExportedBy)
649 Path.push_back(I->M);
650 Cb(Path, C.Other, C.Message);
654 VisitModule({M, nullptr});