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