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