]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/clang/lib/Basic/Module.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / clang / lib / Basic / Module.cpp
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"
23 using namespace clang;
24
25 Module::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
45 Module::~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.
54 static 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
68 bool 
69 Module::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
86 bool 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
98 const Module *Module::getTopLevelModule() const {
99   const Module *Result = this;
100   while (Result->Parent)
101     Result = Result->Parent;
102   
103   return Result;
104 }
105
106 std::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
126 const DirectoryEntry *Module::getUmbrellaDir() const {
127   if (const FileEntry *Header = getUmbrellaHeader())
128     return Header->getDir();
129   
130   return Umbrella.dyn_cast<const DirectoryEntry *>();
131 }
132
133 ArrayRef<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
146 void 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
176 Module *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
184 static 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
192 void 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
245 void 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
385 void Module::dump() const {
386   print(llvm::errs());
387 }
388
389