blob: c3a8a377c44fefbb49829009ddd77bd3d1288325 [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 Gregor1a4761e2011-11-30 23:21:26 +000040std::string Module::getFullModuleName() const {
41 llvm::SmallVector<StringRef, 2> Names;
42
43 // Build up the set of module names (from innermost to outermost).
44 for (const Module *M = this; M; M = M->Parent)
45 Names.push_back(M->Name);
46
47 std::string Result;
48 for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(),
49 IEnd = Names.rend();
50 I != IEnd; ++I) {
51 if (!Result.empty())
52 Result += '.';
53
54 Result += *I;
55 }
56
57 return Result;
58}
59
60StringRef Module::getTopLevelModuleName() const {
61 const Module *Top = this;
62 while (Top->Parent)
63 Top = Top->Parent;
64
65 return Top->Name;
66}
67
Douglas Gregoraf13bfc2011-12-02 18:58:38 +000068static void printModuleId(llvm::raw_ostream &OS, const ModuleId &Id) {
69 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
70 if (I)
71 OS << ".";
72 OS << Id[I].first;
73 }
74}
75
Douglas Gregor1a4761e2011-11-30 23:21:26 +000076void Module::print(llvm::raw_ostream &OS, unsigned Indent) const {
77 OS.indent(Indent);
78 if (IsFramework)
79 OS << "framework ";
80 if (IsExplicit)
81 OS << "explicit ";
82 OS << "module " << Name << " {\n";
83
84 if (UmbrellaHeader) {
85 OS.indent(Indent + 2);
86 OS << "umbrella \"";
87 OS.write_escaped(UmbrellaHeader->getName());
88 OS << "\"\n";
89 }
90
91 for (unsigned I = 0, N = Headers.size(); I != N; ++I) {
92 OS.indent(Indent + 2);
93 OS << "header \"";
94 OS.write_escaped(Headers[I]->getName());
95 OS << "\"\n";
96 }
97
98 for (llvm::StringMap<Module *>::const_iterator MI = SubModules.begin(),
99 MIEnd = SubModules.end();
100 MI != MIEnd; ++MI)
101 MI->getValue()->print(OS, Indent + 2);
102
Douglas Gregoraf13bfc2011-12-02 18:58:38 +0000103 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
104 OS.indent(Indent + 2);
Douglas Gregorf4ac17e2011-12-05 17:34:59 +0000105 OS << "export ";
106 if (Module *Restriction = Exports[I].getPointer()) {
107 OS << Restriction->getFullModuleName();
108 if (Exports[I].getInt())
109 OS << ".*";
110 } else {
111 OS << "*";
112 }
Douglas Gregoraf13bfc2011-12-02 18:58:38 +0000113 OS << "\n";
114 }
115
116 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
117 OS.indent(Indent + 2);
118 OS << "export ";
119 printModuleId(OS, UnresolvedExports[I].Id);
Douglas Gregorf4ac17e2011-12-05 17:34:59 +0000120 if (UnresolvedExports[I].Wildcard) {
121 if (UnresolvedExports[I].Id.empty())
122 OS << "*";
123 else
124 OS << ".*";
125 }
Douglas Gregoraf13bfc2011-12-02 18:58:38 +0000126 OS << "\n";
127 }
128
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000129 OS.indent(Indent);
130 OS << "}\n";
131}
132
133void Module::dump() const {
134 print(llvm::errs());
135}
136
137