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, LLVMValueRef Source, const char *Name,
353 LLVMAtomicOrdering Order) {
354 Value *Ptr = unwrap(Source);
355 Type *Ty = Ptr->getType()->getPointerElementType();
356 LoadInst *LI = unwrap(B)->CreateLoad(Ty, Ptr, Name);
357 LI->setAtomic(fromRust(Order));
361 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
364 LLVMAtomicOrdering Order) {
365 StoreInst *SI = unwrap(B)->CreateStore(unwrap(V), unwrap(Target));
366 SI->setAtomic(fromRust(Order));
370 // FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak
371 // once we raise our minimum support to LLVM 10.
372 extern "C" LLVMValueRef
373 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
374 LLVMValueRef Old, LLVMValueRef Source,
375 LLVMAtomicOrdering Order,
376 LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
377 #if LLVM_VERSION_GE(13,0)
378 // Rust probably knows the alignment of the target value and should be able to
379 // specify something more precise than MaybeAlign here. See also
380 // https://reviews.llvm.org/D97224 which may be a useful reference.
381 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
382 unwrap(Target), unwrap(Old), unwrap(Source), llvm::MaybeAlign(), fromRust(Order),
383 fromRust(FailureOrder));
385 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
386 unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
387 fromRust(FailureOrder));
393 enum class LLVMRustSynchronizationScope {
398 static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
400 case LLVMRustSynchronizationScope::SingleThread:
401 return SyncScope::SingleThread;
402 case LLVMRustSynchronizationScope::CrossThread:
403 return SyncScope::System;
405 report_fatal_error("bad SynchronizationScope.");
409 extern "C" LLVMValueRef
410 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
411 LLVMRustSynchronizationScope Scope) {
412 return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
415 enum class LLVMRustAsmDialect {
420 static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
422 case LLVMRustAsmDialect::Att:
423 return InlineAsm::AD_ATT;
424 case LLVMRustAsmDialect::Intel:
425 return InlineAsm::AD_Intel;
427 report_fatal_error("bad AsmDialect.");
431 extern "C" LLVMValueRef
432 LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
433 char *Constraints, size_t ConstraintsLen,
434 LLVMBool HasSideEffects, LLVMBool IsAlignStack,
435 LLVMRustAsmDialect Dialect) {
436 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
437 StringRef(AsmString, AsmStringLen),
438 StringRef(Constraints, ConstraintsLen),
439 HasSideEffects, IsAlignStack, fromRust(Dialect)));
442 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
443 size_t ConstraintsLen) {
444 return InlineAsm::Verify(unwrap<FunctionType>(Ty),
445 StringRef(Constraints, ConstraintsLen));
448 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
450 unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen));
453 typedef DIBuilder *LLVMRustDIBuilderRef;
455 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
456 return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
459 #define DIDescriptor DIScope
460 #define DIArray DINodeArray
461 #define unwrapDI unwrapDIPtr
463 // These values **must** match debuginfo::DIFlags! They also *happen*
464 // to match LLVM, but that isn't required as we do giant sets of
465 // matching below. The value shouldn't be directly passed to LLVM.
466 enum class LLVMRustDIFlags : uint32_t {
471 FlagFwdDecl = (1 << 2),
472 FlagAppleBlock = (1 << 3),
473 FlagBlockByrefStruct = (1 << 4),
474 FlagVirtual = (1 << 5),
475 FlagArtificial = (1 << 6),
476 FlagExplicit = (1 << 7),
477 FlagPrototyped = (1 << 8),
478 FlagObjcClassComplete = (1 << 9),
479 FlagObjectPointer = (1 << 10),
480 FlagVector = (1 << 11),
481 FlagStaticMember = (1 << 12),
482 FlagLValueReference = (1 << 13),
483 FlagRValueReference = (1 << 14),
484 FlagExternalTypeRef = (1 << 15),
485 FlagIntroducedVirtual = (1 << 18),
486 FlagBitField = (1 << 19),
487 FlagNoReturn = (1 << 20),
488 // Do not add values that are not supported by the minimum LLVM
489 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
492 inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
493 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
494 static_cast<uint32_t>(B));
497 inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
498 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
499 static_cast<uint32_t>(B));
502 inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
506 inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
508 inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
509 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
512 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
513 DINode::DIFlags Result = DINode::DIFlags::FlagZero;
515 switch (visibility(Flags)) {
516 case LLVMRustDIFlags::FlagPrivate:
517 Result |= DINode::DIFlags::FlagPrivate;
519 case LLVMRustDIFlags::FlagProtected:
520 Result |= DINode::DIFlags::FlagProtected;
522 case LLVMRustDIFlags::FlagPublic:
523 Result |= DINode::DIFlags::FlagPublic;
526 // The rest are handled below
530 if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
531 Result |= DINode::DIFlags::FlagFwdDecl;
533 if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
534 Result |= DINode::DIFlags::FlagAppleBlock;
536 if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
537 Result |= DINode::DIFlags::FlagVirtual;
539 if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
540 Result |= DINode::DIFlags::FlagArtificial;
542 if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
543 Result |= DINode::DIFlags::FlagExplicit;
545 if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
546 Result |= DINode::DIFlags::FlagPrototyped;
548 if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
549 Result |= DINode::DIFlags::FlagObjcClassComplete;
551 if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
552 Result |= DINode::DIFlags::FlagObjectPointer;
554 if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
555 Result |= DINode::DIFlags::FlagVector;
557 if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
558 Result |= DINode::DIFlags::FlagStaticMember;
560 if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
561 Result |= DINode::DIFlags::FlagLValueReference;
563 if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
564 Result |= DINode::DIFlags::FlagRValueReference;
566 if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
567 Result |= DINode::DIFlags::FlagIntroducedVirtual;
569 if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
570 Result |= DINode::DIFlags::FlagBitField;
572 if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
573 Result |= DINode::DIFlags::FlagNoReturn;
579 // These values **must** match debuginfo::DISPFlags! They also *happen*
580 // to match LLVM, but that isn't required as we do giant sets of
581 // matching below. The value shouldn't be directly passed to LLVM.
582 enum class LLVMRustDISPFlags : uint32_t {
585 SPFlagPureVirtual = 2,
586 SPFlagLocalToUnit = (1 << 2),
587 SPFlagDefinition = (1 << 3),
588 SPFlagOptimized = (1 << 4),
589 SPFlagMainSubprogram = (1 << 5),
590 // Do not add values that are not supported by the minimum LLVM
591 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
592 // (In LLVM < 8, createFunction supported these as separate bool arguments.)
595 inline LLVMRustDISPFlags operator&(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
596 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) &
597 static_cast<uint32_t>(B));
600 inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
601 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) |
602 static_cast<uint32_t>(B));
605 inline LLVMRustDISPFlags &operator|=(LLVMRustDISPFlags &A, LLVMRustDISPFlags B) {
609 inline bool isSet(LLVMRustDISPFlags F) { return F != LLVMRustDISPFlags::SPFlagZero; }
611 inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) {
612 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(F) & 0x3);
615 static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) {
616 DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero;
618 switch (virtuality(SPFlags)) {
619 case LLVMRustDISPFlags::SPFlagVirtual:
620 Result |= DISubprogram::DISPFlags::SPFlagVirtual;
622 case LLVMRustDISPFlags::SPFlagPureVirtual:
623 Result |= DISubprogram::DISPFlags::SPFlagPureVirtual;
626 // The rest are handled below
630 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit)) {
631 Result |= DISubprogram::DISPFlags::SPFlagLocalToUnit;
633 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition)) {
634 Result |= DISubprogram::DISPFlags::SPFlagDefinition;
636 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) {
637 Result |= DISubprogram::DISPFlags::SPFlagOptimized;
639 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) {
640 Result |= DISubprogram::DISPFlags::SPFlagMainSubprogram;
646 enum class LLVMRustDebugEmissionKind {
652 static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
654 case LLVMRustDebugEmissionKind::NoDebug:
655 return DICompileUnit::DebugEmissionKind::NoDebug;
656 case LLVMRustDebugEmissionKind::FullDebug:
657 return DICompileUnit::DebugEmissionKind::FullDebug;
658 case LLVMRustDebugEmissionKind::LineTablesOnly:
659 return DICompileUnit::DebugEmissionKind::LineTablesOnly;
661 report_fatal_error("bad DebugEmissionKind.");
665 enum class LLVMRustChecksumKind {
672 static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
674 case LLVMRustChecksumKind::None:
676 case LLVMRustChecksumKind::MD5:
677 return DIFile::ChecksumKind::CSK_MD5;
678 case LLVMRustChecksumKind::SHA1:
679 return DIFile::ChecksumKind::CSK_SHA1;
680 #if (LLVM_VERSION_MAJOR >= 11)
681 case LLVMRustChecksumKind::SHA256:
682 return DIFile::ChecksumKind::CSK_SHA256;
685 report_fatal_error("bad ChecksumKind.");
689 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
690 return DEBUG_METADATA_VERSION;
693 extern "C" uint32_t LLVMRustVersionPatch() { return LLVM_VERSION_PATCH; }
695 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
697 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
699 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
701 unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
704 extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
705 return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
708 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
709 return new DIBuilder(*unwrap(M));
712 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
716 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
720 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
721 LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
722 const char *Producer, size_t ProducerLen, bool isOptimized,
723 const char *Flags, unsigned RuntimeVer,
724 const char *SplitName, size_t SplitNameLen,
725 LLVMRustDebugEmissionKind Kind,
726 uint64_t DWOId, bool SplitDebugInlining) {
727 auto *File = unwrapDI<DIFile>(FileRef);
729 return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
730 isOptimized, Flags, RuntimeVer,
731 StringRef(SplitName, SplitNameLen),
732 fromRust(Kind), DWOId, SplitDebugInlining));
735 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
736 LLVMRustDIBuilderRef Builder,
737 const char *Filename, size_t FilenameLen,
738 const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
739 const char *Checksum, size_t ChecksumLen) {
740 Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
741 Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
743 CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
744 return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
745 StringRef(Directory, DirectoryLen),
749 extern "C" LLVMMetadataRef
750 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
751 LLVMMetadataRef ParameterTypes) {
752 return wrap(Builder->createSubroutineType(
753 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
756 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
757 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
758 const char *Name, size_t NameLen,
759 const char *LinkageName, size_t LinkageNameLen,
760 LLVMMetadataRef File, unsigned LineNo,
761 LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
762 LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam,
763 LLVMMetadataRef Decl) {
764 DITemplateParameterArray TParams =
765 DITemplateParameterArray(unwrap<MDTuple>(TParam));
766 DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
767 DINode::DIFlags llvmFlags = fromRust(Flags);
768 DISubprogram *Sub = Builder->createFunction(
769 unwrapDI<DIScope>(Scope),
770 StringRef(Name, NameLen),
771 StringRef(LinkageName, LinkageNameLen),
772 unwrapDI<DIFile>(File), LineNo,
773 unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
774 llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
776 unwrap<Function>(MaybeFn)->setSubprogram(Sub);
780 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
781 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
782 uint64_t SizeInBits, unsigned Encoding) {
783 return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
786 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
787 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
788 LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
789 return wrap(Builder->createTypedef(
790 unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
791 LineNo, unwrapDIPtr<DIScope>(Scope)));
794 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
795 LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
796 uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
797 const char *Name, size_t NameLen) {
798 return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
799 SizeInBits, AlignInBits,
801 StringRef(Name, NameLen)));
804 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
805 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
806 const char *Name, size_t NameLen,
807 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
808 uint32_t AlignInBits, LLVMRustDIFlags Flags,
809 LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
810 unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
811 const char *UniqueId, size_t UniqueIdLen) {
812 return wrap(Builder->createStructType(
813 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
814 unwrapDI<DIFile>(File), LineNumber,
815 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
816 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
817 unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen)));
820 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
821 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
822 const char *Name, size_t NameLen,
823 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
824 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
825 LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) {
826 return wrap(Builder->createVariantPart(
827 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
828 unwrapDI<DIFile>(File), LineNumber,
829 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
830 DINodeArray(unwrapDI<MDTuple>(Elements)), StringRef(UniqueId, UniqueIdLen)));
833 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
834 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
835 const char *Name, size_t NameLen,
836 LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
837 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
838 LLVMMetadataRef Ty) {
839 return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope),
840 StringRef(Name, NameLen),
841 unwrapDI<DIFile>(File), LineNo,
842 SizeInBits, AlignInBits, OffsetInBits,
843 fromRust(Flags), unwrapDI<DIType>(Ty)));
846 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
847 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
848 const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
849 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
850 LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
851 llvm::ConstantInt* D = nullptr;
853 D = unwrap<llvm::ConstantInt>(Discriminant);
855 return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope),
856 StringRef(Name, NameLen),
857 unwrapDI<DIFile>(File), LineNo,
858 SizeInBits, AlignInBits, OffsetInBits, D,
859 fromRust(Flags), unwrapDI<DIType>(Ty)));
862 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
863 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
864 LLVMMetadataRef File, unsigned Line, unsigned Col) {
865 return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
866 unwrapDI<DIFile>(File), Line, Col));
869 extern "C" LLVMMetadataRef
870 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
871 LLVMMetadataRef Scope,
872 LLVMMetadataRef File) {
873 return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
874 unwrapDI<DIFile>(File)));
877 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
878 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context,
879 const char *Name, size_t NameLen,
880 const char *LinkageName, size_t LinkageNameLen,
881 LLVMMetadataRef File, unsigned LineNo,
882 LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
883 LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
884 llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
886 llvm::DIExpression *InitExpr = nullptr;
887 if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
888 InitExpr = Builder->createConstantValueExpression(
889 IntVal->getValue().getSExtValue());
890 } else if (llvm::ConstantFP *FPVal =
891 llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
892 InitExpr = Builder->createConstantValueExpression(
893 FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
896 llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
897 unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
898 StringRef(LinkageName, LinkageNameLen),
899 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
900 /* isDefined */ true,
901 InitExpr, unwrapDIPtr<MDNode>(Decl),
902 /* templateParams */ nullptr,
905 InitVal->setMetadata("dbg", VarExpr);
907 return wrap(VarExpr);
910 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
911 LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
912 const char *Name, size_t NameLen,
913 LLVMMetadataRef File, unsigned LineNo,
914 LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
915 unsigned ArgNo, uint32_t AlignInBits) {
916 if (Tag == 0x100) { // DW_TAG_auto_variable
917 return wrap(Builder->createAutoVariable(
918 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
919 unwrapDI<DIFile>(File), LineNo,
920 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
922 return wrap(Builder->createParameterVariable(
923 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
924 unwrapDI<DIFile>(File), LineNo,
925 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
929 extern "C" LLVMMetadataRef
930 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
931 uint32_t AlignInBits, LLVMMetadataRef Ty,
932 LLVMMetadataRef Subscripts) {
934 Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
935 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
938 extern "C" LLVMMetadataRef
939 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
941 return wrap(Builder->getOrCreateSubrange(Lo, Count));
944 extern "C" LLVMMetadataRef
945 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
946 LLVMMetadataRef *Ptr, unsigned Count) {
947 Metadata **DataValue = unwrap(Ptr);
949 Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
952 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
953 LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
954 int64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
955 LLVMBasicBlockRef InsertAtEnd) {
956 return wrap(Builder->insertDeclare(
957 unwrap(V), unwrap<DILocalVariable>(VarInfo),
958 Builder->createExpression(llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
959 DebugLoc(cast<MDNode>(unwrap(DL))),
960 unwrap(InsertAtEnd)));
963 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
964 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
965 int64_t Value, bool IsUnsigned) {
966 return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
969 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
970 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
971 const char *Name, size_t NameLen,
972 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
973 uint32_t AlignInBits, LLVMMetadataRef Elements,
974 LLVMMetadataRef ClassTy, bool IsScoped) {
975 return wrap(Builder->createEnumerationType(
976 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
977 unwrapDI<DIFile>(File), LineNumber,
978 SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
979 unwrapDI<DIType>(ClassTy), "", IsScoped));
982 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
983 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
984 const char *Name, size_t NameLen,
985 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
986 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
987 unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) {
988 return wrap(Builder->createUnionType(
989 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File),
990 LineNumber, SizeInBits, AlignInBits, fromRust(Flags),
991 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
992 StringRef(UniqueId, UniqueIdLen)));
995 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
996 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
997 const char *Name, size_t NameLen, LLVMMetadataRef Ty) {
998 #if LLVM_VERSION_GE(11, 0)
999 bool IsDefault = false; // FIXME: should we ever set this true?
1000 return wrap(Builder->createTemplateTypeParameter(
1001 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty), IsDefault));
1003 return wrap(Builder->createTemplateTypeParameter(
1004 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty)));
1008 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateNameSpace(
1009 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1010 const char *Name, size_t NameLen, bool ExportSymbols) {
1011 return wrap(Builder->createNameSpace(
1012 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols
1017 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
1018 LLVMMetadataRef CompositeTy,
1019 LLVMMetadataRef Elements,
1020 LLVMMetadataRef Params) {
1021 DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
1022 Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
1023 DINodeArray(unwrap<MDTuple>(Params)));
1026 extern "C" LLVMMetadataRef
1027 LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
1028 LLVMMetadataRef ScopeRef,
1029 LLVMMetadataRef InlinedAt) {
1030 #if LLVM_VERSION_GE(12, 0)
1031 MDNode *Scope = unwrapDIPtr<MDNode>(ScopeRef);
1032 DILocation *Loc = DILocation::get(
1033 Scope->getContext(), Line, Column, Scope,
1034 unwrapDIPtr<MDNode>(InlinedAt));
1037 DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(ScopeRef),
1038 unwrapDIPtr<MDNode>(InlinedAt));
1039 return wrap(debug_loc.getAsMDNode());
1043 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
1044 return dwarf::DW_OP_deref;
1047 extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1048 return dwarf::DW_OP_plus_uconst;
1051 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
1052 RawRustStringOstream OS(Str);
1053 unwrap<llvm::Type>(Ty)->print(OS);
1056 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
1057 RustStringRef Str) {
1058 RawRustStringOstream OS(Str);
1063 unwrap<llvm::Value>(V)->getType()->print(OS);
1065 unwrap<llvm::Value>(V)->print(OS);
1070 // LLVMArrayType function does not support 64-bit ElementCount
1071 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
1072 uint64_t ElementCount) {
1073 return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
1076 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1078 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
1079 RawRustStringOstream OS(Str);
1080 unwrap(T)->print(OS);
1083 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1084 LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
1085 LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
1086 RustStringRef FilenameOut, RustStringRef MessageOut) {
1087 // Undefined to call this not on an optimization diagnostic!
1088 llvm::DiagnosticInfoOptimizationBase *Opt =
1089 static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
1091 RawRustStringOstream PassNameOS(PassNameOut);
1092 PassNameOS << Opt->getPassName();
1093 *FunctionOut = wrap(&Opt->getFunction());
1095 RawRustStringOstream FilenameOS(FilenameOut);
1096 DiagnosticLocation loc = Opt->getLocation();
1097 if (loc.isValid()) {
1098 *Line = loc.getLine();
1099 *Column = loc.getColumn();
1100 FilenameOS << loc.getAbsolutePath();
1103 RawRustStringOstream MessageOS(MessageOut);
1104 MessageOS << Opt->getMsg();
1107 enum class LLVMRustDiagnosticLevel {
1115 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
1116 LLVMRustDiagnosticLevel *LevelOut,
1117 unsigned *CookieOut,
1118 LLVMTwineRef *MessageOut,
1119 LLVMValueRef *InstructionOut) {
1120 // Undefined to call this not on an inline assembly diagnostic!
1121 llvm::DiagnosticInfoInlineAsm *IA =
1122 static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
1124 *CookieOut = IA->getLocCookie();
1125 *MessageOut = wrap(&IA->getMsgStr());
1126 *InstructionOut = wrap(IA->getInstruction());
1128 switch (IA->getSeverity()) {
1130 *LevelOut = LLVMRustDiagnosticLevel::Error;
1133 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1136 *LevelOut = LLVMRustDiagnosticLevel::Note;
1139 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1142 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1146 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
1147 RustStringRef Str) {
1148 RawRustStringOstream OS(Str);
1149 DiagnosticPrinterRawOStream DP(OS);
1150 unwrap(DI)->print(DP);
1153 enum class LLVMRustDiagnosticKind {
1157 DebugMetadataVersion,
1160 OptimizationRemarkMissed,
1161 OptimizationRemarkAnalysis,
1162 OptimizationRemarkAnalysisFPCommute,
1163 OptimizationRemarkAnalysisAliasing,
1164 OptimizationRemarkOther,
1165 OptimizationFailure,
1171 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1174 return LLVMRustDiagnosticKind::InlineAsm;
1176 return LLVMRustDiagnosticKind::StackSize;
1177 case DK_DebugMetadataVersion:
1178 return LLVMRustDiagnosticKind::DebugMetadataVersion;
1179 case DK_SampleProfile:
1180 return LLVMRustDiagnosticKind::SampleProfile;
1181 case DK_OptimizationRemark:
1182 return LLVMRustDiagnosticKind::OptimizationRemark;
1183 case DK_OptimizationRemarkMissed:
1184 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1185 case DK_OptimizationRemarkAnalysis:
1186 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1187 case DK_OptimizationRemarkAnalysisFPCommute:
1188 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1189 case DK_OptimizationRemarkAnalysisAliasing:
1190 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1192 return LLVMRustDiagnosticKind::PGOProfile;
1194 return LLVMRustDiagnosticKind::Linker;
1195 case DK_Unsupported:
1196 return LLVMRustDiagnosticKind::Unsupported;
1198 return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1199 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1200 : LLVMRustDiagnosticKind::Other;
1204 extern "C" LLVMRustDiagnosticKind
1205 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1206 return toRust((DiagnosticKind)unwrap(DI)->getKind());
1209 // This is kept distinct from LLVMGetTypeKind, because when
1210 // a new type kind is added, the Rust-side enum must be
1211 // updated or UB will result.
1212 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1213 switch (unwrap(Ty)->getTypeID()) {
1214 case Type::VoidTyID:
1215 return LLVMVoidTypeKind;
1216 case Type::HalfTyID:
1217 return LLVMHalfTypeKind;
1218 case Type::FloatTyID:
1219 return LLVMFloatTypeKind;
1220 case Type::DoubleTyID:
1221 return LLVMDoubleTypeKind;
1222 case Type::X86_FP80TyID:
1223 return LLVMX86_FP80TypeKind;
1224 case Type::FP128TyID:
1225 return LLVMFP128TypeKind;
1226 case Type::PPC_FP128TyID:
1227 return LLVMPPC_FP128TypeKind;
1228 case Type::LabelTyID:
1229 return LLVMLabelTypeKind;
1230 case Type::MetadataTyID:
1231 return LLVMMetadataTypeKind;
1232 case Type::IntegerTyID:
1233 return LLVMIntegerTypeKind;
1234 case Type::FunctionTyID:
1235 return LLVMFunctionTypeKind;
1236 case Type::StructTyID:
1237 return LLVMStructTypeKind;
1238 case Type::ArrayTyID:
1239 return LLVMArrayTypeKind;
1240 case Type::PointerTyID:
1241 return LLVMPointerTypeKind;
1242 #if LLVM_VERSION_GE(11, 0)
1243 case Type::FixedVectorTyID:
1244 return LLVMVectorTypeKind;
1246 case Type::VectorTyID:
1247 return LLVMVectorTypeKind;
1249 case Type::X86_MMXTyID:
1250 return LLVMX86_MMXTypeKind;
1251 case Type::TokenTyID:
1252 return LLVMTokenTypeKind;
1253 #if LLVM_VERSION_GE(11, 0)
1254 case Type::ScalableVectorTyID:
1255 return LLVMScalableVectorTypeKind;
1256 case Type::BFloatTyID:
1257 return LLVMBFloatTypeKind;
1259 #if LLVM_VERSION_GE(12, 0)
1260 case Type::X86_AMXTyID:
1261 return LLVMX86_AMXTypeKind;
1264 report_fatal_error("Unhandled TypeID.");
1267 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1269 #if LLVM_VERSION_LT(13, 0)
1270 using LLVMInlineAsmDiagHandlerTy = LLVMContext::InlineAsmDiagHandlerTy;
1272 using LLVMInlineAsmDiagHandlerTy = void*;
1275 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1276 LLVMContextRef C, LLVMInlineAsmDiagHandlerTy H, void *CX) {
1277 // Diagnostic handlers were unified in LLVM change 5de2d189e6ad, so starting
1278 // with LLVM 13 this function is gone.
1279 #if LLVM_VERSION_LT(13, 0)
1280 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1284 extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
1285 RustStringRef MessageOut,
1286 RustStringRef BufferOut,
1287 LLVMRustDiagnosticLevel* LevelOut,
1289 unsigned* RangesOut,
1290 size_t* NumRanges) {
1291 SMDiagnostic& D = *unwrap(DRef);
1292 RawRustStringOstream MessageOS(MessageOut);
1293 MessageOS << D.getMessage();
1295 switch (D.getKind()) {
1296 case SourceMgr::DK_Error:
1297 *LevelOut = LLVMRustDiagnosticLevel::Error;
1299 case SourceMgr::DK_Warning:
1300 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1302 case SourceMgr::DK_Note:
1303 *LevelOut = LLVMRustDiagnosticLevel::Note;
1305 case SourceMgr::DK_Remark:
1306 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1309 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1312 if (D.getLoc() == SMLoc())
1315 const SourceMgr &LSM = *D.getSourceMgr();
1316 const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
1317 LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), LBuf->getBufferSize());
1319 *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
1321 *NumRanges = std::min(*NumRanges, D.getRanges().size());
1322 size_t LineStart = *LocOut - (size_t)D.getColumnNo();
1323 for (size_t i = 0; i < *NumRanges; i++) {
1324 RangesOut[i * 2] = LineStart + D.getRanges()[i].first;
1325 RangesOut[i * 2 + 1] = LineStart + D.getRanges()[i].second;
1331 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1332 LLVMValueRef ParentPad,
1334 LLVMValueRef *LLArgs,
1336 Value **Args = unwrap(LLArgs);
1337 if (ParentPad == nullptr) {
1338 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1339 ParentPad = wrap(Constant::getNullValue(Ty));
1341 return wrap(unwrap(B)->CreateCleanupPad(
1342 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1345 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1346 LLVMValueRef CleanupPad,
1347 LLVMBasicBlockRef UnwindBB) {
1348 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1349 return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1352 extern "C" LLVMValueRef
1353 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1354 unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1355 Value **Args = unwrap(LLArgs);
1356 return wrap(unwrap(B)->CreateCatchPad(
1357 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1360 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1362 LLVMBasicBlockRef BB) {
1363 return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1367 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1368 LLVMValueRef ParentPad,
1369 LLVMBasicBlockRef BB,
1370 unsigned NumHandlers,
1372 if (ParentPad == nullptr) {
1373 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1374 ParentPad = wrap(Constant::getNullValue(Ty));
1376 return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1377 NumHandlers, Name));
1380 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1381 LLVMBasicBlockRef Handler) {
1382 Value *CatchSwitch = unwrap(CatchSwitchRef);
1383 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1386 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1387 LLVMValueRef *Inputs,
1388 unsigned NumInputs) {
1389 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1392 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1396 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
1397 LLVMValueRef *Args, unsigned NumArgs,
1398 OperandBundleDef *Bundle) {
1399 Value *Callee = unwrap(Fn);
1400 FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1401 unsigned Len = Bundle ? 1 : 0;
1402 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1403 return wrap(unwrap(B)->CreateCall(
1404 FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles));
1407 extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
1408 return wrap(llvm::Intrinsic::getDeclaration(unwrap(M),
1409 (llvm::Intrinsic::ID)llvm::Intrinsic::instrprof_increment));
1412 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
1413 LLVMValueRef Dst, unsigned DstAlign,
1414 LLVMValueRef Src, unsigned SrcAlign,
1415 LLVMValueRef Size, bool IsVolatile) {
1416 return wrap(unwrap(B)->CreateMemCpy(
1417 unwrap(Dst), MaybeAlign(DstAlign),
1418 unwrap(Src), MaybeAlign(SrcAlign),
1419 unwrap(Size), IsVolatile));
1422 extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
1423 LLVMValueRef Dst, unsigned DstAlign,
1424 LLVMValueRef Src, unsigned SrcAlign,
1425 LLVMValueRef Size, bool IsVolatile) {
1426 return wrap(unwrap(B)->CreateMemMove(
1427 unwrap(Dst), MaybeAlign(DstAlign),
1428 unwrap(Src), MaybeAlign(SrcAlign),
1429 unwrap(Size), IsVolatile));
1432 extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
1433 LLVMValueRef Dst, unsigned DstAlign,
1435 LLVMValueRef Size, bool IsVolatile) {
1436 return wrap(unwrap(B)->CreateMemSet(
1437 unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
1440 extern "C" LLVMValueRef
1441 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
1442 unsigned NumArgs, LLVMBasicBlockRef Then,
1443 LLVMBasicBlockRef Catch, OperandBundleDef *Bundle,
1445 Value *Callee = unwrap(Fn);
1446 FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1447 unsigned Len = Bundle ? 1 : 0;
1448 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1449 return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
1450 makeArrayRef(unwrap(Args), NumArgs),
1454 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1455 LLVMBasicBlockRef BB) {
1456 auto Point = unwrap(BB)->getFirstInsertionPt();
1457 unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1460 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1461 const char *Name, size_t NameLen) {
1462 Triple TargetTriple(unwrap(M)->getTargetTriple());
1463 GlobalObject *GV = unwrap<GlobalObject>(V);
1464 if (TargetTriple.supportsCOMDAT()) {
1465 StringRef NameRef(Name, NameLen);
1466 GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
1470 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1471 GlobalObject *GV = unwrap<GlobalObject>(V);
1472 GV->setComdat(nullptr);
1475 enum class LLVMRustLinkage {
1476 ExternalLinkage = 0,
1477 AvailableExternallyLinkage = 1,
1478 LinkOnceAnyLinkage = 2,
1479 LinkOnceODRLinkage = 3,
1482 AppendingLinkage = 6,
1483 InternalLinkage = 7,
1485 ExternalWeakLinkage = 9,
1489 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1491 case LLVMExternalLinkage:
1492 return LLVMRustLinkage::ExternalLinkage;
1493 case LLVMAvailableExternallyLinkage:
1494 return LLVMRustLinkage::AvailableExternallyLinkage;
1495 case LLVMLinkOnceAnyLinkage:
1496 return LLVMRustLinkage::LinkOnceAnyLinkage;
1497 case LLVMLinkOnceODRLinkage:
1498 return LLVMRustLinkage::LinkOnceODRLinkage;
1499 case LLVMWeakAnyLinkage:
1500 return LLVMRustLinkage::WeakAnyLinkage;
1501 case LLVMWeakODRLinkage:
1502 return LLVMRustLinkage::WeakODRLinkage;
1503 case LLVMAppendingLinkage:
1504 return LLVMRustLinkage::AppendingLinkage;
1505 case LLVMInternalLinkage:
1506 return LLVMRustLinkage::InternalLinkage;
1507 case LLVMPrivateLinkage:
1508 return LLVMRustLinkage::PrivateLinkage;
1509 case LLVMExternalWeakLinkage:
1510 return LLVMRustLinkage::ExternalWeakLinkage;
1511 case LLVMCommonLinkage:
1512 return LLVMRustLinkage::CommonLinkage;
1514 report_fatal_error("Invalid LLVMRustLinkage value!");
1518 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1520 case LLVMRustLinkage::ExternalLinkage:
1521 return LLVMExternalLinkage;
1522 case LLVMRustLinkage::AvailableExternallyLinkage:
1523 return LLVMAvailableExternallyLinkage;
1524 case LLVMRustLinkage::LinkOnceAnyLinkage:
1525 return LLVMLinkOnceAnyLinkage;
1526 case LLVMRustLinkage::LinkOnceODRLinkage:
1527 return LLVMLinkOnceODRLinkage;
1528 case LLVMRustLinkage::WeakAnyLinkage:
1529 return LLVMWeakAnyLinkage;
1530 case LLVMRustLinkage::WeakODRLinkage:
1531 return LLVMWeakODRLinkage;
1532 case LLVMRustLinkage::AppendingLinkage:
1533 return LLVMAppendingLinkage;
1534 case LLVMRustLinkage::InternalLinkage:
1535 return LLVMInternalLinkage;
1536 case LLVMRustLinkage::PrivateLinkage:
1537 return LLVMPrivateLinkage;
1538 case LLVMRustLinkage::ExternalWeakLinkage:
1539 return LLVMExternalWeakLinkage;
1540 case LLVMRustLinkage::CommonLinkage:
1541 return LLVMCommonLinkage;
1543 report_fatal_error("Invalid LLVMRustLinkage value!");
1546 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1547 return toRust(LLVMGetLinkage(V));
1550 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1551 LLVMRustLinkage RustLinkage) {
1552 LLVMSetLinkage(V, fromRust(RustLinkage));
1555 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1556 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1557 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1559 auto C = unwrap<llvm::ConstantInt>(CV);
1560 if (C->getBitWidth() > 128) { return false; }
1563 AP = C->getValue().sextOrSelf(128);
1565 AP = C->getValue().zextOrSelf(128);
1567 *low = AP.getLoBits(64).getZExtValue();
1568 *high = AP.getHiBits(64).getZExtValue();
1572 enum class LLVMRustVisibility {
1578 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1580 case LLVMDefaultVisibility:
1581 return LLVMRustVisibility::Default;
1582 case LLVMHiddenVisibility:
1583 return LLVMRustVisibility::Hidden;
1584 case LLVMProtectedVisibility:
1585 return LLVMRustVisibility::Protected;
1587 report_fatal_error("Invalid LLVMRustVisibility value!");
1590 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1592 case LLVMRustVisibility::Default:
1593 return LLVMDefaultVisibility;
1594 case LLVMRustVisibility::Hidden:
1595 return LLVMHiddenVisibility;
1596 case LLVMRustVisibility::Protected:
1597 return LLVMProtectedVisibility;
1599 report_fatal_error("Invalid LLVMRustVisibility value!");
1602 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1603 return toRust(LLVMGetVisibility(V));
1606 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1607 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1608 LLVMTypeRef DestTy, bool isSigned) {
1609 return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1612 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1613 LLVMRustVisibility RustVisibility) {
1614 LLVMSetVisibility(V, fromRust(RustVisibility));
1617 extern "C" void LLVMRustSetDSOLocal(LLVMValueRef Global, bool is_dso_local) {
1618 unwrap<GlobalValue>(Global)->setDSOLocal(is_dso_local);
1621 struct LLVMRustModuleBuffer {
1625 extern "C" LLVMRustModuleBuffer*
1626 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1627 auto Ret = std::make_unique<LLVMRustModuleBuffer>();
1629 raw_string_ostream OS(Ret->data);
1631 legacy::PassManager PM;
1632 PM.add(createBitcodeWriterPass(OS));
1636 return Ret.release();
1640 LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1644 extern "C" const void*
1645 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1646 return Buffer->data.data();
1650 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1651 return Buffer->data.length();
1655 LLVMRustModuleCost(LLVMModuleRef M) {
1656 auto f = unwrap(M)->functions();
1657 return std::distance(std::begin(f), std::end(f));
1660 // Vector reductions:
1661 extern "C" LLVMValueRef
1662 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1663 return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1665 extern "C" LLVMValueRef
1666 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1667 return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1669 extern "C" LLVMValueRef
1670 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1671 return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1673 extern "C" LLVMValueRef
1674 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1675 return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1677 extern "C" LLVMValueRef
1678 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1679 return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1681 extern "C" LLVMValueRef
1682 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1683 return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1685 extern "C" LLVMValueRef
1686 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1687 return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1689 extern "C" LLVMValueRef
1690 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1691 return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1693 extern "C" LLVMValueRef
1694 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1695 return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1697 extern "C" LLVMValueRef
1698 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1699 #if LLVM_VERSION_GE(12, 0)
1700 Instruction *I = unwrap(B)->CreateFPMinReduce(unwrap(Src));
1701 I->setHasNoNaNs(NoNaN);
1704 return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN));
1707 extern "C" LLVMValueRef
1708 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1709 #if LLVM_VERSION_GE(12, 0)
1710 Instruction *I = unwrap(B)->CreateFPMaxReduce(unwrap(Src));
1711 I->setHasNoNaNs(NoNaN);
1714 return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN));
1718 extern "C" LLVMValueRef
1719 LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1720 return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1722 extern "C" LLVMValueRef
1723 LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1724 return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));
1727 // This struct contains all necessary info about a symbol exported from a DLL.
1728 // At the moment, it's just the symbol's name, but we use a separate struct to
1729 // make it easier to add other information like ordinal later.
1730 struct LLVMRustCOFFShortExport {
1734 // Machine must be a COFF machine type, as defined in PE specs.
1735 extern "C" LLVMRustResult LLVMRustWriteImportLibrary(
1736 const char* ImportName,
1738 const LLVMRustCOFFShortExport* Exports,
1743 std::vector<llvm::object::COFFShortExport> ConvertedExports;
1744 ConvertedExports.reserve(NumExports);
1746 for (size_t i = 0; i < NumExports; ++i) {
1747 ConvertedExports.push_back(llvm::object::COFFShortExport{
1748 Exports[i].name, // Name
1749 std::string{}, // ExtName
1750 std::string{}, // SymbolName
1751 std::string{}, // AliasTarget
1760 auto Error = llvm::object::writeImportLibrary(
1764 static_cast<llvm::COFF::MachineTypes>(Machine),
1767 std::string errorString;
1768 llvm::raw_string_ostream stream(errorString);
1771 LLVMRustSetLastError(errorString.c_str());
1772 return LLVMRustResult::Failure;
1774 return LLVMRustResult::Success;