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