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