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 \""; 94 OS.write_escaped(UmbrellaHeader->getName()); 95 OS << "\"\n"; 96 } 97 98 for (unsigned I = 0, N = Headers.size(); I != N; ++I) { 99 OS.indent(Indent + 2); 100 OS << "header \""; 101 OS.write_escaped(Headers[I]->getName()); 102 OS << "\"\n"; 103 } 104 105 for (llvm::StringMap<Module *>::const_iterator MI = SubModules.begin(), 106 MIEnd = SubModules.end(); 107 MI != MIEnd; ++MI) 108 MI->getValue()->print(OS, Indent + 2); 109 110 for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 111 OS.indent(Indent + 2); 112 OS << "export "; 113 if (Module *Restriction = Exports[I].getPointer()) { 114 OS << Restriction->getFullModuleName(); 115 if (Exports[I].getInt()) 116 OS << ".*"; 117 } else { 118 OS << "*"; 119 } 120 OS << "\n"; 121 } 122 123 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 124 OS.indent(Indent + 2); 125 OS << "export "; 126 printModuleId(OS, UnresolvedExports[I].Id); 127 if (UnresolvedExports[I].Wildcard) { 128 if (UnresolvedExports[I].Id.empty()) 129 OS << "*"; 130 else 131 OS << ".*"; 132 } 133 OS << "\n"; 134 } 135 136 if (InferSubmodules) { 137 OS.indent(Indent + 2); 138 if (InferExplicitSubmodules) 139 OS << "explicit "; 140 OS << "module * {\n"; 141 if (InferExportWildcard) { 142 OS.indent(Indent + 4); 143 OS << "export *\n"; 144 } 145 OS.indent(Indent + 2); 146 OS << "}\n"; 147 } 148 149 OS.indent(Indent); 150 OS << "}\n"; 151 } 152 153 void Module::dump() const { 154 print(llvm::errs()); 155 } 156 157 158