blob: 69a62d394aaf38f299ba0ff415754ef01aea73b0 [file] [log] [blame]
Douglas Gregor1a4761e2011-11-30 23:21:26 +00001//===--- Module.h - Describe a module ---------------------------*- C++ -*-===//
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 "llvm/Support/raw_ostream.h"
17using namespace clang;
18
19Module::~Module() {
20 for (llvm::StringMap<Module *>::iterator I = SubModules.begin(),
21 IEnd = SubModules.end();
22 I != IEnd; ++I) {
23 delete I->getValue();
24 }
25
26}
27
Douglas Gregor0adaa882011-12-05 17:28:06 +000028bool Module::isSubModuleOf(Module *Other) const {
29 const Module *This = this;
30 do {
31 if (This == Other)
32 return true;
33
34 This = This->Parent;
35 } while (This);
36
37 return false;
38}
39
Douglas Gregor1e123682011-12-05 22:27:44 +000040const Module *Module::getTopLevelModule() const {
41 const Module *Result = this;
42 while (Result->Parent)
43 Result = Result->Parent;
44
45 return Result;
46}
47
Douglas Gregor1a4761e2011-11-30 23:21:26 +000048std::string Module::getFullModuleName() const {
49 llvm::SmallVector<StringRef, 2> Names;
50
51 // Build up the set of module names (from innermost to outermost).
52 for (const Module *M = this; M; M = M->Parent)
53 Names.push_back(M->Name);
54
55 std::string Result;
56 for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(),
57 IEnd = Names.rend();
58 I != IEnd; ++I) {
59 if (!Result.empty())
60 Result += '.';
61
62 Result += *I;
63 }
64
65 return Result;
66}
67
Douglas Gregor10694ce2011-12-08 17:39:04 +000068const DirectoryEntry *Module::getUmbrellaDir() const {
69 if (const FileEntry *Header = getUmbrellaHeader())
70 return Header->getDir();
71
72 return Umbrella.dyn_cast<const DirectoryEntry *>();
73}
74
Douglas Gregoraf13bfc2011-12-02 18:58:38 +000075static void printModuleId(llvm::raw_ostream &OS, const ModuleId &Id) {
76 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
77 if (I)
78 OS << ".";
79 OS << Id[I].first;
80 }
81}
82
Douglas Gregor1a4761e2011-11-30 23:21:26 +000083void Module::print(llvm::raw_ostream &OS, unsigned Indent) const {
84 OS.indent(Indent);
85 if (IsFramework)
86 OS << "framework ";
87 if (IsExplicit)
88 OS << "explicit ";
89 OS << "module " << Name << " {\n";
90
Douglas Gregor10694ce2011-12-08 17:39:04 +000091 if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) {
Douglas Gregor1a4761e2011-11-30 23:21:26 +000092 OS.indent(Indent + 2);
Douglas Gregor489ad432011-12-08 18:00:48 +000093 OS << "umbrella header \"";
Douglas Gregor1a4761e2011-11-30 23:21:26 +000094 OS.write_escaped(UmbrellaHeader->getName());
95 OS << "\"\n";
Douglas Gregor489ad432011-12-08 18:00:48 +000096 } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) {
97 OS.indent(Indent + 2);
98 OS << "umbrella \"";
99 OS.write_escaped(UmbrellaDir->getName());
100 OS << "\"\n";
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000101 }
102
103 for (unsigned I = 0, N = Headers.size(); I != N; ++I) {
104 OS.indent(Indent + 2);
105 OS << "header \"";
106 OS.write_escaped(Headers[I]->getName());
107 OS << "\"\n";
108 }
109
110 for (llvm::StringMap<Module *>::const_iterator MI = SubModules.begin(),
Douglas Gregor1e123682011-12-05 22:27:44 +0000111 MIEnd = SubModules.end();
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000112 MI != MIEnd; ++MI)
113 MI->getValue()->print(OS, Indent + 2);
114
Douglas Gregoraf13bfc2011-12-02 18:58:38 +0000115 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
116 OS.indent(Indent + 2);
Douglas Gregorf4ac17e2011-12-05 17:34:59 +0000117 OS << "export ";
118 if (Module *Restriction = Exports[I].getPointer()) {
119 OS << Restriction->getFullModuleName();
120 if (Exports[I].getInt())
121 OS << ".*";
122 } else {
123 OS << "*";
124 }
Douglas Gregoraf13bfc2011-12-02 18:58:38 +0000125 OS << "\n";
126 }
127
128 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
129 OS.indent(Indent + 2);
130 OS << "export ";
131 printModuleId(OS, UnresolvedExports[I].Id);
Douglas Gregorf4ac17e2011-12-05 17:34:59 +0000132 if (UnresolvedExports[I].Wildcard) {
133 if (UnresolvedExports[I].Id.empty())
134 OS << "*";
135 else
136 OS << ".*";
137 }
Douglas Gregoraf13bfc2011-12-02 18:58:38 +0000138 OS << "\n";
139 }
140
Douglas Gregor1e123682011-12-05 22:27:44 +0000141 if (InferSubmodules) {
142 OS.indent(Indent + 2);
143 if (InferExplicitSubmodules)
144 OS << "explicit ";
145 OS << "module * {\n";
146 if (InferExportWildcard) {
147 OS.indent(Indent + 4);
148 OS << "export *\n";
149 }
150 OS.indent(Indent + 2);
151 OS << "}\n";
152 }
153
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000154 OS.indent(Indent);
155 OS << "}\n";
156}
157
158void Module::dump() const {
159 print(llvm::errs());
160}
161
162