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