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