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