1ef860a24SChandler Carruth //===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===//
2ef860a24SChandler Carruth //
3ef860a24SChandler Carruth //                     The LLVM Compiler Infrastructure
4ef860a24SChandler Carruth //
5ef860a24SChandler Carruth // This file is distributed under the University of Illinois Open Source
6ef860a24SChandler Carruth // License. See LICENSE.TXT for details.
7ef860a24SChandler Carruth //
8ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
9ef860a24SChandler Carruth //
10ef860a24SChandler Carruth //  This file implements LLVMContext, as a wrapper around the opaque
11ef860a24SChandler Carruth //  class LLVMContextImpl.
12ef860a24SChandler Carruth //
13ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
14ef860a24SChandler Carruth 
159fb823bbSChandler Carruth #include "llvm/IR/LLVMContext.h"
16ef860a24SChandler Carruth #include "LLVMContextImpl.h"
179fb823bbSChandler Carruth #include "llvm/IR/Constants.h"
189fb823bbSChandler Carruth #include "llvm/IR/Instruction.h"
199fb823bbSChandler Carruth #include "llvm/IR/Metadata.h"
20ef860a24SChandler Carruth #include "llvm/Support/ManagedStatic.h"
21ef860a24SChandler Carruth #include "llvm/Support/SourceMgr.h"
22ef860a24SChandler Carruth #include <cctype>
23ef860a24SChandler Carruth using namespace llvm;
24ef860a24SChandler Carruth 
25ef860a24SChandler Carruth static ManagedStatic<LLVMContext> GlobalContext;
26ef860a24SChandler Carruth 
27ef860a24SChandler Carruth LLVMContext& llvm::getGlobalContext() {
28ef860a24SChandler Carruth   return *GlobalContext;
29ef860a24SChandler Carruth }
30ef860a24SChandler Carruth 
31ef860a24SChandler Carruth LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
32ef860a24SChandler Carruth   // Create the fixed metadata kinds. This is done in the same order as the
33ef860a24SChandler Carruth   // MD_* enum values so that they correspond.
34ef860a24SChandler Carruth 
35ef860a24SChandler Carruth   // Create the 'dbg' metadata kind.
36ef860a24SChandler Carruth   unsigned DbgID = getMDKindID("dbg");
37ef860a24SChandler Carruth   assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID;
38ef860a24SChandler Carruth 
39ef860a24SChandler Carruth   // Create the 'tbaa' metadata kind.
40ef860a24SChandler Carruth   unsigned TBAAID = getMDKindID("tbaa");
41ef860a24SChandler Carruth   assert(TBAAID == MD_tbaa && "tbaa kind id drifted"); (void)TBAAID;
42ef860a24SChandler Carruth 
43ef860a24SChandler Carruth   // Create the 'prof' metadata kind.
44ef860a24SChandler Carruth   unsigned ProfID = getMDKindID("prof");
45ef860a24SChandler Carruth   assert(ProfID == MD_prof && "prof kind id drifted"); (void)ProfID;
46ef860a24SChandler Carruth 
47ef860a24SChandler Carruth   // Create the 'fpmath' metadata kind.
48ef860a24SChandler Carruth   unsigned FPAccuracyID = getMDKindID("fpmath");
49ef860a24SChandler Carruth   assert(FPAccuracyID == MD_fpmath && "fpmath kind id drifted");
50ef860a24SChandler Carruth   (void)FPAccuracyID;
51ef860a24SChandler Carruth 
52ef860a24SChandler Carruth   // Create the 'range' metadata kind.
53ef860a24SChandler Carruth   unsigned RangeID = getMDKindID("range");
54ef860a24SChandler Carruth   assert(RangeID == MD_range && "range kind id drifted");
55ef860a24SChandler Carruth   (void)RangeID;
56ef860a24SChandler Carruth 
57ef860a24SChandler Carruth   // Create the 'tbaa.struct' metadata kind.
58ef860a24SChandler Carruth   unsigned TBAAStructID = getMDKindID("tbaa.struct");
59ef860a24SChandler Carruth   assert(TBAAStructID == MD_tbaa_struct && "tbaa.struct kind id drifted");
60ef860a24SChandler Carruth   (void)TBAAStructID;
61ef860a24SChandler Carruth }
62ef860a24SChandler Carruth LLVMContext::~LLVMContext() { delete pImpl; }
63ef860a24SChandler Carruth 
64ef860a24SChandler Carruth void LLVMContext::addModule(Module *M) {
65ef860a24SChandler Carruth   pImpl->OwnedModules.insert(M);
66ef860a24SChandler Carruth }
67ef860a24SChandler Carruth 
68ef860a24SChandler Carruth void LLVMContext::removeModule(Module *M) {
69ef860a24SChandler Carruth   pImpl->OwnedModules.erase(M);
70ef860a24SChandler Carruth }
71ef860a24SChandler Carruth 
72ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
73ef860a24SChandler Carruth // Recoverable Backend Errors
74ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
75ef860a24SChandler Carruth 
76a594fab4SBob Wilson void LLVMContext::
77a594fab4SBob Wilson setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
78ef860a24SChandler Carruth                               void *DiagContext) {
79a594fab4SBob Wilson   pImpl->InlineAsmDiagHandler = DiagHandler;
80a594fab4SBob Wilson   pImpl->InlineAsmDiagContext = DiagContext;
81ef860a24SChandler Carruth }
82ef860a24SChandler Carruth 
83a594fab4SBob Wilson /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
84a594fab4SBob Wilson /// setInlineAsmDiagnosticHandler.
85a594fab4SBob Wilson LLVMContext::InlineAsmDiagHandlerTy
86a594fab4SBob Wilson LLVMContext::getInlineAsmDiagnosticHandler() const {
87a594fab4SBob Wilson   return pImpl->InlineAsmDiagHandler;
88ef860a24SChandler Carruth }
89ef860a24SChandler Carruth 
90a594fab4SBob Wilson /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
91a594fab4SBob Wilson /// setInlineAsmDiagnosticHandler.
92a594fab4SBob Wilson void *LLVMContext::getInlineAsmDiagnosticContext() const {
93a594fab4SBob Wilson   return pImpl->InlineAsmDiagContext;
94ef860a24SChandler Carruth }
95ef860a24SChandler Carruth 
96ef860a24SChandler Carruth void LLVMContext::emitError(const Twine &ErrorStr) {
97ef860a24SChandler Carruth   emitError(0U, ErrorStr);
98ef860a24SChandler Carruth }
99ef860a24SChandler Carruth 
100bfb44ef9SBob Wilson void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
101ef860a24SChandler Carruth   unsigned LocCookie = 0;
102ef860a24SChandler Carruth   if (const MDNode *SrcLoc = I->getMetadata("srcloc")) {
103ef860a24SChandler Carruth     if (SrcLoc->getNumOperands() != 0)
104ef860a24SChandler Carruth       if (const ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0)))
105ef860a24SChandler Carruth         LocCookie = CI->getZExtValue();
106ef860a24SChandler Carruth   }
107ef860a24SChandler Carruth   return emitError(LocCookie, ErrorStr);
108ef860a24SChandler Carruth }
109ef860a24SChandler Carruth 
110ef860a24SChandler Carruth void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
111ef860a24SChandler Carruth   // If there is no error handler installed, just print the error and exit.
112a594fab4SBob Wilson   if (pImpl->InlineAsmDiagHandler == 0) {
113ef860a24SChandler Carruth     errs() << "error: " << ErrorStr << "\n";
114ef860a24SChandler Carruth     exit(1);
115ef860a24SChandler Carruth   }
116ef860a24SChandler Carruth 
117ef860a24SChandler Carruth   // If we do have an error handler, we can report the error and keep going.
118ef860a24SChandler Carruth   SMDiagnostic Diag("", SourceMgr::DK_Error, ErrorStr.str());
119ef860a24SChandler Carruth 
120a594fab4SBob Wilson   pImpl->InlineAsmDiagHandler(Diag, pImpl->InlineAsmDiagContext, LocCookie);
121ef860a24SChandler Carruth }
122ef860a24SChandler Carruth 
123ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
124ef860a24SChandler Carruth // Metadata Kind Uniquing
125ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
126ef860a24SChandler Carruth 
127ef860a24SChandler Carruth #ifndef NDEBUG
128ef860a24SChandler Carruth /// isValidName - Return true if Name is a valid custom metadata handler name.
129ef860a24SChandler Carruth static bool isValidName(StringRef MDName) {
130ef860a24SChandler Carruth   if (MDName.empty())
131ef860a24SChandler Carruth     return false;
132ef860a24SChandler Carruth 
133*83c74e9fSGuy Benyei   if (!std::isalpha(static_cast<unsigned char>(MDName[0])))
134ef860a24SChandler Carruth     return false;
135ef860a24SChandler Carruth 
136ef860a24SChandler Carruth   for (StringRef::iterator I = MDName.begin() + 1, E = MDName.end(); I != E;
137ef860a24SChandler Carruth        ++I) {
138*83c74e9fSGuy Benyei     if (!std::isalnum(static_cast<unsigned char>(*I)) && *I != '_' &&
139*83c74e9fSGuy Benyei         *I != '-' && *I != '.')
140ef860a24SChandler Carruth       return false;
141ef860a24SChandler Carruth   }
142ef860a24SChandler Carruth   return true;
143ef860a24SChandler Carruth }
144ef860a24SChandler Carruth #endif
145ef860a24SChandler Carruth 
146ef860a24SChandler Carruth /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
147ef860a24SChandler Carruth unsigned LLVMContext::getMDKindID(StringRef Name) const {
148ef860a24SChandler Carruth   assert(isValidName(Name) && "Invalid MDNode name");
149ef860a24SChandler Carruth 
150ef860a24SChandler Carruth   // If this is new, assign it its ID.
151ef860a24SChandler Carruth   return
152ef860a24SChandler Carruth     pImpl->CustomMDKindNames.GetOrCreateValue(
153ef860a24SChandler Carruth       Name, pImpl->CustomMDKindNames.size()).second;
154ef860a24SChandler Carruth }
155ef860a24SChandler Carruth 
156ef860a24SChandler Carruth /// getHandlerNames - Populate client supplied smallvector using custome
157ef860a24SChandler Carruth /// metadata name and ID.
158ef860a24SChandler Carruth void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
159ef860a24SChandler Carruth   Names.resize(pImpl->CustomMDKindNames.size());
160ef860a24SChandler Carruth   for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
161ef860a24SChandler Carruth        E = pImpl->CustomMDKindNames.end(); I != E; ++I)
162ef860a24SChandler Carruth     Names[I->second] = I->first();
163ef860a24SChandler Carruth }
164