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 const Module *Module::getTopLevelModule() const { 41 const Module *Result = this; 42 while (Result->Parent) 43 Result = Result->Parent; 44 45 return Result; 46 } 47 48 std::string Module::getFullModuleName() const { 49 llvm::SmallVector<StringRef, 2> Names; 50 51 // Build up the set of module names (from innermost to outermost). 52 for (const Module *M = this; M; M = M->Parent) 53 Names.push_back(M->Name); 54 55 std::string Result; 56 for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), 57 IEnd = Names.rend(); 58 I != IEnd; ++I) { 59 if (!Result.empty()) 60 Result += '.'; 61 62 Result += *I; 63 } 64 65 return Result; 66 } 67 68 const DirectoryEntry *Module::getUmbrellaDir() const { 69 if (const FileEntry *Header = getUmbrellaHeader()) 70 return Header->getDir(); 71 72 return Umbrella.dyn_cast<const DirectoryEntry *>(); 73 } 74 75 static void printModuleId(llvm::raw_ostream &OS, const ModuleId &Id) { 76 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 77 if (I) 78 OS << "."; 79 OS << Id[I].first; 80 } 81 } 82 83 void Module::print(llvm::raw_ostream &OS, unsigned Indent) const { 84 OS.indent(Indent); 85 if (IsFramework) 86 OS << "framework "; 87 if (IsExplicit) 88 OS << "explicit "; 89 OS << "module " << Name << " {\n"; 90 91 if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) { 92 OS.indent(Indent + 2); 93 OS << "umbrella header \""; 94 OS.write_escaped(UmbrellaHeader->getName()); 95 OS << "\"\n"; 96 } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) { 97 OS.indent(Indent + 2); 98 OS << "umbrella \""; 99 OS.write_escaped(UmbrellaDir->getName()); 100 OS << "\"\n"; 101 } 102 103 for (unsigned I = 0, N = Headers.size(); I != N; ++I) { 104 OS.indent(Indent + 2); 105 OS << "header \""; 106 OS.write_escaped(Headers[I]->getName()); 107 OS << "\"\n"; 108 } 109 110 for (llvm::StringMap<Module *>::const_iterator MI = SubModules.begin(), 111 MIEnd = SubModules.end(); 112 MI != MIEnd; ++MI) 113 MI->getValue()->print(OS, Indent + 2); 114 115 for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 116 OS.indent(Indent + 2); 117 OS << "export "; 118 if (Module *Restriction = Exports[I].getPointer()) { 119 OS << Restriction->getFullModuleName(); 120 if (Exports[I].getInt()) 121 OS << ".*"; 122 } else { 123 OS << "*"; 124 } 125 OS << "\n"; 126 } 127 128 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 129 OS.indent(Indent + 2); 130 OS << "export "; 131 printModuleId(OS, UnresolvedExports[I].Id); 132 if (UnresolvedExports[I].Wildcard) { 133 if (UnresolvedExports[I].Id.empty()) 134 OS << "*"; 135 else 136 OS << ".*"; 137 } 138 OS << "\n"; 139 } 140 141 if (InferSubmodules) { 142 OS.indent(Indent + 2); 143 if (InferExplicitSubmodules) 144 OS << "explicit "; 145 OS << "module * {\n"; 146 if (InferExportWildcard) { 147 OS.indent(Indent + 4); 148 OS << "export *\n"; 149 } 150 OS.indent(Indent + 2); 151 OS << "}\n"; 152 } 153 154 OS.indent(Indent); 155 OS << "}\n"; 156 } 157 158 void Module::dump() const { 159 print(llvm::errs()); 160 } 161 162 163