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