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