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