blob: 067528abac03979d01b59c60fa2506e28d25d853 [file] [log] [blame]
Chandler Carruth3a022472012-12-04 09:13:33 +00001//===--- Module.cpp - Describe a module -----------------------------------===//
Douglas Gregorde3ef502011-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 Smitha3feee22013-10-28 22:18:19 +000014
Douglas Gregorde3ef502011-11-30 23:21:26 +000015#include "clang/Basic/Module.h"
16#include "clang/Basic/FileManager.h"
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +000017#include "clang/Basic/LangOptions.h"
Douglas Gregor0070c0b2012-01-30 06:38:25 +000018#include "clang/Basic/TargetInfo.h"
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +000019#include "llvm/ADT/ArrayRef.h"
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +000020#include "llvm/ADT/SmallVector.h"
21#include "llvm/ADT/StringSwitch.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000022#include "llvm/Support/ErrorHandling.h"
23#include "llvm/Support/raw_ostream.h"
Richard Smitha3feee22013-10-28 22:18:19 +000024
Douglas Gregorde3ef502011-11-30 23:21:26 +000025using namespace clang;
26
Richard Smith77944862014-03-02 05:58:18 +000027Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
Ben Langmuirbeee15e2014-04-14 18:00:01 +000028 const FileEntry *File, bool IsFramework, bool IsExplicit)
Richard Smith86dbed72014-04-21 07:28:16 +000029 : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), ModuleMap(File),
30 Umbrella(), ASTFile(0), IsMissingRequirement(false), IsAvailable(true),
31 IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
32 IsSystem(false), IsExternC(false), InferSubmodules(false),
33 InferExplicitSubmodules(false), InferExportWildcard(false),
34 ConfigMacrosExhaustive(false), NameVisibility(Hidden) {
Douglas Gregoreb90e832012-01-04 23:32:19 +000035 if (Parent) {
36 if (!Parent->isAvailable())
37 IsAvailable = false;
Douglas Gregor3ec66632012-02-02 18:42:48 +000038 if (Parent->IsSystem)
39 IsSystem = true;
Richard Smith9bca2982014-03-08 00:03:56 +000040 if (Parent->IsExternC)
41 IsExternC = true;
Ben Langmuir993055f2014-04-18 23:51:00 +000042 IsMissingRequirement = Parent->IsMissingRequirement;
Douglas Gregoreb90e832012-01-04 23:32:19 +000043
44 Parent->SubModuleIndex[Name] = Parent->SubModules.size();
45 Parent->SubModules.push_back(this);
46 }
47}
48
Douglas Gregorde3ef502011-11-30 23:21:26 +000049Module::~Module() {
Douglas Gregoreb90e832012-01-04 23:32:19 +000050 for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
Douglas Gregorde3ef502011-11-30 23:21:26 +000051 I != IEnd; ++I) {
Douglas Gregoreb90e832012-01-04 23:32:19 +000052 delete *I;
Douglas Gregorde3ef502011-11-30 23:21:26 +000053 }
Douglas Gregorde3ef502011-11-30 23:21:26 +000054}
55
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +000056/// \brief Determine whether a translation unit built using the current
57/// language options has the given feature.
Douglas Gregor89929282012-01-30 06:01:29 +000058static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
59 const TargetInfo &Target) {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +000060 return llvm::StringSwitch<bool>(Feature)
Douglas Gregor0070c0b2012-01-30 06:38:25 +000061 .Case("altivec", LangOpts.AltiVec)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +000062 .Case("blocks", LangOpts.Blocks)
63 .Case("cplusplus", LangOpts.CPlusPlus)
Richard Smith2bf7fdb2013-01-02 11:42:31 +000064 .Case("cplusplus11", LangOpts.CPlusPlus11)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +000065 .Case("objc", LangOpts.ObjC1)
66 .Case("objc_arc", LangOpts.ObjCAutoRefCount)
Douglas Gregor0070c0b2012-01-30 06:38:25 +000067 .Case("opencl", LangOpts.OpenCL)
68 .Case("tls", Target.isTLSSupported())
69 .Default(Target.hasFeature(Feature));
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +000070}
71
Richard Smitha3feee22013-10-28 22:18:19 +000072bool
Douglas Gregor89929282012-01-30 06:01:29 +000073Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
Daniel Jasper0761a8a2013-12-17 10:31:37 +000074 Requirement &Req, HeaderDirective &MissingHeader) const {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +000075 if (IsAvailable)
76 return true;
77
78 for (const Module *Current = this; Current; Current = Current->Parent) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +000079 if (!Current->MissingHeaders.empty()) {
80 MissingHeader = Current->MissingHeaders.front();
81 return false;
82 }
Richard Smitha3feee22013-10-28 22:18:19 +000083 for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
84 if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
85 Current->Requirements[I].second) {
86 Req = Current->Requirements[I];
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +000087 return false;
88 }
89 }
90 }
91
92 llvm_unreachable("could not find a reason why module is unavailable");
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +000093}
94
Dmitri Gribenko62bcd922014-04-18 14:36:51 +000095bool Module::isSubModuleOf(const Module *Other) const {
Douglas Gregorf5eedd02011-12-05 17:28:06 +000096 const Module *This = this;
97 do {
98 if (This == Other)
99 return true;
100
101 This = This->Parent;
102 } while (This);
103
104 return false;
105}
106
Douglas Gregor73441092011-12-05 22:27:44 +0000107const Module *Module::getTopLevelModule() const {
108 const Module *Result = this;
109 while (Result->Parent)
110 Result = Result->Parent;
111
112 return Result;
113}
114
Douglas Gregorde3ef502011-11-30 23:21:26 +0000115std::string Module::getFullModuleName() const {
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000116 SmallVector<StringRef, 2> Names;
Douglas Gregorde3ef502011-11-30 23:21:26 +0000117
118 // Build up the set of module names (from innermost to outermost).
119 for (const Module *M = this; M; M = M->Parent)
120 Names.push_back(M->Name);
121
122 std::string Result;
Craig Topper61ac9062013-07-08 03:55:09 +0000123 for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(),
124 IEnd = Names.rend();
Douglas Gregorde3ef502011-11-30 23:21:26 +0000125 I != IEnd; ++I) {
126 if (!Result.empty())
127 Result += '.';
128
129 Result += *I;
130 }
131
132 return Result;
133}
134
Douglas Gregor73141fa2011-12-08 17:39:04 +0000135const DirectoryEntry *Module::getUmbrellaDir() const {
136 if (const FileEntry *Header = getUmbrellaHeader())
137 return Header->getDir();
138
139 return Umbrella.dyn_cast<const DirectoryEntry *>();
140}
141
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +0000142ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
143 if (!TopHeaderNames.empty()) {
144 for (std::vector<std::string>::iterator
145 I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
146 if (const FileEntry *FE = FileMgr.getFile(*I))
147 TopHeaders.insert(FE);
148 }
149 TopHeaderNames.clear();
150 }
151
152 return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
153}
154
Richard Smitha3feee22013-10-28 22:18:19 +0000155void Module::addRequirement(StringRef Feature, bool RequiredState,
156 const LangOptions &LangOpts,
Douglas Gregor89929282012-01-30 06:01:29 +0000157 const TargetInfo &Target) {
Richard Smitha3feee22013-10-28 22:18:19 +0000158 Requirements.push_back(Requirement(Feature, RequiredState));
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000159
160 // If this feature is currently available, we're done.
Richard Smitha3feee22013-10-28 22:18:19 +0000161 if (hasFeature(Feature, LangOpts, Target) == RequiredState)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000162 return;
163
Ben Langmuir993055f2014-04-18 23:51:00 +0000164 markUnavailable(/*MissingRequirement*/true);
Ben Langmuirec8c9752014-04-18 22:07:31 +0000165}
166
Ben Langmuir993055f2014-04-18 23:51:00 +0000167void Module::markUnavailable(bool MissingRequirement) {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000168 if (!IsAvailable)
169 return;
170
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000171 SmallVector<Module *, 2> Stack;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000172 Stack.push_back(this);
173 while (!Stack.empty()) {
174 Module *Current = Stack.back();
175 Stack.pop_back();
176
177 if (!Current->IsAvailable)
178 continue;
179
180 Current->IsAvailable = false;
Ben Langmuir993055f2014-04-18 23:51:00 +0000181 Current->IsMissingRequirement |= MissingRequirement;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000182 for (submodule_iterator Sub = Current->submodule_begin(),
183 SubEnd = Current->submodule_end();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000184 Sub != SubEnd; ++Sub) {
Douglas Gregoreb90e832012-01-04 23:32:19 +0000185 if ((*Sub)->IsAvailable)
186 Stack.push_back(*Sub);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000187 }
188 }
189}
190
Douglas Gregoreb90e832012-01-04 23:32:19 +0000191Module *Module::findSubmodule(StringRef Name) const {
192 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
193 if (Pos == SubModuleIndex.end())
194 return 0;
195
196 return SubModules[Pos->getValue()];
197}
198
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000199static void printModuleId(raw_ostream &OS, const ModuleId &Id) {
Douglas Gregor24bb9232011-12-02 18:58:38 +0000200 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
201 if (I)
202 OS << ".";
203 OS << Id[I].first;
204 }
205}
206
Argyrios Kyrtzidis8739f7b2013-02-19 19:34:40 +0000207void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
Dmitri Gribenkoe9bcf5b2013-11-04 21:51:33 +0000208 // All non-explicit submodules are exported.
209 for (std::vector<Module *>::const_iterator I = SubModules.begin(),
210 E = SubModules.end();
211 I != E; ++I) {
212 Module *Mod = *I;
213 if (!Mod->IsExplicit)
214 Exported.push_back(Mod);
215 }
216
217 // Find re-exported modules by filtering the list of imported modules.
Argyrios Kyrtzidis8739f7b2013-02-19 19:34:40 +0000218 bool AnyWildcard = false;
219 bool UnrestrictedWildcard = false;
220 SmallVector<Module *, 4> WildcardRestrictions;
221 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
222 Module *Mod = Exports[I].getPointer();
223 if (!Exports[I].getInt()) {
224 // Export a named module directly; no wildcards involved.
225 Exported.push_back(Mod);
226
227 continue;
228 }
229
230 // Wildcard export: export all of the imported modules that match
231 // the given pattern.
232 AnyWildcard = true;
233 if (UnrestrictedWildcard)
234 continue;
235
236 if (Module *Restriction = Exports[I].getPointer())
237 WildcardRestrictions.push_back(Restriction);
238 else {
239 WildcardRestrictions.clear();
240 UnrestrictedWildcard = true;
241 }
242 }
243
244 // If there were any wildcards, push any imported modules that were
245 // re-exported by the wildcard restriction.
246 if (!AnyWildcard)
247 return;
248
249 for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
250 Module *Mod = Imports[I];
251 bool Acceptable = UnrestrictedWildcard;
252 if (!Acceptable) {
253 // Check whether this module meets one of the restrictions.
254 for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
255 Module *Restriction = WildcardRestrictions[R];
256 if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
257 Acceptable = true;
258 break;
259 }
260 }
261 }
262
263 if (!Acceptable)
264 continue;
265
266 Exported.push_back(Mod);
267 }
268}
269
Richard Smith0e5d7b82013-07-25 23:08:39 +0000270void Module::buildVisibleModulesCache() const {
271 assert(VisibleModulesCache.empty() && "cache does not need building");
272
273 // This module is visible to itself.
274 VisibleModulesCache.insert(this);
275
Dmitri Gribenkodc360d52013-10-31 22:24:10 +0000276 // Every imported module is visible.
Richard Smithdde17e72013-11-01 02:19:14 +0000277 SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
Dmitri Gribenkodc360d52013-10-31 22:24:10 +0000278 while (!Stack.empty()) {
279 Module *CurrModule = Stack.pop_back_val();
Richard Smith0e5d7b82013-07-25 23:08:39 +0000280
Richard Smithdde17e72013-11-01 02:19:14 +0000281 // Every module transitively exported by an imported module is visible.
282 if (VisibleModulesCache.insert(CurrModule).second)
283 CurrModule->getExportedModules(Stack);
Richard Smith0e5d7b82013-07-25 23:08:39 +0000284 }
285}
286
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000287void Module::print(raw_ostream &OS, unsigned Indent) const {
Douglas Gregorde3ef502011-11-30 23:21:26 +0000288 OS.indent(Indent);
289 if (IsFramework)
290 OS << "framework ";
291 if (IsExplicit)
292 OS << "explicit ";
Douglas Gregora686e1b2012-01-27 19:52:33 +0000293 OS << "module " << Name;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000294
Douglas Gregora686e1b2012-01-27 19:52:33 +0000295 if (IsSystem) {
296 OS.indent(Indent + 2);
297 OS << " [system]";
298 }
299
300 OS << " {\n";
301
Richard Smitha3feee22013-10-28 22:18:19 +0000302 if (!Requirements.empty()) {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000303 OS.indent(Indent + 2);
304 OS << "requires ";
Richard Smitha3feee22013-10-28 22:18:19 +0000305 for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000306 if (I)
307 OS << ", ";
Richard Smitha3feee22013-10-28 22:18:19 +0000308 if (!Requirements[I].second)
309 OS << "!";
310 OS << Requirements[I].first;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000311 }
312 OS << "\n";
313 }
Douglas Gregorde3ef502011-11-30 23:21:26 +0000314
Douglas Gregor73141fa2011-12-08 17:39:04 +0000315 if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) {
Douglas Gregorde3ef502011-11-30 23:21:26 +0000316 OS.indent(Indent + 2);
Douglas Gregor322f6332011-12-08 18:00:48 +0000317 OS << "umbrella header \"";
Douglas Gregorde3ef502011-11-30 23:21:26 +0000318 OS.write_escaped(UmbrellaHeader->getName());
319 OS << "\"\n";
Douglas Gregor322f6332011-12-08 18:00:48 +0000320 } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) {
321 OS.indent(Indent + 2);
322 OS << "umbrella \"";
323 OS.write_escaped(UmbrellaDir->getName());
324 OS << "\"\n";
Douglas Gregorde3ef502011-11-30 23:21:26 +0000325 }
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000326
327 if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
328 OS.indent(Indent + 2);
329 OS << "config_macros ";
330 if (ConfigMacrosExhaustive)
Douglas Gregor8d932422013-03-20 03:59:18 +0000331 OS << "[exhaustive]";
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000332 for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
333 if (I)
334 OS << ", ";
335 OS << ConfigMacros[I];
336 }
Douglas Gregor8d932422013-03-20 03:59:18 +0000337 OS << "\n";
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000338 }
339
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000340 for (unsigned I = 0, N = NormalHeaders.size(); I != N; ++I) {
Douglas Gregorde3ef502011-11-30 23:21:26 +0000341 OS.indent(Indent + 2);
342 OS << "header \"";
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000343 OS.write_escaped(NormalHeaders[I]->getName());
Douglas Gregorde3ef502011-11-30 23:21:26 +0000344 OS << "\"\n";
345 }
Douglas Gregor59527662012-10-15 06:28:11 +0000346
347 for (unsigned I = 0, N = ExcludedHeaders.size(); I != N; ++I) {
348 OS.indent(Indent + 2);
349 OS << "exclude header \"";
350 OS.write_escaped(ExcludedHeaders[I]->getName());
351 OS << "\"\n";
352 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000353
354 for (unsigned I = 0, N = PrivateHeaders.size(); I != N; ++I) {
355 OS.indent(Indent + 2);
356 OS << "private header \"";
357 OS.write_escaped(PrivateHeaders[I]->getName());
358 OS << "\"\n";
359 }
Douglas Gregorde3ef502011-11-30 23:21:26 +0000360
Douglas Gregoreb90e832012-01-04 23:32:19 +0000361 for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
Douglas Gregorde3ef502011-11-30 23:21:26 +0000362 MI != MIEnd; ++MI)
Douglas Gregoreb90e832012-01-04 23:32:19 +0000363 (*MI)->print(OS, Indent + 2);
Douglas Gregorde3ef502011-11-30 23:21:26 +0000364
Douglas Gregor24bb9232011-12-02 18:58:38 +0000365 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
366 OS.indent(Indent + 2);
Douglas Gregor8c7c8352011-12-05 17:34:59 +0000367 OS << "export ";
368 if (Module *Restriction = Exports[I].getPointer()) {
369 OS << Restriction->getFullModuleName();
370 if (Exports[I].getInt())
371 OS << ".*";
372 } else {
373 OS << "*";
374 }
Douglas Gregor24bb9232011-12-02 18:58:38 +0000375 OS << "\n";
376 }
377
378 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
379 OS.indent(Indent + 2);
380 OS << "export ";
381 printModuleId(OS, UnresolvedExports[I].Id);
Douglas Gregor8c7c8352011-12-05 17:34:59 +0000382 if (UnresolvedExports[I].Wildcard) {
383 if (UnresolvedExports[I].Id.empty())
384 OS << "*";
385 else
386 OS << ".*";
387 }
Douglas Gregor24bb9232011-12-02 18:58:38 +0000388 OS << "\n";
389 }
390
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000391 for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
392 OS.indent(Indent + 2);
393 OS << "use ";
394 OS << DirectUses[I]->getFullModuleName();
395 OS << "\n";
396 }
397
398 for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
399 OS.indent(Indent + 2);
400 OS << "use ";
401 printModuleId(OS, UnresolvedDirectUses[I]);
402 OS << "\n";
403 }
404
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000405 for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
406 OS.indent(Indent + 2);
407 OS << "link ";
408 if (LinkLibraries[I].IsFramework)
409 OS << "framework ";
410 OS << "\"";
411 OS.write_escaped(LinkLibraries[I].Library);
412 OS << "\"";
413 }
414
Douglas Gregorfb912652013-03-20 21:10:35 +0000415 for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
416 OS.indent(Indent + 2);
417 OS << "conflict ";
418 printModuleId(OS, UnresolvedConflicts[I].Id);
419 OS << ", \"";
420 OS.write_escaped(UnresolvedConflicts[I].Message);
421 OS << "\"\n";
422 }
423
424 for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
425 OS.indent(Indent + 2);
426 OS << "conflict ";
427 OS << Conflicts[I].Other->getFullModuleName();
428 OS << ", \"";
429 OS.write_escaped(Conflicts[I].Message);
430 OS << "\"\n";
431 }
432
Douglas Gregor73441092011-12-05 22:27:44 +0000433 if (InferSubmodules) {
434 OS.indent(Indent + 2);
435 if (InferExplicitSubmodules)
436 OS << "explicit ";
437 OS << "module * {\n";
438 if (InferExportWildcard) {
439 OS.indent(Indent + 4);
440 OS << "export *\n";
441 }
442 OS.indent(Indent + 2);
443 OS << "}\n";
444 }
445
Douglas Gregorde3ef502011-11-30 23:21:26 +0000446 OS.indent(Indent);
447 OS << "}\n";
448}
449
450void Module::dump() const {
451 print(llvm::errs());
452}
453
454