]>
Commit | Line | Data |
---|---|---|
970d7e83 | 1 | // Copyright 2013 The Rust Project Developers. See the COPYRIGHT |
223e47cc LB |
2 | // file at the top-level directory of this distribution and at |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
970d7e83 | 11 | #include "rustllvm.h" |
1a4d82fc JJ |
12 | #include "llvm/Object/Archive.h" |
13 | #include "llvm/Object/ObjectFile.h" | |
14 | #include "llvm/IR/DiagnosticInfo.h" | |
15 | #include "llvm/IR/DiagnosticPrinter.h" | |
5bcae85e | 16 | #include "llvm/IR/Instructions.h" |
1a4d82fc | 17 | |
1a4d82fc | 18 | #include "llvm/IR/CallSite.h" |
970d7e83 | 19 | |
223e47cc LB |
20 | //===----------------------------------------------------------------------=== |
21 | // | |
22 | // This file defines alternate interfaces to core functions that are more | |
23 | // readily callable by Rust's FFI. | |
24 | // | |
25 | //===----------------------------------------------------------------------=== | |
26 | ||
223e47cc LB |
27 | using namespace llvm; |
28 | using namespace llvm::sys; | |
1a4d82fc | 29 | using namespace llvm::object; |
223e47cc | 30 | |
5bcae85e SL |
31 | // LLVMAtomicOrdering is already an enum - don't create another |
32 | // one. | |
33 | static AtomicOrdering from_rust(LLVMAtomicOrdering Ordering) { | |
34 | switch (Ordering) { | |
35 | case LLVMAtomicOrderingNotAtomic: | |
36 | return AtomicOrdering::NotAtomic; | |
37 | case LLVMAtomicOrderingUnordered: | |
38 | return AtomicOrdering::Unordered; | |
39 | case LLVMAtomicOrderingMonotonic: | |
40 | return AtomicOrdering::Monotonic; | |
41 | case LLVMAtomicOrderingAcquire: | |
42 | return AtomicOrdering::Acquire; | |
43 | case LLVMAtomicOrderingRelease: | |
44 | return AtomicOrdering::Release; | |
45 | case LLVMAtomicOrderingAcquireRelease: | |
46 | return AtomicOrdering::AcquireRelease; | |
47 | case LLVMAtomicOrderingSequentiallyConsistent: | |
48 | return AtomicOrdering::SequentiallyConsistent; | |
49 | } | |
50 | ||
51 | llvm_unreachable("Invalid LLVMAtomicOrdering value!"); | |
52 | } | |
53 | ||
54 | ||
1a4d82fc | 55 | static char *LastError; |
970d7e83 | 56 | |
223e47cc LB |
57 | extern "C" LLVMMemoryBufferRef |
58 | LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) { | |
1a4d82fc JJ |
59 | ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(Path, |
60 | -1, | |
61 | false); | |
62 | if (!buf_or) { | |
63 | LLVMRustSetLastError(buf_or.getError().message().c_str()); | |
64 | return nullptr; | |
223e47cc | 65 | } |
1a4d82fc | 66 | return wrap(buf_or.get().release()); |
970d7e83 | 67 | } |
223e47cc | 68 | |
1a4d82fc JJ |
69 | extern "C" char *LLVMRustGetLastError(void) { |
70 | char *ret = LastError; | |
71 | LastError = NULL; | |
72 | return ret; | |
223e47cc LB |
73 | } |
74 | ||
1a4d82fc JJ |
75 | void LLVMRustSetLastError(const char *err) { |
76 | free((void*) LastError); | |
77 | LastError = strdup(err); | |
223e47cc LB |
78 | } |
79 | ||
1a4d82fc JJ |
80 | extern "C" void |
81 | LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) { | |
82 | unwrap(M)->setTargetTriple(Triple::normalize(triple)); | |
223e47cc LB |
83 | } |
84 | ||
223e47cc LB |
85 | extern "C" void LLVMRustPrintPassTimings() { |
86 | raw_fd_ostream OS (2, false); // stderr. | |
87 | TimerGroup::printAll(OS); | |
88 | } | |
89 | ||
5bcae85e SL |
90 | extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, |
91 | const char* Name) { | |
9346a6ac AL |
92 | return wrap(unwrap(M)->getNamedValue(Name)); |
93 | } | |
94 | ||
5bcae85e SL |
95 | extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M, |
96 | const char* Name, | |
97 | LLVMTypeRef FunctionTy) { | |
223e47cc LB |
98 | return wrap(unwrap(M)->getOrInsertFunction(Name, |
99 | unwrap<FunctionType>(FunctionTy))); | |
100 | } | |
101 | ||
5bcae85e SL |
102 | extern "C" LLVMValueRef LLVMRustGetOrInsertGlobal(LLVMModuleRef M, |
103 | const char* Name, | |
104 | LLVMTypeRef Ty) { | |
9346a6ac AL |
105 | return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty))); |
106 | } | |
107 | ||
5bcae85e | 108 | extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) { |
223e47cc LB |
109 | return wrap(Type::getMetadataTy(*unwrap(C))); |
110 | } | |
970d7e83 | 111 | |
5bcae85e | 112 | extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uint64_t Val) { |
1a4d82fc JJ |
113 | CallSite Call = CallSite(unwrap<Instruction>(Instr)); |
114 | AttrBuilder B; | |
115 | B.addRawValue(Val); | |
116 | Call.setAttributes( | |
117 | Call.getAttributes().addAttributes(Call->getContext(), index, | |
118 | AttributeSet::get(Call->getContext(), | |
119 | index, B))); | |
120 | } | |
121 | ||
122 | ||
5bcae85e SL |
123 | extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr, |
124 | unsigned idx, | |
125 | uint64_t b) | |
126 | { | |
1a4d82fc JJ |
127 | CallSite Call = CallSite(unwrap<Instruction>(Instr)); |
128 | AttrBuilder B; | |
129 | B.addDereferenceableAttr(b); | |
130 | Call.setAttributes( | |
131 | Call.getAttributes().addAttributes(Call->getContext(), idx, | |
132 | AttributeSet::get(Call->getContext(), | |
133 | idx, B))); | |
134 | } | |
1a4d82fc | 135 | |
5bcae85e SL |
136 | extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, |
137 | unsigned index, | |
138 | uint64_t Val) | |
139 | { | |
1a4d82fc JJ |
140 | Function *A = unwrap<Function>(Fn); |
141 | AttrBuilder B; | |
142 | B.addRawValue(Val); | |
143 | A->addAttributes(index, AttributeSet::get(A->getContext(), index, B)); | |
144 | } | |
145 | ||
5bcae85e SL |
146 | extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, |
147 | unsigned index, | |
148 | uint64_t bytes) | |
149 | { | |
1a4d82fc JJ |
150 | Function *A = unwrap<Function>(Fn); |
151 | AttrBuilder B; | |
152 | B.addDereferenceableAttr(bytes); | |
153 | A->addAttributes(index, AttributeSet::get(A->getContext(), index, B)); | |
154 | } | |
1a4d82fc | 155 | |
5bcae85e SL |
156 | extern "C" void LLVMRustAddFunctionAttrString(LLVMValueRef Fn, |
157 | unsigned index, | |
158 | const char *Name) | |
159 | { | |
1a4d82fc JJ |
160 | Function *F = unwrap<Function>(Fn); |
161 | AttrBuilder B; | |
162 | B.addAttribute(Name); | |
163 | F->addAttributes(index, AttributeSet::get(F->getContext(), index, B)); | |
164 | } | |
165 | ||
5bcae85e SL |
166 | extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn, |
167 | unsigned index, | |
168 | const char *Name, | |
169 | const char *Value) { | |
62682a34 SL |
170 | Function *F = unwrap<Function>(Fn); |
171 | AttrBuilder B; | |
172 | B.addAttribute(Name, Value); | |
173 | F->addAttributes(index, AttributeSet::get(F->getContext(), index, B)); | |
174 | } | |
175 | ||
5bcae85e SL |
176 | extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn, |
177 | unsigned index, | |
178 | uint64_t Val) | |
179 | { | |
54a0048b SL |
180 | Function *A = unwrap<Function>(Fn); |
181 | const AttributeSet PAL = A->getAttributes(); | |
182 | AttrBuilder B(Val); | |
183 | const AttributeSet PALnew = | |
184 | PAL.removeAttributes(A->getContext(), index, | |
185 | AttributeSet::get(A->getContext(), index, B)); | |
186 | A->setAttributes(PALnew); | |
187 | } | |
188 | ||
5bcae85e SL |
189 | extern "C" void LLVMRustRemoveFunctionAttrString(LLVMValueRef fn, |
190 | unsigned index, | |
191 | const char *Name) | |
192 | { | |
1a4d82fc JJ |
193 | Function *f = unwrap<Function>(fn); |
194 | LLVMContext &C = f->getContext(); | |
195 | AttrBuilder B; | |
196 | B.addAttribute(Name); | |
197 | AttributeSet to_remove = AttributeSet::get(C, index, B); | |
198 | ||
199 | AttributeSet attrs = f->getAttributes(); | |
200 | f->setAttributes(attrs.removeAttributes(f->getContext(), | |
201 | index, | |
202 | to_remove)); | |
203 | } | |
204 | ||
54a0048b SL |
205 | // enable fpmath flag UnsafeAlgebra |
206 | extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) { | |
207 | if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) { | |
208 | I->setHasUnsafeAlgebra(true); | |
209 | } | |
210 | } | |
211 | ||
5bcae85e SL |
212 | extern "C" LLVMValueRef LLVMRustBuildAtomicLoad(LLVMBuilderRef B, |
213 | LLVMValueRef source, | |
214 | const char* Name, | |
215 | LLVMAtomicOrdering order, | |
216 | unsigned alignment) { | |
970d7e83 | 217 | LoadInst* li = new LoadInst(unwrap(source),0); |
5bcae85e | 218 | li->setAtomic(from_rust(order)); |
970d7e83 LB |
219 | li->setAlignment(alignment); |
220 | return wrap(unwrap(B)->Insert(li, Name)); | |
221 | } | |
222 | ||
5bcae85e SL |
223 | extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B, |
224 | LLVMValueRef val, | |
225 | LLVMValueRef target, | |
226 | LLVMAtomicOrdering order, | |
227 | unsigned alignment) { | |
970d7e83 | 228 | StoreInst* si = new StoreInst(unwrap(val),unwrap(target)); |
5bcae85e | 229 | si->setAtomic(from_rust(order)); |
970d7e83 LB |
230 | si->setAlignment(alignment); |
231 | return wrap(unwrap(B)->Insert(si)); | |
223e47cc LB |
232 | } |
233 | ||
5bcae85e | 234 | extern "C" LLVMValueRef LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, |
223e47cc LB |
235 | LLVMValueRef target, |
236 | LLVMValueRef old, | |
237 | LLVMValueRef source, | |
5bcae85e SL |
238 | LLVMAtomicOrdering order, |
239 | LLVMAtomicOrdering failure_order, | |
7453a54e | 240 | LLVMBool weak) { |
5bcae85e SL |
241 | AtomicCmpXchgInst* acxi = unwrap(B)->CreateAtomicCmpXchg( |
242 | unwrap(target), | |
243 | unwrap(old), | |
244 | unwrap(source), | |
245 | from_rust(order), | |
246 | from_rust(failure_order)); | |
7453a54e SL |
247 | acxi->setWeak(weak); |
248 | return wrap(acxi); | |
223e47cc | 249 | } |
5bcae85e SL |
250 | |
251 | enum class LLVMRustSynchronizationScope { | |
252 | Other, | |
253 | SingleThread, | |
254 | CrossThread, | |
255 | }; | |
256 | ||
257 | static SynchronizationScope | |
258 | from_rust(LLVMRustSynchronizationScope scope) | |
259 | { | |
260 | switch (scope) { | |
261 | case LLVMRustSynchronizationScope::SingleThread: | |
262 | return SingleThread; | |
263 | case LLVMRustSynchronizationScope::CrossThread: | |
264 | return CrossThread; | |
265 | default: | |
266 | llvm_unreachable("bad SynchronizationScope."); | |
267 | } | |
223e47cc LB |
268 | } |
269 | ||
5bcae85e SL |
270 | extern "C" LLVMValueRef LLVMRustBuildAtomicFence( |
271 | LLVMBuilderRef B, | |
272 | LLVMAtomicOrdering order, | |
273 | LLVMRustSynchronizationScope scope) | |
274 | { | |
275 | return wrap(unwrap(B)->CreateFence(from_rust(order), from_rust(scope))); | |
276 | } | |
277 | ||
278 | extern "C" void LLVMRustSetDebug(int Enabled) { | |
223e47cc LB |
279 | #ifndef NDEBUG |
280 | DebugFlag = Enabled; | |
281 | #endif | |
282 | } | |
283 | ||
5bcae85e SL |
284 | enum class LLVMRustAsmDialect { |
285 | Other, | |
286 | Att, | |
287 | Intel, | |
288 | }; | |
289 | ||
290 | static InlineAsm::AsmDialect | |
291 | from_rust(LLVMRustAsmDialect dialect) | |
292 | { | |
293 | switch (dialect) { | |
294 | case LLVMRustAsmDialect::Att: | |
295 | return InlineAsm::AD_ATT; | |
296 | case LLVMRustAsmDialect::Intel: | |
297 | return InlineAsm::AD_Intel; | |
298 | default: | |
299 | llvm_unreachable("bad AsmDialect."); | |
300 | } | |
301 | } | |
302 | ||
303 | extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty, | |
304 | char *AsmString, | |
305 | char *Constraints, | |
306 | LLVMBool HasSideEffects, | |
307 | LLVMBool IsAlignStack, | |
308 | LLVMRustAsmDialect Dialect) { | |
223e47cc LB |
309 | return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString, |
310 | Constraints, HasSideEffects, | |
5bcae85e | 311 | IsAlignStack, from_rust(Dialect))); |
223e47cc | 312 | } |
970d7e83 | 313 | |
5bcae85e | 314 | typedef DIBuilder* LLVMRustDIBuilderRef; |
970d7e83 | 315 | |
5bcae85e | 316 | typedef struct LLVMOpaqueMetadata *LLVMRustMetadataRef; |
85aaf69f SL |
317 | |
318 | namespace llvm { | |
5bcae85e | 319 | DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMRustMetadataRef) |
85aaf69f | 320 | |
5bcae85e | 321 | inline Metadata **unwrap(LLVMRustMetadataRef *Vals) { |
85aaf69f SL |
322 | return reinterpret_cast<Metadata**>(Vals); |
323 | } | |
324 | } | |
85aaf69f | 325 | |
62682a34 | 326 | template<typename DIT> |
5bcae85e | 327 | DIT* unwrapDIptr(LLVMRustMetadataRef ref) { |
62682a34 SL |
328 | return (DIT*) (ref ? unwrap<MDNode>(ref) : NULL); |
329 | } | |
330 | ||
62682a34 SL |
331 | #define DIDescriptor DIScope |
332 | #define DIArray DINodeArray | |
333 | #define unwrapDI unwrapDIptr | |
62682a34 SL |
334 | |
335 | extern "C" uint32_t LLVMRustDebugMetadataVersion() { | |
336 | return DEBUG_METADATA_VERSION; | |
337 | } | |
338 | ||
5bcae85e | 339 | extern "C" uint32_t LLVMRustVersionMinor() { |
62682a34 SL |
340 | return LLVM_VERSION_MINOR; |
341 | } | |
342 | ||
5bcae85e | 343 | extern "C" uint32_t LLVMRustVersionMajor() { |
62682a34 SL |
344 | return LLVM_VERSION_MAJOR; |
345 | } | |
1a4d82fc JJ |
346 | |
347 | extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, | |
348 | const char *name, | |
349 | uint32_t value) { | |
350 | unwrap(M)->addModuleFlag(Module::Warning, name, value); | |
970d7e83 LB |
351 | } |
352 | ||
5bcae85e | 353 | extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) { |
970d7e83 LB |
354 | return new DIBuilder(*unwrap(M)); |
355 | } | |
356 | ||
5bcae85e | 357 | extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) { |
970d7e83 LB |
358 | delete Builder; |
359 | } | |
360 | ||
5bcae85e | 361 | extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) { |
970d7e83 LB |
362 | Builder->finalize(); |
363 | } | |
364 | ||
5bcae85e SL |
365 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateCompileUnit( |
366 | LLVMRustDIBuilderRef Builder, | |
970d7e83 LB |
367 | unsigned Lang, |
368 | const char* File, | |
369 | const char* Dir, | |
370 | const char* Producer, | |
371 | bool isOptimized, | |
372 | const char* Flags, | |
373 | unsigned RuntimeVer, | |
374 | const char* SplitName) { | |
1a4d82fc JJ |
375 | return wrap(Builder->createCompileUnit(Lang, |
376 | File, | |
377 | Dir, | |
378 | Producer, | |
379 | isOptimized, | |
380 | Flags, | |
381 | RuntimeVer, | |
382 | SplitName)); | |
970d7e83 LB |
383 | } |
384 | ||
5bcae85e SL |
385 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFile( |
386 | LLVMRustDIBuilderRef Builder, | |
970d7e83 LB |
387 | const char* Filename, |
388 | const char* Directory) { | |
389 | return wrap(Builder->createFile(Filename, Directory)); | |
390 | } | |
391 | ||
5bcae85e SL |
392 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateSubroutineType( |
393 | LLVMRustDIBuilderRef Builder, | |
394 | LLVMRustMetadataRef File, | |
395 | LLVMRustMetadataRef ParameterTypes) { | |
970d7e83 | 396 | return wrap(Builder->createSubroutineType( |
3157f602 | 397 | #if LLVM_VERSION_MINOR == 7 |
1a4d82fc | 398 | unwrapDI<DIFile>(File), |
b039eaaf | 399 | #endif |
62682a34 | 400 | DITypeRefArray(unwrap<MDTuple>(ParameterTypes)))); |
970d7e83 LB |
401 | } |
402 | ||
5bcae85e SL |
403 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction( |
404 | LLVMRustDIBuilderRef Builder, | |
405 | LLVMRustMetadataRef Scope, | |
970d7e83 LB |
406 | const char* Name, |
407 | const char* LinkageName, | |
5bcae85e | 408 | LLVMRustMetadataRef File, |
970d7e83 | 409 | unsigned LineNo, |
5bcae85e | 410 | LLVMRustMetadataRef Ty, |
970d7e83 LB |
411 | bool isLocalToUnit, |
412 | bool isDefinition, | |
413 | unsigned ScopeLine, | |
414 | unsigned Flags, | |
415 | bool isOptimized, | |
416 | LLVMValueRef Fn, | |
5bcae85e SL |
417 | LLVMRustMetadataRef TParam, |
418 | LLVMRustMetadataRef Decl) { | |
7453a54e SL |
419 | #if LLVM_VERSION_MINOR >= 8 |
420 | DITemplateParameterArray TParams = | |
421 | DITemplateParameterArray(unwrap<MDTuple>(TParam)); | |
422 | DISubprogram *Sub = Builder->createFunction( | |
423 | unwrapDI<DIScope>(Scope), Name, LinkageName, | |
424 | unwrapDI<DIFile>(File), LineNo, | |
425 | unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine, | |
426 | Flags, isOptimized, | |
427 | TParams, | |
428 | unwrapDIptr<DISubprogram>(Decl)); | |
429 | unwrap<Function>(Fn)->setSubprogram(Sub); | |
430 | return wrap(Sub); | |
431 | #else | |
970d7e83 | 432 | return wrap(Builder->createFunction( |
1a4d82fc JJ |
433 | unwrapDI<DIScope>(Scope), Name, LinkageName, |
434 | unwrapDI<DIFile>(File), LineNo, | |
62682a34 | 435 | unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine, |
970d7e83 | 436 | Flags, isOptimized, |
1a4d82fc | 437 | unwrap<Function>(Fn), |
62682a34 SL |
438 | unwrapDIptr<MDNode>(TParam), |
439 | unwrapDIptr<MDNode>(Decl))); | |
7453a54e | 440 | #endif |
970d7e83 LB |
441 | } |
442 | ||
5bcae85e SL |
443 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateBasicType( |
444 | LLVMRustDIBuilderRef Builder, | |
970d7e83 LB |
445 | const char* Name, |
446 | uint64_t SizeInBits, | |
447 | uint64_t AlignInBits, | |
448 | unsigned Encoding) { | |
449 | return wrap(Builder->createBasicType( | |
1a4d82fc | 450 | Name, SizeInBits, |
970d7e83 LB |
451 | AlignInBits, Encoding)); |
452 | } | |
1a4d82fc | 453 | |
5bcae85e SL |
454 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreatePointerType( |
455 | LLVMRustDIBuilderRef Builder, | |
456 | LLVMRustMetadataRef PointeeTy, | |
970d7e83 LB |
457 | uint64_t SizeInBits, |
458 | uint64_t AlignInBits, | |
459 | const char* Name) { | |
460 | return wrap(Builder->createPointerType( | |
461 | unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name)); | |
462 | } | |
463 | ||
5bcae85e SL |
464 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType( |
465 | LLVMRustDIBuilderRef Builder, | |
466 | LLVMRustMetadataRef Scope, | |
970d7e83 | 467 | const char* Name, |
5bcae85e | 468 | LLVMRustMetadataRef File, |
970d7e83 LB |
469 | unsigned LineNumber, |
470 | uint64_t SizeInBits, | |
471 | uint64_t AlignInBits, | |
472 | unsigned Flags, | |
5bcae85e SL |
473 | LLVMRustMetadataRef DerivedFrom, |
474 | LLVMRustMetadataRef Elements, | |
970d7e83 | 475 | unsigned RunTimeLang, |
5bcae85e | 476 | LLVMRustMetadataRef VTableHolder, |
1a4d82fc | 477 | const char *UniqueId) { |
970d7e83 | 478 | return wrap(Builder->createStructType( |
1a4d82fc JJ |
479 | unwrapDI<DIDescriptor>(Scope), |
480 | Name, | |
481 | unwrapDI<DIFile>(File), | |
482 | LineNumber, | |
483 | SizeInBits, | |
484 | AlignInBits, | |
485 | Flags, | |
486 | unwrapDI<DIType>(DerivedFrom), | |
62682a34 | 487 | DINodeArray(unwrapDI<MDTuple>(Elements)), |
1a4d82fc | 488 | RunTimeLang, |
c34b1796 AL |
489 | unwrapDI<DIType>(VTableHolder), |
490 | UniqueId | |
1a4d82fc | 491 | )); |
970d7e83 LB |
492 | } |
493 | ||
5bcae85e SL |
494 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateMemberType( |
495 | LLVMRustDIBuilderRef Builder, | |
496 | LLVMRustMetadataRef Scope, | |
970d7e83 | 497 | const char* Name, |
5bcae85e | 498 | LLVMRustMetadataRef File, |
970d7e83 LB |
499 | unsigned LineNo, |
500 | uint64_t SizeInBits, | |
501 | uint64_t AlignInBits, | |
502 | uint64_t OffsetInBits, | |
503 | unsigned Flags, | |
5bcae85e | 504 | LLVMRustMetadataRef Ty) { |
970d7e83 | 505 | return wrap(Builder->createMemberType( |
1a4d82fc | 506 | unwrapDI<DIDescriptor>(Scope), Name, |
970d7e83 | 507 | unwrapDI<DIFile>(File), LineNo, |
1a4d82fc | 508 | SizeInBits, AlignInBits, OffsetInBits, Flags, |
970d7e83 LB |
509 | unwrapDI<DIType>(Ty))); |
510 | } | |
1a4d82fc | 511 | |
5bcae85e SL |
512 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlock( |
513 | LLVMRustDIBuilderRef Builder, | |
514 | LLVMRustMetadataRef Scope, | |
515 | LLVMRustMetadataRef File, | |
970d7e83 LB |
516 | unsigned Line, |
517 | unsigned Col) { | |
518 | return wrap(Builder->createLexicalBlock( | |
1a4d82fc JJ |
519 | unwrapDI<DIDescriptor>(Scope), |
520 | unwrapDI<DIFile>(File), Line, Col | |
1a4d82fc JJ |
521 | )); |
522 | } | |
523 | ||
5bcae85e SL |
524 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable( |
525 | LLVMRustDIBuilderRef Builder, | |
526 | LLVMRustMetadataRef Context, | |
1a4d82fc JJ |
527 | const char* Name, |
528 | const char* LinkageName, | |
5bcae85e | 529 | LLVMRustMetadataRef File, |
1a4d82fc | 530 | unsigned LineNo, |
5bcae85e | 531 | LLVMRustMetadataRef Ty, |
1a4d82fc JJ |
532 | bool isLocalToUnit, |
533 | LLVMValueRef Val, | |
5bcae85e | 534 | LLVMRustMetadataRef Decl = NULL) { |
1a4d82fc | 535 | return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context), |
1a4d82fc JJ |
536 | Name, |
537 | LinkageName, | |
538 | unwrapDI<DIFile>(File), | |
539 | LineNo, | |
540 | unwrapDI<DIType>(Ty), | |
541 | isLocalToUnit, | |
85aaf69f | 542 | cast<Constant>(unwrap(Val)), |
62682a34 | 543 | unwrapDIptr<MDNode>(Decl))); |
970d7e83 | 544 | } |
1a4d82fc | 545 | |
5bcae85e SL |
546 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable( |
547 | LLVMRustDIBuilderRef Builder, | |
970d7e83 | 548 | unsigned Tag, |
5bcae85e | 549 | LLVMRustMetadataRef Scope, |
970d7e83 | 550 | const char* Name, |
5bcae85e | 551 | LLVMRustMetadataRef File, |
970d7e83 | 552 | unsigned LineNo, |
5bcae85e | 553 | LLVMRustMetadataRef Ty, |
970d7e83 LB |
554 | bool AlwaysPreserve, |
555 | unsigned Flags, | |
85aaf69f SL |
556 | int64_t* AddrOps, |
557 | unsigned AddrOpsCount, | |
970d7e83 | 558 | unsigned ArgNo) { |
b039eaaf SL |
559 | #if LLVM_VERSION_MINOR >= 8 |
560 | if (Tag == 0x100) { // DW_TAG_auto_variable | |
561 | return wrap(Builder->createAutoVariable( | |
562 | unwrapDI<DIDescriptor>(Scope), Name, | |
563 | unwrapDI<DIFile>(File), | |
564 | LineNo, | |
565 | unwrapDI<DIType>(Ty), AlwaysPreserve, Flags)); | |
566 | } else { | |
567 | return wrap(Builder->createParameterVariable( | |
568 | unwrapDI<DIDescriptor>(Scope), Name, ArgNo, | |
569 | unwrapDI<DIFile>(File), | |
570 | LineNo, | |
571 | unwrapDI<DIType>(Ty), AlwaysPreserve, Flags)); | |
572 | } | |
573 | #else | |
1a4d82fc JJ |
574 | return wrap(Builder->createLocalVariable(Tag, |
575 | unwrapDI<DIDescriptor>(Scope), Name, | |
576 | unwrapDI<DIFile>(File), | |
577 | LineNo, | |
970d7e83 | 578 | unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo)); |
b039eaaf | 579 | #endif |
970d7e83 LB |
580 | } |
581 | ||
5bcae85e SL |
582 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateArrayType( |
583 | LLVMRustDIBuilderRef Builder, | |
1a4d82fc JJ |
584 | uint64_t Size, |
585 | uint64_t AlignInBits, | |
5bcae85e SL |
586 | LLVMRustMetadataRef Ty, |
587 | LLVMRustMetadataRef Subscripts) { | |
970d7e83 | 588 | return wrap(Builder->createArrayType(Size, AlignInBits, |
1a4d82fc | 589 | unwrapDI<DIType>(Ty), |
62682a34 | 590 | DINodeArray(unwrapDI<MDTuple>(Subscripts)) |
62682a34 | 591 | )); |
970d7e83 LB |
592 | } |
593 | ||
5bcae85e SL |
594 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVectorType( |
595 | LLVMRustDIBuilderRef Builder, | |
1a4d82fc JJ |
596 | uint64_t Size, |
597 | uint64_t AlignInBits, | |
5bcae85e SL |
598 | LLVMRustMetadataRef Ty, |
599 | LLVMRustMetadataRef Subscripts) { | |
970d7e83 | 600 | return wrap(Builder->createVectorType(Size, AlignInBits, |
1a4d82fc | 601 | unwrapDI<DIType>(Ty), |
62682a34 | 602 | DINodeArray(unwrapDI<MDTuple>(Subscripts)) |
62682a34 | 603 | )); |
970d7e83 LB |
604 | } |
605 | ||
5bcae85e SL |
606 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateSubrange( |
607 | LLVMRustDIBuilderRef Builder, | |
1a4d82fc | 608 | int64_t Lo, |
970d7e83 LB |
609 | int64_t Count) { |
610 | return wrap(Builder->getOrCreateSubrange(Lo, Count)); | |
611 | } | |
612 | ||
5bcae85e SL |
613 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateArray( |
614 | LLVMRustDIBuilderRef Builder, | |
615 | LLVMRustMetadataRef* Ptr, | |
970d7e83 | 616 | unsigned Count) { |
62682a34 SL |
617 | Metadata **DataValue = unwrap(Ptr); |
618 | return wrap(Builder->getOrCreateArray( | |
619 | ArrayRef<Metadata*>(DataValue, Count)).get()); | |
970d7e83 LB |
620 | } |
621 | ||
5bcae85e SL |
622 | extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd( |
623 | LLVMRustDIBuilderRef Builder, | |
970d7e83 | 624 | LLVMValueRef Val, |
5bcae85e | 625 | LLVMRustMetadataRef VarInfo, |
85aaf69f SL |
626 | int64_t* AddrOps, |
627 | unsigned AddrOpsCount, | |
62682a34 | 628 | LLVMValueRef DL, |
970d7e83 LB |
629 | LLVMBasicBlockRef InsertAtEnd) { |
630 | return wrap(Builder->insertDeclare( | |
1a4d82fc | 631 | unwrap(Val), |
62682a34 | 632 | unwrap<DILocalVariable>(VarInfo), |
62682a34 SL |
633 | Builder->createExpression( |
634 | llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)), | |
62682a34 | 635 | DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())), |
970d7e83 LB |
636 | unwrap(InsertAtEnd))); |
637 | } | |
638 | ||
5bcae85e SL |
639 | extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareBefore( |
640 | LLVMRustDIBuilderRef Builder, | |
970d7e83 | 641 | LLVMValueRef Val, |
5bcae85e | 642 | LLVMRustMetadataRef VarInfo, |
85aaf69f SL |
643 | int64_t* AddrOps, |
644 | unsigned AddrOpsCount, | |
62682a34 | 645 | LLVMValueRef DL, |
970d7e83 LB |
646 | LLVMValueRef InsertBefore) { |
647 | return wrap(Builder->insertDeclare( | |
1a4d82fc | 648 | unwrap(Val), |
62682a34 | 649 | unwrap<DILocalVariable>(VarInfo), |
62682a34 SL |
650 | Builder->createExpression( |
651 | llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)), | |
62682a34 | 652 | DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())), |
970d7e83 LB |
653 | unwrap<Instruction>(InsertBefore))); |
654 | } | |
1a4d82fc | 655 | |
5bcae85e SL |
656 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerator( |
657 | LLVMRustDIBuilderRef Builder, | |
1a4d82fc JJ |
658 | const char* Name, |
659 | uint64_t Val) | |
660 | { | |
661 | return wrap(Builder->createEnumerator(Name, Val)); | |
662 | } | |
663 | ||
5bcae85e SL |
664 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerationType( |
665 | LLVMRustDIBuilderRef Builder, | |
666 | LLVMRustMetadataRef Scope, | |
1a4d82fc | 667 | const char* Name, |
5bcae85e | 668 | LLVMRustMetadataRef File, |
1a4d82fc JJ |
669 | unsigned LineNumber, |
670 | uint64_t SizeInBits, | |
671 | uint64_t AlignInBits, | |
5bcae85e SL |
672 | LLVMRustMetadataRef Elements, |
673 | LLVMRustMetadataRef ClassType) | |
1a4d82fc JJ |
674 | { |
675 | return wrap(Builder->createEnumerationType( | |
676 | unwrapDI<DIDescriptor>(Scope), | |
677 | Name, | |
678 | unwrapDI<DIFile>(File), | |
679 | LineNumber, | |
680 | SizeInBits, | |
681 | AlignInBits, | |
62682a34 | 682 | DINodeArray(unwrapDI<MDTuple>(Elements)), |
1a4d82fc JJ |
683 | unwrapDI<DIType>(ClassType))); |
684 | } | |
685 | ||
5bcae85e SL |
686 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType( |
687 | LLVMRustDIBuilderRef Builder, | |
688 | LLVMRustMetadataRef Scope, | |
1a4d82fc | 689 | const char* Name, |
5bcae85e | 690 | LLVMRustMetadataRef File, |
1a4d82fc JJ |
691 | unsigned LineNumber, |
692 | uint64_t SizeInBits, | |
693 | uint64_t AlignInBits, | |
694 | unsigned Flags, | |
5bcae85e | 695 | LLVMRustMetadataRef Elements, |
1a4d82fc JJ |
696 | unsigned RunTimeLang, |
697 | const char* UniqueId) | |
698 | { | |
699 | return wrap(Builder->createUnionType( | |
700 | unwrapDI<DIDescriptor>(Scope), | |
701 | Name, | |
702 | unwrapDI<DIFile>(File), | |
703 | LineNumber, | |
704 | SizeInBits, | |
705 | AlignInBits, | |
706 | Flags, | |
62682a34 | 707 | DINodeArray(unwrapDI<MDTuple>(Elements)), |
c34b1796 AL |
708 | RunTimeLang, |
709 | UniqueId | |
1a4d82fc JJ |
710 | )); |
711 | } | |
712 | ||
5bcae85e SL |
713 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter( |
714 | LLVMRustDIBuilderRef Builder, | |
715 | LLVMRustMetadataRef Scope, | |
1a4d82fc | 716 | const char* Name, |
5bcae85e SL |
717 | LLVMRustMetadataRef Ty, |
718 | LLVMRustMetadataRef File, | |
1a4d82fc JJ |
719 | unsigned LineNo, |
720 | unsigned ColumnNo) | |
721 | { | |
722 | return wrap(Builder->createTemplateTypeParameter( | |
723 | unwrapDI<DIDescriptor>(Scope), | |
724 | Name, | |
62682a34 | 725 | unwrapDI<DIType>(Ty) |
62682a34 | 726 | )); |
1a4d82fc JJ |
727 | } |
728 | ||
5bcae85e SL |
729 | extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateNameSpace( |
730 | LLVMRustDIBuilderRef Builder, | |
731 | LLVMRustMetadataRef Scope, | |
1a4d82fc | 732 | const char* Name, |
5bcae85e | 733 | LLVMRustMetadataRef File, |
1a4d82fc JJ |
734 | unsigned LineNo) |
735 | { | |
736 | return wrap(Builder->createNameSpace( | |
737 | unwrapDI<DIDescriptor>(Scope), | |
738 | Name, | |
739 | unwrapDI<DIFile>(File), | |
740 | LineNo)); | |
741 | } | |
742 | ||
5bcae85e SL |
743 | extern "C" void LLVMRustDICompositeTypeSetTypeArray( |
744 | LLVMRustDIBuilderRef Builder, | |
745 | LLVMRustMetadataRef CompositeType, | |
746 | LLVMRustMetadataRef TypeArray) | |
1a4d82fc | 747 | { |
62682a34 SL |
748 | DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType); |
749 | Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray))); | |
1a4d82fc JJ |
750 | } |
751 | ||
5bcae85e | 752 | extern "C" LLVMValueRef LLVMRustDIBuilderCreateDebugLocation( |
85aaf69f SL |
753 | LLVMContextRef Context, |
754 | unsigned Line, | |
755 | unsigned Column, | |
5bcae85e SL |
756 | LLVMRustMetadataRef Scope, |
757 | LLVMRustMetadataRef InlinedAt) | |
758 | { | |
85aaf69f SL |
759 | LLVMContext& context = *unwrap(Context); |
760 | ||
761 | DebugLoc debug_loc = DebugLoc::get(Line, | |
762 | Column, | |
62682a34 SL |
763 | unwrapDIptr<MDNode>(Scope), |
764 | unwrapDIptr<MDNode>(InlinedAt)); | |
85aaf69f | 765 | |
3157f602 | 766 | return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode())); |
85aaf69f SL |
767 | } |
768 | ||
5bcae85e SL |
769 | extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() |
770 | { | |
771 | return dwarf::DW_OP_deref; | |
772 | } | |
773 | ||
774 | extern "C" int64_t LLVMRustDIBuilderCreateOpPlus() | |
775 | { | |
776 | return dwarf::DW_OP_plus; | |
777 | } | |
778 | ||
779 | extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Type, RustStringRef str) { | |
1a4d82fc JJ |
780 | raw_rust_string_ostream os(str); |
781 | unwrap<llvm::Type>(Type)->print(os); | |
782 | } | |
783 | ||
5bcae85e | 784 | extern "C" void LLVMRustWriteValueToString(LLVMValueRef Value, RustStringRef str) { |
1a4d82fc JJ |
785 | raw_rust_string_ostream os(str); |
786 | os << "("; | |
787 | unwrap<llvm::Value>(Value)->getType()->print(os); | |
788 | os << ":"; | |
789 | unwrap<llvm::Value>(Value)->print(os); | |
790 | os << ")"; | |
791 | } | |
792 | ||
1a4d82fc JJ |
793 | extern "C" bool |
794 | LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) { | |
795 | Module *Dst = unwrap(dst); | |
1a4d82fc | 796 | std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len)); |
62682a34 SL |
797 | ErrorOr<std::unique_ptr<Module>> Src = |
798 | llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext()); | |
1a4d82fc JJ |
799 | if (!Src) { |
800 | LLVMRustSetLastError(Src.getError().message().c_str()); | |
1a4d82fc JJ |
801 | return false; |
802 | } | |
803 | ||
804 | std::string Err; | |
85aaf69f | 805 | |
85aaf69f SL |
806 | raw_string_ostream Stream(Err); |
807 | DiagnosticPrinterRawOStream DP(Stream); | |
7453a54e SL |
808 | #if LLVM_VERSION_MINOR >= 8 |
809 | if (Linker::linkModules(*Dst, std::move(Src.get()))) { | |
85aaf69f | 810 | #else |
3157f602 | 811 | if (Linker::LinkModules(Dst, Src->get(), [&](const DiagnosticInfo &DI) { DI.print(DP); })) { |
85aaf69f | 812 | #endif |
1a4d82fc JJ |
813 | LLVMRustSetLastError(Err.c_str()); |
814 | return false; | |
815 | } | |
816 | return true; | |
817 | } | |
1a4d82fc | 818 | |
1a4d82fc JJ |
819 | // Note that the two following functions look quite similar to the |
820 | // LLVMGetSectionName function. Sadly, it appears that this function only | |
821 | // returns a char* pointer, which isn't guaranteed to be null-terminated. The | |
822 | // function provided by LLVM doesn't return the length, so we've created our own | |
823 | // function which returns the length as well as the data pointer. | |
824 | // | |
825 | // For an example of this not returning a null terminated string, see | |
826 | // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the | |
827 | // branches explicitly creates a StringRef without a null terminator, and then | |
828 | // that's returned. | |
829 | ||
830 | inline section_iterator *unwrap(LLVMSectionIteratorRef SI) { | |
831 | return reinterpret_cast<section_iterator*>(SI); | |
832 | } | |
833 | ||
5bcae85e | 834 | extern "C" size_t |
1a4d82fc JJ |
835 | LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) { |
836 | StringRef ret; | |
1a4d82fc | 837 | if (std::error_code ec = (*unwrap(SI))->getName(ret)) |
1a4d82fc JJ |
838 | report_fatal_error(ec.message()); |
839 | *ptr = ret.data(); | |
840 | return ret.size(); | |
841 | } | |
842 | ||
843 | // LLVMArrayType function does not support 64-bit ElementCount | |
844 | extern "C" LLVMTypeRef | |
845 | LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) { | |
846 | return wrap(ArrayType::get(unwrap(ElementType), ElementCount)); | |
847 | } | |
848 | ||
849 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef) | |
850 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef) | |
851 | ||
852 | extern "C" void | |
5bcae85e | 853 | LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef str) { |
1a4d82fc JJ |
854 | raw_rust_string_ostream os(str); |
855 | unwrap(T)->print(os); | |
856 | } | |
857 | ||
858 | extern "C" void | |
5bcae85e | 859 | LLVMRustUnpackOptimizationDiagnostic( |
1a4d82fc JJ |
860 | LLVMDiagnosticInfoRef di, |
861 | const char **pass_name_out, | |
862 | LLVMValueRef *function_out, | |
863 | LLVMDebugLocRef *debugloc_out, | |
864 | LLVMTwineRef *message_out) | |
865 | { | |
866 | // Undefined to call this not on an optimization diagnostic! | |
867 | llvm::DiagnosticInfoOptimizationBase *opt | |
868 | = static_cast<llvm::DiagnosticInfoOptimizationBase*>(unwrap(di)); | |
869 | ||
870 | *pass_name_out = opt->getPassName(); | |
871 | *function_out = wrap(&opt->getFunction()); | |
872 | *debugloc_out = wrap(&opt->getDebugLoc()); | |
873 | *message_out = wrap(&opt->getMsg()); | |
874 | } | |
875 | ||
85aaf69f | 876 | extern "C" void |
5bcae85e | 877 | LLVMRustUnpackInlineAsmDiagnostic( |
85aaf69f SL |
878 | LLVMDiagnosticInfoRef di, |
879 | unsigned *cookie_out, | |
880 | LLVMTwineRef *message_out, | |
881 | LLVMValueRef *instruction_out) | |
882 | { | |
883 | // Undefined to call this not on an inline assembly diagnostic! | |
884 | llvm::DiagnosticInfoInlineAsm *ia | |
885 | = static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di)); | |
886 | ||
887 | *cookie_out = ia->getLocCookie(); | |
888 | *message_out = wrap(&ia->getMsgStr()); | |
889 | *instruction_out = wrap(ia->getInstruction()); | |
890 | } | |
891 | ||
5bcae85e | 892 | extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) { |
1a4d82fc JJ |
893 | raw_rust_string_ostream os(str); |
894 | DiagnosticPrinterRawOStream dp(os); | |
895 | unwrap(di)->print(dp); | |
896 | } | |
897 | ||
5bcae85e SL |
898 | enum class LLVMRustDiagnosticKind { |
899 | Other, | |
900 | InlineAsm, | |
901 | StackSize, | |
902 | DebugMetadataVersion, | |
903 | SampleProfile, | |
904 | OptimizationRemark, | |
905 | OptimizationRemarkMissed, | |
906 | OptimizationRemarkAnalysis, | |
907 | OptimizationRemarkAnalysisFPCommute, | |
908 | OptimizationRemarkAnalysisAliasing, | |
909 | OptimizationRemarkOther, | |
910 | OptimizationFailure, | |
911 | }; | |
912 | ||
913 | static LLVMRustDiagnosticKind | |
914 | to_rust(DiagnosticKind kind) | |
915 | { | |
916 | switch (kind) { | |
917 | case DK_InlineAsm: | |
918 | return LLVMRustDiagnosticKind::InlineAsm; | |
919 | case DK_StackSize: | |
920 | return LLVMRustDiagnosticKind::StackSize; | |
921 | case DK_DebugMetadataVersion: | |
922 | return LLVMRustDiagnosticKind::DebugMetadataVersion; | |
923 | case DK_SampleProfile: | |
924 | return LLVMRustDiagnosticKind::SampleProfile; | |
925 | case DK_OptimizationRemark: | |
926 | return LLVMRustDiagnosticKind::OptimizationRemark; | |
927 | case DK_OptimizationRemarkMissed: | |
928 | return LLVMRustDiagnosticKind::OptimizationRemarkMissed; | |
929 | case DK_OptimizationRemarkAnalysis: | |
930 | return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis; | |
931 | #if LLVM_VERSION_MINOR >= 8 | |
932 | case DK_OptimizationRemarkAnalysisFPCommute: | |
933 | return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute; | |
934 | case DK_OptimizationRemarkAnalysisAliasing: | |
935 | return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing; | |
936 | #endif | |
937 | default: | |
938 | #if LLVM_VERSION_MINOR >= 9 | |
939 | return (kind >= DK_FirstRemark && kind <= DK_LastRemark) ? | |
940 | LLVMRustDiagnosticKind::OptimizationRemarkOther : | |
941 | LLVMRustDiagnosticKind::Other; | |
942 | #else | |
943 | return LLVMRustDiagnosticKind::Other; | |
944 | #endif | |
945 | } | |
946 | } | |
947 | ||
948 | extern "C" LLVMRustDiagnosticKind LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef di) { | |
949 | return to_rust((DiagnosticKind) unwrap(di)->getKind()); | |
950 | } | |
951 | // This is kept distinct from LLVMGetTypeKind, because when | |
952 | // a new type kind is added, the Rust-side enum must be | |
953 | // updated or UB will result. | |
954 | extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) { | |
955 | switch (unwrap(Ty)->getTypeID()) { | |
956 | case Type::VoidTyID: | |
957 | return LLVMVoidTypeKind; | |
958 | case Type::HalfTyID: | |
959 | return LLVMHalfTypeKind; | |
960 | case Type::FloatTyID: | |
961 | return LLVMFloatTypeKind; | |
962 | case Type::DoubleTyID: | |
963 | return LLVMDoubleTypeKind; | |
964 | case Type::X86_FP80TyID: | |
965 | return LLVMX86_FP80TypeKind; | |
966 | case Type::FP128TyID: | |
967 | return LLVMFP128TypeKind; | |
968 | case Type::PPC_FP128TyID: | |
969 | return LLVMPPC_FP128TypeKind; | |
970 | case Type::LabelTyID: | |
971 | return LLVMLabelTypeKind; | |
972 | case Type::MetadataTyID: | |
973 | return LLVMMetadataTypeKind; | |
974 | case Type::IntegerTyID: | |
975 | return LLVMIntegerTypeKind; | |
976 | case Type::FunctionTyID: | |
977 | return LLVMFunctionTypeKind; | |
978 | case Type::StructTyID: | |
979 | return LLVMStructTypeKind; | |
980 | case Type::ArrayTyID: | |
981 | return LLVMArrayTypeKind; | |
982 | case Type::PointerTyID: | |
983 | return LLVMPointerTypeKind; | |
984 | case Type::VectorTyID: | |
985 | return LLVMVectorTypeKind; | |
986 | case Type::X86_MMXTyID: | |
987 | return LLVMX86_MMXTypeKind; | |
988 | #if LLVM_VERSION_MINOR >= 8 | |
989 | case Type::TokenTyID: | |
990 | return LLVMTokenTypeKind; | |
991 | #endif | |
992 | } | |
993 | llvm_unreachable("Unhandled TypeID."); | |
1a4d82fc JJ |
994 | } |
995 | ||
5bcae85e | 996 | extern "C" void LLVMRustWriteDebugLocToString( |
1a4d82fc JJ |
997 | LLVMContextRef C, |
998 | LLVMDebugLocRef dl, | |
999 | RustStringRef str) | |
1000 | { | |
1001 | raw_rust_string_ostream os(str); | |
62682a34 | 1002 | unwrap(dl)->print(os); |
1a4d82fc JJ |
1003 | } |
1004 | ||
1005 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef) | |
1006 | ||
5bcae85e | 1007 | extern "C" void LLVMRustSetInlineAsmDiagnosticHandler( |
1a4d82fc JJ |
1008 | LLVMContextRef C, |
1009 | LLVMContext::InlineAsmDiagHandlerTy H, | |
1010 | void *CX) | |
1011 | { | |
1012 | unwrap(C)->setInlineAsmDiagnosticHandler(H, CX); | |
1013 | } | |
1014 | ||
5bcae85e SL |
1015 | extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, |
1016 | RustStringRef str) { | |
1a4d82fc JJ |
1017 | raw_rust_string_ostream os(str); |
1018 | unwrap(d)->print("", os); | |
1019 | } | |
c1a9b12d SL |
1020 | |
1021 | extern "C" LLVMValueRef | |
1022 | LLVMRustBuildLandingPad(LLVMBuilderRef Builder, | |
1023 | LLVMTypeRef Ty, | |
1024 | LLVMValueRef PersFn, | |
1025 | unsigned NumClauses, | |
1026 | const char* Name, | |
1027 | LLVMValueRef F) { | |
c1a9b12d | 1028 | return LLVMBuildLandingPad(Builder, Ty, PersFn, NumClauses, Name); |
c1a9b12d | 1029 | } |
7453a54e SL |
1030 | |
1031 | extern "C" LLVMValueRef | |
1032 | LLVMRustBuildCleanupPad(LLVMBuilderRef Builder, | |
1033 | LLVMValueRef ParentPad, | |
1034 | unsigned ArgCnt, | |
1035 | LLVMValueRef *LLArgs, | |
1036 | const char *Name) { | |
1037 | #if LLVM_VERSION_MINOR >= 8 | |
1038 | Value **Args = unwrap(LLArgs); | |
1039 | if (ParentPad == NULL) { | |
1040 | Type *Ty = Type::getTokenTy(unwrap(Builder)->getContext()); | |
1041 | ParentPad = wrap(Constant::getNullValue(Ty)); | |
1042 | } | |
1043 | return wrap(unwrap(Builder)->CreateCleanupPad(unwrap(ParentPad), | |
1044 | ArrayRef<Value*>(Args, ArgCnt), | |
1045 | Name)); | |
1046 | #else | |
1047 | return NULL; | |
1048 | #endif | |
1049 | } | |
1050 | ||
1051 | extern "C" LLVMValueRef | |
1052 | LLVMRustBuildCleanupRet(LLVMBuilderRef Builder, | |
1053 | LLVMValueRef CleanupPad, | |
1054 | LLVMBasicBlockRef UnwindBB) { | |
1055 | #if LLVM_VERSION_MINOR >= 8 | |
1056 | CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad)); | |
1057 | return wrap(unwrap(Builder)->CreateCleanupRet(Inst, unwrap(UnwindBB))); | |
1058 | #else | |
1059 | return NULL; | |
1060 | #endif | |
1061 | } | |
1062 | ||
1063 | extern "C" LLVMValueRef | |
1064 | LLVMRustBuildCatchPad(LLVMBuilderRef Builder, | |
1065 | LLVMValueRef ParentPad, | |
1066 | unsigned ArgCnt, | |
1067 | LLVMValueRef *LLArgs, | |
1068 | const char *Name) { | |
1069 | #if LLVM_VERSION_MINOR >= 8 | |
1070 | Value **Args = unwrap(LLArgs); | |
1071 | return wrap(unwrap(Builder)->CreateCatchPad(unwrap(ParentPad), | |
1072 | ArrayRef<Value*>(Args, ArgCnt), | |
1073 | Name)); | |
1074 | #else | |
1075 | return NULL; | |
1076 | #endif | |
1077 | } | |
1078 | ||
1079 | extern "C" LLVMValueRef | |
1080 | LLVMRustBuildCatchRet(LLVMBuilderRef Builder, | |
1081 | LLVMValueRef Pad, | |
1082 | LLVMBasicBlockRef BB) { | |
1083 | #if LLVM_VERSION_MINOR >= 8 | |
1084 | return wrap(unwrap(Builder)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)), | |
1085 | unwrap(BB))); | |
1086 | #else | |
1087 | return NULL; | |
1088 | #endif | |
1089 | } | |
1090 | ||
1091 | extern "C" LLVMValueRef | |
1092 | LLVMRustBuildCatchSwitch(LLVMBuilderRef Builder, | |
1093 | LLVMValueRef ParentPad, | |
1094 | LLVMBasicBlockRef BB, | |
1095 | unsigned NumHandlers, | |
1096 | const char *Name) { | |
1097 | #if LLVM_VERSION_MINOR >= 8 | |
1098 | if (ParentPad == NULL) { | |
1099 | Type *Ty = Type::getTokenTy(unwrap(Builder)->getContext()); | |
1100 | ParentPad = wrap(Constant::getNullValue(Ty)); | |
1101 | } | |
1102 | return wrap(unwrap(Builder)->CreateCatchSwitch(unwrap(ParentPad), | |
1103 | unwrap(BB), | |
1104 | NumHandlers, | |
1105 | Name)); | |
1106 | #else | |
1107 | return NULL; | |
1108 | #endif | |
1109 | } | |
1110 | ||
1111 | extern "C" void | |
1112 | LLVMRustAddHandler(LLVMValueRef CatchSwitchRef, | |
1113 | LLVMBasicBlockRef Handler) { | |
1114 | #if LLVM_VERSION_MINOR >= 8 | |
1115 | Value *CatchSwitch = unwrap(CatchSwitchRef); | |
1116 | cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler)); | |
1117 | #endif | |
1118 | } | |
1119 | ||
1120 | extern "C" void | |
1121 | LLVMRustSetPersonalityFn(LLVMBuilderRef B, | |
1122 | LLVMValueRef Personality) { | |
1123 | #if LLVM_VERSION_MINOR >= 8 | |
1124 | unwrap(B)->GetInsertBlock() | |
1125 | ->getParent() | |
1126 | ->setPersonalityFn(cast<Function>(unwrap(Personality))); | |
1127 | #endif | |
1128 | } | |
1129 | ||
1130 | #if LLVM_VERSION_MINOR >= 8 | |
1131 | extern "C" OperandBundleDef* | |
1132 | LLVMRustBuildOperandBundleDef(const char *Name, | |
1133 | LLVMValueRef *Inputs, | |
1134 | unsigned NumInputs) { | |
1135 | return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs)); | |
1136 | } | |
1137 | ||
1138 | extern "C" void | |
1139 | LLVMRustFreeOperandBundleDef(OperandBundleDef* Bundle) { | |
1140 | delete Bundle; | |
1141 | } | |
1142 | ||
1143 | extern "C" LLVMValueRef | |
1144 | LLVMRustBuildCall(LLVMBuilderRef B, | |
1145 | LLVMValueRef Fn, | |
1146 | LLVMValueRef *Args, | |
1147 | unsigned NumArgs, | |
1148 | OperandBundleDef *Bundle, | |
1149 | const char *Name) { | |
1150 | unsigned len = Bundle ? 1 : 0; | |
1151 | ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, len); | |
1152 | return wrap(unwrap(B)->CreateCall(unwrap(Fn), | |
1153 | makeArrayRef(unwrap(Args), NumArgs), | |
1154 | Bundles, | |
1155 | Name)); | |
1156 | } | |
1157 | ||
1158 | extern "C" LLVMValueRef | |
1159 | LLVMRustBuildInvoke(LLVMBuilderRef B, | |
1160 | LLVMValueRef Fn, | |
1161 | LLVMValueRef *Args, | |
1162 | unsigned NumArgs, | |
1163 | LLVMBasicBlockRef Then, | |
1164 | LLVMBasicBlockRef Catch, | |
1165 | OperandBundleDef *Bundle, | |
1166 | const char *Name) { | |
1167 | unsigned len = Bundle ? 1 : 0; | |
1168 | ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, len); | |
1169 | return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch), | |
1170 | makeArrayRef(unwrap(Args), NumArgs), | |
1171 | Bundles, | |
1172 | Name)); | |
1173 | } | |
1174 | #else | |
1175 | extern "C" void* | |
1176 | LLVMRustBuildOperandBundleDef(const char *Name, | |
1177 | LLVMValueRef *Inputs, | |
1178 | unsigned NumInputs) { | |
1179 | return NULL; | |
1180 | } | |
1181 | ||
1182 | extern "C" void | |
1183 | LLVMRustFreeOperandBundleDef(void* Bundle) { | |
1184 | } | |
1185 | ||
1186 | extern "C" LLVMValueRef | |
1187 | LLVMRustBuildCall(LLVMBuilderRef B, | |
1188 | LLVMValueRef Fn, | |
1189 | LLVMValueRef *Args, | |
1190 | unsigned NumArgs, | |
1191 | void *Bundle, | |
1192 | const char *Name) { | |
1193 | return LLVMBuildCall(B, Fn, Args, NumArgs, Name); | |
1194 | } | |
1195 | ||
1196 | extern "C" LLVMValueRef | |
1197 | LLVMRustBuildInvoke(LLVMBuilderRef B, | |
1198 | LLVMValueRef Fn, | |
1199 | LLVMValueRef *Args, | |
1200 | unsigned NumArgs, | |
1201 | LLVMBasicBlockRef Then, | |
1202 | LLVMBasicBlockRef Catch, | |
1203 | void *Bundle, | |
1204 | const char *Name) { | |
1205 | return LLVMBuildInvoke(B, Fn, Args, NumArgs, Then, Catch, Name); | |
1206 | } | |
1207 | #endif | |
54a0048b SL |
1208 | |
1209 | extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B, LLVMBasicBlockRef BB) { | |
1210 | auto point = unwrap(BB)->getFirstInsertionPt(); | |
1211 | unwrap(B)->SetInsertPoint(unwrap(BB), point); | |
1212 | } | |
1213 | ||
1214 | extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V, const char *Name) { | |
1215 | Triple TargetTriple(unwrap(M)->getTargetTriple()); | |
1216 | GlobalObject *GV = unwrap<GlobalObject>(V); | |
1217 | if (!TargetTriple.isOSBinFormatMachO()) { | |
1218 | GV->setComdat(unwrap(M)->getOrInsertComdat(Name)); | |
1219 | } | |
1220 | } | |
1221 | ||
1222 | extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) { | |
1223 | GlobalObject *GV = unwrap<GlobalObject>(V); | |
1224 | GV->setComdat(nullptr); | |
1225 | } |