#include "llvm/LLVMContext.h"
#include "llvm/Metadata.h"
#include "llvm/Constants.h"
#include "llvm/Instruction.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/SourceMgr.h"
#include "LLVMContextImpl.h"
#include <cctype>
using namespace llvm;
static ManagedStatic<LLVMContext> GlobalContext;
LLVMContext& llvm::getGlobalContext() {
return *GlobalContext;
}
LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
unsigned DbgID = getMDKindID("dbg");
assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID;
unsigned TBAAID = getMDKindID("tbaa");
assert(TBAAID == MD_tbaa && "tbaa kind id drifted"); (void)TBAAID;
unsigned ProfID = getMDKindID("prof");
assert(ProfID == MD_prof && "prof kind id drifted"); (void)ProfID;
}
LLVMContext::~LLVMContext() { delete pImpl; }
void LLVMContext::addModule(Module *M) {
pImpl->OwnedModules.insert(M);
}
void LLVMContext::removeModule(Module *M) {
pImpl->OwnedModules.erase(M);
}
void LLVMContext::
setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
void *DiagContext) {
pImpl->InlineAsmDiagHandler = DiagHandler;
pImpl->InlineAsmDiagContext = DiagContext;
}
LLVMContext::InlineAsmDiagHandlerTy
LLVMContext::getInlineAsmDiagnosticHandler() const {
return pImpl->InlineAsmDiagHandler;
}
void *LLVMContext::getInlineAsmDiagnosticContext() const {
return pImpl->InlineAsmDiagContext;
}
void LLVMContext::emitError(StringRef ErrorStr) {
emitError(0U, ErrorStr);
}
void LLVMContext::emitError(const Instruction *I, StringRef ErrorStr) {
unsigned LocCookie = 0;
if (const MDNode *SrcLoc = I->getMetadata("srcloc")) {
if (SrcLoc->getNumOperands() != 0)
if (const ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0)))
LocCookie = CI->getZExtValue();
}
return emitError(LocCookie, ErrorStr);
}
void LLVMContext::emitError(unsigned LocCookie, StringRef ErrorStr) {
if (pImpl->InlineAsmDiagHandler == 0) {
errs() << "error: " << ErrorStr << "\n";
exit(1);
}
SMDiagnostic Diag("", "error: " + ErrorStr.str());
pImpl->InlineAsmDiagHandler(Diag, pImpl->InlineAsmDiagContext, LocCookie);
}
#ifndef NDEBUG
static bool isValidName(StringRef MDName) {
if (MDName.empty())
return false;
if (!std::isalpha(MDName[0]))
return false;
for (StringRef::iterator I = MDName.begin() + 1, E = MDName.end(); I != E;
++I) {
if (!std::isalnum(*I) && *I != '_' && *I != '-' && *I != '.')
return false;
}
return true;
}
#endif
unsigned LLVMContext::getMDKindID(StringRef Name) const {
assert(isValidName(Name) && "Invalid MDNode name");
return
pImpl->CustomMDKindNames.GetOrCreateValue(
Name, pImpl->CustomMDKindNames.size()).second;
}
void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
Names.resize(pImpl->CustomMDKindNames.size());
for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
E = pImpl->CustomMDKindNames.end(); I != E; ++I)
Names[I->second] = I->first();
}