1//===-- llvm/LLVMContext.h - Class for managing "global" state --*- C++ -*-===//
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 declares LLVMContext, a container of "global" state in LLVM, such
11// as the global type and constant uniquing tables.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_IR_LLVMCONTEXT_H
16#define LLVM_IR_LLVMCONTEXT_H
17
18#include "llvm-c/Core.h"
19#include "llvm/Support/CBindingWrapping.h"
20#include "llvm/Support/Compiler.h"
21
22namespace llvm {
23
24class LLVMContextImpl;
25class StringRef;
26class Twine;
27class Instruction;
28class Module;
29class SMDiagnostic;
30class DiagnosticInfo;
31template <typename T> class SmallVectorImpl;
32class Function;
33class DebugLoc;
34
35/// This is an important class for using LLVM in a threaded context.  It
36/// (opaquely) owns and manages the core "global" data of LLVM's core
37/// infrastructure, including the type and constant uniquing tables.
38/// LLVMContext itself provides no locking guarantees, so you should be careful
39/// to have one context per thread.
40class LLVMContext {
41public:
42  LLVMContextImpl *const pImpl;
43  LLVMContext();
44  ~LLVMContext();
45
46  // Pinned metadata names, which always have the same value.  This is a
47  // compile-time performance optimization, not a correctness optimization.
48  enum {
49    MD_dbg = 0,  // "dbg"
50    MD_tbaa = 1, // "tbaa"
51    MD_prof = 2,  // "prof"
52    MD_fpmath = 3,  // "fpmath"
53    MD_range = 4, // "range"
54    MD_tbaa_struct = 5, // "tbaa.struct"
55    MD_invariant_load = 6 // "invariant.load"
56  };
57
58  /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
59  /// This ID is uniqued across modules in the current LLVMContext.
60  unsigned getMDKindID(StringRef Name) const;
61
62  /// getMDKindNames - Populate client supplied SmallVector with the name for
63  /// custom metadata IDs registered in this LLVMContext.
64  void getMDKindNames(SmallVectorImpl<StringRef> &Result) const;
65
66
67  typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
68                                         unsigned LocCookie);
69
70  /// Defines the type of a diagnostic handler.
71  /// \see LLVMContext::setDiagnosticHandler.
72  /// \see LLVMContext::diagnose.
73  typedef void (*DiagnosticHandlerTy)(const DiagnosticInfo &DI, void *Context);
74
75  /// Defines the type of a yield callback.
76  /// \see LLVMContext::setYieldCallback.
77  typedef void (*YieldCallbackTy)(LLVMContext *Context, void *OpaqueHandle);
78
79  /// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked
80  /// when problems with inline asm are detected by the backend.  The first
81  /// argument is a function pointer and the second is a context pointer that
82  /// gets passed into the DiagHandler.
83  ///
84  /// LLVMContext doesn't take ownership or interpret either of these
85  /// pointers.
86  void setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
87                                     void *DiagContext = nullptr);
88
89  /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
90  /// setInlineAsmDiagnosticHandler.
91  InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const;
92
93  /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
94  /// setInlineAsmDiagnosticHandler.
95  void *getInlineAsmDiagnosticContext() const;
96
97  /// setDiagnosticHandler - This method sets a handler that is invoked
98  /// when the backend needs to report anything to the user.  The first
99  /// argument is a function pointer and the second is a context pointer that
100  /// gets passed into the DiagHandler.
101  ///
102  /// LLVMContext doesn't take ownership or interpret either of these
103  /// pointers.
104  void setDiagnosticHandler(DiagnosticHandlerTy DiagHandler,
105                            void *DiagContext = nullptr);
106
107  /// getDiagnosticHandler - Return the diagnostic handler set by
108  /// setDiagnosticHandler.
109  DiagnosticHandlerTy getDiagnosticHandler() const;
110
111  /// getDiagnosticContext - Return the diagnostic context set by
112  /// setDiagnosticContext.
113  void *getDiagnosticContext() const;
114
115  /// diagnose - Report a message to the currently installed diagnostic handler.
116  /// This function returns, in particular in the case of error reporting
117  /// (DI.Severity == RS_Error), so the caller should leave the compilation
118  /// process in a self-consistent state, even though the generated code
119  /// need not be correct.
120  /// The diagnostic message will be implicitly prefixed with a severity
121  /// keyword according to \p DI.getSeverity(), i.e., "error: "
122  /// for RS_Error, "warning: " for RS_Warning, and "note: " for RS_Note.
123  void diagnose(const DiagnosticInfo &DI);
124
125  /// \brief Registers a yield callback with the given context.
126  ///
127  /// The yield callback function may be called by LLVM to transfer control back
128  /// to the client that invoked the LLVM compilation. This can be used to yield
129  /// control of the thread, or perform periodic work needed by the client.
130  /// There is no guaranteed frequency at which callbacks must occur; in fact,
131  /// the client is not guaranteed to ever receive this callback. It is at the
132  /// sole discretion of LLVM to do so and only if it can guarantee that
133  /// suspending the thread won't block any forward progress in other LLVM
134  /// contexts in the same process.
135  ///
136  /// At a suspend point, the state of the current LLVM context is intentionally
137  /// undefined. No assumptions about it can or should be made. Only LLVM
138  /// context API calls that explicitly state that they can be used during a
139  /// yield callback are allowed to be used. Any other API calls into the
140  /// context are not supported until the yield callback function returns
141  /// control to LLVM. Other LLVM contexts are unaffected by this restriction.
142  void setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle);
143
144  /// \brief Calls the yield callback (if applicable).
145  ///
146  /// This transfers control of the current thread back to the client, which may
147  /// suspend the current thread. Only call this method when LLVM doesn't hold
148  /// any global mutex or cannot block the execution in another LLVM context.
149  void yield();
150
151  /// emitError - Emit an error message to the currently installed error handler
152  /// with optional location information.  This function returns, so code should
153  /// be prepared to drop the erroneous construct on the floor and "not crash".
154  /// The generated code need not be correct.  The error message will be
155  /// implicitly prefixed with "error: " and should not end with a ".".
156  void emitError(unsigned LocCookie, const Twine &ErrorStr);
157  void emitError(const Instruction *I, const Twine &ErrorStr);
158  void emitError(const Twine &ErrorStr);
159
160private:
161  LLVMContext(LLVMContext&) LLVM_DELETED_FUNCTION;
162  void operator=(LLVMContext&) LLVM_DELETED_FUNCTION;
163
164  /// addModule - Register a module as being instantiated in this context.  If
165  /// the context is deleted, the module will be deleted as well.
166  void addModule(Module*);
167
168  /// removeModule - Unregister a module from this context.
169  void removeModule(Module*);
170
171  // Module needs access to the add/removeModule methods.
172  friend class Module;
173};
174
175/// getGlobalContext - Returns a global context.  This is for LLVM clients that
176/// only care about operating on a single thread.
177extern LLVMContext &getGlobalContext();
178
179// Create wrappers for C Binding types (see CBindingWrapping.h).
180DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef)
181
182/* Specialized opaque context conversions.
183 */
184inline LLVMContext **unwrap(LLVMContextRef* Tys) {
185  return reinterpret_cast<LLVMContext**>(Tys);
186}
187
188inline LLVMContextRef *wrap(const LLVMContext **Tys) {
189  return reinterpret_cast<LLVMContextRef*>(const_cast<LLVMContext**>(Tys));
190}
191
192}
193
194#endif
195