1f4a2713aSLionel Sambuc //===--- Module.cpp - Describe a module -----------------------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file defines the Module class, which describes a module in the source
11f4a2713aSLionel Sambuc // code.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc
15f4a2713aSLionel Sambuc #include "clang/Basic/Module.h"
16f4a2713aSLionel Sambuc #include "clang/Basic/FileManager.h"
17f4a2713aSLionel Sambuc #include "clang/Basic/LangOptions.h"
18f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h"
19f4a2713aSLionel Sambuc #include "llvm/ADT/ArrayRef.h"
20f4a2713aSLionel Sambuc #include "llvm/ADT/SmallVector.h"
21f4a2713aSLionel Sambuc #include "llvm/ADT/StringSwitch.h"
22f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
23f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
24f4a2713aSLionel Sambuc
25f4a2713aSLionel Sambuc using namespace clang;
26f4a2713aSLionel Sambuc
Module(StringRef Name,SourceLocation DefinitionLoc,Module * Parent,bool IsFramework,bool IsExplicit)27f4a2713aSLionel Sambuc Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
28f4a2713aSLionel Sambuc bool IsFramework, bool IsExplicit)
29*0a6a1f1dSLionel Sambuc : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(),
30*0a6a1f1dSLionel Sambuc Umbrella(), ASTFile(nullptr), IsMissingRequirement(false),
31*0a6a1f1dSLionel Sambuc IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
32*0a6a1f1dSLionel Sambuc IsExplicit(IsExplicit), IsSystem(false), IsExternC(false),
33*0a6a1f1dSLionel Sambuc IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false),
34f4a2713aSLionel Sambuc InferExportWildcard(false), ConfigMacrosExhaustive(false),
35*0a6a1f1dSLionel Sambuc NameVisibility(Hidden) {
36f4a2713aSLionel Sambuc if (Parent) {
37f4a2713aSLionel Sambuc if (!Parent->isAvailable())
38f4a2713aSLionel Sambuc IsAvailable = false;
39f4a2713aSLionel Sambuc if (Parent->IsSystem)
40f4a2713aSLionel Sambuc IsSystem = true;
41*0a6a1f1dSLionel Sambuc if (Parent->IsExternC)
42*0a6a1f1dSLionel Sambuc IsExternC = true;
43*0a6a1f1dSLionel Sambuc IsMissingRequirement = Parent->IsMissingRequirement;
44f4a2713aSLionel Sambuc
45f4a2713aSLionel Sambuc Parent->SubModuleIndex[Name] = Parent->SubModules.size();
46f4a2713aSLionel Sambuc Parent->SubModules.push_back(this);
47f4a2713aSLionel Sambuc }
48f4a2713aSLionel Sambuc }
49f4a2713aSLionel Sambuc
~Module()50f4a2713aSLionel Sambuc Module::~Module() {
51f4a2713aSLionel Sambuc for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
52f4a2713aSLionel Sambuc I != IEnd; ++I) {
53f4a2713aSLionel Sambuc delete *I;
54f4a2713aSLionel Sambuc }
55f4a2713aSLionel Sambuc }
56f4a2713aSLionel Sambuc
57f4a2713aSLionel Sambuc /// \brief Determine whether a translation unit built using the current
58f4a2713aSLionel Sambuc /// language options has the given feature.
hasFeature(StringRef Feature,const LangOptions & LangOpts,const TargetInfo & Target)59f4a2713aSLionel Sambuc static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
60f4a2713aSLionel Sambuc const TargetInfo &Target) {
61f4a2713aSLionel Sambuc return llvm::StringSwitch<bool>(Feature)
62f4a2713aSLionel Sambuc .Case("altivec", LangOpts.AltiVec)
63f4a2713aSLionel Sambuc .Case("blocks", LangOpts.Blocks)
64f4a2713aSLionel Sambuc .Case("cplusplus", LangOpts.CPlusPlus)
65f4a2713aSLionel Sambuc .Case("cplusplus11", LangOpts.CPlusPlus11)
66f4a2713aSLionel Sambuc .Case("objc", LangOpts.ObjC1)
67f4a2713aSLionel Sambuc .Case("objc_arc", LangOpts.ObjCAutoRefCount)
68f4a2713aSLionel Sambuc .Case("opencl", LangOpts.OpenCL)
69f4a2713aSLionel Sambuc .Case("tls", Target.isTLSSupported())
70f4a2713aSLionel Sambuc .Default(Target.hasFeature(Feature));
71f4a2713aSLionel Sambuc }
72f4a2713aSLionel Sambuc
isAvailable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,UnresolvedHeaderDirective & MissingHeader) const73*0a6a1f1dSLionel Sambuc bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
74*0a6a1f1dSLionel Sambuc Requirement &Req,
75*0a6a1f1dSLionel Sambuc UnresolvedHeaderDirective &MissingHeader) const {
76f4a2713aSLionel Sambuc if (IsAvailable)
77f4a2713aSLionel Sambuc return true;
78f4a2713aSLionel Sambuc
79f4a2713aSLionel Sambuc for (const Module *Current = this; Current; Current = Current->Parent) {
80*0a6a1f1dSLionel Sambuc if (!Current->MissingHeaders.empty()) {
81*0a6a1f1dSLionel Sambuc MissingHeader = Current->MissingHeaders.front();
82*0a6a1f1dSLionel Sambuc return false;
83*0a6a1f1dSLionel Sambuc }
84f4a2713aSLionel Sambuc for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
85f4a2713aSLionel Sambuc if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
86f4a2713aSLionel Sambuc Current->Requirements[I].second) {
87f4a2713aSLionel Sambuc Req = Current->Requirements[I];
88f4a2713aSLionel Sambuc return false;
89f4a2713aSLionel Sambuc }
90f4a2713aSLionel Sambuc }
91f4a2713aSLionel Sambuc }
92f4a2713aSLionel Sambuc
93f4a2713aSLionel Sambuc llvm_unreachable("could not find a reason why module is unavailable");
94f4a2713aSLionel Sambuc }
95f4a2713aSLionel Sambuc
isSubModuleOf(const Module * Other) const96*0a6a1f1dSLionel Sambuc bool Module::isSubModuleOf(const Module *Other) const {
97f4a2713aSLionel Sambuc const Module *This = this;
98f4a2713aSLionel Sambuc do {
99f4a2713aSLionel Sambuc if (This == Other)
100f4a2713aSLionel Sambuc return true;
101f4a2713aSLionel Sambuc
102f4a2713aSLionel Sambuc This = This->Parent;
103f4a2713aSLionel Sambuc } while (This);
104f4a2713aSLionel Sambuc
105f4a2713aSLionel Sambuc return false;
106f4a2713aSLionel Sambuc }
107f4a2713aSLionel Sambuc
getTopLevelModule() const108f4a2713aSLionel Sambuc const Module *Module::getTopLevelModule() const {
109f4a2713aSLionel Sambuc const Module *Result = this;
110f4a2713aSLionel Sambuc while (Result->Parent)
111f4a2713aSLionel Sambuc Result = Result->Parent;
112f4a2713aSLionel Sambuc
113f4a2713aSLionel Sambuc return Result;
114f4a2713aSLionel Sambuc }
115f4a2713aSLionel Sambuc
getFullModuleName() const116f4a2713aSLionel Sambuc std::string Module::getFullModuleName() const {
117f4a2713aSLionel Sambuc SmallVector<StringRef, 2> Names;
118f4a2713aSLionel Sambuc
119f4a2713aSLionel Sambuc // Build up the set of module names (from innermost to outermost).
120f4a2713aSLionel Sambuc for (const Module *M = this; M; M = M->Parent)
121f4a2713aSLionel Sambuc Names.push_back(M->Name);
122f4a2713aSLionel Sambuc
123f4a2713aSLionel Sambuc std::string Result;
124f4a2713aSLionel Sambuc for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(),
125f4a2713aSLionel Sambuc IEnd = Names.rend();
126f4a2713aSLionel Sambuc I != IEnd; ++I) {
127f4a2713aSLionel Sambuc if (!Result.empty())
128f4a2713aSLionel Sambuc Result += '.';
129f4a2713aSLionel Sambuc
130f4a2713aSLionel Sambuc Result += *I;
131f4a2713aSLionel Sambuc }
132f4a2713aSLionel Sambuc
133f4a2713aSLionel Sambuc return Result;
134f4a2713aSLionel Sambuc }
135f4a2713aSLionel Sambuc
getUmbrellaDir() const136f4a2713aSLionel Sambuc const DirectoryEntry *Module::getUmbrellaDir() const {
137f4a2713aSLionel Sambuc if (const FileEntry *Header = getUmbrellaHeader())
138f4a2713aSLionel Sambuc return Header->getDir();
139f4a2713aSLionel Sambuc
140f4a2713aSLionel Sambuc return Umbrella.dyn_cast<const DirectoryEntry *>();
141f4a2713aSLionel Sambuc }
142f4a2713aSLionel Sambuc
getTopHeaders(FileManager & FileMgr)143f4a2713aSLionel Sambuc ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
144f4a2713aSLionel Sambuc if (!TopHeaderNames.empty()) {
145f4a2713aSLionel Sambuc for (std::vector<std::string>::iterator
146f4a2713aSLionel Sambuc I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
147f4a2713aSLionel Sambuc if (const FileEntry *FE = FileMgr.getFile(*I))
148f4a2713aSLionel Sambuc TopHeaders.insert(FE);
149f4a2713aSLionel Sambuc }
150f4a2713aSLionel Sambuc TopHeaderNames.clear();
151f4a2713aSLionel Sambuc }
152f4a2713aSLionel Sambuc
153f4a2713aSLionel Sambuc return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
154f4a2713aSLionel Sambuc }
155f4a2713aSLionel Sambuc
addRequirement(StringRef Feature,bool RequiredState,const LangOptions & LangOpts,const TargetInfo & Target)156f4a2713aSLionel Sambuc void Module::addRequirement(StringRef Feature, bool RequiredState,
157f4a2713aSLionel Sambuc const LangOptions &LangOpts,
158f4a2713aSLionel Sambuc const TargetInfo &Target) {
159f4a2713aSLionel Sambuc Requirements.push_back(Requirement(Feature, RequiredState));
160f4a2713aSLionel Sambuc
161f4a2713aSLionel Sambuc // If this feature is currently available, we're done.
162f4a2713aSLionel Sambuc if (hasFeature(Feature, LangOpts, Target) == RequiredState)
163f4a2713aSLionel Sambuc return;
164f4a2713aSLionel Sambuc
165*0a6a1f1dSLionel Sambuc markUnavailable(/*MissingRequirement*/true);
166*0a6a1f1dSLionel Sambuc }
167*0a6a1f1dSLionel Sambuc
markUnavailable(bool MissingRequirement)168*0a6a1f1dSLionel Sambuc void Module::markUnavailable(bool MissingRequirement) {
169f4a2713aSLionel Sambuc if (!IsAvailable)
170f4a2713aSLionel Sambuc return;
171f4a2713aSLionel Sambuc
172f4a2713aSLionel Sambuc SmallVector<Module *, 2> Stack;
173f4a2713aSLionel Sambuc Stack.push_back(this);
174f4a2713aSLionel Sambuc while (!Stack.empty()) {
175f4a2713aSLionel Sambuc Module *Current = Stack.back();
176f4a2713aSLionel Sambuc Stack.pop_back();
177f4a2713aSLionel Sambuc
178f4a2713aSLionel Sambuc if (!Current->IsAvailable)
179f4a2713aSLionel Sambuc continue;
180f4a2713aSLionel Sambuc
181f4a2713aSLionel Sambuc Current->IsAvailable = false;
182*0a6a1f1dSLionel Sambuc Current->IsMissingRequirement |= MissingRequirement;
183f4a2713aSLionel Sambuc for (submodule_iterator Sub = Current->submodule_begin(),
184f4a2713aSLionel Sambuc SubEnd = Current->submodule_end();
185f4a2713aSLionel Sambuc Sub != SubEnd; ++Sub) {
186f4a2713aSLionel Sambuc if ((*Sub)->IsAvailable)
187f4a2713aSLionel Sambuc Stack.push_back(*Sub);
188f4a2713aSLionel Sambuc }
189f4a2713aSLionel Sambuc }
190f4a2713aSLionel Sambuc }
191f4a2713aSLionel Sambuc
findSubmodule(StringRef Name) const192f4a2713aSLionel Sambuc Module *Module::findSubmodule(StringRef Name) const {
193f4a2713aSLionel Sambuc llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
194f4a2713aSLionel Sambuc if (Pos == SubModuleIndex.end())
195*0a6a1f1dSLionel Sambuc return nullptr;
196f4a2713aSLionel Sambuc
197f4a2713aSLionel Sambuc return SubModules[Pos->getValue()];
198f4a2713aSLionel Sambuc }
199f4a2713aSLionel Sambuc
printModuleId(raw_ostream & OS,const ModuleId & Id)200f4a2713aSLionel Sambuc static void printModuleId(raw_ostream &OS, const ModuleId &Id) {
201f4a2713aSLionel Sambuc for (unsigned I = 0, N = Id.size(); I != N; ++I) {
202f4a2713aSLionel Sambuc if (I)
203f4a2713aSLionel Sambuc OS << ".";
204f4a2713aSLionel Sambuc OS << Id[I].first;
205f4a2713aSLionel Sambuc }
206f4a2713aSLionel Sambuc }
207f4a2713aSLionel Sambuc
getExportedModules(SmallVectorImpl<Module * > & Exported) const208f4a2713aSLionel Sambuc void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
209f4a2713aSLionel Sambuc // All non-explicit submodules are exported.
210f4a2713aSLionel Sambuc for (std::vector<Module *>::const_iterator I = SubModules.begin(),
211f4a2713aSLionel Sambuc E = SubModules.end();
212f4a2713aSLionel Sambuc I != E; ++I) {
213f4a2713aSLionel Sambuc Module *Mod = *I;
214f4a2713aSLionel Sambuc if (!Mod->IsExplicit)
215f4a2713aSLionel Sambuc Exported.push_back(Mod);
216f4a2713aSLionel Sambuc }
217f4a2713aSLionel Sambuc
218f4a2713aSLionel Sambuc // Find re-exported modules by filtering the list of imported modules.
219f4a2713aSLionel Sambuc bool AnyWildcard = false;
220f4a2713aSLionel Sambuc bool UnrestrictedWildcard = false;
221f4a2713aSLionel Sambuc SmallVector<Module *, 4> WildcardRestrictions;
222f4a2713aSLionel Sambuc for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
223f4a2713aSLionel Sambuc Module *Mod = Exports[I].getPointer();
224f4a2713aSLionel Sambuc if (!Exports[I].getInt()) {
225f4a2713aSLionel Sambuc // Export a named module directly; no wildcards involved.
226f4a2713aSLionel Sambuc Exported.push_back(Mod);
227f4a2713aSLionel Sambuc
228f4a2713aSLionel Sambuc continue;
229f4a2713aSLionel Sambuc }
230f4a2713aSLionel Sambuc
231f4a2713aSLionel Sambuc // Wildcard export: export all of the imported modules that match
232f4a2713aSLionel Sambuc // the given pattern.
233f4a2713aSLionel Sambuc AnyWildcard = true;
234f4a2713aSLionel Sambuc if (UnrestrictedWildcard)
235f4a2713aSLionel Sambuc continue;
236f4a2713aSLionel Sambuc
237f4a2713aSLionel Sambuc if (Module *Restriction = Exports[I].getPointer())
238f4a2713aSLionel Sambuc WildcardRestrictions.push_back(Restriction);
239f4a2713aSLionel Sambuc else {
240f4a2713aSLionel Sambuc WildcardRestrictions.clear();
241f4a2713aSLionel Sambuc UnrestrictedWildcard = true;
242f4a2713aSLionel Sambuc }
243f4a2713aSLionel Sambuc }
244f4a2713aSLionel Sambuc
245f4a2713aSLionel Sambuc // If there were any wildcards, push any imported modules that were
246f4a2713aSLionel Sambuc // re-exported by the wildcard restriction.
247f4a2713aSLionel Sambuc if (!AnyWildcard)
248f4a2713aSLionel Sambuc return;
249f4a2713aSLionel Sambuc
250f4a2713aSLionel Sambuc for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
251f4a2713aSLionel Sambuc Module *Mod = Imports[I];
252f4a2713aSLionel Sambuc bool Acceptable = UnrestrictedWildcard;
253f4a2713aSLionel Sambuc if (!Acceptable) {
254f4a2713aSLionel Sambuc // Check whether this module meets one of the restrictions.
255f4a2713aSLionel Sambuc for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
256f4a2713aSLionel Sambuc Module *Restriction = WildcardRestrictions[R];
257f4a2713aSLionel Sambuc if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
258f4a2713aSLionel Sambuc Acceptable = true;
259f4a2713aSLionel Sambuc break;
260f4a2713aSLionel Sambuc }
261f4a2713aSLionel Sambuc }
262f4a2713aSLionel Sambuc }
263f4a2713aSLionel Sambuc
264f4a2713aSLionel Sambuc if (!Acceptable)
265f4a2713aSLionel Sambuc continue;
266f4a2713aSLionel Sambuc
267f4a2713aSLionel Sambuc Exported.push_back(Mod);
268f4a2713aSLionel Sambuc }
269f4a2713aSLionel Sambuc }
270f4a2713aSLionel Sambuc
buildVisibleModulesCache() const271f4a2713aSLionel Sambuc void Module::buildVisibleModulesCache() const {
272f4a2713aSLionel Sambuc assert(VisibleModulesCache.empty() && "cache does not need building");
273f4a2713aSLionel Sambuc
274f4a2713aSLionel Sambuc // This module is visible to itself.
275f4a2713aSLionel Sambuc VisibleModulesCache.insert(this);
276f4a2713aSLionel Sambuc
277f4a2713aSLionel Sambuc // Every imported module is visible.
278f4a2713aSLionel Sambuc SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
279f4a2713aSLionel Sambuc while (!Stack.empty()) {
280f4a2713aSLionel Sambuc Module *CurrModule = Stack.pop_back_val();
281f4a2713aSLionel Sambuc
282f4a2713aSLionel Sambuc // Every module transitively exported by an imported module is visible.
283f4a2713aSLionel Sambuc if (VisibleModulesCache.insert(CurrModule).second)
284f4a2713aSLionel Sambuc CurrModule->getExportedModules(Stack);
285f4a2713aSLionel Sambuc }
286f4a2713aSLionel Sambuc }
287f4a2713aSLionel Sambuc
print(raw_ostream & OS,unsigned Indent) const288f4a2713aSLionel Sambuc void Module::print(raw_ostream &OS, unsigned Indent) const {
289f4a2713aSLionel Sambuc OS.indent(Indent);
290f4a2713aSLionel Sambuc if (IsFramework)
291f4a2713aSLionel Sambuc OS << "framework ";
292f4a2713aSLionel Sambuc if (IsExplicit)
293f4a2713aSLionel Sambuc OS << "explicit ";
294f4a2713aSLionel Sambuc OS << "module " << Name;
295f4a2713aSLionel Sambuc
296*0a6a1f1dSLionel Sambuc if (IsSystem || IsExternC) {
297f4a2713aSLionel Sambuc OS.indent(Indent + 2);
298*0a6a1f1dSLionel Sambuc if (IsSystem)
299f4a2713aSLionel Sambuc OS << " [system]";
300*0a6a1f1dSLionel Sambuc if (IsExternC)
301*0a6a1f1dSLionel Sambuc OS << " [extern_c]";
302f4a2713aSLionel Sambuc }
303f4a2713aSLionel Sambuc
304f4a2713aSLionel Sambuc OS << " {\n";
305f4a2713aSLionel Sambuc
306f4a2713aSLionel Sambuc if (!Requirements.empty()) {
307f4a2713aSLionel Sambuc OS.indent(Indent + 2);
308f4a2713aSLionel Sambuc OS << "requires ";
309f4a2713aSLionel Sambuc for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
310f4a2713aSLionel Sambuc if (I)
311f4a2713aSLionel Sambuc OS << ", ";
312f4a2713aSLionel Sambuc if (!Requirements[I].second)
313f4a2713aSLionel Sambuc OS << "!";
314f4a2713aSLionel Sambuc OS << Requirements[I].first;
315f4a2713aSLionel Sambuc }
316f4a2713aSLionel Sambuc OS << "\n";
317f4a2713aSLionel Sambuc }
318f4a2713aSLionel Sambuc
319f4a2713aSLionel Sambuc if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) {
320f4a2713aSLionel Sambuc OS.indent(Indent + 2);
321f4a2713aSLionel Sambuc OS << "umbrella header \"";
322f4a2713aSLionel Sambuc OS.write_escaped(UmbrellaHeader->getName());
323f4a2713aSLionel Sambuc OS << "\"\n";
324f4a2713aSLionel Sambuc } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) {
325f4a2713aSLionel Sambuc OS.indent(Indent + 2);
326f4a2713aSLionel Sambuc OS << "umbrella \"";
327f4a2713aSLionel Sambuc OS.write_escaped(UmbrellaDir->getName());
328f4a2713aSLionel Sambuc OS << "\"\n";
329f4a2713aSLionel Sambuc }
330f4a2713aSLionel Sambuc
331f4a2713aSLionel Sambuc if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
332f4a2713aSLionel Sambuc OS.indent(Indent + 2);
333f4a2713aSLionel Sambuc OS << "config_macros ";
334f4a2713aSLionel Sambuc if (ConfigMacrosExhaustive)
335f4a2713aSLionel Sambuc OS << "[exhaustive]";
336f4a2713aSLionel Sambuc for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
337f4a2713aSLionel Sambuc if (I)
338f4a2713aSLionel Sambuc OS << ", ";
339f4a2713aSLionel Sambuc OS << ConfigMacros[I];
340f4a2713aSLionel Sambuc }
341f4a2713aSLionel Sambuc OS << "\n";
342f4a2713aSLionel Sambuc }
343f4a2713aSLionel Sambuc
344*0a6a1f1dSLionel Sambuc struct {
345*0a6a1f1dSLionel Sambuc StringRef Prefix;
346*0a6a1f1dSLionel Sambuc HeaderKind Kind;
347*0a6a1f1dSLionel Sambuc } Kinds[] = {{"", HK_Normal},
348*0a6a1f1dSLionel Sambuc {"textual ", HK_Textual},
349*0a6a1f1dSLionel Sambuc {"private ", HK_Private},
350*0a6a1f1dSLionel Sambuc {"private textual ", HK_PrivateTextual},
351*0a6a1f1dSLionel Sambuc {"exclude ", HK_Excluded}};
352*0a6a1f1dSLionel Sambuc
353*0a6a1f1dSLionel Sambuc for (auto &K : Kinds) {
354*0a6a1f1dSLionel Sambuc for (auto &H : Headers[K.Kind]) {
355f4a2713aSLionel Sambuc OS.indent(Indent + 2);
356*0a6a1f1dSLionel Sambuc OS << K.Prefix << "header \"";
357*0a6a1f1dSLionel Sambuc OS.write_escaped(H.NameAsWritten);
358f4a2713aSLionel Sambuc OS << "\"\n";
359f4a2713aSLionel Sambuc }
360f4a2713aSLionel Sambuc }
361f4a2713aSLionel Sambuc
362f4a2713aSLionel Sambuc for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
363f4a2713aSLionel Sambuc MI != MIEnd; ++MI)
364*0a6a1f1dSLionel Sambuc // Print inferred subframework modules so that we don't need to re-infer
365*0a6a1f1dSLionel Sambuc // them (requires expensive directory iteration + stat calls) when we build
366*0a6a1f1dSLionel Sambuc // the module. Regular inferred submodules are OK, as we need to look at all
367*0a6a1f1dSLionel Sambuc // those header files anyway.
368*0a6a1f1dSLionel Sambuc if (!(*MI)->IsInferred || (*MI)->IsFramework)
369f4a2713aSLionel Sambuc (*MI)->print(OS, Indent + 2);
370f4a2713aSLionel Sambuc
371f4a2713aSLionel Sambuc for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
372f4a2713aSLionel Sambuc OS.indent(Indent + 2);
373f4a2713aSLionel Sambuc OS << "export ";
374f4a2713aSLionel Sambuc if (Module *Restriction = Exports[I].getPointer()) {
375f4a2713aSLionel Sambuc OS << Restriction->getFullModuleName();
376f4a2713aSLionel Sambuc if (Exports[I].getInt())
377f4a2713aSLionel Sambuc OS << ".*";
378f4a2713aSLionel Sambuc } else {
379f4a2713aSLionel Sambuc OS << "*";
380f4a2713aSLionel Sambuc }
381f4a2713aSLionel Sambuc OS << "\n";
382f4a2713aSLionel Sambuc }
383f4a2713aSLionel Sambuc
384f4a2713aSLionel Sambuc for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
385f4a2713aSLionel Sambuc OS.indent(Indent + 2);
386f4a2713aSLionel Sambuc OS << "export ";
387f4a2713aSLionel Sambuc printModuleId(OS, UnresolvedExports[I].Id);
388f4a2713aSLionel Sambuc if (UnresolvedExports[I].Wildcard) {
389f4a2713aSLionel Sambuc if (UnresolvedExports[I].Id.empty())
390f4a2713aSLionel Sambuc OS << "*";
391f4a2713aSLionel Sambuc else
392f4a2713aSLionel Sambuc OS << ".*";
393f4a2713aSLionel Sambuc }
394f4a2713aSLionel Sambuc OS << "\n";
395f4a2713aSLionel Sambuc }
396f4a2713aSLionel Sambuc
397f4a2713aSLionel Sambuc for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
398f4a2713aSLionel Sambuc OS.indent(Indent + 2);
399f4a2713aSLionel Sambuc OS << "use ";
400f4a2713aSLionel Sambuc OS << DirectUses[I]->getFullModuleName();
401f4a2713aSLionel Sambuc OS << "\n";
402f4a2713aSLionel Sambuc }
403f4a2713aSLionel Sambuc
404f4a2713aSLionel Sambuc for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
405f4a2713aSLionel Sambuc OS.indent(Indent + 2);
406f4a2713aSLionel Sambuc OS << "use ";
407f4a2713aSLionel Sambuc printModuleId(OS, UnresolvedDirectUses[I]);
408f4a2713aSLionel Sambuc OS << "\n";
409f4a2713aSLionel Sambuc }
410f4a2713aSLionel Sambuc
411f4a2713aSLionel Sambuc for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
412f4a2713aSLionel Sambuc OS.indent(Indent + 2);
413f4a2713aSLionel Sambuc OS << "link ";
414f4a2713aSLionel Sambuc if (LinkLibraries[I].IsFramework)
415f4a2713aSLionel Sambuc OS << "framework ";
416f4a2713aSLionel Sambuc OS << "\"";
417f4a2713aSLionel Sambuc OS.write_escaped(LinkLibraries[I].Library);
418f4a2713aSLionel Sambuc OS << "\"";
419f4a2713aSLionel Sambuc }
420f4a2713aSLionel Sambuc
421f4a2713aSLionel Sambuc for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
422f4a2713aSLionel Sambuc OS.indent(Indent + 2);
423f4a2713aSLionel Sambuc OS << "conflict ";
424f4a2713aSLionel Sambuc printModuleId(OS, UnresolvedConflicts[I].Id);
425f4a2713aSLionel Sambuc OS << ", \"";
426f4a2713aSLionel Sambuc OS.write_escaped(UnresolvedConflicts[I].Message);
427f4a2713aSLionel Sambuc OS << "\"\n";
428f4a2713aSLionel Sambuc }
429f4a2713aSLionel Sambuc
430f4a2713aSLionel Sambuc for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
431f4a2713aSLionel Sambuc OS.indent(Indent + 2);
432f4a2713aSLionel Sambuc OS << "conflict ";
433f4a2713aSLionel Sambuc OS << Conflicts[I].Other->getFullModuleName();
434f4a2713aSLionel Sambuc OS << ", \"";
435f4a2713aSLionel Sambuc OS.write_escaped(Conflicts[I].Message);
436f4a2713aSLionel Sambuc OS << "\"\n";
437f4a2713aSLionel Sambuc }
438f4a2713aSLionel Sambuc
439f4a2713aSLionel Sambuc if (InferSubmodules) {
440f4a2713aSLionel Sambuc OS.indent(Indent + 2);
441f4a2713aSLionel Sambuc if (InferExplicitSubmodules)
442f4a2713aSLionel Sambuc OS << "explicit ";
443f4a2713aSLionel Sambuc OS << "module * {\n";
444f4a2713aSLionel Sambuc if (InferExportWildcard) {
445f4a2713aSLionel Sambuc OS.indent(Indent + 4);
446f4a2713aSLionel Sambuc OS << "export *\n";
447f4a2713aSLionel Sambuc }
448f4a2713aSLionel Sambuc OS.indent(Indent + 2);
449f4a2713aSLionel Sambuc OS << "}\n";
450f4a2713aSLionel Sambuc }
451f4a2713aSLionel Sambuc
452f4a2713aSLionel Sambuc OS.indent(Indent);
453f4a2713aSLionel Sambuc OS << "}\n";
454f4a2713aSLionel Sambuc }
455f4a2713aSLionel Sambuc
dump() const456f4a2713aSLionel Sambuc void Module::dump() const {
457f4a2713aSLionel Sambuc print(llvm::errs());
458f4a2713aSLionel Sambuc }
459f4a2713aSLionel Sambuc
460f4a2713aSLionel Sambuc
461