xref: /llvm-project/clang/lib/Basic/Module.cpp (revision 24bb923aa84354bfa18240bdda6d9aa07ef83427)
1 //===--- 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"
17 using namespace clang;
18 
19 Module::~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 
28 std::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 
48 StringRef Module::getTopLevelModuleName() const {
49   const Module *Top = this;
50   while (Top->Parent)
51     Top = Top->Parent;
52 
53   return Top->Name;
54 }
55 
56 static 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 
64 void 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 
91   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 
108   OS.indent(Indent);
109   OS << "}\n";
110 }
111 
112 void Module::dump() const {
113   print(llvm::errs());
114 }
115 
116 
117