1 //===- Module.cpp - Describe a module -------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the Module class, which describes a module in the source
10 // code.
11 //
12 //===----------------------------------------------------------------------===//
13
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"
28 #include <algorithm>
29 #include <cassert>
30 #include <functional>
31 #include <string>
32 #include <utility>
33 #include <vector>
34
35 using namespace clang;
36
Module(StringRef Name,SourceLocation DefinitionLoc,Module * Parent,bool IsFramework,bool IsExplicit,unsigned VisibilityID)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), IsUnimportable(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 NamedModuleHasInit(true), NameVisibility(Hidden) {
48 if (Parent) {
49 IsAvailable = Parent->isAvailable();
50 IsUnimportable = Parent->isUnimportable();
51 IsSystem = Parent->IsSystem;
52 IsExternC = Parent->IsExternC;
53 NoUndeclaredIncludes = Parent->NoUndeclaredIncludes;
54 ModuleMapIsPrivate = Parent->ModuleMapIsPrivate;
55
56 Parent->SubModuleIndex[Name] = Parent->SubModules.size();
57 Parent->SubModules.push_back(this);
58 }
59 }
60
~Module()61 Module::~Module() {
62 for (auto *Submodule : SubModules) {
63 delete Submodule;
64 }
65 }
66
isPlatformEnvironment(const TargetInfo & Target,StringRef Feature)67 static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
68 StringRef Platform = Target.getPlatformName();
69 StringRef Env = Target.getTriple().getEnvironmentName();
70
71 // Attempt to match platform and environment.
72 if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
73 Env == Feature)
74 return true;
75
76 auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
77 auto Pos = LHS.find('-');
78 if (Pos == StringRef::npos)
79 return false;
80 SmallString<128> NewLHS = LHS.slice(0, Pos);
81 NewLHS += LHS.slice(Pos+1, LHS.size());
82 return NewLHS == RHS;
83 };
84
85 SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
86 // Darwin has different but equivalent variants for simulators, example:
87 // 1. x86_64-apple-ios-simulator
88 // 2. x86_64-apple-iossimulator
89 // where both are valid examples of the same platform+environment but in the
90 // variant (2) the simulator is hardcoded as part of the platform name. Both
91 // forms above should match for "iossimulator" requirement.
92 if (Target.getTriple().isOSDarwin() && PlatformEnv.ends_with("simulator"))
93 return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
94
95 return PlatformEnv == Feature;
96 }
97
98 /// Determine whether a translation unit built using the current
99 /// language options has the given feature.
hasFeature(StringRef Feature,const LangOptions & LangOpts,const TargetInfo & Target)100 static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
101 const TargetInfo &Target) {
102 bool HasFeature = llvm::StringSwitch<bool>(Feature)
103 .Case("altivec", LangOpts.AltiVec)
104 .Case("blocks", LangOpts.Blocks)
105 .Case("coroutines", LangOpts.Coroutines)
106 .Case("cplusplus", LangOpts.CPlusPlus)
107 .Case("cplusplus11", LangOpts.CPlusPlus11)
108 .Case("cplusplus14", LangOpts.CPlusPlus14)
109 .Case("cplusplus17", LangOpts.CPlusPlus17)
110 .Case("cplusplus20", LangOpts.CPlusPlus20)
111 .Case("cplusplus23", LangOpts.CPlusPlus23)
112 .Case("cplusplus26", LangOpts.CPlusPlus26)
113 .Case("c99", LangOpts.C99)
114 .Case("c11", LangOpts.C11)
115 .Case("c17", LangOpts.C17)
116 .Case("c23", LangOpts.C23)
117 .Case("freestanding", LangOpts.Freestanding)
118 .Case("gnuinlineasm", LangOpts.GNUAsm)
119 .Case("objc", LangOpts.ObjC)
120 .Case("objc_arc", LangOpts.ObjCAutoRefCount)
121 .Case("opencl", LangOpts.OpenCL)
122 .Case("tls", Target.isTLSSupported())
123 .Case("zvector", LangOpts.ZVector)
124 .Default(Target.hasFeature(Feature) ||
125 isPlatformEnvironment(Target, Feature));
126 if (!HasFeature)
127 HasFeature = llvm::is_contained(LangOpts.ModuleFeatures, Feature);
128 return HasFeature;
129 }
130
isUnimportable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,Module * & ShadowingModule) const131 bool Module::isUnimportable(const LangOptions &LangOpts,
132 const TargetInfo &Target, Requirement &Req,
133 Module *&ShadowingModule) const {
134 if (!IsUnimportable)
135 return false;
136
137 for (const Module *Current = this; Current; Current = Current->Parent) {
138 if (Current->ShadowingModule) {
139 ShadowingModule = Current->ShadowingModule;
140 return true;
141 }
142 for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
143 if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
144 Current->Requirements[I].second) {
145 Req = Current->Requirements[I];
146 return true;
147 }
148 }
149 }
150
151 llvm_unreachable("could not find a reason why module is unimportable");
152 }
153
154 // The -fmodule-name option tells the compiler to textually include headers in
155 // the specified module, meaning Clang won't build the specified module. This
156 // is useful in a number of situations, for instance, when building a library
157 // that vends a module map, one might want to avoid hitting intermediate build
158 // products containing the module map or avoid finding the system installed
159 // modulemap for that library.
isForBuilding(const LangOptions & LangOpts) const160 bool Module::isForBuilding(const LangOptions &LangOpts) const {
161 StringRef TopLevelName = getTopLevelModuleName();
162 StringRef CurrentModule = LangOpts.CurrentModule;
163
164 // When building the implementation of framework Foo, we want to make sure
165 // that Foo *and* Foo_Private are textually included and no modules are built
166 // for either.
167 if (!LangOpts.isCompilingModule() && getTopLevelModule()->IsFramework &&
168 CurrentModule == LangOpts.ModuleName &&
169 !CurrentModule.ends_with("_Private") &&
170 TopLevelName.ends_with("_Private"))
171 TopLevelName = TopLevelName.drop_back(8);
172
173 return TopLevelName == CurrentModule;
174 }
175
isAvailable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,UnresolvedHeaderDirective & MissingHeader,Module * & ShadowingModule) const176 bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
177 Requirement &Req,
178 UnresolvedHeaderDirective &MissingHeader,
179 Module *&ShadowingModule) const {
180 if (IsAvailable)
181 return true;
182
183 if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
184 return false;
185
186 // FIXME: All missing headers are listed on the top-level module. Should we
187 // just look there?
188 for (const Module *Current = this; Current; Current = Current->Parent) {
189 if (!Current->MissingHeaders.empty()) {
190 MissingHeader = Current->MissingHeaders.front();
191 return false;
192 }
193 }
194
195 llvm_unreachable("could not find a reason why module is unavailable");
196 }
197
isSubModuleOf(const Module * Other) const198 bool Module::isSubModuleOf(const Module *Other) const {
199 for (auto *Parent = this; Parent; Parent = Parent->Parent) {
200 if (Parent == Other)
201 return true;
202 }
203 return false;
204 }
205
getTopLevelModule() const206 const Module *Module::getTopLevelModule() const {
207 const Module *Result = this;
208 while (Result->Parent)
209 Result = Result->Parent;
210
211 return Result;
212 }
213
getModuleNameFromComponent(const std::pair<std::string,SourceLocation> & IdComponent)214 static StringRef getModuleNameFromComponent(
215 const std::pair<std::string, SourceLocation> &IdComponent) {
216 return IdComponent.first;
217 }
218
getModuleNameFromComponent(StringRef R)219 static StringRef getModuleNameFromComponent(StringRef R) { return R; }
220
221 template<typename InputIter>
printModuleId(raw_ostream & OS,InputIter Begin,InputIter End,bool AllowStringLiterals=true)222 static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
223 bool AllowStringLiterals = true) {
224 for (InputIter It = Begin; It != End; ++It) {
225 if (It != Begin)
226 OS << ".";
227
228 StringRef Name = getModuleNameFromComponent(*It);
229 if (!AllowStringLiterals || isValidAsciiIdentifier(Name))
230 OS << Name;
231 else {
232 OS << '"';
233 OS.write_escaped(Name);
234 OS << '"';
235 }
236 }
237 }
238
239 template<typename Container>
printModuleId(raw_ostream & OS,const Container & C)240 static void printModuleId(raw_ostream &OS, const Container &C) {
241 return printModuleId(OS, C.begin(), C.end());
242 }
243
getFullModuleName(bool AllowStringLiterals) const244 std::string Module::getFullModuleName(bool AllowStringLiterals) const {
245 SmallVector<StringRef, 2> Names;
246
247 // Build up the set of module names (from innermost to outermost).
248 for (const Module *M = this; M; M = M->Parent)
249 Names.push_back(M->Name);
250
251 std::string Result;
252
253 llvm::raw_string_ostream Out(Result);
254 printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
255 Out.flush();
256
257 return Result;
258 }
259
fullModuleNameIs(ArrayRef<StringRef> nameParts) const260 bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
261 for (const Module *M = this; M; M = M->Parent) {
262 if (nameParts.empty() || M->Name != nameParts.back())
263 return false;
264 nameParts = nameParts.drop_back();
265 }
266 return nameParts.empty();
267 }
268
getEffectiveUmbrellaDir() const269 OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const {
270 if (const auto *Hdr = std::get_if<FileEntryRef>(&Umbrella))
271 return Hdr->getDir();
272 if (const auto *Dir = std::get_if<DirectoryEntryRef>(&Umbrella))
273 return *Dir;
274 return std::nullopt;
275 }
276
addTopHeader(FileEntryRef File)277 void Module::addTopHeader(FileEntryRef File) {
278 assert(File);
279 TopHeaders.insert(File);
280 }
281
getTopHeaders(FileManager & FileMgr)282 ArrayRef<FileEntryRef> Module::getTopHeaders(FileManager &FileMgr) {
283 if (!TopHeaderNames.empty()) {
284 for (StringRef TopHeaderName : TopHeaderNames)
285 if (auto FE = FileMgr.getOptionalFileRef(TopHeaderName))
286 TopHeaders.insert(*FE);
287 TopHeaderNames.clear();
288 }
289
290 return llvm::ArrayRef(TopHeaders.begin(), TopHeaders.end());
291 }
292
directlyUses(const Module * Requested)293 bool Module::directlyUses(const Module *Requested) {
294 auto *Top = getTopLevelModule();
295
296 // A top-level module implicitly uses itself.
297 if (Requested->isSubModuleOf(Top))
298 return true;
299
300 for (auto *Use : Top->DirectUses)
301 if (Requested->isSubModuleOf(Use))
302 return true;
303
304 // Anyone is allowed to use our builtin stddef.h and its accompanying modules.
305 if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) ||
306 Requested->fullModuleNameIs({"_Builtin_stddef_wint_t"}))
307 return true;
308
309 if (NoUndeclaredIncludes)
310 UndeclaredUses.insert(Requested);
311
312 return false;
313 }
314
addRequirement(StringRef Feature,bool RequiredState,const LangOptions & LangOpts,const TargetInfo & Target)315 void Module::addRequirement(StringRef Feature, bool RequiredState,
316 const LangOptions &LangOpts,
317 const TargetInfo &Target) {
318 Requirements.push_back(Requirement(std::string(Feature), RequiredState));
319
320 // If this feature is currently available, we're done.
321 if (hasFeature(Feature, LangOpts, Target) == RequiredState)
322 return;
323
324 markUnavailable(/*Unimportable*/true);
325 }
326
markUnavailable(bool Unimportable)327 void Module::markUnavailable(bool Unimportable) {
328 auto needUpdate = [Unimportable](Module *M) {
329 return M->IsAvailable || (!M->IsUnimportable && Unimportable);
330 };
331
332 if (!needUpdate(this))
333 return;
334
335 SmallVector<Module *, 2> Stack;
336 Stack.push_back(this);
337 while (!Stack.empty()) {
338 Module *Current = Stack.back();
339 Stack.pop_back();
340
341 if (!needUpdate(Current))
342 continue;
343
344 Current->IsAvailable = false;
345 Current->IsUnimportable |= Unimportable;
346 for (auto *Submodule : Current->submodules()) {
347 if (needUpdate(Submodule))
348 Stack.push_back(Submodule);
349 }
350 }
351 }
352
findSubmodule(StringRef Name) const353 Module *Module::findSubmodule(StringRef Name) const {
354 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
355 if (Pos == SubModuleIndex.end())
356 return nullptr;
357
358 return SubModules[Pos->getValue()];
359 }
360
findOrInferSubmodule(StringRef Name)361 Module *Module::findOrInferSubmodule(StringRef Name) {
362 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
363 if (Pos != SubModuleIndex.end())
364 return SubModules[Pos->getValue()];
365 if (!InferSubmodules)
366 return nullptr;
367 Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
368 Result->InferExplicitSubmodules = InferExplicitSubmodules;
369 Result->InferSubmodules = InferSubmodules;
370 Result->InferExportWildcard = InferExportWildcard;
371 if (Result->InferExportWildcard)
372 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
373 return Result;
374 }
375
getGlobalModuleFragment() const376 Module *Module::getGlobalModuleFragment() const {
377 assert(isNamedModuleUnit() && "We should only query the global module "
378 "fragment from the C++ 20 Named modules");
379
380 for (auto *SubModule : SubModules)
381 if (SubModule->isExplicitGlobalModule())
382 return SubModule;
383
384 return nullptr;
385 }
386
getPrivateModuleFragment() const387 Module *Module::getPrivateModuleFragment() const {
388 assert(isNamedModuleUnit() && "We should only query the private module "
389 "fragment from the C++ 20 Named modules");
390
391 for (auto *SubModule : SubModules)
392 if (SubModule->isPrivateModule())
393 return SubModule;
394
395 return nullptr;
396 }
397
getExportedModules(SmallVectorImpl<Module * > & Exported) const398 void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
399 // All non-explicit submodules are exported.
400 for (std::vector<Module *>::const_iterator I = SubModules.begin(),
401 E = SubModules.end();
402 I != E; ++I) {
403 Module *Mod = *I;
404 if (!Mod->IsExplicit)
405 Exported.push_back(Mod);
406 }
407
408 // Find re-exported modules by filtering the list of imported modules.
409 bool AnyWildcard = false;
410 bool UnrestrictedWildcard = false;
411 SmallVector<Module *, 4> WildcardRestrictions;
412 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
413 Module *Mod = Exports[I].getPointer();
414 if (!Exports[I].getInt()) {
415 // Export a named module directly; no wildcards involved.
416 Exported.push_back(Mod);
417
418 continue;
419 }
420
421 // Wildcard export: export all of the imported modules that match
422 // the given pattern.
423 AnyWildcard = true;
424 if (UnrestrictedWildcard)
425 continue;
426
427 if (Module *Restriction = Exports[I].getPointer())
428 WildcardRestrictions.push_back(Restriction);
429 else {
430 WildcardRestrictions.clear();
431 UnrestrictedWildcard = true;
432 }
433 }
434
435 // If there were any wildcards, push any imported modules that were
436 // re-exported by the wildcard restriction.
437 if (!AnyWildcard)
438 return;
439
440 for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
441 Module *Mod = Imports[I];
442 bool Acceptable = UnrestrictedWildcard;
443 if (!Acceptable) {
444 // Check whether this module meets one of the restrictions.
445 for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
446 Module *Restriction = WildcardRestrictions[R];
447 if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
448 Acceptable = true;
449 break;
450 }
451 }
452 }
453
454 if (!Acceptable)
455 continue;
456
457 Exported.push_back(Mod);
458 }
459 }
460
buildVisibleModulesCache() const461 void Module::buildVisibleModulesCache() const {
462 assert(VisibleModulesCache.empty() && "cache does not need building");
463
464 // This module is visible to itself.
465 VisibleModulesCache.insert(this);
466
467 // Every imported module is visible.
468 SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
469 while (!Stack.empty()) {
470 Module *CurrModule = Stack.pop_back_val();
471
472 // Every module transitively exported by an imported module is visible.
473 if (VisibleModulesCache.insert(CurrModule).second)
474 CurrModule->getExportedModules(Stack);
475 }
476 }
477
print(raw_ostream & OS,unsigned Indent,bool Dump) const478 void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
479 OS.indent(Indent);
480 if (IsFramework)
481 OS << "framework ";
482 if (IsExplicit)
483 OS << "explicit ";
484 OS << "module ";
485 printModuleId(OS, &Name, &Name + 1);
486
487 if (IsSystem || IsExternC) {
488 OS.indent(Indent + 2);
489 if (IsSystem)
490 OS << " [system]";
491 if (IsExternC)
492 OS << " [extern_c]";
493 }
494
495 OS << " {\n";
496
497 if (!Requirements.empty()) {
498 OS.indent(Indent + 2);
499 OS << "requires ";
500 for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
501 if (I)
502 OS << ", ";
503 if (!Requirements[I].second)
504 OS << "!";
505 OS << Requirements[I].first;
506 }
507 OS << "\n";
508 }
509
510 if (std::optional<Header> H = getUmbrellaHeaderAsWritten()) {
511 OS.indent(Indent + 2);
512 OS << "umbrella header \"";
513 OS.write_escaped(H->NameAsWritten);
514 OS << "\"\n";
515 } else if (std::optional<DirectoryName> D = getUmbrellaDirAsWritten()) {
516 OS.indent(Indent + 2);
517 OS << "umbrella \"";
518 OS.write_escaped(D->NameAsWritten);
519 OS << "\"\n";
520 }
521
522 if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
523 OS.indent(Indent + 2);
524 OS << "config_macros ";
525 if (ConfigMacrosExhaustive)
526 OS << "[exhaustive]";
527 for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
528 if (I)
529 OS << ", ";
530 OS << ConfigMacros[I];
531 }
532 OS << "\n";
533 }
534
535 struct {
536 StringRef Prefix;
537 HeaderKind Kind;
538 } Kinds[] = {{"", HK_Normal},
539 {"textual ", HK_Textual},
540 {"private ", HK_Private},
541 {"private textual ", HK_PrivateTextual},
542 {"exclude ", HK_Excluded}};
543
544 for (auto &K : Kinds) {
545 assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
546 for (auto &H : Headers[K.Kind]) {
547 OS.indent(Indent + 2);
548 OS << K.Prefix << "header \"";
549 OS.write_escaped(H.NameAsWritten);
550 OS << "\" { size " << H.Entry.getSize()
551 << " mtime " << H.Entry.getModificationTime() << " }\n";
552 }
553 }
554 for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
555 for (auto &U : *Unresolved) {
556 OS.indent(Indent + 2);
557 OS << Kinds[U.Kind].Prefix << "header \"";
558 OS.write_escaped(U.FileName);
559 OS << "\"";
560 if (U.Size || U.ModTime) {
561 OS << " {";
562 if (U.Size)
563 OS << " size " << *U.Size;
564 if (U.ModTime)
565 OS << " mtime " << *U.ModTime;
566 OS << " }";
567 }
568 OS << "\n";
569 }
570 }
571
572 if (!ExportAsModule.empty()) {
573 OS.indent(Indent + 2);
574 OS << "export_as" << ExportAsModule << "\n";
575 }
576
577 for (auto *Submodule : submodules())
578 // Print inferred subframework modules so that we don't need to re-infer
579 // them (requires expensive directory iteration + stat calls) when we build
580 // the module. Regular inferred submodules are OK, as we need to look at all
581 // those header files anyway.
582 if (!Submodule->IsInferred || Submodule->IsFramework)
583 Submodule->print(OS, Indent + 2, Dump);
584
585 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
586 OS.indent(Indent + 2);
587 OS << "export ";
588 if (Module *Restriction = Exports[I].getPointer()) {
589 OS << Restriction->getFullModuleName(true);
590 if (Exports[I].getInt())
591 OS << ".*";
592 } else {
593 OS << "*";
594 }
595 OS << "\n";
596 }
597
598 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
599 OS.indent(Indent + 2);
600 OS << "export ";
601 printModuleId(OS, UnresolvedExports[I].Id);
602 if (UnresolvedExports[I].Wildcard)
603 OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
604 OS << "\n";
605 }
606
607 if (Dump) {
608 for (Module *M : Imports) {
609 OS.indent(Indent + 2);
610 llvm::errs() << "import " << M->getFullModuleName() << "\n";
611 }
612 }
613
614 for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
615 OS.indent(Indent + 2);
616 OS << "use ";
617 OS << DirectUses[I]->getFullModuleName(true);
618 OS << "\n";
619 }
620
621 for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
622 OS.indent(Indent + 2);
623 OS << "use ";
624 printModuleId(OS, UnresolvedDirectUses[I]);
625 OS << "\n";
626 }
627
628 for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
629 OS.indent(Indent + 2);
630 OS << "link ";
631 if (LinkLibraries[I].IsFramework)
632 OS << "framework ";
633 OS << "\"";
634 OS.write_escaped(LinkLibraries[I].Library);
635 OS << "\"";
636 }
637
638 for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
639 OS.indent(Indent + 2);
640 OS << "conflict ";
641 printModuleId(OS, UnresolvedConflicts[I].Id);
642 OS << ", \"";
643 OS.write_escaped(UnresolvedConflicts[I].Message);
644 OS << "\"\n";
645 }
646
647 for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
648 OS.indent(Indent + 2);
649 OS << "conflict ";
650 OS << Conflicts[I].Other->getFullModuleName(true);
651 OS << ", \"";
652 OS.write_escaped(Conflicts[I].Message);
653 OS << "\"\n";
654 }
655
656 if (InferSubmodules) {
657 OS.indent(Indent + 2);
658 if (InferExplicitSubmodules)
659 OS << "explicit ";
660 OS << "module * {\n";
661 if (InferExportWildcard) {
662 OS.indent(Indent + 4);
663 OS << "export *\n";
664 }
665 OS.indent(Indent + 2);
666 OS << "}\n";
667 }
668
669 OS.indent(Indent);
670 OS << "}\n";
671 }
672
dump() const673 LLVM_DUMP_METHOD void Module::dump() const {
674 print(llvm::errs(), 0, true);
675 }
676
setVisible(Module * M,SourceLocation Loc,VisibleCallback Vis,ConflictCallback Cb)677 void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
678 VisibleCallback Vis, ConflictCallback Cb) {
679 // We can't import a global module fragment so the location can be invalid.
680 assert((M->isGlobalModule() || Loc.isValid()) &&
681 "setVisible expects a valid import location");
682 if (isVisible(M))
683 return;
684
685 ++Generation;
686
687 struct Visiting {
688 Module *M;
689 Visiting *ExportedBy;
690 };
691
692 std::function<void(Visiting)> VisitModule = [&](Visiting V) {
693 // Nothing to do for a module that's already visible.
694 unsigned ID = V.M->getVisibilityID();
695 if (ImportLocs.size() <= ID)
696 ImportLocs.resize(ID + 1);
697 else if (ImportLocs[ID].isValid())
698 return;
699
700 ImportLocs[ID] = Loc;
701 Vis(V.M);
702
703 // Make any exported modules visible.
704 SmallVector<Module *, 16> Exports;
705 V.M->getExportedModules(Exports);
706 for (Module *E : Exports) {
707 // Don't import non-importable modules.
708 if (!E->isUnimportable())
709 VisitModule({E, &V});
710 }
711
712 for (auto &C : V.M->Conflicts) {
713 if (isVisible(C.Other)) {
714 llvm::SmallVector<Module*, 8> Path;
715 for (Visiting *I = &V; I; I = I->ExportedBy)
716 Path.push_back(I->M);
717 Cb(Path, C.Other, C.Message);
718 }
719 }
720 };
721 VisitModule({M, nullptr});
722 }
723
makeTransitiveImportsVisible(Module * M,SourceLocation Loc,VisibleCallback Vis,ConflictCallback Cb)724 void VisibleModuleSet::makeTransitiveImportsVisible(Module *M,
725 SourceLocation Loc,
726 VisibleCallback Vis,
727 ConflictCallback Cb) {
728 for (auto *I : M->Imports)
729 setVisible(I, Loc, Vis, Cb);
730 }
731
ASTSourceDescriptor(Module & M)732 ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
733 : Signature(M.Signature), ClangModule(&M) {
734 if (M.Directory)
735 Path = M.Directory->getName();
736 if (auto File = M.getASTFile())
737 ASTFile = File->getName();
738 }
739
getModuleName() const740 std::string ASTSourceDescriptor::getModuleName() const {
741 if (ClangModule)
742 return ClangModule->Name;
743 else
744 return std::string(PCHModuleName);
745 }
746