]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Auto merge of #82122 - bstrie:dep4real, r=dtolnay
[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   AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
386       unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
387       fromRust(FailureOrder));
388   ACXI->setWeak(Weak);
389   return wrap(ACXI);
390 }
391
392 enum class LLVMRustSynchronizationScope {
393   SingleThread,
394   CrossThread,
395 };
396
397 static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
398   switch (Scope) {
399   case LLVMRustSynchronizationScope::SingleThread:
400     return SyncScope::SingleThread;
401   case LLVMRustSynchronizationScope::CrossThread:
402     return SyncScope::System;
403   default:
404     report_fatal_error("bad SynchronizationScope.");
405   }
406 }
407
408 extern "C" LLVMValueRef
409 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
410                          LLVMRustSynchronizationScope Scope) {
411   return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
412 }
413
414 enum class LLVMRustAsmDialect {
415   Att,
416   Intel,
417 };
418
419 static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
420   switch (Dialect) {
421   case LLVMRustAsmDialect::Att:
422     return InlineAsm::AD_ATT;
423   case LLVMRustAsmDialect::Intel:
424     return InlineAsm::AD_Intel;
425   default:
426     report_fatal_error("bad AsmDialect.");
427   }
428 }
429
430 extern "C" LLVMValueRef
431 LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
432                   char *Constraints, size_t ConstraintsLen,
433                   LLVMBool HasSideEffects, LLVMBool IsAlignStack,
434                   LLVMRustAsmDialect Dialect) {
435   return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
436                              StringRef(AsmString, AsmStringLen),
437                              StringRef(Constraints, ConstraintsLen),
438                              HasSideEffects, IsAlignStack, fromRust(Dialect)));
439 }
440
441 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
442                                         size_t ConstraintsLen) {
443   return InlineAsm::Verify(unwrap<FunctionType>(Ty),
444                            StringRef(Constraints, ConstraintsLen));
445 }
446
447 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
448                                               size_t AsmLen) {
449   unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen));
450 }
451
452 typedef DIBuilder *LLVMRustDIBuilderRef;
453
454 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
455   return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
456 }
457
458 #define DIDescriptor DIScope
459 #define DIArray DINodeArray
460 #define unwrapDI unwrapDIPtr
461
462 // These values **must** match debuginfo::DIFlags! They also *happen*
463 // to match LLVM, but that isn't required as we do giant sets of
464 // matching below. The value shouldn't be directly passed to LLVM.
465 enum class LLVMRustDIFlags : uint32_t {
466   FlagZero = 0,
467   FlagPrivate = 1,
468   FlagProtected = 2,
469   FlagPublic = 3,
470   FlagFwdDecl = (1 << 2),
471   FlagAppleBlock = (1 << 3),
472   FlagBlockByrefStruct = (1 << 4),
473   FlagVirtual = (1 << 5),
474   FlagArtificial = (1 << 6),
475   FlagExplicit = (1 << 7),
476   FlagPrototyped = (1 << 8),
477   FlagObjcClassComplete = (1 << 9),
478   FlagObjectPointer = (1 << 10),
479   FlagVector = (1 << 11),
480   FlagStaticMember = (1 << 12),
481   FlagLValueReference = (1 << 13),
482   FlagRValueReference = (1 << 14),
483   FlagExternalTypeRef = (1 << 15),
484   FlagIntroducedVirtual = (1 << 18),
485   FlagBitField = (1 << 19),
486   FlagNoReturn = (1 << 20),
487   // Do not add values that are not supported by the minimum LLVM
488   // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
489 };
490
491 inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
492   return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
493                                       static_cast<uint32_t>(B));
494 }
495
496 inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
497   return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
498                                       static_cast<uint32_t>(B));
499 }
500
501 inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
502   return A = A | B;
503 }
504
505 inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
506
507 inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
508   return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
509 }
510
511 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
512   DINode::DIFlags Result = DINode::DIFlags::FlagZero;
513
514   switch (visibility(Flags)) {
515   case LLVMRustDIFlags::FlagPrivate:
516     Result |= DINode::DIFlags::FlagPrivate;
517     break;
518   case LLVMRustDIFlags::FlagProtected:
519     Result |= DINode::DIFlags::FlagProtected;
520     break;
521   case LLVMRustDIFlags::FlagPublic:
522     Result |= DINode::DIFlags::FlagPublic;
523     break;
524   default:
525     // The rest are handled below
526     break;
527   }
528
529   if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
530     Result |= DINode::DIFlags::FlagFwdDecl;
531   }
532   if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
533     Result |= DINode::DIFlags::FlagAppleBlock;
534   }
535 #if LLVM_VERSION_LT(10, 0)
536   if (isSet(Flags & LLVMRustDIFlags::FlagBlockByrefStruct)) {
537     Result |= DINode::DIFlags::FlagBlockByrefStruct;
538   }
539 #endif
540   if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
541     Result |= DINode::DIFlags::FlagVirtual;
542   }
543   if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
544     Result |= DINode::DIFlags::FlagArtificial;
545   }
546   if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
547     Result |= DINode::DIFlags::FlagExplicit;
548   }
549   if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
550     Result |= DINode::DIFlags::FlagPrototyped;
551   }
552   if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
553     Result |= DINode::DIFlags::FlagObjcClassComplete;
554   }
555   if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
556     Result |= DINode::DIFlags::FlagObjectPointer;
557   }
558   if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
559     Result |= DINode::DIFlags::FlagVector;
560   }
561   if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
562     Result |= DINode::DIFlags::FlagStaticMember;
563   }
564   if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
565     Result |= DINode::DIFlags::FlagLValueReference;
566   }
567   if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
568     Result |= DINode::DIFlags::FlagRValueReference;
569   }
570   if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
571     Result |= DINode::DIFlags::FlagIntroducedVirtual;
572   }
573   if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
574     Result |= DINode::DIFlags::FlagBitField;
575   }
576   if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
577     Result |= DINode::DIFlags::FlagNoReturn;
578   }
579
580   return Result;
581 }
582
583 // These values **must** match debuginfo::DISPFlags! They also *happen*
584 // to match LLVM, but that isn't required as we do giant sets of
585 // matching below. The value shouldn't be directly passed to LLVM.
586 enum class LLVMRustDISPFlags : uint32_t {
587   SPFlagZero = 0,
588   SPFlagVirtual = 1,
589   SPFlagPureVirtual = 2,
590   SPFlagLocalToUnit = (1 << 2),
591   SPFlagDefinition = (1 << 3),
592   SPFlagOptimized = (1 << 4),
593   SPFlagMainSubprogram = (1 << 5),
594   // Do not add values that are not supported by the minimum LLVM
595   // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
596   // (In LLVM < 8, createFunction supported these as separate bool arguments.)
597 };
598
599 inline LLVMRustDISPFlags operator&(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
600   return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) &
601                                       static_cast<uint32_t>(B));
602 }
603
604 inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
605   return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) |
606                                       static_cast<uint32_t>(B));
607 }
608
609 inline LLVMRustDISPFlags &operator|=(LLVMRustDISPFlags &A, LLVMRustDISPFlags B) {
610   return A = A | B;
611 }
612
613 inline bool isSet(LLVMRustDISPFlags F) { return F != LLVMRustDISPFlags::SPFlagZero; }
614
615 inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) {
616   return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(F) & 0x3);
617 }
618
619 static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) {
620   DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero;
621
622   switch (virtuality(SPFlags)) {
623   case LLVMRustDISPFlags::SPFlagVirtual:
624     Result |= DISubprogram::DISPFlags::SPFlagVirtual;
625     break;
626   case LLVMRustDISPFlags::SPFlagPureVirtual:
627     Result |= DISubprogram::DISPFlags::SPFlagPureVirtual;
628     break;
629   default:
630     // The rest are handled below
631     break;
632   }
633
634   if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit)) {
635     Result |= DISubprogram::DISPFlags::SPFlagLocalToUnit;
636   }
637   if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition)) {
638     Result |= DISubprogram::DISPFlags::SPFlagDefinition;
639   }
640   if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) {
641     Result |= DISubprogram::DISPFlags::SPFlagOptimized;
642   }
643   if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) {
644     Result |= DISubprogram::DISPFlags::SPFlagMainSubprogram;
645   }
646
647   return Result;
648 }
649
650 enum class LLVMRustDebugEmissionKind {
651   NoDebug,
652   FullDebug,
653   LineTablesOnly,
654 };
655
656 static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
657   switch (Kind) {
658   case LLVMRustDebugEmissionKind::NoDebug:
659     return DICompileUnit::DebugEmissionKind::NoDebug;
660   case LLVMRustDebugEmissionKind::FullDebug:
661     return DICompileUnit::DebugEmissionKind::FullDebug;
662   case LLVMRustDebugEmissionKind::LineTablesOnly:
663     return DICompileUnit::DebugEmissionKind::LineTablesOnly;
664   default:
665     report_fatal_error("bad DebugEmissionKind.");
666   }
667 }
668
669 enum class LLVMRustChecksumKind {
670   None,
671   MD5,
672   SHA1,
673   SHA256,
674 };
675
676 static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
677   switch (Kind) {
678   case LLVMRustChecksumKind::None:
679     return None;
680   case LLVMRustChecksumKind::MD5:
681     return DIFile::ChecksumKind::CSK_MD5;
682   case LLVMRustChecksumKind::SHA1:
683     return DIFile::ChecksumKind::CSK_SHA1;
684 #if (LLVM_VERSION_MAJOR >= 11)
685   case LLVMRustChecksumKind::SHA256:
686     return DIFile::ChecksumKind::CSK_SHA256;
687 #endif
688   default:
689     report_fatal_error("bad ChecksumKind.");
690   }
691 }
692
693 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
694   return DEBUG_METADATA_VERSION;
695 }
696
697 extern "C" uint32_t LLVMRustVersionPatch() { return LLVM_VERSION_PATCH; }
698
699 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
700
701 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
702
703 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
704                                       uint32_t Value) {
705   unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
706 }
707
708 extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
709   return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
710 }
711
712 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
713   return new DIBuilder(*unwrap(M));
714 }
715
716 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
717   delete Builder;
718 }
719
720 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
721   Builder->finalize();
722 }
723
724 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
725     LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
726     const char *Producer, size_t ProducerLen, bool isOptimized,
727     const char *Flags, unsigned RuntimeVer,
728     const char *SplitName, size_t SplitNameLen,
729     LLVMRustDebugEmissionKind Kind,
730     uint64_t DWOId, bool SplitDebugInlining) {
731   auto *File = unwrapDI<DIFile>(FileRef);
732
733   return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
734                                          isOptimized, Flags, RuntimeVer,
735                                          StringRef(SplitName, SplitNameLen),
736                                          fromRust(Kind), DWOId, SplitDebugInlining));
737 }
738
739 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
740     LLVMRustDIBuilderRef Builder,
741     const char *Filename, size_t FilenameLen,
742     const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
743     const char *Checksum, size_t ChecksumLen) {
744   Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
745   Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
746   if (llvmCSKind)
747     CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
748   return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
749                                   StringRef(Directory, DirectoryLen),
750                                   CSInfo));
751 }
752
753 extern "C" LLVMMetadataRef
754 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
755                                       LLVMMetadataRef ParameterTypes) {
756   return wrap(Builder->createSubroutineType(
757       DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
758 }
759
760 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
761     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
762     const char *Name, size_t NameLen,
763     const char *LinkageName, size_t LinkageNameLen,
764     LLVMMetadataRef File, unsigned LineNo,
765     LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
766     LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam,
767     LLVMMetadataRef Decl) {
768   DITemplateParameterArray TParams =
769       DITemplateParameterArray(unwrap<MDTuple>(TParam));
770   DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
771   DINode::DIFlags llvmFlags = fromRust(Flags);
772   DISubprogram *Sub = Builder->createFunction(
773       unwrapDI<DIScope>(Scope),
774       StringRef(Name, NameLen),
775       StringRef(LinkageName, LinkageNameLen),
776       unwrapDI<DIFile>(File), LineNo,
777       unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
778       llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
779   if (MaybeFn)
780     unwrap<Function>(MaybeFn)->setSubprogram(Sub);
781   return wrap(Sub);
782 }
783
784 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
785     LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
786     uint64_t SizeInBits, unsigned Encoding) {
787   return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
788 }
789
790 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
791     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
792     LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
793   return wrap(Builder->createTypedef(
794     unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
795     LineNo, unwrapDIPtr<DIScope>(Scope)));
796 }
797
798 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
799     LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
800     uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
801     const char *Name, size_t NameLen) {
802   return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
803                                          SizeInBits, AlignInBits,
804                                          AddressSpace,
805                                          StringRef(Name, NameLen)));
806 }
807
808 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
809     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
810     const char *Name, size_t NameLen,
811     LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
812     uint32_t AlignInBits, LLVMRustDIFlags Flags,
813     LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
814     unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
815     const char *UniqueId, size_t UniqueIdLen) {
816   return wrap(Builder->createStructType(
817       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
818       unwrapDI<DIFile>(File), LineNumber,
819       SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
820       DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
821       unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen)));
822 }
823
824 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
825     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
826     const char *Name, size_t NameLen,
827     LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
828     uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
829     LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) {
830   return wrap(Builder->createVariantPart(
831       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
832       unwrapDI<DIFile>(File), LineNumber,
833       SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
834       DINodeArray(unwrapDI<MDTuple>(Elements)), StringRef(UniqueId, UniqueIdLen)));
835 }
836
837 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
838     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
839     const char *Name, size_t NameLen,
840     LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
841     uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
842     LLVMMetadataRef Ty) {
843   return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope),
844                                         StringRef(Name, NameLen),
845                                         unwrapDI<DIFile>(File), LineNo,
846                                         SizeInBits, AlignInBits, OffsetInBits,
847                                         fromRust(Flags), unwrapDI<DIType>(Ty)));
848 }
849
850 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
851     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
852     const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
853     uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
854     LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
855   llvm::ConstantInt* D = nullptr;
856   if (Discriminant) {
857     D = unwrap<llvm::ConstantInt>(Discriminant);
858   }
859   return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope),
860                                                StringRef(Name, NameLen),
861                                                unwrapDI<DIFile>(File), LineNo,
862                                                SizeInBits, AlignInBits, OffsetInBits, D,
863                                                fromRust(Flags), unwrapDI<DIType>(Ty)));
864 }
865
866 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
867     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
868     LLVMMetadataRef File, unsigned Line, unsigned Col) {
869   return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
870                                           unwrapDI<DIFile>(File), Line, Col));
871 }
872
873 extern "C" LLVMMetadataRef
874 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
875                                         LLVMMetadataRef Scope,
876                                         LLVMMetadataRef File) {
877   return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
878                                               unwrapDI<DIFile>(File)));
879 }
880
881 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
882     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context,
883     const char *Name, size_t NameLen,
884     const char *LinkageName, size_t LinkageNameLen,
885     LLVMMetadataRef File, unsigned LineNo,
886     LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
887     LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
888   llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
889
890   llvm::DIExpression *InitExpr = nullptr;
891   if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
892     InitExpr = Builder->createConstantValueExpression(
893         IntVal->getValue().getSExtValue());
894   } else if (llvm::ConstantFP *FPVal =
895                  llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
896     InitExpr = Builder->createConstantValueExpression(
897         FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
898   }
899
900   llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
901       unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
902       StringRef(LinkageName, LinkageNameLen),
903       unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
904 #if LLVM_VERSION_GE(10, 0)
905       /* isDefined */ true,
906 #endif
907       InitExpr, unwrapDIPtr<MDNode>(Decl),
908       /* templateParams */ nullptr,
909       AlignInBits);
910
911   InitVal->setMetadata("dbg", VarExpr);
912
913   return wrap(VarExpr);
914 }
915
916 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
917     LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
918     const char *Name, size_t NameLen,
919     LLVMMetadataRef File, unsigned LineNo,
920     LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
921     unsigned ArgNo, uint32_t AlignInBits) {
922   if (Tag == 0x100) { // DW_TAG_auto_variable
923     return wrap(Builder->createAutoVariable(
924         unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
925         unwrapDI<DIFile>(File), LineNo,
926         unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
927   } else {
928     return wrap(Builder->createParameterVariable(
929         unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
930         unwrapDI<DIFile>(File), LineNo,
931         unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
932   }
933 }
934
935 extern "C" LLVMMetadataRef
936 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
937                                  uint32_t AlignInBits, LLVMMetadataRef Ty,
938                                  LLVMMetadataRef Subscripts) {
939   return wrap(
940       Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
941                                DINodeArray(unwrapDI<MDTuple>(Subscripts))));
942 }
943
944 extern "C" LLVMMetadataRef
945 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
946                                      int64_t Count) {
947   return wrap(Builder->getOrCreateSubrange(Lo, Count));
948 }
949
950 extern "C" LLVMMetadataRef
951 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
952                                   LLVMMetadataRef *Ptr, unsigned Count) {
953   Metadata **DataValue = unwrap(Ptr);
954   return wrap(
955       Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
956 }
957
958 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
959     LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
960     int64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
961     LLVMBasicBlockRef InsertAtEnd) {
962   return wrap(Builder->insertDeclare(
963       unwrap(V), unwrap<DILocalVariable>(VarInfo),
964       Builder->createExpression(llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
965       DebugLoc(cast<MDNode>(unwrap(DL))),
966       unwrap(InsertAtEnd)));
967 }
968
969 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
970     LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
971     int64_t Value, bool IsUnsigned) {
972   return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
973 }
974
975 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
976     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
977     const char *Name, size_t NameLen,
978     LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
979     uint32_t AlignInBits, LLVMMetadataRef Elements,
980     LLVMMetadataRef ClassTy, bool IsScoped) {
981   return wrap(Builder->createEnumerationType(
982       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
983       unwrapDI<DIFile>(File), LineNumber,
984       SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
985       unwrapDI<DIType>(ClassTy), "", IsScoped));
986 }
987
988 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
989     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
990     const char *Name, size_t NameLen,
991     LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
992     uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
993     unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) {
994   return wrap(Builder->createUnionType(
995       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File),
996       LineNumber, SizeInBits, AlignInBits, fromRust(Flags),
997       DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
998       StringRef(UniqueId, UniqueIdLen)));
999 }
1000
1001 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
1002     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1003     const char *Name, size_t NameLen, LLVMMetadataRef Ty) {
1004 #if LLVM_VERSION_GE(11, 0)
1005   bool IsDefault = false; // FIXME: should we ever set this true?
1006   return wrap(Builder->createTemplateTypeParameter(
1007       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty), IsDefault));
1008 #else
1009   return wrap(Builder->createTemplateTypeParameter(
1010       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty)));
1011 #endif
1012 }
1013
1014 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateNameSpace(
1015     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1016     const char *Name, size_t NameLen, bool ExportSymbols) {
1017   return wrap(Builder->createNameSpace(
1018       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols
1019   ));
1020 }
1021
1022 extern "C" void
1023 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
1024                                      LLVMMetadataRef CompositeTy,
1025                                      LLVMMetadataRef Elements,
1026                                      LLVMMetadataRef Params) {
1027   DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
1028   Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
1029                          DINodeArray(unwrap<MDTuple>(Params)));
1030 }
1031
1032 extern "C" LLVMMetadataRef
1033 LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
1034                                      LLVMMetadataRef ScopeRef,
1035                                      LLVMMetadataRef InlinedAt) {
1036 #if LLVM_VERSION_GE(12, 0)
1037   MDNode *Scope = unwrapDIPtr<MDNode>(ScopeRef);
1038   DILocation *Loc = DILocation::get(
1039       Scope->getContext(), Line, Column, Scope,
1040       unwrapDIPtr<MDNode>(InlinedAt));
1041   return wrap(Loc);
1042 #else
1043   DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(ScopeRef),
1044                                      unwrapDIPtr<MDNode>(InlinedAt));
1045   return wrap(debug_loc.getAsMDNode());
1046 #endif
1047 }
1048
1049 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
1050   return dwarf::DW_OP_deref;
1051 }
1052
1053 extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1054   return dwarf::DW_OP_plus_uconst;
1055 }
1056
1057 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
1058   RawRustStringOstream OS(Str);
1059   unwrap<llvm::Type>(Ty)->print(OS);
1060 }
1061
1062 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
1063                                            RustStringRef Str) {
1064   RawRustStringOstream OS(Str);
1065   if (!V) {
1066     OS << "(null)";
1067   } else {
1068     OS << "(";
1069     unwrap<llvm::Value>(V)->getType()->print(OS);
1070     OS << ":";
1071     unwrap<llvm::Value>(V)->print(OS);
1072     OS << ")";
1073   }
1074 }
1075
1076 // Note that the two following functions look quite similar to the
1077 // LLVMGetSectionName function. Sadly, it appears that this function only
1078 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
1079 // function provided by LLVM doesn't return the length, so we've created our own
1080 // function which returns the length as well as the data pointer.
1081 //
1082 // For an example of this not returning a null terminated string, see
1083 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
1084 // branches explicitly creates a StringRef without a null terminator, and then
1085 // that's returned.
1086
1087 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
1088   return reinterpret_cast<section_iterator *>(SI);
1089 }
1090
1091 extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI,
1092                                          const char **Ptr) {
1093 #if LLVM_VERSION_GE(10, 0)
1094   auto NameOrErr = (*unwrap(SI))->getName();
1095   if (!NameOrErr)
1096     report_fatal_error(NameOrErr.takeError());
1097   *Ptr = NameOrErr->data();
1098   return NameOrErr->size();
1099 #else
1100   StringRef Ret;
1101   if (std::error_code EC = (*unwrap(SI))->getName(Ret))
1102     report_fatal_error(EC.message());
1103   *Ptr = Ret.data();
1104   return Ret.size();
1105 #endif
1106 }
1107
1108 // LLVMArrayType function does not support 64-bit ElementCount
1109 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
1110                                          uint64_t ElementCount) {
1111   return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
1112 }
1113
1114 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1115
1116 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
1117   RawRustStringOstream OS(Str);
1118   unwrap(T)->print(OS);
1119 }
1120
1121 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1122     LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
1123     LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
1124     RustStringRef FilenameOut, RustStringRef MessageOut) {
1125   // Undefined to call this not on an optimization diagnostic!
1126   llvm::DiagnosticInfoOptimizationBase *Opt =
1127       static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
1128
1129   RawRustStringOstream PassNameOS(PassNameOut);
1130   PassNameOS << Opt->getPassName();
1131   *FunctionOut = wrap(&Opt->getFunction());
1132
1133   RawRustStringOstream FilenameOS(FilenameOut);
1134   DiagnosticLocation loc = Opt->getLocation();
1135   if (loc.isValid()) {
1136     *Line = loc.getLine();
1137     *Column = loc.getColumn();
1138     FilenameOS << loc.getAbsolutePath();
1139   }
1140
1141   RawRustStringOstream MessageOS(MessageOut);
1142   MessageOS << Opt->getMsg();
1143 }
1144
1145 enum class LLVMRustDiagnosticLevel {
1146     Error,
1147     Warning,
1148     Note,
1149     Remark,
1150 };
1151
1152 extern "C" void
1153 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
1154                                   LLVMRustDiagnosticLevel *LevelOut,
1155                                   unsigned *CookieOut,
1156                                   LLVMTwineRef *MessageOut,
1157                                   LLVMValueRef *InstructionOut) {
1158   // Undefined to call this not on an inline assembly diagnostic!
1159   llvm::DiagnosticInfoInlineAsm *IA =
1160       static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
1161
1162   *CookieOut = IA->getLocCookie();
1163   *MessageOut = wrap(&IA->getMsgStr());
1164   *InstructionOut = wrap(IA->getInstruction());
1165
1166   switch (IA->getSeverity()) {
1167     case DS_Error:
1168       *LevelOut = LLVMRustDiagnosticLevel::Error;
1169       break;
1170     case DS_Warning:
1171       *LevelOut = LLVMRustDiagnosticLevel::Warning;
1172       break;
1173     case DS_Note:
1174       *LevelOut = LLVMRustDiagnosticLevel::Note;
1175       break;
1176     case DS_Remark:
1177       *LevelOut = LLVMRustDiagnosticLevel::Remark;
1178       break;
1179     default:
1180       report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1181   }
1182 }
1183
1184 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
1185                                                     RustStringRef Str) {
1186   RawRustStringOstream OS(Str);
1187   DiagnosticPrinterRawOStream DP(OS);
1188   unwrap(DI)->print(DP);
1189 }
1190
1191 enum class LLVMRustDiagnosticKind {
1192   Other,
1193   InlineAsm,
1194   StackSize,
1195   DebugMetadataVersion,
1196   SampleProfile,
1197   OptimizationRemark,
1198   OptimizationRemarkMissed,
1199   OptimizationRemarkAnalysis,
1200   OptimizationRemarkAnalysisFPCommute,
1201   OptimizationRemarkAnalysisAliasing,
1202   OptimizationRemarkOther,
1203   OptimizationFailure,
1204   PGOProfile,
1205   Linker,
1206   Unsupported,
1207 };
1208
1209 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1210   switch (Kind) {
1211   case DK_InlineAsm:
1212     return LLVMRustDiagnosticKind::InlineAsm;
1213   case DK_StackSize:
1214     return LLVMRustDiagnosticKind::StackSize;
1215   case DK_DebugMetadataVersion:
1216     return LLVMRustDiagnosticKind::DebugMetadataVersion;
1217   case DK_SampleProfile:
1218     return LLVMRustDiagnosticKind::SampleProfile;
1219   case DK_OptimizationRemark:
1220     return LLVMRustDiagnosticKind::OptimizationRemark;
1221   case DK_OptimizationRemarkMissed:
1222     return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1223   case DK_OptimizationRemarkAnalysis:
1224     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1225   case DK_OptimizationRemarkAnalysisFPCommute:
1226     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1227   case DK_OptimizationRemarkAnalysisAliasing:
1228     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1229   case DK_PGOProfile:
1230     return LLVMRustDiagnosticKind::PGOProfile;
1231   case DK_Linker:
1232     return LLVMRustDiagnosticKind::Linker;
1233   case DK_Unsupported:
1234     return LLVMRustDiagnosticKind::Unsupported;
1235   default:
1236     return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1237                ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1238                : LLVMRustDiagnosticKind::Other;
1239   }
1240 }
1241
1242 extern "C" LLVMRustDiagnosticKind
1243 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1244   return toRust((DiagnosticKind)unwrap(DI)->getKind());
1245 }
1246
1247 // This is kept distinct from LLVMGetTypeKind, because when
1248 // a new type kind is added, the Rust-side enum must be
1249 // updated or UB will result.
1250 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1251   switch (unwrap(Ty)->getTypeID()) {
1252   case Type::VoidTyID:
1253     return LLVMVoidTypeKind;
1254   case Type::HalfTyID:
1255     return LLVMHalfTypeKind;
1256   case Type::FloatTyID:
1257     return LLVMFloatTypeKind;
1258   case Type::DoubleTyID:
1259     return LLVMDoubleTypeKind;
1260   case Type::X86_FP80TyID:
1261     return LLVMX86_FP80TypeKind;
1262   case Type::FP128TyID:
1263     return LLVMFP128TypeKind;
1264   case Type::PPC_FP128TyID:
1265     return LLVMPPC_FP128TypeKind;
1266   case Type::LabelTyID:
1267     return LLVMLabelTypeKind;
1268   case Type::MetadataTyID:
1269     return LLVMMetadataTypeKind;
1270   case Type::IntegerTyID:
1271     return LLVMIntegerTypeKind;
1272   case Type::FunctionTyID:
1273     return LLVMFunctionTypeKind;
1274   case Type::StructTyID:
1275     return LLVMStructTypeKind;
1276   case Type::ArrayTyID:
1277     return LLVMArrayTypeKind;
1278   case Type::PointerTyID:
1279     return LLVMPointerTypeKind;
1280 #if LLVM_VERSION_GE(11, 0)
1281   case Type::FixedVectorTyID:
1282     return LLVMVectorTypeKind;
1283 #else
1284   case Type::VectorTyID:
1285     return LLVMVectorTypeKind;
1286 #endif
1287   case Type::X86_MMXTyID:
1288     return LLVMX86_MMXTypeKind;
1289   case Type::TokenTyID:
1290     return LLVMTokenTypeKind;
1291 #if LLVM_VERSION_GE(11, 0)
1292   case Type::ScalableVectorTyID:
1293     return LLVMScalableVectorTypeKind;
1294   case Type::BFloatTyID:
1295     return LLVMBFloatTypeKind;
1296 #endif
1297 #if LLVM_VERSION_GE(12, 0)
1298   case Type::X86_AMXTyID:
1299     return LLVMX86_AMXTypeKind;
1300 #endif
1301   }
1302   report_fatal_error("Unhandled TypeID.");
1303 }
1304
1305 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1306
1307 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1308     LLVMContextRef C, LLVMContext::InlineAsmDiagHandlerTy H, void *CX) {
1309   unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1310 }
1311
1312 extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
1313                                            RustStringRef MessageOut,
1314                                            RustStringRef BufferOut,
1315                                            LLVMRustDiagnosticLevel* LevelOut,
1316                                            unsigned* LocOut,
1317                                            unsigned* RangesOut,
1318                                            size_t* NumRanges) {
1319   SMDiagnostic& D = *unwrap(DRef);
1320   RawRustStringOstream MessageOS(MessageOut);
1321   MessageOS << D.getMessage();
1322
1323   switch (D.getKind()) {
1324     case SourceMgr::DK_Error:
1325       *LevelOut = LLVMRustDiagnosticLevel::Error;
1326       break;
1327     case SourceMgr::DK_Warning:
1328       *LevelOut = LLVMRustDiagnosticLevel::Warning;
1329       break;
1330     case SourceMgr::DK_Note:
1331       *LevelOut = LLVMRustDiagnosticLevel::Note;
1332       break;
1333     case SourceMgr::DK_Remark:
1334       *LevelOut = LLVMRustDiagnosticLevel::Remark;
1335       break;
1336     default:
1337       report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1338   }
1339
1340   if (D.getLoc() == SMLoc())
1341     return false;
1342
1343   const SourceMgr &LSM = *D.getSourceMgr();
1344   const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
1345   LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), LBuf->getBufferSize());
1346
1347   *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
1348
1349   *NumRanges = std::min(*NumRanges, D.getRanges().size());
1350   size_t LineStart = *LocOut - (size_t)D.getColumnNo();
1351   for (size_t i = 0; i < *NumRanges; i++) {
1352     RangesOut[i * 2] = LineStart + D.getRanges()[i].first;
1353     RangesOut[i * 2 + 1] = LineStart + D.getRanges()[i].second;
1354   }
1355
1356   return true;
1357 }
1358
1359 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1360                                                 LLVMValueRef ParentPad,
1361                                                 unsigned ArgCount,
1362                                                 LLVMValueRef *LLArgs,
1363                                                 const char *Name) {
1364   Value **Args = unwrap(LLArgs);
1365   if (ParentPad == nullptr) {
1366     Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1367     ParentPad = wrap(Constant::getNullValue(Ty));
1368   }
1369   return wrap(unwrap(B)->CreateCleanupPad(
1370       unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1371 }
1372
1373 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1374                                                 LLVMValueRef CleanupPad,
1375                                                 LLVMBasicBlockRef UnwindBB) {
1376   CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1377   return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1378 }
1379
1380 extern "C" LLVMValueRef
1381 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1382                       unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1383   Value **Args = unwrap(LLArgs);
1384   return wrap(unwrap(B)->CreateCatchPad(
1385       unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1386 }
1387
1388 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1389                                               LLVMValueRef Pad,
1390                                               LLVMBasicBlockRef BB) {
1391   return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1392                                               unwrap(BB)));
1393 }
1394
1395 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1396                                                  LLVMValueRef ParentPad,
1397                                                  LLVMBasicBlockRef BB,
1398                                                  unsigned NumHandlers,
1399                                                  const char *Name) {
1400   if (ParentPad == nullptr) {
1401     Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1402     ParentPad = wrap(Constant::getNullValue(Ty));
1403   }
1404   return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1405                                                  NumHandlers, Name));
1406 }
1407
1408 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1409                                    LLVMBasicBlockRef Handler) {
1410   Value *CatchSwitch = unwrap(CatchSwitchRef);
1411   cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1412 }
1413
1414 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1415                                                            LLVMValueRef *Inputs,
1416                                                            unsigned NumInputs) {
1417   return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1418 }
1419
1420 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1421   delete Bundle;
1422 }
1423
1424 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
1425                                           LLVMValueRef *Args, unsigned NumArgs,
1426                                           OperandBundleDef *Bundle) {
1427   Value *Callee = unwrap(Fn);
1428   FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1429   unsigned Len = Bundle ? 1 : 0;
1430   ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1431   return wrap(unwrap(B)->CreateCall(
1432       FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles));
1433 }
1434
1435 extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
1436   return wrap(llvm::Intrinsic::getDeclaration(unwrap(M),
1437               (llvm::Intrinsic::ID)llvm::Intrinsic::instrprof_increment));
1438 }
1439
1440 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
1441                                             LLVMValueRef Dst, unsigned DstAlign,
1442                                             LLVMValueRef Src, unsigned SrcAlign,
1443                                             LLVMValueRef Size, bool IsVolatile) {
1444 #if LLVM_VERSION_GE(10, 0)
1445   return wrap(unwrap(B)->CreateMemCpy(
1446       unwrap(Dst), MaybeAlign(DstAlign),
1447       unwrap(Src), MaybeAlign(SrcAlign),
1448       unwrap(Size), IsVolatile));
1449 #else
1450   return wrap(unwrap(B)->CreateMemCpy(
1451       unwrap(Dst), DstAlign,
1452       unwrap(Src), SrcAlign,
1453       unwrap(Size), IsVolatile));
1454 #endif
1455 }
1456
1457 extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
1458                                              LLVMValueRef Dst, unsigned DstAlign,
1459                                              LLVMValueRef Src, unsigned SrcAlign,
1460                                              LLVMValueRef Size, bool IsVolatile) {
1461 #if LLVM_VERSION_GE(10, 0)
1462   return wrap(unwrap(B)->CreateMemMove(
1463       unwrap(Dst), MaybeAlign(DstAlign),
1464       unwrap(Src), MaybeAlign(SrcAlign),
1465       unwrap(Size), IsVolatile));
1466 #else
1467   return wrap(unwrap(B)->CreateMemMove(
1468       unwrap(Dst), DstAlign,
1469       unwrap(Src), SrcAlign,
1470       unwrap(Size), IsVolatile));
1471 #endif
1472 }
1473
1474 extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
1475                                             LLVMValueRef Dst, unsigned DstAlign,
1476                                             LLVMValueRef Val,
1477                                             LLVMValueRef Size, bool IsVolatile) {
1478 #if LLVM_VERSION_GE(10, 0)
1479   return wrap(unwrap(B)->CreateMemSet(
1480       unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
1481 #else
1482   return wrap(unwrap(B)->CreateMemSet(
1483       unwrap(Dst), unwrap(Val), unwrap(Size), DstAlign, IsVolatile));
1484 #endif
1485 }
1486
1487 extern "C" LLVMValueRef
1488 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
1489                     unsigned NumArgs, LLVMBasicBlockRef Then,
1490                     LLVMBasicBlockRef Catch, OperandBundleDef *Bundle,
1491                     const char *Name) {
1492   Value *Callee = unwrap(Fn);
1493   FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1494   unsigned Len = Bundle ? 1 : 0;
1495   ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1496   return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
1497                                       makeArrayRef(unwrap(Args), NumArgs),
1498                                       Bundles, Name));
1499 }
1500
1501 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1502                                                LLVMBasicBlockRef BB) {
1503   auto Point = unwrap(BB)->getFirstInsertionPt();
1504   unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1505 }
1506
1507 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1508                                   const char *Name, size_t NameLen) {
1509   Triple TargetTriple(unwrap(M)->getTargetTriple());
1510   GlobalObject *GV = unwrap<GlobalObject>(V);
1511   if (TargetTriple.supportsCOMDAT()) {
1512     StringRef NameRef(Name, NameLen);
1513     GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
1514   }
1515 }
1516
1517 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1518   GlobalObject *GV = unwrap<GlobalObject>(V);
1519   GV->setComdat(nullptr);
1520 }
1521
1522 enum class LLVMRustLinkage {
1523   ExternalLinkage = 0,
1524   AvailableExternallyLinkage = 1,
1525   LinkOnceAnyLinkage = 2,
1526   LinkOnceODRLinkage = 3,
1527   WeakAnyLinkage = 4,
1528   WeakODRLinkage = 5,
1529   AppendingLinkage = 6,
1530   InternalLinkage = 7,
1531   PrivateLinkage = 8,
1532   ExternalWeakLinkage = 9,
1533   CommonLinkage = 10,
1534 };
1535
1536 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1537   switch (Linkage) {
1538   case LLVMExternalLinkage:
1539     return LLVMRustLinkage::ExternalLinkage;
1540   case LLVMAvailableExternallyLinkage:
1541     return LLVMRustLinkage::AvailableExternallyLinkage;
1542   case LLVMLinkOnceAnyLinkage:
1543     return LLVMRustLinkage::LinkOnceAnyLinkage;
1544   case LLVMLinkOnceODRLinkage:
1545     return LLVMRustLinkage::LinkOnceODRLinkage;
1546   case LLVMWeakAnyLinkage:
1547     return LLVMRustLinkage::WeakAnyLinkage;
1548   case LLVMWeakODRLinkage:
1549     return LLVMRustLinkage::WeakODRLinkage;
1550   case LLVMAppendingLinkage:
1551     return LLVMRustLinkage::AppendingLinkage;
1552   case LLVMInternalLinkage:
1553     return LLVMRustLinkage::InternalLinkage;
1554   case LLVMPrivateLinkage:
1555     return LLVMRustLinkage::PrivateLinkage;
1556   case LLVMExternalWeakLinkage:
1557     return LLVMRustLinkage::ExternalWeakLinkage;
1558   case LLVMCommonLinkage:
1559     return LLVMRustLinkage::CommonLinkage;
1560   default:
1561     report_fatal_error("Invalid LLVMRustLinkage value!");
1562   }
1563 }
1564
1565 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1566   switch (Linkage) {
1567   case LLVMRustLinkage::ExternalLinkage:
1568     return LLVMExternalLinkage;
1569   case LLVMRustLinkage::AvailableExternallyLinkage:
1570     return LLVMAvailableExternallyLinkage;
1571   case LLVMRustLinkage::LinkOnceAnyLinkage:
1572     return LLVMLinkOnceAnyLinkage;
1573   case LLVMRustLinkage::LinkOnceODRLinkage:
1574     return LLVMLinkOnceODRLinkage;
1575   case LLVMRustLinkage::WeakAnyLinkage:
1576     return LLVMWeakAnyLinkage;
1577   case LLVMRustLinkage::WeakODRLinkage:
1578     return LLVMWeakODRLinkage;
1579   case LLVMRustLinkage::AppendingLinkage:
1580     return LLVMAppendingLinkage;
1581   case LLVMRustLinkage::InternalLinkage:
1582     return LLVMInternalLinkage;
1583   case LLVMRustLinkage::PrivateLinkage:
1584     return LLVMPrivateLinkage;
1585   case LLVMRustLinkage::ExternalWeakLinkage:
1586     return LLVMExternalWeakLinkage;
1587   case LLVMRustLinkage::CommonLinkage:
1588     return LLVMCommonLinkage;
1589   }
1590   report_fatal_error("Invalid LLVMRustLinkage value!");
1591 }
1592
1593 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1594   return toRust(LLVMGetLinkage(V));
1595 }
1596
1597 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1598                                    LLVMRustLinkage RustLinkage) {
1599   LLVMSetLinkage(V, fromRust(RustLinkage));
1600 }
1601
1602 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1603 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1604 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1605 {
1606     auto C = unwrap<llvm::ConstantInt>(CV);
1607     if (C->getBitWidth() > 128) { return false; }
1608     APInt AP;
1609     if (sext) {
1610         AP = C->getValue().sextOrSelf(128);
1611     } else {
1612         AP = C->getValue().zextOrSelf(128);
1613     }
1614     *low = AP.getLoBits(64).getZExtValue();
1615     *high = AP.getHiBits(64).getZExtValue();
1616     return true;
1617 }
1618
1619 enum class LLVMRustVisibility {
1620   Default = 0,
1621   Hidden = 1,
1622   Protected = 2,
1623 };
1624
1625 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1626   switch (Vis) {
1627   case LLVMDefaultVisibility:
1628     return LLVMRustVisibility::Default;
1629   case LLVMHiddenVisibility:
1630     return LLVMRustVisibility::Hidden;
1631   case LLVMProtectedVisibility:
1632     return LLVMRustVisibility::Protected;
1633   }
1634   report_fatal_error("Invalid LLVMRustVisibility value!");
1635 }
1636
1637 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1638   switch (Vis) {
1639   case LLVMRustVisibility::Default:
1640     return LLVMDefaultVisibility;
1641   case LLVMRustVisibility::Hidden:
1642     return LLVMHiddenVisibility;
1643   case LLVMRustVisibility::Protected:
1644     return LLVMProtectedVisibility;
1645   }
1646   report_fatal_error("Invalid LLVMRustVisibility value!");
1647 }
1648
1649 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1650   return toRust(LLVMGetVisibility(V));
1651 }
1652
1653 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1654 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1655                                              LLVMTypeRef DestTy, bool isSigned) {
1656   return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1657 }
1658
1659 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1660                                       LLVMRustVisibility RustVisibility) {
1661   LLVMSetVisibility(V, fromRust(RustVisibility));
1662 }
1663
1664 struct LLVMRustModuleBuffer {
1665   std::string data;
1666 };
1667
1668 extern "C" LLVMRustModuleBuffer*
1669 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1670 #if LLVM_VERSION_GE(10, 0)
1671   auto Ret = std::make_unique<LLVMRustModuleBuffer>();
1672 #else
1673   auto Ret = llvm::make_unique<LLVMRustModuleBuffer>();
1674 #endif
1675   {
1676     raw_string_ostream OS(Ret->data);
1677     {
1678       legacy::PassManager PM;
1679       PM.add(createBitcodeWriterPass(OS));
1680       PM.run(*unwrap(M));
1681     }
1682   }
1683   return Ret.release();
1684 }
1685
1686 extern "C" void
1687 LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1688   delete Buffer;
1689 }
1690
1691 extern "C" const void*
1692 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1693   return Buffer->data.data();
1694 }
1695
1696 extern "C" size_t
1697 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1698   return Buffer->data.length();
1699 }
1700
1701 extern "C" uint64_t
1702 LLVMRustModuleCost(LLVMModuleRef M) {
1703   auto f = unwrap(M)->functions();
1704   return std::distance(std::begin(f), std::end(f));
1705 }
1706
1707 // Vector reductions:
1708 extern "C" LLVMValueRef
1709 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1710     return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1711 }
1712 extern "C" LLVMValueRef
1713 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1714     return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1715 }
1716 extern "C" LLVMValueRef
1717 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1718     return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1719 }
1720 extern "C" LLVMValueRef
1721 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1722     return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1723 }
1724 extern "C" LLVMValueRef
1725 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1726     return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1727 }
1728 extern "C" LLVMValueRef
1729 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1730     return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1731 }
1732 extern "C" LLVMValueRef
1733 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1734     return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1735 }
1736 extern "C" LLVMValueRef
1737 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1738     return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1739 }
1740 extern "C" LLVMValueRef
1741 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1742     return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1743 }
1744 extern "C" LLVMValueRef
1745 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1746 #if LLVM_VERSION_GE(12, 0)
1747   Instruction *I = unwrap(B)->CreateFPMinReduce(unwrap(Src));
1748   I->setHasNoNaNs(NoNaN);
1749   return wrap(I);
1750 #else
1751   return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN));
1752 #endif
1753 }
1754 extern "C" LLVMValueRef
1755 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1756 #if LLVM_VERSION_GE(12, 0)
1757   Instruction *I = unwrap(B)->CreateFPMaxReduce(unwrap(Src));
1758   I->setHasNoNaNs(NoNaN);
1759   return wrap(I);
1760 #else
1761   return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN));
1762 #endif
1763 }
1764
1765 extern "C" LLVMValueRef
1766 LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1767     return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1768 }
1769 extern "C" LLVMValueRef
1770 LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1771     return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));
1772 }