150
|
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
|
|
37 Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
|
|
38 bool IsFramework, bool IsExplicit, unsigned VisibilityID)
|
|
39 : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
|
173
|
40 VisibilityID(VisibilityID), IsUnimportable(false),
|
150
|
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),
|
173
|
47 HasUmbrellaDir(false), NameVisibility(Hidden) {
|
150
|
48 if (Parent) {
|
173
|
49 IsAvailable = Parent->isAvailable();
|
|
50 IsUnimportable = Parent->isUnimportable();
|
|
51 IsSystem = Parent->IsSystem;
|
|
52 IsExternC = Parent->IsExternC;
|
|
53 NoUndeclaredIncludes = Parent->NoUndeclaredIncludes;
|
|
54 ModuleMapIsPrivate = Parent->ModuleMapIsPrivate;
|
150
|
55
|
|
56 Parent->SubModuleIndex[Name] = Parent->SubModules.size();
|
|
57 Parent->SubModules.push_back(this);
|
|
58 }
|
|
59 }
|
|
60
|
|
61 Module::~Module() {
|
|
62 for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
|
|
63 I != IEnd; ++I) {
|
|
64 delete *I;
|
|
65 }
|
|
66 }
|
|
67
|
|
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.
|
|
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
|
173
|
130 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
|
150
|
153 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
|
173
|
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?
|
150
|
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
|
|
175 bool Module::isSubModuleOf(const Module *Other) const {
|
|
176 const Module *This = this;
|
|
177 do {
|
|
178 if (This == Other)
|
|
179 return true;
|
|
180
|
|
181 This = This->Parent;
|
|
182 } while (This);
|
|
183
|
|
184 return false;
|
|
185 }
|
|
186
|
|
187 const Module *Module::getTopLevelModule() const {
|
|
188 const Module *Result = this;
|
|
189 while (Result->Parent)
|
|
190 Result = Result->Parent;
|
|
191
|
|
192 return Result;
|
|
193 }
|
|
194
|
|
195 static StringRef getModuleNameFromComponent(
|
|
196 const std::pair<std::string, SourceLocation> &IdComponent) {
|
|
197 return IdComponent.first;
|
|
198 }
|
|
199
|
|
200 static StringRef getModuleNameFromComponent(StringRef R) { return R; }
|
|
201
|
|
202 template<typename InputIter>
|
|
203 static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
|
|
204 bool AllowStringLiterals = true) {
|
|
205 for (InputIter It = Begin; It != End; ++It) {
|
|
206 if (It != Begin)
|
|
207 OS << ".";
|
|
208
|
|
209 StringRef Name = getModuleNameFromComponent(*It);
|
|
210 if (!AllowStringLiterals || isValidIdentifier(Name))
|
|
211 OS << Name;
|
|
212 else {
|
|
213 OS << '"';
|
|
214 OS.write_escaped(Name);
|
|
215 OS << '"';
|
|
216 }
|
|
217 }
|
|
218 }
|
|
219
|
|
220 template<typename Container>
|
|
221 static void printModuleId(raw_ostream &OS, const Container &C) {
|
|
222 return printModuleId(OS, C.begin(), C.end());
|
|
223 }
|
|
224
|
|
225 std::string Module::getFullModuleName(bool AllowStringLiterals) const {
|
|
226 SmallVector<StringRef, 2> Names;
|
|
227
|
|
228 // Build up the set of module names (from innermost to outermost).
|
|
229 for (const Module *M = this; M; M = M->Parent)
|
|
230 Names.push_back(M->Name);
|
|
231
|
|
232 std::string Result;
|
|
233
|
|
234 llvm::raw_string_ostream Out(Result);
|
|
235 printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
|
|
236 Out.flush();
|
|
237
|
|
238 return Result;
|
|
239 }
|
|
240
|
|
241 bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
|
|
242 for (const Module *M = this; M; M = M->Parent) {
|
|
243 if (nameParts.empty() || M->Name != nameParts.back())
|
|
244 return false;
|
|
245 nameParts = nameParts.drop_back();
|
|
246 }
|
|
247 return nameParts.empty();
|
|
248 }
|
|
249
|
|
250 Module::DirectoryName Module::getUmbrellaDir() const {
|
|
251 if (Header U = getUmbrellaHeader())
|
|
252 return {"", U.Entry->getDir()};
|
|
253
|
173
|
254 return {UmbrellaAsWritten, static_cast<const DirectoryEntry *>(Umbrella)};
|
|
255 }
|
|
256
|
|
257 void Module::addTopHeader(const FileEntry *File) {
|
|
258 assert(File);
|
|
259 TopHeaders.insert(File);
|
150
|
260 }
|
|
261
|
|
262 ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
|
|
263 if (!TopHeaderNames.empty()) {
|
|
264 for (std::vector<std::string>::iterator
|
|
265 I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
|
|
266 if (auto FE = FileMgr.getFile(*I))
|
|
267 TopHeaders.insert(*FE);
|
|
268 }
|
|
269 TopHeaderNames.clear();
|
|
270 }
|
|
271
|
|
272 return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
|
|
273 }
|
|
274
|
|
275 bool Module::directlyUses(const Module *Requested) const {
|
|
276 auto *Top = getTopLevelModule();
|
|
277
|
|
278 // A top-level module implicitly uses itself.
|
|
279 if (Requested->isSubModuleOf(Top))
|
|
280 return true;
|
|
281
|
|
282 for (auto *Use : Top->DirectUses)
|
|
283 if (Requested->isSubModuleOf(Use))
|
|
284 return true;
|
|
285
|
|
286 // Anyone is allowed to use our builtin stddef.h and its accompanying module.
|
|
287 if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
|
|
288 return true;
|
|
289
|
|
290 return false;
|
|
291 }
|
|
292
|
|
293 void Module::addRequirement(StringRef Feature, bool RequiredState,
|
|
294 const LangOptions &LangOpts,
|
|
295 const TargetInfo &Target) {
|
|
296 Requirements.push_back(Requirement(std::string(Feature), RequiredState));
|
|
297
|
|
298 // If this feature is currently available, we're done.
|
|
299 if (hasFeature(Feature, LangOpts, Target) == RequiredState)
|
|
300 return;
|
|
301
|
173
|
302 markUnavailable(/*Unimportable*/true);
|
150
|
303 }
|
|
304
|
173
|
305 void Module::markUnavailable(bool Unimportable) {
|
|
306 auto needUpdate = [Unimportable](Module *M) {
|
|
307 return M->IsAvailable || (!M->IsUnimportable && Unimportable);
|
150
|
308 };
|
|
309
|
|
310 if (!needUpdate(this))
|
|
311 return;
|
|
312
|
|
313 SmallVector<Module *, 2> Stack;
|
|
314 Stack.push_back(this);
|
|
315 while (!Stack.empty()) {
|
|
316 Module *Current = Stack.back();
|
|
317 Stack.pop_back();
|
|
318
|
|
319 if (!needUpdate(Current))
|
|
320 continue;
|
|
321
|
|
322 Current->IsAvailable = false;
|
173
|
323 Current->IsUnimportable |= Unimportable;
|
150
|
324 for (submodule_iterator Sub = Current->submodule_begin(),
|
|
325 SubEnd = Current->submodule_end();
|
|
326 Sub != SubEnd; ++Sub) {
|
|
327 if (needUpdate(*Sub))
|
|
328 Stack.push_back(*Sub);
|
|
329 }
|
|
330 }
|
|
331 }
|
|
332
|
|
333 Module *Module::findSubmodule(StringRef Name) const {
|
|
334 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
|
|
335 if (Pos == SubModuleIndex.end())
|
|
336 return nullptr;
|
|
337
|
|
338 return SubModules[Pos->getValue()];
|
|
339 }
|
|
340
|
|
341 Module *Module::findOrInferSubmodule(StringRef Name) {
|
|
342 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
|
|
343 if (Pos != SubModuleIndex.end())
|
|
344 return SubModules[Pos->getValue()];
|
|
345 if (!InferSubmodules)
|
|
346 return nullptr;
|
|
347 Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
|
|
348 Result->InferExplicitSubmodules = InferExplicitSubmodules;
|
|
349 Result->InferSubmodules = InferSubmodules;
|
|
350 Result->InferExportWildcard = InferExportWildcard;
|
|
351 if (Result->InferExportWildcard)
|
|
352 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
|
|
353 return Result;
|
|
354 }
|
|
355
|
|
356 void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
|
|
357 // All non-explicit submodules are exported.
|
|
358 for (std::vector<Module *>::const_iterator I = SubModules.begin(),
|
|
359 E = SubModules.end();
|
|
360 I != E; ++I) {
|
|
361 Module *Mod = *I;
|
|
362 if (!Mod->IsExplicit)
|
|
363 Exported.push_back(Mod);
|
|
364 }
|
|
365
|
|
366 // Find re-exported modules by filtering the list of imported modules.
|
|
367 bool AnyWildcard = false;
|
|
368 bool UnrestrictedWildcard = false;
|
|
369 SmallVector<Module *, 4> WildcardRestrictions;
|
|
370 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
|
|
371 Module *Mod = Exports[I].getPointer();
|
|
372 if (!Exports[I].getInt()) {
|
|
373 // Export a named module directly; no wildcards involved.
|
|
374 Exported.push_back(Mod);
|
|
375
|
|
376 continue;
|
|
377 }
|
|
378
|
|
379 // Wildcard export: export all of the imported modules that match
|
|
380 // the given pattern.
|
|
381 AnyWildcard = true;
|
|
382 if (UnrestrictedWildcard)
|
|
383 continue;
|
|
384
|
|
385 if (Module *Restriction = Exports[I].getPointer())
|
|
386 WildcardRestrictions.push_back(Restriction);
|
|
387 else {
|
|
388 WildcardRestrictions.clear();
|
|
389 UnrestrictedWildcard = true;
|
|
390 }
|
|
391 }
|
|
392
|
|
393 // If there were any wildcards, push any imported modules that were
|
|
394 // re-exported by the wildcard restriction.
|
|
395 if (!AnyWildcard)
|
|
396 return;
|
|
397
|
|
398 for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
|
|
399 Module *Mod = Imports[I];
|
|
400 bool Acceptable = UnrestrictedWildcard;
|
|
401 if (!Acceptable) {
|
|
402 // Check whether this module meets one of the restrictions.
|
|
403 for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
|
|
404 Module *Restriction = WildcardRestrictions[R];
|
|
405 if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
|
|
406 Acceptable = true;
|
|
407 break;
|
|
408 }
|
|
409 }
|
|
410 }
|
|
411
|
|
412 if (!Acceptable)
|
|
413 continue;
|
|
414
|
|
415 Exported.push_back(Mod);
|
|
416 }
|
|
417 }
|
|
418
|
|
419 void Module::buildVisibleModulesCache() const {
|
|
420 assert(VisibleModulesCache.empty() && "cache does not need building");
|
|
421
|
|
422 // This module is visible to itself.
|
|
423 VisibleModulesCache.insert(this);
|
|
424
|
|
425 // Every imported module is visible.
|
|
426 SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
|
|
427 while (!Stack.empty()) {
|
|
428 Module *CurrModule = Stack.pop_back_val();
|
|
429
|
|
430 // Every module transitively exported by an imported module is visible.
|
|
431 if (VisibleModulesCache.insert(CurrModule).second)
|
|
432 CurrModule->getExportedModules(Stack);
|
|
433 }
|
|
434 }
|
|
435
|
|
436 void Module::print(raw_ostream &OS, unsigned Indent) const {
|
|
437 OS.indent(Indent);
|
|
438 if (IsFramework)
|
|
439 OS << "framework ";
|
|
440 if (IsExplicit)
|
|
441 OS << "explicit ";
|
|
442 OS << "module ";
|
|
443 printModuleId(OS, &Name, &Name + 1);
|
|
444
|
|
445 if (IsSystem || IsExternC) {
|
|
446 OS.indent(Indent + 2);
|
|
447 if (IsSystem)
|
|
448 OS << " [system]";
|
|
449 if (IsExternC)
|
|
450 OS << " [extern_c]";
|
|
451 }
|
|
452
|
|
453 OS << " {\n";
|
|
454
|
|
455 if (!Requirements.empty()) {
|
|
456 OS.indent(Indent + 2);
|
|
457 OS << "requires ";
|
|
458 for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
|
|
459 if (I)
|
|
460 OS << ", ";
|
|
461 if (!Requirements[I].second)
|
|
462 OS << "!";
|
|
463 OS << Requirements[I].first;
|
|
464 }
|
|
465 OS << "\n";
|
|
466 }
|
|
467
|
|
468 if (Header H = getUmbrellaHeader()) {
|
|
469 OS.indent(Indent + 2);
|
|
470 OS << "umbrella header \"";
|
|
471 OS.write_escaped(H.NameAsWritten);
|
|
472 OS << "\"\n";
|
|
473 } else if (DirectoryName D = getUmbrellaDir()) {
|
|
474 OS.indent(Indent + 2);
|
|
475 OS << "umbrella \"";
|
|
476 OS.write_escaped(D.NameAsWritten);
|
|
477 OS << "\"\n";
|
|
478 }
|
|
479
|
|
480 if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
|
|
481 OS.indent(Indent + 2);
|
|
482 OS << "config_macros ";
|
|
483 if (ConfigMacrosExhaustive)
|
|
484 OS << "[exhaustive]";
|
|
485 for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
|
|
486 if (I)
|
|
487 OS << ", ";
|
|
488 OS << ConfigMacros[I];
|
|
489 }
|
|
490 OS << "\n";
|
|
491 }
|
|
492
|
|
493 struct {
|
|
494 StringRef Prefix;
|
|
495 HeaderKind Kind;
|
|
496 } Kinds[] = {{"", HK_Normal},
|
|
497 {"textual ", HK_Textual},
|
|
498 {"private ", HK_Private},
|
|
499 {"private textual ", HK_PrivateTextual},
|
|
500 {"exclude ", HK_Excluded}};
|
|
501
|
|
502 for (auto &K : Kinds) {
|
|
503 assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
|
|
504 for (auto &H : Headers[K.Kind]) {
|
|
505 OS.indent(Indent + 2);
|
|
506 OS << K.Prefix << "header \"";
|
|
507 OS.write_escaped(H.NameAsWritten);
|
|
508 OS << "\" { size " << H.Entry->getSize()
|
|
509 << " mtime " << H.Entry->getModificationTime() << " }\n";
|
|
510 }
|
|
511 }
|
|
512 for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
|
|
513 for (auto &U : *Unresolved) {
|
|
514 OS.indent(Indent + 2);
|
|
515 OS << Kinds[U.Kind].Prefix << "header \"";
|
|
516 OS.write_escaped(U.FileName);
|
|
517 OS << "\"";
|
|
518 if (U.Size || U.ModTime) {
|
|
519 OS << " {";
|
|
520 if (U.Size)
|
|
521 OS << " size " << *U.Size;
|
|
522 if (U.ModTime)
|
|
523 OS << " mtime " << *U.ModTime;
|
|
524 OS << " }";
|
|
525 }
|
|
526 OS << "\n";
|
|
527 }
|
|
528 }
|
|
529
|
|
530 if (!ExportAsModule.empty()) {
|
|
531 OS.indent(Indent + 2);
|
|
532 OS << "export_as" << ExportAsModule << "\n";
|
|
533 }
|
|
534
|
|
535 for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
|
|
536 MI != MIEnd; ++MI)
|
|
537 // Print inferred subframework modules so that we don't need to re-infer
|
|
538 // them (requires expensive directory iteration + stat calls) when we build
|
|
539 // the module. Regular inferred submodules are OK, as we need to look at all
|
|
540 // those header files anyway.
|
|
541 if (!(*MI)->IsInferred || (*MI)->IsFramework)
|
|
542 (*MI)->print(OS, Indent + 2);
|
|
543
|
|
544 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
|
|
545 OS.indent(Indent + 2);
|
|
546 OS << "export ";
|
|
547 if (Module *Restriction = Exports[I].getPointer()) {
|
|
548 OS << Restriction->getFullModuleName(true);
|
|
549 if (Exports[I].getInt())
|
|
550 OS << ".*";
|
|
551 } else {
|
|
552 OS << "*";
|
|
553 }
|
|
554 OS << "\n";
|
|
555 }
|
|
556
|
|
557 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
|
|
558 OS.indent(Indent + 2);
|
|
559 OS << "export ";
|
|
560 printModuleId(OS, UnresolvedExports[I].Id);
|
|
561 if (UnresolvedExports[I].Wildcard)
|
|
562 OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
|
|
563 OS << "\n";
|
|
564 }
|
|
565
|
|
566 for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
|
|
567 OS.indent(Indent + 2);
|
|
568 OS << "use ";
|
|
569 OS << DirectUses[I]->getFullModuleName(true);
|
|
570 OS << "\n";
|
|
571 }
|
|
572
|
|
573 for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
|
|
574 OS.indent(Indent + 2);
|
|
575 OS << "use ";
|
|
576 printModuleId(OS, UnresolvedDirectUses[I]);
|
|
577 OS << "\n";
|
|
578 }
|
|
579
|
|
580 for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
|
|
581 OS.indent(Indent + 2);
|
|
582 OS << "link ";
|
|
583 if (LinkLibraries[I].IsFramework)
|
|
584 OS << "framework ";
|
|
585 OS << "\"";
|
|
586 OS.write_escaped(LinkLibraries[I].Library);
|
|
587 OS << "\"";
|
|
588 }
|
|
589
|
|
590 for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
|
|
591 OS.indent(Indent + 2);
|
|
592 OS << "conflict ";
|
|
593 printModuleId(OS, UnresolvedConflicts[I].Id);
|
|
594 OS << ", \"";
|
|
595 OS.write_escaped(UnresolvedConflicts[I].Message);
|
|
596 OS << "\"\n";
|
|
597 }
|
|
598
|
|
599 for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
|
|
600 OS.indent(Indent + 2);
|
|
601 OS << "conflict ";
|
|
602 OS << Conflicts[I].Other->getFullModuleName(true);
|
|
603 OS << ", \"";
|
|
604 OS.write_escaped(Conflicts[I].Message);
|
|
605 OS << "\"\n";
|
|
606 }
|
|
607
|
|
608 if (InferSubmodules) {
|
|
609 OS.indent(Indent + 2);
|
|
610 if (InferExplicitSubmodules)
|
|
611 OS << "explicit ";
|
|
612 OS << "module * {\n";
|
|
613 if (InferExportWildcard) {
|
|
614 OS.indent(Indent + 4);
|
|
615 OS << "export *\n";
|
|
616 }
|
|
617 OS.indent(Indent + 2);
|
|
618 OS << "}\n";
|
|
619 }
|
|
620
|
|
621 OS.indent(Indent);
|
|
622 OS << "}\n";
|
|
623 }
|
|
624
|
|
625 LLVM_DUMP_METHOD void Module::dump() const {
|
|
626 print(llvm::errs());
|
|
627 }
|
|
628
|
|
629 void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
|
|
630 VisibleCallback Vis, ConflictCallback Cb) {
|
|
631 assert(Loc.isValid() && "setVisible expects a valid import location");
|
|
632 if (isVisible(M))
|
|
633 return;
|
|
634
|
|
635 ++Generation;
|
|
636
|
|
637 struct Visiting {
|
|
638 Module *M;
|
|
639 Visiting *ExportedBy;
|
|
640 };
|
|
641
|
|
642 std::function<void(Visiting)> VisitModule = [&](Visiting V) {
|
|
643 // Nothing to do for a module that's already visible.
|
|
644 unsigned ID = V.M->getVisibilityID();
|
|
645 if (ImportLocs.size() <= ID)
|
|
646 ImportLocs.resize(ID + 1);
|
|
647 else if (ImportLocs[ID].isValid())
|
|
648 return;
|
|
649
|
|
650 ImportLocs[ID] = Loc;
|
|
651 Vis(M);
|
|
652
|
|
653 // Make any exported modules visible.
|
|
654 SmallVector<Module *, 16> Exports;
|
|
655 V.M->getExportedModules(Exports);
|
|
656 for (Module *E : Exports) {
|
173
|
657 // Don't import non-importable modules.
|
|
658 if (!E->isUnimportable())
|
150
|
659 VisitModule({E, &V});
|
|
660 }
|
|
661
|
|
662 for (auto &C : V.M->Conflicts) {
|
|
663 if (isVisible(C.Other)) {
|
|
664 llvm::SmallVector<Module*, 8> Path;
|
|
665 for (Visiting *I = &V; I; I = I->ExportedBy)
|
|
666 Path.push_back(I->M);
|
|
667 Cb(Path, C.Other, C.Message);
|
|
668 }
|
|
669 }
|
|
670 };
|
|
671 VisitModule({M, nullptr});
|
|
672 }
|
173
|
673
|
|
674 ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
|
|
675 : Signature(M.Signature), ClangModule(&M) {
|
|
676 if (M.Directory)
|
|
677 Path = M.Directory->getName();
|
|
678 if (auto *File = M.getASTFile())
|
|
679 ASTFile = File->getName();
|
|
680 }
|
|
681
|
|
682 std::string ASTSourceDescriptor::getModuleName() const {
|
|
683 if (ClangModule)
|
|
684 return ClangModule->Name;
|
|
685 else
|
|
686 return std::string(PCHModuleName);
|
|
687 }
|