1918e0ca7SEugene Zelenko //===- Module.cpp - Describe a module -------------------------------------===//
2de3ef502SDouglas Gregor //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6de3ef502SDouglas Gregor //
7de3ef502SDouglas Gregor //===----------------------------------------------------------------------===//
8de3ef502SDouglas Gregor //
9de3ef502SDouglas Gregor // This file defines the Module class, which describes a module in the source
10de3ef502SDouglas Gregor // code.
11de3ef502SDouglas Gregor //
12de3ef502SDouglas Gregor //===----------------------------------------------------------------------===//
13a3feee2aSRichard Smith 
14de3ef502SDouglas Gregor #include "clang/Basic/Module.h"
159565c75bSRichard Smith #include "clang/Basic/CharInfo.h"
16de3ef502SDouglas Gregor #include "clang/Basic/FileManager.h"
171fb5c3a6SDouglas Gregor #include "clang/Basic/LangOptions.h"
18918e0ca7SEugene Zelenko #include "clang/Basic/SourceLocation.h"
190070c0bfSDouglas Gregor #include "clang/Basic/TargetInfo.h"
203c5305c1SArgyrios Kyrtzidis #include "llvm/ADT/ArrayRef.h"
211fb5c3a6SDouglas Gregor #include "llvm/ADT/SmallVector.h"
22918e0ca7SEugene Zelenko #include "llvm/ADT/StringMap.h"
23918e0ca7SEugene Zelenko #include "llvm/ADT/StringRef.h"
241fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h"
25918e0ca7SEugene Zelenko #include "llvm/Support/Compiler.h"
263a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h"
273a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h"
28918e0ca7SEugene Zelenko #include <algorithm>
29918e0ca7SEugene Zelenko #include <cassert>
30918e0ca7SEugene Zelenko #include <functional>
31918e0ca7SEugene Zelenko #include <string>
32918e0ca7SEugene Zelenko #include <utility>
33918e0ca7SEugene Zelenko #include <vector>
34a3feee2aSRichard Smith 
35de3ef502SDouglas Gregor using namespace clang;
36de3ef502SDouglas Gregor 
37eb90e830SDouglas Gregor Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
38a7e2cc68SRichard Smith                bool IsFramework, bool IsExplicit, unsigned VisibilityID)
39918e0ca7SEugene Zelenko     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
40918e0ca7SEugene Zelenko       VisibilityID(VisibilityID), IsMissingRequirement(false),
41918e0ca7SEugene Zelenko       HasIncompatibleModuleFile(false), IsAvailable(true),
42918e0ca7SEugene Zelenko       IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
43918e0ca7SEugene Zelenko       IsSystem(false), IsExternC(false), IsInferred(false),
44918e0ca7SEugene Zelenko       InferSubmodules(false), InferExplicitSubmodules(false),
458a308ec2SRichard Smith       InferExportWildcard(false), ConfigMacrosExhaustive(false),
4690b0a1fcSJordan Rose       NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
47bc883665SReid Kleckner       HasUmbrellaDir(false), NameVisibility(Hidden) {
48eb90e830SDouglas Gregor   if (Parent) {
49eb90e830SDouglas Gregor     if (!Parent->isAvailable())
50eb90e830SDouglas Gregor       IsAvailable = false;
513ec6663bSDouglas Gregor     if (Parent->IsSystem)
523ec6663bSDouglas Gregor       IsSystem = true;
539bca298fSRichard Smith     if (Parent->IsExternC)
549bca298fSRichard Smith       IsExternC = true;
55ed84df00SBruno Cardoso Lopes     if (Parent->NoUndeclaredIncludes)
56ed84df00SBruno Cardoso Lopes       NoUndeclaredIncludes = true;
5790b0a1fcSJordan Rose     if (Parent->ModuleMapIsPrivate)
5890b0a1fcSJordan Rose       ModuleMapIsPrivate = true;
59993055f8SBen Langmuir     IsMissingRequirement = Parent->IsMissingRequirement;
60eb90e830SDouglas Gregor 
61eb90e830SDouglas Gregor     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
62eb90e830SDouglas Gregor     Parent->SubModules.push_back(this);
63eb90e830SDouglas Gregor   }
64eb90e830SDouglas Gregor }
65eb90e830SDouglas Gregor 
66de3ef502SDouglas Gregor Module::~Module() {
67eb90e830SDouglas Gregor   for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
68de3ef502SDouglas Gregor        I != IEnd; ++I) {
69eb90e830SDouglas Gregor     delete *I;
70de3ef502SDouglas Gregor   }
71de3ef502SDouglas Gregor }
72de3ef502SDouglas Gregor 
73e7240f02SBruno Cardoso Lopes static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
74e7240f02SBruno Cardoso Lopes   StringRef Platform = Target.getPlatformName();
75e7240f02SBruno Cardoso Lopes   StringRef Env = Target.getTriple().getEnvironmentName();
76e7240f02SBruno Cardoso Lopes 
77e7240f02SBruno Cardoso Lopes   // Attempt to match platform and environment.
78e7240f02SBruno Cardoso Lopes   if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
79e7240f02SBruno Cardoso Lopes       Env == Feature)
80e7240f02SBruno Cardoso Lopes     return true;
81e7240f02SBruno Cardoso Lopes 
82e7240f02SBruno Cardoso Lopes   auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
83e7240f02SBruno Cardoso Lopes     auto Pos = LHS.find("-");
84e7240f02SBruno Cardoso Lopes     if (Pos == StringRef::npos)
85e7240f02SBruno Cardoso Lopes       return false;
86e7240f02SBruno Cardoso Lopes     SmallString<128> NewLHS = LHS.slice(0, Pos);
87e7240f02SBruno Cardoso Lopes     NewLHS += LHS.slice(Pos+1, LHS.size());
88e7240f02SBruno Cardoso Lopes     return NewLHS == RHS;
89e7240f02SBruno Cardoso Lopes   };
90e7240f02SBruno Cardoso Lopes 
91e7240f02SBruno Cardoso Lopes   SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
92e7240f02SBruno Cardoso Lopes   // Darwin has different but equivalent variants for simulators, example:
93e7240f02SBruno Cardoso Lopes   //   1. x86_64-apple-ios-simulator
94e7240f02SBruno Cardoso Lopes   //   2. x86_64-apple-iossimulator
95e7240f02SBruno Cardoso Lopes   // where both are valid examples of the same platform+environment but in the
96e7240f02SBruno Cardoso Lopes   // variant (2) the simulator is hardcoded as part of the platform name. Both
97e7240f02SBruno Cardoso Lopes   // forms above should match for "iossimulator" requirement.
98e7240f02SBruno Cardoso Lopes   if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator"))
99e7240f02SBruno Cardoso Lopes     return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
100e7240f02SBruno Cardoso Lopes 
101e7240f02SBruno Cardoso Lopes   return PlatformEnv == Feature;
102e7240f02SBruno Cardoso Lopes }
103e7240f02SBruno Cardoso Lopes 
1049fc8faf9SAdrian Prantl /// Determine whether a translation unit built using the current
1051fb5c3a6SDouglas Gregor /// language options has the given feature.
10689929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
10789929282SDouglas Gregor                        const TargetInfo &Target) {
108532d2104SBen Langmuir   bool HasFeature = llvm::StringSwitch<bool>(Feature)
1090070c0bfSDouglas Gregor                         .Case("altivec", LangOpts.AltiVec)
1101fb5c3a6SDouglas Gregor                         .Case("blocks", LangOpts.Blocks)
11110ab78e8SRichard Smith                         .Case("coroutines", LangOpts.Coroutines)
1121fb5c3a6SDouglas Gregor                         .Case("cplusplus", LangOpts.CPlusPlus)
1132bf7fdb7SRichard Smith                         .Case("cplusplus11", LangOpts.CPlusPlus11)
1146d9cf8aaSBruno Cardoso Lopes                         .Case("cplusplus14", LangOpts.CPlusPlus14)
1156d9cf8aaSBruno Cardoso Lopes                         .Case("cplusplus17", LangOpts.CPlusPlus17)
1166d9cf8aaSBruno Cardoso Lopes                         .Case("c99", LangOpts.C99)
1176d9cf8aaSBruno Cardoso Lopes                         .Case("c11", LangOpts.C11)
1186d9cf8aaSBruno Cardoso Lopes                         .Case("c17", LangOpts.C17)
119fb6358d2SElad Cohen                         .Case("freestanding", LangOpts.Freestanding)
1206736e199SBruno Cardoso Lopes                         .Case("gnuinlineasm", LangOpts.GNUAsm)
121fa98390bSErik Pilkington                         .Case("objc", LangOpts.ObjC)
1221fb5c3a6SDouglas Gregor                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
1230070c0bfSDouglas Gregor                         .Case("opencl", LangOpts.OpenCL)
1240070c0bfSDouglas Gregor                         .Case("tls", Target.isTLSSupported())
1253c5038a5SUlrich Weigand                         .Case("zvector", LangOpts.ZVector)
126e7240f02SBruno Cardoso Lopes                         .Default(Target.hasFeature(Feature) ||
127e7240f02SBruno Cardoso Lopes                                  isPlatformEnvironment(Target, Feature));
128532d2104SBen Langmuir   if (!HasFeature)
129532d2104SBen Langmuir     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
130532d2104SBen Langmuir                            LangOpts.ModuleFeatures.end(),
131532d2104SBen Langmuir                            Feature) != LangOpts.ModuleFeatures.end();
132532d2104SBen Langmuir   return HasFeature;
1331fb5c3a6SDouglas Gregor }
1341fb5c3a6SDouglas Gregor 
1353c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
1363c1a41adSRichard Smith                          Requirement &Req,
1378587dfd9SBruno Cardoso Lopes                          UnresolvedHeaderDirective &MissingHeader,
1388587dfd9SBruno Cardoso Lopes                          Module *&ShadowingModule) const {
1391fb5c3a6SDouglas Gregor   if (IsAvailable)
1401fb5c3a6SDouglas Gregor     return true;
1411fb5c3a6SDouglas Gregor 
1421fb5c3a6SDouglas Gregor   for (const Module *Current = this; Current; Current = Current->Parent) {
1438587dfd9SBruno Cardoso Lopes     if (Current->ShadowingModule) {
1448587dfd9SBruno Cardoso Lopes       ShadowingModule = Current->ShadowingModule;
1458587dfd9SBruno Cardoso Lopes       return false;
1468587dfd9SBruno Cardoso Lopes     }
147a3feee2aSRichard Smith     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
148a3feee2aSRichard Smith       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
149a3feee2aSRichard Smith               Current->Requirements[I].second) {
150a3feee2aSRichard Smith         Req = Current->Requirements[I];
1511fb5c3a6SDouglas Gregor         return false;
1521fb5c3a6SDouglas Gregor       }
1531fb5c3a6SDouglas Gregor     }
15475a7e435SBen Langmuir     if (!Current->MissingHeaders.empty()) {
15575a7e435SBen Langmuir       MissingHeader = Current->MissingHeaders.front();
15675a7e435SBen Langmuir       return false;
15775a7e435SBen Langmuir     }
1581fb5c3a6SDouglas Gregor   }
1591fb5c3a6SDouglas Gregor 
1601fb5c3a6SDouglas Gregor   llvm_unreachable("could not find a reason why module is unavailable");
1611fb5c3a6SDouglas Gregor }
1621fb5c3a6SDouglas Gregor 
16362bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const {
164f5eedd05SDouglas Gregor   const Module *This = this;
165f5eedd05SDouglas Gregor   do {
166f5eedd05SDouglas Gregor     if (This == Other)
167f5eedd05SDouglas Gregor       return true;
168f5eedd05SDouglas Gregor 
169f5eedd05SDouglas Gregor     This = This->Parent;
170f5eedd05SDouglas Gregor   } while (This);
171f5eedd05SDouglas Gregor 
172f5eedd05SDouglas Gregor   return false;
173f5eedd05SDouglas Gregor }
174f5eedd05SDouglas Gregor 
17573441091SDouglas Gregor const Module *Module::getTopLevelModule() const {
17673441091SDouglas Gregor   const Module *Result = this;
17773441091SDouglas Gregor   while (Result->Parent)
17873441091SDouglas Gregor     Result = Result->Parent;
17973441091SDouglas Gregor 
18073441091SDouglas Gregor   return Result;
18173441091SDouglas Gregor }
18273441091SDouglas Gregor 
1839565c75bSRichard Smith static StringRef getModuleNameFromComponent(
1849565c75bSRichard Smith     const std::pair<std::string, SourceLocation> &IdComponent) {
1859565c75bSRichard Smith   return IdComponent.first;
1869565c75bSRichard Smith }
187918e0ca7SEugene Zelenko 
1889565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; }
1899565c75bSRichard Smith 
1909565c75bSRichard Smith template<typename InputIter>
1919565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
1929565c75bSRichard Smith                           bool AllowStringLiterals = true) {
1939565c75bSRichard Smith   for (InputIter It = Begin; It != End; ++It) {
1949565c75bSRichard Smith     if (It != Begin)
1959565c75bSRichard Smith       OS << ".";
1969565c75bSRichard Smith 
1979565c75bSRichard Smith     StringRef Name = getModuleNameFromComponent(*It);
1989565c75bSRichard Smith     if (!AllowStringLiterals || isValidIdentifier(Name))
1999565c75bSRichard Smith       OS << Name;
2009565c75bSRichard Smith     else {
2019565c75bSRichard Smith       OS << '"';
2029565c75bSRichard Smith       OS.write_escaped(Name);
2039565c75bSRichard Smith       OS << '"';
2049565c75bSRichard Smith     }
2059565c75bSRichard Smith   }
2069565c75bSRichard Smith }
2079565c75bSRichard Smith 
2089565c75bSRichard Smith template<typename Container>
2099565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) {
2109565c75bSRichard Smith   return printModuleId(OS, C.begin(), C.end());
2119565c75bSRichard Smith }
2129565c75bSRichard Smith 
2139565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const {
214f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Names;
215de3ef502SDouglas Gregor 
216de3ef502SDouglas Gregor   // Build up the set of module names (from innermost to outermost).
217de3ef502SDouglas Gregor   for (const Module *M = this; M; M = M->Parent)
218de3ef502SDouglas Gregor     Names.push_back(M->Name);
219de3ef502SDouglas Gregor 
220de3ef502SDouglas Gregor   std::string Result;
221de3ef502SDouglas Gregor 
2229565c75bSRichard Smith   llvm::raw_string_ostream Out(Result);
2239565c75bSRichard Smith   printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
2249565c75bSRichard Smith   Out.flush();
225de3ef502SDouglas Gregor 
226de3ef502SDouglas Gregor   return Result;
227de3ef502SDouglas Gregor }
228de3ef502SDouglas Gregor 
2297ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
2307ff29148SBen Langmuir   for (const Module *M = this; M; M = M->Parent) {
2317ff29148SBen Langmuir     if (nameParts.empty() || M->Name != nameParts.back())
2327ff29148SBen Langmuir       return false;
2337ff29148SBen Langmuir     nameParts = nameParts.drop_back();
2347ff29148SBen Langmuir   }
2357ff29148SBen Langmuir   return nameParts.empty();
2367ff29148SBen Langmuir }
2377ff29148SBen Langmuir 
2382b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const {
2392b63d15fSRichard Smith   if (Header U = getUmbrellaHeader())
2402b63d15fSRichard Smith     return {"", U.Entry->getDir()};
24173141fa9SDouglas Gregor 
242bc883665SReid Kleckner   return {UmbrellaAsWritten, static_cast<const DirectoryEntry *>(Umbrella)};
243bc883665SReid Kleckner }
244bc883665SReid Kleckner 
245bc883665SReid Kleckner void Module::addTopHeader(const FileEntry *File) {
246bc883665SReid Kleckner   assert(File);
247bc883665SReid Kleckner   TopHeaders.insert(File);
24873141fa9SDouglas Gregor }
24973141fa9SDouglas Gregor 
2503c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
2513c5305c1SArgyrios Kyrtzidis   if (!TopHeaderNames.empty()) {
2523c5305c1SArgyrios Kyrtzidis     for (std::vector<std::string>::iterator
2533c5305c1SArgyrios Kyrtzidis            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
2548d323d15SHarlan Haskins       if (auto FE = FileMgr.getFile(*I))
2558d323d15SHarlan Haskins         TopHeaders.insert(*FE);
2563c5305c1SArgyrios Kyrtzidis     }
2573c5305c1SArgyrios Kyrtzidis     TopHeaderNames.clear();
2583c5305c1SArgyrios Kyrtzidis   }
2593c5305c1SArgyrios Kyrtzidis 
2603c5305c1SArgyrios Kyrtzidis   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
2613c5305c1SArgyrios Kyrtzidis }
2623c5305c1SArgyrios Kyrtzidis 
2638f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const {
2648f4d3ff1SRichard Smith   auto *Top = getTopLevelModule();
2658f4d3ff1SRichard Smith 
2668f4d3ff1SRichard Smith   // A top-level module implicitly uses itself.
2678f4d3ff1SRichard Smith   if (Requested->isSubModuleOf(Top))
2688f4d3ff1SRichard Smith     return true;
2698f4d3ff1SRichard Smith 
2708f4d3ff1SRichard Smith   for (auto *Use : Top->DirectUses)
2718f4d3ff1SRichard Smith     if (Requested->isSubModuleOf(Use))
2728f4d3ff1SRichard Smith       return true;
273ed84df00SBruno Cardoso Lopes 
274ed84df00SBruno Cardoso Lopes   // Anyone is allowed to use our builtin stddef.h and its accompanying module.
275ed84df00SBruno Cardoso Lopes   if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
276ed84df00SBruno Cardoso Lopes     return true;
277ed84df00SBruno Cardoso Lopes 
2788f4d3ff1SRichard Smith   return false;
2798f4d3ff1SRichard Smith }
2808f4d3ff1SRichard Smith 
281a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState,
282a3feee2aSRichard Smith                             const LangOptions &LangOpts,
28389929282SDouglas Gregor                             const TargetInfo &Target) {
284bb39b529SBenjamin Kramer   Requirements.push_back(Requirement(std::string(Feature), RequiredState));
2851fb5c3a6SDouglas Gregor 
2861fb5c3a6SDouglas Gregor   // If this feature is currently available, we're done.
287a3feee2aSRichard Smith   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
2881fb5c3a6SDouglas Gregor     return;
2891fb5c3a6SDouglas Gregor 
290993055f8SBen Langmuir   markUnavailable(/*MissingRequirement*/true);
291ec8c9752SBen Langmuir }
292ec8c9752SBen Langmuir 
293993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) {
29475a7e435SBen Langmuir   auto needUpdate = [MissingRequirement](Module *M) {
29575a7e435SBen Langmuir     return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
29675a7e435SBen Langmuir   };
29775a7e435SBen Langmuir 
29875a7e435SBen Langmuir   if (!needUpdate(this))
2991fb5c3a6SDouglas Gregor     return;
3001fb5c3a6SDouglas Gregor 
301f857950dSDmitri Gribenko   SmallVector<Module *, 2> Stack;
3021fb5c3a6SDouglas Gregor   Stack.push_back(this);
3031fb5c3a6SDouglas Gregor   while (!Stack.empty()) {
3041fb5c3a6SDouglas Gregor     Module *Current = Stack.back();
3051fb5c3a6SDouglas Gregor     Stack.pop_back();
3061fb5c3a6SDouglas Gregor 
30775a7e435SBen Langmuir     if (!needUpdate(Current))
3081fb5c3a6SDouglas Gregor       continue;
3091fb5c3a6SDouglas Gregor 
3101fb5c3a6SDouglas Gregor     Current->IsAvailable = false;
311993055f8SBen Langmuir     Current->IsMissingRequirement |= MissingRequirement;
312eb90e830SDouglas Gregor     for (submodule_iterator Sub = Current->submodule_begin(),
313eb90e830SDouglas Gregor                          SubEnd = Current->submodule_end();
3141fb5c3a6SDouglas Gregor          Sub != SubEnd; ++Sub) {
31575a7e435SBen Langmuir       if (needUpdate(*Sub))
316eb90e830SDouglas Gregor         Stack.push_back(*Sub);
3171fb5c3a6SDouglas Gregor     }
3181fb5c3a6SDouglas Gregor   }
3191fb5c3a6SDouglas Gregor }
3201fb5c3a6SDouglas Gregor 
321eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const {
322eb90e830SDouglas Gregor   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
323eb90e830SDouglas Gregor   if (Pos == SubModuleIndex.end())
324f1186c5aSCraig Topper     return nullptr;
325eb90e830SDouglas Gregor 
326eb90e830SDouglas Gregor   return SubModules[Pos->getValue()];
327eb90e830SDouglas Gregor }
328eb90e830SDouglas Gregor 
32989e58ddbSDavid Blaikie Module *Module::findOrInferSubmodule(StringRef Name) {
33089e58ddbSDavid Blaikie   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
33189e58ddbSDavid Blaikie   if (Pos != SubModuleIndex.end())
33289e58ddbSDavid Blaikie     return SubModules[Pos->getValue()];
33389e58ddbSDavid Blaikie   if (!InferSubmodules)
33489e58ddbSDavid Blaikie     return nullptr;
33589e58ddbSDavid Blaikie   Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
33689e58ddbSDavid Blaikie   Result->InferExplicitSubmodules = InferExplicitSubmodules;
33789e58ddbSDavid Blaikie   Result->InferSubmodules = InferSubmodules;
33889e58ddbSDavid Blaikie   Result->InferExportWildcard = InferExportWildcard;
33989e58ddbSDavid Blaikie   if (Result->InferExportWildcard)
34089e58ddbSDavid Blaikie     Result->Exports.push_back(Module::ExportDecl(nullptr, true));
34189e58ddbSDavid Blaikie   return Result;
34289e58ddbSDavid Blaikie }
34389e58ddbSDavid Blaikie 
3448739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
345e9bcf5b7SDmitri Gribenko   // All non-explicit submodules are exported.
346e9bcf5b7SDmitri Gribenko   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
347e9bcf5b7SDmitri Gribenko                                              E = SubModules.end();
348e9bcf5b7SDmitri Gribenko        I != E; ++I) {
349e9bcf5b7SDmitri Gribenko     Module *Mod = *I;
350e9bcf5b7SDmitri Gribenko     if (!Mod->IsExplicit)
351e9bcf5b7SDmitri Gribenko       Exported.push_back(Mod);
352e9bcf5b7SDmitri Gribenko   }
353e9bcf5b7SDmitri Gribenko 
354e9bcf5b7SDmitri Gribenko   // Find re-exported modules by filtering the list of imported modules.
3558739f7b7SArgyrios Kyrtzidis   bool AnyWildcard = false;
3568739f7b7SArgyrios Kyrtzidis   bool UnrestrictedWildcard = false;
3578739f7b7SArgyrios Kyrtzidis   SmallVector<Module *, 4> WildcardRestrictions;
3588739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
3598739f7b7SArgyrios Kyrtzidis     Module *Mod = Exports[I].getPointer();
3608739f7b7SArgyrios Kyrtzidis     if (!Exports[I].getInt()) {
3618739f7b7SArgyrios Kyrtzidis       // Export a named module directly; no wildcards involved.
3628739f7b7SArgyrios Kyrtzidis       Exported.push_back(Mod);
3638739f7b7SArgyrios Kyrtzidis 
3648739f7b7SArgyrios Kyrtzidis       continue;
3658739f7b7SArgyrios Kyrtzidis     }
3668739f7b7SArgyrios Kyrtzidis 
3678739f7b7SArgyrios Kyrtzidis     // Wildcard export: export all of the imported modules that match
3688739f7b7SArgyrios Kyrtzidis     // the given pattern.
3698739f7b7SArgyrios Kyrtzidis     AnyWildcard = true;
3708739f7b7SArgyrios Kyrtzidis     if (UnrestrictedWildcard)
3718739f7b7SArgyrios Kyrtzidis       continue;
3728739f7b7SArgyrios Kyrtzidis 
3738739f7b7SArgyrios Kyrtzidis     if (Module *Restriction = Exports[I].getPointer())
3748739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.push_back(Restriction);
3758739f7b7SArgyrios Kyrtzidis     else {
3768739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.clear();
3778739f7b7SArgyrios Kyrtzidis       UnrestrictedWildcard = true;
3788739f7b7SArgyrios Kyrtzidis     }
3798739f7b7SArgyrios Kyrtzidis   }
3808739f7b7SArgyrios Kyrtzidis 
3818739f7b7SArgyrios Kyrtzidis   // If there were any wildcards, push any imported modules that were
3828739f7b7SArgyrios Kyrtzidis   // re-exported by the wildcard restriction.
3838739f7b7SArgyrios Kyrtzidis   if (!AnyWildcard)
3848739f7b7SArgyrios Kyrtzidis     return;
3858739f7b7SArgyrios Kyrtzidis 
3868739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
3878739f7b7SArgyrios Kyrtzidis     Module *Mod = Imports[I];
3888739f7b7SArgyrios Kyrtzidis     bool Acceptable = UnrestrictedWildcard;
3898739f7b7SArgyrios Kyrtzidis     if (!Acceptable) {
3908739f7b7SArgyrios Kyrtzidis       // Check whether this module meets one of the restrictions.
3918739f7b7SArgyrios Kyrtzidis       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
3928739f7b7SArgyrios Kyrtzidis         Module *Restriction = WildcardRestrictions[R];
3938739f7b7SArgyrios Kyrtzidis         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
3948739f7b7SArgyrios Kyrtzidis           Acceptable = true;
3958739f7b7SArgyrios Kyrtzidis           break;
3968739f7b7SArgyrios Kyrtzidis         }
3978739f7b7SArgyrios Kyrtzidis       }
3988739f7b7SArgyrios Kyrtzidis     }
3998739f7b7SArgyrios Kyrtzidis 
4008739f7b7SArgyrios Kyrtzidis     if (!Acceptable)
4018739f7b7SArgyrios Kyrtzidis       continue;
4028739f7b7SArgyrios Kyrtzidis 
4038739f7b7SArgyrios Kyrtzidis     Exported.push_back(Mod);
4048739f7b7SArgyrios Kyrtzidis   }
4058739f7b7SArgyrios Kyrtzidis }
4068739f7b7SArgyrios Kyrtzidis 
4070e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const {
4080e5d7b8cSRichard Smith   assert(VisibleModulesCache.empty() && "cache does not need building");
4090e5d7b8cSRichard Smith 
4100e5d7b8cSRichard Smith   // This module is visible to itself.
4110e5d7b8cSRichard Smith   VisibleModulesCache.insert(this);
4120e5d7b8cSRichard Smith 
4130e5d7b8cSRichard Smith   // Every imported module is visible.
414dde17e74SRichard Smith   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
415dc360d57SDmitri Gribenko   while (!Stack.empty()) {
416dc360d57SDmitri Gribenko     Module *CurrModule = Stack.pop_back_val();
417dc360d57SDmitri Gribenko 
418dde17e74SRichard Smith     // Every module transitively exported by an imported module is visible.
419dde17e74SRichard Smith     if (VisibleModulesCache.insert(CurrModule).second)
420dde17e74SRichard Smith       CurrModule->getExportedModules(Stack);
4210e5d7b8cSRichard Smith   }
4220e5d7b8cSRichard Smith }
4230e5d7b8cSRichard Smith 
424f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const {
425de3ef502SDouglas Gregor   OS.indent(Indent);
426de3ef502SDouglas Gregor   if (IsFramework)
427de3ef502SDouglas Gregor     OS << "framework ";
428de3ef502SDouglas Gregor   if (IsExplicit)
429de3ef502SDouglas Gregor     OS << "explicit ";
4309565c75bSRichard Smith   OS << "module ";
4319565c75bSRichard Smith   printModuleId(OS, &Name, &Name + 1);
432a686e1b0SDouglas Gregor 
4337615f00eSBen Langmuir   if (IsSystem || IsExternC) {
434a686e1b0SDouglas Gregor     OS.indent(Indent + 2);
4357615f00eSBen Langmuir     if (IsSystem)
436a686e1b0SDouglas Gregor       OS << " [system]";
4377615f00eSBen Langmuir     if (IsExternC)
4387615f00eSBen Langmuir       OS << " [extern_c]";
439a686e1b0SDouglas Gregor   }
440a686e1b0SDouglas Gregor 
441a686e1b0SDouglas Gregor   OS << " {\n";
442de3ef502SDouglas Gregor 
443a3feee2aSRichard Smith   if (!Requirements.empty()) {
4441fb5c3a6SDouglas Gregor     OS.indent(Indent + 2);
4451fb5c3a6SDouglas Gregor     OS << "requires ";
446a3feee2aSRichard Smith     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
4471fb5c3a6SDouglas Gregor       if (I)
4481fb5c3a6SDouglas Gregor         OS << ", ";
449a3feee2aSRichard Smith       if (!Requirements[I].second)
450a3feee2aSRichard Smith         OS << "!";
451a3feee2aSRichard Smith       OS << Requirements[I].first;
4521fb5c3a6SDouglas Gregor     }
4531fb5c3a6SDouglas Gregor     OS << "\n";
4541fb5c3a6SDouglas Gregor   }
4551fb5c3a6SDouglas Gregor 
4562b63d15fSRichard Smith   if (Header H = getUmbrellaHeader()) {
457de3ef502SDouglas Gregor     OS.indent(Indent + 2);
458322f633cSDouglas Gregor     OS << "umbrella header \"";
4592b63d15fSRichard Smith     OS.write_escaped(H.NameAsWritten);
460de3ef502SDouglas Gregor     OS << "\"\n";
4612b63d15fSRichard Smith   } else if (DirectoryName D = getUmbrellaDir()) {
462322f633cSDouglas Gregor     OS.indent(Indent + 2);
463322f633cSDouglas Gregor     OS << "umbrella \"";
4642b63d15fSRichard Smith     OS.write_escaped(D.NameAsWritten);
465322f633cSDouglas Gregor     OS << "\"\n";
466de3ef502SDouglas Gregor   }
467de3ef502SDouglas Gregor 
46835b13eceSDouglas Gregor   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
46935b13eceSDouglas Gregor     OS.indent(Indent + 2);
47035b13eceSDouglas Gregor     OS << "config_macros ";
47135b13eceSDouglas Gregor     if (ConfigMacrosExhaustive)
4728d932427SDouglas Gregor       OS << "[exhaustive]";
47335b13eceSDouglas Gregor     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
47435b13eceSDouglas Gregor       if (I)
47535b13eceSDouglas Gregor         OS << ", ";
47635b13eceSDouglas Gregor       OS << ConfigMacros[I];
47735b13eceSDouglas Gregor     }
4788d932427SDouglas Gregor     OS << "\n";
47935b13eceSDouglas Gregor   }
48035b13eceSDouglas Gregor 
4813c1a41adSRichard Smith   struct {
482306d8920SRichard Smith     StringRef Prefix;
4833c1a41adSRichard Smith     HeaderKind Kind;
4843c1a41adSRichard Smith   } Kinds[] = {{"", HK_Normal},
4853c1a41adSRichard Smith                {"textual ", HK_Textual},
4863c1a41adSRichard Smith                {"private ", HK_Private},
4873c1a41adSRichard Smith                {"private textual ", HK_PrivateTextual},
4883c1a41adSRichard Smith                {"exclude ", HK_Excluded}};
489306d8920SRichard Smith 
490306d8920SRichard Smith   for (auto &K : Kinds) {
491040e1266SRichard Smith     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
4923c1a41adSRichard Smith     for (auto &H : Headers[K.Kind]) {
493de3ef502SDouglas Gregor       OS.indent(Indent + 2);
494306d8920SRichard Smith       OS << K.Prefix << "header \"";
4953c1a41adSRichard Smith       OS.write_escaped(H.NameAsWritten);
496040e1266SRichard Smith       OS << "\" { size " << H.Entry->getSize()
497040e1266SRichard Smith          << " mtime " << H.Entry->getModificationTime() << " }\n";
498040e1266SRichard Smith     }
499040e1266SRichard Smith   }
500040e1266SRichard Smith   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
501040e1266SRichard Smith     for (auto &U : *Unresolved) {
502040e1266SRichard Smith       OS.indent(Indent + 2);
503040e1266SRichard Smith       OS << Kinds[U.Kind].Prefix << "header \"";
504040e1266SRichard Smith       OS.write_escaped(U.FileName);
505040e1266SRichard Smith       OS << "\"";
506040e1266SRichard Smith       if (U.Size || U.ModTime) {
507040e1266SRichard Smith         OS << " {";
508040e1266SRichard Smith         if (U.Size)
509040e1266SRichard Smith           OS << " size " << *U.Size;
510040e1266SRichard Smith         if (U.ModTime)
511040e1266SRichard Smith           OS << " mtime " << *U.ModTime;
512040e1266SRichard Smith         OS << " }";
513040e1266SRichard Smith       }
514040e1266SRichard Smith       OS << "\n";
515de3ef502SDouglas Gregor     }
516b53e5483SLawrence Crowl   }
517b53e5483SLawrence Crowl 
518f0b11de2SDouglas Gregor   if (!ExportAsModule.empty()) {
519f0b11de2SDouglas Gregor     OS.indent(Indent + 2);
520f0b11de2SDouglas Gregor     OS << "export_as" << ExportAsModule << "\n";
521f0b11de2SDouglas Gregor   }
522f0b11de2SDouglas Gregor 
523eb90e830SDouglas Gregor   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
524de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
5259d6448b1SBen Langmuir     // Print inferred subframework modules so that we don't need to re-infer
5269d6448b1SBen Langmuir     // them (requires expensive directory iteration + stat calls) when we build
5279d6448b1SBen Langmuir     // the module. Regular inferred submodules are OK, as we need to look at all
5289d6448b1SBen Langmuir     // those header files anyway.
5299d6448b1SBen Langmuir     if (!(*MI)->IsInferred || (*MI)->IsFramework)
530eb90e830SDouglas Gregor       (*MI)->print(OS, Indent + 2);
531de3ef502SDouglas Gregor 
53224bb923aSDouglas Gregor   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
53324bb923aSDouglas Gregor     OS.indent(Indent + 2);
5348c7c8352SDouglas Gregor     OS << "export ";
5358c7c8352SDouglas Gregor     if (Module *Restriction = Exports[I].getPointer()) {
5369565c75bSRichard Smith       OS << Restriction->getFullModuleName(true);
53724bb923aSDouglas Gregor       if (Exports[I].getInt())
53824bb923aSDouglas Gregor         OS << ".*";
5398c7c8352SDouglas Gregor     } else {
5408c7c8352SDouglas Gregor       OS << "*";
5418c7c8352SDouglas Gregor     }
54224bb923aSDouglas Gregor     OS << "\n";
54324bb923aSDouglas Gregor   }
54424bb923aSDouglas Gregor 
54524bb923aSDouglas Gregor   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
54624bb923aSDouglas Gregor     OS.indent(Indent + 2);
54724bb923aSDouglas Gregor     OS << "export ";
54824bb923aSDouglas Gregor     printModuleId(OS, UnresolvedExports[I].Id);
5497f96b391SDavide Italiano     if (UnresolvedExports[I].Wildcard)
5507f96b391SDavide Italiano       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
55124bb923aSDouglas Gregor     OS << "\n";
55224bb923aSDouglas Gregor   }
55324bb923aSDouglas Gregor 
554ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
555ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
556ba7f2f71SDaniel Jasper     OS << "use ";
5579565c75bSRichard Smith     OS << DirectUses[I]->getFullModuleName(true);
558ba7f2f71SDaniel Jasper     OS << "\n";
559ba7f2f71SDaniel Jasper   }
560ba7f2f71SDaniel Jasper 
561ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
562ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
563ba7f2f71SDaniel Jasper     OS << "use ";
564ba7f2f71SDaniel Jasper     printModuleId(OS, UnresolvedDirectUses[I]);
565ba7f2f71SDaniel Jasper     OS << "\n";
566ba7f2f71SDaniel Jasper   }
567ba7f2f71SDaniel Jasper 
5686ddfca91SDouglas Gregor   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
5696ddfca91SDouglas Gregor     OS.indent(Indent + 2);
5706ddfca91SDouglas Gregor     OS << "link ";
5716ddfca91SDouglas Gregor     if (LinkLibraries[I].IsFramework)
5726ddfca91SDouglas Gregor       OS << "framework ";
5736ddfca91SDouglas Gregor     OS << "\"";
5746ddfca91SDouglas Gregor     OS.write_escaped(LinkLibraries[I].Library);
5756ddfca91SDouglas Gregor     OS << "\"";
5766ddfca91SDouglas Gregor   }
5776ddfca91SDouglas Gregor 
578fb912657SDouglas Gregor   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
579fb912657SDouglas Gregor     OS.indent(Indent + 2);
580fb912657SDouglas Gregor     OS << "conflict ";
581fb912657SDouglas Gregor     printModuleId(OS, UnresolvedConflicts[I].Id);
582fb912657SDouglas Gregor     OS << ", \"";
583fb912657SDouglas Gregor     OS.write_escaped(UnresolvedConflicts[I].Message);
584fb912657SDouglas Gregor     OS << "\"\n";
585fb912657SDouglas Gregor   }
586fb912657SDouglas Gregor 
587fb912657SDouglas Gregor   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
588fb912657SDouglas Gregor     OS.indent(Indent + 2);
589fb912657SDouglas Gregor     OS << "conflict ";
5909565c75bSRichard Smith     OS << Conflicts[I].Other->getFullModuleName(true);
591fb912657SDouglas Gregor     OS << ", \"";
592fb912657SDouglas Gregor     OS.write_escaped(Conflicts[I].Message);
593fb912657SDouglas Gregor     OS << "\"\n";
594fb912657SDouglas Gregor   }
595fb912657SDouglas Gregor 
59673441091SDouglas Gregor   if (InferSubmodules) {
59773441091SDouglas Gregor     OS.indent(Indent + 2);
59873441091SDouglas Gregor     if (InferExplicitSubmodules)
59973441091SDouglas Gregor       OS << "explicit ";
60073441091SDouglas Gregor     OS << "module * {\n";
60173441091SDouglas Gregor     if (InferExportWildcard) {
60273441091SDouglas Gregor       OS.indent(Indent + 4);
60373441091SDouglas Gregor       OS << "export *\n";
60473441091SDouglas Gregor     }
60573441091SDouglas Gregor     OS.indent(Indent + 2);
60673441091SDouglas Gregor     OS << "}\n";
60773441091SDouglas Gregor   }
60873441091SDouglas Gregor 
609de3ef502SDouglas Gregor   OS.indent(Indent);
610de3ef502SDouglas Gregor   OS << "}\n";
611de3ef502SDouglas Gregor }
612de3ef502SDouglas Gregor 
613cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const {
614de3ef502SDouglas Gregor   print(llvm::errs());
615de3ef502SDouglas Gregor }
616de3ef502SDouglas Gregor 
617a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
618a7e2cc68SRichard Smith                                   VisibleCallback Vis, ConflictCallback Cb) {
6196d25fdc4SBen Langmuir   assert(Loc.isValid() && "setVisible expects a valid import location");
620a7e2cc68SRichard Smith   if (isVisible(M))
621a7e2cc68SRichard Smith     return;
622de3ef502SDouglas Gregor 
623a7e2cc68SRichard Smith   ++Generation;
624a7e2cc68SRichard Smith 
625a7e2cc68SRichard Smith   struct Visiting {
626a7e2cc68SRichard Smith     Module *M;
627a7e2cc68SRichard Smith     Visiting *ExportedBy;
628a7e2cc68SRichard Smith   };
629a7e2cc68SRichard Smith 
630a7e2cc68SRichard Smith   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
631a7e2cc68SRichard Smith     // Nothing to do for a module that's already visible.
632a7e2cc68SRichard Smith     unsigned ID = V.M->getVisibilityID();
633a7e2cc68SRichard Smith     if (ImportLocs.size() <= ID)
634a7e2cc68SRichard Smith       ImportLocs.resize(ID + 1);
635a7e2cc68SRichard Smith     else if (ImportLocs[ID].isValid())
636a7e2cc68SRichard Smith       return;
637a7e2cc68SRichard Smith 
638a7e2cc68SRichard Smith     ImportLocs[ID] = Loc;
639a7e2cc68SRichard Smith     Vis(M);
640a7e2cc68SRichard Smith 
641a7e2cc68SRichard Smith     // Make any exported modules visible.
642a7e2cc68SRichard Smith     SmallVector<Module *, 16> Exports;
643a7e2cc68SRichard Smith     V.M->getExportedModules(Exports);
644841dbda3SRichard Smith     for (Module *E : Exports) {
645841dbda3SRichard Smith       // Don't recurse to unavailable submodules.
646841dbda3SRichard Smith       if (E->isAvailable())
647a7e2cc68SRichard Smith         VisitModule({E, &V});
648841dbda3SRichard Smith     }
649a7e2cc68SRichard Smith 
650a7e2cc68SRichard Smith     for (auto &C : V.M->Conflicts) {
651a7e2cc68SRichard Smith       if (isVisible(C.Other)) {
652a7e2cc68SRichard Smith         llvm::SmallVector<Module*, 8> Path;
653a7e2cc68SRichard Smith         for (Visiting *I = &V; I; I = I->ExportedBy)
654a7e2cc68SRichard Smith           Path.push_back(I->M);
655a7e2cc68SRichard Smith         Cb(Path, C.Other, C.Message);
656a7e2cc68SRichard Smith       }
657a7e2cc68SRichard Smith     }
658a7e2cc68SRichard Smith   };
659a7e2cc68SRichard Smith   VisitModule({M, nullptr});
660a7e2cc68SRichard Smith }
661c915cb95SReid Kleckner 
662*f4754ea0SAdrian Prantl ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
663c915cb95SReid Kleckner     : Signature(M.Signature), ClangModule(&M) {
664c915cb95SReid Kleckner   if (M.Directory)
665c915cb95SReid Kleckner     Path = M.Directory->getName();
666c915cb95SReid Kleckner   if (auto *File = M.getASTFile())
667c915cb95SReid Kleckner     ASTFile = File->getName();
668c915cb95SReid Kleckner }
669c915cb95SReid Kleckner 
670c915cb95SReid Kleckner std::string ASTSourceDescriptor::getModuleName() const {
671c915cb95SReid Kleckner   if (ClangModule)
672c915cb95SReid Kleckner     return ClangModule->Name;
673c915cb95SReid Kleckner   else
674c915cb95SReid Kleckner     return std::string(PCHModuleName);
675c915cb95SReid Kleckner }
676