LLVMContext.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
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>
26using namespace llvm;
27
28static ManagedStatic<LLVMContext> GlobalContext;
29
30LLVMContext& llvm::getGlobalContext() {
31  return *GlobalContext;
32}
33
34LLVMContext::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}
70LLVMContext::~LLVMContext() { delete pImpl; }
71
72void LLVMContext::addModule(Module *M) {
73  pImpl->OwnedModules.insert(M);
74}
75
76void LLVMContext::removeModule(Module *M) {
77  pImpl->OwnedModules.erase(M);
78}
79
80//===----------------------------------------------------------------------===//
81// Recoverable Backend Errors
82//===----------------------------------------------------------------------===//
83
84void LLVMContext::
85setInlineAsmDiagnosticHandler(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.
93LLVMContext::InlineAsmDiagHandlerTy
94LLVMContext::getInlineAsmDiagnosticHandler() const {
95  return pImpl->InlineAsmDiagHandler;
96}
97
98/// getInlineAsmDiagnosticContext - Return the diagnostic context set by
99/// setInlineAsmDiagnosticHandler.
100void *LLVMContext::getInlineAsmDiagnosticContext() const {
101  return pImpl->InlineAsmDiagContext;
102}
103
104void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler,
105                                       void *DiagnosticContext) {
106  pImpl->DiagnosticHandler = DiagnosticHandler;
107  pImpl->DiagnosticContext = DiagnosticContext;
108}
109
110LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const {
111  return pImpl->DiagnosticHandler;
112}
113
114void *LLVMContext::getDiagnosticContext() const {
115  return pImpl->DiagnosticContext;
116}
117
118void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
119{
120  pImpl->YieldCallback = Callback;
121  pImpl->YieldOpaqueHandle = OpaqueHandle;
122}
123
124void LLVMContext::yield() {
125  if (pImpl->YieldCallback)
126    pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);
127}
128
129void LLVMContext::emitError(const Twine &ErrorStr) {
130  diagnose(DiagnosticInfoInlineAsm(ErrorStr));
131}
132
133void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
134  assert (I && "Invalid instruction");
135  diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
136}
137
138void 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
188void 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.
198static 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.
216unsigned 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.
227void 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