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 "clang/Basic/LangOptions.h" 17 #include "llvm/Support/ErrorHandling.h" 18 #include "llvm/Support/raw_ostream.h" 19 #include "llvm/ADT/SmallVector.h" 20 #include "llvm/ADT/StringSwitch.h" 21 using namespace clang; 22 23 Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 24 bool IsFramework, bool IsExplicit) 25 : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), 26 Umbrella(), IsAvailable(true), IsFromModuleFile(false), 27 IsFramework(IsFramework), IsExplicit(IsExplicit), InferSubmodules(false), 28 InferExplicitSubmodules(false), InferExportWildcard(false), 29 NameVisibility(Hidden) 30 { 31 if (Parent) { 32 if (!Parent->isAvailable()) 33 IsAvailable = false; 34 35 Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 36 Parent->SubModules.push_back(this); 37 } 38 } 39 40 Module::~Module() { 41 for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 42 I != IEnd; ++I) { 43 delete *I; 44 } 45 46 } 47 48 /// \brief Determine whether a translation unit built using the current 49 /// language options has the given feature. 50 static bool hasFeature(StringRef Feature, const LangOptions &LangOpts) { 51 return llvm::StringSwitch<bool>(Feature) 52 .Case("blocks", LangOpts.Blocks) 53 .Case("cplusplus", LangOpts.CPlusPlus) 54 .Case("cplusplus11", LangOpts.CPlusPlus0x) 55 .Case("objc", LangOpts.ObjC1) 56 .Case("objc_arc", LangOpts.ObjCAutoRefCount) 57 .Default(false); 58 } 59 60 bool 61 Module::isAvailable(const LangOptions &LangOpts, StringRef &Feature) const { 62 if (IsAvailable) 63 return true; 64 65 for (const Module *Current = this; Current; Current = Current->Parent) { 66 for (unsigned I = 0, N = Current->Requires.size(); I != N; ++I) { 67 if (!hasFeature(Current->Requires[I], LangOpts)) { 68 Feature = Current->Requires[I]; 69 return false; 70 } 71 } 72 } 73 74 llvm_unreachable("could not find a reason why module is unavailable"); 75 } 76 77 bool Module::isSubModuleOf(Module *Other) const { 78 const Module *This = this; 79 do { 80 if (This == Other) 81 return true; 82 83 This = This->Parent; 84 } while (This); 85 86 return false; 87 } 88 89 const Module *Module::getTopLevelModule() const { 90 const Module *Result = this; 91 while (Result->Parent) 92 Result = Result->Parent; 93 94 return Result; 95 } 96 97 std::string Module::getFullModuleName() const { 98 llvm::SmallVector<StringRef, 2> Names; 99 100 // Build up the set of module names (from innermost to outermost). 101 for (const Module *M = this; M; M = M->Parent) 102 Names.push_back(M->Name); 103 104 std::string Result; 105 for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), 106 IEnd = Names.rend(); 107 I != IEnd; ++I) { 108 if (!Result.empty()) 109 Result += '.'; 110 111 Result += *I; 112 } 113 114 return Result; 115 } 116 117 const DirectoryEntry *Module::getUmbrellaDir() const { 118 if (const FileEntry *Header = getUmbrellaHeader()) 119 return Header->getDir(); 120 121 return Umbrella.dyn_cast<const DirectoryEntry *>(); 122 } 123 124 void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts) { 125 Requires.push_back(Feature); 126 127 // If this feature is currently available, we're done. 128 if (hasFeature(Feature, LangOpts)) 129 return; 130 131 if (!IsAvailable) 132 return; 133 134 llvm::SmallVector<Module *, 2> Stack; 135 Stack.push_back(this); 136 while (!Stack.empty()) { 137 Module *Current = Stack.back(); 138 Stack.pop_back(); 139 140 if (!Current->IsAvailable) 141 continue; 142 143 Current->IsAvailable = false; 144 for (submodule_iterator Sub = Current->submodule_begin(), 145 SubEnd = Current->submodule_end(); 146 Sub != SubEnd; ++Sub) { 147 if ((*Sub)->IsAvailable) 148 Stack.push_back(*Sub); 149 } 150 } 151 } 152 153 Module *Module::findSubmodule(StringRef Name) const { 154 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 155 if (Pos == SubModuleIndex.end()) 156 return 0; 157 158 return SubModules[Pos->getValue()]; 159 } 160 161 static void printModuleId(llvm::raw_ostream &OS, const ModuleId &Id) { 162 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 163 if (I) 164 OS << "."; 165 OS << Id[I].first; 166 } 167 } 168 169 void Module::print(llvm::raw_ostream &OS, unsigned Indent) const { 170 OS.indent(Indent); 171 if (IsFramework) 172 OS << "framework "; 173 if (IsExplicit) 174 OS << "explicit "; 175 OS << "module " << Name << " {\n"; 176 177 if (!Requires.empty()) { 178 OS.indent(Indent + 2); 179 OS << "requires "; 180 for (unsigned I = 0, N = Requires.size(); I != N; ++I) { 181 if (I) 182 OS << ", "; 183 OS << Requires[I]; 184 } 185 OS << "\n"; 186 } 187 188 if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) { 189 OS.indent(Indent + 2); 190 OS << "umbrella header \""; 191 OS.write_escaped(UmbrellaHeader->getName()); 192 OS << "\"\n"; 193 } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) { 194 OS.indent(Indent + 2); 195 OS << "umbrella \""; 196 OS.write_escaped(UmbrellaDir->getName()); 197 OS << "\"\n"; 198 } 199 200 for (unsigned I = 0, N = Headers.size(); I != N; ++I) { 201 OS.indent(Indent + 2); 202 OS << "header \""; 203 OS.write_escaped(Headers[I]->getName()); 204 OS << "\"\n"; 205 } 206 207 for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 208 MI != MIEnd; ++MI) 209 (*MI)->print(OS, Indent + 2); 210 211 for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 212 OS.indent(Indent + 2); 213 OS << "export "; 214 if (Module *Restriction = Exports[I].getPointer()) { 215 OS << Restriction->getFullModuleName(); 216 if (Exports[I].getInt()) 217 OS << ".*"; 218 } else { 219 OS << "*"; 220 } 221 OS << "\n"; 222 } 223 224 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 225 OS.indent(Indent + 2); 226 OS << "export "; 227 printModuleId(OS, UnresolvedExports[I].Id); 228 if (UnresolvedExports[I].Wildcard) { 229 if (UnresolvedExports[I].Id.empty()) 230 OS << "*"; 231 else 232 OS << ".*"; 233 } 234 OS << "\n"; 235 } 236 237 if (InferSubmodules) { 238 OS.indent(Indent + 2); 239 if (InferExplicitSubmodules) 240 OS << "explicit "; 241 OS << "module * {\n"; 242 if (InferExportWildcard) { 243 OS.indent(Indent + 4); 244 OS << "export *\n"; 245 } 246 OS.indent(Indent + 2); 247 OS << "}\n"; 248 } 249 250 OS.indent(Indent); 251 OS << "}\n"; 252 } 253 254 void Module::dump() const { 255 print(llvm::errs()); 256 } 257 258 259