blob: 237c78981f2c8e0d85e2ba67559902136f3123af [file] [log] [blame]
Chandler Carruth55fc8732012-12-04 09:13:33 +00001//===--- Module.cpp - Describe a module -----------------------------------===//
Douglas Gregor1a4761e2011-11-30 23:21:26 +00002//
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//===----------------------------------------------------------------------===//
Richard Smith5794b532013-10-28 22:18:19 +000014
Douglas Gregor1a4761e2011-11-30 23:21:26 +000015#include "clang/Basic/Module.h"
16#include "clang/Basic/FileManager.h"
Douglas Gregor51f564f2011-12-31 04:05:44 +000017#include "clang/Basic/LangOptions.h"
Douglas Gregore727d212012-01-30 06:38:25 +000018#include "clang/Basic/TargetInfo.h"
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +000019#include "llvm/ADT/ArrayRef.h"
Douglas Gregor51f564f2011-12-31 04:05:44 +000020#include "llvm/ADT/SmallVector.h"
21#include "llvm/ADT/StringSwitch.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000022#include "llvm/Support/ErrorHandling.h"
23#include "llvm/Support/raw_ostream.h"
Richard Smith5794b532013-10-28 22:18:19 +000024
Douglas Gregor1a4761e2011-11-30 23:21:26 +000025using namespace clang;
26
Stephen Hines651f13c2014-04-23 16:59:28 -070027Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
Douglas Gregorb7a78192012-01-04 23:32:19 +000028 bool IsFramework, bool IsExplicit)
Argyrios Kyrtzidise2ac16b2012-09-29 01:06:04 +000029 : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
30 Umbrella(), ASTFile(0), IsAvailable(true), IsFromModuleFile(false),
Douglas Gregora1f1fad2012-01-27 19:52:33 +000031 IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false),
Stephen Hines651f13c2014-04-23 16:59:28 -070032 IsExternC(false), InferSubmodules(false), InferExplicitSubmodules(false),
Douglas Gregor970e4412013-03-20 03:59:18 +000033 InferExportWildcard(false), ConfigMacrosExhaustive(false),
Stephen Hines651f13c2014-04-23 16:59:28 -070034 NameVisibility(Hidden) {
Douglas Gregorb7a78192012-01-04 23:32:19 +000035 if (Parent) {
36 if (!Parent->isAvailable())
37 IsAvailable = false;
Douglas Gregor2f04f182012-02-02 18:42:48 +000038 if (Parent->IsSystem)
39 IsSystem = true;
Stephen Hines651f13c2014-04-23 16:59:28 -070040 if (Parent->IsExternC)
41 IsExternC = true;
Douglas Gregorb7a78192012-01-04 23:32:19 +000042
43 Parent->SubModuleIndex[Name] = Parent->SubModules.size();
44 Parent->SubModules.push_back(this);
45 }
46}
47
Douglas Gregor1a4761e2011-11-30 23:21:26 +000048Module::~Module() {
Douglas Gregorb7a78192012-01-04 23:32:19 +000049 for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
Douglas Gregor1a4761e2011-11-30 23:21:26 +000050 I != IEnd; ++I) {
Douglas Gregorb7a78192012-01-04 23:32:19 +000051 delete *I;
Douglas Gregor1a4761e2011-11-30 23:21:26 +000052 }
Douglas Gregor1a4761e2011-11-30 23:21:26 +000053}
54
Douglas Gregor51f564f2011-12-31 04:05:44 +000055/// \brief Determine whether a translation unit built using the current
56/// language options has the given feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +000057static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
58 const TargetInfo &Target) {
Douglas Gregor51f564f2011-12-31 04:05:44 +000059 return llvm::StringSwitch<bool>(Feature)
Douglas Gregore727d212012-01-30 06:38:25 +000060 .Case("altivec", LangOpts.AltiVec)
Douglas Gregor51f564f2011-12-31 04:05:44 +000061 .Case("blocks", LangOpts.Blocks)
62 .Case("cplusplus", LangOpts.CPlusPlus)
Richard Smith80ad52f2013-01-02 11:42:31 +000063 .Case("cplusplus11", LangOpts.CPlusPlus11)
Douglas Gregor51f564f2011-12-31 04:05:44 +000064 .Case("objc", LangOpts.ObjC1)
65 .Case("objc_arc", LangOpts.ObjCAutoRefCount)
Douglas Gregore727d212012-01-30 06:38:25 +000066 .Case("opencl", LangOpts.OpenCL)
67 .Case("tls", Target.isTLSSupported())
68 .Default(Target.hasFeature(Feature));
Douglas Gregor51f564f2011-12-31 04:05:44 +000069}
70
Richard Smith5794b532013-10-28 22:18:19 +000071bool
Douglas Gregordc58aa72012-01-30 06:01:29 +000072Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
Stephen Hines651f13c2014-04-23 16:59:28 -070073 Requirement &Req, HeaderDirective &MissingHeader) const {
Douglas Gregor51f564f2011-12-31 04:05:44 +000074 if (IsAvailable)
75 return true;
76
77 for (const Module *Current = this; Current; Current = Current->Parent) {
Stephen Hines651f13c2014-04-23 16:59:28 -070078 if (!Current->MissingHeaders.empty()) {
79 MissingHeader = Current->MissingHeaders.front();
80 return false;
81 }
Richard Smith5794b532013-10-28 22:18:19 +000082 for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
83 if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
84 Current->Requirements[I].second) {
85 Req = Current->Requirements[I];
Douglas Gregor51f564f2011-12-31 04:05:44 +000086 return false;
87 }
88 }
89 }
90
91 llvm_unreachable("could not find a reason why module is unavailable");
Douglas Gregor51f564f2011-12-31 04:05:44 +000092}
93
Douglas Gregor0adaa882011-12-05 17:28:06 +000094bool Module::isSubModuleOf(Module *Other) const {
95 const Module *This = this;
96 do {
97 if (This == Other)
98 return true;
99
100 This = This->Parent;
101 } while (This);
102
103 return false;
104}
105
Douglas Gregor1e123682011-12-05 22:27:44 +0000106const Module *Module::getTopLevelModule() const {
107 const Module *Result = this;
108 while (Result->Parent)
109 Result = Result->Parent;
110
111 return Result;
112}
113
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000114std::string Module::getFullModuleName() const {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000115 SmallVector<StringRef, 2> Names;
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000116
117 // Build up the set of module names (from innermost to outermost).
118 for (const Module *M = this; M; M = M->Parent)
119 Names.push_back(M->Name);
120
121 std::string Result;
Craig Topper163fbf82013-07-08 03:55:09 +0000122 for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(),
123 IEnd = Names.rend();
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000124 I != IEnd; ++I) {
125 if (!Result.empty())
126 Result += '.';
127
128 Result += *I;
129 }
130
131 return Result;
132}
133
Douglas Gregor10694ce2011-12-08 17:39:04 +0000134const DirectoryEntry *Module::getUmbrellaDir() const {
135 if (const FileEntry *Header = getUmbrellaHeader())
136 return Header->getDir();
137
138 return Umbrella.dyn_cast<const DirectoryEntry *>();
139}
140
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +0000141ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
142 if (!TopHeaderNames.empty()) {
143 for (std::vector<std::string>::iterator
144 I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
145 if (const FileEntry *FE = FileMgr.getFile(*I))
146 TopHeaders.insert(FE);
147 }
148 TopHeaderNames.clear();
149 }
150
151 return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
152}
153
Richard Smith5794b532013-10-28 22:18:19 +0000154void Module::addRequirement(StringRef Feature, bool RequiredState,
155 const LangOptions &LangOpts,
Douglas Gregordc58aa72012-01-30 06:01:29 +0000156 const TargetInfo &Target) {
Richard Smith5794b532013-10-28 22:18:19 +0000157 Requirements.push_back(Requirement(Feature, RequiredState));
Douglas Gregor51f564f2011-12-31 04:05:44 +0000158
159 // If this feature is currently available, we're done.
Richard Smith5794b532013-10-28 22:18:19 +0000160 if (hasFeature(Feature, LangOpts, Target) == RequiredState)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000161 return;
162
163 if (!IsAvailable)
164 return;
165
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000166 SmallVector<Module *, 2> Stack;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000167 Stack.push_back(this);
168 while (!Stack.empty()) {
169 Module *Current = Stack.back();
170 Stack.pop_back();
171
172 if (!Current->IsAvailable)
173 continue;
174
175 Current->IsAvailable = false;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000176 for (submodule_iterator Sub = Current->submodule_begin(),
177 SubEnd = Current->submodule_end();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000178 Sub != SubEnd; ++Sub) {
Douglas Gregorb7a78192012-01-04 23:32:19 +0000179 if ((*Sub)->IsAvailable)
180 Stack.push_back(*Sub);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000181 }
182 }
183}
184
Douglas Gregorb7a78192012-01-04 23:32:19 +0000185Module *Module::findSubmodule(StringRef Name) const {
186 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
187 if (Pos == SubModuleIndex.end())
188 return 0;
189
190 return SubModules[Pos->getValue()];
191}
192
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000193static void printModuleId(raw_ostream &OS, const ModuleId &Id) {
Douglas Gregoraf13bfc2011-12-02 18:58:38 +0000194 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
195 if (I)
196 OS << ".";
197 OS << Id[I].first;
198 }
199}
200
Argyrios Kyrtzidis21a00042013-02-19 19:34:40 +0000201void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
Dmitri Gribenko86250892013-11-04 21:51:33 +0000202 // All non-explicit submodules are exported.
203 for (std::vector<Module *>::const_iterator I = SubModules.begin(),
204 E = SubModules.end();
205 I != E; ++I) {
206 Module *Mod = *I;
207 if (!Mod->IsExplicit)
208 Exported.push_back(Mod);
209 }
210
211 // Find re-exported modules by filtering the list of imported modules.
Argyrios Kyrtzidis21a00042013-02-19 19:34:40 +0000212 bool AnyWildcard = false;
213 bool UnrestrictedWildcard = false;
214 SmallVector<Module *, 4> WildcardRestrictions;
215 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
216 Module *Mod = Exports[I].getPointer();
217 if (!Exports[I].getInt()) {
218 // Export a named module directly; no wildcards involved.
219 Exported.push_back(Mod);
220
221 continue;
222 }
223
224 // Wildcard export: export all of the imported modules that match
225 // the given pattern.
226 AnyWildcard = true;
227 if (UnrestrictedWildcard)
228 continue;
229
230 if (Module *Restriction = Exports[I].getPointer())
231 WildcardRestrictions.push_back(Restriction);
232 else {
233 WildcardRestrictions.clear();
234 UnrestrictedWildcard = true;
235 }
236 }
237
238 // If there were any wildcards, push any imported modules that were
239 // re-exported by the wildcard restriction.
240 if (!AnyWildcard)
241 return;
242
243 for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
244 Module *Mod = Imports[I];
245 bool Acceptable = UnrestrictedWildcard;
246 if (!Acceptable) {
247 // Check whether this module meets one of the restrictions.
248 for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
249 Module *Restriction = WildcardRestrictions[R];
250 if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
251 Acceptable = true;
252 break;
253 }
254 }
255 }
256
257 if (!Acceptable)
258 continue;
259
260 Exported.push_back(Mod);
261 }
262}
263
Richard Smithb7751002013-07-25 23:08:39 +0000264void Module::buildVisibleModulesCache() const {
265 assert(VisibleModulesCache.empty() && "cache does not need building");
266
267 // This module is visible to itself.
268 VisibleModulesCache.insert(this);
269
Dmitri Gribenkobc64d352013-10-31 22:24:10 +0000270 // Every imported module is visible.
Richard Smith8b1ab402013-11-01 02:19:14 +0000271 SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
Dmitri Gribenkobc64d352013-10-31 22:24:10 +0000272 while (!Stack.empty()) {
273 Module *CurrModule = Stack.pop_back_val();
Richard Smithb7751002013-07-25 23:08:39 +0000274
Richard Smith8b1ab402013-11-01 02:19:14 +0000275 // Every module transitively exported by an imported module is visible.
276 if (VisibleModulesCache.insert(CurrModule).second)
277 CurrModule->getExportedModules(Stack);
Richard Smithb7751002013-07-25 23:08:39 +0000278 }
279}
280
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000281void Module::print(raw_ostream &OS, unsigned Indent) const {
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000282 OS.indent(Indent);
283 if (IsFramework)
284 OS << "framework ";
285 if (IsExplicit)
286 OS << "explicit ";
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000287 OS << "module " << Name;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000288
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000289 if (IsSystem) {
290 OS.indent(Indent + 2);
291 OS << " [system]";
292 }
293
294 OS << " {\n";
295
Richard Smith5794b532013-10-28 22:18:19 +0000296 if (!Requirements.empty()) {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000297 OS.indent(Indent + 2);
298 OS << "requires ";
Richard Smith5794b532013-10-28 22:18:19 +0000299 for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000300 if (I)
301 OS << ", ";
Richard Smith5794b532013-10-28 22:18:19 +0000302 if (!Requirements[I].second)
303 OS << "!";
304 OS << Requirements[I].first;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000305 }
306 OS << "\n";
307 }
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000308
Douglas Gregor10694ce2011-12-08 17:39:04 +0000309 if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) {
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000310 OS.indent(Indent + 2);
Douglas Gregor489ad432011-12-08 18:00:48 +0000311 OS << "umbrella header \"";
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000312 OS.write_escaped(UmbrellaHeader->getName());
313 OS << "\"\n";
Douglas Gregor489ad432011-12-08 18:00:48 +0000314 } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) {
315 OS.indent(Indent + 2);
316 OS << "umbrella \"";
317 OS.write_escaped(UmbrellaDir->getName());
318 OS << "\"\n";
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000319 }
Douglas Gregor63a72682013-03-20 00:22:05 +0000320
321 if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
322 OS.indent(Indent + 2);
323 OS << "config_macros ";
324 if (ConfigMacrosExhaustive)
Douglas Gregor970e4412013-03-20 03:59:18 +0000325 OS << "[exhaustive]";
Douglas Gregor63a72682013-03-20 00:22:05 +0000326 for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
327 if (I)
328 OS << ", ";
329 OS << ConfigMacros[I];
330 }
Douglas Gregor970e4412013-03-20 03:59:18 +0000331 OS << "\n";
Douglas Gregor63a72682013-03-20 00:22:05 +0000332 }
333
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000334 for (unsigned I = 0, N = NormalHeaders.size(); I != N; ++I) {
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000335 OS.indent(Indent + 2);
336 OS << "header \"";
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000337 OS.write_escaped(NormalHeaders[I]->getName());
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000338 OS << "\"\n";
339 }
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000340
341 for (unsigned I = 0, N = ExcludedHeaders.size(); I != N; ++I) {
342 OS.indent(Indent + 2);
343 OS << "exclude header \"";
344 OS.write_escaped(ExcludedHeaders[I]->getName());
345 OS << "\"\n";
346 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000347
348 for (unsigned I = 0, N = PrivateHeaders.size(); I != N; ++I) {
349 OS.indent(Indent + 2);
350 OS << "private header \"";
351 OS.write_escaped(PrivateHeaders[I]->getName());
352 OS << "\"\n";
353 }
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000354
Douglas Gregorb7a78192012-01-04 23:32:19 +0000355 for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000356 MI != MIEnd; ++MI)
Douglas Gregorb7a78192012-01-04 23:32:19 +0000357 (*MI)->print(OS, Indent + 2);
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000358
Douglas Gregoraf13bfc2011-12-02 18:58:38 +0000359 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
360 OS.indent(Indent + 2);
Douglas Gregorf4ac17e2011-12-05 17:34:59 +0000361 OS << "export ";
362 if (Module *Restriction = Exports[I].getPointer()) {
363 OS << Restriction->getFullModuleName();
364 if (Exports[I].getInt())
365 OS << ".*";
366 } else {
367 OS << "*";
368 }
Douglas Gregoraf13bfc2011-12-02 18:58:38 +0000369 OS << "\n";
370 }
371
372 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
373 OS.indent(Indent + 2);
374 OS << "export ";
375 printModuleId(OS, UnresolvedExports[I].Id);
Douglas Gregorf4ac17e2011-12-05 17:34:59 +0000376 if (UnresolvedExports[I].Wildcard) {
377 if (UnresolvedExports[I].Id.empty())
378 OS << "*";
379 else
380 OS << ".*";
381 }
Douglas Gregoraf13bfc2011-12-02 18:58:38 +0000382 OS << "\n";
383 }
384
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000385 for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
386 OS.indent(Indent + 2);
387 OS << "use ";
388 OS << DirectUses[I]->getFullModuleName();
389 OS << "\n";
390 }
391
392 for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
393 OS.indent(Indent + 2);
394 OS << "use ";
395 printModuleId(OS, UnresolvedDirectUses[I]);
396 OS << "\n";
397 }
398
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000399 for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
400 OS.indent(Indent + 2);
401 OS << "link ";
402 if (LinkLibraries[I].IsFramework)
403 OS << "framework ";
404 OS << "\"";
405 OS.write_escaped(LinkLibraries[I].Library);
406 OS << "\"";
407 }
408
Douglas Gregor906d66a2013-03-20 21:10:35 +0000409 for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
410 OS.indent(Indent + 2);
411 OS << "conflict ";
412 printModuleId(OS, UnresolvedConflicts[I].Id);
413 OS << ", \"";
414 OS.write_escaped(UnresolvedConflicts[I].Message);
415 OS << "\"\n";
416 }
417
418 for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
419 OS.indent(Indent + 2);
420 OS << "conflict ";
421 OS << Conflicts[I].Other->getFullModuleName();
422 OS << ", \"";
423 OS.write_escaped(Conflicts[I].Message);
424 OS << "\"\n";
425 }
426
Douglas Gregor1e123682011-12-05 22:27:44 +0000427 if (InferSubmodules) {
428 OS.indent(Indent + 2);
429 if (InferExplicitSubmodules)
430 OS << "explicit ";
431 OS << "module * {\n";
432 if (InferExportWildcard) {
433 OS.indent(Indent + 4);
434 OS << "export *\n";
435 }
436 OS.indent(Indent + 2);
437 OS << "}\n";
438 }
439
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000440 OS.indent(Indent);
441 OS << "}\n";
442}
443
444void Module::dump() const {
445 print(llvm::errs());
446}
447
448