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 28de3ef502SDouglas Gregor std::string Module::getFullModuleName() const { 29de3ef502SDouglas Gregor llvm::SmallVector<StringRef, 2> Names; 30de3ef502SDouglas Gregor 31de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 32de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 33de3ef502SDouglas Gregor Names.push_back(M->Name); 34de3ef502SDouglas Gregor 35de3ef502SDouglas Gregor std::string Result; 36de3ef502SDouglas Gregor for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), 37de3ef502SDouglas Gregor IEnd = Names.rend(); 38de3ef502SDouglas Gregor I != IEnd; ++I) { 39de3ef502SDouglas Gregor if (!Result.empty()) 40de3ef502SDouglas Gregor Result += '.'; 41de3ef502SDouglas Gregor 42de3ef502SDouglas Gregor Result += *I; 43de3ef502SDouglas Gregor } 44de3ef502SDouglas Gregor 45de3ef502SDouglas Gregor return Result; 46de3ef502SDouglas Gregor } 47de3ef502SDouglas Gregor 48de3ef502SDouglas Gregor StringRef Module::getTopLevelModuleName() const { 49de3ef502SDouglas Gregor const Module *Top = this; 50de3ef502SDouglas Gregor while (Top->Parent) 51de3ef502SDouglas Gregor Top = Top->Parent; 52de3ef502SDouglas Gregor 53de3ef502SDouglas Gregor return Top->Name; 54de3ef502SDouglas Gregor } 55de3ef502SDouglas Gregor 56*24bb923aSDouglas Gregor static void printModuleId(llvm::raw_ostream &OS, const ModuleId &Id) { 57*24bb923aSDouglas Gregor for (unsigned I = 0, N = Id.size(); I != N; ++I) { 58*24bb923aSDouglas Gregor if (I) 59*24bb923aSDouglas Gregor OS << "."; 60*24bb923aSDouglas Gregor OS << Id[I].first; 61*24bb923aSDouglas Gregor } 62*24bb923aSDouglas Gregor } 63*24bb923aSDouglas Gregor 64de3ef502SDouglas Gregor void Module::print(llvm::raw_ostream &OS, unsigned Indent) const { 65de3ef502SDouglas Gregor OS.indent(Indent); 66de3ef502SDouglas Gregor if (IsFramework) 67de3ef502SDouglas Gregor OS << "framework "; 68de3ef502SDouglas Gregor if (IsExplicit) 69de3ef502SDouglas Gregor OS << "explicit "; 70de3ef502SDouglas Gregor OS << "module " << Name << " {\n"; 71de3ef502SDouglas Gregor 72de3ef502SDouglas Gregor if (UmbrellaHeader) { 73de3ef502SDouglas Gregor OS.indent(Indent + 2); 74de3ef502SDouglas Gregor OS << "umbrella \""; 75de3ef502SDouglas Gregor OS.write_escaped(UmbrellaHeader->getName()); 76de3ef502SDouglas Gregor OS << "\"\n"; 77de3ef502SDouglas Gregor } 78de3ef502SDouglas Gregor 79de3ef502SDouglas Gregor for (unsigned I = 0, N = Headers.size(); I != N; ++I) { 80de3ef502SDouglas Gregor OS.indent(Indent + 2); 81de3ef502SDouglas Gregor OS << "header \""; 82de3ef502SDouglas Gregor OS.write_escaped(Headers[I]->getName()); 83de3ef502SDouglas Gregor OS << "\"\n"; 84de3ef502SDouglas Gregor } 85de3ef502SDouglas Gregor 86de3ef502SDouglas Gregor for (llvm::StringMap<Module *>::const_iterator MI = SubModules.begin(), 87de3ef502SDouglas Gregor MIEnd = SubModules.end(); 88de3ef502SDouglas Gregor MI != MIEnd; ++MI) 89de3ef502SDouglas Gregor MI->getValue()->print(OS, Indent + 2); 90de3ef502SDouglas Gregor 91*24bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 92*24bb923aSDouglas Gregor OS.indent(Indent + 2); 93*24bb923aSDouglas Gregor OS << "export " << Exports[I].getPointer()->getFullModuleName(); 94*24bb923aSDouglas Gregor if (Exports[I].getInt()) 95*24bb923aSDouglas Gregor OS << ".*"; 96*24bb923aSDouglas Gregor OS << "\n"; 97*24bb923aSDouglas Gregor } 98*24bb923aSDouglas Gregor 99*24bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 100*24bb923aSDouglas Gregor OS.indent(Indent + 2); 101*24bb923aSDouglas Gregor OS << "export "; 102*24bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 103*24bb923aSDouglas Gregor if (UnresolvedExports[I].Wildcard) 104*24bb923aSDouglas Gregor OS << ".*"; 105*24bb923aSDouglas Gregor OS << "\n"; 106*24bb923aSDouglas Gregor } 107*24bb923aSDouglas Gregor 108de3ef502SDouglas Gregor OS.indent(Indent); 109de3ef502SDouglas Gregor OS << "}\n"; 110de3ef502SDouglas Gregor } 111de3ef502SDouglas Gregor 112de3ef502SDouglas Gregor void Module::dump() const { 113de3ef502SDouglas Gregor print(llvm::errs()); 114de3ef502SDouglas Gregor } 115de3ef502SDouglas Gregor 116de3ef502SDouglas Gregor 117