1de3ef502SDouglas Gregor //===--- Module.h - Describe a module ---------------------------*- C++ -*-===// 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" 16de3ef502SDouglas Gregor #include "llvm/Support/raw_ostream.h" 17de3ef502SDouglas Gregor using namespace clang; 18de3ef502SDouglas Gregor 19de3ef502SDouglas Gregor Module::~Module() { 20de3ef502SDouglas Gregor for (llvm::StringMap<Module *>::iterator I = SubModules.begin(), 21de3ef502SDouglas Gregor IEnd = SubModules.end(); 22de3ef502SDouglas Gregor I != IEnd; ++I) { 23de3ef502SDouglas Gregor delete I->getValue(); 24de3ef502SDouglas Gregor } 25de3ef502SDouglas Gregor 26de3ef502SDouglas Gregor } 27de3ef502SDouglas Gregor 28f5eedd05SDouglas Gregor bool Module::isSubModuleOf(Module *Other) const { 29f5eedd05SDouglas Gregor const Module *This = this; 30f5eedd05SDouglas Gregor do { 31f5eedd05SDouglas Gregor if (This == Other) 32f5eedd05SDouglas Gregor return true; 33f5eedd05SDouglas Gregor 34f5eedd05SDouglas Gregor This = This->Parent; 35f5eedd05SDouglas Gregor } while (This); 36f5eedd05SDouglas Gregor 37f5eedd05SDouglas Gregor return false; 38f5eedd05SDouglas Gregor } 39f5eedd05SDouglas Gregor 4073441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 4173441091SDouglas Gregor const Module *Result = this; 4273441091SDouglas Gregor while (Result->Parent) 4373441091SDouglas Gregor Result = Result->Parent; 4473441091SDouglas Gregor 4573441091SDouglas Gregor return Result; 4673441091SDouglas Gregor } 4773441091SDouglas Gregor 48de3ef502SDouglas Gregor std::string Module::getFullModuleName() const { 49de3ef502SDouglas Gregor llvm::SmallVector<StringRef, 2> Names; 50de3ef502SDouglas Gregor 51de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 52de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 53de3ef502SDouglas Gregor Names.push_back(M->Name); 54de3ef502SDouglas Gregor 55de3ef502SDouglas Gregor std::string Result; 56de3ef502SDouglas Gregor for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), 57de3ef502SDouglas Gregor IEnd = Names.rend(); 58de3ef502SDouglas Gregor I != IEnd; ++I) { 59de3ef502SDouglas Gregor if (!Result.empty()) 60de3ef502SDouglas Gregor Result += '.'; 61de3ef502SDouglas Gregor 62de3ef502SDouglas Gregor Result += *I; 63de3ef502SDouglas Gregor } 64de3ef502SDouglas Gregor 65de3ef502SDouglas Gregor return Result; 66de3ef502SDouglas Gregor } 67de3ef502SDouglas Gregor 6873141fa9SDouglas Gregor const DirectoryEntry *Module::getUmbrellaDir() const { 6973141fa9SDouglas Gregor if (const FileEntry *Header = getUmbrellaHeader()) 7073141fa9SDouglas Gregor return Header->getDir(); 7173141fa9SDouglas Gregor 7273141fa9SDouglas Gregor return Umbrella.dyn_cast<const DirectoryEntry *>(); 7373141fa9SDouglas Gregor } 7473141fa9SDouglas Gregor 7524bb923aSDouglas Gregor static void printModuleId(llvm::raw_ostream &OS, const ModuleId &Id) { 7624bb923aSDouglas Gregor for (unsigned I = 0, N = Id.size(); I != N; ++I) { 7724bb923aSDouglas Gregor if (I) 7824bb923aSDouglas Gregor OS << "."; 7924bb923aSDouglas Gregor OS << Id[I].first; 8024bb923aSDouglas Gregor } 8124bb923aSDouglas Gregor } 8224bb923aSDouglas Gregor 83de3ef502SDouglas Gregor void Module::print(llvm::raw_ostream &OS, unsigned Indent) const { 84de3ef502SDouglas Gregor OS.indent(Indent); 85de3ef502SDouglas Gregor if (IsFramework) 86de3ef502SDouglas Gregor OS << "framework "; 87de3ef502SDouglas Gregor if (IsExplicit) 88de3ef502SDouglas Gregor OS << "explicit "; 89de3ef502SDouglas Gregor OS << "module " << Name << " {\n"; 90de3ef502SDouglas Gregor 9173141fa9SDouglas Gregor if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) { 92de3ef502SDouglas Gregor OS.indent(Indent + 2); 93*322f633cSDouglas Gregor OS << "umbrella header \""; 94de3ef502SDouglas Gregor OS.write_escaped(UmbrellaHeader->getName()); 95de3ef502SDouglas Gregor OS << "\"\n"; 96*322f633cSDouglas Gregor } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) { 97*322f633cSDouglas Gregor OS.indent(Indent + 2); 98*322f633cSDouglas Gregor OS << "umbrella \""; 99*322f633cSDouglas Gregor OS.write_escaped(UmbrellaDir->getName()); 100*322f633cSDouglas Gregor OS << "\"\n"; 101de3ef502SDouglas Gregor } 102de3ef502SDouglas Gregor 103de3ef502SDouglas Gregor for (unsigned I = 0, N = Headers.size(); I != N; ++I) { 104de3ef502SDouglas Gregor OS.indent(Indent + 2); 105de3ef502SDouglas Gregor OS << "header \""; 106de3ef502SDouglas Gregor OS.write_escaped(Headers[I]->getName()); 107de3ef502SDouglas Gregor OS << "\"\n"; 108de3ef502SDouglas Gregor } 109de3ef502SDouglas Gregor 110de3ef502SDouglas Gregor for (llvm::StringMap<Module *>::const_iterator MI = SubModules.begin(), 111de3ef502SDouglas Gregor MIEnd = SubModules.end(); 112de3ef502SDouglas Gregor MI != MIEnd; ++MI) 113de3ef502SDouglas Gregor MI->getValue()->print(OS, Indent + 2); 114de3ef502SDouglas Gregor 11524bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 11624bb923aSDouglas Gregor OS.indent(Indent + 2); 1178c7c8352SDouglas Gregor OS << "export "; 1188c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 1198c7c8352SDouglas Gregor OS << Restriction->getFullModuleName(); 12024bb923aSDouglas Gregor if (Exports[I].getInt()) 12124bb923aSDouglas Gregor OS << ".*"; 1228c7c8352SDouglas Gregor } else { 1238c7c8352SDouglas Gregor OS << "*"; 1248c7c8352SDouglas Gregor } 12524bb923aSDouglas Gregor OS << "\n"; 12624bb923aSDouglas Gregor } 12724bb923aSDouglas Gregor 12824bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 12924bb923aSDouglas Gregor OS.indent(Indent + 2); 13024bb923aSDouglas Gregor OS << "export "; 13124bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 1328c7c8352SDouglas Gregor if (UnresolvedExports[I].Wildcard) { 1338c7c8352SDouglas Gregor if (UnresolvedExports[I].Id.empty()) 1348c7c8352SDouglas Gregor OS << "*"; 1358c7c8352SDouglas Gregor else 13624bb923aSDouglas Gregor OS << ".*"; 1378c7c8352SDouglas Gregor } 13824bb923aSDouglas Gregor OS << "\n"; 13924bb923aSDouglas Gregor } 14024bb923aSDouglas Gregor 14173441091SDouglas Gregor if (InferSubmodules) { 14273441091SDouglas Gregor OS.indent(Indent + 2); 14373441091SDouglas Gregor if (InferExplicitSubmodules) 14473441091SDouglas Gregor OS << "explicit "; 14573441091SDouglas Gregor OS << "module * {\n"; 14673441091SDouglas Gregor if (InferExportWildcard) { 14773441091SDouglas Gregor OS.indent(Indent + 4); 14873441091SDouglas Gregor OS << "export *\n"; 14973441091SDouglas Gregor } 15073441091SDouglas Gregor OS.indent(Indent + 2); 15173441091SDouglas Gregor OS << "}\n"; 15273441091SDouglas Gregor } 15373441091SDouglas Gregor 154de3ef502SDouglas Gregor OS.indent(Indent); 155de3ef502SDouglas Gregor OS << "}\n"; 156de3ef502SDouglas Gregor } 157de3ef502SDouglas Gregor 158de3ef502SDouglas Gregor void Module::dump() const { 159de3ef502SDouglas Gregor print(llvm::errs()); 160de3ef502SDouglas Gregor } 161de3ef502SDouglas Gregor 162de3ef502SDouglas Gregor 163