1*de3ef502SDouglas Gregor //===--- Module.h - Describe a module ---------------------------*- C++ -*-===//
2*de3ef502SDouglas Gregor //
3*de3ef502SDouglas Gregor //                     The LLVM Compiler Infrastructure
4*de3ef502SDouglas Gregor //
5*de3ef502SDouglas Gregor // This file is distributed under the University of Illinois Open Source
6*de3ef502SDouglas Gregor // License. See LICENSE.TXT for details.
7*de3ef502SDouglas Gregor //
8*de3ef502SDouglas Gregor //===----------------------------------------------------------------------===//
9*de3ef502SDouglas Gregor //
10*de3ef502SDouglas Gregor // This file defines the Module class, which describes a module in the source
11*de3ef502SDouglas Gregor // code.
12*de3ef502SDouglas Gregor //
13*de3ef502SDouglas Gregor //===----------------------------------------------------------------------===//
14*de3ef502SDouglas Gregor #include "clang/Basic/Module.h"
15*de3ef502SDouglas Gregor #include "clang/Basic/FileManager.h"
16*de3ef502SDouglas Gregor #include "llvm/Support/raw_ostream.h"
17*de3ef502SDouglas Gregor using namespace clang;
18*de3ef502SDouglas Gregor 
19*de3ef502SDouglas Gregor Module::~Module() {
20*de3ef502SDouglas Gregor   for (llvm::StringMap<Module *>::iterator I = SubModules.begin(),
21*de3ef502SDouglas Gregor                                         IEnd = SubModules.end();
22*de3ef502SDouglas Gregor        I != IEnd; ++I) {
23*de3ef502SDouglas Gregor     delete I->getValue();
24*de3ef502SDouglas Gregor   }
25*de3ef502SDouglas Gregor 
26*de3ef502SDouglas Gregor }
27*de3ef502SDouglas Gregor 
28*de3ef502SDouglas Gregor std::string Module::getFullModuleName() const {
29*de3ef502SDouglas Gregor   llvm::SmallVector<StringRef, 2> Names;
30*de3ef502SDouglas Gregor 
31*de3ef502SDouglas Gregor   // Build up the set of module names (from innermost to outermost).
32*de3ef502SDouglas Gregor   for (const Module *M = this; M; M = M->Parent)
33*de3ef502SDouglas Gregor     Names.push_back(M->Name);
34*de3ef502SDouglas Gregor 
35*de3ef502SDouglas Gregor   std::string Result;
36*de3ef502SDouglas Gregor   for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(),
37*de3ef502SDouglas Gregor                                                       IEnd = Names.rend();
38*de3ef502SDouglas Gregor        I != IEnd; ++I) {
39*de3ef502SDouglas Gregor     if (!Result.empty())
40*de3ef502SDouglas Gregor       Result += '.';
41*de3ef502SDouglas Gregor 
42*de3ef502SDouglas Gregor     Result += *I;
43*de3ef502SDouglas Gregor   }
44*de3ef502SDouglas Gregor 
45*de3ef502SDouglas Gregor   return Result;
46*de3ef502SDouglas Gregor }
47*de3ef502SDouglas Gregor 
48*de3ef502SDouglas Gregor StringRef Module::getTopLevelModuleName() const {
49*de3ef502SDouglas Gregor   const Module *Top = this;
50*de3ef502SDouglas Gregor   while (Top->Parent)
51*de3ef502SDouglas Gregor     Top = Top->Parent;
52*de3ef502SDouglas Gregor 
53*de3ef502SDouglas Gregor   return Top->Name;
54*de3ef502SDouglas Gregor }
55*de3ef502SDouglas Gregor 
56*de3ef502SDouglas Gregor void Module::print(llvm::raw_ostream &OS, unsigned Indent) const {
57*de3ef502SDouglas Gregor   OS.indent(Indent);
58*de3ef502SDouglas Gregor   if (IsFramework)
59*de3ef502SDouglas Gregor     OS << "framework ";
60*de3ef502SDouglas Gregor   if (IsExplicit)
61*de3ef502SDouglas Gregor     OS << "explicit ";
62*de3ef502SDouglas Gregor   OS << "module " << Name << " {\n";
63*de3ef502SDouglas Gregor 
64*de3ef502SDouglas Gregor   if (UmbrellaHeader) {
65*de3ef502SDouglas Gregor     OS.indent(Indent + 2);
66*de3ef502SDouglas Gregor     OS << "umbrella \"";
67*de3ef502SDouglas Gregor     OS.write_escaped(UmbrellaHeader->getName());
68*de3ef502SDouglas Gregor     OS << "\"\n";
69*de3ef502SDouglas Gregor   }
70*de3ef502SDouglas Gregor 
71*de3ef502SDouglas Gregor   for (unsigned I = 0, N = Headers.size(); I != N; ++I) {
72*de3ef502SDouglas Gregor     OS.indent(Indent + 2);
73*de3ef502SDouglas Gregor     OS << "header \"";
74*de3ef502SDouglas Gregor     OS.write_escaped(Headers[I]->getName());
75*de3ef502SDouglas Gregor     OS << "\"\n";
76*de3ef502SDouglas Gregor   }
77*de3ef502SDouglas Gregor 
78*de3ef502SDouglas Gregor   for (llvm::StringMap<Module *>::const_iterator MI = SubModules.begin(),
79*de3ef502SDouglas Gregor        MIEnd = SubModules.end();
80*de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
81*de3ef502SDouglas Gregor     MI->getValue()->print(OS, Indent + 2);
82*de3ef502SDouglas Gregor 
83*de3ef502SDouglas Gregor   OS.indent(Indent);
84*de3ef502SDouglas Gregor   OS << "}\n";
85*de3ef502SDouglas Gregor }
86*de3ef502SDouglas Gregor 
87*de3ef502SDouglas Gregor void Module::dump() const {
88*de3ef502SDouglas Gregor   print(llvm::errs());
89*de3ef502SDouglas Gregor }
90*de3ef502SDouglas Gregor 
91*de3ef502SDouglas Gregor 
92