]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Auto merge of #83445 - erikdesjardins:rmunion, r=RalfJung
[rust.git] / compiler / rustc_llvm / llvm-wrapper / RustWrapper.cpp
1 #include "LLVMWrapper.h"
2 #include "llvm/IR/DebugInfoMetadata.h"
3 #include "llvm/IR/DiagnosticInfo.h"
4 #include "llvm/IR/DiagnosticPrinter.h"
5 #include "llvm/IR/GlobalVariable.h"
6 #include "llvm/IR/Instructions.h"
7 #include "llvm/IR/Intrinsics.h"
8 #include "llvm/Object/Archive.h"
9 #include "llvm/Object/ObjectFile.h"
10 #include "llvm/Bitcode/BitcodeWriterPass.h"
11 #include "llvm/Support/Signals.h"
12 #include "llvm/ADT/Optional.h"
13
14 #include <iostream>
15
16 //===----------------------------------------------------------------------===
17 //
18 // This file defines alternate interfaces to core functions that are more
19 // readily callable by Rust's FFI.
20 //
21 //===----------------------------------------------------------------------===
22
23 using namespace llvm;
24 using namespace llvm::sys;
25 using namespace llvm::object;
26
27 // LLVMAtomicOrdering is already an enum - don't create another
28 // one.
29 static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
30   switch (Ordering) {
31   case LLVMAtomicOrderingNotAtomic:
32     return AtomicOrdering::NotAtomic;
33   case LLVMAtomicOrderingUnordered:
34     return AtomicOrdering::Unordered;
35   case LLVMAtomicOrderingMonotonic:
36     return AtomicOrdering::Monotonic;
37   case LLVMAtomicOrderingAcquire:
38     return AtomicOrdering::Acquire;
39   case LLVMAtomicOrderingRelease:
40     return AtomicOrdering::Release;
41   case LLVMAtomicOrderingAcquireRelease:
42     return AtomicOrdering::AcquireRelease;
43   case LLVMAtomicOrderingSequentiallyConsistent:
44     return AtomicOrdering::SequentiallyConsistent;
45   }
46
47   report_fatal_error("Invalid LLVMAtomicOrdering value!");
48 }
49
50 static LLVM_THREAD_LOCAL char *LastError;
51
52 // Custom error handler for fatal LLVM errors.
53 //
54 // Notably it exits the process with code 101, unlike LLVM's default of 1.
55 static void FatalErrorHandler(void *UserData,
56                               const std::string& Reason,
57                               bool GenCrashDiag) {
58   // Do the same thing that the default error handler does.
59   std::cerr << "LLVM ERROR: " << Reason << std::endl;
60
61   // Since this error handler exits the process, we have to run any cleanup that
62   // LLVM would run after handling the error. This might change with an LLVM
63   // upgrade.
64   sys::RunInterruptHandlers();
65
66   exit(101);
67 }
68
69 extern "C" void LLVMRustInstallFatalErrorHandler() {
70   install_fatal_error_handler(FatalErrorHandler);
71 }
72
73 extern "C" LLVMMemoryBufferRef
74 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
75   ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =
76       MemoryBuffer::getFile(Path, -1, false);
77   if (!BufOr) {
78     LLVMRustSetLastError(BufOr.getError().message().c_str());
79     return nullptr;
80   }
81   return wrap(BufOr.get().release());
82 }
83
84 extern "C" char *LLVMRustGetLastError(void) {
85   char *Ret = LastError;
86   LastError = nullptr;
87   return Ret;
88 }
89
90 extern "C" unsigned int LLVMRustGetInstructionCount(LLVMModuleRef M) {
91   return unwrap(M)->getInstructionCount();
92 }
93
94 extern "C" void LLVMRustSetLastError(const char *Err) {
95   free((void *)LastError);
96   LastError = strdup(Err);
97 }
98
99 extern "C" LLVMContextRef LLVMRustContextCreate(bool shouldDiscardNames) {
100   auto ctx = new LLVMContext();
101   ctx->setDiscardValueNames(shouldDiscardNames);
102   return wrap(ctx);
103 }
104
105 extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M,
106                                             const char *Triple) {
107   unwrap(M)->setTargetTriple(Triple::normalize(Triple));
108 }
109
110 extern "C" void LLVMRustPrintPassTimings() {
111   raw_fd_ostream OS(2, false); // stderr.
112   TimerGroup::printAll(OS);
113 }
114
115 extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
116                                               size_t NameLen) {
117   return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen)));
118 }
119
120 extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
121                                                     const char *Name,
122                                                     size_t NameLen,
123                                                     LLVMTypeRef FunctionTy) {
124   return wrap(unwrap(M)
125                   ->getOrInsertFunction(StringRef(Name, NameLen),
126                                         unwrap<FunctionType>(FunctionTy))
127                   .getCallee()
128   );
129 }
130
131 extern "C" LLVMValueRef
132 LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) {
133   StringRef NameRef(Name, NameLen);
134   return wrap(unwrap(M)->getOrInsertGlobal(NameRef, unwrap(Ty)));
135 }
136
137 extern "C" LLVMValueRef
138 LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) {
139   return wrap(new GlobalVariable(*unwrap(M),
140                                  unwrap(Ty),
141                                  false,
142                                  GlobalValue::PrivateLinkage,
143                                  nullptr));
144 }
145
146 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
147   return wrap(Type::getMetadataTy(*unwrap(C)));
148 }
149
150 static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
151   switch (Kind) {
152   case AlwaysInline:
153     return Attribute::AlwaysInline;
154   case ByVal:
155     return Attribute::ByVal;
156   case Cold:
157     return Attribute::Cold;
158   case InlineHint:
159     return Attribute::InlineHint;
160   case MinSize:
161     return Attribute::MinSize;
162   case Naked:
163     return Attribute::Naked;
164   case NoAlias:
165     return Attribute::NoAlias;
166   case NoCapture:
167     return Attribute::NoCapture;
168   case NoInline:
169     return Attribute::NoInline;
170   case NonNull:
171     return Attribute::NonNull;
172   case NoRedZone:
173     return Attribute::NoRedZone;
174   case NoReturn:
175     return Attribute::NoReturn;
176   case NoUnwind:
177     return Attribute::NoUnwind;
178   case OptimizeForSize:
179     return Attribute::OptimizeForSize;
180   case ReadOnly:
181     return Attribute::ReadOnly;
182   case SExt:
183     return Attribute::SExt;
184   case StructRet:
185     return Attribute::StructRet;
186   case UWTable:
187     return Attribute::UWTable;
188   case ZExt:
189     return Attribute::ZExt;
190   case InReg:
191     return Attribute::InReg;
192   case SanitizeThread:
193     return Attribute::SanitizeThread;
194   case SanitizeAddress:
195     return Attribute::SanitizeAddress;
196   case SanitizeMemory:
197     return Attribute::SanitizeMemory;
198   case NonLazyBind:
199     return Attribute::NonLazyBind;
200   case OptimizeNone:
201     return Attribute::OptimizeNone;
202   case ReturnsTwice:
203     return Attribute::ReturnsTwice;
204   case ReadNone:
205     return Attribute::ReadNone;
206   case InaccessibleMemOnly:
207     return Attribute::InaccessibleMemOnly;
208   case SanitizeHWAddress:
209     return Attribute::SanitizeHWAddress;
210   case WillReturn:
211     return Attribute::WillReturn;
212   }
213   report_fatal_error("bad AttributeKind");
214 }
215
216 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
217                                              LLVMRustAttribute RustAttr) {
218   CallBase *Call = unwrap<CallBase>(Instr);
219   Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
220   Call->addAttribute(Index, Attr);
221 }
222
223 extern "C" void LLVMRustAddCallSiteAttrString(LLVMValueRef Instr, unsigned Index,
224                                               const char *Name) {
225   CallBase *Call = unwrap<CallBase>(Instr);
226   Attribute Attr = Attribute::get(Call->getContext(), Name);
227   Call->addAttribute(Index, Attr);
228 }
229
230
231 extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
232                                                  unsigned Index,
233                                                  uint32_t Bytes) {
234   CallBase *Call = unwrap<CallBase>(Instr);
235   AttrBuilder B;
236   B.addAlignmentAttr(Bytes);
237   Call->setAttributes(Call->getAttributes().addAttributes(
238       Call->getContext(), Index, B));
239 }
240
241 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
242                                                        unsigned Index,
243                                                        uint64_t Bytes) {
244   CallBase *Call = unwrap<CallBase>(Instr);
245   AttrBuilder B;
246   B.addDereferenceableAttr(Bytes);
247   Call->setAttributes(Call->getAttributes().addAttributes(
248       Call->getContext(), Index, B));
249 }
250
251 extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
252                                                              unsigned Index,
253                                                              uint64_t Bytes) {
254   CallBase *Call = unwrap<CallBase>(Instr);
255   AttrBuilder B;
256   B.addDereferenceableOrNullAttr(Bytes);
257   Call->setAttributes(Call->getAttributes().addAttributes(
258       Call->getContext(), Index, B));
259 }
260
261 extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index,
262                                              LLVMTypeRef Ty) {
263   CallBase *Call = unwrap<CallBase>(Instr);
264   Attribute Attr = Attribute::getWithByValType(Call->getContext(), unwrap(Ty));
265   Call->addAttribute(Index, Attr);
266 }
267
268 extern "C" void LLVMRustAddStructRetCallSiteAttr(LLVMValueRef Instr, unsigned Index,
269                                                  LLVMTypeRef Ty) {
270   CallBase *Call = unwrap<CallBase>(Instr);
271 #if LLVM_VERSION_GE(12, 0)
272   Attribute Attr = Attribute::getWithStructRetType(Call->getContext(), unwrap(Ty));
273 #else
274   Attribute Attr = Attribute::get(Call->getContext(), Attribute::StructRet);
275 #endif
276   Call->addAttribute(Index, Attr);
277 }
278
279 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
280                                              LLVMRustAttribute RustAttr) {
281   Function *A = unwrap<Function>(Fn);
282   Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
283   AttrBuilder B(Attr);
284   A->addAttributes(Index, B);
285 }
286
287 extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn,
288                                          unsigned Index,
289                                          uint32_t Bytes) {
290   Function *A = unwrap<Function>(Fn);
291   AttrBuilder B;
292   B.addAlignmentAttr(Bytes);
293   A->addAttributes(Index, B);
294 }
295
296 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
297                                                uint64_t Bytes) {
298   Function *A = unwrap<Function>(Fn);
299   AttrBuilder B;
300   B.addDereferenceableAttr(Bytes);
301   A->addAttributes(Index, B);
302 }
303
304 extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
305                                                      unsigned Index,
306                                                      uint64_t Bytes) {
307   Function *A = unwrap<Function>(Fn);
308   AttrBuilder B;
309   B.addDereferenceableOrNullAttr(Bytes);
310   A->addAttributes(Index, B);
311 }
312
313 extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index,
314                                      LLVMTypeRef Ty) {
315   Function *F = unwrap<Function>(Fn);
316   Attribute Attr = Attribute::getWithByValType(F->getContext(), unwrap(Ty));
317   F->addAttribute(Index, Attr);
318 }
319
320 extern "C" void LLVMRustAddStructRetAttr(LLVMValueRef Fn, unsigned Index,
321                                          LLVMTypeRef Ty) {
322   Function *F = unwrap<Function>(Fn);
323 #if LLVM_VERSION_GE(12, 0)
324   Attribute Attr = Attribute::getWithStructRetType(F->getContext(), unwrap(Ty));
325 #else
326   Attribute Attr = Attribute::get(F->getContext(), Attribute::StructRet);
327 #endif
328   F->addAttribute(Index, Attr);
329 }
330
331 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
332                                                    unsigned Index,
333                                                    const char *Name,
334                                                    const char *Value) {
335   Function *F = unwrap<Function>(Fn);
336   AttrBuilder B;
337   B.addAttribute(Name, Value);
338   F->addAttributes(Index, B);
339 }
340
341 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
342                                                  unsigned Index,
343                                                  LLVMRustAttribute RustAttr) {
344   Function *F = unwrap<Function>(Fn);
345   Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
346   AttrBuilder B(Attr);
347   auto PAL = F->getAttributes();
348   auto PALNew = PAL.removeAttributes(F->getContext(), Index, B);
349   F->setAttributes(PALNew);
350 }
351
352 // enable fpmath flag UnsafeAlgebra
353 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
354   if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
355     I->setFast(true);
356   }
357 }
358
359 extern "C" LLVMValueRef
360 LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef Source, const char *Name,
361                         LLVMAtomicOrdering Order) {
362   Value *Ptr = unwrap(Source);
363   Type *Ty = Ptr->getType()->getPointerElementType();
364   LoadInst *LI = unwrap(B)->CreateLoad(Ty, Ptr, Name);
365   LI->setAtomic(fromRust(Order));
366   return wrap(LI);
367 }
368
369 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
370                                                  LLVMValueRef V,
371                                                  LLVMValueRef Target,
372                                                  LLVMAtomicOrdering Order) {
373   StoreInst *SI = unwrap(B)->CreateStore(unwrap(V), unwrap(Target));
374   SI->setAtomic(fromRust(Order));
375   return wrap(SI);
376 }
377
378 // FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak
379 // once we raise our minimum support to LLVM 10.
380 extern "C" LLVMValueRef
381 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
382                            LLVMValueRef Old, LLVMValueRef Source,
383                            LLVMAtomicOrdering Order,
384                            LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
385 #if LLVM_VERSION_GE(13,0)
386   // Rust probably knows the alignment of the target value and should be able to
387   // specify something more precise than MaybeAlign here. See also
388   // https://reviews.llvm.org/D97224 which may be a useful reference.
389   AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
390       unwrap(Target), unwrap(Old), unwrap(Source), llvm::MaybeAlign(), fromRust(Order),
391       fromRust(FailureOrder));
392 #else
393   AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
394       unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
395       fromRust(FailureOrder));
396 #endif
397   ACXI->setWeak(Weak);
398   return wrap(ACXI);
399 }
400
401 enum class LLVMRustSynchronizationScope {
402   SingleThread,
403   CrossThread,
404 };
405
406 static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
407   switch (Scope) {
408   case LLVMRustSynchronizationScope::SingleThread:
409     return SyncScope::SingleThread;
410   case LLVMRustSynchronizationScope::CrossThread:
411     return SyncScope::System;
412   default:
413     report_fatal_error("bad SynchronizationScope.");
414   }
415 }
416
417 extern "C" LLVMValueRef
418 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
419                          LLVMRustSynchronizationScope Scope) {
420   return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
421 }
422
423 enum class LLVMRustAsmDialect {
424   Att,
425   Intel,
426 };
427
428 static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
429   switch (Dialect) {
430   case LLVMRustAsmDialect::Att:
431     return InlineAsm::AD_ATT;
432   case LLVMRustAsmDialect::Intel:
433     return InlineAsm::AD_Intel;
434   default:
435     report_fatal_error("bad AsmDialect.");
436   }
437 }
438
439 extern "C" LLVMValueRef
440 LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
441                   char *Constraints, size_t ConstraintsLen,
442                   LLVMBool HasSideEffects, LLVMBool IsAlignStack,
443                   LLVMRustAsmDialect Dialect) {
444   return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
445                              StringRef(AsmString, AsmStringLen),
446                              StringRef(Constraints, ConstraintsLen),
447                              HasSideEffects, IsAlignStack, fromRust(Dialect)));
448 }
449
450 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
451                                         size_t ConstraintsLen) {
452   return InlineAsm::Verify(unwrap<FunctionType>(Ty),
453                            StringRef(Constraints, ConstraintsLen));
454 }
455
456 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
457                                               size_t AsmLen) {
458   unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen));
459 }
460
461 typedef DIBuilder *LLVMRustDIBuilderRef;
462
463 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
464   return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
465 }
466
467 #define DIDescriptor DIScope
468 #define DIArray DINodeArray
469 #define unwrapDI unwrapDIPtr
470
471 // These values **must** match debuginfo::DIFlags! They also *happen*
472 // to match LLVM, but that isn't required as we do giant sets of
473 // matching below. The value shouldn't be directly passed to LLVM.
474 enum class LLVMRustDIFlags : uint32_t {
475   FlagZero = 0,
476   FlagPrivate = 1,
477   FlagProtected = 2,
478   FlagPublic = 3,
479   FlagFwdDecl = (1 << 2),
480   FlagAppleBlock = (1 << 3),
481   FlagBlockByrefStruct = (1 << 4),
482   FlagVirtual = (1 << 5),
483   FlagArtificial = (1 << 6),
484   FlagExplicit = (1 << 7),
485   FlagPrototyped = (1 << 8),
486   FlagObjcClassComplete = (1 << 9),
487   FlagObjectPointer = (1 << 10),
488   FlagVector = (1 << 11),
489   FlagStaticMember = (1 << 12),
490   FlagLValueReference = (1 << 13),
491   FlagRValueReference = (1 << 14),
492   FlagExternalTypeRef = (1 << 15),
493   FlagIntroducedVirtual = (1 << 18),
494   FlagBitField = (1 << 19),
495   FlagNoReturn = (1 << 20),
496   // Do not add values that are not supported by the minimum LLVM
497   // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
498 };
499
500 inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
501   return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
502                                       static_cast<uint32_t>(B));
503 }
504
505 inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
506   return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
507                                       static_cast<uint32_t>(B));
508 }
509
510 inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
511   return A = A | B;
512 }
513
514 inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
515
516 inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
517   return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
518 }
519
520 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
521   DINode::DIFlags Result = DINode::DIFlags::FlagZero;
522
523   switch (visibility(Flags)) {
524   case LLVMRustDIFlags::FlagPrivate:
525     Result |= DINode::DIFlags::FlagPrivate;
526     break;
527   case LLVMRustDIFlags::FlagProtected:
528     Result |= DINode::DIFlags::FlagProtected;
529     break;
530   case LLVMRustDIFlags::FlagPublic:
531     Result |= DINode::DIFlags::FlagPublic;
532     break;
533   default:
534     // The rest are handled below
535     break;
536   }
537
538   if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
539     Result |= DINode::DIFlags::FlagFwdDecl;
540   }
541   if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
542     Result |= DINode::DIFlags::FlagAppleBlock;
543   }
544 #if LLVM_VERSION_LT(10, 0)
545   if (isSet(Flags & LLVMRustDIFlags::FlagBlockByrefStruct)) {
546     Result |= DINode::DIFlags::FlagBlockByrefStruct;
547   }
548 #endif
549   if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
550     Result |= DINode::DIFlags::FlagVirtual;
551   }
552   if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
553     Result |= DINode::DIFlags::FlagArtificial;
554   }
555   if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
556     Result |= DINode::DIFlags::FlagExplicit;
557   }
558   if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
559     Result |= DINode::DIFlags::FlagPrototyped;
560   }
561   if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
562     Result |= DINode::DIFlags::FlagObjcClassComplete;
563   }
564   if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
565     Result |= DINode::DIFlags::FlagObjectPointer;
566   }
567   if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
568     Result |= DINode::DIFlags::FlagVector;
569   }
570   if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
571     Result |= DINode::DIFlags::FlagStaticMember;
572   }
573   if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
574     Result |= DINode::DIFlags::FlagLValueReference;
575   }
576   if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
577     Result |= DINode::DIFlags::FlagRValueReference;
578   }
579   if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
580     Result |= DINode::DIFlags::FlagIntroducedVirtual;
581   }
582   if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
583     Result |= DINode::DIFlags::FlagBitField;
584   }
585   if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
586     Result |= DINode::DIFlags::FlagNoReturn;
587   }
588
589   return Result;
590 }
591
592 // These values **must** match debuginfo::DISPFlags! They also *happen*
593 // to match LLVM, but that isn't required as we do giant sets of
594 // matching below. The value shouldn't be directly passed to LLVM.
595 enum class LLVMRustDISPFlags : uint32_t {
596   SPFlagZero = 0,
597   SPFlagVirtual = 1,
598   SPFlagPureVirtual = 2,
599   SPFlagLocalToUnit = (1 << 2),
600   SPFlagDefinition = (1 << 3),
601   SPFlagOptimized = (1 << 4),
602   SPFlagMainSubprogram = (1 << 5),
603   // Do not add values that are not supported by the minimum LLVM
604   // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
605   // (In LLVM < 8, createFunction supported these as separate bool arguments.)
606 };
607
608 inline LLVMRustDISPFlags operator&(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
609   return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) &
610                                       static_cast<uint32_t>(B));
611 }
612
613 inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
614   return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) |
615                                       static_cast<uint32_t>(B));
616 }
617
618 inline LLVMRustDISPFlags &operator|=(LLVMRustDISPFlags &A, LLVMRustDISPFlags B) {
619   return A = A | B;
620 }
621
622 inline bool isSet(LLVMRustDISPFlags F) { return F != LLVMRustDISPFlags::SPFlagZero; }
623
624 inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) {
625   return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(F) & 0x3);
626 }
627
628 static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) {
629   DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero;
630
631   switch (virtuality(SPFlags)) {
632   case LLVMRustDISPFlags::SPFlagVirtual:
633     Result |= DISubprogram::DISPFlags::SPFlagVirtual;
634     break;
635   case LLVMRustDISPFlags::SPFlagPureVirtual:
636     Result |= DISubprogram::DISPFlags::SPFlagPureVirtual;
637     break;
638   default:
639     // The rest are handled below
640     break;
641   }
642
643   if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit)) {
644     Result |= DISubprogram::DISPFlags::SPFlagLocalToUnit;
645   }
646   if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition)) {
647     Result |= DISubprogram::DISPFlags::SPFlagDefinition;
648   }
649   if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) {
650     Result |= DISubprogram::DISPFlags::SPFlagOptimized;
651   }
652   if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) {
653     Result |= DISubprogram::DISPFlags::SPFlagMainSubprogram;
654   }
655
656   return Result;
657 }
658
659 enum class LLVMRustDebugEmissionKind {
660   NoDebug,
661   FullDebug,
662   LineTablesOnly,
663 };
664
665 static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
666   switch (Kind) {
667   case LLVMRustDebugEmissionKind::NoDebug:
668     return DICompileUnit::DebugEmissionKind::NoDebug;
669   case LLVMRustDebugEmissionKind::FullDebug:
670     return DICompileUnit::DebugEmissionKind::FullDebug;
671   case LLVMRustDebugEmissionKind::LineTablesOnly:
672     return DICompileUnit::DebugEmissionKind::LineTablesOnly;
673   default:
674     report_fatal_error("bad DebugEmissionKind.");
675   }
676 }
677
678 enum class LLVMRustChecksumKind {
679   None,
680   MD5,
681   SHA1,
682   SHA256,
683 };
684
685 static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
686   switch (Kind) {
687   case LLVMRustChecksumKind::None:
688     return None;
689   case LLVMRustChecksumKind::MD5:
690     return DIFile::ChecksumKind::CSK_MD5;
691   case LLVMRustChecksumKind::SHA1:
692     return DIFile::ChecksumKind::CSK_SHA1;
693 #if (LLVM_VERSION_MAJOR >= 11)
694   case LLVMRustChecksumKind::SHA256:
695     return DIFile::ChecksumKind::CSK_SHA256;
696 #endif
697   default:
698     report_fatal_error("bad ChecksumKind.");
699   }
700 }
701
702 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
703   return DEBUG_METADATA_VERSION;
704 }
705
706 extern "C" uint32_t LLVMRustVersionPatch() { return LLVM_VERSION_PATCH; }
707
708 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
709
710 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
711
712 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
713                                       uint32_t Value) {
714   unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
715 }
716
717 extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
718   return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
719 }
720
721 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
722   return new DIBuilder(*unwrap(M));
723 }
724
725 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
726   delete Builder;
727 }
728
729 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
730   Builder->finalize();
731 }
732
733 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
734     LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
735     const char *Producer, size_t ProducerLen, bool isOptimized,
736     const char *Flags, unsigned RuntimeVer,
737     const char *SplitName, size_t SplitNameLen,
738     LLVMRustDebugEmissionKind Kind,
739     uint64_t DWOId, bool SplitDebugInlining) {
740   auto *File = unwrapDI<DIFile>(FileRef);
741
742   return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
743                                          isOptimized, Flags, RuntimeVer,
744                                          StringRef(SplitName, SplitNameLen),
745                                          fromRust(Kind), DWOId, SplitDebugInlining));
746 }
747
748 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
749     LLVMRustDIBuilderRef Builder,
750     const char *Filename, size_t FilenameLen,
751     const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
752     const char *Checksum, size_t ChecksumLen) {
753   Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
754   Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
755   if (llvmCSKind)
756     CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
757   return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
758                                   StringRef(Directory, DirectoryLen),
759                                   CSInfo));
760 }
761
762 extern "C" LLVMMetadataRef
763 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
764                                       LLVMMetadataRef ParameterTypes) {
765   return wrap(Builder->createSubroutineType(
766       DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
767 }
768
769 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
770     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
771     const char *Name, size_t NameLen,
772     const char *LinkageName, size_t LinkageNameLen,
773     LLVMMetadataRef File, unsigned LineNo,
774     LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
775     LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam,
776     LLVMMetadataRef Decl) {
777   DITemplateParameterArray TParams =
778       DITemplateParameterArray(unwrap<MDTuple>(TParam));
779   DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
780   DINode::DIFlags llvmFlags = fromRust(Flags);
781   DISubprogram *Sub = Builder->createFunction(
782       unwrapDI<DIScope>(Scope),
783       StringRef(Name, NameLen),
784       StringRef(LinkageName, LinkageNameLen),
785       unwrapDI<DIFile>(File), LineNo,
786       unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
787       llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
788   if (MaybeFn)
789     unwrap<Function>(MaybeFn)->setSubprogram(Sub);
790   return wrap(Sub);
791 }
792
793 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
794     LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
795     uint64_t SizeInBits, unsigned Encoding) {
796   return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
797 }
798
799 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
800     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
801     LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
802   return wrap(Builder->createTypedef(
803     unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
804     LineNo, unwrapDIPtr<DIScope>(Scope)));
805 }
806
807 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
808     LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
809     uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
810     const char *Name, size_t NameLen) {
811   return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
812                                          SizeInBits, AlignInBits,
813                                          AddressSpace,
814                                          StringRef(Name, NameLen)));
815 }
816
817 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
818     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
819     const char *Name, size_t NameLen,
820     LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
821     uint32_t AlignInBits, LLVMRustDIFlags Flags,
822     LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
823     unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
824     const char *UniqueId, size_t UniqueIdLen) {
825   return wrap(Builder->createStructType(
826       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
827       unwrapDI<DIFile>(File), LineNumber,
828       SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
829       DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
830       unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen)));
831 }
832
833 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
834     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
835     const char *Name, size_t NameLen,
836     LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
837     uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
838     LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) {
839   return wrap(Builder->createVariantPart(
840       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
841       unwrapDI<DIFile>(File), LineNumber,
842       SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
843       DINodeArray(unwrapDI<MDTuple>(Elements)), StringRef(UniqueId, UniqueIdLen)));
844 }
845
846 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
847     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
848     const char *Name, size_t NameLen,
849     LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
850     uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
851     LLVMMetadataRef Ty) {
852   return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope),
853                                         StringRef(Name, NameLen),
854                                         unwrapDI<DIFile>(File), LineNo,
855                                         SizeInBits, AlignInBits, OffsetInBits,
856                                         fromRust(Flags), unwrapDI<DIType>(Ty)));
857 }
858
859 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
860     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
861     const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
862     uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
863     LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
864   llvm::ConstantInt* D = nullptr;
865   if (Discriminant) {
866     D = unwrap<llvm::ConstantInt>(Discriminant);
867   }
868   return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope),
869                                                StringRef(Name, NameLen),
870                                                unwrapDI<DIFile>(File), LineNo,
871                                                SizeInBits, AlignInBits, OffsetInBits, D,
872                                                fromRust(Flags), unwrapDI<DIType>(Ty)));
873 }
874
875 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
876     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
877     LLVMMetadataRef File, unsigned Line, unsigned Col) {
878   return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
879                                           unwrapDI<DIFile>(File), Line, Col));
880 }
881
882 extern "C" LLVMMetadataRef
883 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
884                                         LLVMMetadataRef Scope,
885                                         LLVMMetadataRef File) {
886   return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
887                                               unwrapDI<DIFile>(File)));
888 }
889
890 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
891     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context,
892     const char *Name, size_t NameLen,
893     const char *LinkageName, size_t LinkageNameLen,
894     LLVMMetadataRef File, unsigned LineNo,
895     LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
896     LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
897   llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
898
899   llvm::DIExpression *InitExpr = nullptr;
900   if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
901     InitExpr = Builder->createConstantValueExpression(
902         IntVal->getValue().getSExtValue());
903   } else if (llvm::ConstantFP *FPVal =
904                  llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
905     InitExpr = Builder->createConstantValueExpression(
906         FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
907   }
908
909   llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
910       unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
911       StringRef(LinkageName, LinkageNameLen),
912       unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
913 #if LLVM_VERSION_GE(10, 0)
914       /* isDefined */ true,
915 #endif
916       InitExpr, unwrapDIPtr<MDNode>(Decl),
917       /* templateParams */ nullptr,
918       AlignInBits);
919
920   InitVal->setMetadata("dbg", VarExpr);
921
922   return wrap(VarExpr);
923 }
924
925 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
926     LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
927     const char *Name, size_t NameLen,
928     LLVMMetadataRef File, unsigned LineNo,
929     LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
930     unsigned ArgNo, uint32_t AlignInBits) {
931   if (Tag == 0x100) { // DW_TAG_auto_variable
932     return wrap(Builder->createAutoVariable(
933         unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
934         unwrapDI<DIFile>(File), LineNo,
935         unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
936   } else {
937     return wrap(Builder->createParameterVariable(
938         unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
939         unwrapDI<DIFile>(File), LineNo,
940         unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
941   }
942 }
943
944 extern "C" LLVMMetadataRef
945 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
946                                  uint32_t AlignInBits, LLVMMetadataRef Ty,
947                                  LLVMMetadataRef Subscripts) {
948   return wrap(
949       Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
950                                DINodeArray(unwrapDI<MDTuple>(Subscripts))));
951 }
952
953 extern "C" LLVMMetadataRef
954 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
955                                      int64_t Count) {
956   return wrap(Builder->getOrCreateSubrange(Lo, Count));
957 }
958
959 extern "C" LLVMMetadataRef
960 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
961                                   LLVMMetadataRef *Ptr, unsigned Count) {
962   Metadata **DataValue = unwrap(Ptr);
963   return wrap(
964       Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
965 }
966
967 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
968     LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
969     int64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
970     LLVMBasicBlockRef InsertAtEnd) {
971   return wrap(Builder->insertDeclare(
972       unwrap(V), unwrap<DILocalVariable>(VarInfo),
973       Builder->createExpression(llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
974       DebugLoc(cast<MDNode>(unwrap(DL))),
975       unwrap(InsertAtEnd)));
976 }
977
978 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
979     LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
980     int64_t Value, bool IsUnsigned) {
981   return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
982 }
983
984 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
985     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
986     const char *Name, size_t NameLen,
987     LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
988     uint32_t AlignInBits, LLVMMetadataRef Elements,
989     LLVMMetadataRef ClassTy, bool IsScoped) {
990   return wrap(Builder->createEnumerationType(
991       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
992       unwrapDI<DIFile>(File), LineNumber,
993       SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
994       unwrapDI<DIType>(ClassTy), "", IsScoped));
995 }
996
997 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
998     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
999     const char *Name, size_t NameLen,
1000     LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
1001     uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
1002     unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) {
1003   return wrap(Builder->createUnionType(
1004       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File),
1005       LineNumber, SizeInBits, AlignInBits, fromRust(Flags),
1006       DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
1007       StringRef(UniqueId, UniqueIdLen)));
1008 }
1009
1010 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
1011     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1012     const char *Name, size_t NameLen, LLVMMetadataRef Ty) {
1013 #if LLVM_VERSION_GE(11, 0)
1014   bool IsDefault = false; // FIXME: should we ever set this true?
1015   return wrap(Builder->createTemplateTypeParameter(
1016       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty), IsDefault));
1017 #else
1018   return wrap(Builder->createTemplateTypeParameter(
1019       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty)));
1020 #endif
1021 }
1022
1023 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateNameSpace(
1024     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1025     const char *Name, size_t NameLen, bool ExportSymbols) {
1026   return wrap(Builder->createNameSpace(
1027       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols
1028   ));
1029 }
1030
1031 extern "C" void
1032 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
1033                                      LLVMMetadataRef CompositeTy,
1034                                      LLVMMetadataRef Elements,
1035                                      LLVMMetadataRef Params) {
1036   DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
1037   Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
1038                          DINodeArray(unwrap<MDTuple>(Params)));
1039 }
1040
1041 extern "C" LLVMMetadataRef
1042 LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
1043                                      LLVMMetadataRef ScopeRef,
1044                                      LLVMMetadataRef InlinedAt) {
1045 #if LLVM_VERSION_GE(12, 0)
1046   MDNode *Scope = unwrapDIPtr<MDNode>(ScopeRef);
1047   DILocation *Loc = DILocation::get(
1048       Scope->getContext(), Line, Column, Scope,
1049       unwrapDIPtr<MDNode>(InlinedAt));
1050   return wrap(Loc);
1051 #else
1052   DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(ScopeRef),
1053                                      unwrapDIPtr<MDNode>(InlinedAt));
1054   return wrap(debug_loc.getAsMDNode());
1055 #endif
1056 }
1057
1058 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
1059   return dwarf::DW_OP_deref;
1060 }
1061
1062 extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1063   return dwarf::DW_OP_plus_uconst;
1064 }
1065
1066 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
1067   RawRustStringOstream OS(Str);
1068   unwrap<llvm::Type>(Ty)->print(OS);
1069 }
1070
1071 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
1072                                            RustStringRef Str) {
1073   RawRustStringOstream OS(Str);
1074   if (!V) {
1075     OS << "(null)";
1076   } else {
1077     OS << "(";
1078     unwrap<llvm::Value>(V)->getType()->print(OS);
1079     OS << ":";
1080     unwrap<llvm::Value>(V)->print(OS);
1081     OS << ")";
1082   }
1083 }
1084
1085 // Note that the two following functions look quite similar to the
1086 // LLVMGetSectionName function. Sadly, it appears that this function only
1087 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
1088 // function provided by LLVM doesn't return the length, so we've created our own
1089 // function which returns the length as well as the data pointer.
1090 //
1091 // For an example of this not returning a null terminated string, see
1092 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
1093 // branches explicitly creates a StringRef without a null terminator, and then
1094 // that's returned.
1095
1096 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
1097   return reinterpret_cast<section_iterator *>(SI);
1098 }
1099
1100 extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI,
1101                                          const char **Ptr) {
1102 #if LLVM_VERSION_GE(10, 0)
1103   auto NameOrErr = (*unwrap(SI))->getName();
1104   if (!NameOrErr)
1105     report_fatal_error(NameOrErr.takeError());
1106   *Ptr = NameOrErr->data();
1107   return NameOrErr->size();
1108 #else
1109   StringRef Ret;
1110   if (std::error_code EC = (*unwrap(SI))->getName(Ret))
1111     report_fatal_error(EC.message());
1112   *Ptr = Ret.data();
1113   return Ret.size();
1114 #endif
1115 }
1116
1117 // LLVMArrayType function does not support 64-bit ElementCount
1118 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
1119                                          uint64_t ElementCount) {
1120   return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
1121 }
1122
1123 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1124
1125 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
1126   RawRustStringOstream OS(Str);
1127   unwrap(T)->print(OS);
1128 }
1129
1130 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1131     LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
1132     LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
1133     RustStringRef FilenameOut, RustStringRef MessageOut) {
1134   // Undefined to call this not on an optimization diagnostic!
1135   llvm::DiagnosticInfoOptimizationBase *Opt =
1136       static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
1137
1138   RawRustStringOstream PassNameOS(PassNameOut);
1139   PassNameOS << Opt->getPassName();
1140   *FunctionOut = wrap(&Opt->getFunction());
1141
1142   RawRustStringOstream FilenameOS(FilenameOut);
1143   DiagnosticLocation loc = Opt->getLocation();
1144   if (loc.isValid()) {
1145     *Line = loc.getLine();
1146     *Column = loc.getColumn();
1147     FilenameOS << loc.getAbsolutePath();
1148   }
1149
1150   RawRustStringOstream MessageOS(MessageOut);
1151   MessageOS << Opt->getMsg();
1152 }
1153
1154 enum class LLVMRustDiagnosticLevel {
1155     Error,
1156     Warning,
1157     Note,
1158     Remark,
1159 };
1160
1161 extern "C" void
1162 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
1163                                   LLVMRustDiagnosticLevel *LevelOut,
1164                                   unsigned *CookieOut,
1165                                   LLVMTwineRef *MessageOut,
1166                                   LLVMValueRef *InstructionOut) {
1167   // Undefined to call this not on an inline assembly diagnostic!
1168   llvm::DiagnosticInfoInlineAsm *IA =
1169       static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
1170
1171   *CookieOut = IA->getLocCookie();
1172   *MessageOut = wrap(&IA->getMsgStr());
1173   *InstructionOut = wrap(IA->getInstruction());
1174
1175   switch (IA->getSeverity()) {
1176     case DS_Error:
1177       *LevelOut = LLVMRustDiagnosticLevel::Error;
1178       break;
1179     case DS_Warning:
1180       *LevelOut = LLVMRustDiagnosticLevel::Warning;
1181       break;
1182     case DS_Note:
1183       *LevelOut = LLVMRustDiagnosticLevel::Note;
1184       break;
1185     case DS_Remark:
1186       *LevelOut = LLVMRustDiagnosticLevel::Remark;
1187       break;
1188     default:
1189       report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1190   }
1191 }
1192
1193 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
1194                                                     RustStringRef Str) {
1195   RawRustStringOstream OS(Str);
1196   DiagnosticPrinterRawOStream DP(OS);
1197   unwrap(DI)->print(DP);
1198 }
1199
1200 enum class LLVMRustDiagnosticKind {
1201   Other,
1202   InlineAsm,
1203   StackSize,
1204   DebugMetadataVersion,
1205   SampleProfile,
1206   OptimizationRemark,
1207   OptimizationRemarkMissed,
1208   OptimizationRemarkAnalysis,
1209   OptimizationRemarkAnalysisFPCommute,
1210   OptimizationRemarkAnalysisAliasing,
1211   OptimizationRemarkOther,
1212   OptimizationFailure,
1213   PGOProfile,
1214   Linker,
1215   Unsupported,
1216 };
1217
1218 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1219   switch (Kind) {
1220   case DK_InlineAsm:
1221     return LLVMRustDiagnosticKind::InlineAsm;
1222   case DK_StackSize:
1223     return LLVMRustDiagnosticKind::StackSize;
1224   case DK_DebugMetadataVersion:
1225     return LLVMRustDiagnosticKind::DebugMetadataVersion;
1226   case DK_SampleProfile:
1227     return LLVMRustDiagnosticKind::SampleProfile;
1228   case DK_OptimizationRemark:
1229     return LLVMRustDiagnosticKind::OptimizationRemark;
1230   case DK_OptimizationRemarkMissed:
1231     return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1232   case DK_OptimizationRemarkAnalysis:
1233     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1234   case DK_OptimizationRemarkAnalysisFPCommute:
1235     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1236   case DK_OptimizationRemarkAnalysisAliasing:
1237     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1238   case DK_PGOProfile:
1239     return LLVMRustDiagnosticKind::PGOProfile;
1240   case DK_Linker:
1241     return LLVMRustDiagnosticKind::Linker;
1242   case DK_Unsupported:
1243     return LLVMRustDiagnosticKind::Unsupported;
1244   default:
1245     return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1246                ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1247                : LLVMRustDiagnosticKind::Other;
1248   }
1249 }
1250
1251 extern "C" LLVMRustDiagnosticKind
1252 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1253   return toRust((DiagnosticKind)unwrap(DI)->getKind());
1254 }
1255
1256 // This is kept distinct from LLVMGetTypeKind, because when
1257 // a new type kind is added, the Rust-side enum must be
1258 // updated or UB will result.
1259 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1260   switch (unwrap(Ty)->getTypeID()) {
1261   case Type::VoidTyID:
1262     return LLVMVoidTypeKind;
1263   case Type::HalfTyID:
1264     return LLVMHalfTypeKind;
1265   case Type::FloatTyID:
1266     return LLVMFloatTypeKind;
1267   case Type::DoubleTyID:
1268     return LLVMDoubleTypeKind;
1269   case Type::X86_FP80TyID:
1270     return LLVMX86_FP80TypeKind;
1271   case Type::FP128TyID:
1272     return LLVMFP128TypeKind;
1273   case Type::PPC_FP128TyID:
1274     return LLVMPPC_FP128TypeKind;
1275   case Type::LabelTyID:
1276     return LLVMLabelTypeKind;
1277   case Type::MetadataTyID:
1278     return LLVMMetadataTypeKind;
1279   case Type::IntegerTyID:
1280     return LLVMIntegerTypeKind;
1281   case Type::FunctionTyID:
1282     return LLVMFunctionTypeKind;
1283   case Type::StructTyID:
1284     return LLVMStructTypeKind;
1285   case Type::ArrayTyID:
1286     return LLVMArrayTypeKind;
1287   case Type::PointerTyID:
1288     return LLVMPointerTypeKind;
1289 #if LLVM_VERSION_GE(11, 0)
1290   case Type::FixedVectorTyID:
1291     return LLVMVectorTypeKind;
1292 #else
1293   case Type::VectorTyID:
1294     return LLVMVectorTypeKind;
1295 #endif
1296   case Type::X86_MMXTyID:
1297     return LLVMX86_MMXTypeKind;
1298   case Type::TokenTyID:
1299     return LLVMTokenTypeKind;
1300 #if LLVM_VERSION_GE(11, 0)
1301   case Type::ScalableVectorTyID:
1302     return LLVMScalableVectorTypeKind;
1303   case Type::BFloatTyID:
1304     return LLVMBFloatTypeKind;
1305 #endif
1306 #if LLVM_VERSION_GE(12, 0)
1307   case Type::X86_AMXTyID:
1308     return LLVMX86_AMXTypeKind;
1309 #endif
1310   }
1311   report_fatal_error("Unhandled TypeID.");
1312 }
1313
1314 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1315
1316 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1317     LLVMContextRef C, LLVMContext::InlineAsmDiagHandlerTy H, void *CX) {
1318   unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1319 }
1320
1321 extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
1322                                            RustStringRef MessageOut,
1323                                            RustStringRef BufferOut,
1324                                            LLVMRustDiagnosticLevel* LevelOut,
1325                                            unsigned* LocOut,
1326                                            unsigned* RangesOut,
1327                                            size_t* NumRanges) {
1328   SMDiagnostic& D = *unwrap(DRef);
1329   RawRustStringOstream MessageOS(MessageOut);
1330   MessageOS << D.getMessage();
1331
1332   switch (D.getKind()) {
1333     case SourceMgr::DK_Error:
1334       *LevelOut = LLVMRustDiagnosticLevel::Error;
1335       break;
1336     case SourceMgr::DK_Warning:
1337       *LevelOut = LLVMRustDiagnosticLevel::Warning;
1338       break;
1339     case SourceMgr::DK_Note:
1340       *LevelOut = LLVMRustDiagnosticLevel::Note;
1341       break;
1342     case SourceMgr::DK_Remark:
1343       *LevelOut = LLVMRustDiagnosticLevel::Remark;
1344       break;
1345     default:
1346       report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1347   }
1348
1349   if (D.getLoc() == SMLoc())
1350     return false;
1351
1352   const SourceMgr &LSM = *D.getSourceMgr();
1353   const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
1354   LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), LBuf->getBufferSize());
1355
1356   *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
1357
1358   *NumRanges = std::min(*NumRanges, D.getRanges().size());
1359   size_t LineStart = *LocOut - (size_t)D.getColumnNo();
1360   for (size_t i = 0; i < *NumRanges; i++) {
1361     RangesOut[i * 2] = LineStart + D.getRanges()[i].first;
1362     RangesOut[i * 2 + 1] = LineStart + D.getRanges()[i].second;
1363   }
1364
1365   return true;
1366 }
1367
1368 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1369                                                 LLVMValueRef ParentPad,
1370                                                 unsigned ArgCount,
1371                                                 LLVMValueRef *LLArgs,
1372                                                 const char *Name) {
1373   Value **Args = unwrap(LLArgs);
1374   if (ParentPad == nullptr) {
1375     Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1376     ParentPad = wrap(Constant::getNullValue(Ty));
1377   }
1378   return wrap(unwrap(B)->CreateCleanupPad(
1379       unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1380 }
1381
1382 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1383                                                 LLVMValueRef CleanupPad,
1384                                                 LLVMBasicBlockRef UnwindBB) {
1385   CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1386   return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1387 }
1388
1389 extern "C" LLVMValueRef
1390 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1391                       unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1392   Value **Args = unwrap(LLArgs);
1393   return wrap(unwrap(B)->CreateCatchPad(
1394       unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1395 }
1396
1397 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1398                                               LLVMValueRef Pad,
1399                                               LLVMBasicBlockRef BB) {
1400   return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1401                                               unwrap(BB)));
1402 }
1403
1404 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1405                                                  LLVMValueRef ParentPad,
1406                                                  LLVMBasicBlockRef BB,
1407                                                  unsigned NumHandlers,
1408                                                  const char *Name) {
1409   if (ParentPad == nullptr) {
1410     Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1411     ParentPad = wrap(Constant::getNullValue(Ty));
1412   }
1413   return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1414                                                  NumHandlers, Name));
1415 }
1416
1417 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1418                                    LLVMBasicBlockRef Handler) {
1419   Value *CatchSwitch = unwrap(CatchSwitchRef);
1420   cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1421 }
1422
1423 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1424                                                            LLVMValueRef *Inputs,
1425                                                            unsigned NumInputs) {
1426   return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1427 }
1428
1429 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1430   delete Bundle;
1431 }
1432
1433 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
1434                                           LLVMValueRef *Args, unsigned NumArgs,
1435                                           OperandBundleDef *Bundle) {
1436   Value *Callee = unwrap(Fn);
1437   FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1438   unsigned Len = Bundle ? 1 : 0;
1439   ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1440   return wrap(unwrap(B)->CreateCall(
1441       FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles));
1442 }
1443
1444 extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
1445   return wrap(llvm::Intrinsic::getDeclaration(unwrap(M),
1446               (llvm::Intrinsic::ID)llvm::Intrinsic::instrprof_increment));
1447 }
1448
1449 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
1450                                             LLVMValueRef Dst, unsigned DstAlign,
1451                                             LLVMValueRef Src, unsigned SrcAlign,
1452                                             LLVMValueRef Size, bool IsVolatile) {
1453 #if LLVM_VERSION_GE(10, 0)
1454   return wrap(unwrap(B)->CreateMemCpy(
1455       unwrap(Dst), MaybeAlign(DstAlign),
1456       unwrap(Src), MaybeAlign(SrcAlign),
1457       unwrap(Size), IsVolatile));
1458 #else
1459   return wrap(unwrap(B)->CreateMemCpy(
1460       unwrap(Dst), DstAlign,
1461       unwrap(Src), SrcAlign,
1462       unwrap(Size), IsVolatile));
1463 #endif
1464 }
1465
1466 extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
1467                                              LLVMValueRef Dst, unsigned DstAlign,
1468                                              LLVMValueRef Src, unsigned SrcAlign,
1469                                              LLVMValueRef Size, bool IsVolatile) {
1470 #if LLVM_VERSION_GE(10, 0)
1471   return wrap(unwrap(B)->CreateMemMove(
1472       unwrap(Dst), MaybeAlign(DstAlign),
1473       unwrap(Src), MaybeAlign(SrcAlign),
1474       unwrap(Size), IsVolatile));
1475 #else
1476   return wrap(unwrap(B)->CreateMemMove(
1477       unwrap(Dst), DstAlign,
1478       unwrap(Src), SrcAlign,
1479       unwrap(Size), IsVolatile));
1480 #endif
1481 }
1482
1483 extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
1484                                             LLVMValueRef Dst, unsigned DstAlign,
1485                                             LLVMValueRef Val,
1486                                             LLVMValueRef Size, bool IsVolatile) {
1487 #if LLVM_VERSION_GE(10, 0)
1488   return wrap(unwrap(B)->CreateMemSet(
1489       unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
1490 #else
1491   return wrap(unwrap(B)->CreateMemSet(
1492       unwrap(Dst), unwrap(Val), unwrap(Size), DstAlign, IsVolatile));
1493 #endif
1494 }
1495
1496 extern "C" LLVMValueRef
1497 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
1498                     unsigned NumArgs, LLVMBasicBlockRef Then,
1499                     LLVMBasicBlockRef Catch, OperandBundleDef *Bundle,
1500                     const char *Name) {
1501   Value *Callee = unwrap(Fn);
1502   FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1503   unsigned Len = Bundle ? 1 : 0;
1504   ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1505   return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
1506                                       makeArrayRef(unwrap(Args), NumArgs),
1507                                       Bundles, Name));
1508 }
1509
1510 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1511                                                LLVMBasicBlockRef BB) {
1512   auto Point = unwrap(BB)->getFirstInsertionPt();
1513   unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1514 }
1515
1516 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1517                                   const char *Name, size_t NameLen) {
1518   Triple TargetTriple(unwrap(M)->getTargetTriple());
1519   GlobalObject *GV = unwrap<GlobalObject>(V);
1520   if (TargetTriple.supportsCOMDAT()) {
1521     StringRef NameRef(Name, NameLen);
1522     GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
1523   }
1524 }
1525
1526 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1527   GlobalObject *GV = unwrap<GlobalObject>(V);
1528   GV->setComdat(nullptr);
1529 }
1530
1531 enum class LLVMRustLinkage {
1532   ExternalLinkage = 0,
1533   AvailableExternallyLinkage = 1,
1534   LinkOnceAnyLinkage = 2,
1535   LinkOnceODRLinkage = 3,
1536   WeakAnyLinkage = 4,
1537   WeakODRLinkage = 5,
1538   AppendingLinkage = 6,
1539   InternalLinkage = 7,
1540   PrivateLinkage = 8,
1541   ExternalWeakLinkage = 9,
1542   CommonLinkage = 10,
1543 };
1544
1545 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1546   switch (Linkage) {
1547   case LLVMExternalLinkage:
1548     return LLVMRustLinkage::ExternalLinkage;
1549   case LLVMAvailableExternallyLinkage:
1550     return LLVMRustLinkage::AvailableExternallyLinkage;
1551   case LLVMLinkOnceAnyLinkage:
1552     return LLVMRustLinkage::LinkOnceAnyLinkage;
1553   case LLVMLinkOnceODRLinkage:
1554     return LLVMRustLinkage::LinkOnceODRLinkage;
1555   case LLVMWeakAnyLinkage:
1556     return LLVMRustLinkage::WeakAnyLinkage;
1557   case LLVMWeakODRLinkage:
1558     return LLVMRustLinkage::WeakODRLinkage;
1559   case LLVMAppendingLinkage:
1560     return LLVMRustLinkage::AppendingLinkage;
1561   case LLVMInternalLinkage:
1562     return LLVMRustLinkage::InternalLinkage;
1563   case LLVMPrivateLinkage:
1564     return LLVMRustLinkage::PrivateLinkage;
1565   case LLVMExternalWeakLinkage:
1566     return LLVMRustLinkage::ExternalWeakLinkage;
1567   case LLVMCommonLinkage:
1568     return LLVMRustLinkage::CommonLinkage;
1569   default:
1570     report_fatal_error("Invalid LLVMRustLinkage value!");
1571   }
1572 }
1573
1574 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1575   switch (Linkage) {
1576   case LLVMRustLinkage::ExternalLinkage:
1577     return LLVMExternalLinkage;
1578   case LLVMRustLinkage::AvailableExternallyLinkage:
1579     return LLVMAvailableExternallyLinkage;
1580   case LLVMRustLinkage::LinkOnceAnyLinkage:
1581     return LLVMLinkOnceAnyLinkage;
1582   case LLVMRustLinkage::LinkOnceODRLinkage:
1583     return LLVMLinkOnceODRLinkage;
1584   case LLVMRustLinkage::WeakAnyLinkage:
1585     return LLVMWeakAnyLinkage;
1586   case LLVMRustLinkage::WeakODRLinkage:
1587     return LLVMWeakODRLinkage;
1588   case LLVMRustLinkage::AppendingLinkage:
1589     return LLVMAppendingLinkage;
1590   case LLVMRustLinkage::InternalLinkage:
1591     return LLVMInternalLinkage;
1592   case LLVMRustLinkage::PrivateLinkage:
1593     return LLVMPrivateLinkage;
1594   case LLVMRustLinkage::ExternalWeakLinkage:
1595     return LLVMExternalWeakLinkage;
1596   case LLVMRustLinkage::CommonLinkage:
1597     return LLVMCommonLinkage;
1598   }
1599   report_fatal_error("Invalid LLVMRustLinkage value!");
1600 }
1601
1602 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1603   return toRust(LLVMGetLinkage(V));
1604 }
1605
1606 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1607                                    LLVMRustLinkage RustLinkage) {
1608   LLVMSetLinkage(V, fromRust(RustLinkage));
1609 }
1610
1611 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1612 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1613 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1614 {
1615     auto C = unwrap<llvm::ConstantInt>(CV);
1616     if (C->getBitWidth() > 128) { return false; }
1617     APInt AP;
1618     if (sext) {
1619         AP = C->getValue().sextOrSelf(128);
1620     } else {
1621         AP = C->getValue().zextOrSelf(128);
1622     }
1623     *low = AP.getLoBits(64).getZExtValue();
1624     *high = AP.getHiBits(64).getZExtValue();
1625     return true;
1626 }
1627
1628 enum class LLVMRustVisibility {
1629   Default = 0,
1630   Hidden = 1,
1631   Protected = 2,
1632 };
1633
1634 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1635   switch (Vis) {
1636   case LLVMDefaultVisibility:
1637     return LLVMRustVisibility::Default;
1638   case LLVMHiddenVisibility:
1639     return LLVMRustVisibility::Hidden;
1640   case LLVMProtectedVisibility:
1641     return LLVMRustVisibility::Protected;
1642   }
1643   report_fatal_error("Invalid LLVMRustVisibility value!");
1644 }
1645
1646 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1647   switch (Vis) {
1648   case LLVMRustVisibility::Default:
1649     return LLVMDefaultVisibility;
1650   case LLVMRustVisibility::Hidden:
1651     return LLVMHiddenVisibility;
1652   case LLVMRustVisibility::Protected:
1653     return LLVMProtectedVisibility;
1654   }
1655   report_fatal_error("Invalid LLVMRustVisibility value!");
1656 }
1657
1658 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1659   return toRust(LLVMGetVisibility(V));
1660 }
1661
1662 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1663 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1664                                              LLVMTypeRef DestTy, bool isSigned) {
1665   return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1666 }
1667
1668 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1669                                       LLVMRustVisibility RustVisibility) {
1670   LLVMSetVisibility(V, fromRust(RustVisibility));
1671 }
1672
1673 struct LLVMRustModuleBuffer {
1674   std::string data;
1675 };
1676
1677 extern "C" LLVMRustModuleBuffer*
1678 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1679 #if LLVM_VERSION_GE(10, 0)
1680   auto Ret = std::make_unique<LLVMRustModuleBuffer>();
1681 #else
1682   auto Ret = llvm::make_unique<LLVMRustModuleBuffer>();
1683 #endif
1684   {
1685     raw_string_ostream OS(Ret->data);
1686     {
1687       legacy::PassManager PM;
1688       PM.add(createBitcodeWriterPass(OS));
1689       PM.run(*unwrap(M));
1690     }
1691   }
1692   return Ret.release();
1693 }
1694
1695 extern "C" void
1696 LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1697   delete Buffer;
1698 }
1699
1700 extern "C" const void*
1701 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1702   return Buffer->data.data();
1703 }
1704
1705 extern "C" size_t
1706 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1707   return Buffer->data.length();
1708 }
1709
1710 extern "C" uint64_t
1711 LLVMRustModuleCost(LLVMModuleRef M) {
1712   auto f = unwrap(M)->functions();
1713   return std::distance(std::begin(f), std::end(f));
1714 }
1715
1716 // Vector reductions:
1717 extern "C" LLVMValueRef
1718 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1719     return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1720 }
1721 extern "C" LLVMValueRef
1722 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1723     return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1724 }
1725 extern "C" LLVMValueRef
1726 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1727     return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1728 }
1729 extern "C" LLVMValueRef
1730 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1731     return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1732 }
1733 extern "C" LLVMValueRef
1734 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1735     return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1736 }
1737 extern "C" LLVMValueRef
1738 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1739     return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1740 }
1741 extern "C" LLVMValueRef
1742 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1743     return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1744 }
1745 extern "C" LLVMValueRef
1746 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1747     return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1748 }
1749 extern "C" LLVMValueRef
1750 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1751     return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1752 }
1753 extern "C" LLVMValueRef
1754 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1755 #if LLVM_VERSION_GE(12, 0)
1756   Instruction *I = unwrap(B)->CreateFPMinReduce(unwrap(Src));
1757   I->setHasNoNaNs(NoNaN);
1758   return wrap(I);
1759 #else
1760   return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN));
1761 #endif
1762 }
1763 extern "C" LLVMValueRef
1764 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1765 #if LLVM_VERSION_GE(12, 0)
1766   Instruction *I = unwrap(B)->CreateFPMaxReduce(unwrap(Src));
1767   I->setHasNoNaNs(NoNaN);
1768   return wrap(I);
1769 #else
1770   return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN));
1771 #endif
1772 }
1773
1774 extern "C" LLVMValueRef
1775 LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1776     return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1777 }
1778 extern "C" LLVMValueRef
1779 LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1780     return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));
1781 }