1 #include "LLVMWrapper.h"
2 #include "llvm/IR/DebugInfoMetadata.h"
3 #include "llvm/IR/DiagnosticHandler.h"
4 #include "llvm/IR/DiagnosticInfo.h"
5 #include "llvm/IR/DiagnosticPrinter.h"
6 #include "llvm/IR/GlobalVariable.h"
7 #include "llvm/IR/Instructions.h"
8 #include "llvm/IR/Intrinsics.h"
9 #include "llvm/Object/Archive.h"
10 #include "llvm/Object/COFFImportFile.h"
11 #include "llvm/Object/ObjectFile.h"
12 #include "llvm/Bitcode/BitcodeWriterPass.h"
13 #include "llvm/Support/Signals.h"
14 #include "llvm/ADT/Optional.h"
18 //===----------------------------------------------------------------------===
20 // This file defines alternate interfaces to core functions that are more
21 // readily callable by Rust's FFI.
23 //===----------------------------------------------------------------------===
26 using namespace llvm::sys;
27 using namespace llvm::object;
29 // LLVMAtomicOrdering is already an enum - don't create another
31 static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
33 case LLVMAtomicOrderingNotAtomic:
34 return AtomicOrdering::NotAtomic;
35 case LLVMAtomicOrderingUnordered:
36 return AtomicOrdering::Unordered;
37 case LLVMAtomicOrderingMonotonic:
38 return AtomicOrdering::Monotonic;
39 case LLVMAtomicOrderingAcquire:
40 return AtomicOrdering::Acquire;
41 case LLVMAtomicOrderingRelease:
42 return AtomicOrdering::Release;
43 case LLVMAtomicOrderingAcquireRelease:
44 return AtomicOrdering::AcquireRelease;
45 case LLVMAtomicOrderingSequentiallyConsistent:
46 return AtomicOrdering::SequentiallyConsistent;
49 report_fatal_error("Invalid LLVMAtomicOrdering value!");
52 static LLVM_THREAD_LOCAL char *LastError;
54 // Custom error handler for fatal LLVM errors.
56 // Notably it exits the process with code 101, unlike LLVM's default of 1.
57 static void FatalErrorHandler(void *UserData,
58 #if LLVM_VERSION_LT(14, 0)
59 const std::string& Reason,
64 // Do the same thing that the default error handler does.
65 std::cerr << "LLVM ERROR: " << Reason << std::endl;
67 // Since this error handler exits the process, we have to run any cleanup that
68 // LLVM would run after handling the error. This might change with an LLVM
70 sys::RunInterruptHandlers();
75 extern "C" void LLVMRustInstallFatalErrorHandler() {
76 install_fatal_error_handler(FatalErrorHandler);
79 extern "C" char *LLVMRustGetLastError(void) {
80 char *Ret = LastError;
85 extern "C" unsigned int LLVMRustGetInstructionCount(LLVMModuleRef M) {
86 return unwrap(M)->getInstructionCount();
89 extern "C" void LLVMRustSetLastError(const char *Err) {
90 free((void *)LastError);
91 LastError = strdup(Err);
94 extern "C" LLVMContextRef LLVMRustContextCreate(bool shouldDiscardNames) {
95 auto ctx = new LLVMContext();
96 ctx->setDiscardValueNames(shouldDiscardNames);
100 extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M,
101 const char *Triple) {
102 unwrap(M)->setTargetTriple(Triple::normalize(Triple));
105 extern "C" void LLVMRustPrintPassTimings() {
106 raw_fd_ostream OS(2, false); // stderr.
107 TimerGroup::printAll(OS);
110 extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
112 return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen)));
115 extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
118 LLVMTypeRef FunctionTy) {
119 return wrap(unwrap(M)
120 ->getOrInsertFunction(StringRef(Name, NameLen),
121 unwrap<FunctionType>(FunctionTy))
126 extern "C" LLVMValueRef
127 LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) {
128 Module *Mod = unwrap(M);
129 StringRef NameRef(Name, NameLen);
131 // We don't use Module::getOrInsertGlobal because that returns a Constant*,
132 // which may either be the real GlobalVariable*, or a constant bitcast of it
133 // if our type doesn't match the original declaration. We always want the
134 // GlobalVariable* so we can access linkage, visibility, etc.
135 GlobalVariable *GV = Mod->getGlobalVariable(NameRef, true);
137 GV = new GlobalVariable(*Mod, unwrap(Ty), false,
138 GlobalValue::ExternalLinkage, nullptr, NameRef);
142 extern "C" LLVMValueRef
143 LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) {
144 return wrap(new GlobalVariable(*unwrap(M),
147 GlobalValue::PrivateLinkage,
151 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
152 return wrap(Type::getMetadataTy(*unwrap(C)));
155 static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
158 return Attribute::AlwaysInline;
160 return Attribute::ByVal;
162 return Attribute::Cold;
164 return Attribute::InlineHint;
166 return Attribute::MinSize;
168 return Attribute::Naked;
170 return Attribute::NoAlias;
172 return Attribute::NoCapture;
174 return Attribute::NoInline;
176 return Attribute::NonNull;
178 return Attribute::NoRedZone;
180 return Attribute::NoReturn;
182 return Attribute::NoUnwind;
183 case OptimizeForSize:
184 return Attribute::OptimizeForSize;
186 return Attribute::ReadOnly;
188 return Attribute::SExt;
190 return Attribute::StructRet;
192 return Attribute::UWTable;
194 return Attribute::ZExt;
196 return Attribute::InReg;
198 return Attribute::SanitizeThread;
199 case SanitizeAddress:
200 return Attribute::SanitizeAddress;
202 return Attribute::SanitizeMemory;
204 return Attribute::NonLazyBind;
206 return Attribute::OptimizeNone;
208 return Attribute::ReturnsTwice;
210 return Attribute::ReadNone;
211 case InaccessibleMemOnly:
212 return Attribute::InaccessibleMemOnly;
213 case SanitizeHWAddress:
214 return Attribute::SanitizeHWAddress;
216 return Attribute::WillReturn;
217 case StackProtectReq:
218 return Attribute::StackProtectReq;
219 case StackProtectStrong:
220 return Attribute::StackProtectStrong;
222 return Attribute::StackProtect;
224 report_fatal_error("bad AttributeKind");
227 template<typename T> static inline void AddAttribute(T *t, unsigned Index, Attribute Attr) {
228 #if LLVM_VERSION_LT(14, 0)
229 t->addAttribute(Index, Attr);
231 t->addAttributeAtIndex(Index, Attr);
235 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
236 LLVMRustAttribute RustAttr) {
237 CallBase *Call = unwrap<CallBase>(Instr);
238 Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
239 AddAttribute(Call, Index, Attr);
242 extern "C" void LLVMRustAddCallSiteAttrString(LLVMValueRef Instr, unsigned Index,
244 CallBase *Call = unwrap<CallBase>(Instr);
245 Attribute Attr = Attribute::get(Call->getContext(), Name);
246 AddAttribute(Call, Index, Attr);
249 extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
252 CallBase *Call = unwrap<CallBase>(Instr);
253 Attribute Attr = Attribute::getWithAlignment(Call->getContext(), Align(Bytes));
254 AddAttribute(Call, Index, Attr);
257 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
260 CallBase *Call = unwrap<CallBase>(Instr);
261 Attribute Attr = Attribute::getWithDereferenceableBytes(Call->getContext(), Bytes);
262 AddAttribute(Call, Index, Attr);
265 extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
268 CallBase *Call = unwrap<CallBase>(Instr);
269 Attribute Attr = Attribute::getWithDereferenceableOrNullBytes(Call->getContext(), Bytes);
270 AddAttribute(Call, Index, Attr);
273 extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index,
275 CallBase *Call = unwrap<CallBase>(Instr);
276 Attribute Attr = Attribute::getWithByValType(Call->getContext(), unwrap(Ty));
277 AddAttribute(Call, Index, Attr);
280 extern "C" void LLVMRustAddStructRetCallSiteAttr(LLVMValueRef Instr, unsigned Index,
282 CallBase *Call = unwrap<CallBase>(Instr);
283 Attribute Attr = Attribute::getWithStructRetType(Call->getContext(), unwrap(Ty));
284 AddAttribute(Call, Index, Attr);
287 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
288 LLVMRustAttribute RustAttr) {
289 Function *A = unwrap<Function>(Fn);
290 Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
291 AddAttribute(A, Index, Attr);
294 extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn,
297 Function *A = unwrap<Function>(Fn);
298 AddAttribute(A, Index, Attribute::getWithAlignment(
299 A->getContext(), llvm::Align(Bytes)));
302 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
304 Function *A = unwrap<Function>(Fn);
305 AddAttribute(A, Index, Attribute::getWithDereferenceableBytes(A->getContext(),
309 extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
312 Function *A = unwrap<Function>(Fn);
313 AddAttribute(A, Index, Attribute::getWithDereferenceableOrNullBytes(
314 A->getContext(), Bytes));
317 extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index,
319 Function *F = unwrap<Function>(Fn);
320 Attribute Attr = Attribute::getWithByValType(F->getContext(), unwrap(Ty));
321 AddAttribute(F, Index, Attr);
324 extern "C" void LLVMRustAddStructRetAttr(LLVMValueRef Fn, unsigned Index,
326 Function *F = unwrap<Function>(Fn);
327 Attribute Attr = Attribute::getWithStructRetType(F->getContext(), unwrap(Ty));
328 AddAttribute(F, Index, Attr);
331 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
335 Function *F = unwrap<Function>(Fn);
336 AddAttribute(F, Index, Attribute::get(
337 F->getContext(), StringRef(Name), StringRef(Value)));
340 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
342 LLVMRustAttribute RustAttr) {
343 Function *F = unwrap<Function>(Fn);
344 AttributeList PAL = F->getAttributes();
345 AttributeList PALNew;
346 #if LLVM_VERSION_LT(14, 0)
347 PALNew = PAL.removeAttribute(F->getContext(), Index, fromRust(RustAttr));
349 PALNew = PAL.removeAttributeAtIndex(F->getContext(), Index, fromRust(RustAttr));
351 F->setAttributes(PALNew);
354 // Enable a fast-math flag
356 // https://llvm.org/docs/LangRef.html#fast-math-flags
357 extern "C" void LLVMRustSetFastMath(LLVMValueRef V) {
358 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
363 extern "C" LLVMValueRef
364 LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Source,
365 const char *Name, LLVMAtomicOrdering Order) {
366 Value *Ptr = unwrap(Source);
367 LoadInst *LI = unwrap(B)->CreateLoad(unwrap(Ty), Ptr, Name);
368 LI->setAtomic(fromRust(Order));
372 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
375 LLVMAtomicOrdering Order) {
376 StoreInst *SI = unwrap(B)->CreateStore(unwrap(V), unwrap(Target));
377 SI->setAtomic(fromRust(Order));
381 // FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak
382 // once we raise our minimum support to LLVM 10.
383 extern "C" LLVMValueRef
384 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
385 LLVMValueRef Old, LLVMValueRef Source,
386 LLVMAtomicOrdering Order,
387 LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
388 #if LLVM_VERSION_GE(13,0)
389 // Rust probably knows the alignment of the target value and should be able to
390 // specify something more precise than MaybeAlign here. See also
391 // https://reviews.llvm.org/D97224 which may be a useful reference.
392 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
393 unwrap(Target), unwrap(Old), unwrap(Source), llvm::MaybeAlign(), fromRust(Order),
394 fromRust(FailureOrder));
396 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
397 unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
398 fromRust(FailureOrder));
404 enum class LLVMRustSynchronizationScope {
409 static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
411 case LLVMRustSynchronizationScope::SingleThread:
412 return SyncScope::SingleThread;
413 case LLVMRustSynchronizationScope::CrossThread:
414 return SyncScope::System;
416 report_fatal_error("bad SynchronizationScope.");
420 extern "C" LLVMValueRef
421 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
422 LLVMRustSynchronizationScope Scope) {
423 return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
426 enum class LLVMRustAsmDialect {
431 static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
433 case LLVMRustAsmDialect::Att:
434 return InlineAsm::AD_ATT;
435 case LLVMRustAsmDialect::Intel:
436 return InlineAsm::AD_Intel;
438 report_fatal_error("bad AsmDialect.");
442 extern "C" LLVMValueRef
443 LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
444 char *Constraints, size_t ConstraintsLen,
445 LLVMBool HasSideEffects, LLVMBool IsAlignStack,
446 LLVMRustAsmDialect Dialect, LLVMBool CanThrow) {
447 #if LLVM_VERSION_GE(13, 0)
448 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
449 StringRef(AsmString, AsmStringLen),
450 StringRef(Constraints, ConstraintsLen),
451 HasSideEffects, IsAlignStack,
452 fromRust(Dialect), CanThrow));
454 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
455 StringRef(AsmString, AsmStringLen),
456 StringRef(Constraints, ConstraintsLen),
457 HasSideEffects, IsAlignStack,
462 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
463 size_t ConstraintsLen) {
464 return InlineAsm::Verify(unwrap<FunctionType>(Ty),
465 StringRef(Constraints, ConstraintsLen));
468 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
470 unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen));
473 typedef DIBuilder *LLVMRustDIBuilderRef;
475 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
476 return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
479 #define DIDescriptor DIScope
480 #define DIArray DINodeArray
481 #define unwrapDI unwrapDIPtr
483 // These values **must** match debuginfo::DIFlags! They also *happen*
484 // to match LLVM, but that isn't required as we do giant sets of
485 // matching below. The value shouldn't be directly passed to LLVM.
486 enum class LLVMRustDIFlags : uint32_t {
491 FlagFwdDecl = (1 << 2),
492 FlagAppleBlock = (1 << 3),
493 FlagBlockByrefStruct = (1 << 4),
494 FlagVirtual = (1 << 5),
495 FlagArtificial = (1 << 6),
496 FlagExplicit = (1 << 7),
497 FlagPrototyped = (1 << 8),
498 FlagObjcClassComplete = (1 << 9),
499 FlagObjectPointer = (1 << 10),
500 FlagVector = (1 << 11),
501 FlagStaticMember = (1 << 12),
502 FlagLValueReference = (1 << 13),
503 FlagRValueReference = (1 << 14),
504 FlagExternalTypeRef = (1 << 15),
505 FlagIntroducedVirtual = (1 << 18),
506 FlagBitField = (1 << 19),
507 FlagNoReturn = (1 << 20),
508 // Do not add values that are not supported by the minimum LLVM
509 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
512 inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
513 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
514 static_cast<uint32_t>(B));
517 inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
518 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
519 static_cast<uint32_t>(B));
522 inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
526 inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
528 inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
529 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
532 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
533 DINode::DIFlags Result = DINode::DIFlags::FlagZero;
535 switch (visibility(Flags)) {
536 case LLVMRustDIFlags::FlagPrivate:
537 Result |= DINode::DIFlags::FlagPrivate;
539 case LLVMRustDIFlags::FlagProtected:
540 Result |= DINode::DIFlags::FlagProtected;
542 case LLVMRustDIFlags::FlagPublic:
543 Result |= DINode::DIFlags::FlagPublic;
546 // The rest are handled below
550 if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
551 Result |= DINode::DIFlags::FlagFwdDecl;
553 if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
554 Result |= DINode::DIFlags::FlagAppleBlock;
556 if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
557 Result |= DINode::DIFlags::FlagVirtual;
559 if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
560 Result |= DINode::DIFlags::FlagArtificial;
562 if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
563 Result |= DINode::DIFlags::FlagExplicit;
565 if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
566 Result |= DINode::DIFlags::FlagPrototyped;
568 if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
569 Result |= DINode::DIFlags::FlagObjcClassComplete;
571 if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
572 Result |= DINode::DIFlags::FlagObjectPointer;
574 if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
575 Result |= DINode::DIFlags::FlagVector;
577 if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
578 Result |= DINode::DIFlags::FlagStaticMember;
580 if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
581 Result |= DINode::DIFlags::FlagLValueReference;
583 if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
584 Result |= DINode::DIFlags::FlagRValueReference;
586 if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
587 Result |= DINode::DIFlags::FlagIntroducedVirtual;
589 if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
590 Result |= DINode::DIFlags::FlagBitField;
592 if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
593 Result |= DINode::DIFlags::FlagNoReturn;
599 // These values **must** match debuginfo::DISPFlags! They also *happen*
600 // to match LLVM, but that isn't required as we do giant sets of
601 // matching below. The value shouldn't be directly passed to LLVM.
602 enum class LLVMRustDISPFlags : uint32_t {
605 SPFlagPureVirtual = 2,
606 SPFlagLocalToUnit = (1 << 2),
607 SPFlagDefinition = (1 << 3),
608 SPFlagOptimized = (1 << 4),
609 SPFlagMainSubprogram = (1 << 5),
610 // Do not add values that are not supported by the minimum LLVM
611 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
612 // (In LLVM < 8, createFunction supported these as separate bool arguments.)
615 inline LLVMRustDISPFlags operator&(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
616 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) &
617 static_cast<uint32_t>(B));
620 inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
621 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) |
622 static_cast<uint32_t>(B));
625 inline LLVMRustDISPFlags &operator|=(LLVMRustDISPFlags &A, LLVMRustDISPFlags B) {
629 inline bool isSet(LLVMRustDISPFlags F) { return F != LLVMRustDISPFlags::SPFlagZero; }
631 inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) {
632 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(F) & 0x3);
635 static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) {
636 DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero;
638 switch (virtuality(SPFlags)) {
639 case LLVMRustDISPFlags::SPFlagVirtual:
640 Result |= DISubprogram::DISPFlags::SPFlagVirtual;
642 case LLVMRustDISPFlags::SPFlagPureVirtual:
643 Result |= DISubprogram::DISPFlags::SPFlagPureVirtual;
646 // The rest are handled below
650 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit)) {
651 Result |= DISubprogram::DISPFlags::SPFlagLocalToUnit;
653 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition)) {
654 Result |= DISubprogram::DISPFlags::SPFlagDefinition;
656 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) {
657 Result |= DISubprogram::DISPFlags::SPFlagOptimized;
659 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) {
660 Result |= DISubprogram::DISPFlags::SPFlagMainSubprogram;
666 enum class LLVMRustDebugEmissionKind {
672 static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
674 case LLVMRustDebugEmissionKind::NoDebug:
675 return DICompileUnit::DebugEmissionKind::NoDebug;
676 case LLVMRustDebugEmissionKind::FullDebug:
677 return DICompileUnit::DebugEmissionKind::FullDebug;
678 case LLVMRustDebugEmissionKind::LineTablesOnly:
679 return DICompileUnit::DebugEmissionKind::LineTablesOnly;
681 report_fatal_error("bad DebugEmissionKind.");
685 enum class LLVMRustChecksumKind {
692 static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
694 case LLVMRustChecksumKind::None:
696 case LLVMRustChecksumKind::MD5:
697 return DIFile::ChecksumKind::CSK_MD5;
698 case LLVMRustChecksumKind::SHA1:
699 return DIFile::ChecksumKind::CSK_SHA1;
700 case LLVMRustChecksumKind::SHA256:
701 return DIFile::ChecksumKind::CSK_SHA256;
703 report_fatal_error("bad ChecksumKind.");
707 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
708 return DEBUG_METADATA_VERSION;
711 extern "C" uint32_t LLVMRustVersionPatch() { return LLVM_VERSION_PATCH; }
713 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
715 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
717 extern "C" bool LLVMRustIsRustLLVM() {
725 extern "C" void LLVMRustAddModuleFlag(
727 Module::ModFlagBehavior MergeBehavior,
730 unwrap(M)->addModuleFlag(MergeBehavior, Name, Value);
733 extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
734 return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
737 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
738 return new DIBuilder(*unwrap(M));
741 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
745 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
749 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
750 LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
751 const char *Producer, size_t ProducerLen, bool isOptimized,
752 const char *Flags, unsigned RuntimeVer,
753 const char *SplitName, size_t SplitNameLen,
754 LLVMRustDebugEmissionKind Kind,
755 uint64_t DWOId, bool SplitDebugInlining) {
756 auto *File = unwrapDI<DIFile>(FileRef);
758 return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
759 isOptimized, Flags, RuntimeVer,
760 StringRef(SplitName, SplitNameLen),
761 fromRust(Kind), DWOId, SplitDebugInlining));
764 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
765 LLVMRustDIBuilderRef Builder,
766 const char *Filename, size_t FilenameLen,
767 const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
768 const char *Checksum, size_t ChecksumLen) {
769 Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
770 Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
772 CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
773 return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
774 StringRef(Directory, DirectoryLen),
778 extern "C" LLVMMetadataRef
779 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
780 LLVMMetadataRef ParameterTypes) {
781 return wrap(Builder->createSubroutineType(
782 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
785 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
786 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
787 const char *Name, size_t NameLen,
788 const char *LinkageName, size_t LinkageNameLen,
789 LLVMMetadataRef File, unsigned LineNo,
790 LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
791 LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam,
792 LLVMMetadataRef Decl) {
793 DITemplateParameterArray TParams =
794 DITemplateParameterArray(unwrap<MDTuple>(TParam));
795 DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
796 DINode::DIFlags llvmFlags = fromRust(Flags);
797 DISubprogram *Sub = Builder->createFunction(
798 unwrapDI<DIScope>(Scope),
799 StringRef(Name, NameLen),
800 StringRef(LinkageName, LinkageNameLen),
801 unwrapDI<DIFile>(File), LineNo,
802 unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
803 llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
805 unwrap<Function>(MaybeFn)->setSubprogram(Sub);
809 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
810 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
811 uint64_t SizeInBits, unsigned Encoding) {
812 return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
815 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
816 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
817 LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
818 return wrap(Builder->createTypedef(
819 unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
820 LineNo, unwrapDIPtr<DIScope>(Scope)));
823 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
824 LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
825 uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
826 const char *Name, size_t NameLen) {
827 return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
828 SizeInBits, AlignInBits,
830 StringRef(Name, NameLen)));
833 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
834 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
835 const char *Name, size_t NameLen,
836 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
837 uint32_t AlignInBits, LLVMRustDIFlags Flags,
838 LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
839 unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
840 const char *UniqueId, size_t UniqueIdLen) {
841 return wrap(Builder->createStructType(
842 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
843 unwrapDI<DIFile>(File), LineNumber,
844 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
845 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
846 unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen)));
849 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
850 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
851 const char *Name, size_t NameLen,
852 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
853 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
854 LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) {
855 return wrap(Builder->createVariantPart(
856 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
857 unwrapDI<DIFile>(File), LineNumber,
858 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
859 DINodeArray(unwrapDI<MDTuple>(Elements)), StringRef(UniqueId, UniqueIdLen)));
862 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
863 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
864 const char *Name, size_t NameLen,
865 LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
866 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
867 LLVMMetadataRef Ty) {
868 return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope),
869 StringRef(Name, NameLen),
870 unwrapDI<DIFile>(File), LineNo,
871 SizeInBits, AlignInBits, OffsetInBits,
872 fromRust(Flags), unwrapDI<DIType>(Ty)));
875 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
876 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
877 const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
878 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
879 LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
880 llvm::ConstantInt* D = nullptr;
882 D = unwrap<llvm::ConstantInt>(Discriminant);
884 return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope),
885 StringRef(Name, NameLen),
886 unwrapDI<DIFile>(File), LineNo,
887 SizeInBits, AlignInBits, OffsetInBits, D,
888 fromRust(Flags), unwrapDI<DIType>(Ty)));
891 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
892 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
893 LLVMMetadataRef File, unsigned Line, unsigned Col) {
894 return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
895 unwrapDI<DIFile>(File), Line, Col));
898 extern "C" LLVMMetadataRef
899 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
900 LLVMMetadataRef Scope,
901 LLVMMetadataRef File) {
902 return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
903 unwrapDI<DIFile>(File)));
906 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
907 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context,
908 const char *Name, size_t NameLen,
909 const char *LinkageName, size_t LinkageNameLen,
910 LLVMMetadataRef File, unsigned LineNo,
911 LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
912 LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
913 llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
915 llvm::DIExpression *InitExpr = nullptr;
916 if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
917 InitExpr = Builder->createConstantValueExpression(
918 IntVal->getValue().getSExtValue());
919 } else if (llvm::ConstantFP *FPVal =
920 llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
921 InitExpr = Builder->createConstantValueExpression(
922 FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
925 llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
926 unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
927 StringRef(LinkageName, LinkageNameLen),
928 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
929 /* isDefined */ true,
930 InitExpr, unwrapDIPtr<MDNode>(Decl),
931 /* templateParams */ nullptr,
934 InitVal->setMetadata("dbg", VarExpr);
936 return wrap(VarExpr);
939 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
940 LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
941 const char *Name, size_t NameLen,
942 LLVMMetadataRef File, unsigned LineNo,
943 LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
944 unsigned ArgNo, uint32_t AlignInBits) {
945 if (Tag == 0x100) { // DW_TAG_auto_variable
946 return wrap(Builder->createAutoVariable(
947 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
948 unwrapDI<DIFile>(File), LineNo,
949 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
951 return wrap(Builder->createParameterVariable(
952 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
953 unwrapDI<DIFile>(File), LineNo,
954 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
958 extern "C" LLVMMetadataRef
959 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
960 uint32_t AlignInBits, LLVMMetadataRef Ty,
961 LLVMMetadataRef Subscripts) {
963 Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
964 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
967 extern "C" LLVMMetadataRef
968 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
970 return wrap(Builder->getOrCreateSubrange(Lo, Count));
973 extern "C" LLVMMetadataRef
974 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
975 LLVMMetadataRef *Ptr, unsigned Count) {
976 Metadata **DataValue = unwrap(Ptr);
978 Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
981 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
982 LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
983 uint64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
984 LLVMBasicBlockRef InsertAtEnd) {
985 return wrap(Builder->insertDeclare(
986 unwrap(V), unwrap<DILocalVariable>(VarInfo),
987 Builder->createExpression(llvm::ArrayRef<uint64_t>(AddrOps, AddrOpsCount)),
988 DebugLoc(cast<MDNode>(unwrap(DL))),
989 unwrap(InsertAtEnd)));
992 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
993 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
994 int64_t Value, bool IsUnsigned) {
995 return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
998 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
999 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1000 const char *Name, size_t NameLen,
1001 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
1002 uint32_t AlignInBits, LLVMMetadataRef Elements,
1003 LLVMMetadataRef ClassTy, bool IsScoped) {
1004 return wrap(Builder->createEnumerationType(
1005 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
1006 unwrapDI<DIFile>(File), LineNumber,
1007 SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
1008 unwrapDI<DIType>(ClassTy), "", IsScoped));
1011 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
1012 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1013 const char *Name, size_t NameLen,
1014 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
1015 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
1016 unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) {
1017 return wrap(Builder->createUnionType(
1018 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File),
1019 LineNumber, SizeInBits, AlignInBits, fromRust(Flags),
1020 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
1021 StringRef(UniqueId, UniqueIdLen)));
1024 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
1025 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1026 const char *Name, size_t NameLen, LLVMMetadataRef Ty) {
1027 bool IsDefault = false; // FIXME: should we ever set this true?
1028 return wrap(Builder->createTemplateTypeParameter(
1029 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty), IsDefault));
1032 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateNameSpace(
1033 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
1034 const char *Name, size_t NameLen, bool ExportSymbols) {
1035 return wrap(Builder->createNameSpace(
1036 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols
1041 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
1042 LLVMMetadataRef CompositeTy,
1043 LLVMMetadataRef Elements,
1044 LLVMMetadataRef Params) {
1045 DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
1046 Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
1047 DINodeArray(unwrap<MDTuple>(Params)));
1050 extern "C" LLVMMetadataRef
1051 LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
1052 LLVMMetadataRef ScopeRef,
1053 LLVMMetadataRef InlinedAt) {
1054 MDNode *Scope = unwrapDIPtr<MDNode>(ScopeRef);
1055 DILocation *Loc = DILocation::get(
1056 Scope->getContext(), Line, Column, Scope,
1057 unwrapDIPtr<MDNode>(InlinedAt));
1061 extern "C" uint64_t LLVMRustDIBuilderCreateOpDeref() {
1062 return dwarf::DW_OP_deref;
1065 extern "C" uint64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1066 return dwarf::DW_OP_plus_uconst;
1069 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
1070 RawRustStringOstream OS(Str);
1071 unwrap<llvm::Type>(Ty)->print(OS);
1074 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
1075 RustStringRef Str) {
1076 RawRustStringOstream OS(Str);
1081 unwrap<llvm::Value>(V)->getType()->print(OS);
1083 unwrap<llvm::Value>(V)->print(OS);
1088 // LLVMArrayType function does not support 64-bit ElementCount
1089 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
1090 uint64_t ElementCount) {
1091 return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
1094 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1096 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
1097 RawRustStringOstream OS(Str);
1098 unwrap(T)->print(OS);
1101 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1102 LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
1103 LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
1104 RustStringRef FilenameOut, RustStringRef MessageOut) {
1105 // Undefined to call this not on an optimization diagnostic!
1106 llvm::DiagnosticInfoOptimizationBase *Opt =
1107 static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
1109 RawRustStringOstream PassNameOS(PassNameOut);
1110 PassNameOS << Opt->getPassName();
1111 *FunctionOut = wrap(&Opt->getFunction());
1113 RawRustStringOstream FilenameOS(FilenameOut);
1114 DiagnosticLocation loc = Opt->getLocation();
1115 if (loc.isValid()) {
1116 *Line = loc.getLine();
1117 *Column = loc.getColumn();
1118 FilenameOS << loc.getAbsolutePath();
1121 RawRustStringOstream MessageOS(MessageOut);
1122 MessageOS << Opt->getMsg();
1125 enum class LLVMRustDiagnosticLevel {
1133 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
1134 LLVMRustDiagnosticLevel *LevelOut,
1135 unsigned *CookieOut,
1136 LLVMTwineRef *MessageOut) {
1137 // Undefined to call this not on an inline assembly diagnostic!
1138 llvm::DiagnosticInfoInlineAsm *IA =
1139 static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
1141 *CookieOut = IA->getLocCookie();
1142 *MessageOut = wrap(&IA->getMsgStr());
1144 switch (IA->getSeverity()) {
1146 *LevelOut = LLVMRustDiagnosticLevel::Error;
1149 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1152 *LevelOut = LLVMRustDiagnosticLevel::Note;
1155 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1158 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1162 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
1163 RustStringRef Str) {
1164 RawRustStringOstream OS(Str);
1165 DiagnosticPrinterRawOStream DP(OS);
1166 unwrap(DI)->print(DP);
1169 enum class LLVMRustDiagnosticKind {
1173 DebugMetadataVersion,
1176 OptimizationRemarkMissed,
1177 OptimizationRemarkAnalysis,
1178 OptimizationRemarkAnalysisFPCommute,
1179 OptimizationRemarkAnalysisAliasing,
1180 OptimizationRemarkOther,
1181 OptimizationFailure,
1188 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1191 return LLVMRustDiagnosticKind::InlineAsm;
1193 return LLVMRustDiagnosticKind::StackSize;
1194 case DK_DebugMetadataVersion:
1195 return LLVMRustDiagnosticKind::DebugMetadataVersion;
1196 case DK_SampleProfile:
1197 return LLVMRustDiagnosticKind::SampleProfile;
1198 case DK_OptimizationRemark:
1199 case DK_MachineOptimizationRemark:
1200 return LLVMRustDiagnosticKind::OptimizationRemark;
1201 case DK_OptimizationRemarkMissed:
1202 case DK_MachineOptimizationRemarkMissed:
1203 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1204 case DK_OptimizationRemarkAnalysis:
1205 case DK_MachineOptimizationRemarkAnalysis:
1206 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1207 case DK_OptimizationRemarkAnalysisFPCommute:
1208 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1209 case DK_OptimizationRemarkAnalysisAliasing:
1210 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1212 return LLVMRustDiagnosticKind::PGOProfile;
1214 return LLVMRustDiagnosticKind::Linker;
1215 case DK_Unsupported:
1216 return LLVMRustDiagnosticKind::Unsupported;
1217 #if LLVM_VERSION_GE(13, 0)
1219 return LLVMRustDiagnosticKind::SrcMgr;
1222 return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1223 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1224 : LLVMRustDiagnosticKind::Other;
1228 extern "C" LLVMRustDiagnosticKind
1229 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1230 return toRust((DiagnosticKind)unwrap(DI)->getKind());
1233 // This is kept distinct from LLVMGetTypeKind, because when
1234 // a new type kind is added, the Rust-side enum must be
1235 // updated or UB will result.
1236 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1237 switch (unwrap(Ty)->getTypeID()) {
1238 case Type::VoidTyID:
1239 return LLVMVoidTypeKind;
1240 case Type::HalfTyID:
1241 return LLVMHalfTypeKind;
1242 case Type::FloatTyID:
1243 return LLVMFloatTypeKind;
1244 case Type::DoubleTyID:
1245 return LLVMDoubleTypeKind;
1246 case Type::X86_FP80TyID:
1247 return LLVMX86_FP80TypeKind;
1248 case Type::FP128TyID:
1249 return LLVMFP128TypeKind;
1250 case Type::PPC_FP128TyID:
1251 return LLVMPPC_FP128TypeKind;
1252 case Type::LabelTyID:
1253 return LLVMLabelTypeKind;
1254 case Type::MetadataTyID:
1255 return LLVMMetadataTypeKind;
1256 case Type::IntegerTyID:
1257 return LLVMIntegerTypeKind;
1258 case Type::FunctionTyID:
1259 return LLVMFunctionTypeKind;
1260 case Type::StructTyID:
1261 return LLVMStructTypeKind;
1262 case Type::ArrayTyID:
1263 return LLVMArrayTypeKind;
1264 case Type::PointerTyID:
1265 return LLVMPointerTypeKind;
1266 case Type::FixedVectorTyID:
1267 return LLVMVectorTypeKind;
1268 case Type::X86_MMXTyID:
1269 return LLVMX86_MMXTypeKind;
1270 case Type::TokenTyID:
1271 return LLVMTokenTypeKind;
1272 case Type::ScalableVectorTyID:
1273 return LLVMScalableVectorTypeKind;
1274 case Type::BFloatTyID:
1275 return LLVMBFloatTypeKind;
1276 case Type::X86_AMXTyID:
1277 return LLVMX86_AMXTypeKind;
1279 report_fatal_error("Unhandled TypeID.");
1282 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1284 #if LLVM_VERSION_LT(13, 0)
1285 using LLVMInlineAsmDiagHandlerTy = LLVMContext::InlineAsmDiagHandlerTy;
1287 using LLVMInlineAsmDiagHandlerTy = void*;
1290 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1291 LLVMContextRef C, LLVMInlineAsmDiagHandlerTy H, void *CX) {
1292 // Diagnostic handlers were unified in LLVM change 5de2d189e6ad, so starting
1293 // with LLVM 13 this function is gone.
1294 #if LLVM_VERSION_LT(13, 0)
1295 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1299 extern "C" LLVMSMDiagnosticRef LLVMRustGetSMDiagnostic(
1300 LLVMDiagnosticInfoRef DI, unsigned *Cookie) {
1301 #if LLVM_VERSION_GE(13, 0)
1302 llvm::DiagnosticInfoSrcMgr *SM = static_cast<llvm::DiagnosticInfoSrcMgr *>(unwrap(DI));
1303 *Cookie = SM->getLocCookie();
1304 return wrap(&SM->getSMDiag());
1306 report_fatal_error("Shouldn't get called on older versions");
1310 extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
1311 RustStringRef MessageOut,
1312 RustStringRef BufferOut,
1313 LLVMRustDiagnosticLevel* LevelOut,
1315 unsigned* RangesOut,
1316 size_t* NumRanges) {
1317 SMDiagnostic& D = *unwrap(DRef);
1318 RawRustStringOstream MessageOS(MessageOut);
1319 MessageOS << D.getMessage();
1321 switch (D.getKind()) {
1322 case SourceMgr::DK_Error:
1323 *LevelOut = LLVMRustDiagnosticLevel::Error;
1325 case SourceMgr::DK_Warning:
1326 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1328 case SourceMgr::DK_Note:
1329 *LevelOut = LLVMRustDiagnosticLevel::Note;
1331 case SourceMgr::DK_Remark:
1332 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1335 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1338 if (D.getLoc() == SMLoc())
1341 const SourceMgr &LSM = *D.getSourceMgr();
1342 const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
1343 LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), LBuf->getBufferSize());
1345 *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
1347 *NumRanges = std::min(*NumRanges, D.getRanges().size());
1348 size_t LineStart = *LocOut - (size_t)D.getColumnNo();
1349 for (size_t i = 0; i < *NumRanges; i++) {
1350 RangesOut[i * 2] = LineStart + D.getRanges()[i].first;
1351 RangesOut[i * 2 + 1] = LineStart + D.getRanges()[i].second;
1357 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1358 LLVMValueRef ParentPad,
1360 LLVMValueRef *LLArgs,
1362 Value **Args = unwrap(LLArgs);
1363 if (ParentPad == nullptr) {
1364 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1365 ParentPad = wrap(Constant::getNullValue(Ty));
1367 return wrap(unwrap(B)->CreateCleanupPad(
1368 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1371 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1372 LLVMValueRef CleanupPad,
1373 LLVMBasicBlockRef UnwindBB) {
1374 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1375 return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1378 extern "C" LLVMValueRef
1379 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1380 unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1381 Value **Args = unwrap(LLArgs);
1382 return wrap(unwrap(B)->CreateCatchPad(
1383 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1386 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1388 LLVMBasicBlockRef BB) {
1389 return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1393 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1394 LLVMValueRef ParentPad,
1395 LLVMBasicBlockRef BB,
1396 unsigned NumHandlers,
1398 if (ParentPad == nullptr) {
1399 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1400 ParentPad = wrap(Constant::getNullValue(Ty));
1402 return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1403 NumHandlers, Name));
1406 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1407 LLVMBasicBlockRef Handler) {
1408 Value *CatchSwitch = unwrap(CatchSwitchRef);
1409 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1412 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1413 LLVMValueRef *Inputs,
1414 unsigned NumInputs) {
1415 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1418 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1422 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
1423 LLVMValueRef *Args, unsigned NumArgs,
1424 OperandBundleDef *Bundle) {
1425 Value *Callee = unwrap(Fn);
1426 FunctionType *FTy = unwrap<FunctionType>(Ty);
1427 unsigned Len = Bundle ? 1 : 0;
1428 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1429 return wrap(unwrap(B)->CreateCall(
1430 FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles));
1433 extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
1434 return wrap(llvm::Intrinsic::getDeclaration(unwrap(M),
1435 (llvm::Intrinsic::ID)llvm::Intrinsic::instrprof_increment));
1438 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
1439 LLVMValueRef Dst, unsigned DstAlign,
1440 LLVMValueRef Src, unsigned SrcAlign,
1441 LLVMValueRef Size, bool IsVolatile) {
1442 return wrap(unwrap(B)->CreateMemCpy(
1443 unwrap(Dst), MaybeAlign(DstAlign),
1444 unwrap(Src), MaybeAlign(SrcAlign),
1445 unwrap(Size), IsVolatile));
1448 extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
1449 LLVMValueRef Dst, unsigned DstAlign,
1450 LLVMValueRef Src, unsigned SrcAlign,
1451 LLVMValueRef Size, bool IsVolatile) {
1452 return wrap(unwrap(B)->CreateMemMove(
1453 unwrap(Dst), MaybeAlign(DstAlign),
1454 unwrap(Src), MaybeAlign(SrcAlign),
1455 unwrap(Size), IsVolatile));
1458 extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
1459 LLVMValueRef Dst, unsigned DstAlign,
1461 LLVMValueRef Size, bool IsVolatile) {
1462 return wrap(unwrap(B)->CreateMemSet(
1463 unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
1466 extern "C" LLVMValueRef
1467 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
1468 LLVMValueRef *Args, unsigned NumArgs,
1469 LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
1470 OperandBundleDef *Bundle, const char *Name) {
1471 Value *Callee = unwrap(Fn);
1472 FunctionType *FTy = unwrap<FunctionType>(Ty);
1473 unsigned Len = Bundle ? 1 : 0;
1474 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1475 return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
1476 makeArrayRef(unwrap(Args), NumArgs),
1480 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1481 LLVMBasicBlockRef BB) {
1482 auto Point = unwrap(BB)->getFirstInsertionPt();
1483 unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1486 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1487 const char *Name, size_t NameLen) {
1488 Triple TargetTriple(unwrap(M)->getTargetTriple());
1489 GlobalObject *GV = unwrap<GlobalObject>(V);
1490 if (TargetTriple.supportsCOMDAT()) {
1491 StringRef NameRef(Name, NameLen);
1492 GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
1496 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1497 GlobalObject *GV = unwrap<GlobalObject>(V);
1498 GV->setComdat(nullptr);
1501 enum class LLVMRustLinkage {
1502 ExternalLinkage = 0,
1503 AvailableExternallyLinkage = 1,
1504 LinkOnceAnyLinkage = 2,
1505 LinkOnceODRLinkage = 3,
1508 AppendingLinkage = 6,
1509 InternalLinkage = 7,
1511 ExternalWeakLinkage = 9,
1515 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1517 case LLVMExternalLinkage:
1518 return LLVMRustLinkage::ExternalLinkage;
1519 case LLVMAvailableExternallyLinkage:
1520 return LLVMRustLinkage::AvailableExternallyLinkage;
1521 case LLVMLinkOnceAnyLinkage:
1522 return LLVMRustLinkage::LinkOnceAnyLinkage;
1523 case LLVMLinkOnceODRLinkage:
1524 return LLVMRustLinkage::LinkOnceODRLinkage;
1525 case LLVMWeakAnyLinkage:
1526 return LLVMRustLinkage::WeakAnyLinkage;
1527 case LLVMWeakODRLinkage:
1528 return LLVMRustLinkage::WeakODRLinkage;
1529 case LLVMAppendingLinkage:
1530 return LLVMRustLinkage::AppendingLinkage;
1531 case LLVMInternalLinkage:
1532 return LLVMRustLinkage::InternalLinkage;
1533 case LLVMPrivateLinkage:
1534 return LLVMRustLinkage::PrivateLinkage;
1535 case LLVMExternalWeakLinkage:
1536 return LLVMRustLinkage::ExternalWeakLinkage;
1537 case LLVMCommonLinkage:
1538 return LLVMRustLinkage::CommonLinkage;
1540 report_fatal_error("Invalid LLVMRustLinkage value!");
1544 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1546 case LLVMRustLinkage::ExternalLinkage:
1547 return LLVMExternalLinkage;
1548 case LLVMRustLinkage::AvailableExternallyLinkage:
1549 return LLVMAvailableExternallyLinkage;
1550 case LLVMRustLinkage::LinkOnceAnyLinkage:
1551 return LLVMLinkOnceAnyLinkage;
1552 case LLVMRustLinkage::LinkOnceODRLinkage:
1553 return LLVMLinkOnceODRLinkage;
1554 case LLVMRustLinkage::WeakAnyLinkage:
1555 return LLVMWeakAnyLinkage;
1556 case LLVMRustLinkage::WeakODRLinkage:
1557 return LLVMWeakODRLinkage;
1558 case LLVMRustLinkage::AppendingLinkage:
1559 return LLVMAppendingLinkage;
1560 case LLVMRustLinkage::InternalLinkage:
1561 return LLVMInternalLinkage;
1562 case LLVMRustLinkage::PrivateLinkage:
1563 return LLVMPrivateLinkage;
1564 case LLVMRustLinkage::ExternalWeakLinkage:
1565 return LLVMExternalWeakLinkage;
1566 case LLVMRustLinkage::CommonLinkage:
1567 return LLVMCommonLinkage;
1569 report_fatal_error("Invalid LLVMRustLinkage value!");
1572 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1573 return toRust(LLVMGetLinkage(V));
1576 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1577 LLVMRustLinkage RustLinkage) {
1578 LLVMSetLinkage(V, fromRust(RustLinkage));
1581 extern "C" LLVMValueRef LLVMRustConstInBoundsGEP2(LLVMTypeRef Ty,
1582 LLVMValueRef ConstantVal,
1583 LLVMValueRef *ConstantIndices,
1584 unsigned NumIndices) {
1585 ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
1587 Constant *Val = unwrap<Constant>(ConstantVal);
1588 return wrap(ConstantExpr::getInBoundsGetElementPtr(unwrap(Ty), Val, IdxList));
1591 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1592 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1593 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1595 auto C = unwrap<llvm::ConstantInt>(CV);
1596 if (C->getBitWidth() > 128) { return false; }
1599 AP = C->getValue().sextOrSelf(128);
1601 AP = C->getValue().zextOrSelf(128);
1603 *low = AP.getLoBits(64).getZExtValue();
1604 *high = AP.getHiBits(64).getZExtValue();
1608 enum class LLVMRustVisibility {
1614 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1616 case LLVMDefaultVisibility:
1617 return LLVMRustVisibility::Default;
1618 case LLVMHiddenVisibility:
1619 return LLVMRustVisibility::Hidden;
1620 case LLVMProtectedVisibility:
1621 return LLVMRustVisibility::Protected;
1623 report_fatal_error("Invalid LLVMRustVisibility value!");
1626 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1628 case LLVMRustVisibility::Default:
1629 return LLVMDefaultVisibility;
1630 case LLVMRustVisibility::Hidden:
1631 return LLVMHiddenVisibility;
1632 case LLVMRustVisibility::Protected:
1633 return LLVMProtectedVisibility;
1635 report_fatal_error("Invalid LLVMRustVisibility value!");
1638 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1639 return toRust(LLVMGetVisibility(V));
1642 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1643 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1644 LLVMTypeRef DestTy, bool isSigned) {
1645 return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1648 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1649 LLVMRustVisibility RustVisibility) {
1650 LLVMSetVisibility(V, fromRust(RustVisibility));
1653 extern "C" void LLVMRustSetDSOLocal(LLVMValueRef Global, bool is_dso_local) {
1654 unwrap<GlobalValue>(Global)->setDSOLocal(is_dso_local);
1657 struct LLVMRustModuleBuffer {
1661 extern "C" LLVMRustModuleBuffer*
1662 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1663 auto Ret = std::make_unique<LLVMRustModuleBuffer>();
1665 raw_string_ostream OS(Ret->data);
1667 legacy::PassManager PM;
1668 PM.add(createBitcodeWriterPass(OS));
1672 return Ret.release();
1676 LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1680 extern "C" const void*
1681 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1682 return Buffer->data.data();
1686 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1687 return Buffer->data.length();
1691 LLVMRustModuleCost(LLVMModuleRef M) {
1692 auto f = unwrap(M)->functions();
1693 return std::distance(std::begin(f), std::end(f));
1696 // Vector reductions:
1697 extern "C" LLVMValueRef
1698 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1699 return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1701 extern "C" LLVMValueRef
1702 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1703 return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1705 extern "C" LLVMValueRef
1706 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1707 return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1709 extern "C" LLVMValueRef
1710 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1711 return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1713 extern "C" LLVMValueRef
1714 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1715 return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1717 extern "C" LLVMValueRef
1718 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1719 return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1721 extern "C" LLVMValueRef
1722 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1723 return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1725 extern "C" LLVMValueRef
1726 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1727 return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1729 extern "C" LLVMValueRef
1730 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1731 return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1733 extern "C" LLVMValueRef
1734 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1735 Instruction *I = unwrap(B)->CreateFPMinReduce(unwrap(Src));
1736 I->setHasNoNaNs(NoNaN);
1739 extern "C" LLVMValueRef
1740 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1741 Instruction *I = unwrap(B)->CreateFPMaxReduce(unwrap(Src));
1742 I->setHasNoNaNs(NoNaN);
1746 extern "C" LLVMValueRef
1747 LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1748 return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1750 extern "C" LLVMValueRef
1751 LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1752 return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));
1755 // This struct contains all necessary info about a symbol exported from a DLL.
1756 struct LLVMRustCOFFShortExport {
1758 bool ordinal_present;
1759 // The value of `ordinal` is only meaningful if `ordinal_present` is true.
1763 // Machine must be a COFF machine type, as defined in PE specs.
1764 extern "C" LLVMRustResult LLVMRustWriteImportLibrary(
1765 const char* ImportName,
1767 const LLVMRustCOFFShortExport* Exports,
1772 std::vector<llvm::object::COFFShortExport> ConvertedExports;
1773 ConvertedExports.reserve(NumExports);
1775 for (size_t i = 0; i < NumExports; ++i) {
1776 bool ordinal_present = Exports[i].ordinal_present;
1777 uint16_t ordinal = ordinal_present ? Exports[i].ordinal : 0;
1778 ConvertedExports.push_back(llvm::object::COFFShortExport{
1779 Exports[i].name, // Name
1780 std::string{}, // ExtName
1781 std::string{}, // SymbolName
1782 std::string{}, // AliasTarget
1784 ordinal_present, // Noname
1791 auto Error = llvm::object::writeImportLibrary(
1795 static_cast<llvm::COFF::MachineTypes>(Machine),
1798 std::string errorString;
1799 llvm::raw_string_ostream stream(errorString);
1802 LLVMRustSetLastError(errorString.c_str());
1803 return LLVMRustResult::Failure;
1805 return LLVMRustResult::Success;
1809 // Transfers ownership of DiagnosticHandler unique_ptr to the caller.
1810 extern "C" DiagnosticHandler *
1811 LLVMRustContextGetDiagnosticHandler(LLVMContextRef C) {
1812 std::unique_ptr<DiagnosticHandler> DH = unwrap(C)->getDiagnosticHandler();
1813 return DH.release();
1816 // Sets unique_ptr to object of DiagnosticHandler to provide custom diagnostic
1817 // handling. Ownership of the handler is moved to the LLVMContext.
1818 extern "C" void LLVMRustContextSetDiagnosticHandler(LLVMContextRef C,
1819 DiagnosticHandler *DH) {
1820 unwrap(C)->setDiagnosticHandler(std::unique_ptr<DiagnosticHandler>(DH));
1823 using LLVMDiagnosticHandlerTy = DiagnosticHandler::DiagnosticHandlerTy;
1825 // Configures a diagnostic handler that invokes provided callback when a
1826 // backend needs to emit a diagnostic.
1828 // When RemarkAllPasses is true, remarks are enabled for all passes. Otherwise
1829 // the RemarkPasses array specifies individual passes for which remarks will be
1831 extern "C" void LLVMRustContextConfigureDiagnosticHandler(
1832 LLVMContextRef C, LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
1833 void *DiagnosticHandlerContext, bool RemarkAllPasses,
1834 const char * const * RemarkPasses, size_t RemarkPassesLen) {
1836 class RustDiagnosticHandler final : public DiagnosticHandler {
1838 RustDiagnosticHandler(LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
1839 void *DiagnosticHandlerContext,
1840 bool RemarkAllPasses,
1841 std::vector<std::string> RemarkPasses)
1842 : DiagnosticHandlerCallback(DiagnosticHandlerCallback),
1843 DiagnosticHandlerContext(DiagnosticHandlerContext),
1844 RemarkAllPasses(RemarkAllPasses),
1845 RemarkPasses(RemarkPasses) {}
1847 virtual bool handleDiagnostics(const DiagnosticInfo &DI) override {
1848 if (DiagnosticHandlerCallback) {
1849 DiagnosticHandlerCallback(DI, DiagnosticHandlerContext);
1855 bool isAnalysisRemarkEnabled(StringRef PassName) const override {
1856 return isRemarkEnabled(PassName);
1859 bool isMissedOptRemarkEnabled(StringRef PassName) const override {
1860 return isRemarkEnabled(PassName);
1863 bool isPassedOptRemarkEnabled(StringRef PassName) const override {
1864 return isRemarkEnabled(PassName);
1867 bool isAnyRemarkEnabled() const override {
1868 return RemarkAllPasses || !RemarkPasses.empty();
1872 bool isRemarkEnabled(StringRef PassName) const {
1873 if (RemarkAllPasses)
1876 for (auto &Pass : RemarkPasses)
1877 if (Pass == PassName)
1883 LLVMDiagnosticHandlerTy DiagnosticHandlerCallback = nullptr;
1884 void *DiagnosticHandlerContext = nullptr;
1886 bool RemarkAllPasses = false;
1887 std::vector<std::string> RemarkPasses;
1890 std::vector<std::string> Passes;
1891 for (size_t I = 0; I != RemarkPassesLen; ++I)
1892 Passes.push_back(RemarkPasses[I]);
1894 unwrap(C)->setDiagnosticHandler(std::make_unique<RustDiagnosticHandler>(
1895 DiagnosticHandlerCallback, DiagnosticHandlerContext, RemarkAllPasses, Passes));