• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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       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 (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
63        I != IEnd; ++I) {
64     delete *I;
65   }
66 }
67 
isPlatformEnvironment(const TargetInfo & Target,StringRef Feature)68 static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
69   StringRef Platform = Target.getPlatformName();
70   StringRef Env = Target.getTriple().getEnvironmentName();
71 
72   // Attempt to match platform and environment.
73   if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
74       Env == Feature)
75     return true;
76 
77   auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
78     auto Pos = LHS.find("-");
79     if (Pos == StringRef::npos)
80       return false;
81     SmallString<128> NewLHS = LHS.slice(0, Pos);
82     NewLHS += LHS.slice(Pos+1, LHS.size());
83     return NewLHS == RHS;
84   };
85 
86   SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
87   // Darwin has different but equivalent variants for simulators, example:
88   //   1. x86_64-apple-ios-simulator
89   //   2. x86_64-apple-iossimulator
90   // where both are valid examples of the same platform+environment but in the
91   // variant (2) the simulator is hardcoded as part of the platform name. Both
92   // forms above should match for "iossimulator" requirement.
93   if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator"))
94     return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
95 
96   return PlatformEnv == Feature;
97 }
98 
99 /// Determine whether a translation unit built using the current
100 /// language options has the given feature.
hasFeature(StringRef Feature,const LangOptions & LangOpts,const TargetInfo & Target)101 static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
102                        const TargetInfo &Target) {
103   bool HasFeature = llvm::StringSwitch<bool>(Feature)
104                         .Case("altivec", LangOpts.AltiVec)
105                         .Case("blocks", LangOpts.Blocks)
106                         .Case("coroutines", LangOpts.Coroutines)
107                         .Case("cplusplus", LangOpts.CPlusPlus)
108                         .Case("cplusplus11", LangOpts.CPlusPlus11)
109                         .Case("cplusplus14", LangOpts.CPlusPlus14)
110                         .Case("cplusplus17", LangOpts.CPlusPlus17)
111                         .Case("c99", LangOpts.C99)
112                         .Case("c11", LangOpts.C11)
113                         .Case("c17", LangOpts.C17)
114                         .Case("freestanding", LangOpts.Freestanding)
115                         .Case("gnuinlineasm", LangOpts.GNUAsm)
116                         .Case("objc", LangOpts.ObjC)
117                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
118                         .Case("opencl", LangOpts.OpenCL)
119                         .Case("tls", Target.isTLSSupported())
120                         .Case("zvector", LangOpts.ZVector)
121                         .Default(Target.hasFeature(Feature) ||
122                                  isPlatformEnvironment(Target, Feature));
123   if (!HasFeature)
124     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
125                            LangOpts.ModuleFeatures.end(),
126                            Feature) != LangOpts.ModuleFeatures.end();
127   return HasFeature;
128 }
129 
isUnimportable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,Module * & ShadowingModule) const130 bool Module::isUnimportable(const LangOptions &LangOpts,
131                             const TargetInfo &Target, Requirement &Req,
132                             Module *&ShadowingModule) const {
133   if (!IsUnimportable)
134     return false;
135 
136   for (const Module *Current = this; Current; Current = Current->Parent) {
137     if (Current->ShadowingModule) {
138       ShadowingModule = Current->ShadowingModule;
139       return true;
140     }
141     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
142       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
143               Current->Requirements[I].second) {
144         Req = Current->Requirements[I];
145         return true;
146       }
147     }
148   }
149 
150   llvm_unreachable("could not find a reason why module is unimportable");
151 }
152 
isAvailable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,UnresolvedHeaderDirective & MissingHeader,Module * & ShadowingModule) const153 bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
154                          Requirement &Req,
155                          UnresolvedHeaderDirective &MissingHeader,
156                          Module *&ShadowingModule) const {
157   if (IsAvailable)
158     return true;
159 
160   if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
161     return false;
162 
163   // FIXME: All missing headers are listed on the top-level module. Should we
164   // just look there?
165   for (const Module *Current = this; Current; Current = Current->Parent) {
166     if (!Current->MissingHeaders.empty()) {
167       MissingHeader = Current->MissingHeaders.front();
168       return false;
169     }
170   }
171 
172   llvm_unreachable("could not find a reason why module is unavailable");
173 }
174 
isSubModuleOf(const Module * Other) const175 bool Module::isSubModuleOf(const Module *Other) const {
176   for (auto *Parent = this; Parent; Parent = Parent->Parent) {
177     if (Parent == Other)
178       return true;
179   }
180   return false;
181 }
182 
getTopLevelModule() const183 const Module *Module::getTopLevelModule() const {
184   const Module *Result = this;
185   while (Result->Parent)
186     Result = Result->Parent;
187 
188   return Result;
189 }
190 
getModuleNameFromComponent(const std::pair<std::string,SourceLocation> & IdComponent)191 static StringRef getModuleNameFromComponent(
192     const std::pair<std::string, SourceLocation> &IdComponent) {
193   return IdComponent.first;
194 }
195 
getModuleNameFromComponent(StringRef R)196 static StringRef getModuleNameFromComponent(StringRef R) { return R; }
197 
198 template<typename InputIter>
printModuleId(raw_ostream & OS,InputIter Begin,InputIter End,bool AllowStringLiterals=true)199 static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
200                           bool AllowStringLiterals = true) {
201   for (InputIter It = Begin; It != End; ++It) {
202     if (It != Begin)
203       OS << ".";
204 
205     StringRef Name = getModuleNameFromComponent(*It);
206     if (!AllowStringLiterals || isValidIdentifier(Name))
207       OS << Name;
208     else {
209       OS << '"';
210       OS.write_escaped(Name);
211       OS << '"';
212     }
213   }
214 }
215 
216 template<typename Container>
printModuleId(raw_ostream & OS,const Container & C)217 static void printModuleId(raw_ostream &OS, const Container &C) {
218   return printModuleId(OS, C.begin(), C.end());
219 }
220 
getFullModuleName(bool AllowStringLiterals) const221 std::string Module::getFullModuleName(bool AllowStringLiterals) const {
222   SmallVector<StringRef, 2> Names;
223 
224   // Build up the set of module names (from innermost to outermost).
225   for (const Module *M = this; M; M = M->Parent)
226     Names.push_back(M->Name);
227 
228   std::string Result;
229 
230   llvm::raw_string_ostream Out(Result);
231   printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
232   Out.flush();
233 
234   return Result;
235 }
236 
fullModuleNameIs(ArrayRef<StringRef> nameParts) const237 bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
238   for (const Module *M = this; M; M = M->Parent) {
239     if (nameParts.empty() || M->Name != nameParts.back())
240       return false;
241     nameParts = nameParts.drop_back();
242   }
243   return nameParts.empty();
244 }
245 
getUmbrellaDir() const246 Module::DirectoryName Module::getUmbrellaDir() const {
247   if (Header U = getUmbrellaHeader())
248     return {"", U.Entry->getDir()};
249 
250   if (auto *ME = Umbrella.dyn_cast<const DirectoryEntryRef::MapEntry *>())
251     return {UmbrellaAsWritten, DirectoryEntryRef(*ME)};
252 
253   return {"", None};
254 }
255 
addTopHeader(const FileEntry * File)256 void Module::addTopHeader(const FileEntry *File) {
257   assert(File);
258   TopHeaders.insert(File);
259 }
260 
getTopHeaders(FileManager & FileMgr)261 ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
262   if (!TopHeaderNames.empty()) {
263     for (std::vector<std::string>::iterator
264            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
265       if (auto FE = FileMgr.getFile(*I))
266         TopHeaders.insert(*FE);
267     }
268     TopHeaderNames.clear();
269   }
270 
271   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
272 }
273 
directlyUses(const Module * Requested) const274 bool Module::directlyUses(const Module *Requested) const {
275   auto *Top = getTopLevelModule();
276 
277   // A top-level module implicitly uses itself.
278   if (Requested->isSubModuleOf(Top))
279     return true;
280 
281   for (auto *Use : Top->DirectUses)
282     if (Requested->isSubModuleOf(Use))
283       return true;
284 
285   // Anyone is allowed to use our builtin stddef.h and its accompanying module.
286   if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
287     return true;
288 
289   return false;
290 }
291 
addRequirement(StringRef Feature,bool RequiredState,const LangOptions & LangOpts,const TargetInfo & Target)292 void Module::addRequirement(StringRef Feature, bool RequiredState,
293                             const LangOptions &LangOpts,
294                             const TargetInfo &Target) {
295   Requirements.push_back(Requirement(std::string(Feature), RequiredState));
296 
297   // If this feature is currently available, we're done.
298   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
299     return;
300 
301   markUnavailable(/*Unimportable*/true);
302 }
303 
markUnavailable(bool Unimportable)304 void Module::markUnavailable(bool Unimportable) {
305   auto needUpdate = [Unimportable](Module *M) {
306     return M->IsAvailable || (!M->IsUnimportable && Unimportable);
307   };
308 
309   if (!needUpdate(this))
310     return;
311 
312   SmallVector<Module *, 2> Stack;
313   Stack.push_back(this);
314   while (!Stack.empty()) {
315     Module *Current = Stack.back();
316     Stack.pop_back();
317 
318     if (!needUpdate(Current))
319       continue;
320 
321     Current->IsAvailable = false;
322     Current->IsUnimportable |= Unimportable;
323     for (submodule_iterator Sub = Current->submodule_begin(),
324                          SubEnd = Current->submodule_end();
325          Sub != SubEnd; ++Sub) {
326       if (needUpdate(*Sub))
327         Stack.push_back(*Sub);
328     }
329   }
330 }
331 
findSubmodule(StringRef Name) const332 Module *Module::findSubmodule(StringRef Name) const {
333   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
334   if (Pos == SubModuleIndex.end())
335     return nullptr;
336 
337   return SubModules[Pos->getValue()];
338 }
339 
findOrInferSubmodule(StringRef Name)340 Module *Module::findOrInferSubmodule(StringRef Name) {
341   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
342   if (Pos != SubModuleIndex.end())
343     return SubModules[Pos->getValue()];
344   if (!InferSubmodules)
345     return nullptr;
346   Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
347   Result->InferExplicitSubmodules = InferExplicitSubmodules;
348   Result->InferSubmodules = InferSubmodules;
349   Result->InferExportWildcard = InferExportWildcard;
350   if (Result->InferExportWildcard)
351     Result->Exports.push_back(Module::ExportDecl(nullptr, true));
352   return Result;
353 }
354 
getExportedModules(SmallVectorImpl<Module * > & Exported) const355 void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
356   // All non-explicit submodules are exported.
357   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
358                                              E = SubModules.end();
359        I != E; ++I) {
360     Module *Mod = *I;
361     if (!Mod->IsExplicit)
362       Exported.push_back(Mod);
363   }
364 
365   // Find re-exported modules by filtering the list of imported modules.
366   bool AnyWildcard = false;
367   bool UnrestrictedWildcard = false;
368   SmallVector<Module *, 4> WildcardRestrictions;
369   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
370     Module *Mod = Exports[I].getPointer();
371     if (!Exports[I].getInt()) {
372       // Export a named module directly; no wildcards involved.
373       Exported.push_back(Mod);
374 
375       continue;
376     }
377 
378     // Wildcard export: export all of the imported modules that match
379     // the given pattern.
380     AnyWildcard = true;
381     if (UnrestrictedWildcard)
382       continue;
383 
384     if (Module *Restriction = Exports[I].getPointer())
385       WildcardRestrictions.push_back(Restriction);
386     else {
387       WildcardRestrictions.clear();
388       UnrestrictedWildcard = true;
389     }
390   }
391 
392   // If there were any wildcards, push any imported modules that were
393   // re-exported by the wildcard restriction.
394   if (!AnyWildcard)
395     return;
396 
397   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
398     Module *Mod = Imports[I];
399     bool Acceptable = UnrestrictedWildcard;
400     if (!Acceptable) {
401       // Check whether this module meets one of the restrictions.
402       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
403         Module *Restriction = WildcardRestrictions[R];
404         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
405           Acceptable = true;
406           break;
407         }
408       }
409     }
410 
411     if (!Acceptable)
412       continue;
413 
414     Exported.push_back(Mod);
415   }
416 }
417 
buildVisibleModulesCache() const418 void Module::buildVisibleModulesCache() const {
419   assert(VisibleModulesCache.empty() && "cache does not need building");
420 
421   // This module is visible to itself.
422   VisibleModulesCache.insert(this);
423 
424   // Every imported module is visible.
425   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
426   while (!Stack.empty()) {
427     Module *CurrModule = Stack.pop_back_val();
428 
429     // Every module transitively exported by an imported module is visible.
430     if (VisibleModulesCache.insert(CurrModule).second)
431       CurrModule->getExportedModules(Stack);
432   }
433 }
434 
print(raw_ostream & OS,unsigned Indent) const435 void Module::print(raw_ostream &OS, unsigned Indent) const {
436   OS.indent(Indent);
437   if (IsFramework)
438     OS << "framework ";
439   if (IsExplicit)
440     OS << "explicit ";
441   OS << "module ";
442   printModuleId(OS, &Name, &Name + 1);
443 
444   if (IsSystem || IsExternC) {
445     OS.indent(Indent + 2);
446     if (IsSystem)
447       OS << " [system]";
448     if (IsExternC)
449       OS << " [extern_c]";
450   }
451 
452   OS << " {\n";
453 
454   if (!Requirements.empty()) {
455     OS.indent(Indent + 2);
456     OS << "requires ";
457     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
458       if (I)
459         OS << ", ";
460       if (!Requirements[I].second)
461         OS << "!";
462       OS << Requirements[I].first;
463     }
464     OS << "\n";
465   }
466 
467   if (Header H = getUmbrellaHeader()) {
468     OS.indent(Indent + 2);
469     OS << "umbrella header \"";
470     OS.write_escaped(H.NameAsWritten);
471     OS << "\"\n";
472   } else if (DirectoryName D = getUmbrellaDir()) {
473     OS.indent(Indent + 2);
474     OS << "umbrella \"";
475     OS.write_escaped(D.NameAsWritten);
476     OS << "\"\n";
477   }
478 
479   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
480     OS.indent(Indent + 2);
481     OS << "config_macros ";
482     if (ConfigMacrosExhaustive)
483       OS << "[exhaustive]";
484     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
485       if (I)
486         OS << ", ";
487       OS << ConfigMacros[I];
488     }
489     OS << "\n";
490   }
491 
492   struct {
493     StringRef Prefix;
494     HeaderKind Kind;
495   } Kinds[] = {{"", HK_Normal},
496                {"textual ", HK_Textual},
497                {"private ", HK_Private},
498                {"private textual ", HK_PrivateTextual},
499                {"exclude ", HK_Excluded}};
500 
501   for (auto &K : Kinds) {
502     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
503     for (auto &H : Headers[K.Kind]) {
504       OS.indent(Indent + 2);
505       OS << K.Prefix << "header \"";
506       OS.write_escaped(H.NameAsWritten);
507       OS << "\" { size " << H.Entry->getSize()
508          << " mtime " << H.Entry->getModificationTime() << " }\n";
509     }
510   }
511   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
512     for (auto &U : *Unresolved) {
513       OS.indent(Indent + 2);
514       OS << Kinds[U.Kind].Prefix << "header \"";
515       OS.write_escaped(U.FileName);
516       OS << "\"";
517       if (U.Size || U.ModTime) {
518         OS << " {";
519         if (U.Size)
520           OS << " size " << *U.Size;
521         if (U.ModTime)
522           OS << " mtime " << *U.ModTime;
523         OS << " }";
524       }
525       OS << "\n";
526     }
527   }
528 
529   if (!ExportAsModule.empty()) {
530     OS.indent(Indent + 2);
531     OS << "export_as" << ExportAsModule << "\n";
532   }
533 
534   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
535        MI != MIEnd; ++MI)
536     // Print inferred subframework modules so that we don't need to re-infer
537     // them (requires expensive directory iteration + stat calls) when we build
538     // the module. Regular inferred submodules are OK, as we need to look at all
539     // those header files anyway.
540     if (!(*MI)->IsInferred || (*MI)->IsFramework)
541       (*MI)->print(OS, Indent + 2);
542 
543   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
544     OS.indent(Indent + 2);
545     OS << "export ";
546     if (Module *Restriction = Exports[I].getPointer()) {
547       OS << Restriction->getFullModuleName(true);
548       if (Exports[I].getInt())
549         OS << ".*";
550     } else {
551       OS << "*";
552     }
553     OS << "\n";
554   }
555 
556   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
557     OS.indent(Indent + 2);
558     OS << "export ";
559     printModuleId(OS, UnresolvedExports[I].Id);
560     if (UnresolvedExports[I].Wildcard)
561       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
562     OS << "\n";
563   }
564 
565   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
566     OS.indent(Indent + 2);
567     OS << "use ";
568     OS << DirectUses[I]->getFullModuleName(true);
569     OS << "\n";
570   }
571 
572   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
573     OS.indent(Indent + 2);
574     OS << "use ";
575     printModuleId(OS, UnresolvedDirectUses[I]);
576     OS << "\n";
577   }
578 
579   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
580     OS.indent(Indent + 2);
581     OS << "link ";
582     if (LinkLibraries[I].IsFramework)
583       OS << "framework ";
584     OS << "\"";
585     OS.write_escaped(LinkLibraries[I].Library);
586     OS << "\"";
587   }
588 
589   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
590     OS.indent(Indent + 2);
591     OS << "conflict ";
592     printModuleId(OS, UnresolvedConflicts[I].Id);
593     OS << ", \"";
594     OS.write_escaped(UnresolvedConflicts[I].Message);
595     OS << "\"\n";
596   }
597 
598   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
599     OS.indent(Indent + 2);
600     OS << "conflict ";
601     OS << Conflicts[I].Other->getFullModuleName(true);
602     OS << ", \"";
603     OS.write_escaped(Conflicts[I].Message);
604     OS << "\"\n";
605   }
606 
607   if (InferSubmodules) {
608     OS.indent(Indent + 2);
609     if (InferExplicitSubmodules)
610       OS << "explicit ";
611     OS << "module * {\n";
612     if (InferExportWildcard) {
613       OS.indent(Indent + 4);
614       OS << "export *\n";
615     }
616     OS.indent(Indent + 2);
617     OS << "}\n";
618   }
619 
620   OS.indent(Indent);
621   OS << "}\n";
622 }
623 
dump() const624 LLVM_DUMP_METHOD void Module::dump() const {
625   print(llvm::errs());
626 }
627 
setVisible(Module * M,SourceLocation Loc,VisibleCallback Vis,ConflictCallback Cb)628 void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
629                                   VisibleCallback Vis, ConflictCallback Cb) {
630   assert(Loc.isValid() && "setVisible expects a valid import location");
631   if (isVisible(M))
632     return;
633 
634   ++Generation;
635 
636   struct Visiting {
637     Module *M;
638     Visiting *ExportedBy;
639   };
640 
641   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
642     // Nothing to do for a module that's already visible.
643     unsigned ID = V.M->getVisibilityID();
644     if (ImportLocs.size() <= ID)
645       ImportLocs.resize(ID + 1);
646     else if (ImportLocs[ID].isValid())
647       return;
648 
649     ImportLocs[ID] = Loc;
650     Vis(M);
651 
652     // Make any exported modules visible.
653     SmallVector<Module *, 16> Exports;
654     V.M->getExportedModules(Exports);
655     for (Module *E : Exports) {
656       // Don't import non-importable modules.
657       if (!E->isUnimportable())
658         VisitModule({E, &V});
659     }
660 
661     for (auto &C : V.M->Conflicts) {
662       if (isVisible(C.Other)) {
663         llvm::SmallVector<Module*, 8> Path;
664         for (Visiting *I = &V; I; I = I->ExportedBy)
665           Path.push_back(I->M);
666         Cb(Path, C.Other, C.Message);
667       }
668     }
669   };
670   VisitModule({M, nullptr});
671 }
672 
ASTSourceDescriptor(Module & M)673 ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
674     : Signature(M.Signature), ClangModule(&M) {
675   if (M.Directory)
676     Path = M.Directory->getName();
677   if (auto File = M.getASTFile())
678     ASTFile = File->getName();
679 }
680 
getModuleName() const681 std::string ASTSourceDescriptor::getModuleName() const {
682   if (ClangModule)
683     return ClangModule->Name;
684   else
685     return std::string(PCHModuleName);
686 }
687