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