Home | History | Annotate | Download | only in IR
      1 //===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file implements LLVMContext, as a wrapper around the opaque
     11 //  class LLVMContextImpl.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "llvm/IR/LLVMContext.h"
     16 #include "LLVMContextImpl.h"
     17 #include "llvm/IR/Constants.h"
     18 #include "llvm/IR/DebugLoc.h"
     19 #include "llvm/IR/DiagnosticInfo.h"
     20 #include "llvm/IR/DiagnosticPrinter.h"
     21 #include "llvm/IR/Instruction.h"
     22 #include "llvm/IR/Metadata.h"
     23 #include "llvm/Support/ManagedStatic.h"
     24 #include "llvm/Support/SourceMgr.h"
     25 #include <cctype>
     26 using namespace llvm;
     27 
     28 static ManagedStatic<LLVMContext> GlobalContext;
     29 
     30 LLVMContext& llvm::getGlobalContext() {
     31   return *GlobalContext;
     32 }
     33 
     34 LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
     35   // Create the fixed metadata kinds. This is done in the same order as the
     36   // MD_* enum values so that they correspond.
     37 
     38   // Create the 'dbg' metadata kind.
     39   unsigned DbgID = getMDKindID("dbg");
     40   assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID;
     41 
     42   // Create the 'tbaa' metadata kind.
     43   unsigned TBAAID = getMDKindID("tbaa");
     44   assert(TBAAID == MD_tbaa && "tbaa kind id drifted"); (void)TBAAID;
     45 
     46   // Create the 'prof' metadata kind.
     47   unsigned ProfID = getMDKindID("prof");
     48   assert(ProfID == MD_prof && "prof kind id drifted"); (void)ProfID;
     49 
     50   // Create the 'fpmath' metadata kind.
     51   unsigned FPAccuracyID = getMDKindID("fpmath");
     52   assert(FPAccuracyID == MD_fpmath && "fpmath kind id drifted");
     53   (void)FPAccuracyID;
     54 
     55   // Create the 'range' metadata kind.
     56   unsigned RangeID = getMDKindID("range");
     57   assert(RangeID == MD_range && "range kind id drifted");
     58   (void)RangeID;
     59 
     60   // Create the 'tbaa.struct' metadata kind.
     61   unsigned TBAAStructID = getMDKindID("tbaa.struct");
     62   assert(TBAAStructID == MD_tbaa_struct && "tbaa.struct kind id drifted");
     63   (void)TBAAStructID;
     64 
     65   // Create the 'invariant.load' metadata kind.
     66   unsigned InvariantLdId = getMDKindID("invariant.load");
     67   assert(InvariantLdId == MD_invariant_load && "invariant.load kind id drifted");
     68   (void)InvariantLdId;
     69 }
     70 LLVMContext::~LLVMContext() { delete pImpl; }
     71 
     72 void LLVMContext::addModule(Module *M) {
     73   pImpl->OwnedModules.insert(M);
     74 }
     75 
     76 void LLVMContext::removeModule(Module *M) {
     77   pImpl->OwnedModules.erase(M);
     78 }
     79 
     80 //===----------------------------------------------------------------------===//
     81 // Recoverable Backend Errors
     82 //===----------------------------------------------------------------------===//
     83 
     84 void LLVMContext::
     85 setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
     86                               void *DiagContext) {
     87   pImpl->InlineAsmDiagHandler = DiagHandler;
     88   pImpl->InlineAsmDiagContext = DiagContext;
     89 }
     90 
     91 /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
     92 /// setInlineAsmDiagnosticHandler.
     93 LLVMContext::InlineAsmDiagHandlerTy
     94 LLVMContext::getInlineAsmDiagnosticHandler() const {
     95   return pImpl->InlineAsmDiagHandler;
     96 }
     97 
     98 /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
     99 /// setInlineAsmDiagnosticHandler.
    100 void *LLVMContext::getInlineAsmDiagnosticContext() const {
    101   return pImpl->InlineAsmDiagContext;
    102 }
    103 
    104 void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler,
    105                                        void *DiagnosticContext) {
    106   pImpl->DiagnosticHandler = DiagnosticHandler;
    107   pImpl->DiagnosticContext = DiagnosticContext;
    108 }
    109 
    110 LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const {
    111   return pImpl->DiagnosticHandler;
    112 }
    113 
    114 void *LLVMContext::getDiagnosticContext() const {
    115   return pImpl->DiagnosticContext;
    116 }
    117 
    118 void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
    119 {
    120   pImpl->YieldCallback = Callback;
    121   pImpl->YieldOpaqueHandle = OpaqueHandle;
    122 }
    123 
    124 void LLVMContext::yield() {
    125   if (pImpl->YieldCallback)
    126     pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);
    127 }
    128 
    129 void LLVMContext::emitError(const Twine &ErrorStr) {
    130   diagnose(DiagnosticInfoInlineAsm(ErrorStr));
    131 }
    132 
    133 void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
    134   assert (I && "Invalid instruction");
    135   diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
    136 }
    137 
    138 void LLVMContext::diagnose(const DiagnosticInfo &DI) {
    139   // If there is a report handler, use it.
    140   if (pImpl->DiagnosticHandler) {
    141     pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext);
    142     return;
    143   }
    144 
    145   // Optimization remarks are selective. They need to check whether the regexp
    146   // pattern, passed via one of the -pass-remarks* flags, matches the name of
    147   // the pass that is emitting the diagnostic. If there is no match, ignore the
    148   // diagnostic and return.
    149   switch (DI.getKind()) {
    150   case llvm::DK_OptimizationRemark:
    151     if (!cast<DiagnosticInfoOptimizationRemark>(DI).isEnabled())
    152       return;
    153     break;
    154   case llvm::DK_OptimizationRemarkMissed:
    155     if (!cast<DiagnosticInfoOptimizationRemarkMissed>(DI).isEnabled())
    156       return;
    157     break;
    158   case llvm::DK_OptimizationRemarkAnalysis:
    159     if (!cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI).isEnabled())
    160       return;
    161     break;
    162   default:
    163     break;
    164   }
    165 
    166   // Otherwise, print the message with a prefix based on the severity.
    167   std::string MsgStorage;
    168   raw_string_ostream Stream(MsgStorage);
    169   DiagnosticPrinterRawOStream DP(Stream);
    170   DI.print(DP);
    171   Stream.flush();
    172   switch (DI.getSeverity()) {
    173   case DS_Error:
    174     errs() << "error: " << MsgStorage << "\n";
    175     exit(1);
    176   case DS_Warning:
    177     errs() << "warning: " << MsgStorage << "\n";
    178     break;
    179   case DS_Remark:
    180     errs() << "remark: " << MsgStorage << "\n";
    181     break;
    182   case DS_Note:
    183     errs() << "note: " << MsgStorage << "\n";
    184     break;
    185   }
    186 }
    187 
    188 void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
    189   diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
    190 }
    191 
    192 //===----------------------------------------------------------------------===//
    193 // Metadata Kind Uniquing
    194 //===----------------------------------------------------------------------===//
    195 
    196 #ifndef NDEBUG
    197 /// isValidName - Return true if Name is a valid custom metadata handler name.
    198 static bool isValidName(StringRef MDName) {
    199   if (MDName.empty())
    200     return false;
    201 
    202   if (!std::isalpha(static_cast<unsigned char>(MDName[0])))
    203     return false;
    204 
    205   for (StringRef::iterator I = MDName.begin() + 1, E = MDName.end(); I != E;
    206        ++I) {
    207     if (!std::isalnum(static_cast<unsigned char>(*I)) && *I != '_' &&
    208         *I != '-' && *I != '.')
    209       return false;
    210   }
    211   return true;
    212 }
    213 #endif
    214 
    215 /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
    216 unsigned LLVMContext::getMDKindID(StringRef Name) const {
    217   assert(isValidName(Name) && "Invalid MDNode name");
    218 
    219   // If this is new, assign it its ID.
    220   return
    221     pImpl->CustomMDKindNames.GetOrCreateValue(
    222       Name, pImpl->CustomMDKindNames.size()).second;
    223 }
    224 
    225 /// getHandlerNames - Populate client supplied smallvector using custome
    226 /// metadata name and ID.
    227 void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
    228   Names.resize(pImpl->CustomMDKindNames.size());
    229   for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
    230        E = pImpl->CustomMDKindNames.end(); I != E; ++I)
    231     Names[I->second] = I->first();
    232 }
    233