]> git.proxmox.com Git - rustc.git/blob - src/rustllvm/RustWrapper.cpp
New upstream version 1.15.0+dfsg1
[rustc.git] / src / rustllvm / RustWrapper.cpp
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
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
11 #include "rustllvm.h"
12 #include "llvm/Object/Archive.h"
13 #include "llvm/Object/ObjectFile.h"
14 #include "llvm/IR/DiagnosticInfo.h"
15 #include "llvm/IR/DiagnosticPrinter.h"
16 #include "llvm/IR/Instructions.h"
17
18 #include "llvm/IR/CallSite.h"
19
20 //===----------------------------------------------------------------------===
21 //
22 // This file defines alternate interfaces to core functions that are more
23 // readily callable by Rust's FFI.
24 //
25 //===----------------------------------------------------------------------===
26
27 using namespace llvm;
28 using namespace llvm::sys;
29 using namespace llvm::object;
30
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
55 static char *LastError;
56
57 extern "C" LLVMMemoryBufferRef
58 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
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;
65 }
66 return wrap(buf_or.get().release());
67 }
68
69 extern "C" char *LLVMRustGetLastError(void) {
70 char *ret = LastError;
71 LastError = NULL;
72 return ret;
73 }
74
75 void LLVMRustSetLastError(const char *err) {
76 free((void*) LastError);
77 LastError = strdup(err);
78 }
79
80 extern "C" void
81 LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) {
82 unwrap(M)->setTargetTriple(Triple::normalize(triple));
83 }
84
85 extern "C" void LLVMRustPrintPassTimings() {
86 raw_fd_ostream OS (2, false); // stderr.
87 TimerGroup::printAll(OS);
88 }
89
90 extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M,
91 const char* Name) {
92 return wrap(unwrap(M)->getNamedValue(Name));
93 }
94
95 extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
96 const char* Name,
97 LLVMTypeRef FunctionTy) {
98 return wrap(unwrap(M)->getOrInsertFunction(Name,
99 unwrap<FunctionType>(FunctionTy)));
100 }
101
102 extern "C" LLVMValueRef LLVMRustGetOrInsertGlobal(LLVMModuleRef M,
103 const char* Name,
104 LLVMTypeRef Ty) {
105 return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty)));
106 }
107
108 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
109 return wrap(Type::getMetadataTy(*unwrap(C)));
110 }
111
112 static Attribute::AttrKind
113 from_rust(LLVMRustAttribute kind) {
114 switch (kind) {
115 case AlwaysInline:
116 return Attribute::AlwaysInline;
117 case ByVal:
118 return Attribute::ByVal;
119 case Cold:
120 return Attribute::Cold;
121 case InlineHint:
122 return Attribute::InlineHint;
123 case MinSize:
124 return Attribute::MinSize;
125 case Naked:
126 return Attribute::Naked;
127 case NoAlias:
128 return Attribute::NoAlias;
129 case NoCapture:
130 return Attribute::NoCapture;
131 case NoInline:
132 return Attribute::NoInline;
133 case NonNull:
134 return Attribute::NonNull;
135 case NoRedZone:
136 return Attribute::NoRedZone;
137 case NoReturn:
138 return Attribute::NoReturn;
139 case NoUnwind:
140 return Attribute::NoUnwind;
141 case OptimizeForSize:
142 return Attribute::OptimizeForSize;
143 case ReadOnly:
144 return Attribute::ReadOnly;
145 case SExt:
146 return Attribute::SExt;
147 case StructRet:
148 return Attribute::StructRet;
149 case UWTable:
150 return Attribute::UWTable;
151 case ZExt:
152 return Attribute::ZExt;
153 default:
154 llvm_unreachable("bad AttributeKind");
155 }
156 }
157
158 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, LLVMRustAttribute attr) {
159 CallSite Call = CallSite(unwrap<Instruction>(Instr));
160 Attribute Attr = Attribute::get(Call->getContext(), from_rust(attr));
161 AttrBuilder B(Attr);
162 Call.setAttributes(
163 Call.getAttributes().addAttributes(Call->getContext(), index,
164 AttributeSet::get(Call->getContext(),
165 index, B)));
166 }
167
168 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
169 unsigned index,
170 uint64_t bytes)
171 {
172 CallSite Call = CallSite(unwrap<Instruction>(Instr));
173 AttrBuilder B;
174 B.addDereferenceableAttr(bytes);
175 Call.setAttributes(
176 Call.getAttributes().addAttributes(Call->getContext(), index,
177 AttributeSet::get(Call->getContext(),
178 index, B)));
179 }
180
181 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn,
182 unsigned index,
183 LLVMRustAttribute attr)
184 {
185 Function *A = unwrap<Function>(Fn);
186 Attribute Attr = Attribute::get(A->getContext(), from_rust(attr));
187 AttrBuilder B(Attr);
188 A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
189 }
190
191 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn,
192 unsigned index,
193 uint64_t bytes)
194 {
195 Function *A = unwrap<Function>(Fn);
196 AttrBuilder B;
197 B.addDereferenceableAttr(bytes);
198 A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
199 }
200
201 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
202 unsigned index,
203 const char *Name,
204 const char *Value) {
205 Function *F = unwrap<Function>(Fn);
206 AttrBuilder B;
207 B.addAttribute(Name, Value);
208 F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
209 }
210
211 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
212 unsigned index,
213 LLVMRustAttribute attr)
214 {
215 Function *F = unwrap<Function>(Fn);
216 const AttributeSet PAL = F->getAttributes();
217 Attribute Attr = Attribute::get(F->getContext(), from_rust(attr));
218 AttrBuilder B(Attr);
219 const AttributeSet PALnew =
220 PAL.removeAttributes(F->getContext(), index,
221 AttributeSet::get(F->getContext(), index, B));
222 F->setAttributes(PALnew);
223 }
224
225 // enable fpmath flag UnsafeAlgebra
226 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
227 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
228 I->setHasUnsafeAlgebra(true);
229 }
230 }
231
232 extern "C" LLVMValueRef LLVMRustBuildAtomicLoad(LLVMBuilderRef B,
233 LLVMValueRef source,
234 const char* Name,
235 LLVMAtomicOrdering order,
236 unsigned alignment) {
237 LoadInst* li = new LoadInst(unwrap(source),0);
238 li->setAtomic(from_rust(order));
239 li->setAlignment(alignment);
240 return wrap(unwrap(B)->Insert(li, Name));
241 }
242
243 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
244 LLVMValueRef val,
245 LLVMValueRef target,
246 LLVMAtomicOrdering order,
247 unsigned alignment) {
248 StoreInst* si = new StoreInst(unwrap(val),unwrap(target));
249 si->setAtomic(from_rust(order));
250 si->setAlignment(alignment);
251 return wrap(unwrap(B)->Insert(si));
252 }
253
254 extern "C" LLVMValueRef LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B,
255 LLVMValueRef target,
256 LLVMValueRef old,
257 LLVMValueRef source,
258 LLVMAtomicOrdering order,
259 LLVMAtomicOrdering failure_order,
260 LLVMBool weak) {
261 AtomicCmpXchgInst* acxi = unwrap(B)->CreateAtomicCmpXchg(
262 unwrap(target),
263 unwrap(old),
264 unwrap(source),
265 from_rust(order),
266 from_rust(failure_order));
267 acxi->setWeak(weak);
268 return wrap(acxi);
269 }
270
271 enum class LLVMRustSynchronizationScope {
272 Other,
273 SingleThread,
274 CrossThread,
275 };
276
277 static SynchronizationScope
278 from_rust(LLVMRustSynchronizationScope scope)
279 {
280 switch (scope) {
281 case LLVMRustSynchronizationScope::SingleThread:
282 return SingleThread;
283 case LLVMRustSynchronizationScope::CrossThread:
284 return CrossThread;
285 default:
286 llvm_unreachable("bad SynchronizationScope.");
287 }
288 }
289
290 extern "C" LLVMValueRef LLVMRustBuildAtomicFence(
291 LLVMBuilderRef B,
292 LLVMAtomicOrdering order,
293 LLVMRustSynchronizationScope scope)
294 {
295 return wrap(unwrap(B)->CreateFence(from_rust(order), from_rust(scope)));
296 }
297
298 extern "C" void LLVMRustSetDebug(int Enabled) {
299 #ifndef NDEBUG
300 DebugFlag = Enabled;
301 #endif
302 }
303
304 enum class LLVMRustAsmDialect {
305 Other,
306 Att,
307 Intel,
308 };
309
310 static InlineAsm::AsmDialect
311 from_rust(LLVMRustAsmDialect dialect)
312 {
313 switch (dialect) {
314 case LLVMRustAsmDialect::Att:
315 return InlineAsm::AD_ATT;
316 case LLVMRustAsmDialect::Intel:
317 return InlineAsm::AD_Intel;
318 default:
319 llvm_unreachable("bad AsmDialect.");
320 }
321 }
322
323 extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty,
324 char *AsmString,
325 char *Constraints,
326 LLVMBool HasSideEffects,
327 LLVMBool IsAlignStack,
328 LLVMRustAsmDialect Dialect) {
329 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
330 Constraints, HasSideEffects,
331 IsAlignStack, from_rust(Dialect)));
332 }
333
334 typedef DIBuilder* LLVMRustDIBuilderRef;
335
336 typedef struct LLVMOpaqueMetadata *LLVMRustMetadataRef;
337
338 namespace llvm {
339 DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMRustMetadataRef)
340
341 inline Metadata **unwrap(LLVMRustMetadataRef *Vals) {
342 return reinterpret_cast<Metadata**>(Vals);
343 }
344 }
345
346 template<typename DIT>
347 DIT* unwrapDIptr(LLVMRustMetadataRef ref) {
348 return (DIT*) (ref ? unwrap<MDNode>(ref) : NULL);
349 }
350
351 #define DIDescriptor DIScope
352 #define DIArray DINodeArray
353 #define unwrapDI unwrapDIptr
354
355 // These values **must** match debuginfo::DIFlags! They also *happen*
356 // to match LLVM, but that isn't required as we do giant sets of
357 // matching below. The value shouldn't be directly passed to LLVM.
358 enum class LLVMRustDIFlags : uint32_t {
359 FlagZero = 0,
360 FlagPrivate = 1,
361 FlagProtected = 2,
362 FlagPublic = 3,
363 FlagFwdDecl = (1 << 2),
364 FlagAppleBlock = (1 << 3),
365 FlagBlockByrefStruct = (1 << 4),
366 FlagVirtual = (1 << 5),
367 FlagArtificial = (1 << 6),
368 FlagExplicit = (1 << 7),
369 FlagPrototyped = (1 << 8),
370 FlagObjcClassComplete = (1 << 9),
371 FlagObjectPointer = (1 << 10),
372 FlagVector = (1 << 11),
373 FlagStaticMember = (1 << 12),
374 FlagLValueReference = (1 << 13),
375 FlagRValueReference = (1 << 14),
376 // Do not add values that are not supported by the minimum LLVM
377 // version we support!
378 };
379
380 inline LLVMRustDIFlags operator& (LLVMRustDIFlags a, LLVMRustDIFlags b) {
381 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(a) & static_cast<uint32_t>(b));
382 }
383
384 inline LLVMRustDIFlags operator| (LLVMRustDIFlags a, LLVMRustDIFlags b) {
385 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
386 }
387
388 inline LLVMRustDIFlags& operator|= (LLVMRustDIFlags& a, LLVMRustDIFlags b) {
389 return a = a | b;
390 }
391
392 inline bool is_set(LLVMRustDIFlags f) {
393 return f != LLVMRustDIFlags::FlagZero;
394 }
395
396 inline LLVMRustDIFlags visibility(LLVMRustDIFlags f) {
397 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(f) & 0x3);
398 }
399
400 #if LLVM_VERSION_GE(4, 0)
401 static DINode::DIFlags from_rust(LLVMRustDIFlags flags) {
402 DINode::DIFlags result = DINode::DIFlags::FlagZero;
403 #else
404 static unsigned from_rust(LLVMRustDIFlags flags) {
405 unsigned result = 0;
406 #endif
407
408 switch (visibility(flags)) {
409 case LLVMRustDIFlags::FlagPrivate:
410 result |= DINode::DIFlags::FlagPrivate;
411 break;
412 case LLVMRustDIFlags::FlagProtected:
413 result |= DINode::DIFlags::FlagProtected;
414 break;
415 case LLVMRustDIFlags::FlagPublic:
416 result |= DINode::DIFlags::FlagPublic;
417 break;
418 default:
419 // The rest are handled below
420 break;
421 }
422
423 if (is_set(flags & LLVMRustDIFlags::FlagFwdDecl)) { result |= DINode::DIFlags::FlagFwdDecl; }
424 if (is_set(flags & LLVMRustDIFlags::FlagAppleBlock)) { result |= DINode::DIFlags::FlagAppleBlock; }
425 if (is_set(flags & LLVMRustDIFlags::FlagBlockByrefStruct)) { result |= DINode::DIFlags::FlagBlockByrefStruct; }
426 if (is_set(flags & LLVMRustDIFlags::FlagVirtual)) { result |= DINode::DIFlags::FlagVirtual; }
427 if (is_set(flags & LLVMRustDIFlags::FlagArtificial)) { result |= DINode::DIFlags::FlagArtificial; }
428 if (is_set(flags & LLVMRustDIFlags::FlagExplicit)) { result |= DINode::DIFlags::FlagExplicit; }
429 if (is_set(flags & LLVMRustDIFlags::FlagPrototyped)) { result |= DINode::DIFlags::FlagPrototyped; }
430 if (is_set(flags & LLVMRustDIFlags::FlagObjcClassComplete)) { result |= DINode::DIFlags::FlagObjcClassComplete; }
431 if (is_set(flags & LLVMRustDIFlags::FlagObjectPointer)) { result |= DINode::DIFlags::FlagObjectPointer; }
432 if (is_set(flags & LLVMRustDIFlags::FlagVector)) { result |= DINode::DIFlags::FlagVector; }
433 if (is_set(flags & LLVMRustDIFlags::FlagStaticMember)) { result |= DINode::DIFlags::FlagStaticMember; }
434 if (is_set(flags & LLVMRustDIFlags::FlagLValueReference)) { result |= DINode::DIFlags::FlagLValueReference; }
435 if (is_set(flags & LLVMRustDIFlags::FlagRValueReference)) { result |= DINode::DIFlags::FlagRValueReference; }
436
437 return result;
438 }
439
440 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
441 return DEBUG_METADATA_VERSION;
442 }
443
444 extern "C" uint32_t LLVMRustVersionMinor() {
445 return LLVM_VERSION_MINOR;
446 }
447
448 extern "C" uint32_t LLVMRustVersionMajor() {
449 return LLVM_VERSION_MAJOR;
450 }
451
452 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
453 const char *name,
454 uint32_t value) {
455 unwrap(M)->addModuleFlag(Module::Warning, name, value);
456 }
457
458 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
459 return new DIBuilder(*unwrap(M));
460 }
461
462 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
463 delete Builder;
464 }
465
466 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
467 Builder->finalize();
468 }
469
470 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateCompileUnit(
471 LLVMRustDIBuilderRef Builder,
472 unsigned Lang,
473 const char* File,
474 const char* Dir,
475 const char* Producer,
476 bool isOptimized,
477 const char* Flags,
478 unsigned RuntimeVer,
479 const char* SplitName) {
480 return wrap(Builder->createCompileUnit(Lang,
481 File,
482 Dir,
483 Producer,
484 isOptimized,
485 Flags,
486 RuntimeVer,
487 SplitName));
488 }
489
490 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFile(
491 LLVMRustDIBuilderRef Builder,
492 const char* Filename,
493 const char* Directory) {
494 return wrap(Builder->createFile(Filename, Directory));
495 }
496
497 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateSubroutineType(
498 LLVMRustDIBuilderRef Builder,
499 LLVMRustMetadataRef File,
500 LLVMRustMetadataRef ParameterTypes) {
501 return wrap(Builder->createSubroutineType(
502 #if LLVM_VERSION_EQ(3, 7)
503 unwrapDI<DIFile>(File),
504 #endif
505 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
506 }
507
508 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction(
509 LLVMRustDIBuilderRef Builder,
510 LLVMRustMetadataRef Scope,
511 const char* Name,
512 const char* LinkageName,
513 LLVMRustMetadataRef File,
514 unsigned LineNo,
515 LLVMRustMetadataRef Ty,
516 bool isLocalToUnit,
517 bool isDefinition,
518 unsigned ScopeLine,
519 LLVMRustDIFlags Flags,
520 bool isOptimized,
521 LLVMValueRef Fn,
522 LLVMRustMetadataRef TParam,
523 LLVMRustMetadataRef Decl) {
524 #if LLVM_VERSION_GE(3, 8)
525 DITemplateParameterArray TParams =
526 DITemplateParameterArray(unwrap<MDTuple>(TParam));
527 DISubprogram *Sub = Builder->createFunction(
528 unwrapDI<DIScope>(Scope), Name, LinkageName,
529 unwrapDI<DIFile>(File), LineNo,
530 unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
531 from_rust(Flags), isOptimized,
532 TParams,
533 unwrapDIptr<DISubprogram>(Decl));
534 unwrap<Function>(Fn)->setSubprogram(Sub);
535 return wrap(Sub);
536 #else
537 return wrap(Builder->createFunction(
538 unwrapDI<DIScope>(Scope), Name, LinkageName,
539 unwrapDI<DIFile>(File), LineNo,
540 unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
541 from_rust(Flags), isOptimized,
542 unwrap<Function>(Fn),
543 unwrapDIptr<MDNode>(TParam),
544 unwrapDIptr<MDNode>(Decl)));
545 #endif
546 }
547
548 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateBasicType(
549 LLVMRustDIBuilderRef Builder,
550 const char* Name,
551 uint64_t SizeInBits,
552 uint64_t AlignInBits,
553 unsigned Encoding) {
554 return wrap(Builder->createBasicType(
555 Name,
556 SizeInBits,
557 #if LLVM_VERSION_LE(3, 9)
558 AlignInBits,
559 #endif
560 Encoding
561 ));
562 }
563
564 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreatePointerType(
565 LLVMRustDIBuilderRef Builder,
566 LLVMRustMetadataRef PointeeTy,
567 uint64_t SizeInBits,
568 uint64_t AlignInBits,
569 const char* Name) {
570 return wrap(Builder->createPointerType(
571 unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
572 }
573
574 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType(
575 LLVMRustDIBuilderRef Builder,
576 LLVMRustMetadataRef Scope,
577 const char* Name,
578 LLVMRustMetadataRef File,
579 unsigned LineNumber,
580 uint64_t SizeInBits,
581 uint64_t AlignInBits,
582 LLVMRustDIFlags Flags,
583 LLVMRustMetadataRef DerivedFrom,
584 LLVMRustMetadataRef Elements,
585 unsigned RunTimeLang,
586 LLVMRustMetadataRef VTableHolder,
587 const char *UniqueId) {
588 return wrap(Builder->createStructType(
589 unwrapDI<DIDescriptor>(Scope),
590 Name,
591 unwrapDI<DIFile>(File),
592 LineNumber,
593 SizeInBits,
594 AlignInBits,
595 from_rust(Flags),
596 unwrapDI<DIType>(DerivedFrom),
597 DINodeArray(unwrapDI<MDTuple>(Elements)),
598 RunTimeLang,
599 unwrapDI<DIType>(VTableHolder),
600 UniqueId
601 ));
602 }
603
604 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateMemberType(
605 LLVMRustDIBuilderRef Builder,
606 LLVMRustMetadataRef Scope,
607 const char* Name,
608 LLVMRustMetadataRef File,
609 unsigned LineNo,
610 uint64_t SizeInBits,
611 uint64_t AlignInBits,
612 uint64_t OffsetInBits,
613 LLVMRustDIFlags Flags,
614 LLVMRustMetadataRef Ty) {
615 return wrap(Builder->createMemberType(
616 unwrapDI<DIDescriptor>(Scope), Name,
617 unwrapDI<DIFile>(File), LineNo,
618 SizeInBits, AlignInBits, OffsetInBits, from_rust(Flags),
619 unwrapDI<DIType>(Ty)));
620 }
621
622 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
623 LLVMRustDIBuilderRef Builder,
624 LLVMRustMetadataRef Scope,
625 LLVMRustMetadataRef File,
626 unsigned Line,
627 unsigned Col) {
628 return wrap(Builder->createLexicalBlock(
629 unwrapDI<DIDescriptor>(Scope),
630 unwrapDI<DIFile>(File), Line, Col
631 ));
632 }
633
634 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlockFile(
635 LLVMRustDIBuilderRef Builder,
636 LLVMRustMetadataRef Scope,
637 LLVMRustMetadataRef File) {
638 return wrap(Builder->createLexicalBlockFile(
639 unwrapDI<DIDescriptor>(Scope),
640 unwrapDI<DIFile>(File)));
641 }
642
643 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable(
644 LLVMRustDIBuilderRef Builder,
645 LLVMRustMetadataRef Context,
646 const char* Name,
647 const char* LinkageName,
648 LLVMRustMetadataRef File,
649 unsigned LineNo,
650 LLVMRustMetadataRef Ty,
651 bool isLocalToUnit,
652 LLVMValueRef Val,
653 LLVMRustMetadataRef Decl = NULL,
654 uint64_t AlignInBits = 0) {
655 Constant *InitVal = cast<Constant>(unwrap(Val));
656
657 #if LLVM_VERSION_GE(4, 0)
658 llvm::DIExpression *InitExpr = nullptr;
659 if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
660 InitExpr = Builder->createConstantValueExpression(
661 IntVal->getValue().getSExtValue());
662 } else if (llvm::ConstantFP *FPVal = llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
663 InitExpr = Builder->createConstantValueExpression(
664 FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
665 }
666 #endif
667
668 return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context),
669 Name,
670 LinkageName,
671 unwrapDI<DIFile>(File),
672 LineNo,
673 unwrapDI<DIType>(Ty),
674 isLocalToUnit,
675 #if LLVM_VERSION_GE(4, 0)
676 InitExpr,
677 #else
678 InitVal,
679 #endif
680 unwrapDIptr<MDNode>(Decl)
681 #if LLVM_VERSION_GE(4, 0)
682 , AlignInBits
683 #endif
684 ));
685 }
686
687 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(
688 LLVMRustDIBuilderRef Builder,
689 unsigned Tag,
690 LLVMRustMetadataRef Scope,
691 const char* Name,
692 LLVMRustMetadataRef File,
693 unsigned LineNo,
694 LLVMRustMetadataRef Ty,
695 bool AlwaysPreserve,
696 LLVMRustDIFlags Flags,
697 unsigned ArgNo,
698 uint64_t AlignInBits)
699 {
700 #if LLVM_VERSION_GE(3, 8)
701 if (Tag == 0x100) { // DW_TAG_auto_variable
702 return wrap(Builder->createAutoVariable(
703 unwrapDI<DIDescriptor>(Scope),
704 Name,
705 unwrapDI<DIFile>(File),
706 LineNo,
707 unwrapDI<DIType>(Ty),
708 AlwaysPreserve,
709 from_rust(Flags)
710 #if LLVM_VERSION_GE(4,0)
711 , AlignInBits
712 #endif
713 ));
714 } else {
715 return wrap(Builder->createParameterVariable(
716 unwrapDI<DIDescriptor>(Scope), Name, ArgNo,
717 unwrapDI<DIFile>(File),
718 LineNo,
719 unwrapDI<DIType>(Ty), AlwaysPreserve, from_rust(Flags)));
720 }
721 #else
722 return wrap(Builder->createLocalVariable(Tag,
723 unwrapDI<DIDescriptor>(Scope), Name,
724 unwrapDI<DIFile>(File),
725 LineNo,
726 unwrapDI<DIType>(Ty), AlwaysPreserve, from_rust(Flags), ArgNo));
727 #endif
728 }
729
730 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateArrayType(
731 LLVMRustDIBuilderRef Builder,
732 uint64_t Size,
733 uint64_t AlignInBits,
734 LLVMRustMetadataRef Ty,
735 LLVMRustMetadataRef Subscripts) {
736 return wrap(Builder->createArrayType(Size, AlignInBits,
737 unwrapDI<DIType>(Ty),
738 DINodeArray(unwrapDI<MDTuple>(Subscripts))
739 ));
740 }
741
742 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVectorType(
743 LLVMRustDIBuilderRef Builder,
744 uint64_t Size,
745 uint64_t AlignInBits,
746 LLVMRustMetadataRef Ty,
747 LLVMRustMetadataRef Subscripts) {
748 return wrap(Builder->createVectorType(Size, AlignInBits,
749 unwrapDI<DIType>(Ty),
750 DINodeArray(unwrapDI<MDTuple>(Subscripts))
751 ));
752 }
753
754 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateSubrange(
755 LLVMRustDIBuilderRef Builder,
756 int64_t Lo,
757 int64_t Count) {
758 return wrap(Builder->getOrCreateSubrange(Lo, Count));
759 }
760
761 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateArray(
762 LLVMRustDIBuilderRef Builder,
763 LLVMRustMetadataRef* Ptr,
764 unsigned Count) {
765 Metadata **DataValue = unwrap(Ptr);
766 return wrap(Builder->getOrCreateArray(
767 ArrayRef<Metadata*>(DataValue, Count)).get());
768 }
769
770 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
771 LLVMRustDIBuilderRef Builder,
772 LLVMValueRef Val,
773 LLVMRustMetadataRef VarInfo,
774 int64_t* AddrOps,
775 unsigned AddrOpsCount,
776 LLVMValueRef DL,
777 LLVMBasicBlockRef InsertAtEnd) {
778 return wrap(Builder->insertDeclare(
779 unwrap(Val),
780 unwrap<DILocalVariable>(VarInfo),
781 Builder->createExpression(
782 llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
783 DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
784 unwrap(InsertAtEnd)));
785 }
786
787 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerator(
788 LLVMRustDIBuilderRef Builder,
789 const char* Name,
790 uint64_t Val)
791 {
792 return wrap(Builder->createEnumerator(Name, Val));
793 }
794
795 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerationType(
796 LLVMRustDIBuilderRef Builder,
797 LLVMRustMetadataRef Scope,
798 const char* Name,
799 LLVMRustMetadataRef File,
800 unsigned LineNumber,
801 uint64_t SizeInBits,
802 uint64_t AlignInBits,
803 LLVMRustMetadataRef Elements,
804 LLVMRustMetadataRef ClassType)
805 {
806 return wrap(Builder->createEnumerationType(
807 unwrapDI<DIDescriptor>(Scope),
808 Name,
809 unwrapDI<DIFile>(File),
810 LineNumber,
811 SizeInBits,
812 AlignInBits,
813 DINodeArray(unwrapDI<MDTuple>(Elements)),
814 unwrapDI<DIType>(ClassType)));
815 }
816
817 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType(
818 LLVMRustDIBuilderRef Builder,
819 LLVMRustMetadataRef Scope,
820 const char* Name,
821 LLVMRustMetadataRef File,
822 unsigned LineNumber,
823 uint64_t SizeInBits,
824 uint64_t AlignInBits,
825 LLVMRustDIFlags Flags,
826 LLVMRustMetadataRef Elements,
827 unsigned RunTimeLang,
828 const char* UniqueId)
829 {
830 return wrap(Builder->createUnionType(
831 unwrapDI<DIDescriptor>(Scope),
832 Name,
833 unwrapDI<DIFile>(File),
834 LineNumber,
835 SizeInBits,
836 AlignInBits,
837 from_rust(Flags),
838 DINodeArray(unwrapDI<MDTuple>(Elements)),
839 RunTimeLang,
840 UniqueId
841 ));
842 }
843
844 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
845 LLVMRustDIBuilderRef Builder,
846 LLVMRustMetadataRef Scope,
847 const char* Name,
848 LLVMRustMetadataRef Ty,
849 LLVMRustMetadataRef File,
850 unsigned LineNo,
851 unsigned ColumnNo)
852 {
853 return wrap(Builder->createTemplateTypeParameter(
854 unwrapDI<DIDescriptor>(Scope),
855 Name,
856 unwrapDI<DIType>(Ty)
857 ));
858 }
859
860 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateNameSpace(
861 LLVMRustDIBuilderRef Builder,
862 LLVMRustMetadataRef Scope,
863 const char* Name,
864 LLVMRustMetadataRef File,
865 unsigned LineNo)
866 {
867 return wrap(Builder->createNameSpace(
868 unwrapDI<DIDescriptor>(Scope),
869 Name,
870 unwrapDI<DIFile>(File),
871 LineNo
872 #if LLVM_VERSION_GE(4, 0)
873 , false // ExportSymbols (only relevant for C++ anonymous namespaces)
874 #endif
875 ));
876 }
877
878 extern "C" void LLVMRustDICompositeTypeSetTypeArray(
879 LLVMRustDIBuilderRef Builder,
880 LLVMRustMetadataRef CompositeType,
881 LLVMRustMetadataRef TypeArray)
882 {
883 DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType);
884 Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray)));
885 }
886
887 extern "C" LLVMValueRef LLVMRustDIBuilderCreateDebugLocation(
888 LLVMContextRef Context,
889 unsigned Line,
890 unsigned Column,
891 LLVMRustMetadataRef Scope,
892 LLVMRustMetadataRef InlinedAt)
893 {
894 LLVMContext& context = *unwrap(Context);
895
896 DebugLoc debug_loc = DebugLoc::get(Line,
897 Column,
898 unwrapDIptr<MDNode>(Scope),
899 unwrapDIptr<MDNode>(InlinedAt));
900
901 return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode()));
902 }
903
904 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref()
905 {
906 return dwarf::DW_OP_deref;
907 }
908
909 extern "C" int64_t LLVMRustDIBuilderCreateOpPlus()
910 {
911 return dwarf::DW_OP_plus;
912 }
913
914 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
915 raw_rust_string_ostream os(str);
916 unwrap<llvm::Type>(Type)->print(os);
917 }
918
919 extern "C" void LLVMRustWriteValueToString(LLVMValueRef Value, RustStringRef str) {
920 raw_rust_string_ostream os(str);
921 os << "(";
922 unwrap<llvm::Value>(Value)->getType()->print(os);
923 os << ":";
924 unwrap<llvm::Value>(Value)->print(os);
925 os << ")";
926 }
927
928 extern "C" bool
929 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
930 Module *Dst = unwrap(dst);
931
932 std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
933
934 #if LLVM_VERSION_GE(4, 0)
935 Expected<std::unique_ptr<Module>> SrcOrError =
936 llvm::getLazyBitcodeModule(buf->getMemBufferRef(), Dst->getContext());
937 if (!SrcOrError) {
938 LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
939 return false;
940 }
941
942 auto Src = std::move(*SrcOrError);
943 #else
944 ErrorOr<std::unique_ptr<Module>> Src =
945 llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
946 if (!Src) {
947 LLVMRustSetLastError(Src.getError().message().c_str());
948 return false;
949 }
950 #endif
951
952 std::string Err;
953
954 raw_string_ostream Stream(Err);
955 DiagnosticPrinterRawOStream DP(Stream);
956 #if LLVM_VERSION_GE(4, 0)
957 if (Linker::linkModules(*Dst, std::move(Src))) {
958 #elif LLVM_VERSION_GE(3, 8)
959 if (Linker::linkModules(*Dst, std::move(Src.get()))) {
960 #else
961 if (Linker::LinkModules(Dst, Src->get(), [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
962 #endif
963 LLVMRustSetLastError(Err.c_str());
964 return false;
965 }
966 return true;
967 }
968
969 // Note that the two following functions look quite similar to the
970 // LLVMGetSectionName function. Sadly, it appears that this function only
971 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
972 // function provided by LLVM doesn't return the length, so we've created our own
973 // function which returns the length as well as the data pointer.
974 //
975 // For an example of this not returning a null terminated string, see
976 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
977 // branches explicitly creates a StringRef without a null terminator, and then
978 // that's returned.
979
980 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
981 return reinterpret_cast<section_iterator*>(SI);
982 }
983
984 extern "C" size_t
985 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
986 StringRef ret;
987 if (std::error_code ec = (*unwrap(SI))->getName(ret))
988 report_fatal_error(ec.message());
989 *ptr = ret.data();
990 return ret.size();
991 }
992
993 // LLVMArrayType function does not support 64-bit ElementCount
994 extern "C" LLVMTypeRef
995 LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {
996 return wrap(ArrayType::get(unwrap(ElementType), ElementCount));
997 }
998
999 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1000 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
1001
1002 extern "C" void
1003 LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
1004 raw_rust_string_ostream os(str);
1005 unwrap(T)->print(os);
1006 }
1007
1008 extern "C" void
1009 LLVMRustUnpackOptimizationDiagnostic(
1010 LLVMDiagnosticInfoRef di,
1011 RustStringRef pass_name_out,
1012 LLVMValueRef *function_out,
1013 LLVMDebugLocRef *debugloc_out,
1014 RustStringRef message_out)
1015 {
1016 // Undefined to call this not on an optimization diagnostic!
1017 llvm::DiagnosticInfoOptimizationBase *opt
1018 = static_cast<llvm::DiagnosticInfoOptimizationBase*>(unwrap(di));
1019
1020 raw_rust_string_ostream pass_name_os(pass_name_out);
1021 pass_name_os << opt->getPassName();
1022 *function_out = wrap(&opt->getFunction());
1023 *debugloc_out = wrap(&opt->getDebugLoc());
1024 raw_rust_string_ostream message_os(message_out);
1025 message_os << opt->getMsg();
1026 }
1027
1028 extern "C" void
1029 LLVMRustUnpackInlineAsmDiagnostic(
1030 LLVMDiagnosticInfoRef di,
1031 unsigned *cookie_out,
1032 LLVMTwineRef *message_out,
1033 LLVMValueRef *instruction_out)
1034 {
1035 // Undefined to call this not on an inline assembly diagnostic!
1036 llvm::DiagnosticInfoInlineAsm *ia
1037 = static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di));
1038
1039 *cookie_out = ia->getLocCookie();
1040 *message_out = wrap(&ia->getMsgStr());
1041 *instruction_out = wrap(ia->getInstruction());
1042 }
1043
1044 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
1045 raw_rust_string_ostream os(str);
1046 DiagnosticPrinterRawOStream dp(os);
1047 unwrap(di)->print(dp);
1048 }
1049
1050 enum class LLVMRustDiagnosticKind {
1051 Other,
1052 InlineAsm,
1053 StackSize,
1054 DebugMetadataVersion,
1055 SampleProfile,
1056 OptimizationRemark,
1057 OptimizationRemarkMissed,
1058 OptimizationRemarkAnalysis,
1059 OptimizationRemarkAnalysisFPCommute,
1060 OptimizationRemarkAnalysisAliasing,
1061 OptimizationRemarkOther,
1062 OptimizationFailure,
1063 };
1064
1065 static LLVMRustDiagnosticKind
1066 to_rust(DiagnosticKind kind)
1067 {
1068 switch (kind) {
1069 case DK_InlineAsm:
1070 return LLVMRustDiagnosticKind::InlineAsm;
1071 case DK_StackSize:
1072 return LLVMRustDiagnosticKind::StackSize;
1073 case DK_DebugMetadataVersion:
1074 return LLVMRustDiagnosticKind::DebugMetadataVersion;
1075 case DK_SampleProfile:
1076 return LLVMRustDiagnosticKind::SampleProfile;
1077 case DK_OptimizationRemark:
1078 return LLVMRustDiagnosticKind::OptimizationRemark;
1079 case DK_OptimizationRemarkMissed:
1080 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1081 case DK_OptimizationRemarkAnalysis:
1082 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1083 #if LLVM_VERSION_GE(3, 8)
1084 case DK_OptimizationRemarkAnalysisFPCommute:
1085 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1086 case DK_OptimizationRemarkAnalysisAliasing:
1087 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1088 #endif
1089 default:
1090 #if LLVM_VERSION_GE(3, 9)
1091 return (kind >= DK_FirstRemark && kind <= DK_LastRemark) ?
1092 LLVMRustDiagnosticKind::OptimizationRemarkOther :
1093 LLVMRustDiagnosticKind::Other;
1094 #else
1095 return LLVMRustDiagnosticKind::Other;
1096 #endif
1097 }
1098 }
1099
1100 extern "C" LLVMRustDiagnosticKind LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
1101 return to_rust((DiagnosticKind) unwrap(di)->getKind());
1102 }
1103 // This is kept distinct from LLVMGetTypeKind, because when
1104 // a new type kind is added, the Rust-side enum must be
1105 // updated or UB will result.
1106 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1107 switch (unwrap(Ty)->getTypeID()) {
1108 case Type::VoidTyID:
1109 return LLVMVoidTypeKind;
1110 case Type::HalfTyID:
1111 return LLVMHalfTypeKind;
1112 case Type::FloatTyID:
1113 return LLVMFloatTypeKind;
1114 case Type::DoubleTyID:
1115 return LLVMDoubleTypeKind;
1116 case Type::X86_FP80TyID:
1117 return LLVMX86_FP80TypeKind;
1118 case Type::FP128TyID:
1119 return LLVMFP128TypeKind;
1120 case Type::PPC_FP128TyID:
1121 return LLVMPPC_FP128TypeKind;
1122 case Type::LabelTyID:
1123 return LLVMLabelTypeKind;
1124 case Type::MetadataTyID:
1125 return LLVMMetadataTypeKind;
1126 case Type::IntegerTyID:
1127 return LLVMIntegerTypeKind;
1128 case Type::FunctionTyID:
1129 return LLVMFunctionTypeKind;
1130 case Type::StructTyID:
1131 return LLVMStructTypeKind;
1132 case Type::ArrayTyID:
1133 return LLVMArrayTypeKind;
1134 case Type::PointerTyID:
1135 return LLVMPointerTypeKind;
1136 case Type::VectorTyID:
1137 return LLVMVectorTypeKind;
1138 case Type::X86_MMXTyID:
1139 return LLVMX86_MMXTypeKind;
1140 #if LLVM_VERSION_GE(3, 8)
1141 case Type::TokenTyID:
1142 return LLVMTokenTypeKind;
1143 #endif
1144 }
1145 llvm_unreachable("Unhandled TypeID.");
1146 }
1147
1148 extern "C" void LLVMRustWriteDebugLocToString(
1149 LLVMContextRef C,
1150 LLVMDebugLocRef dl,
1151 RustStringRef str)
1152 {
1153 raw_rust_string_ostream os(str);
1154 unwrap(dl)->print(os);
1155 }
1156
1157 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1158
1159 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1160 LLVMContextRef C,
1161 LLVMContext::InlineAsmDiagHandlerTy H,
1162 void *CX)
1163 {
1164 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1165 }
1166
1167 extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef d,
1168 RustStringRef str) {
1169 raw_rust_string_ostream os(str);
1170 unwrap(d)->print("", os);
1171 }
1172
1173 extern "C" LLVMValueRef
1174 LLVMRustBuildLandingPad(LLVMBuilderRef Builder,
1175 LLVMTypeRef Ty,
1176 LLVMValueRef PersFn,
1177 unsigned NumClauses,
1178 const char* Name,
1179 LLVMValueRef F) {
1180 return LLVMBuildLandingPad(Builder, Ty, PersFn, NumClauses, Name);
1181 }
1182
1183 extern "C" LLVMValueRef
1184 LLVMRustBuildCleanupPad(LLVMBuilderRef Builder,
1185 LLVMValueRef ParentPad,
1186 unsigned ArgCnt,
1187 LLVMValueRef *LLArgs,
1188 const char *Name) {
1189 #if LLVM_VERSION_GE(3, 8)
1190 Value **Args = unwrap(LLArgs);
1191 if (ParentPad == NULL) {
1192 Type *Ty = Type::getTokenTy(unwrap(Builder)->getContext());
1193 ParentPad = wrap(Constant::getNullValue(Ty));
1194 }
1195 return wrap(unwrap(Builder)->CreateCleanupPad(unwrap(ParentPad),
1196 ArrayRef<Value*>(Args, ArgCnt),
1197 Name));
1198 #else
1199 return NULL;
1200 #endif
1201 }
1202
1203 extern "C" LLVMValueRef
1204 LLVMRustBuildCleanupRet(LLVMBuilderRef Builder,
1205 LLVMValueRef CleanupPad,
1206 LLVMBasicBlockRef UnwindBB) {
1207 #if LLVM_VERSION_GE(3, 8)
1208 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1209 return wrap(unwrap(Builder)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1210 #else
1211 return NULL;
1212 #endif
1213 }
1214
1215 extern "C" LLVMValueRef
1216 LLVMRustBuildCatchPad(LLVMBuilderRef Builder,
1217 LLVMValueRef ParentPad,
1218 unsigned ArgCnt,
1219 LLVMValueRef *LLArgs,
1220 const char *Name) {
1221 #if LLVM_VERSION_GE(3, 8)
1222 Value **Args = unwrap(LLArgs);
1223 return wrap(unwrap(Builder)->CreateCatchPad(unwrap(ParentPad),
1224 ArrayRef<Value*>(Args, ArgCnt),
1225 Name));
1226 #else
1227 return NULL;
1228 #endif
1229 }
1230
1231 extern "C" LLVMValueRef
1232 LLVMRustBuildCatchRet(LLVMBuilderRef Builder,
1233 LLVMValueRef Pad,
1234 LLVMBasicBlockRef BB) {
1235 #if LLVM_VERSION_GE(3, 8)
1236 return wrap(unwrap(Builder)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1237 unwrap(BB)));
1238 #else
1239 return NULL;
1240 #endif
1241 }
1242
1243 extern "C" LLVMValueRef
1244 LLVMRustBuildCatchSwitch(LLVMBuilderRef Builder,
1245 LLVMValueRef ParentPad,
1246 LLVMBasicBlockRef BB,
1247 unsigned NumHandlers,
1248 const char *Name) {
1249 #if LLVM_VERSION_GE(3, 8)
1250 if (ParentPad == NULL) {
1251 Type *Ty = Type::getTokenTy(unwrap(Builder)->getContext());
1252 ParentPad = wrap(Constant::getNullValue(Ty));
1253 }
1254 return wrap(unwrap(Builder)->CreateCatchSwitch(unwrap(ParentPad),
1255 unwrap(BB),
1256 NumHandlers,
1257 Name));
1258 #else
1259 return NULL;
1260 #endif
1261 }
1262
1263 extern "C" void
1264 LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1265 LLVMBasicBlockRef Handler) {
1266 #if LLVM_VERSION_GE(3, 8)
1267 Value *CatchSwitch = unwrap(CatchSwitchRef);
1268 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1269 #endif
1270 }
1271
1272 extern "C" void
1273 LLVMRustSetPersonalityFn(LLVMBuilderRef B,
1274 LLVMValueRef Personality) {
1275 #if LLVM_VERSION_GE(3, 8)
1276 unwrap(B)->GetInsertBlock()
1277 ->getParent()
1278 ->setPersonalityFn(cast<Function>(unwrap(Personality)));
1279 #endif
1280 }
1281
1282 #if LLVM_VERSION_GE(3, 8)
1283 extern "C" OperandBundleDef*
1284 LLVMRustBuildOperandBundleDef(const char *Name,
1285 LLVMValueRef *Inputs,
1286 unsigned NumInputs) {
1287 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1288 }
1289
1290 extern "C" void
1291 LLVMRustFreeOperandBundleDef(OperandBundleDef* Bundle) {
1292 delete Bundle;
1293 }
1294
1295 extern "C" LLVMValueRef
1296 LLVMRustBuildCall(LLVMBuilderRef B,
1297 LLVMValueRef Fn,
1298 LLVMValueRef *Args,
1299 unsigned NumArgs,
1300 OperandBundleDef *Bundle,
1301 const char *Name) {
1302 unsigned len = Bundle ? 1 : 0;
1303 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, len);
1304 return wrap(unwrap(B)->CreateCall(unwrap(Fn),
1305 makeArrayRef(unwrap(Args), NumArgs),
1306 Bundles,
1307 Name));
1308 }
1309
1310 extern "C" LLVMValueRef
1311 LLVMRustBuildInvoke(LLVMBuilderRef B,
1312 LLVMValueRef Fn,
1313 LLVMValueRef *Args,
1314 unsigned NumArgs,
1315 LLVMBasicBlockRef Then,
1316 LLVMBasicBlockRef Catch,
1317 OperandBundleDef *Bundle,
1318 const char *Name) {
1319 unsigned len = Bundle ? 1 : 0;
1320 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, len);
1321 return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch),
1322 makeArrayRef(unwrap(Args), NumArgs),
1323 Bundles,
1324 Name));
1325 }
1326 #else
1327 extern "C" void*
1328 LLVMRustBuildOperandBundleDef(const char *Name,
1329 LLVMValueRef *Inputs,
1330 unsigned NumInputs) {
1331 return NULL;
1332 }
1333
1334 extern "C" void
1335 LLVMRustFreeOperandBundleDef(void* Bundle) {
1336 }
1337
1338 extern "C" LLVMValueRef
1339 LLVMRustBuildCall(LLVMBuilderRef B,
1340 LLVMValueRef Fn,
1341 LLVMValueRef *Args,
1342 unsigned NumArgs,
1343 void *Bundle,
1344 const char *Name) {
1345 return LLVMBuildCall(B, Fn, Args, NumArgs, Name);
1346 }
1347
1348 extern "C" LLVMValueRef
1349 LLVMRustBuildInvoke(LLVMBuilderRef B,
1350 LLVMValueRef Fn,
1351 LLVMValueRef *Args,
1352 unsigned NumArgs,
1353 LLVMBasicBlockRef Then,
1354 LLVMBasicBlockRef Catch,
1355 void *Bundle,
1356 const char *Name) {
1357 return LLVMBuildInvoke(B, Fn, Args, NumArgs, Then, Catch, Name);
1358 }
1359 #endif
1360
1361 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B, LLVMBasicBlockRef BB) {
1362 auto point = unwrap(BB)->getFirstInsertionPt();
1363 unwrap(B)->SetInsertPoint(unwrap(BB), point);
1364 }
1365
1366 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V, const char *Name) {
1367 Triple TargetTriple(unwrap(M)->getTargetTriple());
1368 GlobalObject *GV = unwrap<GlobalObject>(V);
1369 if (!TargetTriple.isOSBinFormatMachO()) {
1370 GV->setComdat(unwrap(M)->getOrInsertComdat(Name));
1371 }
1372 }
1373
1374 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1375 GlobalObject *GV = unwrap<GlobalObject>(V);
1376 GV->setComdat(nullptr);
1377 }
1378
1379 enum class LLVMRustLinkage {
1380 ExternalLinkage = 0,
1381 AvailableExternallyLinkage = 1,
1382 LinkOnceAnyLinkage = 2,
1383 LinkOnceODRLinkage = 3,
1384 WeakAnyLinkage = 4,
1385 WeakODRLinkage = 5,
1386 AppendingLinkage = 6,
1387 InternalLinkage = 7,
1388 PrivateLinkage = 8,
1389 ExternalWeakLinkage = 9,
1390 CommonLinkage = 10,
1391 };
1392
1393 static LLVMRustLinkage to_rust(LLVMLinkage linkage) {
1394 switch (linkage) {
1395 case LLVMExternalLinkage:
1396 return LLVMRustLinkage::ExternalLinkage;
1397 case LLVMAvailableExternallyLinkage:
1398 return LLVMRustLinkage::AvailableExternallyLinkage;
1399 case LLVMLinkOnceAnyLinkage:
1400 return LLVMRustLinkage::LinkOnceAnyLinkage;
1401 case LLVMLinkOnceODRLinkage:
1402 return LLVMRustLinkage::LinkOnceODRLinkage;
1403 case LLVMWeakAnyLinkage:
1404 return LLVMRustLinkage::WeakAnyLinkage;
1405 case LLVMWeakODRLinkage:
1406 return LLVMRustLinkage::WeakODRLinkage;
1407 case LLVMAppendingLinkage:
1408 return LLVMRustLinkage::AppendingLinkage;
1409 case LLVMInternalLinkage:
1410 return LLVMRustLinkage::InternalLinkage;
1411 case LLVMPrivateLinkage:
1412 return LLVMRustLinkage::PrivateLinkage;
1413 case LLVMExternalWeakLinkage:
1414 return LLVMRustLinkage::ExternalWeakLinkage;
1415 case LLVMCommonLinkage:
1416 return LLVMRustLinkage::CommonLinkage;
1417 default:
1418 llvm_unreachable("Invalid LLVMRustLinkage value!");
1419 }
1420 }
1421
1422 static LLVMLinkage from_rust(LLVMRustLinkage linkage) {
1423 switch (linkage) {
1424 case LLVMRustLinkage::ExternalLinkage:
1425 return LLVMExternalLinkage;
1426 case LLVMRustLinkage::AvailableExternallyLinkage:
1427 return LLVMAvailableExternallyLinkage;
1428 case LLVMRustLinkage::LinkOnceAnyLinkage:
1429 return LLVMLinkOnceAnyLinkage;
1430 case LLVMRustLinkage::LinkOnceODRLinkage:
1431 return LLVMLinkOnceODRLinkage;
1432 case LLVMRustLinkage::WeakAnyLinkage:
1433 return LLVMWeakAnyLinkage;
1434 case LLVMRustLinkage::WeakODRLinkage:
1435 return LLVMWeakODRLinkage;
1436 case LLVMRustLinkage::AppendingLinkage:
1437 return LLVMAppendingLinkage;
1438 case LLVMRustLinkage::InternalLinkage:
1439 return LLVMInternalLinkage;
1440 case LLVMRustLinkage::PrivateLinkage:
1441 return LLVMPrivateLinkage;
1442 case LLVMRustLinkage::ExternalWeakLinkage:
1443 return LLVMExternalWeakLinkage;
1444 case LLVMRustLinkage::CommonLinkage:
1445 return LLVMCommonLinkage;
1446 default:
1447 llvm_unreachable("Invalid LLVMRustLinkage value!");
1448 }
1449 }
1450
1451 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1452 return to_rust(LLVMGetLinkage(V));
1453 }
1454
1455 extern "C" void LLVMRustSetLinkage(LLVMValueRef V, LLVMRustLinkage RustLinkage) {
1456 LLVMSetLinkage(V, from_rust(RustLinkage));
1457 }
1458
1459 extern "C" LLVMContextRef LLVMRustGetValueContext(LLVMValueRef V) {
1460 return wrap(&unwrap(V)->getContext());
1461 }
1462
1463 enum class LLVMRustVisibility {
1464 Default = 0,
1465 Hidden = 1,
1466 Protected = 2,
1467 };
1468
1469 static LLVMRustVisibility to_rust(LLVMVisibility vis) {
1470 switch (vis) {
1471 case LLVMDefaultVisibility:
1472 return LLVMRustVisibility::Default;
1473 case LLVMHiddenVisibility:
1474 return LLVMRustVisibility::Hidden;
1475 case LLVMProtectedVisibility:
1476 return LLVMRustVisibility::Protected;
1477
1478 default:
1479 llvm_unreachable("Invalid LLVMRustVisibility value!");
1480 }
1481 }
1482
1483 static LLVMVisibility from_rust(LLVMRustVisibility vis) {
1484 switch (vis) {
1485 case LLVMRustVisibility::Default:
1486 return LLVMDefaultVisibility;
1487 case LLVMRustVisibility::Hidden:
1488 return LLVMHiddenVisibility;
1489 case LLVMRustVisibility::Protected:
1490 return LLVMProtectedVisibility;
1491
1492 default:
1493 llvm_unreachable("Invalid LLVMRustVisibility value!");
1494 }
1495 }
1496
1497 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1498 return to_rust(LLVMGetVisibility(V));
1499 }
1500
1501 extern "C" void LLVMRustSetVisibility(LLVMValueRef V, LLVMRustVisibility RustVisibility) {
1502 LLVMSetVisibility(V, from_rust(RustVisibility));
1503 }