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