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