]> git.proxmox.com Git - rustc.git/blame - src/rustllvm/RustWrapper.cpp
New upstream version 1.12.0+dfsg1
[rustc.git] / src / rustllvm / RustWrapper.cpp
CommitLineData
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
27using namespace llvm;
28using namespace llvm::sys;
1a4d82fc 29using namespace llvm::object;
223e47cc 30
5bcae85e
SL
31// LLVMAtomicOrdering is already an enum - don't create another
32// one.
33static 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 55static char *LastError;
970d7e83 56
223e47cc
LB
57extern "C" LLVMMemoryBufferRef
58LLVMRustCreateMemoryBufferWithContentsOfFile(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
69extern "C" char *LLVMRustGetLastError(void) {
70 char *ret = LastError;
71 LastError = NULL;
72 return ret;
223e47cc
LB
73}
74
1a4d82fc
JJ
75void LLVMRustSetLastError(const char *err) {
76 free((void*) LastError);
77 LastError = strdup(err);
223e47cc
LB
78}
79
1a4d82fc
JJ
80extern "C" void
81LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) {
82 unwrap(M)->setTargetTriple(Triple::normalize(triple));
223e47cc
LB
83}
84
223e47cc
LB
85extern "C" void LLVMRustPrintPassTimings() {
86 raw_fd_ostream OS (2, false); // stderr.
87 TimerGroup::printAll(OS);
88}
89
5bcae85e
SL
90extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M,
91 const char* Name) {
9346a6ac
AL
92 return wrap(unwrap(M)->getNamedValue(Name));
93}
94
5bcae85e
SL
95extern "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
102extern "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 108extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
223e47cc
LB
109 return wrap(Type::getMetadataTy(*unwrap(C)));
110}
970d7e83 111
5bcae85e 112extern "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
123extern "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
136extern "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
146extern "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
156extern "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
166extern "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
176extern "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
189extern "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
206extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
207 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
208 I->setHasUnsafeAlgebra(true);
209 }
210}
211
5bcae85e
SL
212extern "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
223extern "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 234extern "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
251enum class LLVMRustSynchronizationScope {
252 Other,
253 SingleThread,
254 CrossThread,
255};
256
257static SynchronizationScope
258from_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
270extern "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
278extern "C" void LLVMRustSetDebug(int Enabled) {
223e47cc
LB
279#ifndef NDEBUG
280 DebugFlag = Enabled;
281#endif
282}
283
5bcae85e
SL
284enum class LLVMRustAsmDialect {
285 Other,
286 Att,
287 Intel,
288};
289
290static InlineAsm::AsmDialect
291from_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
303extern "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 314typedef DIBuilder* LLVMRustDIBuilderRef;
970d7e83 315
5bcae85e 316typedef struct LLVMOpaqueMetadata *LLVMRustMetadataRef;
85aaf69f
SL
317
318namespace llvm {
5bcae85e 319DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMRustMetadataRef)
85aaf69f 320
5bcae85e 321inline Metadata **unwrap(LLVMRustMetadataRef *Vals) {
85aaf69f
SL
322 return reinterpret_cast<Metadata**>(Vals);
323}
324}
85aaf69f 325
62682a34 326template<typename DIT>
5bcae85e 327DIT* 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
335extern "C" uint32_t LLVMRustDebugMetadataVersion() {
336 return DEBUG_METADATA_VERSION;
337}
338
5bcae85e 339extern "C" uint32_t LLVMRustVersionMinor() {
62682a34
SL
340 return LLVM_VERSION_MINOR;
341}
342
5bcae85e 343extern "C" uint32_t LLVMRustVersionMajor() {
62682a34
SL
344 return LLVM_VERSION_MAJOR;
345}
1a4d82fc
JJ
346
347extern "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 353extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
970d7e83
LB
354 return new DIBuilder(*unwrap(M));
355}
356
5bcae85e 357extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
970d7e83
LB
358 delete Builder;
359}
360
5bcae85e 361extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
970d7e83
LB
362 Builder->finalize();
363}
364
5bcae85e
SL
365extern "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
385extern "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
392extern "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
403extern "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
443extern "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
454extern "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
464extern "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
494extern "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
512extern "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
524extern "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
546extern "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
582extern "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
594extern "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
606extern "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
613extern "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
622extern "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
639extern "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
656extern "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
664extern "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
686extern "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
713extern "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
729extern "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
743extern "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 752extern "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
769extern "C" int64_t LLVMRustDIBuilderCreateOpDeref()
770{
771 return dwarf::DW_OP_deref;
772}
773
774extern "C" int64_t LLVMRustDIBuilderCreateOpPlus()
775{
776 return dwarf::DW_OP_plus;
777}
778
779extern "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 784extern "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
793extern "C" bool
794LLVMRustLinkInExternalBitcode(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
830inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
831 return reinterpret_cast<section_iterator*>(SI);
832}
833
5bcae85e 834extern "C" size_t
1a4d82fc
JJ
835LLVMRustGetSectionName(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
844extern "C" LLVMTypeRef
845LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {
846 return wrap(ArrayType::get(unwrap(ElementType), ElementCount));
847}
848
849DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
850DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
851
852extern "C" void
5bcae85e 853LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
1a4d82fc
JJ
854 raw_rust_string_ostream os(str);
855 unwrap(T)->print(os);
856}
857
858extern "C" void
5bcae85e 859LLVMRustUnpackOptimizationDiagnostic(
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 876extern "C" void
5bcae85e 877LLVMRustUnpackInlineAsmDiagnostic(
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 892extern "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
898enum 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
913static LLVMRustDiagnosticKind
914to_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
948extern "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.
954extern "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 996extern "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
1005DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1006
5bcae85e 1007extern "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
1015extern "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
1021extern "C" LLVMValueRef
1022LLVMRustBuildLandingPad(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
1031extern "C" LLVMValueRef
1032LLVMRustBuildCleanupPad(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
1051extern "C" LLVMValueRef
1052LLVMRustBuildCleanupRet(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
1063extern "C" LLVMValueRef
1064LLVMRustBuildCatchPad(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
1079extern "C" LLVMValueRef
1080LLVMRustBuildCatchRet(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
1091extern "C" LLVMValueRef
1092LLVMRustBuildCatchSwitch(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
1111extern "C" void
1112LLVMRustAddHandler(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
1120extern "C" void
1121LLVMRustSetPersonalityFn(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
1131extern "C" OperandBundleDef*
1132LLVMRustBuildOperandBundleDef(const char *Name,
1133 LLVMValueRef *Inputs,
1134 unsigned NumInputs) {
1135 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1136}
1137
1138extern "C" void
1139LLVMRustFreeOperandBundleDef(OperandBundleDef* Bundle) {
1140 delete Bundle;
1141}
1142
1143extern "C" LLVMValueRef
1144LLVMRustBuildCall(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
1158extern "C" LLVMValueRef
1159LLVMRustBuildInvoke(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
1175extern "C" void*
1176LLVMRustBuildOperandBundleDef(const char *Name,
1177 LLVMValueRef *Inputs,
1178 unsigned NumInputs) {
1179 return NULL;
1180}
1181
1182extern "C" void
1183LLVMRustFreeOperandBundleDef(void* Bundle) {
1184}
1185
1186extern "C" LLVMValueRef
1187LLVMRustBuildCall(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
1196extern "C" LLVMValueRef
1197LLVMRustBuildInvoke(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
1209extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B, LLVMBasicBlockRef BB) {
1210 auto point = unwrap(BB)->getFirstInsertionPt();
1211 unwrap(B)->SetInsertPoint(unwrap(BB), point);
1212}
1213
1214extern "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
1222extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1223 GlobalObject *GV = unwrap<GlobalObject>(V);
1224 GV->setComdat(nullptr);
1225}