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
34using namespace clang;
35
36Module::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(x: this);
57 }
58}
59
60Module::~Module() = default;
61
62static 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(C: '-');
73 if (Pos == StringRef::npos)
74 return false;
75 SmallString<128> NewLHS = LHS.slice(Start: 0, End: Pos);
76 NewLHS += LHS.slice(Start: Pos+1, End: 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(Suffix: "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.
95static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
96 const TargetInfo &Target) {
97 bool HasFeature = llvm::StringSwitch<bool>(Feature)
98 .Case(S: "altivec", Value: LangOpts.AltiVec)
99 .Case(S: "blocks", Value: LangOpts.Blocks)
100 .Case(S: "coroutines", Value: LangOpts.Coroutines)
101 .Case(S: "cplusplus", Value: LangOpts.CPlusPlus)
102 .Case(S: "cplusplus11", Value: LangOpts.CPlusPlus11)
103 .Case(S: "cplusplus14", Value: LangOpts.CPlusPlus14)
104 .Case(S: "cplusplus17", Value: LangOpts.CPlusPlus17)
105 .Case(S: "cplusplus20", Value: LangOpts.CPlusPlus20)
106 .Case(S: "cplusplus23", Value: LangOpts.CPlusPlus23)
107 .Case(S: "cplusplus26", Value: LangOpts.CPlusPlus26)
108 .Case(S: "c99", Value: LangOpts.C99)
109 .Case(S: "c11", Value: LangOpts.C11)
110 .Case(S: "c17", Value: LangOpts.C17)
111 .Case(S: "c23", Value: LangOpts.C23)
112 .Case(S: "freestanding", Value: LangOpts.Freestanding)
113 .Case(S: "gnuinlineasm", Value: LangOpts.GNUAsm)
114 .Case(S: "objc", Value: LangOpts.ObjC)
115 .Case(S: "objc_arc", Value: LangOpts.ObjCAutoRefCount)
116 .Case(S: "opencl", Value: LangOpts.OpenCL)
117 .Case(S: "tls", Value: Target.isTLSSupported())
118 .Case(S: "zvector", Value: LangOpts.ZVector)
119 .Default(Value: Target.hasFeature(Feature) ||
120 isPlatformEnvironment(Target, Feature));
121 if (!HasFeature)
122 HasFeature = llvm::is_contained(Range: LangOpts.ModuleFeatures, Element: Feature);
123 return HasFeature;
124}
125
126bool 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(Feature: 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.
155bool 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(Suffix: "_Private") &&
165 TopLevelName.ends_with(Suffix: "_Private"))
166 TopLevelName = TopLevelName.drop_back(N: 8);
167
168 return TopLevelName == CurrentModule;
169}
170
171bool 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
193bool 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
201const Module *Module::getTopLevelModule() const {
202 const Module *Result = this;
203 while (Result->Parent)
204 Result = Result->Parent;
205
206 return Result;
207}
208
209static StringRef getModuleNameFromComponent(
210 const std::pair<std::string, SourceLocation> &IdComponent) {
211 return IdComponent.first;
212}
213
214static StringRef getModuleNameFromComponent(StringRef R) { return R; }
215
216template<typename InputIter>
217static 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(S: Name))
225 OS << Name;
226 else {
227 OS << '"';
228 OS.write_escaped(Str: Name);
229 OS << '"';
230 }
231 }
232}
233
234template<typename Container>
235static void printModuleId(raw_ostream &OS, const Container &C) {
236 return printModuleId(OS, C.begin(), C.end());
237}
238
239std::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(Elt: M->Name);
245
246 std::string Result;
247
248 llvm::raw_string_ostream Out(Result);
249 printModuleId(OS&: Out, Begin: Names.rbegin(), End: Names.rend(), AllowStringLiterals);
250
251 return Result;
252}
253
254bool 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
263OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const {
264 if (const auto *Hdr = std::get_if<FileEntryRef>(ptr: &Umbrella))
265 return Hdr->getDir();
266 if (const auto *Dir = std::get_if<DirectoryEntryRef>(ptr: &Umbrella))
267 return *Dir;
268 return std::nullopt;
269}
270
271void Module::addTopHeader(FileEntryRef File) {
272 assert(File);
273 TopHeaders.insert(X: File);
274}
275
276ArrayRef<FileEntryRef> Module::getTopHeaders(FileManager &FileMgr) {
277 if (!TopHeaderNames.empty()) {
278 for (StringRef TopHeaderName : TopHeaderNames)
279 if (auto FE = FileMgr.getOptionalFileRef(Filename: TopHeaderName))
280 TopHeaders.insert(X: *FE);
281 TopHeaderNames.clear();
282 }
283
284 return llvm::ArrayRef(TopHeaders.begin(), TopHeaders.end());
285}
286
287bool Module::directlyUses(const Module *Requested) {
288 auto *Top = getTopLevelModule();
289
290 // A top-level module implicitly uses itself.
291 if (Requested->isSubModuleOf(Other: Top))
292 return true;
293
294 for (auto *Use : Top->DirectUses)
295 if (Requested->isSubModuleOf(Other: Use))
296 return true;
297
298 // Anyone is allowed to use our builtin stddef.h and its accompanying modules.
299 if (Requested->fullModuleNameIs(nameParts: {"_Builtin_stddef", "max_align_t"}) ||
300 Requested->fullModuleNameIs(nameParts: {"_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(X: Requested);
309
310 return false;
311}
312
313void Module::addRequirement(StringRef Feature, bool RequiredState,
314 const LangOptions &LangOpts,
315 const TargetInfo &Target) {
316 Requirements.push_back(Elt: Requirement{.FeatureName: std::string(Feature), .RequiredState: 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
325void 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(Elt: 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(Elt: Submodule);
346 }
347 }
348}
349
350Module *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(Key: Name); It != SubModuleIndex.end())
356 return SubModules[It->second];
357
358 return nullptr;
359}
360
361Module *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
372Module *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
383void 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(Elt: 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(Elt: 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(Elt: 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(Other: Restriction)) {
433 Acceptable = true;
434 break;
435 }
436 }
437 }
438
439 if (!Acceptable)
440 continue;
441
442 Exported.push_back(Elt: Mod);
443 }
444}
445
446void Module::buildVisibleModulesCache() const {
447 assert(VisibleModulesCache.empty() && "cache does not need building");
448
449 // This module is visible to itself.
450 VisibleModulesCache.insert(V: 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(V: CurrModule).second)
459 CurrModule->getExportedModules(Exported&: Stack);
460 }
461}
462
463void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
464 OS.indent(NumSpaces: Indent);
465 if (IsFramework)
466 OS << "framework ";
467 if (IsExplicit)
468 OS << "explicit ";
469 OS << "module ";
470 printModuleId(OS, Begin: &Name, End: &Name + 1);
471
472 if (IsSystem || IsExternC) {
473 OS.indent(NumSpaces: 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(NumSpaces: 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(NumSpaces: Indent + 2);
497 OS << "umbrella header \"";
498 OS.write_escaped(Str: H->NameAsWritten);
499 OS << "\"\n";
500 } else if (std::optional<DirectoryName> D = getUmbrellaDirAsWritten()) {
501 OS.indent(NumSpaces: Indent + 2);
502 OS << "umbrella \"";
503 OS.write_escaped(Str: D->NameAsWritten);
504 OS << "\"\n";
505 }
506
507 if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
508 OS.indent(NumSpaces: 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[] = {{.Prefix: "", .Kind: HK_Normal},
524 {.Prefix: "textual ", .Kind: HK_Textual},
525 {.Prefix: "private ", .Kind: HK_Private},
526 {.Prefix: "private textual ", .Kind: HK_PrivateTextual},
527 {.Prefix: "exclude ", .Kind: HK_Excluded}};
528
529 for (auto &K : Kinds) {
530 assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
531 for (auto &H : getHeaders(HK: K.Kind)) {
532 OS.indent(NumSpaces: Indent + 2);
533 OS << K.Prefix << "header \"";
534 OS.write_escaped(Str: 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(NumSpaces: Indent + 2);
542 OS << Kinds[U.Kind].Prefix << "header \"";
543 OS.write_escaped(Str: 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(NumSpaces: 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: Indent + 2, Dump);
569
570 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
571 OS.indent(NumSpaces: Indent + 2);
572 OS << "export ";
573 if (Module *Restriction = Exports[I].getPointer()) {
574 OS << Restriction->getFullModuleName(AllowStringLiterals: 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(NumSpaces: Indent + 2);
585 OS << "export ";
586 printModuleId(OS, C: 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(NumSpaces: 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(NumSpaces: Indent + 2);
601 OS << "use ";
602 OS << DirectUses[I]->getFullModuleName(AllowStringLiterals: true);
603 OS << "\n";
604 }
605
606 for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
607 OS.indent(NumSpaces: Indent + 2);
608 OS << "use ";
609 printModuleId(OS, C: UnresolvedDirectUses[I]);
610 OS << "\n";
611 }
612
613 for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
614 OS.indent(NumSpaces: Indent + 2);
615 OS << "link ";
616 if (LinkLibraries[I].IsFramework)
617 OS << "framework ";
618 OS << "\"";
619 OS.write_escaped(Str: LinkLibraries[I].Library);
620 OS << "\"";
621 }
622
623 for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
624 OS.indent(NumSpaces: Indent + 2);
625 OS << "conflict ";
626 printModuleId(OS, C: UnresolvedConflicts[I].Id);
627 OS << ", \"";
628 OS.write_escaped(Str: UnresolvedConflicts[I].Message);
629 OS << "\"\n";
630 }
631
632 for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
633 OS.indent(NumSpaces: Indent + 2);
634 OS << "conflict ";
635 OS << Conflicts[I].Other->getFullModuleName(AllowStringLiterals: true);
636 OS << ", \"";
637 OS.write_escaped(Str: Conflicts[I].Message);
638 OS << "\"\n";
639 }
640
641 if (InferSubmodules) {
642 OS.indent(NumSpaces: Indent + 2);
643 if (InferExplicitSubmodules)
644 OS << "explicit ";
645 OS << "module * {\n";
646 if (InferExportWildcard) {
647 OS.indent(NumSpaces: Indent + 4);
648 OS << "export *\n";
649 }
650 OS.indent(NumSpaces: Indent + 2);
651 OS << "}\n";
652 }
653
654 OS.indent(NumSpaces: Indent);
655 OS << "}\n";
656}
657
658LLVM_DUMP_METHOD void Module::dump() const {
659 print(OS&: llvm::errs(), Indent: 0, Dump: true);
660}
661
662void 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(new_size: 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(Exported&: Exports);
693 for (Module *E : Exports) {
694 // Don't import non-importable modules.
695 if (!E->isUnimportable())
696 VisitModule({.M: E, .ExportedBy: &V});
697 }
698 }
699
700 for (auto &C : V.M->Conflicts) {
701 if (isVisible(M: C.Other)) {
702 llvm::SmallVector<Module*, 8> Path;
703 for (Visiting *I = &V; I; I = I->ExportedBy)
704 Path.push_back(Elt: I->M);
705 Cb(Path, C.Other, C.Message);
706 }
707 }
708 };
709 VisitModule({.M: M, .ExportedBy: nullptr});
710}
711

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of clang/lib/Basic/Module.cpp