LLVM API Documentation
00001 //===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===// 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 implements LLVMContext, as a wrapper around the opaque 00011 // class LLVMContextImpl. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "llvm/IR/LLVMContext.h" 00016 #include "LLVMContextImpl.h" 00017 #include "llvm/IR/Constants.h" 00018 #include "llvm/IR/DebugLoc.h" 00019 #include "llvm/IR/DiagnosticInfo.h" 00020 #include "llvm/IR/DiagnosticPrinter.h" 00021 #include "llvm/IR/Instruction.h" 00022 #include "llvm/IR/Metadata.h" 00023 #include "llvm/Support/ManagedStatic.h" 00024 #include "llvm/Support/SourceMgr.h" 00025 #include <cctype> 00026 using namespace llvm; 00027 00028 static ManagedStatic<LLVMContext> GlobalContext; 00029 00030 LLVMContext& llvm::getGlobalContext() { 00031 return *GlobalContext; 00032 } 00033 00034 LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { 00035 // Create the fixed metadata kinds. This is done in the same order as the 00036 // MD_* enum values so that they correspond. 00037 00038 // Create the 'dbg' metadata kind. 00039 unsigned DbgID = getMDKindID("dbg"); 00040 assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID; 00041 00042 // Create the 'tbaa' metadata kind. 00043 unsigned TBAAID = getMDKindID("tbaa"); 00044 assert(TBAAID == MD_tbaa && "tbaa kind id drifted"); (void)TBAAID; 00045 00046 // Create the 'prof' metadata kind. 00047 unsigned ProfID = getMDKindID("prof"); 00048 assert(ProfID == MD_prof && "prof kind id drifted"); (void)ProfID; 00049 00050 // Create the 'fpmath' metadata kind. 00051 unsigned FPAccuracyID = getMDKindID("fpmath"); 00052 assert(FPAccuracyID == MD_fpmath && "fpmath kind id drifted"); 00053 (void)FPAccuracyID; 00054 00055 // Create the 'range' metadata kind. 00056 unsigned RangeID = getMDKindID("range"); 00057 assert(RangeID == MD_range && "range kind id drifted"); 00058 (void)RangeID; 00059 00060 // Create the 'tbaa.struct' metadata kind. 00061 unsigned TBAAStructID = getMDKindID("tbaa.struct"); 00062 assert(TBAAStructID == MD_tbaa_struct && "tbaa.struct kind id drifted"); 00063 (void)TBAAStructID; 00064 00065 // Create the 'invariant.load' metadata kind. 00066 unsigned InvariantLdId = getMDKindID("invariant.load"); 00067 assert(InvariantLdId == MD_invariant_load && "invariant.load kind id drifted"); 00068 (void)InvariantLdId; 00069 00070 // Create the 'alias.scope' metadata kind. 00071 unsigned AliasScopeID = getMDKindID("alias.scope"); 00072 assert(AliasScopeID == MD_alias_scope && "alias.scope kind id drifted"); 00073 (void)AliasScopeID; 00074 00075 // Create the 'noalias' metadata kind. 00076 unsigned NoAliasID = getMDKindID("noalias"); 00077 assert(NoAliasID == MD_noalias && "noalias kind id drifted"); 00078 (void)NoAliasID; 00079 } 00080 LLVMContext::~LLVMContext() { delete pImpl; } 00081 00082 void LLVMContext::addModule(Module *M) { 00083 pImpl->OwnedModules.insert(M); 00084 } 00085 00086 void LLVMContext::removeModule(Module *M) { 00087 pImpl->OwnedModules.erase(M); 00088 } 00089 00090 //===----------------------------------------------------------------------===// 00091 // Recoverable Backend Errors 00092 //===----------------------------------------------------------------------===// 00093 00094 void LLVMContext:: 00095 setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler, 00096 void *DiagContext) { 00097 pImpl->InlineAsmDiagHandler = DiagHandler; 00098 pImpl->InlineAsmDiagContext = DiagContext; 00099 } 00100 00101 /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by 00102 /// setInlineAsmDiagnosticHandler. 00103 LLVMContext::InlineAsmDiagHandlerTy 00104 LLVMContext::getInlineAsmDiagnosticHandler() const { 00105 return pImpl->InlineAsmDiagHandler; 00106 } 00107 00108 /// getInlineAsmDiagnosticContext - Return the diagnostic context set by 00109 /// setInlineAsmDiagnosticHandler. 00110 void *LLVMContext::getInlineAsmDiagnosticContext() const { 00111 return pImpl->InlineAsmDiagContext; 00112 } 00113 00114 void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler, 00115 void *DiagnosticContext) { 00116 pImpl->DiagnosticHandler = DiagnosticHandler; 00117 pImpl->DiagnosticContext = DiagnosticContext; 00118 } 00119 00120 LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const { 00121 return pImpl->DiagnosticHandler; 00122 } 00123 00124 void *LLVMContext::getDiagnosticContext() const { 00125 return pImpl->DiagnosticContext; 00126 } 00127 00128 void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle) 00129 { 00130 pImpl->YieldCallback = Callback; 00131 pImpl->YieldOpaqueHandle = OpaqueHandle; 00132 } 00133 00134 void LLVMContext::yield() { 00135 if (pImpl->YieldCallback) 00136 pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle); 00137 } 00138 00139 void LLVMContext::emitError(const Twine &ErrorStr) { 00140 diagnose(DiagnosticInfoInlineAsm(ErrorStr)); 00141 } 00142 00143 void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) { 00144 assert (I && "Invalid instruction"); 00145 diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr)); 00146 } 00147 00148 void LLVMContext::diagnose(const DiagnosticInfo &DI) { 00149 // If there is a report handler, use it. 00150 if (pImpl->DiagnosticHandler) { 00151 pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext); 00152 return; 00153 } 00154 00155 // Optimization remarks are selective. They need to check whether the regexp 00156 // pattern, passed via one of the -pass-remarks* flags, matches the name of 00157 // the pass that is emitting the diagnostic. If there is no match, ignore the 00158 // diagnostic and return. 00159 switch (DI.getKind()) { 00160 case llvm::DK_OptimizationRemark: 00161 if (!cast<DiagnosticInfoOptimizationRemark>(DI).isEnabled()) 00162 return; 00163 break; 00164 case llvm::DK_OptimizationRemarkMissed: 00165 if (!cast<DiagnosticInfoOptimizationRemarkMissed>(DI).isEnabled()) 00166 return; 00167 break; 00168 case llvm::DK_OptimizationRemarkAnalysis: 00169 if (!cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI).isEnabled()) 00170 return; 00171 break; 00172 default: 00173 break; 00174 } 00175 00176 // Otherwise, print the message with a prefix based on the severity. 00177 std::string MsgStorage; 00178 raw_string_ostream Stream(MsgStorage); 00179 DiagnosticPrinterRawOStream DP(Stream); 00180 DI.print(DP); 00181 Stream.flush(); 00182 switch (DI.getSeverity()) { 00183 case DS_Error: 00184 errs() << "error: " << MsgStorage << "\n"; 00185 exit(1); 00186 case DS_Warning: 00187 errs() << "warning: " << MsgStorage << "\n"; 00188 break; 00189 case DS_Remark: 00190 errs() << "remark: " << MsgStorage << "\n"; 00191 break; 00192 case DS_Note: 00193 errs() << "note: " << MsgStorage << "\n"; 00194 break; 00195 } 00196 } 00197 00198 void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) { 00199 diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr)); 00200 } 00201 00202 //===----------------------------------------------------------------------===// 00203 // Metadata Kind Uniquing 00204 //===----------------------------------------------------------------------===// 00205 00206 #ifndef NDEBUG 00207 /// isValidName - Return true if Name is a valid custom metadata handler name. 00208 static bool isValidName(StringRef MDName) { 00209 if (MDName.empty()) 00210 return false; 00211 00212 if (!std::isalpha(static_cast<unsigned char>(MDName[0]))) 00213 return false; 00214 00215 for (StringRef::iterator I = MDName.begin() + 1, E = MDName.end(); I != E; 00216 ++I) { 00217 if (!std::isalnum(static_cast<unsigned char>(*I)) && *I != '_' && 00218 *I != '-' && *I != '.') 00219 return false; 00220 } 00221 return true; 00222 } 00223 #endif 00224 00225 /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. 00226 unsigned LLVMContext::getMDKindID(StringRef Name) const { 00227 assert(isValidName(Name) && "Invalid MDNode name"); 00228 00229 // If this is new, assign it its ID. 00230 return 00231 pImpl->CustomMDKindNames.GetOrCreateValue( 00232 Name, pImpl->CustomMDKindNames.size()).second; 00233 } 00234 00235 /// getHandlerNames - Populate client supplied smallvector using custome 00236 /// metadata name and ID. 00237 void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const { 00238 Names.resize(pImpl->CustomMDKindNames.size()); 00239 for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(), 00240 E = pImpl->CustomMDKindNames.end(); I != E; ++I) 00241 Names[I->second] = I->first(); 00242 }