blob: 6bca55c754a8f09bd4dcfcd5859bd5461b00c38e [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
28std::string Module::getFullModuleName() const {
29 llvm::SmallVector<StringRef, 2> Names;
30
31 // Build up the set of module names (from innermost to outermost).
32 for (const Module *M = this; M; M = M->Parent)
33 Names.push_back(M->Name);
34
35 std::string Result;
36 for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(),
37 IEnd = Names.rend();
38 I != IEnd; ++I) {
39 if (!Result.empty())
40 Result += '.';
41
42 Result += *I;
43 }
44
45 return Result;
46}
47
48StringRef Module::getTopLevelModuleName() const {
49 const Module *Top = this;
50 while (Top->Parent)
51 Top = Top->Parent;
52
53 return Top->Name;
54}
55
Douglas Gregoraf13bfc2011-12-02 18:58:38 +000056static void printModuleId(llvm::raw_ostream &OS, const ModuleId &Id) {
57 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
58 if (I)
59 OS << ".";
60 OS << Id[I].first;
61 }
62}
63
Douglas Gregor1a4761e2011-11-30 23:21:26 +000064void Module::print(llvm::raw_ostream &OS, unsigned Indent) const {
65 OS.indent(Indent);
66 if (IsFramework)
67 OS << "framework ";
68 if (IsExplicit)
69 OS << "explicit ";
70 OS << "module " << Name << " {\n";
71
72 if (UmbrellaHeader) {
73 OS.indent(Indent + 2);
74 OS << "umbrella \"";
75 OS.write_escaped(UmbrellaHeader->getName());
76 OS << "\"\n";
77 }
78
79 for (unsigned I = 0, N = Headers.size(); I != N; ++I) {
80 OS.indent(Indent + 2);
81 OS << "header \"";
82 OS.write_escaped(Headers[I]->getName());
83 OS << "\"\n";
84 }
85
86 for (llvm::StringMap<Module *>::const_iterator MI = SubModules.begin(),
87 MIEnd = SubModules.end();
88 MI != MIEnd; ++MI)
89 MI->getValue()->print(OS, Indent + 2);
90
Douglas Gregoraf13bfc2011-12-02 18:58:38 +000091 for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
92 OS.indent(Indent + 2);
93 OS << "export " << Exports[I].getPointer()->getFullModuleName();
94 if (Exports[I].getInt())
95 OS << ".*";
96 OS << "\n";
97 }
98
99 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
100 OS.indent(Indent + 2);
101 OS << "export ";
102 printModuleId(OS, UnresolvedExports[I].Id);
103 if (UnresolvedExports[I].Wildcard)
104 OS << ".*";
105 OS << "\n";
106 }
107
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000108 OS.indent(Indent);
109 OS << "}\n";
110}
111
112void Module::dump() const {
113 print(llvm::errs());
114}
115
116