13a02247dSChandler Carruth //===--- Module.cpp - Describe a module -----------------------------------===// 2de3ef502SDouglas Gregor // 3de3ef502SDouglas Gregor // The LLVM Compiler Infrastructure 4de3ef502SDouglas Gregor // 5de3ef502SDouglas Gregor // This file is distributed under the University of Illinois Open Source 6de3ef502SDouglas Gregor // License. See LICENSE.TXT for details. 7de3ef502SDouglas Gregor // 8de3ef502SDouglas Gregor //===----------------------------------------------------------------------===// 9de3ef502SDouglas Gregor // 10de3ef502SDouglas Gregor // This file defines the Module class, which describes a module in the source 11de3ef502SDouglas Gregor // code. 12de3ef502SDouglas Gregor // 13de3ef502SDouglas Gregor //===----------------------------------------------------------------------===// 14de3ef502SDouglas Gregor #include "clang/Basic/Module.h" 15de3ef502SDouglas Gregor #include "clang/Basic/FileManager.h" 161fb5c3a6SDouglas Gregor #include "clang/Basic/LangOptions.h" 170070c0bfSDouglas Gregor #include "clang/Basic/TargetInfo.h" 181fb5c3a6SDouglas Gregor #include "llvm/ADT/SmallVector.h" 191fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h" 203a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h" 213a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 22de3ef502SDouglas Gregor using namespace clang; 23de3ef502SDouglas Gregor 24eb90e830SDouglas Gregor Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 25eb90e830SDouglas Gregor bool IsFramework, bool IsExplicit) 26eb90e830SDouglas Gregor : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), 2743af5132SArgyrios Kyrtzidis Umbrella(), ASTFile(0), IsAvailable(true), IsFromModuleFile(false), 28a686e1b0SDouglas Gregor IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), 29a686e1b0SDouglas Gregor InferSubmodules(false), InferExplicitSubmodules(false), 30a686e1b0SDouglas Gregor InferExportWildcard(false), NameVisibility(Hidden) 31eb90e830SDouglas Gregor { 32eb90e830SDouglas Gregor if (Parent) { 33eb90e830SDouglas Gregor if (!Parent->isAvailable()) 34eb90e830SDouglas Gregor IsAvailable = false; 353ec6663bSDouglas Gregor if (Parent->IsSystem) 363ec6663bSDouglas Gregor IsSystem = true; 37eb90e830SDouglas Gregor 38eb90e830SDouglas Gregor Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 39eb90e830SDouglas Gregor Parent->SubModules.push_back(this); 40eb90e830SDouglas Gregor } 41eb90e830SDouglas Gregor } 42eb90e830SDouglas Gregor 43de3ef502SDouglas Gregor Module::~Module() { 44eb90e830SDouglas Gregor for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 45de3ef502SDouglas Gregor I != IEnd; ++I) { 46eb90e830SDouglas Gregor delete *I; 47de3ef502SDouglas Gregor } 48de3ef502SDouglas Gregor 49de3ef502SDouglas Gregor } 50de3ef502SDouglas Gregor 511fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current 521fb5c3a6SDouglas Gregor /// language options has the given feature. 5389929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 5489929282SDouglas Gregor const TargetInfo &Target) { 551fb5c3a6SDouglas Gregor return llvm::StringSwitch<bool>(Feature) 560070c0bfSDouglas Gregor .Case("altivec", LangOpts.AltiVec) 571fb5c3a6SDouglas Gregor .Case("blocks", LangOpts.Blocks) 581fb5c3a6SDouglas Gregor .Case("cplusplus", LangOpts.CPlusPlus) 592bf7fdb7SRichard Smith .Case("cplusplus11", LangOpts.CPlusPlus11) 601fb5c3a6SDouglas Gregor .Case("objc", LangOpts.ObjC1) 611fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 620070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 630070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 640070c0bfSDouglas Gregor .Default(Target.hasFeature(Feature)); 651fb5c3a6SDouglas Gregor } 661fb5c3a6SDouglas Gregor 671fb5c3a6SDouglas Gregor bool 6889929282SDouglas Gregor Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 6989929282SDouglas Gregor StringRef &Feature) const { 701fb5c3a6SDouglas Gregor if (IsAvailable) 711fb5c3a6SDouglas Gregor return true; 721fb5c3a6SDouglas Gregor 731fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 741fb5c3a6SDouglas Gregor for (unsigned I = 0, N = Current->Requires.size(); I != N; ++I) { 7589929282SDouglas Gregor if (!hasFeature(Current->Requires[I], LangOpts, Target)) { 761fb5c3a6SDouglas Gregor Feature = Current->Requires[I]; 771fb5c3a6SDouglas Gregor return false; 781fb5c3a6SDouglas Gregor } 791fb5c3a6SDouglas Gregor } 801fb5c3a6SDouglas Gregor } 811fb5c3a6SDouglas Gregor 821fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 831fb5c3a6SDouglas Gregor } 841fb5c3a6SDouglas Gregor 85f5eedd05SDouglas Gregor bool Module::isSubModuleOf(Module *Other) const { 86f5eedd05SDouglas Gregor const Module *This = this; 87f5eedd05SDouglas Gregor do { 88f5eedd05SDouglas Gregor if (This == Other) 89f5eedd05SDouglas Gregor return true; 90f5eedd05SDouglas Gregor 91f5eedd05SDouglas Gregor This = This->Parent; 92f5eedd05SDouglas Gregor } while (This); 93f5eedd05SDouglas Gregor 94f5eedd05SDouglas Gregor return false; 95f5eedd05SDouglas Gregor } 96f5eedd05SDouglas Gregor 9773441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 9873441091SDouglas Gregor const Module *Result = this; 9973441091SDouglas Gregor while (Result->Parent) 10073441091SDouglas Gregor Result = Result->Parent; 10173441091SDouglas Gregor 10273441091SDouglas Gregor return Result; 10373441091SDouglas Gregor } 10473441091SDouglas Gregor 105de3ef502SDouglas Gregor std::string Module::getFullModuleName() const { 106f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 107de3ef502SDouglas Gregor 108de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 109de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 110de3ef502SDouglas Gregor Names.push_back(M->Name); 111de3ef502SDouglas Gregor 112de3ef502SDouglas Gregor std::string Result; 113f857950dSDmitri Gribenko for (SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), 114de3ef502SDouglas Gregor IEnd = Names.rend(); 115de3ef502SDouglas Gregor I != IEnd; ++I) { 116de3ef502SDouglas Gregor if (!Result.empty()) 117de3ef502SDouglas Gregor Result += '.'; 118de3ef502SDouglas Gregor 119de3ef502SDouglas Gregor Result += *I; 120de3ef502SDouglas Gregor } 121de3ef502SDouglas Gregor 122de3ef502SDouglas Gregor return Result; 123de3ef502SDouglas Gregor } 124de3ef502SDouglas Gregor 12573141fa9SDouglas Gregor const DirectoryEntry *Module::getUmbrellaDir() const { 12673141fa9SDouglas Gregor if (const FileEntry *Header = getUmbrellaHeader()) 12773141fa9SDouglas Gregor return Header->getDir(); 12873141fa9SDouglas Gregor 12973141fa9SDouglas Gregor return Umbrella.dyn_cast<const DirectoryEntry *>(); 13073141fa9SDouglas Gregor } 13173141fa9SDouglas Gregor 13289929282SDouglas Gregor void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts, 13389929282SDouglas Gregor const TargetInfo &Target) { 1341fb5c3a6SDouglas Gregor Requires.push_back(Feature); 1351fb5c3a6SDouglas Gregor 1361fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 13789929282SDouglas Gregor if (hasFeature(Feature, LangOpts, Target)) 1381fb5c3a6SDouglas Gregor return; 1391fb5c3a6SDouglas Gregor 1401fb5c3a6SDouglas Gregor if (!IsAvailable) 1411fb5c3a6SDouglas Gregor return; 1421fb5c3a6SDouglas Gregor 143f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 1441fb5c3a6SDouglas Gregor Stack.push_back(this); 1451fb5c3a6SDouglas Gregor while (!Stack.empty()) { 1461fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 1471fb5c3a6SDouglas Gregor Stack.pop_back(); 1481fb5c3a6SDouglas Gregor 1491fb5c3a6SDouglas Gregor if (!Current->IsAvailable) 1501fb5c3a6SDouglas Gregor continue; 1511fb5c3a6SDouglas Gregor 1521fb5c3a6SDouglas Gregor Current->IsAvailable = false; 153eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 154eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 1551fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 156eb90e830SDouglas Gregor if ((*Sub)->IsAvailable) 157eb90e830SDouglas Gregor Stack.push_back(*Sub); 1581fb5c3a6SDouglas Gregor } 1591fb5c3a6SDouglas Gregor } 1601fb5c3a6SDouglas Gregor } 1611fb5c3a6SDouglas Gregor 162eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 163eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 164eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 165eb90e830SDouglas Gregor return 0; 166eb90e830SDouglas Gregor 167eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 168eb90e830SDouglas Gregor } 169eb90e830SDouglas Gregor 170f857950dSDmitri Gribenko static void printModuleId(raw_ostream &OS, const ModuleId &Id) { 17124bb923aSDouglas Gregor for (unsigned I = 0, N = Id.size(); I != N; ++I) { 17224bb923aSDouglas Gregor if (I) 17324bb923aSDouglas Gregor OS << "."; 17424bb923aSDouglas Gregor OS << Id[I].first; 17524bb923aSDouglas Gregor } 17624bb923aSDouglas Gregor } 17724bb923aSDouglas Gregor 178*8739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 179*8739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 180*8739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 181*8739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 182*8739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 183*8739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 184*8739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 185*8739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 186*8739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 187*8739f7b7SArgyrios Kyrtzidis 188*8739f7b7SArgyrios Kyrtzidis continue; 189*8739f7b7SArgyrios Kyrtzidis } 190*8739f7b7SArgyrios Kyrtzidis 191*8739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 192*8739f7b7SArgyrios Kyrtzidis // the given pattern. 193*8739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 194*8739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 195*8739f7b7SArgyrios Kyrtzidis continue; 196*8739f7b7SArgyrios Kyrtzidis 197*8739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 198*8739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 199*8739f7b7SArgyrios Kyrtzidis else { 200*8739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 201*8739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 202*8739f7b7SArgyrios Kyrtzidis } 203*8739f7b7SArgyrios Kyrtzidis } 204*8739f7b7SArgyrios Kyrtzidis 205*8739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 206*8739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 207*8739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 208*8739f7b7SArgyrios Kyrtzidis return; 209*8739f7b7SArgyrios Kyrtzidis 210*8739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 211*8739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 212*8739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 213*8739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 214*8739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 215*8739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 216*8739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 217*8739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 218*8739f7b7SArgyrios Kyrtzidis Acceptable = true; 219*8739f7b7SArgyrios Kyrtzidis break; 220*8739f7b7SArgyrios Kyrtzidis } 221*8739f7b7SArgyrios Kyrtzidis } 222*8739f7b7SArgyrios Kyrtzidis } 223*8739f7b7SArgyrios Kyrtzidis 224*8739f7b7SArgyrios Kyrtzidis if (!Acceptable) 225*8739f7b7SArgyrios Kyrtzidis continue; 226*8739f7b7SArgyrios Kyrtzidis 227*8739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 228*8739f7b7SArgyrios Kyrtzidis } 229*8739f7b7SArgyrios Kyrtzidis } 230*8739f7b7SArgyrios Kyrtzidis 231f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 232de3ef502SDouglas Gregor OS.indent(Indent); 233de3ef502SDouglas Gregor if (IsFramework) 234de3ef502SDouglas Gregor OS << "framework "; 235de3ef502SDouglas Gregor if (IsExplicit) 236de3ef502SDouglas Gregor OS << "explicit "; 237a686e1b0SDouglas Gregor OS << "module " << Name; 238a686e1b0SDouglas Gregor 239a686e1b0SDouglas Gregor if (IsSystem) { 240a686e1b0SDouglas Gregor OS.indent(Indent + 2); 241a686e1b0SDouglas Gregor OS << " [system]"; 242a686e1b0SDouglas Gregor } 243a686e1b0SDouglas Gregor 244a686e1b0SDouglas Gregor OS << " {\n"; 245de3ef502SDouglas Gregor 2461fb5c3a6SDouglas Gregor if (!Requires.empty()) { 2471fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 2481fb5c3a6SDouglas Gregor OS << "requires "; 2491fb5c3a6SDouglas Gregor for (unsigned I = 0, N = Requires.size(); I != N; ++I) { 2501fb5c3a6SDouglas Gregor if (I) 2511fb5c3a6SDouglas Gregor OS << ", "; 2521fb5c3a6SDouglas Gregor OS << Requires[I]; 2531fb5c3a6SDouglas Gregor } 2541fb5c3a6SDouglas Gregor OS << "\n"; 2551fb5c3a6SDouglas Gregor } 2561fb5c3a6SDouglas Gregor 25773141fa9SDouglas Gregor if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) { 258de3ef502SDouglas Gregor OS.indent(Indent + 2); 259322f633cSDouglas Gregor OS << "umbrella header \""; 260de3ef502SDouglas Gregor OS.write_escaped(UmbrellaHeader->getName()); 261de3ef502SDouglas Gregor OS << "\"\n"; 262322f633cSDouglas Gregor } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) { 263322f633cSDouglas Gregor OS.indent(Indent + 2); 264322f633cSDouglas Gregor OS << "umbrella \""; 265322f633cSDouglas Gregor OS.write_escaped(UmbrellaDir->getName()); 266322f633cSDouglas Gregor OS << "\"\n"; 267de3ef502SDouglas Gregor } 268de3ef502SDouglas Gregor 269de3ef502SDouglas Gregor for (unsigned I = 0, N = Headers.size(); I != N; ++I) { 270de3ef502SDouglas Gregor OS.indent(Indent + 2); 271de3ef502SDouglas Gregor OS << "header \""; 272de3ef502SDouglas Gregor OS.write_escaped(Headers[I]->getName()); 273de3ef502SDouglas Gregor OS << "\"\n"; 274de3ef502SDouglas Gregor } 27559527666SDouglas Gregor 27659527666SDouglas Gregor for (unsigned I = 0, N = ExcludedHeaders.size(); I != N; ++I) { 27759527666SDouglas Gregor OS.indent(Indent + 2); 27859527666SDouglas Gregor OS << "exclude header \""; 27959527666SDouglas Gregor OS.write_escaped(ExcludedHeaders[I]->getName()); 28059527666SDouglas Gregor OS << "\"\n"; 28159527666SDouglas Gregor } 282de3ef502SDouglas Gregor 283eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 284de3ef502SDouglas Gregor MI != MIEnd; ++MI) 285eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 286de3ef502SDouglas Gregor 28724bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 28824bb923aSDouglas Gregor OS.indent(Indent + 2); 2898c7c8352SDouglas Gregor OS << "export "; 2908c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 2918c7c8352SDouglas Gregor OS << Restriction->getFullModuleName(); 29224bb923aSDouglas Gregor if (Exports[I].getInt()) 29324bb923aSDouglas Gregor OS << ".*"; 2948c7c8352SDouglas Gregor } else { 2958c7c8352SDouglas Gregor OS << "*"; 2968c7c8352SDouglas Gregor } 29724bb923aSDouglas Gregor OS << "\n"; 29824bb923aSDouglas Gregor } 29924bb923aSDouglas Gregor 30024bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 30124bb923aSDouglas Gregor OS.indent(Indent + 2); 30224bb923aSDouglas Gregor OS << "export "; 30324bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 3048c7c8352SDouglas Gregor if (UnresolvedExports[I].Wildcard) { 3058c7c8352SDouglas Gregor if (UnresolvedExports[I].Id.empty()) 3068c7c8352SDouglas Gregor OS << "*"; 3078c7c8352SDouglas Gregor else 30824bb923aSDouglas Gregor OS << ".*"; 3098c7c8352SDouglas Gregor } 31024bb923aSDouglas Gregor OS << "\n"; 31124bb923aSDouglas Gregor } 31224bb923aSDouglas Gregor 3136ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 3146ddfca91SDouglas Gregor OS.indent(Indent + 2); 3156ddfca91SDouglas Gregor OS << "link "; 3166ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 3176ddfca91SDouglas Gregor OS << "framework "; 3186ddfca91SDouglas Gregor OS << "\""; 3196ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 3206ddfca91SDouglas Gregor OS << "\""; 3216ddfca91SDouglas Gregor } 3226ddfca91SDouglas Gregor 32373441091SDouglas Gregor if (InferSubmodules) { 32473441091SDouglas Gregor OS.indent(Indent + 2); 32573441091SDouglas Gregor if (InferExplicitSubmodules) 32673441091SDouglas Gregor OS << "explicit "; 32773441091SDouglas Gregor OS << "module * {\n"; 32873441091SDouglas Gregor if (InferExportWildcard) { 32973441091SDouglas Gregor OS.indent(Indent + 4); 33073441091SDouglas Gregor OS << "export *\n"; 33173441091SDouglas Gregor } 33273441091SDouglas Gregor OS.indent(Indent + 2); 33373441091SDouglas Gregor OS << "}\n"; 33473441091SDouglas Gregor } 33573441091SDouglas Gregor 336de3ef502SDouglas Gregor OS.indent(Indent); 337de3ef502SDouglas Gregor OS << "}\n"; 338de3ef502SDouglas Gregor } 339de3ef502SDouglas Gregor 340de3ef502SDouglas Gregor void Module::dump() const { 341de3ef502SDouglas Gregor print(llvm::errs()); 342de3ef502SDouglas Gregor } 343de3ef502SDouglas Gregor 344de3ef502SDouglas Gregor 345