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