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