1//===--- Module.cpp - Describe a module -----------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the Module class, which describes a module in the source
11// code.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/Basic/Module.h"
15#include "clang/Basic/FileManager.h"
16#include "clang/Basic/LangOptions.h"
17#include "clang/Basic/TargetInfo.h"
18#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/Support/ErrorHandling.h"
22#include "llvm/Support/raw_ostream.h"
23using namespace clang;
24
25Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
26               bool IsFramework, bool IsExplicit)
27  : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
28    Umbrella(), ASTFile(0), IsAvailable(true), IsFromModuleFile(false),
29    IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false),
30    InferSubmodules(false), InferExplicitSubmodules(false),
31    InferExportWildcard(false), ConfigMacrosExhaustive(false),
32    NameVisibility(Hidden)
33{
34  if (Parent) {
35    if (!Parent->isAvailable())
36      IsAvailable = false;
37    if (Parent->IsSystem)
38      IsSystem = true;
39
40    Parent->SubModuleIndex[Name] = Parent->SubModules.size();
41    Parent->SubModules.push_back(this);
42  }
43}
44
45Module::~Module() {
46  for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
47       I != IEnd; ++I) {
48    delete *I;
49  }
50}
51
52/// \brief Determine whether a translation unit built using the current
53/// language options has the given feature.
54static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
55                       const TargetInfo &Target) {
56  return llvm::StringSwitch<bool>(Feature)
57           .Case("altivec", LangOpts.AltiVec)
58           .Case("blocks", LangOpts.Blocks)
59           .Case("cplusplus", LangOpts.CPlusPlus)
60           .Case("cplusplus11", LangOpts.CPlusPlus11)
61           .Case("objc", LangOpts.ObjC1)
62           .Case("objc_arc", LangOpts.ObjCAutoRefCount)
63           .Case("opencl", LangOpts.OpenCL)
64           .Case("tls", Target.isTLSSupported())
65           .Default(Target.hasFeature(Feature));
66}
67
68bool
69Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
70                    StringRef &Feature) const {
71  if (IsAvailable)
72    return true;
73
74  for (const Module *Current = this; Current; Current = Current->Parent) {
75    for (unsigned I = 0, N = Current->Requires.size(); I != N; ++I) {
76      if (!hasFeature(Current->Requires[I], LangOpts, Target)) {
77        Feature = Current->Requires[I];
78        return false;
79      }
80    }
81  }
82
83  llvm_unreachable("could not find a reason why module is unavailable");
84}
85
86bool Module::isSubModuleOf(Module *Other) const {
87  const Module *This = this;
88  do {
89    if (This == Other)
90      return true;
91
92    This = This->Parent;
93  } while (This);
94
95  return false;
96}
97
98const Module *Module::getTopLevelModule() const {
99  const Module *Result = this;
100  while (Result->Parent)
101    Result = Result->Parent;
102
103  return Result;
104}
105
106std::string Module::getFullModuleName() const {
107  SmallVector<StringRef, 2> Names;
108
109  // Build up the set of module names (from innermost to outermost).
110  for (const Module *M = this; M; M = M->Parent)
111    Names.push_back(M->Name);
112
113  std::string Result;
114  for (SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(),
115                                                IEnd = Names.rend();
116       I != IEnd; ++I) {
117    if (!Result.empty())
118      Result += '.';
119
120    Result += *I;
121  }
122
123  return Result;
124}
125
126const DirectoryEntry *Module::getUmbrellaDir() const {
127  if (const FileEntry *Header = getUmbrellaHeader())
128    return Header->getDir();
129
130  return Umbrella.dyn_cast<const DirectoryEntry *>();
131}
132
133ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
134  if (!TopHeaderNames.empty()) {
135    for (std::vector<std::string>::iterator
136           I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
137      if (const FileEntry *FE = FileMgr.getFile(*I))
138        TopHeaders.insert(FE);
139    }
140    TopHeaderNames.clear();
141  }
142
143  return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
144}
145
146void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts,
147                            const TargetInfo &Target) {
148  Requires.push_back(Feature);
149
150  // If this feature is currently available, we're done.
151  if (hasFeature(Feature, LangOpts, Target))
152    return;
153
154  if (!IsAvailable)
155    return;
156
157  SmallVector<Module *, 2> Stack;
158  Stack.push_back(this);
159  while (!Stack.empty()) {
160    Module *Current = Stack.back();
161    Stack.pop_back();
162
163    if (!Current->IsAvailable)
164      continue;
165
166    Current->IsAvailable = false;
167    for (submodule_iterator Sub = Current->submodule_begin(),
168                         SubEnd = Current->submodule_end();
169         Sub != SubEnd; ++Sub) {
170      if ((*Sub)->IsAvailable)
171        Stack.push_back(*Sub);
172    }
173  }
174}
175
176Module *Module::findSubmodule(StringRef Name) const {
177  llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
178  if (Pos == SubModuleIndex.end())
179    return 0;
180
181  return SubModules[Pos->getValue()];
182}
183
184static void printModuleId(raw_ostream &OS, const ModuleId &Id) {
185  for (unsigned I = 0, N = Id.size(); I != N; ++I) {
186    if (I)
187      OS << ".";
188    OS << Id[I].first;
189  }
190}
191
192void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
193  bool AnyWildcard = false;
194  bool UnrestrictedWildcard = false;
195  SmallVector<Module *, 4> WildcardRestrictions;
196  for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
197    Module *Mod = Exports[I].getPointer();
198    if (!Exports[I].getInt()) {
199      // Export a named module directly; no wildcards involved.
200      Exported.push_back(Mod);
201
202      continue;
203    }
204
205    // Wildcard export: export all of the imported modules that match
206    // the given pattern.
207    AnyWildcard = true;
208    if (UnrestrictedWildcard)
209      continue;
210
211    if (Module *Restriction = Exports[I].getPointer())
212      WildcardRestrictions.push_back(Restriction);
213    else {
214      WildcardRestrictions.clear();
215      UnrestrictedWildcard = true;
216    }
217  }
218
219  // If there were any wildcards, push any imported modules that were
220  // re-exported by the wildcard restriction.
221  if (!AnyWildcard)
222    return;
223
224  for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
225    Module *Mod = Imports[I];
226    bool Acceptable = UnrestrictedWildcard;
227    if (!Acceptable) {
228      // Check whether this module meets one of the restrictions.
229      for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
230        Module *Restriction = WildcardRestrictions[R];
231        if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
232          Acceptable = true;
233          break;
234        }
235      }
236    }
237
238    if (!Acceptable)
239      continue;
240
241    Exported.push_back(Mod);
242  }
243}
244
245void Module::print(raw_ostream &OS, unsigned Indent) const {
246  OS.indent(Indent);
247  if (IsFramework)
248    OS << "framework ";
249  if (IsExplicit)
250    OS << "explicit ";
251  OS << "module " << Name;
252
253  if (IsSystem) {
254    OS.indent(Indent + 2);
255    OS << " [system]";
256  }
257
258  OS << " {\n";
259
260  if (!Requires.empty()) {
261    OS.indent(Indent + 2);
262    OS << "requires ";
263    for (unsigned I = 0, N = Requires.size(); I != N; ++I) {
264      if (I)
265        OS << ", ";
266      OS << Requires[I];
267    }
268    OS << "\n";
269  }
270
271  if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) {
272    OS.indent(Indent + 2);
273    OS << "umbrella header \"";
274    OS.write_escaped(UmbrellaHeader->getName());
275    OS << "\"\n";
276  } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) {
277    OS.indent(Indent + 2);
278    OS << "umbrella \"";
279    OS.write_escaped(UmbrellaDir->getName());
280    OS << "\"\n";
281  }
282
283  if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
284    OS.indent(Indent + 2);
285    OS << "config_macros ";
286    if (ConfigMacrosExhaustive)
287      OS << "[exhaustive]";
288    for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
289      if (I)
290        OS << ", ";
291      OS << ConfigMacros[I];
292    }
293    OS << "\n";
294  }
295
296  for (unsigned I = 0, N = Headers.size(); I != N; ++I) {
297    OS.indent(Indent + 2);
298    OS << "header \"";
299    OS.write_escaped(Headers[I]->getName());
300    OS << "\"\n";
301  }
302
303  for (unsigned I = 0, N = ExcludedHeaders.size(); I != N; ++I) {
304    OS.indent(Indent + 2);
305    OS << "exclude header \"";
306    OS.write_escaped(ExcludedHeaders[I]->getName());
307    OS << "\"\n";
308  }
309
310  for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
311       MI != MIEnd; ++MI)
312    (*MI)->print(OS, Indent + 2);
313
314  for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
315    OS.indent(Indent + 2);
316    OS << "export ";
317    if (Module *Restriction = Exports[I].getPointer()) {
318      OS << Restriction->getFullModuleName();
319      if (Exports[I].getInt())
320        OS << ".*";
321    } else {
322      OS << "*";
323    }
324    OS << "\n";
325  }
326
327  for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
328    OS.indent(Indent + 2);
329    OS << "export ";
330    printModuleId(OS, UnresolvedExports[I].Id);
331    if (UnresolvedExports[I].Wildcard) {
332      if (UnresolvedExports[I].Id.empty())
333        OS << "*";
334      else
335        OS << ".*";
336    }
337    OS << "\n";
338  }
339
340  for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
341    OS.indent(Indent + 2);
342    OS << "link ";
343    if (LinkLibraries[I].IsFramework)
344      OS << "framework ";
345    OS << "\"";
346    OS.write_escaped(LinkLibraries[I].Library);
347    OS << "\"";
348  }
349
350  for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
351    OS.indent(Indent + 2);
352    OS << "conflict ";
353    printModuleId(OS, UnresolvedConflicts[I].Id);
354    OS << ", \"";
355    OS.write_escaped(UnresolvedConflicts[I].Message);
356    OS << "\"\n";
357  }
358
359  for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
360    OS.indent(Indent + 2);
361    OS << "conflict ";
362    OS << Conflicts[I].Other->getFullModuleName();
363    OS << ", \"";
364    OS.write_escaped(Conflicts[I].Message);
365    OS << "\"\n";
366  }
367
368  if (InferSubmodules) {
369    OS.indent(Indent + 2);
370    if (InferExplicitSubmodules)
371      OS << "explicit ";
372    OS << "module * {\n";
373    if (InferExportWildcard) {
374      OS.indent(Indent + 4);
375      OS << "export *\n";
376    }
377    OS.indent(Indent + 2);
378    OS << "}\n";
379  }
380
381  OS.indent(Indent);
382  OS << "}\n";
383}
384
385void Module::dump() const {
386  print(llvm::errs());
387}
388
389
390