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 
15*9fb823bbSChandler Carruth #include "llvm/IR/LLVMContext.h"
16ef860a24SChandler Carruth #include "LLVMContextImpl.h"
17*9fb823bbSChandler Carruth #include "llvm/IR/Constants.h"
18*9fb823bbSChandler Carruth #include "llvm/IR/Instruction.h"
19*9fb823bbSChandler 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 
76ef860a24SChandler Carruth void LLVMContext::setDiagnosticHandler(DiagHandlerTy DiagHandler,
77ef860a24SChandler Carruth                                        void *DiagContext) {
78ef860a24SChandler Carruth   pImpl->DiagHandler = DiagHandler;
79ef860a24SChandler Carruth   pImpl->DiagContext = DiagContext;
80ef860a24SChandler Carruth }
81ef860a24SChandler Carruth 
82ef860a24SChandler Carruth /// getDiagnosticHandler - Return the diagnostic handler set by
83ef860a24SChandler Carruth /// setDiagnosticHandler.
84ef860a24SChandler Carruth LLVMContext::DiagHandlerTy LLVMContext::getDiagnosticHandler() const {
85ef860a24SChandler Carruth   return pImpl->DiagHandler;
86ef860a24SChandler Carruth }
87ef860a24SChandler Carruth 
88ef860a24SChandler Carruth /// getDiagnosticContext - Return the diagnostic context set by
89ef860a24SChandler Carruth /// setDiagnosticHandler.
90ef860a24SChandler Carruth void *LLVMContext::getDiagnosticContext() const {
91ef860a24SChandler Carruth   return pImpl->DiagContext;
92ef860a24SChandler Carruth }
93ef860a24SChandler Carruth 
94ef860a24SChandler Carruth void LLVMContext::emitError(const Twine &ErrorStr) {
95ef860a24SChandler Carruth   emitError(0U, ErrorStr);
96ef860a24SChandler Carruth }
97ef860a24SChandler Carruth 
98ef860a24SChandler Carruth void LLVMContext::emitWarning(const Twine &ErrorStr) {
99ef860a24SChandler Carruth   emitWarning(0U, ErrorStr);
100ef860a24SChandler Carruth }
101ef860a24SChandler Carruth 
102ef860a24SChandler Carruth static unsigned getSrcLocation(const Instruction *I) {
103ef860a24SChandler Carruth   unsigned LocCookie = 0;
104ef860a24SChandler Carruth   if (const MDNode *SrcLoc = I->getMetadata("srcloc")) {
105ef860a24SChandler Carruth     if (SrcLoc->getNumOperands() != 0)
106ef860a24SChandler Carruth       if (const ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0)))
107ef860a24SChandler Carruth         LocCookie = CI->getZExtValue();
108ef860a24SChandler Carruth   }
109ef860a24SChandler Carruth   return LocCookie;
110ef860a24SChandler Carruth }
111ef860a24SChandler Carruth 
112ef860a24SChandler Carruth void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
113ef860a24SChandler Carruth   unsigned LocCookie = getSrcLocation(I);
114ef860a24SChandler Carruth   return emitError(LocCookie, ErrorStr);
115ef860a24SChandler Carruth }
116ef860a24SChandler Carruth 
117ef860a24SChandler Carruth void LLVMContext::emitWarning(const Instruction *I, const Twine &ErrorStr) {
118ef860a24SChandler Carruth   unsigned LocCookie = getSrcLocation(I);
119ef860a24SChandler Carruth   return emitWarning(LocCookie, ErrorStr);
120ef860a24SChandler Carruth }
121ef860a24SChandler Carruth 
122ef860a24SChandler Carruth void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
123ef860a24SChandler Carruth   // If there is no error handler installed, just print the error and exit.
124ef860a24SChandler Carruth   if (pImpl->DiagHandler == 0) {
125ef860a24SChandler Carruth     errs() << "error: " << ErrorStr << "\n";
126ef860a24SChandler Carruth     exit(1);
127ef860a24SChandler Carruth   }
128ef860a24SChandler Carruth 
129ef860a24SChandler Carruth   // If we do have an error handler, we can report the error and keep going.
130ef860a24SChandler Carruth   SMDiagnostic Diag("", SourceMgr::DK_Error, ErrorStr.str());
131ef860a24SChandler Carruth 
132ef860a24SChandler Carruth   pImpl->DiagHandler(Diag, pImpl->DiagContext, LocCookie);
133ef860a24SChandler Carruth }
134ef860a24SChandler Carruth 
135ef860a24SChandler Carruth void LLVMContext::emitWarning(unsigned LocCookie, const Twine &ErrorStr) {
136ef860a24SChandler Carruth   // If there is no handler installed, just print the warning.
137ef860a24SChandler Carruth   if (pImpl->DiagHandler == 0) {
138ef860a24SChandler Carruth     errs() << "warning: " << ErrorStr << "\n";
139ef860a24SChandler Carruth     return;
140ef860a24SChandler Carruth   }
141ef860a24SChandler Carruth 
142ef860a24SChandler Carruth   // If we do have a handler, we can report the warning.
143ef860a24SChandler Carruth   SMDiagnostic Diag("", SourceMgr::DK_Warning, ErrorStr.str());
144ef860a24SChandler Carruth 
145ef860a24SChandler Carruth   pImpl->DiagHandler(Diag, pImpl->DiagContext, LocCookie);
146ef860a24SChandler Carruth }
147ef860a24SChandler Carruth 
148ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
149ef860a24SChandler Carruth // Metadata Kind Uniquing
150ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
151ef860a24SChandler Carruth 
152ef860a24SChandler Carruth #ifndef NDEBUG
153ef860a24SChandler Carruth /// isValidName - Return true if Name is a valid custom metadata handler name.
154ef860a24SChandler Carruth static bool isValidName(StringRef MDName) {
155ef860a24SChandler Carruth   if (MDName.empty())
156ef860a24SChandler Carruth     return false;
157ef860a24SChandler Carruth 
158ef860a24SChandler Carruth   if (!std::isalpha(MDName[0]))
159ef860a24SChandler Carruth     return false;
160ef860a24SChandler Carruth 
161ef860a24SChandler Carruth   for (StringRef::iterator I = MDName.begin() + 1, E = MDName.end(); I != E;
162ef860a24SChandler Carruth        ++I) {
163ef860a24SChandler Carruth     if (!std::isalnum(*I) && *I != '_' && *I != '-' && *I != '.')
164ef860a24SChandler Carruth       return false;
165ef860a24SChandler Carruth   }
166ef860a24SChandler Carruth   return true;
167ef860a24SChandler Carruth }
168ef860a24SChandler Carruth #endif
169ef860a24SChandler Carruth 
170ef860a24SChandler Carruth /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
171ef860a24SChandler Carruth unsigned LLVMContext::getMDKindID(StringRef Name) const {
172ef860a24SChandler Carruth   assert(isValidName(Name) && "Invalid MDNode name");
173ef860a24SChandler Carruth 
174ef860a24SChandler Carruth   // If this is new, assign it its ID.
175ef860a24SChandler Carruth   return
176ef860a24SChandler Carruth     pImpl->CustomMDKindNames.GetOrCreateValue(
177ef860a24SChandler Carruth       Name, pImpl->CustomMDKindNames.size()).second;
178ef860a24SChandler Carruth }
179ef860a24SChandler Carruth 
180ef860a24SChandler Carruth /// getHandlerNames - Populate client supplied smallvector using custome
181ef860a24SChandler Carruth /// metadata name and ID.
182ef860a24SChandler Carruth void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
183ef860a24SChandler Carruth   Names.resize(pImpl->CustomMDKindNames.size());
184ef860a24SChandler Carruth   for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
185ef860a24SChandler Carruth        E = pImpl->CustomMDKindNames.end(); I != E; ++I)
186ef860a24SChandler Carruth     Names[I->second] = I->first();
187ef860a24SChandler Carruth }
188