]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Auto merge of #93089 - pierwill:rm-outlivesconstraint-ord, 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/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(
726     LLVMModuleRef M,
727     Module::ModFlagBehavior MergeBehavior,
728     const char *Name,
729     uint32_t Value) {
730   unwrap(M)->addModuleFlag(MergeBehavior, Name, Value);
731 }
732
733 extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
734   return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
735 }
736
737 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
738   return new DIBuilder(*unwrap(M));
739 }
740
741 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
742   delete Builder;
743 }
744
745 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
746   Builder->finalize();
747 }
748
749 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
750     LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
751     const char *Producer, size_t ProducerLen, bool isOptimized,
752     const char *Flags, unsigned RuntimeVer,
753     const char *SplitName, size_t SplitNameLen,
754     LLVMRustDebugEmissionKind Kind,
755     uint64_t DWOId, bool SplitDebugInlining) {
756   auto *File = unwrapDI<DIFile>(FileRef);
757
758   return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
759                                          isOptimized, Flags, RuntimeVer,
760                                          StringRef(SplitName, SplitNameLen),
761                                          fromRust(Kind), DWOId, SplitDebugInlining));
762 }
763
764 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
765     LLVMRustDIBuilderRef Builder,
766     const char *Filename, size_t FilenameLen,
767     const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
768     const char *Checksum, size_t ChecksumLen) {
769   Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
770   Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
771   if (llvmCSKind)
772     CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
773   return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
774                                   StringRef(Directory, DirectoryLen),
775                                   CSInfo));
776 }
777
778 extern "C" LLVMMetadataRef
779 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
780                                       LLVMMetadataRef ParameterTypes) {
781   return wrap(Builder->createSubroutineType(
782       DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
783 }
784
785 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
786     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
787     const char *Name, size_t NameLen,
788     const char *LinkageName, size_t LinkageNameLen,
789     LLVMMetadataRef File, unsigned LineNo,
790     LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
791     LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam,
792     LLVMMetadataRef Decl) {
793   DITemplateParameterArray TParams =
794       DITemplateParameterArray(unwrap<MDTuple>(TParam));
795   DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
796   DINode::DIFlags llvmFlags = fromRust(Flags);
797   DISubprogram *Sub = Builder->createFunction(
798       unwrapDI<DIScope>(Scope),
799       StringRef(Name, NameLen),
800       StringRef(LinkageName, LinkageNameLen),
801       unwrapDI<DIFile>(File), LineNo,
802       unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
803       llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
804   if (MaybeFn)
805     unwrap<Function>(MaybeFn)->setSubprogram(Sub);
806   return wrap(Sub);
807 }
808
809 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
810     LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
811     uint64_t SizeInBits, unsigned Encoding) {
812   return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
813 }
814
815 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
816     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
817     LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
818   return wrap(Builder->createTypedef(
819     unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
820     LineNo, unwrapDIPtr<DIScope>(Scope)));
821 }
822
823 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
824     LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
825     uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
826     const char *Name, size_t NameLen) {
827   return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
828                                          SizeInBits, AlignInBits,
829                                          AddressSpace,
830                                          StringRef(Name, NameLen)));
831 }
832
833 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
834     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
835     const char *Name, size_t NameLen,
836     LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
837     uint32_t AlignInBits, LLVMRustDIFlags Flags,
838     LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
839     unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
840     const char *UniqueId, size_t UniqueIdLen) {
841   return wrap(Builder->createStructType(
842       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
843       unwrapDI<DIFile>(File), LineNumber,
844       SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
845       DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
846       unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen)));
847 }
848
849 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
850     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
851     const char *Name, size_t NameLen,
852     LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
853     uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
854     LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) {
855   return wrap(Builder->createVariantPart(
856       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
857       unwrapDI<DIFile>(File), LineNumber,
858       SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
859       DINodeArray(unwrapDI<MDTuple>(Elements)), StringRef(UniqueId, UniqueIdLen)));
860 }
861
862 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
863     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
864     const char *Name, size_t NameLen,
865     LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
866     uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
867     LLVMMetadataRef Ty) {
868   return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope),
869                                         StringRef(Name, NameLen),
870                                         unwrapDI<DIFile>(File), LineNo,
871                                         SizeInBits, AlignInBits, OffsetInBits,
872                                         fromRust(Flags), unwrapDI<DIType>(Ty)));
873 }
874
875 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
876     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
877     const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
878     uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
879     LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
880   llvm::ConstantInt* D = nullptr;
881   if (Discriminant) {
882     D = unwrap<llvm::ConstantInt>(Discriminant);
883   }
884   return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope),
885                                                StringRef(Name, NameLen),
886                                                unwrapDI<DIFile>(File), LineNo,
887                                                SizeInBits, AlignInBits, OffsetInBits, D,
888                                                fromRust(Flags), unwrapDI<DIType>(Ty)));
889 }
890
891 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
892     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
893     LLVMMetadataRef File, unsigned Line, unsigned Col) {
894   return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
895                                           unwrapDI<DIFile>(File), Line, Col));
896 }
897
898 extern "C" LLVMMetadataRef
899 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
900                                         LLVMMetadataRef Scope,
901                                         LLVMMetadataRef File) {
902   return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
903                                               unwrapDI<DIFile>(File)));
904 }
905
906 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
907     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context,
908     const char *Name, size_t NameLen,
909     const char *LinkageName, size_t LinkageNameLen,
910     LLVMMetadataRef File, unsigned LineNo,
911     LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
912     LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
913   llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
914
915   llvm::DIExpression *InitExpr = nullptr;
916   if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
917     InitExpr = Builder->createConstantValueExpression(
918         IntVal->getValue().getSExtValue());
919   } else if (llvm::ConstantFP *FPVal =
920                  llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
921     InitExpr = Builder->createConstantValueExpression(
922         FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
923   }
924
925   llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
926       unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
927       StringRef(LinkageName, LinkageNameLen),
928       unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
929       /* isDefined */ true,
930       InitExpr, unwrapDIPtr<MDNode>(Decl),
931       /* templateParams */ nullptr,
932       AlignInBits);
933
934   InitVal->setMetadata("dbg", VarExpr);
935
936   return wrap(VarExpr);
937 }
938
939 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
940     LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
941     const char *Name, size_t NameLen,
942     LLVMMetadataRef File, unsigned LineNo,
943     LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
944     unsigned ArgNo, uint32_t AlignInBits) {
945   if (Tag == 0x100) { // DW_TAG_auto_variable
946     return wrap(Builder->createAutoVariable(
947         unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
948         unwrapDI<DIFile>(File), LineNo,
949         unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
950   } else {
951     return wrap(Builder->createParameterVariable(
952         unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
953         unwrapDI<DIFile>(File), LineNo,
954         unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
955   }
956 }
957
958 extern "C" LLVMMetadataRef
959 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
960                                  uint32_t AlignInBits, LLVMMetadataRef Ty,
961                                  LLVMMetadataRef Subscripts) {
962   return wrap(
963       Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
964                                DINodeArray(unwrapDI<MDTuple>(Subscripts))));
965 }
966
967 extern "C" LLVMMetadataRef
968 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
969                                      int64_t Count) {
970   return wrap(Builder->getOrCreateSubrange(Lo, Count));
971 }
972
973 extern "C" LLVMMetadataRef
974 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
975                                   LLVMMetadataRef *Ptr, unsigned Count) {
976   Metadata **DataValue = unwrap(Ptr);
977   return wrap(
978       Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
979 }
980
981 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
982     LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
983     uint64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
984     LLVMBasicBlockRef InsertAtEnd) {
985   return wrap(Builder->insertDeclare(
986       unwrap(V), unwrap<DILocalVariable>(VarInfo),
987       Builder->createExpression(llvm::ArrayRef<uint64_t>(AddrOps, AddrOpsCount)),
988       DebugLoc(cast<MDNode>(unwrap(DL))),
989       unwrap(InsertAtEnd)));
990 }
991
992 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
993     LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
994     int64_t Value, bool IsUnsigned) {
995   return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
996 }
997
998 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
999     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1000     const char *Name, size_t NameLen,
1001     LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
1002     uint32_t AlignInBits, LLVMMetadataRef Elements,
1003     LLVMMetadataRef ClassTy, bool IsScoped) {
1004   return wrap(Builder->createEnumerationType(
1005       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
1006       unwrapDI<DIFile>(File), LineNumber,
1007       SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
1008       unwrapDI<DIType>(ClassTy), "", IsScoped));
1009 }
1010
1011 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
1012     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1013     const char *Name, size_t NameLen,
1014     LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
1015     uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
1016     unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) {
1017   return wrap(Builder->createUnionType(
1018       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File),
1019       LineNumber, SizeInBits, AlignInBits, fromRust(Flags),
1020       DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
1021       StringRef(UniqueId, UniqueIdLen)));
1022 }
1023
1024 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
1025     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1026     const char *Name, size_t NameLen, LLVMMetadataRef Ty) {
1027   bool IsDefault = false; // FIXME: should we ever set this true?
1028   return wrap(Builder->createTemplateTypeParameter(
1029       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty), IsDefault));
1030 }
1031
1032 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateNameSpace(
1033     LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1034     const char *Name, size_t NameLen, bool ExportSymbols) {
1035   return wrap(Builder->createNameSpace(
1036       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols
1037   ));
1038 }
1039
1040 extern "C" void
1041 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
1042                                      LLVMMetadataRef CompositeTy,
1043                                      LLVMMetadataRef Elements,
1044                                      LLVMMetadataRef Params) {
1045   DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
1046   Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
1047                          DINodeArray(unwrap<MDTuple>(Params)));
1048 }
1049
1050 extern "C" LLVMMetadataRef
1051 LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
1052                                      LLVMMetadataRef ScopeRef,
1053                                      LLVMMetadataRef InlinedAt) {
1054   MDNode *Scope = unwrapDIPtr<MDNode>(ScopeRef);
1055   DILocation *Loc = DILocation::get(
1056       Scope->getContext(), Line, Column, Scope,
1057       unwrapDIPtr<MDNode>(InlinedAt));
1058   return wrap(Loc);
1059 }
1060
1061 extern "C" uint64_t LLVMRustDIBuilderCreateOpDeref() {
1062   return dwarf::DW_OP_deref;
1063 }
1064
1065 extern "C" uint64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1066   return dwarf::DW_OP_plus_uconst;
1067 }
1068
1069 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
1070   RawRustStringOstream OS(Str);
1071   unwrap<llvm::Type>(Ty)->print(OS);
1072 }
1073
1074 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
1075                                            RustStringRef Str) {
1076   RawRustStringOstream OS(Str);
1077   if (!V) {
1078     OS << "(null)";
1079   } else {
1080     OS << "(";
1081     unwrap<llvm::Value>(V)->getType()->print(OS);
1082     OS << ":";
1083     unwrap<llvm::Value>(V)->print(OS);
1084     OS << ")";
1085   }
1086 }
1087
1088 // LLVMArrayType function does not support 64-bit ElementCount
1089 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
1090                                          uint64_t ElementCount) {
1091   return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
1092 }
1093
1094 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1095
1096 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
1097   RawRustStringOstream OS(Str);
1098   unwrap(T)->print(OS);
1099 }
1100
1101 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1102     LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
1103     LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
1104     RustStringRef FilenameOut, RustStringRef MessageOut) {
1105   // Undefined to call this not on an optimization diagnostic!
1106   llvm::DiagnosticInfoOptimizationBase *Opt =
1107       static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
1108
1109   RawRustStringOstream PassNameOS(PassNameOut);
1110   PassNameOS << Opt->getPassName();
1111   *FunctionOut = wrap(&Opt->getFunction());
1112
1113   RawRustStringOstream FilenameOS(FilenameOut);
1114   DiagnosticLocation loc = Opt->getLocation();
1115   if (loc.isValid()) {
1116     *Line = loc.getLine();
1117     *Column = loc.getColumn();
1118     FilenameOS << loc.getAbsolutePath();
1119   }
1120
1121   RawRustStringOstream MessageOS(MessageOut);
1122   MessageOS << Opt->getMsg();
1123 }
1124
1125 enum class LLVMRustDiagnosticLevel {
1126     Error,
1127     Warning,
1128     Note,
1129     Remark,
1130 };
1131
1132 extern "C" void
1133 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
1134                                   LLVMRustDiagnosticLevel *LevelOut,
1135                                   unsigned *CookieOut,
1136                                   LLVMTwineRef *MessageOut) {
1137   // Undefined to call this not on an inline assembly diagnostic!
1138   llvm::DiagnosticInfoInlineAsm *IA =
1139       static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
1140
1141   *CookieOut = IA->getLocCookie();
1142   *MessageOut = wrap(&IA->getMsgStr());
1143
1144   switch (IA->getSeverity()) {
1145     case DS_Error:
1146       *LevelOut = LLVMRustDiagnosticLevel::Error;
1147       break;
1148     case DS_Warning:
1149       *LevelOut = LLVMRustDiagnosticLevel::Warning;
1150       break;
1151     case DS_Note:
1152       *LevelOut = LLVMRustDiagnosticLevel::Note;
1153       break;
1154     case DS_Remark:
1155       *LevelOut = LLVMRustDiagnosticLevel::Remark;
1156       break;
1157     default:
1158       report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1159   }
1160 }
1161
1162 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
1163                                                     RustStringRef Str) {
1164   RawRustStringOstream OS(Str);
1165   DiagnosticPrinterRawOStream DP(OS);
1166   unwrap(DI)->print(DP);
1167 }
1168
1169 enum class LLVMRustDiagnosticKind {
1170   Other,
1171   InlineAsm,
1172   StackSize,
1173   DebugMetadataVersion,
1174   SampleProfile,
1175   OptimizationRemark,
1176   OptimizationRemarkMissed,
1177   OptimizationRemarkAnalysis,
1178   OptimizationRemarkAnalysisFPCommute,
1179   OptimizationRemarkAnalysisAliasing,
1180   OptimizationRemarkOther,
1181   OptimizationFailure,
1182   PGOProfile,
1183   Linker,
1184   Unsupported,
1185   SrcMgr,
1186 };
1187
1188 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1189   switch (Kind) {
1190   case DK_InlineAsm:
1191     return LLVMRustDiagnosticKind::InlineAsm;
1192   case DK_StackSize:
1193     return LLVMRustDiagnosticKind::StackSize;
1194   case DK_DebugMetadataVersion:
1195     return LLVMRustDiagnosticKind::DebugMetadataVersion;
1196   case DK_SampleProfile:
1197     return LLVMRustDiagnosticKind::SampleProfile;
1198   case DK_OptimizationRemark:
1199   case DK_MachineOptimizationRemark:
1200     return LLVMRustDiagnosticKind::OptimizationRemark;
1201   case DK_OptimizationRemarkMissed:
1202   case DK_MachineOptimizationRemarkMissed:
1203     return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1204   case DK_OptimizationRemarkAnalysis:
1205   case DK_MachineOptimizationRemarkAnalysis:
1206     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1207   case DK_OptimizationRemarkAnalysisFPCommute:
1208     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1209   case DK_OptimizationRemarkAnalysisAliasing:
1210     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1211   case DK_PGOProfile:
1212     return LLVMRustDiagnosticKind::PGOProfile;
1213   case DK_Linker:
1214     return LLVMRustDiagnosticKind::Linker;
1215   case DK_Unsupported:
1216     return LLVMRustDiagnosticKind::Unsupported;
1217 #if LLVM_VERSION_GE(13, 0)
1218   case DK_SrcMgr:
1219     return LLVMRustDiagnosticKind::SrcMgr;
1220 #endif
1221   default:
1222     return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1223                ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1224                : LLVMRustDiagnosticKind::Other;
1225   }
1226 }
1227
1228 extern "C" LLVMRustDiagnosticKind
1229 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1230   return toRust((DiagnosticKind)unwrap(DI)->getKind());
1231 }
1232
1233 // This is kept distinct from LLVMGetTypeKind, because when
1234 // a new type kind is added, the Rust-side enum must be
1235 // updated or UB will result.
1236 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1237   switch (unwrap(Ty)->getTypeID()) {
1238   case Type::VoidTyID:
1239     return LLVMVoidTypeKind;
1240   case Type::HalfTyID:
1241     return LLVMHalfTypeKind;
1242   case Type::FloatTyID:
1243     return LLVMFloatTypeKind;
1244   case Type::DoubleTyID:
1245     return LLVMDoubleTypeKind;
1246   case Type::X86_FP80TyID:
1247     return LLVMX86_FP80TypeKind;
1248   case Type::FP128TyID:
1249     return LLVMFP128TypeKind;
1250   case Type::PPC_FP128TyID:
1251     return LLVMPPC_FP128TypeKind;
1252   case Type::LabelTyID:
1253     return LLVMLabelTypeKind;
1254   case Type::MetadataTyID:
1255     return LLVMMetadataTypeKind;
1256   case Type::IntegerTyID:
1257     return LLVMIntegerTypeKind;
1258   case Type::FunctionTyID:
1259     return LLVMFunctionTypeKind;
1260   case Type::StructTyID:
1261     return LLVMStructTypeKind;
1262   case Type::ArrayTyID:
1263     return LLVMArrayTypeKind;
1264   case Type::PointerTyID:
1265     return LLVMPointerTypeKind;
1266   case Type::FixedVectorTyID:
1267     return LLVMVectorTypeKind;
1268   case Type::X86_MMXTyID:
1269     return LLVMX86_MMXTypeKind;
1270   case Type::TokenTyID:
1271     return LLVMTokenTypeKind;
1272   case Type::ScalableVectorTyID:
1273     return LLVMScalableVectorTypeKind;
1274   case Type::BFloatTyID:
1275     return LLVMBFloatTypeKind;
1276   case Type::X86_AMXTyID:
1277     return LLVMX86_AMXTypeKind;
1278   }
1279   report_fatal_error("Unhandled TypeID.");
1280 }
1281
1282 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1283
1284 #if LLVM_VERSION_LT(13, 0)
1285 using LLVMInlineAsmDiagHandlerTy = LLVMContext::InlineAsmDiagHandlerTy;
1286 #else
1287 using LLVMInlineAsmDiagHandlerTy = void*;
1288 #endif
1289
1290 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1291     LLVMContextRef C, LLVMInlineAsmDiagHandlerTy H, void *CX) {
1292   // Diagnostic handlers were unified in LLVM change 5de2d189e6ad, so starting
1293   // with LLVM 13 this function is gone.
1294 #if LLVM_VERSION_LT(13, 0)
1295   unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1296 #endif
1297 }
1298
1299 extern "C" LLVMSMDiagnosticRef LLVMRustGetSMDiagnostic(
1300     LLVMDiagnosticInfoRef DI, unsigned *Cookie) {
1301 #if LLVM_VERSION_GE(13, 0)
1302   llvm::DiagnosticInfoSrcMgr *SM = static_cast<llvm::DiagnosticInfoSrcMgr *>(unwrap(DI));
1303   *Cookie = SM->getLocCookie();
1304   return wrap(&SM->getSMDiag());
1305 #else
1306   report_fatal_error("Shouldn't get called on older versions");
1307 #endif
1308 }
1309
1310 extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
1311                                            RustStringRef MessageOut,
1312                                            RustStringRef BufferOut,
1313                                            LLVMRustDiagnosticLevel* LevelOut,
1314                                            unsigned* LocOut,
1315                                            unsigned* RangesOut,
1316                                            size_t* NumRanges) {
1317   SMDiagnostic& D = *unwrap(DRef);
1318   RawRustStringOstream MessageOS(MessageOut);
1319   MessageOS << D.getMessage();
1320
1321   switch (D.getKind()) {
1322     case SourceMgr::DK_Error:
1323       *LevelOut = LLVMRustDiagnosticLevel::Error;
1324       break;
1325     case SourceMgr::DK_Warning:
1326       *LevelOut = LLVMRustDiagnosticLevel::Warning;
1327       break;
1328     case SourceMgr::DK_Note:
1329       *LevelOut = LLVMRustDiagnosticLevel::Note;
1330       break;
1331     case SourceMgr::DK_Remark:
1332       *LevelOut = LLVMRustDiagnosticLevel::Remark;
1333       break;
1334     default:
1335       report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1336   }
1337
1338   if (D.getLoc() == SMLoc())
1339     return false;
1340
1341   const SourceMgr &LSM = *D.getSourceMgr();
1342   const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
1343   LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), LBuf->getBufferSize());
1344
1345   *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
1346
1347   *NumRanges = std::min(*NumRanges, D.getRanges().size());
1348   size_t LineStart = *LocOut - (size_t)D.getColumnNo();
1349   for (size_t i = 0; i < *NumRanges; i++) {
1350     RangesOut[i * 2] = LineStart + D.getRanges()[i].first;
1351     RangesOut[i * 2 + 1] = LineStart + D.getRanges()[i].second;
1352   }
1353
1354   return true;
1355 }
1356
1357 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1358                                                 LLVMValueRef ParentPad,
1359                                                 unsigned ArgCount,
1360                                                 LLVMValueRef *LLArgs,
1361                                                 const char *Name) {
1362   Value **Args = unwrap(LLArgs);
1363   if (ParentPad == nullptr) {
1364     Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1365     ParentPad = wrap(Constant::getNullValue(Ty));
1366   }
1367   return wrap(unwrap(B)->CreateCleanupPad(
1368       unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1369 }
1370
1371 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1372                                                 LLVMValueRef CleanupPad,
1373                                                 LLVMBasicBlockRef UnwindBB) {
1374   CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1375   return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1376 }
1377
1378 extern "C" LLVMValueRef
1379 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1380                       unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1381   Value **Args = unwrap(LLArgs);
1382   return wrap(unwrap(B)->CreateCatchPad(
1383       unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1384 }
1385
1386 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1387                                               LLVMValueRef Pad,
1388                                               LLVMBasicBlockRef BB) {
1389   return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1390                                               unwrap(BB)));
1391 }
1392
1393 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1394                                                  LLVMValueRef ParentPad,
1395                                                  LLVMBasicBlockRef BB,
1396                                                  unsigned NumHandlers,
1397                                                  const char *Name) {
1398   if (ParentPad == nullptr) {
1399     Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1400     ParentPad = wrap(Constant::getNullValue(Ty));
1401   }
1402   return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1403                                                  NumHandlers, Name));
1404 }
1405
1406 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1407                                    LLVMBasicBlockRef Handler) {
1408   Value *CatchSwitch = unwrap(CatchSwitchRef);
1409   cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1410 }
1411
1412 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1413                                                            LLVMValueRef *Inputs,
1414                                                            unsigned NumInputs) {
1415   return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1416 }
1417
1418 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1419   delete Bundle;
1420 }
1421
1422 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
1423                                           LLVMValueRef *Args, unsigned NumArgs,
1424                                           OperandBundleDef *Bundle) {
1425   Value *Callee = unwrap(Fn);
1426   FunctionType *FTy = unwrap<FunctionType>(Ty);
1427   unsigned Len = Bundle ? 1 : 0;
1428   ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1429   return wrap(unwrap(B)->CreateCall(
1430       FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles));
1431 }
1432
1433 extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
1434   return wrap(llvm::Intrinsic::getDeclaration(unwrap(M),
1435               (llvm::Intrinsic::ID)llvm::Intrinsic::instrprof_increment));
1436 }
1437
1438 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
1439                                             LLVMValueRef Dst, unsigned DstAlign,
1440                                             LLVMValueRef Src, unsigned SrcAlign,
1441                                             LLVMValueRef Size, bool IsVolatile) {
1442   return wrap(unwrap(B)->CreateMemCpy(
1443       unwrap(Dst), MaybeAlign(DstAlign),
1444       unwrap(Src), MaybeAlign(SrcAlign),
1445       unwrap(Size), IsVolatile));
1446 }
1447
1448 extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
1449                                              LLVMValueRef Dst, unsigned DstAlign,
1450                                              LLVMValueRef Src, unsigned SrcAlign,
1451                                              LLVMValueRef Size, bool IsVolatile) {
1452   return wrap(unwrap(B)->CreateMemMove(
1453       unwrap(Dst), MaybeAlign(DstAlign),
1454       unwrap(Src), MaybeAlign(SrcAlign),
1455       unwrap(Size), IsVolatile));
1456 }
1457
1458 extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
1459                                             LLVMValueRef Dst, unsigned DstAlign,
1460                                             LLVMValueRef Val,
1461                                             LLVMValueRef Size, bool IsVolatile) {
1462   return wrap(unwrap(B)->CreateMemSet(
1463       unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
1464 }
1465
1466 extern "C" LLVMValueRef
1467 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
1468                     LLVMValueRef *Args, unsigned NumArgs,
1469                     LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
1470                     OperandBundleDef *Bundle, const char *Name) {
1471   Value *Callee = unwrap(Fn);
1472   FunctionType *FTy = unwrap<FunctionType>(Ty);
1473   unsigned Len = Bundle ? 1 : 0;
1474   ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1475   return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
1476                                       makeArrayRef(unwrap(Args), NumArgs),
1477                                       Bundles, Name));
1478 }
1479
1480 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1481                                                LLVMBasicBlockRef BB) {
1482   auto Point = unwrap(BB)->getFirstInsertionPt();
1483   unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1484 }
1485
1486 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1487                                   const char *Name, size_t NameLen) {
1488   Triple TargetTriple(unwrap(M)->getTargetTriple());
1489   GlobalObject *GV = unwrap<GlobalObject>(V);
1490   if (TargetTriple.supportsCOMDAT()) {
1491     StringRef NameRef(Name, NameLen);
1492     GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
1493   }
1494 }
1495
1496 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1497   GlobalObject *GV = unwrap<GlobalObject>(V);
1498   GV->setComdat(nullptr);
1499 }
1500
1501 enum class LLVMRustLinkage {
1502   ExternalLinkage = 0,
1503   AvailableExternallyLinkage = 1,
1504   LinkOnceAnyLinkage = 2,
1505   LinkOnceODRLinkage = 3,
1506   WeakAnyLinkage = 4,
1507   WeakODRLinkage = 5,
1508   AppendingLinkage = 6,
1509   InternalLinkage = 7,
1510   PrivateLinkage = 8,
1511   ExternalWeakLinkage = 9,
1512   CommonLinkage = 10,
1513 };
1514
1515 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1516   switch (Linkage) {
1517   case LLVMExternalLinkage:
1518     return LLVMRustLinkage::ExternalLinkage;
1519   case LLVMAvailableExternallyLinkage:
1520     return LLVMRustLinkage::AvailableExternallyLinkage;
1521   case LLVMLinkOnceAnyLinkage:
1522     return LLVMRustLinkage::LinkOnceAnyLinkage;
1523   case LLVMLinkOnceODRLinkage:
1524     return LLVMRustLinkage::LinkOnceODRLinkage;
1525   case LLVMWeakAnyLinkage:
1526     return LLVMRustLinkage::WeakAnyLinkage;
1527   case LLVMWeakODRLinkage:
1528     return LLVMRustLinkage::WeakODRLinkage;
1529   case LLVMAppendingLinkage:
1530     return LLVMRustLinkage::AppendingLinkage;
1531   case LLVMInternalLinkage:
1532     return LLVMRustLinkage::InternalLinkage;
1533   case LLVMPrivateLinkage:
1534     return LLVMRustLinkage::PrivateLinkage;
1535   case LLVMExternalWeakLinkage:
1536     return LLVMRustLinkage::ExternalWeakLinkage;
1537   case LLVMCommonLinkage:
1538     return LLVMRustLinkage::CommonLinkage;
1539   default:
1540     report_fatal_error("Invalid LLVMRustLinkage value!");
1541   }
1542 }
1543
1544 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1545   switch (Linkage) {
1546   case LLVMRustLinkage::ExternalLinkage:
1547     return LLVMExternalLinkage;
1548   case LLVMRustLinkage::AvailableExternallyLinkage:
1549     return LLVMAvailableExternallyLinkage;
1550   case LLVMRustLinkage::LinkOnceAnyLinkage:
1551     return LLVMLinkOnceAnyLinkage;
1552   case LLVMRustLinkage::LinkOnceODRLinkage:
1553     return LLVMLinkOnceODRLinkage;
1554   case LLVMRustLinkage::WeakAnyLinkage:
1555     return LLVMWeakAnyLinkage;
1556   case LLVMRustLinkage::WeakODRLinkage:
1557     return LLVMWeakODRLinkage;
1558   case LLVMRustLinkage::AppendingLinkage:
1559     return LLVMAppendingLinkage;
1560   case LLVMRustLinkage::InternalLinkage:
1561     return LLVMInternalLinkage;
1562   case LLVMRustLinkage::PrivateLinkage:
1563     return LLVMPrivateLinkage;
1564   case LLVMRustLinkage::ExternalWeakLinkage:
1565     return LLVMExternalWeakLinkage;
1566   case LLVMRustLinkage::CommonLinkage:
1567     return LLVMCommonLinkage;
1568   }
1569   report_fatal_error("Invalid LLVMRustLinkage value!");
1570 }
1571
1572 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1573   return toRust(LLVMGetLinkage(V));
1574 }
1575
1576 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1577                                    LLVMRustLinkage RustLinkage) {
1578   LLVMSetLinkage(V, fromRust(RustLinkage));
1579 }
1580
1581 extern "C" LLVMValueRef LLVMRustConstInBoundsGEP2(LLVMTypeRef Ty,
1582                                                   LLVMValueRef ConstantVal,
1583                                                   LLVMValueRef *ConstantIndices,
1584                                                   unsigned NumIndices) {
1585   ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
1586                                NumIndices);
1587   Constant *Val = unwrap<Constant>(ConstantVal);
1588   return wrap(ConstantExpr::getInBoundsGetElementPtr(unwrap(Ty), Val, IdxList));
1589 }
1590
1591 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1592 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1593 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1594 {
1595     auto C = unwrap<llvm::ConstantInt>(CV);
1596     if (C->getBitWidth() > 128) { return false; }
1597     APInt AP;
1598     if (sext) {
1599         AP = C->getValue().sextOrSelf(128);
1600     } else {
1601         AP = C->getValue().zextOrSelf(128);
1602     }
1603     *low = AP.getLoBits(64).getZExtValue();
1604     *high = AP.getHiBits(64).getZExtValue();
1605     return true;
1606 }
1607
1608 enum class LLVMRustVisibility {
1609   Default = 0,
1610   Hidden = 1,
1611   Protected = 2,
1612 };
1613
1614 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1615   switch (Vis) {
1616   case LLVMDefaultVisibility:
1617     return LLVMRustVisibility::Default;
1618   case LLVMHiddenVisibility:
1619     return LLVMRustVisibility::Hidden;
1620   case LLVMProtectedVisibility:
1621     return LLVMRustVisibility::Protected;
1622   }
1623   report_fatal_error("Invalid LLVMRustVisibility value!");
1624 }
1625
1626 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1627   switch (Vis) {
1628   case LLVMRustVisibility::Default:
1629     return LLVMDefaultVisibility;
1630   case LLVMRustVisibility::Hidden:
1631     return LLVMHiddenVisibility;
1632   case LLVMRustVisibility::Protected:
1633     return LLVMProtectedVisibility;
1634   }
1635   report_fatal_error("Invalid LLVMRustVisibility value!");
1636 }
1637
1638 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1639   return toRust(LLVMGetVisibility(V));
1640 }
1641
1642 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1643 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1644                                              LLVMTypeRef DestTy, bool isSigned) {
1645   return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1646 }
1647
1648 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1649                                       LLVMRustVisibility RustVisibility) {
1650   LLVMSetVisibility(V, fromRust(RustVisibility));
1651 }
1652
1653 extern "C" void LLVMRustSetDSOLocal(LLVMValueRef Global, bool is_dso_local) {
1654   unwrap<GlobalValue>(Global)->setDSOLocal(is_dso_local);
1655 }
1656
1657 struct LLVMRustModuleBuffer {
1658   std::string data;
1659 };
1660
1661 extern "C" LLVMRustModuleBuffer*
1662 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1663   auto Ret = std::make_unique<LLVMRustModuleBuffer>();
1664   {
1665     raw_string_ostream OS(Ret->data);
1666     {
1667       legacy::PassManager PM;
1668       PM.add(createBitcodeWriterPass(OS));
1669       PM.run(*unwrap(M));
1670     }
1671   }
1672   return Ret.release();
1673 }
1674
1675 extern "C" void
1676 LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1677   delete Buffer;
1678 }
1679
1680 extern "C" const void*
1681 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1682   return Buffer->data.data();
1683 }
1684
1685 extern "C" size_t
1686 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1687   return Buffer->data.length();
1688 }
1689
1690 extern "C" uint64_t
1691 LLVMRustModuleCost(LLVMModuleRef M) {
1692   auto f = unwrap(M)->functions();
1693   return std::distance(std::begin(f), std::end(f));
1694 }
1695
1696 // Vector reductions:
1697 extern "C" LLVMValueRef
1698 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1699     return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1700 }
1701 extern "C" LLVMValueRef
1702 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1703     return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1704 }
1705 extern "C" LLVMValueRef
1706 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1707     return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1708 }
1709 extern "C" LLVMValueRef
1710 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1711     return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1712 }
1713 extern "C" LLVMValueRef
1714 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1715     return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1716 }
1717 extern "C" LLVMValueRef
1718 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1719     return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1720 }
1721 extern "C" LLVMValueRef
1722 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1723     return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1724 }
1725 extern "C" LLVMValueRef
1726 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1727     return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1728 }
1729 extern "C" LLVMValueRef
1730 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1731     return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1732 }
1733 extern "C" LLVMValueRef
1734 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1735   Instruction *I = unwrap(B)->CreateFPMinReduce(unwrap(Src));
1736   I->setHasNoNaNs(NoNaN);
1737   return wrap(I);
1738 }
1739 extern "C" LLVMValueRef
1740 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1741   Instruction *I = unwrap(B)->CreateFPMaxReduce(unwrap(Src));
1742   I->setHasNoNaNs(NoNaN);
1743   return wrap(I);
1744 }
1745
1746 extern "C" LLVMValueRef
1747 LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1748     return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1749 }
1750 extern "C" LLVMValueRef
1751 LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1752     return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));
1753 }
1754
1755 // This struct contains all necessary info about a symbol exported from a DLL.
1756 struct LLVMRustCOFFShortExport {
1757   const char* name;
1758   bool ordinal_present;
1759   // The value of `ordinal` is only meaningful if `ordinal_present` is true.
1760   uint16_t ordinal;
1761 };
1762
1763 // Machine must be a COFF machine type, as defined in PE specs.
1764 extern "C" LLVMRustResult LLVMRustWriteImportLibrary(
1765   const char* ImportName,
1766   const char* Path,
1767   const LLVMRustCOFFShortExport* Exports,
1768   size_t NumExports,
1769   uint16_t Machine,
1770   bool MinGW)
1771 {
1772   std::vector<llvm::object::COFFShortExport> ConvertedExports;
1773   ConvertedExports.reserve(NumExports);
1774
1775   for (size_t i = 0; i < NumExports; ++i) {
1776     bool ordinal_present = Exports[i].ordinal_present;
1777     uint16_t ordinal = ordinal_present ? Exports[i].ordinal : 0;
1778     ConvertedExports.push_back(llvm::object::COFFShortExport{
1779       Exports[i].name,  // Name
1780       std::string{},    // ExtName
1781       std::string{},    // SymbolName
1782       std::string{},    // AliasTarget
1783       ordinal,          // Ordinal
1784       ordinal_present,  // Noname
1785       false,            // Data
1786       false,            // Private
1787       false             // Constant
1788     });
1789   }
1790
1791   auto Error = llvm::object::writeImportLibrary(
1792     ImportName,
1793     Path,
1794     ConvertedExports,
1795     static_cast<llvm::COFF::MachineTypes>(Machine),
1796     MinGW);
1797   if (Error) {
1798     std::string errorString;
1799     llvm::raw_string_ostream stream(errorString);
1800     stream << Error;
1801     stream.flush();
1802     LLVMRustSetLastError(errorString.c_str());
1803     return LLVMRustResult::Failure;
1804   } else {
1805     return LLVMRustResult::Success;
1806   }
1807 }
1808
1809 // Transfers ownership of DiagnosticHandler unique_ptr to the caller.
1810 extern "C" DiagnosticHandler *
1811 LLVMRustContextGetDiagnosticHandler(LLVMContextRef C) {
1812   std::unique_ptr<DiagnosticHandler> DH = unwrap(C)->getDiagnosticHandler();
1813   return DH.release();
1814 }
1815
1816 // Sets unique_ptr to object of DiagnosticHandler to provide custom diagnostic
1817 // handling. Ownership of the handler is moved to the LLVMContext.
1818 extern "C" void LLVMRustContextSetDiagnosticHandler(LLVMContextRef C,
1819                                                     DiagnosticHandler *DH) {
1820   unwrap(C)->setDiagnosticHandler(std::unique_ptr<DiagnosticHandler>(DH));
1821 }
1822
1823 using LLVMDiagnosticHandlerTy = DiagnosticHandler::DiagnosticHandlerTy;
1824
1825 // Configures a diagnostic handler that invokes provided callback when a
1826 // backend needs to emit a diagnostic.
1827 //
1828 // When RemarkAllPasses is true, remarks are enabled for all passes. Otherwise
1829 // the RemarkPasses array specifies individual passes for which remarks will be
1830 // enabled.
1831 extern "C" void LLVMRustContextConfigureDiagnosticHandler(
1832     LLVMContextRef C, LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
1833     void *DiagnosticHandlerContext, bool RemarkAllPasses,
1834     const char * const * RemarkPasses, size_t RemarkPassesLen) {
1835
1836   class RustDiagnosticHandler final : public DiagnosticHandler {
1837   public:
1838     RustDiagnosticHandler(LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
1839                           void *DiagnosticHandlerContext,
1840                           bool RemarkAllPasses,
1841                           std::vector<std::string> RemarkPasses)
1842         : DiagnosticHandlerCallback(DiagnosticHandlerCallback),
1843           DiagnosticHandlerContext(DiagnosticHandlerContext),
1844           RemarkAllPasses(RemarkAllPasses),
1845           RemarkPasses(RemarkPasses) {}
1846
1847     virtual bool handleDiagnostics(const DiagnosticInfo &DI) override {
1848       if (DiagnosticHandlerCallback) {
1849         DiagnosticHandlerCallback(DI, DiagnosticHandlerContext);
1850         return true;
1851       }
1852       return false;
1853     }
1854
1855     bool isAnalysisRemarkEnabled(StringRef PassName) const override {
1856       return isRemarkEnabled(PassName);
1857     }
1858
1859     bool isMissedOptRemarkEnabled(StringRef PassName) const override {
1860       return isRemarkEnabled(PassName);
1861     }
1862
1863     bool isPassedOptRemarkEnabled(StringRef PassName) const override {
1864       return isRemarkEnabled(PassName);
1865     }
1866
1867     bool isAnyRemarkEnabled() const override {
1868       return RemarkAllPasses || !RemarkPasses.empty();
1869     }
1870
1871   private:
1872     bool isRemarkEnabled(StringRef PassName) const {
1873       if (RemarkAllPasses)
1874         return true;
1875
1876       for (auto &Pass : RemarkPasses)
1877         if (Pass == PassName)
1878           return true;
1879
1880       return false;
1881     }
1882
1883     LLVMDiagnosticHandlerTy DiagnosticHandlerCallback = nullptr;
1884     void *DiagnosticHandlerContext = nullptr;
1885
1886     bool RemarkAllPasses = false;
1887     std::vector<std::string> RemarkPasses;
1888   };
1889
1890   std::vector<std::string> Passes;
1891   for (size_t I = 0; I != RemarkPassesLen; ++I)
1892     Passes.push_back(RemarkPasses[I]);
1893
1894   unwrap(C)->setDiagnosticHandler(std::make_unique<RustDiagnosticHandler>(
1895       DiagnosticHandlerCallback, DiagnosticHandlerContext, RemarkAllPasses, Passes));
1896 }