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