Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
numba
GitHub Repository: numba/llvmlite
Path: blob/main/ffi/module.cpp
1154 views
1
#include "llvm/IR/Module.h"
2
#include "core.h"
3
#include "llvm-c/Analysis.h"
4
#include "llvm-c/Core.h"
5
#include "llvm/IR/TypeFinder.h"
6
#include <clocale>
7
#include <string>
8
9
/* An iterator around a module's globals, including the stop condition */
10
struct GlobalsIterator {
11
typedef llvm::Module::global_iterator iterator;
12
iterator cur;
13
iterator end;
14
15
GlobalsIterator(iterator cur, iterator end) : cur(cur), end(end) {}
16
};
17
18
struct OpaqueGlobalsIterator;
19
typedef OpaqueGlobalsIterator *LLVMGlobalsIteratorRef;
20
21
/* An iterator around a module's functions, including the stop condition */
22
struct FunctionsIterator {
23
typedef llvm::Module::const_iterator const_iterator;
24
const_iterator cur;
25
const_iterator end;
26
27
FunctionsIterator(const_iterator cur, const_iterator end)
28
: cur(cur), end(end) {}
29
};
30
31
struct OpaqueFunctionsIterator;
32
typedef OpaqueFunctionsIterator *LLVMFunctionsIteratorRef;
33
34
/* module types iterator */
35
class TypesIterator {
36
private:
37
llvm::TypeFinder finder;
38
using const_iterator = llvm::TypeFinder::const_iterator;
39
const_iterator cur;
40
41
public:
42
TypesIterator(llvm::Module &m, bool namedOnly)
43
: finder(llvm::TypeFinder()) {
44
finder.run(m, namedOnly);
45
cur = finder.begin();
46
}
47
const llvm::Type *next() {
48
if (cur != finder.end()) {
49
return *cur++;
50
}
51
return nullptr;
52
}
53
};
54
55
typedef TypesIterator *LLVMTypesIteratorRef;
56
57
//
58
// Local helper functions
59
//
60
61
namespace llvm {
62
63
static LLVMGlobalsIteratorRef wrap(GlobalsIterator *GI) {
64
return reinterpret_cast<LLVMGlobalsIteratorRef>(GI);
65
}
66
67
static GlobalsIterator *unwrap(LLVMGlobalsIteratorRef GI) {
68
return reinterpret_cast<GlobalsIterator *>(GI);
69
}
70
71
static LLVMFunctionsIteratorRef wrap(FunctionsIterator *GI) {
72
return reinterpret_cast<LLVMFunctionsIteratorRef>(GI);
73
}
74
75
static FunctionsIterator *unwrap(LLVMFunctionsIteratorRef GI) {
76
return reinterpret_cast<FunctionsIterator *>(GI);
77
}
78
79
static LLVMTypesIteratorRef wrap(TypesIterator *TyI) {
80
return reinterpret_cast<LLVMTypesIteratorRef>(TyI);
81
}
82
83
static TypesIterator *unwrap(LLVMTypesIteratorRef TyI) {
84
return reinterpret_cast<TypesIterator *>(TyI);
85
}
86
87
} // end namespace llvm
88
89
//
90
// Exported API
91
//
92
93
extern "C" {
94
95
API_EXPORT(void)
96
LLVMPY_DisposeModule(LLVMModuleRef m) { return LLVMDisposeModule(m); }
97
98
API_EXPORT(void)
99
LLVMPY_PrintModuleToString(LLVMModuleRef M, const char **outstr) {
100
// Change the locale to en_US before calling LLVM to print the module
101
// due to a LLVM bug https://llvm.org/bugs/show_bug.cgi?id=12906
102
char *old_locale = strdup(setlocale(LC_ALL, NULL));
103
setlocale(LC_ALL, "C");
104
105
*outstr = LLVMPrintModuleToString(M);
106
107
// Revert locale
108
setlocale(LC_ALL, old_locale);
109
free(old_locale);
110
}
111
112
API_EXPORT(const char *)
113
LLVMPY_GetModuleSourceFileName(LLVMModuleRef M) {
114
return llvm::unwrap(M)->getSourceFileName().c_str();
115
}
116
117
API_EXPORT(const char *)
118
LLVMPY_GetModuleName(LLVMModuleRef M) {
119
return llvm::unwrap(M)->getModuleIdentifier().c_str();
120
}
121
122
API_EXPORT(void)
123
LLVMPY_SetModuleName(LLVMModuleRef M, const char *Name) {
124
llvm::unwrap(M)->setModuleIdentifier(Name);
125
}
126
127
API_EXPORT(LLVMValueRef)
128
LLVMPY_GetNamedFunction(LLVMModuleRef M, const char *Name) {
129
return LLVMGetNamedFunction(M, Name);
130
}
131
132
API_EXPORT(LLVMValueRef)
133
LLVMPY_GetNamedGlobalVariable(LLVMModuleRef M, const char *Name) {
134
using namespace llvm;
135
return wrap(unwrap(M)->getGlobalVariable(Name));
136
}
137
138
API_EXPORT(LLVMTypeRef)
139
LLVMPY_GetNamedStructType(LLVMModuleRef M, const char *Name) {
140
return LLVMGetTypeByName(M, Name);
141
}
142
143
API_EXPORT(int)
144
LLVMPY_VerifyModule(LLVMModuleRef M, char **OutMsg) {
145
return LLVMVerifyModule(M, LLVMReturnStatusAction, OutMsg);
146
}
147
148
API_EXPORT(void)
149
LLVMPY_GetDataLayout(LLVMModuleRef M, const char **DL) {
150
*DL = LLVMGetDataLayoutStr(M);
151
}
152
153
API_EXPORT(void)
154
LLVMPY_SetDataLayout(LLVMModuleRef M, const char *DL) {
155
LLVMSetDataLayout(M, DL);
156
}
157
158
API_EXPORT(void)
159
LLVMPY_GetTarget(LLVMModuleRef M, const char **Triple) {
160
*Triple = LLVMGetTarget(M);
161
}
162
163
API_EXPORT(void)
164
LLVMPY_SetTarget(LLVMModuleRef M, const char *Triple) {
165
LLVMSetTarget(M, Triple);
166
}
167
168
// Iteration APIs
169
170
API_EXPORT(LLVMGlobalsIteratorRef)
171
LLVMPY_ModuleGlobalsIter(LLVMModuleRef M) {
172
using namespace llvm;
173
Module *mod = unwrap(M);
174
return wrap(new GlobalsIterator(mod->global_begin(), mod->global_end()));
175
}
176
177
API_EXPORT(LLVMFunctionsIteratorRef)
178
LLVMPY_ModuleFunctionsIter(LLVMModuleRef M) {
179
using namespace llvm;
180
Module *mod = unwrap(M);
181
return wrap(new FunctionsIterator(mod->begin(), mod->end()));
182
}
183
184
API_EXPORT(LLVMTypesIteratorRef)
185
LLVMPY_ModuleTypesIter(LLVMModuleRef M) {
186
llvm::Module *mod = llvm::unwrap(M);
187
auto *iter = new TypesIterator(*mod, false);
188
return llvm::wrap(iter);
189
}
190
191
/*
192
These functions return NULL if we are at the end
193
*/
194
API_EXPORT(LLVMValueRef)
195
LLVMPY_GlobalsIterNext(LLVMGlobalsIteratorRef GI) {
196
using namespace llvm;
197
GlobalsIterator *iter = unwrap(GI);
198
if (iter->cur != iter->end) {
199
return wrap(&*iter->cur++);
200
} else {
201
return NULL;
202
}
203
}
204
205
API_EXPORT(LLVMValueRef)
206
LLVMPY_FunctionsIterNext(LLVMFunctionsIteratorRef GI) {
207
using namespace llvm;
208
FunctionsIterator *iter = unwrap(GI);
209
if (iter->cur != iter->end) {
210
return wrap(&*iter->cur++);
211
} else {
212
return NULL;
213
}
214
}
215
216
API_EXPORT(LLVMTypeRef)
217
LLVMPY_TypesIterNext(LLVMTypesIteratorRef TyI) {
218
return llvm::wrap(llvm::unwrap(TyI)->next());
219
}
220
221
API_EXPORT(void)
222
LLVMPY_DisposeGlobalsIter(LLVMGlobalsIteratorRef GI) {
223
delete llvm::unwrap(GI);
224
}
225
226
API_EXPORT(void)
227
LLVMPY_DisposeFunctionsIter(LLVMFunctionsIteratorRef GI) {
228
delete llvm::unwrap(GI);
229
}
230
231
API_EXPORT(void)
232
LLVMPY_DisposeTypesIter(LLVMTypesIteratorRef TyI) { delete llvm::unwrap(TyI); }
233
234
API_EXPORT(LLVMModuleRef)
235
LLVMPY_CloneModule(LLVMModuleRef M) { return LLVMCloneModule(M); }
236
237
} // end extern "C"
238
239