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/COFFImportFile.h"
10 #include "llvm/Object/ObjectFile.h"
11 #include "llvm/Bitcode/BitcodeWriterPass.h"
12 #include "llvm/Support/Signals.h"
13 #include "llvm/ADT/Optional.h"
17 //===----------------------------------------------------------------------===
19 // This file defines alternate interfaces to core functions that are more
20 // readily callable by Rust's FFI.
22 //===----------------------------------------------------------------------===
25 using namespace llvm::sys;
26 using namespace llvm::object;
28 // LLVMAtomicOrdering is already an enum - don't create another
30 static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
32 case LLVMAtomicOrderingNotAtomic:
33 return AtomicOrdering::NotAtomic;
34 case LLVMAtomicOrderingUnordered:
35 return AtomicOrdering::Unordered;
36 case LLVMAtomicOrderingMonotonic:
37 return AtomicOrdering::Monotonic;
38 case LLVMAtomicOrderingAcquire:
39 return AtomicOrdering::Acquire;
40 case LLVMAtomicOrderingRelease:
41 return AtomicOrdering::Release;
42 case LLVMAtomicOrderingAcquireRelease:
43 return AtomicOrdering::AcquireRelease;
44 case LLVMAtomicOrderingSequentiallyConsistent:
45 return AtomicOrdering::SequentiallyConsistent;
48 report_fatal_error("Invalid LLVMAtomicOrdering value!");
51 static LLVM_THREAD_LOCAL char *LastError;
53 // Custom error handler for fatal LLVM errors.
55 // Notably it exits the process with code 101, unlike LLVM's default of 1.
56 static void FatalErrorHandler(void *UserData,
57 const std::string& Reason,
59 // Do the same thing that the default error handler does.
60 std::cerr << "LLVM ERROR: " << Reason << std::endl;
62 // Since this error handler exits the process, we have to run any cleanup that
63 // LLVM would run after handling the error. This might change with an LLVM
65 sys::RunInterruptHandlers();
70 extern "C" void LLVMRustInstallFatalErrorHandler() {
71 install_fatal_error_handler(FatalErrorHandler);
74 extern "C" char *LLVMRustGetLastError(void) {
75 char *Ret = LastError;
80 extern "C" unsigned int LLVMRustGetInstructionCount(LLVMModuleRef M) {
81 return unwrap(M)->getInstructionCount();
84 extern "C" void LLVMRustSetLastError(const char *Err) {
85 free((void *)LastError);
86 LastError = strdup(Err);
89 extern "C" LLVMContextRef LLVMRustContextCreate(bool shouldDiscardNames) {
90 auto ctx = new LLVMContext();
91 ctx->setDiscardValueNames(shouldDiscardNames);
95 extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M,
97 unwrap(M)->setTargetTriple(Triple::normalize(Triple));
100 extern "C" void LLVMRustPrintPassTimings() {
101 raw_fd_ostream OS(2, false); // stderr.
102 TimerGroup::printAll(OS);
105 extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
107 return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen)));
110 extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
113 LLVMTypeRef FunctionTy) {
114 return wrap(unwrap(M)
115 ->getOrInsertFunction(StringRef(Name, NameLen),
116 unwrap<FunctionType>(FunctionTy))
121 extern "C" LLVMValueRef
122 LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) {
123 StringRef NameRef(Name, NameLen);
124 return wrap(unwrap(M)->getOrInsertGlobal(NameRef, unwrap(Ty)));
127 extern "C" LLVMValueRef
128 LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) {
129 return wrap(new GlobalVariable(*unwrap(M),
132 GlobalValue::PrivateLinkage,
136 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
137 return wrap(Type::getMetadataTy(*unwrap(C)));
140 static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
143 return Attribute::AlwaysInline;
145 return Attribute::ByVal;
147 return Attribute::Cold;
149 return Attribute::InlineHint;
151 return Attribute::MinSize;
153 return Attribute::Naked;
155 return Attribute::NoAlias;
157 return Attribute::NoCapture;
159 return Attribute::NoInline;
161 return Attribute::NonNull;
163 return Attribute::NoRedZone;
165 return Attribute::NoReturn;
167 return Attribute::NoUnwind;
168 case OptimizeForSize:
169 return Attribute::OptimizeForSize;
171 return Attribute::ReadOnly;
173 return Attribute::SExt;
175 return Attribute::StructRet;
177 return Attribute::UWTable;
179 return Attribute::ZExt;
181 return Attribute::InReg;
183 return Attribute::SanitizeThread;
184 case SanitizeAddress:
185 return Attribute::SanitizeAddress;
187 return Attribute::SanitizeMemory;
189 return Attribute::NonLazyBind;
191 return Attribute::OptimizeNone;
193 return Attribute::ReturnsTwice;
195 return Attribute::ReadNone;
196 case InaccessibleMemOnly:
197 return Attribute::InaccessibleMemOnly;
198 case SanitizeHWAddress:
199 return Attribute::SanitizeHWAddress;
201 return Attribute::WillReturn;
203 report_fatal_error("bad AttributeKind");
206 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
207 LLVMRustAttribute RustAttr) {
208 CallBase *Call = unwrap<CallBase>(Instr);
209 Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
210 Call->addAttribute(Index, Attr);
213 extern "C" void LLVMRustAddCallSiteAttrString(LLVMValueRef Instr, unsigned Index,
215 CallBase *Call = unwrap<CallBase>(Instr);
216 Attribute Attr = Attribute::get(Call->getContext(), Name);
217 Call->addAttribute(Index, Attr);
221 extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
224 CallBase *Call = unwrap<CallBase>(Instr);
226 B.addAlignmentAttr(Bytes);
227 Call->setAttributes(Call->getAttributes().addAttributes(
228 Call->getContext(), Index, B));
231 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
234 CallBase *Call = unwrap<CallBase>(Instr);
236 B.addDereferenceableAttr(Bytes);
237 Call->setAttributes(Call->getAttributes().addAttributes(
238 Call->getContext(), Index, B));
241 extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
244 CallBase *Call = unwrap<CallBase>(Instr);
246 B.addDereferenceableOrNullAttr(Bytes);
247 Call->setAttributes(Call->getAttributes().addAttributes(
248 Call->getContext(), Index, B));
251 extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index,
253 CallBase *Call = unwrap<CallBase>(Instr);
254 Attribute Attr = Attribute::getWithByValType(Call->getContext(), unwrap(Ty));
255 Call->addAttribute(Index, Attr);
258 extern "C" void LLVMRustAddStructRetCallSiteAttr(LLVMValueRef Instr, unsigned Index,
260 CallBase *Call = unwrap<CallBase>(Instr);
261 #if LLVM_VERSION_GE(12, 0)
262 Attribute Attr = Attribute::getWithStructRetType(Call->getContext(), unwrap(Ty));
264 Attribute Attr = Attribute::get(Call->getContext(), Attribute::StructRet);
266 Call->addAttribute(Index, Attr);
269 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
270 LLVMRustAttribute RustAttr) {
271 Function *A = unwrap<Function>(Fn);
272 Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
274 A->addAttributes(Index, B);
277 extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn,
280 Function *A = unwrap<Function>(Fn);
282 B.addAlignmentAttr(Bytes);
283 A->addAttributes(Index, B);
286 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
288 Function *A = unwrap<Function>(Fn);
290 B.addDereferenceableAttr(Bytes);
291 A->addAttributes(Index, B);
294 extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
297 Function *A = unwrap<Function>(Fn);
299 B.addDereferenceableOrNullAttr(Bytes);
300 A->addAttributes(Index, B);
303 extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index,
305 Function *F = unwrap<Function>(Fn);
306 Attribute Attr = Attribute::getWithByValType(F->getContext(), unwrap(Ty));
307 F->addAttribute(Index, Attr);
310 extern "C" void LLVMRustAddStructRetAttr(LLVMValueRef Fn, unsigned Index,
312 Function *F = unwrap<Function>(Fn);
313 #if LLVM_VERSION_GE(12, 0)
314 Attribute Attr = Attribute::getWithStructRetType(F->getContext(), unwrap(Ty));
316 Attribute Attr = Attribute::get(F->getContext(), Attribute::StructRet);
318 F->addAttribute(Index, Attr);
321 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
325 Function *F = unwrap<Function>(Fn);
327 B.addAttribute(Name, Value);
328 F->addAttributes(Index, B);
331 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
333 LLVMRustAttribute RustAttr) {
334 Function *F = unwrap<Function>(Fn);
335 Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
337 auto PAL = F->getAttributes();
338 auto PALNew = PAL.removeAttributes(F->getContext(), Index, B);
339 F->setAttributes(PALNew);
342 // Enable a fast-math flag
344 // https://llvm.org/docs/LangRef.html#fast-math-flags
345 extern "C" void LLVMRustSetFastMath(LLVMValueRef V) {
346 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
351 extern "C" LLVMValueRef
352 LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Source,
353 const char *Name, LLVMAtomicOrdering Order) {
354 Value *Ptr = unwrap(Source);
355 LoadInst *LI = unwrap(B)->CreateLoad(unwrap(Ty), Ptr, Name);
356 LI->setAtomic(fromRust(Order));
360 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
363 LLVMAtomicOrdering Order) {
364 StoreInst *SI = unwrap(B)->CreateStore(unwrap(V), unwrap(Target));
365 SI->setAtomic(fromRust(Order));
369 // FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak
370 // once we raise our minimum support to LLVM 10.
371 extern "C" LLVMValueRef
372 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
373 LLVMValueRef Old, LLVMValueRef Source,
374 LLVMAtomicOrdering Order,
375 LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
376 #if LLVM_VERSION_GE(13,0)
377 // Rust probably knows the alignment of the target value and should be able to
378 // specify something more precise than MaybeAlign here. See also
379 // https://reviews.llvm.org/D97224 which may be a useful reference.
380 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
381 unwrap(Target), unwrap(Old), unwrap(Source), llvm::MaybeAlign(), fromRust(Order),
382 fromRust(FailureOrder));
384 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
385 unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
386 fromRust(FailureOrder));
392 enum class LLVMRustSynchronizationScope {
397 static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
399 case LLVMRustSynchronizationScope::SingleThread:
400 return SyncScope::SingleThread;
401 case LLVMRustSynchronizationScope::CrossThread:
402 return SyncScope::System;
404 report_fatal_error("bad SynchronizationScope.");
408 extern "C" LLVMValueRef
409 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
410 LLVMRustSynchronizationScope Scope) {
411 return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
414 enum class LLVMRustAsmDialect {
419 static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
421 case LLVMRustAsmDialect::Att:
422 return InlineAsm::AD_ATT;
423 case LLVMRustAsmDialect::Intel:
424 return InlineAsm::AD_Intel;
426 report_fatal_error("bad AsmDialect.");
430 extern "C" LLVMValueRef
431 LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
432 char *Constraints, size_t ConstraintsLen,
433 LLVMBool HasSideEffects, LLVMBool IsAlignStack,
434 LLVMRustAsmDialect Dialect) {
435 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
436 StringRef(AsmString, AsmStringLen),
437 StringRef(Constraints, ConstraintsLen),
438 HasSideEffects, IsAlignStack, fromRust(Dialect)));
441 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
442 size_t ConstraintsLen) {
443 return InlineAsm::Verify(unwrap<FunctionType>(Ty),
444 StringRef(Constraints, ConstraintsLen));
447 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
449 unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen));
452 typedef DIBuilder *LLVMRustDIBuilderRef;
454 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
455 return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
458 #define DIDescriptor DIScope
459 #define DIArray DINodeArray
460 #define unwrapDI unwrapDIPtr
462 // These values **must** match debuginfo::DIFlags! They also *happen*
463 // to match LLVM, but that isn't required as we do giant sets of
464 // matching below. The value shouldn't be directly passed to LLVM.
465 enum class LLVMRustDIFlags : uint32_t {
470 FlagFwdDecl = (1 << 2),
471 FlagAppleBlock = (1 << 3),
472 FlagBlockByrefStruct = (1 << 4),
473 FlagVirtual = (1 << 5),
474 FlagArtificial = (1 << 6),
475 FlagExplicit = (1 << 7),
476 FlagPrototyped = (1 << 8),
477 FlagObjcClassComplete = (1 << 9),
478 FlagObjectPointer = (1 << 10),
479 FlagVector = (1 << 11),
480 FlagStaticMember = (1 << 12),
481 FlagLValueReference = (1 << 13),
482 FlagRValueReference = (1 << 14),
483 FlagExternalTypeRef = (1 << 15),
484 FlagIntroducedVirtual = (1 << 18),
485 FlagBitField = (1 << 19),
486 FlagNoReturn = (1 << 20),
487 // Do not add values that are not supported by the minimum LLVM
488 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
491 inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
492 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
493 static_cast<uint32_t>(B));
496 inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
497 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
498 static_cast<uint32_t>(B));
501 inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
505 inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
507 inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
508 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
511 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
512 DINode::DIFlags Result = DINode::DIFlags::FlagZero;
514 switch (visibility(Flags)) {
515 case LLVMRustDIFlags::FlagPrivate:
516 Result |= DINode::DIFlags::FlagPrivate;
518 case LLVMRustDIFlags::FlagProtected:
519 Result |= DINode::DIFlags::FlagProtected;
521 case LLVMRustDIFlags::FlagPublic:
522 Result |= DINode::DIFlags::FlagPublic;
525 // The rest are handled below
529 if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
530 Result |= DINode::DIFlags::FlagFwdDecl;
532 if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
533 Result |= DINode::DIFlags::FlagAppleBlock;
535 if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
536 Result |= DINode::DIFlags::FlagVirtual;
538 if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
539 Result |= DINode::DIFlags::FlagArtificial;
541 if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
542 Result |= DINode::DIFlags::FlagExplicit;
544 if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
545 Result |= DINode::DIFlags::FlagPrototyped;
547 if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
548 Result |= DINode::DIFlags::FlagObjcClassComplete;
550 if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
551 Result |= DINode::DIFlags::FlagObjectPointer;
553 if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
554 Result |= DINode::DIFlags::FlagVector;
556 if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
557 Result |= DINode::DIFlags::FlagStaticMember;
559 if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
560 Result |= DINode::DIFlags::FlagLValueReference;
562 if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
563 Result |= DINode::DIFlags::FlagRValueReference;
565 if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
566 Result |= DINode::DIFlags::FlagIntroducedVirtual;
568 if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
569 Result |= DINode::DIFlags::FlagBitField;
571 if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
572 Result |= DINode::DIFlags::FlagNoReturn;
578 // These values **must** match debuginfo::DISPFlags! They also *happen*
579 // to match LLVM, but that isn't required as we do giant sets of
580 // matching below. The value shouldn't be directly passed to LLVM.
581 enum class LLVMRustDISPFlags : uint32_t {
584 SPFlagPureVirtual = 2,
585 SPFlagLocalToUnit = (1 << 2),
586 SPFlagDefinition = (1 << 3),
587 SPFlagOptimized = (1 << 4),
588 SPFlagMainSubprogram = (1 << 5),
589 // Do not add values that are not supported by the minimum LLVM
590 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
591 // (In LLVM < 8, createFunction supported these as separate bool arguments.)
594 inline LLVMRustDISPFlags operator&(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
595 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) &
596 static_cast<uint32_t>(B));
599 inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
600 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) |
601 static_cast<uint32_t>(B));
604 inline LLVMRustDISPFlags &operator|=(LLVMRustDISPFlags &A, LLVMRustDISPFlags B) {
608 inline bool isSet(LLVMRustDISPFlags F) { return F != LLVMRustDISPFlags::SPFlagZero; }
610 inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) {
611 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(F) & 0x3);
614 static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) {
615 DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero;
617 switch (virtuality(SPFlags)) {
618 case LLVMRustDISPFlags::SPFlagVirtual:
619 Result |= DISubprogram::DISPFlags::SPFlagVirtual;
621 case LLVMRustDISPFlags::SPFlagPureVirtual:
622 Result |= DISubprogram::DISPFlags::SPFlagPureVirtual;
625 // The rest are handled below
629 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit)) {
630 Result |= DISubprogram::DISPFlags::SPFlagLocalToUnit;
632 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition)) {
633 Result |= DISubprogram::DISPFlags::SPFlagDefinition;
635 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) {
636 Result |= DISubprogram::DISPFlags::SPFlagOptimized;
638 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) {
639 Result |= DISubprogram::DISPFlags::SPFlagMainSubprogram;
645 enum class LLVMRustDebugEmissionKind {
651 static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
653 case LLVMRustDebugEmissionKind::NoDebug:
654 return DICompileUnit::DebugEmissionKind::NoDebug;
655 case LLVMRustDebugEmissionKind::FullDebug:
656 return DICompileUnit::DebugEmissionKind::FullDebug;
657 case LLVMRustDebugEmissionKind::LineTablesOnly:
658 return DICompileUnit::DebugEmissionKind::LineTablesOnly;
660 report_fatal_error("bad DebugEmissionKind.");
664 enum class LLVMRustChecksumKind {
671 static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
673 case LLVMRustChecksumKind::None:
675 case LLVMRustChecksumKind::MD5:
676 return DIFile::ChecksumKind::CSK_MD5;
677 case LLVMRustChecksumKind::SHA1:
678 return DIFile::ChecksumKind::CSK_SHA1;
679 #if (LLVM_VERSION_MAJOR >= 11)
680 case LLVMRustChecksumKind::SHA256:
681 return DIFile::ChecksumKind::CSK_SHA256;
684 report_fatal_error("bad ChecksumKind.");
688 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
689 return DEBUG_METADATA_VERSION;
692 extern "C" uint32_t LLVMRustVersionPatch() { return LLVM_VERSION_PATCH; }
694 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
696 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
698 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
700 unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
703 extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
704 return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
707 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
708 return new DIBuilder(*unwrap(M));
711 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
715 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
719 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
720 LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
721 const char *Producer, size_t ProducerLen, bool isOptimized,
722 const char *Flags, unsigned RuntimeVer,
723 const char *SplitName, size_t SplitNameLen,
724 LLVMRustDebugEmissionKind Kind,
725 uint64_t DWOId, bool SplitDebugInlining) {
726 auto *File = unwrapDI<DIFile>(FileRef);
728 return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
729 isOptimized, Flags, RuntimeVer,
730 StringRef(SplitName, SplitNameLen),
731 fromRust(Kind), DWOId, SplitDebugInlining));
734 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
735 LLVMRustDIBuilderRef Builder,
736 const char *Filename, size_t FilenameLen,
737 const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
738 const char *Checksum, size_t ChecksumLen) {
739 Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
740 Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
742 CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
743 return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
744 StringRef(Directory, DirectoryLen),
748 extern "C" LLVMMetadataRef
749 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
750 LLVMMetadataRef ParameterTypes) {
751 return wrap(Builder->createSubroutineType(
752 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
755 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
756 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
757 const char *Name, size_t NameLen,
758 const char *LinkageName, size_t LinkageNameLen,
759 LLVMMetadataRef File, unsigned LineNo,
760 LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
761 LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam,
762 LLVMMetadataRef Decl) {
763 DITemplateParameterArray TParams =
764 DITemplateParameterArray(unwrap<MDTuple>(TParam));
765 DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
766 DINode::DIFlags llvmFlags = fromRust(Flags);
767 DISubprogram *Sub = Builder->createFunction(
768 unwrapDI<DIScope>(Scope),
769 StringRef(Name, NameLen),
770 StringRef(LinkageName, LinkageNameLen),
771 unwrapDI<DIFile>(File), LineNo,
772 unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
773 llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
775 unwrap<Function>(MaybeFn)->setSubprogram(Sub);
779 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
780 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
781 uint64_t SizeInBits, unsigned Encoding) {
782 return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
785 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
786 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
787 LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
788 return wrap(Builder->createTypedef(
789 unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
790 LineNo, unwrapDIPtr<DIScope>(Scope)));
793 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
794 LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
795 uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
796 const char *Name, size_t NameLen) {
797 return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
798 SizeInBits, AlignInBits,
800 StringRef(Name, NameLen)));
803 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
804 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
805 const char *Name, size_t NameLen,
806 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
807 uint32_t AlignInBits, LLVMRustDIFlags Flags,
808 LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
809 unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
810 const char *UniqueId, size_t UniqueIdLen) {
811 return wrap(Builder->createStructType(
812 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
813 unwrapDI<DIFile>(File), LineNumber,
814 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
815 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
816 unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen)));
819 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
820 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
821 const char *Name, size_t NameLen,
822 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
823 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
824 LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) {
825 return wrap(Builder->createVariantPart(
826 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
827 unwrapDI<DIFile>(File), LineNumber,
828 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
829 DINodeArray(unwrapDI<MDTuple>(Elements)), StringRef(UniqueId, UniqueIdLen)));
832 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
833 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
834 const char *Name, size_t NameLen,
835 LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
836 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
837 LLVMMetadataRef Ty) {
838 return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope),
839 StringRef(Name, NameLen),
840 unwrapDI<DIFile>(File), LineNo,
841 SizeInBits, AlignInBits, OffsetInBits,
842 fromRust(Flags), unwrapDI<DIType>(Ty)));
845 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
846 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
847 const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
848 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
849 LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
850 llvm::ConstantInt* D = nullptr;
852 D = unwrap<llvm::ConstantInt>(Discriminant);
854 return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope),
855 StringRef(Name, NameLen),
856 unwrapDI<DIFile>(File), LineNo,
857 SizeInBits, AlignInBits, OffsetInBits, D,
858 fromRust(Flags), unwrapDI<DIType>(Ty)));
861 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
862 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
863 LLVMMetadataRef File, unsigned Line, unsigned Col) {
864 return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
865 unwrapDI<DIFile>(File), Line, Col));
868 extern "C" LLVMMetadataRef
869 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
870 LLVMMetadataRef Scope,
871 LLVMMetadataRef File) {
872 return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
873 unwrapDI<DIFile>(File)));
876 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
877 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context,
878 const char *Name, size_t NameLen,
879 const char *LinkageName, size_t LinkageNameLen,
880 LLVMMetadataRef File, unsigned LineNo,
881 LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
882 LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
883 llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
885 llvm::DIExpression *InitExpr = nullptr;
886 if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
887 InitExpr = Builder->createConstantValueExpression(
888 IntVal->getValue().getSExtValue());
889 } else if (llvm::ConstantFP *FPVal =
890 llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
891 InitExpr = Builder->createConstantValueExpression(
892 FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
895 llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
896 unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
897 StringRef(LinkageName, LinkageNameLen),
898 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
899 /* isDefined */ true,
900 InitExpr, unwrapDIPtr<MDNode>(Decl),
901 /* templateParams */ nullptr,
904 InitVal->setMetadata("dbg", VarExpr);
906 return wrap(VarExpr);
909 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
910 LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
911 const char *Name, size_t NameLen,
912 LLVMMetadataRef File, unsigned LineNo,
913 LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
914 unsigned ArgNo, uint32_t AlignInBits) {
915 if (Tag == 0x100) { // DW_TAG_auto_variable
916 return wrap(Builder->createAutoVariable(
917 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
918 unwrapDI<DIFile>(File), LineNo,
919 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
921 return wrap(Builder->createParameterVariable(
922 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
923 unwrapDI<DIFile>(File), LineNo,
924 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
928 extern "C" LLVMMetadataRef
929 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
930 uint32_t AlignInBits, LLVMMetadataRef Ty,
931 LLVMMetadataRef Subscripts) {
933 Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
934 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
937 extern "C" LLVMMetadataRef
938 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
940 return wrap(Builder->getOrCreateSubrange(Lo, Count));
943 extern "C" LLVMMetadataRef
944 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
945 LLVMMetadataRef *Ptr, unsigned Count) {
946 Metadata **DataValue = unwrap(Ptr);
948 Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
951 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
952 LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
953 int64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
954 LLVMBasicBlockRef InsertAtEnd) {
955 return wrap(Builder->insertDeclare(
956 unwrap(V), unwrap<DILocalVariable>(VarInfo),
957 Builder->createExpression(llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
958 DebugLoc(cast<MDNode>(unwrap(DL))),
959 unwrap(InsertAtEnd)));
962 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
963 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
964 int64_t Value, bool IsUnsigned) {
965 return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
968 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
969 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
970 const char *Name, size_t NameLen,
971 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
972 uint32_t AlignInBits, LLVMMetadataRef Elements,
973 LLVMMetadataRef ClassTy, bool IsScoped) {
974 return wrap(Builder->createEnumerationType(
975 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
976 unwrapDI<DIFile>(File), LineNumber,
977 SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
978 unwrapDI<DIType>(ClassTy), "", IsScoped));
981 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
982 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
983 const char *Name, size_t NameLen,
984 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
985 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
986 unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) {
987 return wrap(Builder->createUnionType(
988 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File),
989 LineNumber, SizeInBits, AlignInBits, fromRust(Flags),
990 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
991 StringRef(UniqueId, UniqueIdLen)));
994 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
995 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
996 const char *Name, size_t NameLen, LLVMMetadataRef Ty) {
997 #if LLVM_VERSION_GE(11, 0)
998 bool IsDefault = false; // FIXME: should we ever set this true?
999 return wrap(Builder->createTemplateTypeParameter(
1000 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty), IsDefault));
1002 return wrap(Builder->createTemplateTypeParameter(
1003 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty)));
1007 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateNameSpace(
1008 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1009 const char *Name, size_t NameLen, bool ExportSymbols) {
1010 return wrap(Builder->createNameSpace(
1011 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols
1016 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
1017 LLVMMetadataRef CompositeTy,
1018 LLVMMetadataRef Elements,
1019 LLVMMetadataRef Params) {
1020 DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
1021 Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
1022 DINodeArray(unwrap<MDTuple>(Params)));
1025 extern "C" LLVMMetadataRef
1026 LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
1027 LLVMMetadataRef ScopeRef,
1028 LLVMMetadataRef InlinedAt) {
1029 #if LLVM_VERSION_GE(12, 0)
1030 MDNode *Scope = unwrapDIPtr<MDNode>(ScopeRef);
1031 DILocation *Loc = DILocation::get(
1032 Scope->getContext(), Line, Column, Scope,
1033 unwrapDIPtr<MDNode>(InlinedAt));
1036 DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(ScopeRef),
1037 unwrapDIPtr<MDNode>(InlinedAt));
1038 return wrap(debug_loc.getAsMDNode());
1042 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
1043 return dwarf::DW_OP_deref;
1046 extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1047 return dwarf::DW_OP_plus_uconst;
1050 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
1051 RawRustStringOstream OS(Str);
1052 unwrap<llvm::Type>(Ty)->print(OS);
1055 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
1056 RustStringRef Str) {
1057 RawRustStringOstream OS(Str);
1062 unwrap<llvm::Value>(V)->getType()->print(OS);
1064 unwrap<llvm::Value>(V)->print(OS);
1069 // LLVMArrayType function does not support 64-bit ElementCount
1070 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
1071 uint64_t ElementCount) {
1072 return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
1075 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1077 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
1078 RawRustStringOstream OS(Str);
1079 unwrap(T)->print(OS);
1082 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1083 LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
1084 LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
1085 RustStringRef FilenameOut, RustStringRef MessageOut) {
1086 // Undefined to call this not on an optimization diagnostic!
1087 llvm::DiagnosticInfoOptimizationBase *Opt =
1088 static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
1090 RawRustStringOstream PassNameOS(PassNameOut);
1091 PassNameOS << Opt->getPassName();
1092 *FunctionOut = wrap(&Opt->getFunction());
1094 RawRustStringOstream FilenameOS(FilenameOut);
1095 DiagnosticLocation loc = Opt->getLocation();
1096 if (loc.isValid()) {
1097 *Line = loc.getLine();
1098 *Column = loc.getColumn();
1099 FilenameOS << loc.getAbsolutePath();
1102 RawRustStringOstream MessageOS(MessageOut);
1103 MessageOS << Opt->getMsg();
1106 enum class LLVMRustDiagnosticLevel {
1114 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
1115 LLVMRustDiagnosticLevel *LevelOut,
1116 unsigned *CookieOut,
1117 LLVMTwineRef *MessageOut,
1118 LLVMValueRef *InstructionOut) {
1119 // Undefined to call this not on an inline assembly diagnostic!
1120 llvm::DiagnosticInfoInlineAsm *IA =
1121 static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
1123 *CookieOut = IA->getLocCookie();
1124 *MessageOut = wrap(&IA->getMsgStr());
1125 *InstructionOut = wrap(IA->getInstruction());
1127 switch (IA->getSeverity()) {
1129 *LevelOut = LLVMRustDiagnosticLevel::Error;
1132 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1135 *LevelOut = LLVMRustDiagnosticLevel::Note;
1138 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1141 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1145 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
1146 RustStringRef Str) {
1147 RawRustStringOstream OS(Str);
1148 DiagnosticPrinterRawOStream DP(OS);
1149 unwrap(DI)->print(DP);
1152 enum class LLVMRustDiagnosticKind {
1156 DebugMetadataVersion,
1159 OptimizationRemarkMissed,
1160 OptimizationRemarkAnalysis,
1161 OptimizationRemarkAnalysisFPCommute,
1162 OptimizationRemarkAnalysisAliasing,
1163 OptimizationRemarkOther,
1164 OptimizationFailure,
1170 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1173 return LLVMRustDiagnosticKind::InlineAsm;
1175 return LLVMRustDiagnosticKind::StackSize;
1176 case DK_DebugMetadataVersion:
1177 return LLVMRustDiagnosticKind::DebugMetadataVersion;
1178 case DK_SampleProfile:
1179 return LLVMRustDiagnosticKind::SampleProfile;
1180 case DK_OptimizationRemark:
1181 return LLVMRustDiagnosticKind::OptimizationRemark;
1182 case DK_OptimizationRemarkMissed:
1183 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1184 case DK_OptimizationRemarkAnalysis:
1185 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1186 case DK_OptimizationRemarkAnalysisFPCommute:
1187 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1188 case DK_OptimizationRemarkAnalysisAliasing:
1189 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1191 return LLVMRustDiagnosticKind::PGOProfile;
1193 return LLVMRustDiagnosticKind::Linker;
1194 case DK_Unsupported:
1195 return LLVMRustDiagnosticKind::Unsupported;
1197 return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1198 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1199 : LLVMRustDiagnosticKind::Other;
1203 extern "C" LLVMRustDiagnosticKind
1204 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1205 return toRust((DiagnosticKind)unwrap(DI)->getKind());
1208 // This is kept distinct from LLVMGetTypeKind, because when
1209 // a new type kind is added, the Rust-side enum must be
1210 // updated or UB will result.
1211 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1212 switch (unwrap(Ty)->getTypeID()) {
1213 case Type::VoidTyID:
1214 return LLVMVoidTypeKind;
1215 case Type::HalfTyID:
1216 return LLVMHalfTypeKind;
1217 case Type::FloatTyID:
1218 return LLVMFloatTypeKind;
1219 case Type::DoubleTyID:
1220 return LLVMDoubleTypeKind;
1221 case Type::X86_FP80TyID:
1222 return LLVMX86_FP80TypeKind;
1223 case Type::FP128TyID:
1224 return LLVMFP128TypeKind;
1225 case Type::PPC_FP128TyID:
1226 return LLVMPPC_FP128TypeKind;
1227 case Type::LabelTyID:
1228 return LLVMLabelTypeKind;
1229 case Type::MetadataTyID:
1230 return LLVMMetadataTypeKind;
1231 case Type::IntegerTyID:
1232 return LLVMIntegerTypeKind;
1233 case Type::FunctionTyID:
1234 return LLVMFunctionTypeKind;
1235 case Type::StructTyID:
1236 return LLVMStructTypeKind;
1237 case Type::ArrayTyID:
1238 return LLVMArrayTypeKind;
1239 case Type::PointerTyID:
1240 return LLVMPointerTypeKind;
1241 #if LLVM_VERSION_GE(11, 0)
1242 case Type::FixedVectorTyID:
1243 return LLVMVectorTypeKind;
1245 case Type::VectorTyID:
1246 return LLVMVectorTypeKind;
1248 case Type::X86_MMXTyID:
1249 return LLVMX86_MMXTypeKind;
1250 case Type::TokenTyID:
1251 return LLVMTokenTypeKind;
1252 #if LLVM_VERSION_GE(11, 0)
1253 case Type::ScalableVectorTyID:
1254 return LLVMScalableVectorTypeKind;
1255 case Type::BFloatTyID:
1256 return LLVMBFloatTypeKind;
1258 #if LLVM_VERSION_GE(12, 0)
1259 case Type::X86_AMXTyID:
1260 return LLVMX86_AMXTypeKind;
1263 report_fatal_error("Unhandled TypeID.");
1266 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1268 #if LLVM_VERSION_LT(13, 0)
1269 using LLVMInlineAsmDiagHandlerTy = LLVMContext::InlineAsmDiagHandlerTy;
1271 using LLVMInlineAsmDiagHandlerTy = void*;
1274 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1275 LLVMContextRef C, LLVMInlineAsmDiagHandlerTy H, void *CX) {
1276 // Diagnostic handlers were unified in LLVM change 5de2d189e6ad, so starting
1277 // with LLVM 13 this function is gone.
1278 #if LLVM_VERSION_LT(13, 0)
1279 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1283 extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
1284 RustStringRef MessageOut,
1285 RustStringRef BufferOut,
1286 LLVMRustDiagnosticLevel* LevelOut,
1288 unsigned* RangesOut,
1289 size_t* NumRanges) {
1290 SMDiagnostic& D = *unwrap(DRef);
1291 RawRustStringOstream MessageOS(MessageOut);
1292 MessageOS << D.getMessage();
1294 switch (D.getKind()) {
1295 case SourceMgr::DK_Error:
1296 *LevelOut = LLVMRustDiagnosticLevel::Error;
1298 case SourceMgr::DK_Warning:
1299 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1301 case SourceMgr::DK_Note:
1302 *LevelOut = LLVMRustDiagnosticLevel::Note;
1304 case SourceMgr::DK_Remark:
1305 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1308 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1311 if (D.getLoc() == SMLoc())
1314 const SourceMgr &LSM = *D.getSourceMgr();
1315 const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
1316 LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), LBuf->getBufferSize());
1318 *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
1320 *NumRanges = std::min(*NumRanges, D.getRanges().size());
1321 size_t LineStart = *LocOut - (size_t)D.getColumnNo();
1322 for (size_t i = 0; i < *NumRanges; i++) {
1323 RangesOut[i * 2] = LineStart + D.getRanges()[i].first;
1324 RangesOut[i * 2 + 1] = LineStart + D.getRanges()[i].second;
1330 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1331 LLVMValueRef ParentPad,
1333 LLVMValueRef *LLArgs,
1335 Value **Args = unwrap(LLArgs);
1336 if (ParentPad == nullptr) {
1337 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1338 ParentPad = wrap(Constant::getNullValue(Ty));
1340 return wrap(unwrap(B)->CreateCleanupPad(
1341 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1344 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1345 LLVMValueRef CleanupPad,
1346 LLVMBasicBlockRef UnwindBB) {
1347 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1348 return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1351 extern "C" LLVMValueRef
1352 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1353 unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1354 Value **Args = unwrap(LLArgs);
1355 return wrap(unwrap(B)->CreateCatchPad(
1356 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1359 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1361 LLVMBasicBlockRef BB) {
1362 return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1366 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1367 LLVMValueRef ParentPad,
1368 LLVMBasicBlockRef BB,
1369 unsigned NumHandlers,
1371 if (ParentPad == nullptr) {
1372 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1373 ParentPad = wrap(Constant::getNullValue(Ty));
1375 return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1376 NumHandlers, Name));
1379 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1380 LLVMBasicBlockRef Handler) {
1381 Value *CatchSwitch = unwrap(CatchSwitchRef);
1382 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1385 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1386 LLVMValueRef *Inputs,
1387 unsigned NumInputs) {
1388 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1391 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1395 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
1396 LLVMValueRef *Args, unsigned NumArgs,
1397 OperandBundleDef *Bundle) {
1398 Value *Callee = unwrap(Fn);
1399 FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1400 unsigned Len = Bundle ? 1 : 0;
1401 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1402 return wrap(unwrap(B)->CreateCall(
1403 FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles));
1406 extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
1407 return wrap(llvm::Intrinsic::getDeclaration(unwrap(M),
1408 (llvm::Intrinsic::ID)llvm::Intrinsic::instrprof_increment));
1411 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
1412 LLVMValueRef Dst, unsigned DstAlign,
1413 LLVMValueRef Src, unsigned SrcAlign,
1414 LLVMValueRef Size, bool IsVolatile) {
1415 return wrap(unwrap(B)->CreateMemCpy(
1416 unwrap(Dst), MaybeAlign(DstAlign),
1417 unwrap(Src), MaybeAlign(SrcAlign),
1418 unwrap(Size), IsVolatile));
1421 extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
1422 LLVMValueRef Dst, unsigned DstAlign,
1423 LLVMValueRef Src, unsigned SrcAlign,
1424 LLVMValueRef Size, bool IsVolatile) {
1425 return wrap(unwrap(B)->CreateMemMove(
1426 unwrap(Dst), MaybeAlign(DstAlign),
1427 unwrap(Src), MaybeAlign(SrcAlign),
1428 unwrap(Size), IsVolatile));
1431 extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
1432 LLVMValueRef Dst, unsigned DstAlign,
1434 LLVMValueRef Size, bool IsVolatile) {
1435 return wrap(unwrap(B)->CreateMemSet(
1436 unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
1439 extern "C" LLVMValueRef
1440 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
1441 unsigned NumArgs, LLVMBasicBlockRef Then,
1442 LLVMBasicBlockRef Catch, OperandBundleDef *Bundle,
1444 Value *Callee = unwrap(Fn);
1445 FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1446 unsigned Len = Bundle ? 1 : 0;
1447 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1448 return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
1449 makeArrayRef(unwrap(Args), NumArgs),
1453 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1454 LLVMBasicBlockRef BB) {
1455 auto Point = unwrap(BB)->getFirstInsertionPt();
1456 unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1459 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1460 const char *Name, size_t NameLen) {
1461 Triple TargetTriple(unwrap(M)->getTargetTriple());
1462 GlobalObject *GV = unwrap<GlobalObject>(V);
1463 if (TargetTriple.supportsCOMDAT()) {
1464 StringRef NameRef(Name, NameLen);
1465 GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
1469 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1470 GlobalObject *GV = unwrap<GlobalObject>(V);
1471 GV->setComdat(nullptr);
1474 enum class LLVMRustLinkage {
1475 ExternalLinkage = 0,
1476 AvailableExternallyLinkage = 1,
1477 LinkOnceAnyLinkage = 2,
1478 LinkOnceODRLinkage = 3,
1481 AppendingLinkage = 6,
1482 InternalLinkage = 7,
1484 ExternalWeakLinkage = 9,
1488 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1490 case LLVMExternalLinkage:
1491 return LLVMRustLinkage::ExternalLinkage;
1492 case LLVMAvailableExternallyLinkage:
1493 return LLVMRustLinkage::AvailableExternallyLinkage;
1494 case LLVMLinkOnceAnyLinkage:
1495 return LLVMRustLinkage::LinkOnceAnyLinkage;
1496 case LLVMLinkOnceODRLinkage:
1497 return LLVMRustLinkage::LinkOnceODRLinkage;
1498 case LLVMWeakAnyLinkage:
1499 return LLVMRustLinkage::WeakAnyLinkage;
1500 case LLVMWeakODRLinkage:
1501 return LLVMRustLinkage::WeakODRLinkage;
1502 case LLVMAppendingLinkage:
1503 return LLVMRustLinkage::AppendingLinkage;
1504 case LLVMInternalLinkage:
1505 return LLVMRustLinkage::InternalLinkage;
1506 case LLVMPrivateLinkage:
1507 return LLVMRustLinkage::PrivateLinkage;
1508 case LLVMExternalWeakLinkage:
1509 return LLVMRustLinkage::ExternalWeakLinkage;
1510 case LLVMCommonLinkage:
1511 return LLVMRustLinkage::CommonLinkage;
1513 report_fatal_error("Invalid LLVMRustLinkage value!");
1517 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1519 case LLVMRustLinkage::ExternalLinkage:
1520 return LLVMExternalLinkage;
1521 case LLVMRustLinkage::AvailableExternallyLinkage:
1522 return LLVMAvailableExternallyLinkage;
1523 case LLVMRustLinkage::LinkOnceAnyLinkage:
1524 return LLVMLinkOnceAnyLinkage;
1525 case LLVMRustLinkage::LinkOnceODRLinkage:
1526 return LLVMLinkOnceODRLinkage;
1527 case LLVMRustLinkage::WeakAnyLinkage:
1528 return LLVMWeakAnyLinkage;
1529 case LLVMRustLinkage::WeakODRLinkage:
1530 return LLVMWeakODRLinkage;
1531 case LLVMRustLinkage::AppendingLinkage:
1532 return LLVMAppendingLinkage;
1533 case LLVMRustLinkage::InternalLinkage:
1534 return LLVMInternalLinkage;
1535 case LLVMRustLinkage::PrivateLinkage:
1536 return LLVMPrivateLinkage;
1537 case LLVMRustLinkage::ExternalWeakLinkage:
1538 return LLVMExternalWeakLinkage;
1539 case LLVMRustLinkage::CommonLinkage:
1540 return LLVMCommonLinkage;
1542 report_fatal_error("Invalid LLVMRustLinkage value!");
1545 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1546 return toRust(LLVMGetLinkage(V));
1549 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1550 LLVMRustLinkage RustLinkage) {
1551 LLVMSetLinkage(V, fromRust(RustLinkage));
1554 extern "C" LLVMValueRef LLVMRustConstInBoundsGEP2(LLVMTypeRef Ty,
1555 LLVMValueRef ConstantVal,
1556 LLVMValueRef *ConstantIndices,
1557 unsigned NumIndices) {
1558 ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
1560 Constant *Val = unwrap<Constant>(ConstantVal);
1561 return wrap(ConstantExpr::getInBoundsGetElementPtr(unwrap(Ty), Val, IdxList));
1564 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1565 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1566 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1568 auto C = unwrap<llvm::ConstantInt>(CV);
1569 if (C->getBitWidth() > 128) { return false; }
1572 AP = C->getValue().sextOrSelf(128);
1574 AP = C->getValue().zextOrSelf(128);
1576 *low = AP.getLoBits(64).getZExtValue();
1577 *high = AP.getHiBits(64).getZExtValue();
1581 enum class LLVMRustVisibility {
1587 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1589 case LLVMDefaultVisibility:
1590 return LLVMRustVisibility::Default;
1591 case LLVMHiddenVisibility:
1592 return LLVMRustVisibility::Hidden;
1593 case LLVMProtectedVisibility:
1594 return LLVMRustVisibility::Protected;
1596 report_fatal_error("Invalid LLVMRustVisibility value!");
1599 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1601 case LLVMRustVisibility::Default:
1602 return LLVMDefaultVisibility;
1603 case LLVMRustVisibility::Hidden:
1604 return LLVMHiddenVisibility;
1605 case LLVMRustVisibility::Protected:
1606 return LLVMProtectedVisibility;
1608 report_fatal_error("Invalid LLVMRustVisibility value!");
1611 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1612 return toRust(LLVMGetVisibility(V));
1615 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1616 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1617 LLVMTypeRef DestTy, bool isSigned) {
1618 return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1621 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1622 LLVMRustVisibility RustVisibility) {
1623 LLVMSetVisibility(V, fromRust(RustVisibility));
1626 extern "C" void LLVMRustSetDSOLocal(LLVMValueRef Global, bool is_dso_local) {
1627 unwrap<GlobalValue>(Global)->setDSOLocal(is_dso_local);
1630 struct LLVMRustModuleBuffer {
1634 extern "C" LLVMRustModuleBuffer*
1635 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1636 auto Ret = std::make_unique<LLVMRustModuleBuffer>();
1638 raw_string_ostream OS(Ret->data);
1640 legacy::PassManager PM;
1641 PM.add(createBitcodeWriterPass(OS));
1645 return Ret.release();
1649 LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1653 extern "C" const void*
1654 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1655 return Buffer->data.data();
1659 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1660 return Buffer->data.length();
1664 LLVMRustModuleCost(LLVMModuleRef M) {
1665 auto f = unwrap(M)->functions();
1666 return std::distance(std::begin(f), std::end(f));
1669 // Vector reductions:
1670 extern "C" LLVMValueRef
1671 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1672 return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1674 extern "C" LLVMValueRef
1675 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1676 return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1678 extern "C" LLVMValueRef
1679 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1680 return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1682 extern "C" LLVMValueRef
1683 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1684 return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1686 extern "C" LLVMValueRef
1687 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1688 return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1690 extern "C" LLVMValueRef
1691 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1692 return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1694 extern "C" LLVMValueRef
1695 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1696 return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1698 extern "C" LLVMValueRef
1699 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1700 return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1702 extern "C" LLVMValueRef
1703 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1704 return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1706 extern "C" LLVMValueRef
1707 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1708 #if LLVM_VERSION_GE(12, 0)
1709 Instruction *I = unwrap(B)->CreateFPMinReduce(unwrap(Src));
1710 I->setHasNoNaNs(NoNaN);
1713 return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN));
1716 extern "C" LLVMValueRef
1717 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1718 #if LLVM_VERSION_GE(12, 0)
1719 Instruction *I = unwrap(B)->CreateFPMaxReduce(unwrap(Src));
1720 I->setHasNoNaNs(NoNaN);
1723 return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN));
1727 extern "C" LLVMValueRef
1728 LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1729 return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1731 extern "C" LLVMValueRef
1732 LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1733 return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));
1736 // This struct contains all necessary info about a symbol exported from a DLL.
1737 // At the moment, it's just the symbol's name, but we use a separate struct to
1738 // make it easier to add other information like ordinal later.
1739 struct LLVMRustCOFFShortExport {
1743 // Machine must be a COFF machine type, as defined in PE specs.
1744 extern "C" LLVMRustResult LLVMRustWriteImportLibrary(
1745 const char* ImportName,
1747 const LLVMRustCOFFShortExport* Exports,
1752 std::vector<llvm::object::COFFShortExport> ConvertedExports;
1753 ConvertedExports.reserve(NumExports);
1755 for (size_t i = 0; i < NumExports; ++i) {
1756 ConvertedExports.push_back(llvm::object::COFFShortExport{
1757 Exports[i].name, // Name
1758 std::string{}, // ExtName
1759 std::string{}, // SymbolName
1760 std::string{}, // AliasTarget
1769 auto Error = llvm::object::writeImportLibrary(
1773 static_cast<llvm::COFF::MachineTypes>(Machine),
1776 std::string errorString;
1777 llvm::raw_string_ostream stream(errorString);
1780 LLVMRustSetLastError(errorString.c_str());
1781 return LLVMRustResult::Failure;
1783 return LLVMRustResult::Success;