1 #include "LLVMWrapper.h"
2 #include "llvm/IR/DebugInfoMetadata.h"
3 #include "llvm/IR/DiagnosticInfo.h"
4 #include "llvm/IR/DiagnosticPrinter.h"
5 #include "llvm/IR/GlobalVariable.h"
6 #include "llvm/IR/Instructions.h"
7 #include "llvm/IR/Intrinsics.h"
8 #include "llvm/Object/Archive.h"
9 #include "llvm/Object/ObjectFile.h"
10 #include "llvm/Bitcode/BitcodeWriterPass.h"
11 #include "llvm/Support/Signals.h"
12 #include "llvm/ADT/Optional.h"
16 //===----------------------------------------------------------------------===
18 // This file defines alternate interfaces to core functions that are more
19 // readily callable by Rust's FFI.
21 //===----------------------------------------------------------------------===
24 using namespace llvm::sys;
25 using namespace llvm::object;
27 // LLVMAtomicOrdering is already an enum - don't create another
29 static AtomicOrdering fromRust(LLVMAtomicOrdering 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;
47 report_fatal_error("Invalid LLVMAtomicOrdering value!");
50 static LLVM_THREAD_LOCAL char *LastError;
52 // Custom error handler for fatal LLVM errors.
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,
58 // Do the same thing that the default error handler does.
59 std::cerr << "LLVM ERROR: " << Reason << std::endl;
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
64 sys::RunInterruptHandlers();
69 extern "C" void LLVMRustInstallFatalErrorHandler() {
70 install_fatal_error_handler(FatalErrorHandler);
73 extern "C" LLVMMemoryBufferRef
74 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
75 ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =
76 MemoryBuffer::getFile(Path, -1, false);
78 LLVMRustSetLastError(BufOr.getError().message().c_str());
81 return wrap(BufOr.get().release());
84 extern "C" char *LLVMRustGetLastError(void) {
85 char *Ret = LastError;
90 extern "C" unsigned int LLVMRustGetInstructionCount(LLVMModuleRef M) {
91 return unwrap(M)->getInstructionCount();
94 extern "C" void LLVMRustSetLastError(const char *Err) {
95 free((void *)LastError);
96 LastError = strdup(Err);
99 extern "C" LLVMContextRef LLVMRustContextCreate(bool shouldDiscardNames) {
100 auto ctx = new LLVMContext();
101 ctx->setDiscardValueNames(shouldDiscardNames);
105 extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M,
106 const char *Triple) {
107 unwrap(M)->setTargetTriple(Triple::normalize(Triple));
110 extern "C" void LLVMRustPrintPassTimings() {
111 raw_fd_ostream OS(2, false); // stderr.
112 TimerGroup::printAll(OS);
115 extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
117 return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen)));
120 extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
123 LLVMTypeRef FunctionTy) {
124 return wrap(unwrap(M)
125 ->getOrInsertFunction(StringRef(Name, NameLen),
126 unwrap<FunctionType>(FunctionTy))
131 extern "C" LLVMValueRef
132 LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) {
133 StringRef NameRef(Name, NameLen);
134 return wrap(unwrap(M)->getOrInsertGlobal(NameRef, unwrap(Ty)));
137 extern "C" LLVMValueRef
138 LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) {
139 return wrap(new GlobalVariable(*unwrap(M),
142 GlobalValue::PrivateLinkage,
146 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
147 return wrap(Type::getMetadataTy(*unwrap(C)));
150 static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
153 return Attribute::AlwaysInline;
155 return Attribute::ByVal;
157 return Attribute::Cold;
159 return Attribute::InlineHint;
161 return Attribute::MinSize;
163 return Attribute::Naked;
165 return Attribute::NoAlias;
167 return Attribute::NoCapture;
169 return Attribute::NoInline;
171 return Attribute::NonNull;
173 return Attribute::NoRedZone;
175 return Attribute::NoReturn;
177 return Attribute::NoUnwind;
178 case OptimizeForSize:
179 return Attribute::OptimizeForSize;
181 return Attribute::ReadOnly;
183 return Attribute::SExt;
185 return Attribute::StructRet;
187 return Attribute::UWTable;
189 return Attribute::ZExt;
191 return Attribute::InReg;
193 return Attribute::SanitizeThread;
194 case SanitizeAddress:
195 return Attribute::SanitizeAddress;
197 return Attribute::SanitizeMemory;
199 return Attribute::NonLazyBind;
201 return Attribute::OptimizeNone;
203 return Attribute::ReturnsTwice;
205 return Attribute::ReadNone;
206 case InaccessibleMemOnly:
207 return Attribute::InaccessibleMemOnly;
208 case SanitizeHWAddress:
209 return Attribute::SanitizeHWAddress;
211 return Attribute::WillReturn;
213 report_fatal_error("bad AttributeKind");
216 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
217 LLVMRustAttribute RustAttr) {
218 CallBase *Call = unwrap<CallBase>(Instr);
219 Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
220 Call->addAttribute(Index, Attr);
223 extern "C" void LLVMRustAddCallSiteAttrString(LLVMValueRef Instr, unsigned Index,
225 CallBase *Call = unwrap<CallBase>(Instr);
226 Attribute Attr = Attribute::get(Call->getContext(), Name);
227 Call->addAttribute(Index, Attr);
231 extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
234 CallBase *Call = unwrap<CallBase>(Instr);
236 B.addAlignmentAttr(Bytes);
237 Call->setAttributes(Call->getAttributes().addAttributes(
238 Call->getContext(), Index, B));
241 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
244 CallBase *Call = unwrap<CallBase>(Instr);
246 B.addDereferenceableAttr(Bytes);
247 Call->setAttributes(Call->getAttributes().addAttributes(
248 Call->getContext(), Index, B));
251 extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
254 CallBase *Call = unwrap<CallBase>(Instr);
256 B.addDereferenceableOrNullAttr(Bytes);
257 Call->setAttributes(Call->getAttributes().addAttributes(
258 Call->getContext(), Index, B));
261 extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index,
263 CallBase *Call = unwrap<CallBase>(Instr);
264 Attribute Attr = Attribute::getWithByValType(Call->getContext(), unwrap(Ty));
265 Call->addAttribute(Index, Attr);
268 extern "C" void LLVMRustAddStructRetCallSiteAttr(LLVMValueRef Instr, unsigned Index,
270 CallBase *Call = unwrap<CallBase>(Instr);
271 #if LLVM_VERSION_GE(12, 0)
272 Attribute Attr = Attribute::getWithStructRetType(Call->getContext(), unwrap(Ty));
274 Attribute Attr = Attribute::get(Call->getContext(), Attribute::StructRet);
276 Call->addAttribute(Index, Attr);
279 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
280 LLVMRustAttribute RustAttr) {
281 Function *A = unwrap<Function>(Fn);
282 Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
284 A->addAttributes(Index, B);
287 extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn,
290 Function *A = unwrap<Function>(Fn);
292 B.addAlignmentAttr(Bytes);
293 A->addAttributes(Index, B);
296 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
298 Function *A = unwrap<Function>(Fn);
300 B.addDereferenceableAttr(Bytes);
301 A->addAttributes(Index, B);
304 extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
307 Function *A = unwrap<Function>(Fn);
309 B.addDereferenceableOrNullAttr(Bytes);
310 A->addAttributes(Index, B);
313 extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index,
315 Function *F = unwrap<Function>(Fn);
316 Attribute Attr = Attribute::getWithByValType(F->getContext(), unwrap(Ty));
317 F->addAttribute(Index, Attr);
320 extern "C" void LLVMRustAddStructRetAttr(LLVMValueRef Fn, unsigned Index,
322 Function *F = unwrap<Function>(Fn);
323 #if LLVM_VERSION_GE(12, 0)
324 Attribute Attr = Attribute::getWithStructRetType(F->getContext(), unwrap(Ty));
326 Attribute Attr = Attribute::get(F->getContext(), Attribute::StructRet);
328 F->addAttribute(Index, Attr);
331 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
335 Function *F = unwrap<Function>(Fn);
337 B.addAttribute(Name, Value);
338 F->addAttributes(Index, B);
341 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
343 LLVMRustAttribute RustAttr) {
344 Function *F = unwrap<Function>(Fn);
345 Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
347 auto PAL = F->getAttributes();
348 auto PALNew = PAL.removeAttributes(F->getContext(), Index, B);
349 F->setAttributes(PALNew);
352 // enable fpmath flag UnsafeAlgebra
353 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
354 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
359 extern "C" LLVMValueRef
360 LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef Source, const char *Name,
361 LLVMAtomicOrdering Order) {
362 Value *Ptr = unwrap(Source);
363 Type *Ty = Ptr->getType()->getPointerElementType();
364 LoadInst *LI = unwrap(B)->CreateLoad(Ty, Ptr, Name);
365 LI->setAtomic(fromRust(Order));
369 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
372 LLVMAtomicOrdering Order) {
373 StoreInst *SI = unwrap(B)->CreateStore(unwrap(V), unwrap(Target));
374 SI->setAtomic(fromRust(Order));
378 // FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak
379 // once we raise our minimum support to LLVM 10.
380 extern "C" LLVMValueRef
381 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
382 LLVMValueRef Old, LLVMValueRef Source,
383 LLVMAtomicOrdering Order,
384 LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
385 #if LLVM_VERSION_GE(13,0)
386 // Rust probably knows the alignment of the target value and should be able to
387 // specify something more precise than MaybeAlign here. See also
388 // https://reviews.llvm.org/D97224 which may be a useful reference.
389 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
390 unwrap(Target), unwrap(Old), unwrap(Source), llvm::MaybeAlign(), fromRust(Order),
391 fromRust(FailureOrder));
393 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
394 unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
395 fromRust(FailureOrder));
401 enum class LLVMRustSynchronizationScope {
406 static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
408 case LLVMRustSynchronizationScope::SingleThread:
409 return SyncScope::SingleThread;
410 case LLVMRustSynchronizationScope::CrossThread:
411 return SyncScope::System;
413 report_fatal_error("bad SynchronizationScope.");
417 extern "C" LLVMValueRef
418 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
419 LLVMRustSynchronizationScope Scope) {
420 return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
423 enum class LLVMRustAsmDialect {
428 static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
430 case LLVMRustAsmDialect::Att:
431 return InlineAsm::AD_ATT;
432 case LLVMRustAsmDialect::Intel:
433 return InlineAsm::AD_Intel;
435 report_fatal_error("bad AsmDialect.");
439 extern "C" LLVMValueRef
440 LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
441 char *Constraints, size_t ConstraintsLen,
442 LLVMBool HasSideEffects, LLVMBool IsAlignStack,
443 LLVMRustAsmDialect Dialect) {
444 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
445 StringRef(AsmString, AsmStringLen),
446 StringRef(Constraints, ConstraintsLen),
447 HasSideEffects, IsAlignStack, fromRust(Dialect)));
450 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
451 size_t ConstraintsLen) {
452 return InlineAsm::Verify(unwrap<FunctionType>(Ty),
453 StringRef(Constraints, ConstraintsLen));
456 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
458 unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen));
461 typedef DIBuilder *LLVMRustDIBuilderRef;
463 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
464 return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
467 #define DIDescriptor DIScope
468 #define DIArray DINodeArray
469 #define unwrapDI unwrapDIPtr
471 // These values **must** match debuginfo::DIFlags! They also *happen*
472 // to match LLVM, but that isn't required as we do giant sets of
473 // matching below. The value shouldn't be directly passed to LLVM.
474 enum class LLVMRustDIFlags : uint32_t {
479 FlagFwdDecl = (1 << 2),
480 FlagAppleBlock = (1 << 3),
481 FlagBlockByrefStruct = (1 << 4),
482 FlagVirtual = (1 << 5),
483 FlagArtificial = (1 << 6),
484 FlagExplicit = (1 << 7),
485 FlagPrototyped = (1 << 8),
486 FlagObjcClassComplete = (1 << 9),
487 FlagObjectPointer = (1 << 10),
488 FlagVector = (1 << 11),
489 FlagStaticMember = (1 << 12),
490 FlagLValueReference = (1 << 13),
491 FlagRValueReference = (1 << 14),
492 FlagExternalTypeRef = (1 << 15),
493 FlagIntroducedVirtual = (1 << 18),
494 FlagBitField = (1 << 19),
495 FlagNoReturn = (1 << 20),
496 // Do not add values that are not supported by the minimum LLVM
497 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
500 inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
501 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
502 static_cast<uint32_t>(B));
505 inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
506 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
507 static_cast<uint32_t>(B));
510 inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
514 inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
516 inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
517 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
520 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
521 DINode::DIFlags Result = DINode::DIFlags::FlagZero;
523 switch (visibility(Flags)) {
524 case LLVMRustDIFlags::FlagPrivate:
525 Result |= DINode::DIFlags::FlagPrivate;
527 case LLVMRustDIFlags::FlagProtected:
528 Result |= DINode::DIFlags::FlagProtected;
530 case LLVMRustDIFlags::FlagPublic:
531 Result |= DINode::DIFlags::FlagPublic;
534 // The rest are handled below
538 if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
539 Result |= DINode::DIFlags::FlagFwdDecl;
541 if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
542 Result |= DINode::DIFlags::FlagAppleBlock;
544 if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
545 Result |= DINode::DIFlags::FlagVirtual;
547 if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
548 Result |= DINode::DIFlags::FlagArtificial;
550 if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
551 Result |= DINode::DIFlags::FlagExplicit;
553 if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
554 Result |= DINode::DIFlags::FlagPrototyped;
556 if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
557 Result |= DINode::DIFlags::FlagObjcClassComplete;
559 if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
560 Result |= DINode::DIFlags::FlagObjectPointer;
562 if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
563 Result |= DINode::DIFlags::FlagVector;
565 if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
566 Result |= DINode::DIFlags::FlagStaticMember;
568 if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
569 Result |= DINode::DIFlags::FlagLValueReference;
571 if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
572 Result |= DINode::DIFlags::FlagRValueReference;
574 if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
575 Result |= DINode::DIFlags::FlagIntroducedVirtual;
577 if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
578 Result |= DINode::DIFlags::FlagBitField;
580 if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
581 Result |= DINode::DIFlags::FlagNoReturn;
587 // These values **must** match debuginfo::DISPFlags! They also *happen*
588 // to match LLVM, but that isn't required as we do giant sets of
589 // matching below. The value shouldn't be directly passed to LLVM.
590 enum class LLVMRustDISPFlags : uint32_t {
593 SPFlagPureVirtual = 2,
594 SPFlagLocalToUnit = (1 << 2),
595 SPFlagDefinition = (1 << 3),
596 SPFlagOptimized = (1 << 4),
597 SPFlagMainSubprogram = (1 << 5),
598 // Do not add values that are not supported by the minimum LLVM
599 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
600 // (In LLVM < 8, createFunction supported these as separate bool arguments.)
603 inline LLVMRustDISPFlags operator&(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
604 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) &
605 static_cast<uint32_t>(B));
608 inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
609 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) |
610 static_cast<uint32_t>(B));
613 inline LLVMRustDISPFlags &operator|=(LLVMRustDISPFlags &A, LLVMRustDISPFlags B) {
617 inline bool isSet(LLVMRustDISPFlags F) { return F != LLVMRustDISPFlags::SPFlagZero; }
619 inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) {
620 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(F) & 0x3);
623 static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) {
624 DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero;
626 switch (virtuality(SPFlags)) {
627 case LLVMRustDISPFlags::SPFlagVirtual:
628 Result |= DISubprogram::DISPFlags::SPFlagVirtual;
630 case LLVMRustDISPFlags::SPFlagPureVirtual:
631 Result |= DISubprogram::DISPFlags::SPFlagPureVirtual;
634 // The rest are handled below
638 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit)) {
639 Result |= DISubprogram::DISPFlags::SPFlagLocalToUnit;
641 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition)) {
642 Result |= DISubprogram::DISPFlags::SPFlagDefinition;
644 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) {
645 Result |= DISubprogram::DISPFlags::SPFlagOptimized;
647 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) {
648 Result |= DISubprogram::DISPFlags::SPFlagMainSubprogram;
654 enum class LLVMRustDebugEmissionKind {
660 static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
662 case LLVMRustDebugEmissionKind::NoDebug:
663 return DICompileUnit::DebugEmissionKind::NoDebug;
664 case LLVMRustDebugEmissionKind::FullDebug:
665 return DICompileUnit::DebugEmissionKind::FullDebug;
666 case LLVMRustDebugEmissionKind::LineTablesOnly:
667 return DICompileUnit::DebugEmissionKind::LineTablesOnly;
669 report_fatal_error("bad DebugEmissionKind.");
673 enum class LLVMRustChecksumKind {
680 static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
682 case LLVMRustChecksumKind::None:
684 case LLVMRustChecksumKind::MD5:
685 return DIFile::ChecksumKind::CSK_MD5;
686 case LLVMRustChecksumKind::SHA1:
687 return DIFile::ChecksumKind::CSK_SHA1;
688 #if (LLVM_VERSION_MAJOR >= 11)
689 case LLVMRustChecksumKind::SHA256:
690 return DIFile::ChecksumKind::CSK_SHA256;
693 report_fatal_error("bad ChecksumKind.");
697 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
698 return DEBUG_METADATA_VERSION;
701 extern "C" uint32_t LLVMRustVersionPatch() { return LLVM_VERSION_PATCH; }
703 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
705 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
707 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
709 unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
712 extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
713 return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
716 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
717 return new DIBuilder(*unwrap(M));
720 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
724 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
728 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
729 LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
730 const char *Producer, size_t ProducerLen, bool isOptimized,
731 const char *Flags, unsigned RuntimeVer,
732 const char *SplitName, size_t SplitNameLen,
733 LLVMRustDebugEmissionKind Kind,
734 uint64_t DWOId, bool SplitDebugInlining) {
735 auto *File = unwrapDI<DIFile>(FileRef);
737 return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
738 isOptimized, Flags, RuntimeVer,
739 StringRef(SplitName, SplitNameLen),
740 fromRust(Kind), DWOId, SplitDebugInlining));
743 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
744 LLVMRustDIBuilderRef Builder,
745 const char *Filename, size_t FilenameLen,
746 const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
747 const char *Checksum, size_t ChecksumLen) {
748 Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
749 Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
751 CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
752 return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
753 StringRef(Directory, DirectoryLen),
757 extern "C" LLVMMetadataRef
758 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
759 LLVMMetadataRef ParameterTypes) {
760 return wrap(Builder->createSubroutineType(
761 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
764 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
765 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
766 const char *Name, size_t NameLen,
767 const char *LinkageName, size_t LinkageNameLen,
768 LLVMMetadataRef File, unsigned LineNo,
769 LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
770 LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam,
771 LLVMMetadataRef Decl) {
772 DITemplateParameterArray TParams =
773 DITemplateParameterArray(unwrap<MDTuple>(TParam));
774 DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
775 DINode::DIFlags llvmFlags = fromRust(Flags);
776 DISubprogram *Sub = Builder->createFunction(
777 unwrapDI<DIScope>(Scope),
778 StringRef(Name, NameLen),
779 StringRef(LinkageName, LinkageNameLen),
780 unwrapDI<DIFile>(File), LineNo,
781 unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
782 llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
784 unwrap<Function>(MaybeFn)->setSubprogram(Sub);
788 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
789 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
790 uint64_t SizeInBits, unsigned Encoding) {
791 return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
794 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
795 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
796 LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
797 return wrap(Builder->createTypedef(
798 unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
799 LineNo, unwrapDIPtr<DIScope>(Scope)));
802 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
803 LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
804 uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
805 const char *Name, size_t NameLen) {
806 return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
807 SizeInBits, AlignInBits,
809 StringRef(Name, NameLen)));
812 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
813 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
814 const char *Name, size_t NameLen,
815 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
816 uint32_t AlignInBits, LLVMRustDIFlags Flags,
817 LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
818 unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
819 const char *UniqueId, size_t UniqueIdLen) {
820 return wrap(Builder->createStructType(
821 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
822 unwrapDI<DIFile>(File), LineNumber,
823 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
824 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
825 unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen)));
828 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
829 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
830 const char *Name, size_t NameLen,
831 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
832 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
833 LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) {
834 return wrap(Builder->createVariantPart(
835 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
836 unwrapDI<DIFile>(File), LineNumber,
837 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
838 DINodeArray(unwrapDI<MDTuple>(Elements)), StringRef(UniqueId, UniqueIdLen)));
841 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
842 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
843 const char *Name, size_t NameLen,
844 LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
845 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
846 LLVMMetadataRef Ty) {
847 return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope),
848 StringRef(Name, NameLen),
849 unwrapDI<DIFile>(File), LineNo,
850 SizeInBits, AlignInBits, OffsetInBits,
851 fromRust(Flags), unwrapDI<DIType>(Ty)));
854 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
855 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
856 const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
857 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
858 LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
859 llvm::ConstantInt* D = nullptr;
861 D = unwrap<llvm::ConstantInt>(Discriminant);
863 return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope),
864 StringRef(Name, NameLen),
865 unwrapDI<DIFile>(File), LineNo,
866 SizeInBits, AlignInBits, OffsetInBits, D,
867 fromRust(Flags), unwrapDI<DIType>(Ty)));
870 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
871 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
872 LLVMMetadataRef File, unsigned Line, unsigned Col) {
873 return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
874 unwrapDI<DIFile>(File), Line, Col));
877 extern "C" LLVMMetadataRef
878 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
879 LLVMMetadataRef Scope,
880 LLVMMetadataRef File) {
881 return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
882 unwrapDI<DIFile>(File)));
885 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
886 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context,
887 const char *Name, size_t NameLen,
888 const char *LinkageName, size_t LinkageNameLen,
889 LLVMMetadataRef File, unsigned LineNo,
890 LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
891 LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
892 llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
894 llvm::DIExpression *InitExpr = nullptr;
895 if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
896 InitExpr = Builder->createConstantValueExpression(
897 IntVal->getValue().getSExtValue());
898 } else if (llvm::ConstantFP *FPVal =
899 llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
900 InitExpr = Builder->createConstantValueExpression(
901 FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
904 llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
905 unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
906 StringRef(LinkageName, LinkageNameLen),
907 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
908 /* isDefined */ true,
909 InitExpr, unwrapDIPtr<MDNode>(Decl),
910 /* templateParams */ nullptr,
913 InitVal->setMetadata("dbg", VarExpr);
915 return wrap(VarExpr);
918 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
919 LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
920 const char *Name, size_t NameLen,
921 LLVMMetadataRef File, unsigned LineNo,
922 LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
923 unsigned ArgNo, uint32_t AlignInBits) {
924 if (Tag == 0x100) { // DW_TAG_auto_variable
925 return wrap(Builder->createAutoVariable(
926 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
927 unwrapDI<DIFile>(File), LineNo,
928 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
930 return wrap(Builder->createParameterVariable(
931 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
932 unwrapDI<DIFile>(File), LineNo,
933 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
937 extern "C" LLVMMetadataRef
938 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
939 uint32_t AlignInBits, LLVMMetadataRef Ty,
940 LLVMMetadataRef Subscripts) {
942 Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
943 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
946 extern "C" LLVMMetadataRef
947 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
949 return wrap(Builder->getOrCreateSubrange(Lo, Count));
952 extern "C" LLVMMetadataRef
953 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
954 LLVMMetadataRef *Ptr, unsigned Count) {
955 Metadata **DataValue = unwrap(Ptr);
957 Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
960 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
961 LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
962 int64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
963 LLVMBasicBlockRef InsertAtEnd) {
964 return wrap(Builder->insertDeclare(
965 unwrap(V), unwrap<DILocalVariable>(VarInfo),
966 Builder->createExpression(llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
967 DebugLoc(cast<MDNode>(unwrap(DL))),
968 unwrap(InsertAtEnd)));
971 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
972 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
973 int64_t Value, bool IsUnsigned) {
974 return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
977 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
978 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
979 const char *Name, size_t NameLen,
980 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
981 uint32_t AlignInBits, LLVMMetadataRef Elements,
982 LLVMMetadataRef ClassTy, bool IsScoped) {
983 return wrap(Builder->createEnumerationType(
984 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
985 unwrapDI<DIFile>(File), LineNumber,
986 SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
987 unwrapDI<DIType>(ClassTy), "", IsScoped));
990 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
991 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
992 const char *Name, size_t NameLen,
993 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
994 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
995 unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) {
996 return wrap(Builder->createUnionType(
997 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File),
998 LineNumber, SizeInBits, AlignInBits, fromRust(Flags),
999 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
1000 StringRef(UniqueId, UniqueIdLen)));
1003 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
1004 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1005 const char *Name, size_t NameLen, LLVMMetadataRef Ty) {
1006 #if LLVM_VERSION_GE(11, 0)
1007 bool IsDefault = false; // FIXME: should we ever set this true?
1008 return wrap(Builder->createTemplateTypeParameter(
1009 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty), IsDefault));
1011 return wrap(Builder->createTemplateTypeParameter(
1012 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty)));
1016 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateNameSpace(
1017 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1018 const char *Name, size_t NameLen, bool ExportSymbols) {
1019 return wrap(Builder->createNameSpace(
1020 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols
1025 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
1026 LLVMMetadataRef CompositeTy,
1027 LLVMMetadataRef Elements,
1028 LLVMMetadataRef Params) {
1029 DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
1030 Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
1031 DINodeArray(unwrap<MDTuple>(Params)));
1034 extern "C" LLVMMetadataRef
1035 LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
1036 LLVMMetadataRef ScopeRef,
1037 LLVMMetadataRef InlinedAt) {
1038 #if LLVM_VERSION_GE(12, 0)
1039 MDNode *Scope = unwrapDIPtr<MDNode>(ScopeRef);
1040 DILocation *Loc = DILocation::get(
1041 Scope->getContext(), Line, Column, Scope,
1042 unwrapDIPtr<MDNode>(InlinedAt));
1045 DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(ScopeRef),
1046 unwrapDIPtr<MDNode>(InlinedAt));
1047 return wrap(debug_loc.getAsMDNode());
1051 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
1052 return dwarf::DW_OP_deref;
1055 extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1056 return dwarf::DW_OP_plus_uconst;
1059 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
1060 RawRustStringOstream OS(Str);
1061 unwrap<llvm::Type>(Ty)->print(OS);
1064 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
1065 RustStringRef Str) {
1066 RawRustStringOstream OS(Str);
1071 unwrap<llvm::Value>(V)->getType()->print(OS);
1073 unwrap<llvm::Value>(V)->print(OS);
1078 // Note that the two following functions look quite similar to the
1079 // LLVMGetSectionName function. Sadly, it appears that this function only
1080 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
1081 // function provided by LLVM doesn't return the length, so we've created our own
1082 // function which returns the length as well as the data pointer.
1084 // For an example of this not returning a null terminated string, see
1085 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
1086 // branches explicitly creates a StringRef without a null terminator, and then
1089 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
1090 return reinterpret_cast<section_iterator *>(SI);
1093 extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI,
1095 auto NameOrErr = (*unwrap(SI))->getName();
1097 report_fatal_error(NameOrErr.takeError());
1098 *Ptr = NameOrErr->data();
1099 return NameOrErr->size();
1102 // LLVMArrayType function does not support 64-bit ElementCount
1103 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
1104 uint64_t ElementCount) {
1105 return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
1108 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1110 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
1111 RawRustStringOstream OS(Str);
1112 unwrap(T)->print(OS);
1115 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1116 LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
1117 LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
1118 RustStringRef FilenameOut, RustStringRef MessageOut) {
1119 // Undefined to call this not on an optimization diagnostic!
1120 llvm::DiagnosticInfoOptimizationBase *Opt =
1121 static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
1123 RawRustStringOstream PassNameOS(PassNameOut);
1124 PassNameOS << Opt->getPassName();
1125 *FunctionOut = wrap(&Opt->getFunction());
1127 RawRustStringOstream FilenameOS(FilenameOut);
1128 DiagnosticLocation loc = Opt->getLocation();
1129 if (loc.isValid()) {
1130 *Line = loc.getLine();
1131 *Column = loc.getColumn();
1132 FilenameOS << loc.getAbsolutePath();
1135 RawRustStringOstream MessageOS(MessageOut);
1136 MessageOS << Opt->getMsg();
1139 enum class LLVMRustDiagnosticLevel {
1147 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
1148 LLVMRustDiagnosticLevel *LevelOut,
1149 unsigned *CookieOut,
1150 LLVMTwineRef *MessageOut,
1151 LLVMValueRef *InstructionOut) {
1152 // Undefined to call this not on an inline assembly diagnostic!
1153 llvm::DiagnosticInfoInlineAsm *IA =
1154 static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
1156 *CookieOut = IA->getLocCookie();
1157 *MessageOut = wrap(&IA->getMsgStr());
1158 *InstructionOut = wrap(IA->getInstruction());
1160 switch (IA->getSeverity()) {
1162 *LevelOut = LLVMRustDiagnosticLevel::Error;
1165 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1168 *LevelOut = LLVMRustDiagnosticLevel::Note;
1171 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1174 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1178 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
1179 RustStringRef Str) {
1180 RawRustStringOstream OS(Str);
1181 DiagnosticPrinterRawOStream DP(OS);
1182 unwrap(DI)->print(DP);
1185 enum class LLVMRustDiagnosticKind {
1189 DebugMetadataVersion,
1192 OptimizationRemarkMissed,
1193 OptimizationRemarkAnalysis,
1194 OptimizationRemarkAnalysisFPCommute,
1195 OptimizationRemarkAnalysisAliasing,
1196 OptimizationRemarkOther,
1197 OptimizationFailure,
1203 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1206 return LLVMRustDiagnosticKind::InlineAsm;
1208 return LLVMRustDiagnosticKind::StackSize;
1209 case DK_DebugMetadataVersion:
1210 return LLVMRustDiagnosticKind::DebugMetadataVersion;
1211 case DK_SampleProfile:
1212 return LLVMRustDiagnosticKind::SampleProfile;
1213 case DK_OptimizationRemark:
1214 return LLVMRustDiagnosticKind::OptimizationRemark;
1215 case DK_OptimizationRemarkMissed:
1216 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1217 case DK_OptimizationRemarkAnalysis:
1218 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1219 case DK_OptimizationRemarkAnalysisFPCommute:
1220 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1221 case DK_OptimizationRemarkAnalysisAliasing:
1222 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1224 return LLVMRustDiagnosticKind::PGOProfile;
1226 return LLVMRustDiagnosticKind::Linker;
1227 case DK_Unsupported:
1228 return LLVMRustDiagnosticKind::Unsupported;
1230 return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1231 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1232 : LLVMRustDiagnosticKind::Other;
1236 extern "C" LLVMRustDiagnosticKind
1237 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1238 return toRust((DiagnosticKind)unwrap(DI)->getKind());
1241 // This is kept distinct from LLVMGetTypeKind, because when
1242 // a new type kind is added, the Rust-side enum must be
1243 // updated or UB will result.
1244 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1245 switch (unwrap(Ty)->getTypeID()) {
1246 case Type::VoidTyID:
1247 return LLVMVoidTypeKind;
1248 case Type::HalfTyID:
1249 return LLVMHalfTypeKind;
1250 case Type::FloatTyID:
1251 return LLVMFloatTypeKind;
1252 case Type::DoubleTyID:
1253 return LLVMDoubleTypeKind;
1254 case Type::X86_FP80TyID:
1255 return LLVMX86_FP80TypeKind;
1256 case Type::FP128TyID:
1257 return LLVMFP128TypeKind;
1258 case Type::PPC_FP128TyID:
1259 return LLVMPPC_FP128TypeKind;
1260 case Type::LabelTyID:
1261 return LLVMLabelTypeKind;
1262 case Type::MetadataTyID:
1263 return LLVMMetadataTypeKind;
1264 case Type::IntegerTyID:
1265 return LLVMIntegerTypeKind;
1266 case Type::FunctionTyID:
1267 return LLVMFunctionTypeKind;
1268 case Type::StructTyID:
1269 return LLVMStructTypeKind;
1270 case Type::ArrayTyID:
1271 return LLVMArrayTypeKind;
1272 case Type::PointerTyID:
1273 return LLVMPointerTypeKind;
1274 #if LLVM_VERSION_GE(11, 0)
1275 case Type::FixedVectorTyID:
1276 return LLVMVectorTypeKind;
1278 case Type::VectorTyID:
1279 return LLVMVectorTypeKind;
1281 case Type::X86_MMXTyID:
1282 return LLVMX86_MMXTypeKind;
1283 case Type::TokenTyID:
1284 return LLVMTokenTypeKind;
1285 #if LLVM_VERSION_GE(11, 0)
1286 case Type::ScalableVectorTyID:
1287 return LLVMScalableVectorTypeKind;
1288 case Type::BFloatTyID:
1289 return LLVMBFloatTypeKind;
1291 #if LLVM_VERSION_GE(12, 0)
1292 case Type::X86_AMXTyID:
1293 return LLVMX86_AMXTypeKind;
1296 report_fatal_error("Unhandled TypeID.");
1299 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1301 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1302 LLVMContextRef C, LLVMContext::InlineAsmDiagHandlerTy H, void *CX) {
1303 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1306 extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
1307 RustStringRef MessageOut,
1308 RustStringRef BufferOut,
1309 LLVMRustDiagnosticLevel* LevelOut,
1311 unsigned* RangesOut,
1312 size_t* NumRanges) {
1313 SMDiagnostic& D = *unwrap(DRef);
1314 RawRustStringOstream MessageOS(MessageOut);
1315 MessageOS << D.getMessage();
1317 switch (D.getKind()) {
1318 case SourceMgr::DK_Error:
1319 *LevelOut = LLVMRustDiagnosticLevel::Error;
1321 case SourceMgr::DK_Warning:
1322 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1324 case SourceMgr::DK_Note:
1325 *LevelOut = LLVMRustDiagnosticLevel::Note;
1327 case SourceMgr::DK_Remark:
1328 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1331 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1334 if (D.getLoc() == SMLoc())
1337 const SourceMgr &LSM = *D.getSourceMgr();
1338 const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
1339 LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), LBuf->getBufferSize());
1341 *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
1343 *NumRanges = std::min(*NumRanges, D.getRanges().size());
1344 size_t LineStart = *LocOut - (size_t)D.getColumnNo();
1345 for (size_t i = 0; i < *NumRanges; i++) {
1346 RangesOut[i * 2] = LineStart + D.getRanges()[i].first;
1347 RangesOut[i * 2 + 1] = LineStart + D.getRanges()[i].second;
1353 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1354 LLVMValueRef ParentPad,
1356 LLVMValueRef *LLArgs,
1358 Value **Args = unwrap(LLArgs);
1359 if (ParentPad == nullptr) {
1360 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1361 ParentPad = wrap(Constant::getNullValue(Ty));
1363 return wrap(unwrap(B)->CreateCleanupPad(
1364 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1367 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1368 LLVMValueRef CleanupPad,
1369 LLVMBasicBlockRef UnwindBB) {
1370 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1371 return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1374 extern "C" LLVMValueRef
1375 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1376 unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1377 Value **Args = unwrap(LLArgs);
1378 return wrap(unwrap(B)->CreateCatchPad(
1379 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1382 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1384 LLVMBasicBlockRef BB) {
1385 return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1389 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1390 LLVMValueRef ParentPad,
1391 LLVMBasicBlockRef BB,
1392 unsigned NumHandlers,
1394 if (ParentPad == nullptr) {
1395 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1396 ParentPad = wrap(Constant::getNullValue(Ty));
1398 return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1399 NumHandlers, Name));
1402 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1403 LLVMBasicBlockRef Handler) {
1404 Value *CatchSwitch = unwrap(CatchSwitchRef);
1405 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1408 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1409 LLVMValueRef *Inputs,
1410 unsigned NumInputs) {
1411 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1414 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1418 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
1419 LLVMValueRef *Args, unsigned NumArgs,
1420 OperandBundleDef *Bundle) {
1421 Value *Callee = unwrap(Fn);
1422 FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1423 unsigned Len = Bundle ? 1 : 0;
1424 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1425 return wrap(unwrap(B)->CreateCall(
1426 FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles));
1429 extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
1430 return wrap(llvm::Intrinsic::getDeclaration(unwrap(M),
1431 (llvm::Intrinsic::ID)llvm::Intrinsic::instrprof_increment));
1434 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
1435 LLVMValueRef Dst, unsigned DstAlign,
1436 LLVMValueRef Src, unsigned SrcAlign,
1437 LLVMValueRef Size, bool IsVolatile) {
1438 return wrap(unwrap(B)->CreateMemCpy(
1439 unwrap(Dst), MaybeAlign(DstAlign),
1440 unwrap(Src), MaybeAlign(SrcAlign),
1441 unwrap(Size), IsVolatile));
1444 extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
1445 LLVMValueRef Dst, unsigned DstAlign,
1446 LLVMValueRef Src, unsigned SrcAlign,
1447 LLVMValueRef Size, bool IsVolatile) {
1448 return wrap(unwrap(B)->CreateMemMove(
1449 unwrap(Dst), MaybeAlign(DstAlign),
1450 unwrap(Src), MaybeAlign(SrcAlign),
1451 unwrap(Size), IsVolatile));
1454 extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
1455 LLVMValueRef Dst, unsigned DstAlign,
1457 LLVMValueRef Size, bool IsVolatile) {
1458 return wrap(unwrap(B)->CreateMemSet(
1459 unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
1462 extern "C" LLVMValueRef
1463 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
1464 unsigned NumArgs, LLVMBasicBlockRef Then,
1465 LLVMBasicBlockRef Catch, OperandBundleDef *Bundle,
1467 Value *Callee = unwrap(Fn);
1468 FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1469 unsigned Len = Bundle ? 1 : 0;
1470 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1471 return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
1472 makeArrayRef(unwrap(Args), NumArgs),
1476 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1477 LLVMBasicBlockRef BB) {
1478 auto Point = unwrap(BB)->getFirstInsertionPt();
1479 unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1482 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1483 const char *Name, size_t NameLen) {
1484 Triple TargetTriple(unwrap(M)->getTargetTriple());
1485 GlobalObject *GV = unwrap<GlobalObject>(V);
1486 if (TargetTriple.supportsCOMDAT()) {
1487 StringRef NameRef(Name, NameLen);
1488 GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
1492 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1493 GlobalObject *GV = unwrap<GlobalObject>(V);
1494 GV->setComdat(nullptr);
1497 enum class LLVMRustLinkage {
1498 ExternalLinkage = 0,
1499 AvailableExternallyLinkage = 1,
1500 LinkOnceAnyLinkage = 2,
1501 LinkOnceODRLinkage = 3,
1504 AppendingLinkage = 6,
1505 InternalLinkage = 7,
1507 ExternalWeakLinkage = 9,
1511 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1513 case LLVMExternalLinkage:
1514 return LLVMRustLinkage::ExternalLinkage;
1515 case LLVMAvailableExternallyLinkage:
1516 return LLVMRustLinkage::AvailableExternallyLinkage;
1517 case LLVMLinkOnceAnyLinkage:
1518 return LLVMRustLinkage::LinkOnceAnyLinkage;
1519 case LLVMLinkOnceODRLinkage:
1520 return LLVMRustLinkage::LinkOnceODRLinkage;
1521 case LLVMWeakAnyLinkage:
1522 return LLVMRustLinkage::WeakAnyLinkage;
1523 case LLVMWeakODRLinkage:
1524 return LLVMRustLinkage::WeakODRLinkage;
1525 case LLVMAppendingLinkage:
1526 return LLVMRustLinkage::AppendingLinkage;
1527 case LLVMInternalLinkage:
1528 return LLVMRustLinkage::InternalLinkage;
1529 case LLVMPrivateLinkage:
1530 return LLVMRustLinkage::PrivateLinkage;
1531 case LLVMExternalWeakLinkage:
1532 return LLVMRustLinkage::ExternalWeakLinkage;
1533 case LLVMCommonLinkage:
1534 return LLVMRustLinkage::CommonLinkage;
1536 report_fatal_error("Invalid LLVMRustLinkage value!");
1540 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1542 case LLVMRustLinkage::ExternalLinkage:
1543 return LLVMExternalLinkage;
1544 case LLVMRustLinkage::AvailableExternallyLinkage:
1545 return LLVMAvailableExternallyLinkage;
1546 case LLVMRustLinkage::LinkOnceAnyLinkage:
1547 return LLVMLinkOnceAnyLinkage;
1548 case LLVMRustLinkage::LinkOnceODRLinkage:
1549 return LLVMLinkOnceODRLinkage;
1550 case LLVMRustLinkage::WeakAnyLinkage:
1551 return LLVMWeakAnyLinkage;
1552 case LLVMRustLinkage::WeakODRLinkage:
1553 return LLVMWeakODRLinkage;
1554 case LLVMRustLinkage::AppendingLinkage:
1555 return LLVMAppendingLinkage;
1556 case LLVMRustLinkage::InternalLinkage:
1557 return LLVMInternalLinkage;
1558 case LLVMRustLinkage::PrivateLinkage:
1559 return LLVMPrivateLinkage;
1560 case LLVMRustLinkage::ExternalWeakLinkage:
1561 return LLVMExternalWeakLinkage;
1562 case LLVMRustLinkage::CommonLinkage:
1563 return LLVMCommonLinkage;
1565 report_fatal_error("Invalid LLVMRustLinkage value!");
1568 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1569 return toRust(LLVMGetLinkage(V));
1572 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1573 LLVMRustLinkage RustLinkage) {
1574 LLVMSetLinkage(V, fromRust(RustLinkage));
1577 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1578 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1579 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1581 auto C = unwrap<llvm::ConstantInt>(CV);
1582 if (C->getBitWidth() > 128) { return false; }
1585 AP = C->getValue().sextOrSelf(128);
1587 AP = C->getValue().zextOrSelf(128);
1589 *low = AP.getLoBits(64).getZExtValue();
1590 *high = AP.getHiBits(64).getZExtValue();
1594 enum class LLVMRustVisibility {
1600 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1602 case LLVMDefaultVisibility:
1603 return LLVMRustVisibility::Default;
1604 case LLVMHiddenVisibility:
1605 return LLVMRustVisibility::Hidden;
1606 case LLVMProtectedVisibility:
1607 return LLVMRustVisibility::Protected;
1609 report_fatal_error("Invalid LLVMRustVisibility value!");
1612 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1614 case LLVMRustVisibility::Default:
1615 return LLVMDefaultVisibility;
1616 case LLVMRustVisibility::Hidden:
1617 return LLVMHiddenVisibility;
1618 case LLVMRustVisibility::Protected:
1619 return LLVMProtectedVisibility;
1621 report_fatal_error("Invalid LLVMRustVisibility value!");
1624 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1625 return toRust(LLVMGetVisibility(V));
1628 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1629 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1630 LLVMTypeRef DestTy, bool isSigned) {
1631 return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1634 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1635 LLVMRustVisibility RustVisibility) {
1636 LLVMSetVisibility(V, fromRust(RustVisibility));
1639 struct LLVMRustModuleBuffer {
1643 extern "C" LLVMRustModuleBuffer*
1644 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1645 auto Ret = std::make_unique<LLVMRustModuleBuffer>();
1647 raw_string_ostream OS(Ret->data);
1649 legacy::PassManager PM;
1650 PM.add(createBitcodeWriterPass(OS));
1654 return Ret.release();
1658 LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1662 extern "C" const void*
1663 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1664 return Buffer->data.data();
1668 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1669 return Buffer->data.length();
1673 LLVMRustModuleCost(LLVMModuleRef M) {
1674 auto f = unwrap(M)->functions();
1675 return std::distance(std::begin(f), std::end(f));
1678 // Vector reductions:
1679 extern "C" LLVMValueRef
1680 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1681 return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1683 extern "C" LLVMValueRef
1684 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1685 return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1687 extern "C" LLVMValueRef
1688 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1689 return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1691 extern "C" LLVMValueRef
1692 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1693 return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1695 extern "C" LLVMValueRef
1696 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1697 return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1699 extern "C" LLVMValueRef
1700 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1701 return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1703 extern "C" LLVMValueRef
1704 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1705 return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1707 extern "C" LLVMValueRef
1708 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1709 return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1711 extern "C" LLVMValueRef
1712 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1713 return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1715 extern "C" LLVMValueRef
1716 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1717 #if LLVM_VERSION_GE(12, 0)
1718 Instruction *I = unwrap(B)->CreateFPMinReduce(unwrap(Src));
1719 I->setHasNoNaNs(NoNaN);
1722 return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN));
1725 extern "C" LLVMValueRef
1726 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1727 #if LLVM_VERSION_GE(12, 0)
1728 Instruction *I = unwrap(B)->CreateFPMaxReduce(unwrap(Src));
1729 I->setHasNoNaNs(NoNaN);
1732 return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN));
1736 extern "C" LLVMValueRef
1737 LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1738 return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1740 extern "C" LLVMValueRef
1741 LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1742 return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));