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