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