clang API Documentation
00001 //===--- Module.h - Describe a module ---------------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the Module class, which describes a module in the source 00011 // code. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 #include "clang/Basic/Module.h" 00015 #include "clang/Basic/FileManager.h" 00016 #include "clang/Basic/LangOptions.h" 00017 #include "clang/Basic/TargetInfo.h" 00018 #include "llvm/Support/ErrorHandling.h" 00019 #include "llvm/Support/raw_ostream.h" 00020 #include "llvm/ADT/SmallVector.h" 00021 #include "llvm/ADT/StringSwitch.h" 00022 using namespace clang; 00023 00024 Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 00025 bool IsFramework, bool IsExplicit) 00026 : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), 00027 Umbrella(), IsAvailable(true), IsFromModuleFile(false), 00028 IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), 00029 InferSubmodules(false), InferExplicitSubmodules(false), 00030 InferExportWildcard(false), NameVisibility(Hidden) 00031 { 00032 if (Parent) { 00033 if (!Parent->isAvailable()) 00034 IsAvailable = false; 00035 if (Parent->IsSystem) 00036 IsSystem = true; 00037 00038 Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 00039 Parent->SubModules.push_back(this); 00040 } 00041 } 00042 00043 Module::~Module() { 00044 for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 00045 I != IEnd; ++I) { 00046 delete *I; 00047 } 00048 00049 } 00050 00051 /// \brief Determine whether a translation unit built using the current 00052 /// language options has the given feature. 00053 static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 00054 const TargetInfo &Target) { 00055 return llvm::StringSwitch<bool>(Feature) 00056 .Case("altivec", LangOpts.AltiVec) 00057 .Case("blocks", LangOpts.Blocks) 00058 .Case("cplusplus", LangOpts.CPlusPlus) 00059 .Case("cplusplus11", LangOpts.CPlusPlus0x) 00060 .Case("objc", LangOpts.ObjC1) 00061 .Case("objc_arc", LangOpts.ObjCAutoRefCount) 00062 .Case("opencl", LangOpts.OpenCL) 00063 .Case("tls", Target.isTLSSupported()) 00064 .Default(Target.hasFeature(Feature)); 00065 } 00066 00067 bool 00068 Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 00069 StringRef &Feature) const { 00070 if (IsAvailable) 00071 return true; 00072 00073 for (const Module *Current = this; Current; Current = Current->Parent) { 00074 for (unsigned I = 0, N = Current->Requires.size(); I != N; ++I) { 00075 if (!hasFeature(Current->Requires[I], LangOpts, Target)) { 00076 Feature = Current->Requires[I]; 00077 return false; 00078 } 00079 } 00080 } 00081 00082 llvm_unreachable("could not find a reason why module is unavailable"); 00083 } 00084 00085 bool Module::isSubModuleOf(Module *Other) const { 00086 const Module *This = this; 00087 do { 00088 if (This == Other) 00089 return true; 00090 00091 This = This->Parent; 00092 } while (This); 00093 00094 return false; 00095 } 00096 00097 const Module *Module::getTopLevelModule() const { 00098 const Module *Result = this; 00099 while (Result->Parent) 00100 Result = Result->Parent; 00101 00102 return Result; 00103 } 00104 00105 std::string Module::getFullModuleName() const { 00106 llvm::SmallVector<StringRef, 2> Names; 00107 00108 // Build up the set of module names (from innermost to outermost). 00109 for (const Module *M = this; M; M = M->Parent) 00110 Names.push_back(M->Name); 00111 00112 std::string Result; 00113 for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), 00114 IEnd = Names.rend(); 00115 I != IEnd; ++I) { 00116 if (!Result.empty()) 00117 Result += '.'; 00118 00119 Result += *I; 00120 } 00121 00122 return Result; 00123 } 00124 00125 const DirectoryEntry *Module::getUmbrellaDir() const { 00126 if (const FileEntry *Header = getUmbrellaHeader()) 00127 return Header->getDir(); 00128 00129 return Umbrella.dyn_cast<const DirectoryEntry *>(); 00130 } 00131 00132 void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts, 00133 const TargetInfo &Target) { 00134 Requires.push_back(Feature); 00135 00136 // If this feature is currently available, we're done. 00137 if (hasFeature(Feature, LangOpts, Target)) 00138 return; 00139 00140 if (!IsAvailable) 00141 return; 00142 00143 llvm::SmallVector<Module *, 2> Stack; 00144 Stack.push_back(this); 00145 while (!Stack.empty()) { 00146 Module *Current = Stack.back(); 00147 Stack.pop_back(); 00148 00149 if (!Current->IsAvailable) 00150 continue; 00151 00152 Current->IsAvailable = false; 00153 for (submodule_iterator Sub = Current->submodule_begin(), 00154 SubEnd = Current->submodule_end(); 00155 Sub != SubEnd; ++Sub) { 00156 if ((*Sub)->IsAvailable) 00157 Stack.push_back(*Sub); 00158 } 00159 } 00160 } 00161 00162 Module *Module::findSubmodule(StringRef Name) const { 00163 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 00164 if (Pos == SubModuleIndex.end()) 00165 return 0; 00166 00167 return SubModules[Pos->getValue()]; 00168 } 00169 00170 static void printModuleId(llvm::raw_ostream &OS, const ModuleId &Id) { 00171 for (unsigned I = 0, N = Id.size(); I != N; ++I) { 00172 if (I) 00173 OS << "."; 00174 OS << Id[I].first; 00175 } 00176 } 00177 00178 void Module::print(llvm::raw_ostream &OS, unsigned Indent) const { 00179 OS.indent(Indent); 00180 if (IsFramework) 00181 OS << "framework "; 00182 if (IsExplicit) 00183 OS << "explicit "; 00184 OS << "module " << Name; 00185 00186 if (IsSystem) { 00187 OS.indent(Indent + 2); 00188 OS << " [system]"; 00189 } 00190 00191 OS << " {\n"; 00192 00193 if (!Requires.empty()) { 00194 OS.indent(Indent + 2); 00195 OS << "requires "; 00196 for (unsigned I = 0, N = Requires.size(); I != N; ++I) { 00197 if (I) 00198 OS << ", "; 00199 OS << Requires[I]; 00200 } 00201 OS << "\n"; 00202 } 00203 00204 if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) { 00205 OS.indent(Indent + 2); 00206 OS << "umbrella header \""; 00207 OS.write_escaped(UmbrellaHeader->getName()); 00208 OS << "\"\n"; 00209 } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) { 00210 OS.indent(Indent + 2); 00211 OS << "umbrella \""; 00212 OS.write_escaped(UmbrellaDir->getName()); 00213 OS << "\"\n"; 00214 } 00215 00216 for (unsigned I = 0, N = Headers.size(); I != N; ++I) { 00217 OS.indent(Indent + 2); 00218 OS << "header \""; 00219 OS.write_escaped(Headers[I]->getName()); 00220 OS << "\"\n"; 00221 } 00222 00223 for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 00224 MI != MIEnd; ++MI) 00225 (*MI)->print(OS, Indent + 2); 00226 00227 for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 00228 OS.indent(Indent + 2); 00229 OS << "export "; 00230 if (Module *Restriction = Exports[I].getPointer()) { 00231 OS << Restriction->getFullModuleName(); 00232 if (Exports[I].getInt()) 00233 OS << ".*"; 00234 } else { 00235 OS << "*"; 00236 } 00237 OS << "\n"; 00238 } 00239 00240 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 00241 OS.indent(Indent + 2); 00242 OS << "export "; 00243 printModuleId(OS, UnresolvedExports[I].Id); 00244 if (UnresolvedExports[I].Wildcard) { 00245 if (UnresolvedExports[I].Id.empty()) 00246 OS << "*"; 00247 else 00248 OS << ".*"; 00249 } 00250 OS << "\n"; 00251 } 00252 00253 if (InferSubmodules) { 00254 OS.indent(Indent + 2); 00255 if (InferExplicitSubmodules) 00256 OS << "explicit "; 00257 OS << "module * {\n"; 00258 if (InferExportWildcard) { 00259 OS.indent(Indent + 4); 00260 OS << "export *\n"; 00261 } 00262 OS.indent(Indent + 2); 00263 OS << "}\n"; 00264 } 00265 00266 OS.indent(Indent); 00267 OS << "}\n"; 00268 } 00269 00270 void Module::dump() const { 00271 print(llvm::errs()); 00272 } 00273 00274