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 <cassert>
29 #include <functional>
30 #include <string>
31 #include <utility>
32 #include <vector>
33
34 using namespace clang;
35
Module(ModuleConstructorTag,StringRef Name,SourceLocation DefinitionLoc,Module * Parent,bool IsFramework,bool IsExplicit,unsigned VisibilityID)36 Module::Module(ModuleConstructorTag, StringRef Name,
37 SourceLocation DefinitionLoc, Module *Parent, bool IsFramework,
38 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->SubModules.push_back(this);
57 }
58 }
59
60 Module::~Module() = default;
61
isPlatformEnvironment(const TargetInfo & Target,StringRef Feature)62 static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
63 StringRef Platform = Target.getPlatformName();
64 StringRef Env = Target.getTriple().getEnvironmentName();
65
66 // Attempt to match platform and environment.
67 if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
68 Env == Feature)
69 return true;
70
71 auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
72 auto Pos = LHS.find('-');
73 if (Pos == StringRef::npos)
74 return false;
75 SmallString<128> NewLHS = LHS.slice(0, Pos);
76 NewLHS += LHS.slice(Pos+1, LHS.size());
77 return NewLHS == RHS;
78 };
79
80 SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
81 // Darwin has different but equivalent variants for simulators, example:
82 // 1. x86_64-apple-ios-simulator
83 // 2. x86_64-apple-iossimulator
84 // where both are valid examples of the same platform+environment but in the
85 // variant (2) the simulator is hardcoded as part of the platform name. Both
86 // forms above should match for "iossimulator" requirement.
87 if (Target.getTriple().isOSDarwin() && PlatformEnv.ends_with("simulator"))
88 return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
89
90 return PlatformEnv == Feature;
91 }
92
93 /// Determine whether a translation unit built using the current
94 /// language options has the given feature.
hasFeature(StringRef Feature,const LangOptions & LangOpts,const TargetInfo & Target)95 static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
96 const TargetInfo &Target) {
97 bool HasFeature = llvm::StringSwitch<bool>(Feature)
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)
119 .Default(Target.hasFeature(Feature) ||
120 isPlatformEnvironment(Target, Feature));
121 if (!HasFeature)
122 HasFeature = llvm::is_contained(LangOpts.ModuleFeatures, Feature);
123 return HasFeature;
124 }
125
isUnimportable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,Module * & ShadowingModule) const126 bool Module::isUnimportable(const LangOptions &LangOpts,
127 const TargetInfo &Target, Requirement &Req,
128 Module *&ShadowingModule) const {
129 if (!IsUnimportable)
130 return false;
131
132 for (const Module *Current = this; Current; Current = Current->Parent) {
133 if (Current->ShadowingModule) {
134 ShadowingModule = 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 // The -fmodule-name option tells the compiler to textually include headers in
150 // the specified module, meaning Clang won't build the specified module. This
151 // is useful in a number of situations, for instance, when building a library
152 // that vends a module map, one might want to avoid hitting intermediate build
153 // products containing the module map or avoid finding the system installed
154 // modulemap for that library.
isForBuilding(const LangOptions & LangOpts) const155 bool Module::isForBuilding(const LangOptions &LangOpts) const {
156 StringRef TopLevelName = getTopLevelModuleName();
157 StringRef CurrentModule = LangOpts.CurrentModule;
158
159 // When building the implementation of framework Foo, we want to make sure
160 // that Foo *and* Foo_Private are textually included and no modules are built
161 // for either.
162 if (!LangOpts.isCompilingModule() && getTopLevelModule()->IsFramework &&
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
isAvailable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,UnresolvedHeaderDirective & MissingHeader,Module * & ShadowingModule) const171 bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
172 Requirement &Req,
173 UnresolvedHeaderDirective &MissingHeader,
174 Module *&ShadowingModule) const {
175 if (IsAvailable)
176 return true;
177
178 if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
179 return false;
180
181 // FIXME: All missing headers are listed on the top-level module. Should we
182 // just look there?
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
isSubModuleOf(const Module * Other) const193 bool Module::isSubModuleOf(const Module *Other) const {
194 for (auto *Parent = this; Parent; Parent = Parent->Parent) {
195 if (Parent == Other)
196 return true;
197 }
198 return false;
199 }
200
getTopLevelModule() const201 const Module *Module::getTopLevelModule() const {
202 const Module *Result = this;
203 while (Result->Parent)
204 Result = Result->Parent;
205
206 return Result;
207 }
208
getModuleNameFromComponent(const std::pair<std::string,SourceLocation> & IdComponent)209 static StringRef getModuleNameFromComponent(
210 const std::pair<std::string, SourceLocation> &IdComponent) {
211 return IdComponent.first;
212 }
213
getModuleNameFromComponent(StringRef R)214 static StringRef getModuleNameFromComponent(StringRef R) { return R; }
215
216 template<typename InputIter>
printModuleId(raw_ostream & OS,InputIter Begin,InputIter End,bool AllowStringLiterals=true)217 static 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
223 StringRef Name = getModuleNameFromComponent(*It);
224 if (!AllowStringLiterals || isValidAsciiIdentifier(Name))
225 OS << Name;
226 else {
227 OS << '"';
228 OS.write_escaped(Name);
229 OS << '"';
230 }
231 }
232 }
233
234 template<typename Container>
printModuleId(raw_ostream & OS,const Container & C)235 static void printModuleId(raw_ostream &OS, const Container &C) {
236 return printModuleId(OS, C.begin(), C.end());
237 }
238
getFullModuleName(bool AllowStringLiterals) const239 std::string Module::getFullModuleName(bool AllowStringLiterals) const {
240 SmallVector<StringRef, 2> Names;
241
242 // Build up the set of module names (from innermost to outermost).
243 for (const Module *M = this; M; M = M->Parent)
244 Names.push_back(M->Name);
245
246 std::string Result;
247
248 llvm::raw_string_ostream Out(Result);
249 printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
250
251 return Result;
252 }
253
fullModuleNameIs(ArrayRef<StringRef> nameParts) const254 bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
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
getEffectiveUmbrellaDir() const263 OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const {
264 if (const auto *Hdr = std::get_if<FileEntryRef>(&Umbrella))
265 return Hdr->getDir();
266 if (const auto *Dir = std::get_if<DirectoryEntryRef>(&Umbrella))
267 return *Dir;
268 return std::nullopt;
269 }
270
addTopHeader(FileEntryRef File)271 void Module::addTopHeader(FileEntryRef File) {
272 assert(File);
273 TopHeaders.insert(File);
274 }
275
getTopHeaders(FileManager & FileMgr)276 ArrayRef<FileEntryRef> Module::getTopHeaders(FileManager &FileMgr) {
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
directlyUses(const Module * Requested)287 bool Module::directlyUses(const Module *Requested) {
288 auto *Top = getTopLevelModule();
289
290 // A top-level module implicitly uses itself.
291 if (Requested->isSubModuleOf(Top))
292 return true;
293
294 for (auto *Use : Top->DirectUses)
295 if (Requested->isSubModuleOf(Use))
296 return true;
297
298 // Anyone is allowed to use our builtin stddef.h and its accompanying modules.
299 if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) ||
300 Requested->fullModuleNameIs({"_Builtin_stddef_wint_t"}))
301 return true;
302 // Darwin is allowed is to use our builtin 'ptrauth.h' and its accompanying
303 // module.
304 if (!Requested->Parent && Requested->Name == "ptrauth")
305 return true;
306
307 if (NoUndeclaredIncludes)
308 UndeclaredUses.insert(Requested);
309
310 return false;
311 }
312
addRequirement(StringRef Feature,bool RequiredState,const LangOptions & LangOpts,const TargetInfo & Target)313 void Module::addRequirement(StringRef Feature, bool RequiredState,
314 const LangOptions &LangOpts,
315 const TargetInfo &Target) {
316 Requirements.push_back(Requirement{std::string(Feature), RequiredState});
317
318 // If this feature is currently available, we're done.
319 if (hasFeature(Feature, LangOpts, Target) == RequiredState)
320 return;
321
322 markUnavailable(/*Unimportable*/true);
323 }
324
markUnavailable(bool Unimportable)325 void Module::markUnavailable(bool Unimportable) {
326 auto needUpdate = [Unimportable](Module *M) {
327 return M->IsAvailable || (!M->IsUnimportable && Unimportable);
328 };
329
330 if (!needUpdate(this))
331 return;
332
333 SmallVector<Module *, 2> Stack;
334 Stack.push_back(this);
335 while (!Stack.empty()) {
336 Module *Current = Stack.pop_back_val();
337
338 if (!needUpdate(Current))
339 continue;
340
341 Current->IsAvailable = false;
342 Current->IsUnimportable |= Unimportable;
343 for (auto *Submodule : Current->submodules()) {
344 if (needUpdate(Submodule))
345 Stack.push_back(Submodule);
346 }
347 }
348 }
349
findSubmodule(StringRef Name) const350 Module *Module::findSubmodule(StringRef Name) const {
351 // Add new submodules into the index.
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
getGlobalModuleFragment() const361 Module *Module::getGlobalModuleFragment() const {
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
getPrivateModuleFragment() const372 Module *Module::getPrivateModuleFragment() const {
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
getExportedModules(SmallVectorImpl<Module * > & Exported) const383 void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
384 // All non-explicit submodules are exported.
385 for (std::vector<Module *>::const_iterator I = SubModules.begin(),
386 E = SubModules.end();
387 I != E; ++I) {
388 Module *Mod = *I;
389 if (!Mod->IsExplicit)
390 Exported.push_back(Mod);
391 }
392
393 // Find re-exported modules by filtering the list of imported modules.
394 bool AnyWildcard = false;
395 bool UnrestrictedWildcard = false;
396 SmallVector<Module *, 4> WildcardRestrictions;
397 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
398 Module *Mod = Exports[I].getPointer();
399 if (!Exports[I].getInt()) {
400 // Export a named module directly; no wildcards involved.
401 Exported.push_back(Mod);
402
403 continue;
404 }
405
406 // Wildcard export: export all of the imported modules that match
407 // the given pattern.
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 // If there were any wildcards, push any imported modules that were
421 // re-exported by the wildcard restriction.
422 if (!AnyWildcard)
423 return;
424
425 for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
426 Module *Mod = Imports[I];
427 bool Acceptable = UnrestrictedWildcard;
428 if (!Acceptable) {
429 // Check whether this module meets one of the restrictions.
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
buildVisibleModulesCache() const446 void Module::buildVisibleModulesCache() const {
447 assert(VisibleModulesCache.empty() && "cache does not need building");
448
449 // This module is visible to itself.
450 VisibleModulesCache.insert(this);
451
452 // Every imported module is visible.
453 SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
454 while (!Stack.empty()) {
455 Module *CurrModule = Stack.pop_back_val();
456
457 // Every module transitively exported by an imported module is visible.
458 if (VisibleModulesCache.insert(CurrModule).second)
459 CurrModule->getExportedModules(Stack);
460 }
461 }
462
print(raw_ostream & OS,unsigned Indent,bool Dump) const463 void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
464 OS.indent(Indent);
465 if (IsFramework)
466 OS << "framework ";
467 if (IsExplicit)
468 OS << "explicit ";
469 OS << "module ";
470 printModuleId(OS, &Name, &Name + 1);
471
472 if (IsSystem || IsExternC) {
473 OS.indent(Indent + 2);
474 if (IsSystem)
475 OS << " [system]";
476 if (IsExternC)
477 OS << " [extern_c]";
478 }
479
480 OS << " {\n";
481
482 if (!Requirements.empty()) {
483 OS.indent(Indent + 2);
484 OS << "requires ";
485 for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
486 if (I)
487 OS << ", ";
488 if (!Requirements[I].RequiredState)
489 OS << "!";
490 OS << Requirements[I].FeatureName;
491 }
492 OS << "\n";
493 }
494
495 if (std::optional<Header> H = getUmbrellaHeaderAsWritten()) {
496 OS.indent(Indent + 2);
497 OS << "umbrella header \"";
498 OS.write_escaped(H->NameAsWritten);
499 OS << "\"\n";
500 } else if (std::optional<DirectoryName> D = getUmbrellaDirAsWritten()) {
501 OS.indent(Indent + 2);
502 OS << "umbrella \"";
503 OS.write_escaped(D->NameAsWritten);
504 OS << "\"\n";
505 }
506
507 if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
508 OS.indent(Indent + 2);
509 OS << "config_macros ";
510 if (ConfigMacrosExhaustive)
511 OS << "[exhaustive]";
512 for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
513 if (I)
514 OS << ", ";
515 OS << ConfigMacros[I];
516 }
517 OS << "\n";
518 }
519
520 struct {
521 StringRef Prefix;
522 HeaderKind Kind;
523 } Kinds[] = {{"", HK_Normal},
524 {"textual ", HK_Textual},
525 {"private ", HK_Private},
526 {"private textual ", HK_PrivateTextual},
527 {"exclude ", HK_Excluded}};
528
529 for (auto &K : Kinds) {
530 assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
531 for (auto &H : getHeaders(K.Kind)) {
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 }
539 for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
540 for (auto &U : *Unresolved) {
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
557 if (!ExportAsModule.empty()) {
558 OS.indent(Indent + 2);
559 OS << "export_as" << ExportAsModule << "\n";
560 }
561
562 for (auto *Submodule : submodules())
563 // Print inferred subframework modules so that we don't need to re-infer
564 // them (requires expensive directory iteration + stat calls) when we build
565 // the module. Regular inferred submodules are OK, as we need to look at all
566 // those header files anyway.
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);
575 if (Exports[I].getInt())
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 ";
586 printModuleId(OS, UnresolvedExports[I].Id);
587 if (UnresolvedExports[I].Wildcard)
588 OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
589 OS << "\n";
590 }
591
592 if (Dump) {
593 for (Module *M : Imports) {
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
606 for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
607 OS.indent(Indent + 2);
608 OS << "use ";
609 printModuleId(OS, UnresolvedDirectUses[I]);
610 OS << "\n";
611 }
612
613 for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
614 OS.indent(Indent + 2);
615 OS << "link ";
616 if (LinkLibraries[I].IsFramework)
617 OS << "framework ";
618 OS << "\"";
619 OS.write_escaped(LinkLibraries[I].Library);
620 OS << "\"";
621 }
622
623 for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
624 OS.indent(Indent + 2);
625 OS << "conflict ";
626 printModuleId(OS, UnresolvedConflicts[I].Id);
627 OS << ", \"";
628 OS.write_escaped(UnresolvedConflicts[I].Message);
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
641 if (InferSubmodules) {
642 OS.indent(Indent + 2);
643 if (InferExplicitSubmodules)
644 OS << "explicit ";
645 OS << "module * {\n";
646 if (InferExportWildcard) {
647 OS.indent(Indent + 4);
648 OS << "export *\n";
649 }
650 OS.indent(Indent + 2);
651 OS << "}\n";
652 }
653
654 OS.indent(Indent);
655 OS << "}\n";
656 }
657
dump() const658 LLVM_DUMP_METHOD void Module::dump() const {
659 print(llvm::errs(), 0, true);
660 }
661
setVisible(Module * M,SourceLocation Loc,bool IncludeExports,VisibleCallback Vis,ConflictCallback Cb)662 void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
663 bool IncludeExports, VisibleCallback Vis,
664 ConflictCallback Cb) {
665 // We can't import a global module fragment so the location can be invalid.
666 assert((M->isGlobalModule() || Loc.isValid()) &&
667 "setVisible expects a valid import location");
668 if (isVisible(M))
669 return;
670
671 ++Generation;
672
673 struct Visiting {
674 Module *M;
675 Visiting *ExportedBy;
676 };
677
678 std::function<void(Visiting)> VisitModule = [&](Visiting V) {
679 // Nothing to do for a module that's already visible.
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 // Make any exported modules visible.
690 if (IncludeExports) {
691 SmallVector<Module *, 16> Exports;
692 V.M->getExportedModules(Exports);
693 for (Module *E : Exports) {
694 // Don't import non-importable modules.
695 if (!E->isUnimportable())
696 VisitModule({E, &V});
697 }
698 }
699
700 for (auto &C : V.M->Conflicts) {
701 if (isVisible(C.Other)) {
702 llvm::SmallVector<Module*, 8> Path;
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 }
711