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