1//===--- Module.cpp - Describe a module -----------------------------------===// 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 "clang/Basic/TargetInfo.h" 18#include "llvm/ADT/ArrayRef.h" 19#include "llvm/ADT/SmallVector.h" 20#include "llvm/ADT/StringSwitch.h" 21#include "llvm/Support/ErrorHandling.h" 22#include "llvm/Support/raw_ostream.h" 23using namespace clang; 24 25Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 26 bool IsFramework, bool IsExplicit) 27 : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), 28 Umbrella(), ASTFile(0), IsAvailable(true), IsFromModuleFile(false), 29 IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), 30 InferSubmodules(false), InferExplicitSubmodules(false), 31 InferExportWildcard(false), ConfigMacrosExhaustive(false), 32 NameVisibility(Hidden) 33{ 34 if (Parent) { 35 if (!Parent->isAvailable()) 36 IsAvailable = false; 37 if (Parent->IsSystem) 38 IsSystem = true; 39 40 Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 41 Parent->SubModules.push_back(this); 42 } 43} 44 45Module::~Module() { 46 for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 47 I != IEnd; ++I) { 48 delete *I; 49 } 50} 51 52/// \brief Determine whether a translation unit built using the current 53/// language options has the given feature. 54static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 55 const TargetInfo &Target) { 56 return llvm::StringSwitch<bool>(Feature) 57 .Case("altivec", LangOpts.AltiVec) 58 .Case("blocks", LangOpts.Blocks) 59 .Case("cplusplus", LangOpts.CPlusPlus) 60 .Case("cplusplus11", LangOpts.CPlusPlus11) 61 .Case("objc", LangOpts.ObjC1) 62 .Case("objc_arc", LangOpts.ObjCAutoRefCount) 63 .Case("opencl", LangOpts.OpenCL) 64 .Case("tls", Target.isTLSSupported()) 65 .Default(Target.hasFeature(Feature)); 66} 67 68bool 69Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 70 StringRef &Feature) const { 71 if (IsAvailable) 72 return true; 73 74 for (const Module *Current = this; Current; Current = Current->Parent) { 75 for (unsigned I = 0, N = Current->Requires.size(); I != N; ++I) { 76 if (!hasFeature(Current->Requires[I], LangOpts, Target)) { 77 Feature = Current->Requires[I]; 78 return false; 79 } 80 } 81 } 82 83 llvm_unreachable("could not find a reason why module is unavailable"); 84} 85 86bool Module::isSubModuleOf(Module *Other) const { 87 const Module *This = this; 88 do { 89 if (This == Other) 90 return true; 91 92 This = This->Parent; 93 } while (This); 94 95 return false; 96} 97 98const Module *Module::getTopLevelModule() const { 99 const Module *Result = this; 100 while (Result->Parent) 101 Result = Result->Parent; 102 103 return Result; 104} 105 106std::string Module::getFullModuleName() const { 107 SmallVector<StringRef, 2> Names; 108 109 // Build up the set of module names (from innermost to outermost). 110 for (const Module *M = this; M; M = M->Parent) 111 Names.push_back(M->Name); 112 113 std::string Result; 114 for (SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), 115 IEnd = Names.rend(); 116 I != IEnd; ++I) { 117 if (!Result.empty()) 118 Result += '.'; 119 120 Result += *I; 121 } 122 123 return Result; 124} 125 126const DirectoryEntry *Module::getUmbrellaDir() const { 127 if (const FileEntry *Header = getUmbrellaHeader()) 128 return Header->getDir(); 129 130 return Umbrella.dyn_cast<const DirectoryEntry *>(); 131} 132 133ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 134 if (!TopHeaderNames.empty()) { 135 for (std::vector<std::string>::iterator 136 I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 137 if (const FileEntry *FE = FileMgr.getFile(*I)) 138 TopHeaders.insert(FE); 139 } 140 TopHeaderNames.clear(); 141 } 142 143 return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 144} 145 146void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts, 147 const TargetInfo &Target) { 148 Requires.push_back(Feature); 149 150 // If this feature is currently available, we're done. 151 if (hasFeature(Feature, LangOpts, Target)) 152 return; 153 154 if (!IsAvailable) 155 return; 156 157 SmallVector<Module *, 2> Stack; 158 Stack.push_back(this); 159 while (!Stack.empty()) { 160 Module *Current = Stack.back(); 161 Stack.pop_back(); 162 163 if (!Current->IsAvailable) 164 continue; 165 166 Current->IsAvailable = false; 167 for (submodule_iterator Sub = Current->submodule_begin(), 168 SubEnd = Current->submodule_end(); 169 Sub != SubEnd; ++Sub) { 170 if ((*Sub)->IsAvailable) 171 Stack.push_back(*Sub); 172 } 173 } 174} 175 176Module *Module::findSubmodule(StringRef Name) const { 177 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 178 if (Pos == SubModuleIndex.end()) 179 return 0; 180 181 return SubModules[Pos->getValue()]; 182} 183 184static void printModuleId(raw_ostream &OS, const ModuleId &Id) { 185 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 186 if (I) 187 OS << "."; 188 OS << Id[I].first; 189 } 190} 191 192void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 193 bool AnyWildcard = false; 194 bool UnrestrictedWildcard = false; 195 SmallVector<Module *, 4> WildcardRestrictions; 196 for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 197 Module *Mod = Exports[I].getPointer(); 198 if (!Exports[I].getInt()) { 199 // Export a named module directly; no wildcards involved. 200 Exported.push_back(Mod); 201 202 continue; 203 } 204 205 // Wildcard export: export all of the imported modules that match 206 // the given pattern. 207 AnyWildcard = true; 208 if (UnrestrictedWildcard) 209 continue; 210 211 if (Module *Restriction = Exports[I].getPointer()) 212 WildcardRestrictions.push_back(Restriction); 213 else { 214 WildcardRestrictions.clear(); 215 UnrestrictedWildcard = true; 216 } 217 } 218 219 // If there were any wildcards, push any imported modules that were 220 // re-exported by the wildcard restriction. 221 if (!AnyWildcard) 222 return; 223 224 for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 225 Module *Mod = Imports[I]; 226 bool Acceptable = UnrestrictedWildcard; 227 if (!Acceptable) { 228 // Check whether this module meets one of the restrictions. 229 for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 230 Module *Restriction = WildcardRestrictions[R]; 231 if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 232 Acceptable = true; 233 break; 234 } 235 } 236 } 237 238 if (!Acceptable) 239 continue; 240 241 Exported.push_back(Mod); 242 } 243} 244 245void Module::print(raw_ostream &OS, unsigned Indent) const { 246 OS.indent(Indent); 247 if (IsFramework) 248 OS << "framework "; 249 if (IsExplicit) 250 OS << "explicit "; 251 OS << "module " << Name; 252 253 if (IsSystem) { 254 OS.indent(Indent + 2); 255 OS << " [system]"; 256 } 257 258 OS << " {\n"; 259 260 if (!Requires.empty()) { 261 OS.indent(Indent + 2); 262 OS << "requires "; 263 for (unsigned I = 0, N = Requires.size(); I != N; ++I) { 264 if (I) 265 OS << ", "; 266 OS << Requires[I]; 267 } 268 OS << "\n"; 269 } 270 271 if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) { 272 OS.indent(Indent + 2); 273 OS << "umbrella header \""; 274 OS.write_escaped(UmbrellaHeader->getName()); 275 OS << "\"\n"; 276 } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) { 277 OS.indent(Indent + 2); 278 OS << "umbrella \""; 279 OS.write_escaped(UmbrellaDir->getName()); 280 OS << "\"\n"; 281 } 282 283 if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 284 OS.indent(Indent + 2); 285 OS << "config_macros "; 286 if (ConfigMacrosExhaustive) 287 OS << "[exhaustive]"; 288 for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 289 if (I) 290 OS << ", "; 291 OS << ConfigMacros[I]; 292 } 293 OS << "\n"; 294 } 295 296 for (unsigned I = 0, N = Headers.size(); I != N; ++I) { 297 OS.indent(Indent + 2); 298 OS << "header \""; 299 OS.write_escaped(Headers[I]->getName()); 300 OS << "\"\n"; 301 } 302 303 for (unsigned I = 0, N = ExcludedHeaders.size(); I != N; ++I) { 304 OS.indent(Indent + 2); 305 OS << "exclude header \""; 306 OS.write_escaped(ExcludedHeaders[I]->getName()); 307 OS << "\"\n"; 308 } 309 310 for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 311 MI != MIEnd; ++MI) 312 (*MI)->print(OS, Indent + 2); 313 314 for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 315 OS.indent(Indent + 2); 316 OS << "export "; 317 if (Module *Restriction = Exports[I].getPointer()) { 318 OS << Restriction->getFullModuleName(); 319 if (Exports[I].getInt()) 320 OS << ".*"; 321 } else { 322 OS << "*"; 323 } 324 OS << "\n"; 325 } 326 327 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 328 OS.indent(Indent + 2); 329 OS << "export "; 330 printModuleId(OS, UnresolvedExports[I].Id); 331 if (UnresolvedExports[I].Wildcard) { 332 if (UnresolvedExports[I].Id.empty()) 333 OS << "*"; 334 else 335 OS << ".*"; 336 } 337 OS << "\n"; 338 } 339 340 for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 341 OS.indent(Indent + 2); 342 OS << "link "; 343 if (LinkLibraries[I].IsFramework) 344 OS << "framework "; 345 OS << "\""; 346 OS.write_escaped(LinkLibraries[I].Library); 347 OS << "\""; 348 } 349 350 for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 351 OS.indent(Indent + 2); 352 OS << "conflict "; 353 printModuleId(OS, UnresolvedConflicts[I].Id); 354 OS << ", \""; 355 OS.write_escaped(UnresolvedConflicts[I].Message); 356 OS << "\"\n"; 357 } 358 359 for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 360 OS.indent(Indent + 2); 361 OS << "conflict "; 362 OS << Conflicts[I].Other->getFullModuleName(); 363 OS << ", \""; 364 OS.write_escaped(Conflicts[I].Message); 365 OS << "\"\n"; 366 } 367 368 if (InferSubmodules) { 369 OS.indent(Indent + 2); 370 if (InferExplicitSubmodules) 371 OS << "explicit "; 372 OS << "module * {\n"; 373 if (InferExportWildcard) { 374 OS.indent(Indent + 4); 375 OS << "export *\n"; 376 } 377 OS.indent(Indent + 2); 378 OS << "}\n"; 379 } 380 381 OS.indent(Indent); 382 OS << "}\n"; 383} 384 385void Module::dump() const { 386 print(llvm::errs()); 387} 388 389 390