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