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 bool 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 40 std::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 60 StringRef Module::getTopLevelModuleName() const { 61 const Module *Top = this; 62 while (Top->Parent) 63 Top = Top->Parent; 64 65 return Top->Name; 66 } 67 68 static 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 76 void 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 103 for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 104 OS.indent(Indent + 2); 105 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 } 113 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); 120 if (UnresolvedExports[I].Wildcard) { 121 if (UnresolvedExports[I].Id.empty()) 122 OS << "*"; 123 else 124 OS << ".*"; 125 } 126 OS << "\n"; 127 } 128 129 OS.indent(Indent); 130 OS << "}\n"; 131 } 132 133 void Module::dump() const { 134 print(llvm::errs()); 135 } 136 137 138