2 #include "llvm/IR/DebugInfoMetadata.h"
3 #include "llvm/IR/DiagnosticInfo.h"
4 #include "llvm/IR/DiagnosticPrinter.h"
5 #include "llvm/IR/GlobalVariable.h"
6 #include "llvm/IR/Instructions.h"
7 #include "llvm/IR/Intrinsics.h"
8 #include "llvm/Object/Archive.h"
9 #include "llvm/Object/ObjectFile.h"
10 #include "llvm/Bitcode/BitcodeWriterPass.h"
11 #include "llvm/Support/Signals.h"
12 #include "llvm/ADT/Optional.h"
16 //===----------------------------------------------------------------------===
18 // This file defines alternate interfaces to core functions that are more
19 // readily callable by Rust's FFI.
21 //===----------------------------------------------------------------------===
24 using namespace llvm::sys;
25 using namespace llvm::object;
27 // LLVMAtomicOrdering is already an enum - don't create another
29 static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
31 case LLVMAtomicOrderingNotAtomic:
32 return AtomicOrdering::NotAtomic;
33 case LLVMAtomicOrderingUnordered:
34 return AtomicOrdering::Unordered;
35 case LLVMAtomicOrderingMonotonic:
36 return AtomicOrdering::Monotonic;
37 case LLVMAtomicOrderingAcquire:
38 return AtomicOrdering::Acquire;
39 case LLVMAtomicOrderingRelease:
40 return AtomicOrdering::Release;
41 case LLVMAtomicOrderingAcquireRelease:
42 return AtomicOrdering::AcquireRelease;
43 case LLVMAtomicOrderingSequentiallyConsistent:
44 return AtomicOrdering::SequentiallyConsistent;
47 report_fatal_error("Invalid LLVMAtomicOrdering value!");
50 static LLVM_THREAD_LOCAL char *LastError;
52 // Custom error handler for fatal LLVM errors.
54 // Notably it exits the process with code 101, unlike LLVM's default of 1.
55 static void FatalErrorHandler(void *UserData,
56 const std::string& Reason,
58 // Do the same thing that the default error handler does.
59 std::cerr << "LLVM ERROR: " << Reason << std::endl;
61 // Since this error handler exits the process, we have to run any cleanup that
62 // LLVM would run after handling the error. This might change with an LLVM
64 sys::RunInterruptHandlers();
69 extern "C" void LLVMRustInstallFatalErrorHandler() {
70 install_fatal_error_handler(FatalErrorHandler);
73 extern "C" LLVMMemoryBufferRef
74 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
75 ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =
76 MemoryBuffer::getFile(Path, -1, false);
78 LLVMRustSetLastError(BufOr.getError().message().c_str());
81 return wrap(BufOr.get().release());
84 extern "C" char *LLVMRustGetLastError(void) {
85 char *Ret = LastError;
90 extern "C" unsigned int LLVMRustGetInstructionCount(LLVMModuleRef M) {
91 return unwrap(M)->getInstructionCount();
94 extern "C" void LLVMRustSetLastError(const char *Err) {
95 free((void *)LastError);
96 LastError = strdup(Err);
99 extern "C" LLVMContextRef LLVMRustContextCreate(bool shouldDiscardNames) {
100 auto ctx = new LLVMContext();
101 ctx->setDiscardValueNames(shouldDiscardNames);
105 extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M,
106 const char *Triple) {
107 unwrap(M)->setTargetTriple(Triple::normalize(Triple));
110 extern "C" void LLVMRustPrintPassTimings() {
111 raw_fd_ostream OS(2, false); // stderr.
112 TimerGroup::printAll(OS);
115 extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
117 return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen)));
120 extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
123 LLVMTypeRef FunctionTy) {
124 return wrap(unwrap(M)
125 ->getOrInsertFunction(StringRef(Name, NameLen),
126 unwrap<FunctionType>(FunctionTy))
127 #if LLVM_VERSION_GE(9, 0)
133 extern "C" LLVMValueRef
134 LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) {
135 StringRef NameRef(Name, NameLen);
136 return wrap(unwrap(M)->getOrInsertGlobal(NameRef, unwrap(Ty)));
139 extern "C" LLVMValueRef
140 LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) {
141 return wrap(new GlobalVariable(*unwrap(M),
144 GlobalValue::PrivateLinkage,
148 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
149 return wrap(Type::getMetadataTy(*unwrap(C)));
152 static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
155 return Attribute::AlwaysInline;
157 return Attribute::ByVal;
159 return Attribute::Cold;
161 return Attribute::InlineHint;
163 return Attribute::MinSize;
165 return Attribute::Naked;
167 return Attribute::NoAlias;
169 return Attribute::NoCapture;
171 return Attribute::NoInline;
173 return Attribute::NonNull;
175 return Attribute::NoRedZone;
177 return Attribute::NoReturn;
179 return Attribute::NoUnwind;
180 case OptimizeForSize:
181 return Attribute::OptimizeForSize;
183 return Attribute::ReadOnly;
185 return Attribute::SExt;
187 return Attribute::StructRet;
189 return Attribute::UWTable;
191 return Attribute::ZExt;
193 return Attribute::InReg;
195 return Attribute::SanitizeThread;
196 case SanitizeAddress:
197 return Attribute::SanitizeAddress;
199 return Attribute::SanitizeMemory;
201 return Attribute::NonLazyBind;
203 return Attribute::OptimizeNone;
205 return Attribute::ReturnsTwice;
207 return Attribute::ReadNone;
208 case InaccessibleMemOnly:
209 return Attribute::InaccessibleMemOnly;
211 report_fatal_error("bad AttributeKind");
214 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
215 LLVMRustAttribute RustAttr) {
216 CallBase *Call = unwrap<CallBase>(Instr);
217 Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
218 Call->addAttribute(Index, Attr);
221 extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
224 CallBase *Call = unwrap<CallBase>(Instr);
226 B.addAlignmentAttr(Bytes);
227 Call->setAttributes(Call->getAttributes().addAttributes(
228 Call->getContext(), Index, B));
231 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
234 CallBase *Call = unwrap<CallBase>(Instr);
236 B.addDereferenceableAttr(Bytes);
237 Call->setAttributes(Call->getAttributes().addAttributes(
238 Call->getContext(), Index, B));
241 extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
244 CallBase *Call = unwrap<CallBase>(Instr);
246 B.addDereferenceableOrNullAttr(Bytes);
247 Call->setAttributes(Call->getAttributes().addAttributes(
248 Call->getContext(), Index, B));
251 extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index,
253 CallBase *Call = unwrap<CallBase>(Instr);
254 #if LLVM_VERSION_GE(9, 0)
255 Attribute Attr = Attribute::getWithByValType(Call->getContext(), unwrap(Ty));
257 Attribute Attr = Attribute::get(Call->getContext(), Attribute::ByVal);
259 Call->addAttribute(Index, Attr);
262 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
263 LLVMRustAttribute RustAttr) {
264 Function *A = unwrap<Function>(Fn);
265 Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
267 A->addAttributes(Index, B);
270 extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn,
273 Function *A = unwrap<Function>(Fn);
275 B.addAlignmentAttr(Bytes);
276 A->addAttributes(Index, B);
279 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
281 Function *A = unwrap<Function>(Fn);
283 B.addDereferenceableAttr(Bytes);
284 A->addAttributes(Index, B);
287 extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
290 Function *A = unwrap<Function>(Fn);
292 B.addDereferenceableOrNullAttr(Bytes);
293 A->addAttributes(Index, B);
296 extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index,
298 Function *F = unwrap<Function>(Fn);
299 #if LLVM_VERSION_GE(9, 0)
300 Attribute Attr = Attribute::getWithByValType(F->getContext(), unwrap(Ty));
302 Attribute Attr = Attribute::get(F->getContext(), Attribute::ByVal);
304 F->addAttribute(Index, Attr);
307 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
311 Function *F = unwrap<Function>(Fn);
313 B.addAttribute(Name, Value);
314 F->addAttributes(Index, B);
317 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
319 LLVMRustAttribute RustAttr) {
320 Function *F = unwrap<Function>(Fn);
321 Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
323 auto PAL = F->getAttributes();
324 auto PALNew = PAL.removeAttributes(F->getContext(), Index, B);
325 F->setAttributes(PALNew);
328 // enable fpmath flag UnsafeAlgebra
329 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
330 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
335 extern "C" LLVMValueRef
336 LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef Source, const char *Name,
337 LLVMAtomicOrdering Order) {
338 Value *Ptr = unwrap(Source);
339 Type *Ty = Ptr->getType()->getPointerElementType();
340 LoadInst *LI = unwrap(B)->CreateLoad(Ty, Ptr, Name);
341 LI->setAtomic(fromRust(Order));
345 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
348 LLVMAtomicOrdering Order) {
349 StoreInst *SI = unwrap(B)->CreateStore(unwrap(V), unwrap(Target));
350 SI->setAtomic(fromRust(Order));
354 // FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak
355 // once we raise our minimum support to LLVM 10.
356 extern "C" LLVMValueRef
357 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
358 LLVMValueRef Old, LLVMValueRef Source,
359 LLVMAtomicOrdering Order,
360 LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
361 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
362 unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
363 fromRust(FailureOrder));
368 enum class LLVMRustSynchronizationScope {
374 static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
376 case LLVMRustSynchronizationScope::SingleThread:
377 return SyncScope::SingleThread;
378 case LLVMRustSynchronizationScope::CrossThread:
379 return SyncScope::System;
381 report_fatal_error("bad SynchronizationScope.");
385 extern "C" LLVMValueRef
386 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
387 LLVMRustSynchronizationScope Scope) {
388 return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
391 enum class LLVMRustAsmDialect {
397 static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
399 case LLVMRustAsmDialect::Att:
400 return InlineAsm::AD_ATT;
401 case LLVMRustAsmDialect::Intel:
402 return InlineAsm::AD_Intel;
404 report_fatal_error("bad AsmDialect.");
408 extern "C" LLVMValueRef
409 LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
410 char *Constraints, size_t ConstraintsLen,
411 LLVMBool HasSideEffects, LLVMBool IsAlignStack,
412 LLVMRustAsmDialect Dialect) {
413 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
414 StringRef(AsmString, AsmStringLen),
415 StringRef(Constraints, ConstraintsLen),
416 HasSideEffects, IsAlignStack, fromRust(Dialect)));
419 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
420 size_t ConstraintsLen) {
421 return InlineAsm::Verify(unwrap<FunctionType>(Ty),
422 StringRef(Constraints, ConstraintsLen));
425 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
427 unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen));
430 typedef DIBuilder *LLVMRustDIBuilderRef;
432 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
433 return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
436 #define DIDescriptor DIScope
437 #define DIArray DINodeArray
438 #define unwrapDI unwrapDIPtr
440 // These values **must** match debuginfo::DIFlags! They also *happen*
441 // to match LLVM, but that isn't required as we do giant sets of
442 // matching below. The value shouldn't be directly passed to LLVM.
443 enum class LLVMRustDIFlags : uint32_t {
448 FlagFwdDecl = (1 << 2),
449 FlagAppleBlock = (1 << 3),
450 FlagBlockByrefStruct = (1 << 4),
451 FlagVirtual = (1 << 5),
452 FlagArtificial = (1 << 6),
453 FlagExplicit = (1 << 7),
454 FlagPrototyped = (1 << 8),
455 FlagObjcClassComplete = (1 << 9),
456 FlagObjectPointer = (1 << 10),
457 FlagVector = (1 << 11),
458 FlagStaticMember = (1 << 12),
459 FlagLValueReference = (1 << 13),
460 FlagRValueReference = (1 << 14),
461 FlagExternalTypeRef = (1 << 15),
462 FlagIntroducedVirtual = (1 << 18),
463 FlagBitField = (1 << 19),
464 FlagNoReturn = (1 << 20),
465 // Do not add values that are not supported by the minimum LLVM
466 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
469 inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
470 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
471 static_cast<uint32_t>(B));
474 inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
475 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
476 static_cast<uint32_t>(B));
479 inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
483 inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
485 inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
486 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
489 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
490 DINode::DIFlags Result = DINode::DIFlags::FlagZero;
492 switch (visibility(Flags)) {
493 case LLVMRustDIFlags::FlagPrivate:
494 Result |= DINode::DIFlags::FlagPrivate;
496 case LLVMRustDIFlags::FlagProtected:
497 Result |= DINode::DIFlags::FlagProtected;
499 case LLVMRustDIFlags::FlagPublic:
500 Result |= DINode::DIFlags::FlagPublic;
503 // The rest are handled below
507 if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
508 Result |= DINode::DIFlags::FlagFwdDecl;
510 if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
511 Result |= DINode::DIFlags::FlagAppleBlock;
513 #if LLVM_VERSION_LT(10, 0)
514 if (isSet(Flags & LLVMRustDIFlags::FlagBlockByrefStruct)) {
515 Result |= DINode::DIFlags::FlagBlockByrefStruct;
518 if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
519 Result |= DINode::DIFlags::FlagVirtual;
521 if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
522 Result |= DINode::DIFlags::FlagArtificial;
524 if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
525 Result |= DINode::DIFlags::FlagExplicit;
527 if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
528 Result |= DINode::DIFlags::FlagPrototyped;
530 if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
531 Result |= DINode::DIFlags::FlagObjcClassComplete;
533 if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
534 Result |= DINode::DIFlags::FlagObjectPointer;
536 if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
537 Result |= DINode::DIFlags::FlagVector;
539 if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
540 Result |= DINode::DIFlags::FlagStaticMember;
542 if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
543 Result |= DINode::DIFlags::FlagLValueReference;
545 if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
546 Result |= DINode::DIFlags::FlagRValueReference;
548 if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
549 Result |= DINode::DIFlags::FlagIntroducedVirtual;
551 if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
552 Result |= DINode::DIFlags::FlagBitField;
554 if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
555 Result |= DINode::DIFlags::FlagNoReturn;
561 // These values **must** match debuginfo::DISPFlags! They also *happen*
562 // to match LLVM, but that isn't required as we do giant sets of
563 // matching below. The value shouldn't be directly passed to LLVM.
564 enum class LLVMRustDISPFlags : uint32_t {
567 SPFlagPureVirtual = 2,
568 SPFlagLocalToUnit = (1 << 2),
569 SPFlagDefinition = (1 << 3),
570 SPFlagOptimized = (1 << 4),
571 SPFlagMainSubprogram = (1 << 5),
572 // Do not add values that are not supported by the minimum LLVM
573 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
574 // (In LLVM < 8, createFunction supported these as separate bool arguments.)
577 inline LLVMRustDISPFlags operator&(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
578 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) &
579 static_cast<uint32_t>(B));
582 inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
583 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) |
584 static_cast<uint32_t>(B));
587 inline LLVMRustDISPFlags &operator|=(LLVMRustDISPFlags &A, LLVMRustDISPFlags B) {
591 inline bool isSet(LLVMRustDISPFlags F) { return F != LLVMRustDISPFlags::SPFlagZero; }
593 inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) {
594 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(F) & 0x3);
597 static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) {
598 DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero;
600 switch (virtuality(SPFlags)) {
601 case LLVMRustDISPFlags::SPFlagVirtual:
602 Result |= DISubprogram::DISPFlags::SPFlagVirtual;
604 case LLVMRustDISPFlags::SPFlagPureVirtual:
605 Result |= DISubprogram::DISPFlags::SPFlagPureVirtual;
608 // The rest are handled below
612 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit)) {
613 Result |= DISubprogram::DISPFlags::SPFlagLocalToUnit;
615 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition)) {
616 Result |= DISubprogram::DISPFlags::SPFlagDefinition;
618 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) {
619 Result |= DISubprogram::DISPFlags::SPFlagOptimized;
621 #if LLVM_VERSION_GE(9, 0)
622 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) {
623 Result |= DISubprogram::DISPFlags::SPFlagMainSubprogram;
630 enum class LLVMRustDebugEmissionKind {
636 static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
638 case LLVMRustDebugEmissionKind::NoDebug:
639 return DICompileUnit::DebugEmissionKind::NoDebug;
640 case LLVMRustDebugEmissionKind::FullDebug:
641 return DICompileUnit::DebugEmissionKind::FullDebug;
642 case LLVMRustDebugEmissionKind::LineTablesOnly:
643 return DICompileUnit::DebugEmissionKind::LineTablesOnly;
645 report_fatal_error("bad DebugEmissionKind.");
649 enum class LLVMRustChecksumKind {
655 static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
657 case LLVMRustChecksumKind::None:
659 case LLVMRustChecksumKind::MD5:
660 return DIFile::ChecksumKind::CSK_MD5;
661 case LLVMRustChecksumKind::SHA1:
662 return DIFile::ChecksumKind::CSK_SHA1;
664 report_fatal_error("bad ChecksumKind.");
668 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
669 return DEBUG_METADATA_VERSION;
672 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
674 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
676 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
678 unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
681 extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
682 return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
685 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
686 return new DIBuilder(*unwrap(M));
689 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
693 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
697 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
698 LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
699 const char *Producer, size_t ProducerLen, bool isOptimized,
700 const char *Flags, unsigned RuntimeVer,
701 const char *SplitName, size_t SplitNameLen,
702 LLVMRustDebugEmissionKind Kind) {
703 auto *File = unwrapDI<DIFile>(FileRef);
705 return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
706 isOptimized, Flags, RuntimeVer,
707 StringRef(SplitName, SplitNameLen),
711 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
712 LLVMRustDIBuilderRef Builder,
713 const char *Filename, size_t FilenameLen,
714 const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
715 const char *Checksum, size_t ChecksumLen) {
716 Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
717 Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
719 CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
720 return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
721 StringRef(Directory, DirectoryLen),
725 extern "C" LLVMMetadataRef
726 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
727 LLVMMetadataRef ParameterTypes) {
728 return wrap(Builder->createSubroutineType(
729 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
732 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
733 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
734 const char *Name, size_t NameLen,
735 const char *LinkageName, size_t LinkageNameLen,
736 LLVMMetadataRef File, unsigned LineNo,
737 LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
738 LLVMRustDISPFlags SPFlags, LLVMValueRef Fn, LLVMMetadataRef TParam,
739 LLVMMetadataRef Decl) {
740 DITemplateParameterArray TParams =
741 DITemplateParameterArray(unwrap<MDTuple>(TParam));
742 DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
743 DINode::DIFlags llvmFlags = fromRust(Flags);
744 #if LLVM_VERSION_LT(9, 0)
745 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram))
746 llvmFlags |= DINode::DIFlags::FlagMainSubprogram;
748 DISubprogram *Sub = Builder->createFunction(
749 unwrapDI<DIScope>(Scope),
750 StringRef(Name, NameLen),
751 StringRef(LinkageName, LinkageNameLen),
752 unwrapDI<DIFile>(File), LineNo,
753 unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
754 llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
755 unwrap<Function>(Fn)->setSubprogram(Sub);
759 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
760 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
761 uint64_t SizeInBits, unsigned Encoding) {
762 return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
765 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
766 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
767 LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
768 return wrap(Builder->createTypedef(
769 unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
770 LineNo, unwrap<DIScope>(Scope)));
773 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
774 LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
775 uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
776 const char *Name, size_t NameLen) {
777 return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
778 SizeInBits, AlignInBits,
780 StringRef(Name, NameLen)));
783 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
784 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
785 const char *Name, size_t NameLen,
786 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
787 uint32_t AlignInBits, LLVMRustDIFlags Flags,
788 LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
789 unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
790 const char *UniqueId, size_t UniqueIdLen) {
791 return wrap(Builder->createStructType(
792 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
793 unwrapDI<DIFile>(File), LineNumber,
794 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
795 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
796 unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen)));
799 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
800 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
801 const char *Name, size_t NameLen,
802 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
803 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
804 LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) {
805 return wrap(Builder->createVariantPart(
806 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
807 unwrapDI<DIFile>(File), LineNumber,
808 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
809 DINodeArray(unwrapDI<MDTuple>(Elements)), StringRef(UniqueId, UniqueIdLen)));
812 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
813 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
814 const char *Name, size_t NameLen,
815 LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
816 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
817 LLVMMetadataRef Ty) {
818 return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope),
819 StringRef(Name, NameLen),
820 unwrapDI<DIFile>(File), LineNo,
821 SizeInBits, AlignInBits, OffsetInBits,
822 fromRust(Flags), unwrapDI<DIType>(Ty)));
825 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
826 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
827 const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
828 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
829 LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
830 llvm::ConstantInt* D = nullptr;
832 D = unwrap<llvm::ConstantInt>(Discriminant);
834 return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope),
835 StringRef(Name, NameLen),
836 unwrapDI<DIFile>(File), LineNo,
837 SizeInBits, AlignInBits, OffsetInBits, D,
838 fromRust(Flags), unwrapDI<DIType>(Ty)));
841 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
842 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
843 LLVMMetadataRef File, unsigned Line, unsigned Col) {
844 return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
845 unwrapDI<DIFile>(File), Line, Col));
848 extern "C" LLVMMetadataRef
849 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
850 LLVMMetadataRef Scope,
851 LLVMMetadataRef File) {
852 return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
853 unwrapDI<DIFile>(File)));
856 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
857 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context,
858 const char *Name, size_t NameLen,
859 const char *LinkageName, size_t LinkageNameLen,
860 LLVMMetadataRef File, unsigned LineNo,
861 LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
862 LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
863 llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
865 llvm::DIExpression *InitExpr = nullptr;
866 if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
867 InitExpr = Builder->createConstantValueExpression(
868 IntVal->getValue().getSExtValue());
869 } else if (llvm::ConstantFP *FPVal =
870 llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
871 InitExpr = Builder->createConstantValueExpression(
872 FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
875 llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
876 unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
877 StringRef(LinkageName, LinkageNameLen),
878 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
879 #if LLVM_VERSION_GE(10, 0)
880 /* isDefined */ true,
882 InitExpr, unwrapDIPtr<MDNode>(Decl),
883 /* templateParams */ nullptr,
886 InitVal->setMetadata("dbg", VarExpr);
888 return wrap(VarExpr);
891 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
892 LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
893 const char *Name, size_t NameLen,
894 LLVMMetadataRef File, unsigned LineNo,
895 LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
896 unsigned ArgNo, uint32_t AlignInBits) {
897 if (Tag == 0x100) { // DW_TAG_auto_variable
898 return wrap(Builder->createAutoVariable(
899 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
900 unwrapDI<DIFile>(File), LineNo,
901 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
903 return wrap(Builder->createParameterVariable(
904 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
905 unwrapDI<DIFile>(File), LineNo,
906 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
910 extern "C" LLVMMetadataRef
911 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
912 uint32_t AlignInBits, LLVMMetadataRef Ty,
913 LLVMMetadataRef Subscripts) {
915 Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
916 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
919 extern "C" LLVMMetadataRef
920 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
922 return wrap(Builder->getOrCreateSubrange(Lo, Count));
925 extern "C" LLVMMetadataRef
926 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
927 LLVMMetadataRef *Ptr, unsigned Count) {
928 Metadata **DataValue = unwrap(Ptr);
930 Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
933 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
934 LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
935 int64_t *AddrOps, unsigned AddrOpsCount, LLVMValueRef DL,
936 LLVMBasicBlockRef InsertAtEnd) {
937 return wrap(Builder->insertDeclare(
938 unwrap(V), unwrap<DILocalVariable>(VarInfo),
939 Builder->createExpression(llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
940 DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
941 unwrap(InsertAtEnd)));
944 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
945 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
946 int64_t Value, bool IsUnsigned) {
947 return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
950 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
951 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
952 const char *Name, size_t NameLen,
953 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
954 uint32_t AlignInBits, LLVMMetadataRef Elements,
955 LLVMMetadataRef ClassTy, bool IsScoped) {
956 return wrap(Builder->createEnumerationType(
957 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
958 unwrapDI<DIFile>(File), LineNumber,
959 SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
960 unwrapDI<DIType>(ClassTy), "", IsScoped));
963 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
964 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
965 const char *Name, size_t NameLen,
966 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
967 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
968 unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) {
969 return wrap(Builder->createUnionType(
970 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File),
971 LineNumber, SizeInBits, AlignInBits, fromRust(Flags),
972 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
973 StringRef(UniqueId, UniqueIdLen)));
976 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
977 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
978 const char *Name, size_t NameLen, LLVMMetadataRef Ty) {
979 #if LLVM_VERSION_GE(11, 0)
980 bool IsDefault = false; // FIXME: should we ever set this true?
981 return wrap(Builder->createTemplateTypeParameter(
982 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty), IsDefault));
984 return wrap(Builder->createTemplateTypeParameter(
985 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty)));
989 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateNameSpace(
990 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
991 const char *Name, size_t NameLen, bool ExportSymbols) {
992 return wrap(Builder->createNameSpace(
993 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols
998 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
999 LLVMMetadataRef CompositeTy,
1000 LLVMMetadataRef Elements,
1001 LLVMMetadataRef Params) {
1002 DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
1003 Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
1004 DINodeArray(unwrap<MDTuple>(Params)));
1007 extern "C" LLVMValueRef
1008 LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef, unsigned Line,
1009 unsigned Column, LLVMMetadataRef Scope,
1010 LLVMMetadataRef InlinedAt) {
1011 LLVMContext &Context = *unwrap(ContextRef);
1013 DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(Scope),
1014 unwrapDIPtr<MDNode>(InlinedAt));
1016 return wrap(MetadataAsValue::get(Context, debug_loc.getAsMDNode()));
1019 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
1020 return dwarf::DW_OP_deref;
1023 extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1024 return dwarf::DW_OP_plus_uconst;
1027 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
1028 RawRustStringOstream OS(Str);
1029 unwrap<llvm::Type>(Ty)->print(OS);
1032 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
1033 RustStringRef Str) {
1034 RawRustStringOstream OS(Str);
1039 unwrap<llvm::Value>(V)->getType()->print(OS);
1041 unwrap<llvm::Value>(V)->print(OS);
1046 // Note that the two following functions look quite similar to the
1047 // LLVMGetSectionName function. Sadly, it appears that this function only
1048 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
1049 // function provided by LLVM doesn't return the length, so we've created our own
1050 // function which returns the length as well as the data pointer.
1052 // For an example of this not returning a null terminated string, see
1053 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
1054 // branches explicitly creates a StringRef without a null terminator, and then
1057 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
1058 return reinterpret_cast<section_iterator *>(SI);
1061 extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI,
1063 #if LLVM_VERSION_GE(10, 0)
1064 auto NameOrErr = (*unwrap(SI))->getName();
1066 report_fatal_error(NameOrErr.takeError());
1067 *Ptr = NameOrErr->data();
1068 return NameOrErr->size();
1071 if (std::error_code EC = (*unwrap(SI))->getName(Ret))
1072 report_fatal_error(EC.message());
1078 // LLVMArrayType function does not support 64-bit ElementCount
1079 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
1080 uint64_t ElementCount) {
1081 return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
1084 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1086 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
1087 RawRustStringOstream OS(Str);
1088 unwrap(T)->print(OS);
1091 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1092 LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
1093 LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
1094 RustStringRef FilenameOut, RustStringRef MessageOut) {
1095 // Undefined to call this not on an optimization diagnostic!
1096 llvm::DiagnosticInfoOptimizationBase *Opt =
1097 static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
1099 RawRustStringOstream PassNameOS(PassNameOut);
1100 PassNameOS << Opt->getPassName();
1101 *FunctionOut = wrap(&Opt->getFunction());
1103 RawRustStringOstream FilenameOS(FilenameOut);
1104 DiagnosticLocation loc = Opt->getLocation();
1105 if (loc.isValid()) {
1106 *Line = loc.getLine();
1107 *Column = loc.getColumn();
1108 FilenameOS << loc.getAbsolutePath();
1111 RawRustStringOstream MessageOS(MessageOut);
1112 MessageOS << Opt->getMsg();
1115 enum class LLVMRustDiagnosticLevel {
1123 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
1124 LLVMRustDiagnosticLevel *LevelOut,
1125 unsigned *CookieOut,
1126 LLVMTwineRef *MessageOut,
1127 LLVMValueRef *InstructionOut) {
1128 // Undefined to call this not on an inline assembly diagnostic!
1129 llvm::DiagnosticInfoInlineAsm *IA =
1130 static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
1132 *CookieOut = IA->getLocCookie();
1133 *MessageOut = wrap(&IA->getMsgStr());
1134 *InstructionOut = wrap(IA->getInstruction());
1136 switch (IA->getSeverity()) {
1138 *LevelOut = LLVMRustDiagnosticLevel::Error;
1141 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1144 *LevelOut = LLVMRustDiagnosticLevel::Note;
1147 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1150 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1154 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
1155 RustStringRef Str) {
1156 RawRustStringOstream OS(Str);
1157 DiagnosticPrinterRawOStream DP(OS);
1158 unwrap(DI)->print(DP);
1161 enum class LLVMRustDiagnosticKind {
1165 DebugMetadataVersion,
1168 OptimizationRemarkMissed,
1169 OptimizationRemarkAnalysis,
1170 OptimizationRemarkAnalysisFPCommute,
1171 OptimizationRemarkAnalysisAliasing,
1172 OptimizationRemarkOther,
1173 OptimizationFailure,
1178 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1181 return LLVMRustDiagnosticKind::InlineAsm;
1183 return LLVMRustDiagnosticKind::StackSize;
1184 case DK_DebugMetadataVersion:
1185 return LLVMRustDiagnosticKind::DebugMetadataVersion;
1186 case DK_SampleProfile:
1187 return LLVMRustDiagnosticKind::SampleProfile;
1188 case DK_OptimizationRemark:
1189 return LLVMRustDiagnosticKind::OptimizationRemark;
1190 case DK_OptimizationRemarkMissed:
1191 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1192 case DK_OptimizationRemarkAnalysis:
1193 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1194 case DK_OptimizationRemarkAnalysisFPCommute:
1195 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1196 case DK_OptimizationRemarkAnalysisAliasing:
1197 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1199 return LLVMRustDiagnosticKind::PGOProfile;
1201 return LLVMRustDiagnosticKind::Linker;
1203 return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1204 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1205 : LLVMRustDiagnosticKind::Other;
1209 extern "C" LLVMRustDiagnosticKind
1210 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1211 return toRust((DiagnosticKind)unwrap(DI)->getKind());
1214 // This is kept distinct from LLVMGetTypeKind, because when
1215 // a new type kind is added, the Rust-side enum must be
1216 // updated or UB will result.
1217 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1218 switch (unwrap(Ty)->getTypeID()) {
1219 case Type::VoidTyID:
1220 return LLVMVoidTypeKind;
1221 case Type::HalfTyID:
1222 return LLVMHalfTypeKind;
1223 case Type::FloatTyID:
1224 return LLVMFloatTypeKind;
1225 case Type::DoubleTyID:
1226 return LLVMDoubleTypeKind;
1227 case Type::X86_FP80TyID:
1228 return LLVMX86_FP80TypeKind;
1229 case Type::FP128TyID:
1230 return LLVMFP128TypeKind;
1231 case Type::PPC_FP128TyID:
1232 return LLVMPPC_FP128TypeKind;
1233 case Type::LabelTyID:
1234 return LLVMLabelTypeKind;
1235 case Type::MetadataTyID:
1236 return LLVMMetadataTypeKind;
1237 case Type::IntegerTyID:
1238 return LLVMIntegerTypeKind;
1239 case Type::FunctionTyID:
1240 return LLVMFunctionTypeKind;
1241 case Type::StructTyID:
1242 return LLVMStructTypeKind;
1243 case Type::ArrayTyID:
1244 return LLVMArrayTypeKind;
1245 case Type::PointerTyID:
1246 return LLVMPointerTypeKind;
1247 #if LLVM_VERSION_GE(11, 0)
1248 case Type::FixedVectorTyID:
1249 return LLVMVectorTypeKind;
1251 case Type::VectorTyID:
1252 return LLVMVectorTypeKind;
1254 case Type::X86_MMXTyID:
1255 return LLVMX86_MMXTypeKind;
1256 case Type::TokenTyID:
1257 return LLVMTokenTypeKind;
1258 #if LLVM_VERSION_GE(11, 0)
1259 case Type::ScalableVectorTyID:
1260 return LLVMScalableVectorTypeKind;
1261 case Type::BFloatTyID:
1262 return LLVMBFloatTypeKind;
1265 report_fatal_error("Unhandled TypeID.");
1268 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1270 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1271 LLVMContextRef C, LLVMContext::InlineAsmDiagHandlerTy H, void *CX) {
1272 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1275 extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
1276 RustStringRef MessageOut,
1277 RustStringRef BufferOut,
1278 LLVMRustDiagnosticLevel* LevelOut,
1280 unsigned* RangesOut,
1281 size_t* NumRanges) {
1282 SMDiagnostic& D = *unwrap(DRef);
1283 RawRustStringOstream MessageOS(MessageOut);
1284 MessageOS << D.getMessage();
1286 switch (D.getKind()) {
1287 case SourceMgr::DK_Error:
1288 *LevelOut = LLVMRustDiagnosticLevel::Error;
1290 case SourceMgr::DK_Warning:
1291 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1293 case SourceMgr::DK_Note:
1294 *LevelOut = LLVMRustDiagnosticLevel::Note;
1296 case SourceMgr::DK_Remark:
1297 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1300 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1303 if (D.getLoc() == SMLoc())
1306 const SourceMgr &LSM = *D.getSourceMgr();
1307 const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
1308 LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), LBuf->getBufferSize());
1310 *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
1312 *NumRanges = std::min(*NumRanges, D.getRanges().size());
1313 size_t LineStart = *LocOut - (size_t)D.getColumnNo();
1314 for (size_t i = 0; i < *NumRanges; i++) {
1315 RangesOut[i * 2] = LineStart + D.getRanges()[i].first;
1316 RangesOut[i * 2 + 1] = LineStart + D.getRanges()[i].second;
1322 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1323 LLVMValueRef ParentPad,
1325 LLVMValueRef *LLArgs,
1327 Value **Args = unwrap(LLArgs);
1328 if (ParentPad == nullptr) {
1329 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1330 ParentPad = wrap(Constant::getNullValue(Ty));
1332 return wrap(unwrap(B)->CreateCleanupPad(
1333 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1336 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1337 LLVMValueRef CleanupPad,
1338 LLVMBasicBlockRef UnwindBB) {
1339 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1340 return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1343 extern "C" LLVMValueRef
1344 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1345 unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1346 Value **Args = unwrap(LLArgs);
1347 return wrap(unwrap(B)->CreateCatchPad(
1348 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1351 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1353 LLVMBasicBlockRef BB) {
1354 return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1358 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1359 LLVMValueRef ParentPad,
1360 LLVMBasicBlockRef BB,
1361 unsigned NumHandlers,
1363 if (ParentPad == nullptr) {
1364 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1365 ParentPad = wrap(Constant::getNullValue(Ty));
1367 return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1368 NumHandlers, Name));
1371 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1372 LLVMBasicBlockRef Handler) {
1373 Value *CatchSwitch = unwrap(CatchSwitchRef);
1374 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1377 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1378 LLVMValueRef *Inputs,
1379 unsigned NumInputs) {
1380 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1383 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1387 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
1388 LLVMValueRef *Args, unsigned NumArgs,
1389 OperandBundleDef *Bundle) {
1390 Value *Callee = unwrap(Fn);
1391 FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1392 unsigned Len = Bundle ? 1 : 0;
1393 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1394 return wrap(unwrap(B)->CreateCall(
1395 FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles));
1398 extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
1399 return wrap(llvm::Intrinsic::getDeclaration(unwrap(M),
1400 (llvm::Intrinsic::ID)llvm::Intrinsic::instrprof_increment));
1403 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
1404 LLVMValueRef Dst, unsigned DstAlign,
1405 LLVMValueRef Src, unsigned SrcAlign,
1406 LLVMValueRef Size, bool IsVolatile) {
1407 #if LLVM_VERSION_GE(10, 0)
1408 return wrap(unwrap(B)->CreateMemCpy(
1409 unwrap(Dst), MaybeAlign(DstAlign),
1410 unwrap(Src), MaybeAlign(SrcAlign),
1411 unwrap(Size), IsVolatile));
1413 return wrap(unwrap(B)->CreateMemCpy(
1414 unwrap(Dst), DstAlign,
1415 unwrap(Src), SrcAlign,
1416 unwrap(Size), IsVolatile));
1420 extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
1421 LLVMValueRef Dst, unsigned DstAlign,
1422 LLVMValueRef Src, unsigned SrcAlign,
1423 LLVMValueRef Size, bool IsVolatile) {
1424 #if LLVM_VERSION_GE(10, 0)
1425 return wrap(unwrap(B)->CreateMemMove(
1426 unwrap(Dst), MaybeAlign(DstAlign),
1427 unwrap(Src), MaybeAlign(SrcAlign),
1428 unwrap(Size), IsVolatile));
1430 return wrap(unwrap(B)->CreateMemMove(
1431 unwrap(Dst), DstAlign,
1432 unwrap(Src), SrcAlign,
1433 unwrap(Size), IsVolatile));
1437 extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
1438 LLVMValueRef Dst, unsigned DstAlign,
1440 LLVMValueRef Size, bool IsVolatile) {
1441 #if LLVM_VERSION_GE(10, 0)
1442 return wrap(unwrap(B)->CreateMemSet(
1443 unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
1445 return wrap(unwrap(B)->CreateMemSet(
1446 unwrap(Dst), unwrap(Val), unwrap(Size), DstAlign, IsVolatile));
1450 extern "C" LLVMValueRef
1451 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
1452 unsigned NumArgs, LLVMBasicBlockRef Then,
1453 LLVMBasicBlockRef Catch, OperandBundleDef *Bundle,
1455 Value *Callee = unwrap(Fn);
1456 FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1457 unsigned Len = Bundle ? 1 : 0;
1458 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1459 return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
1460 makeArrayRef(unwrap(Args), NumArgs),
1464 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1465 LLVMBasicBlockRef BB) {
1466 auto Point = unwrap(BB)->getFirstInsertionPt();
1467 unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1470 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1471 const char *Name, size_t NameLen) {
1472 Triple TargetTriple(unwrap(M)->getTargetTriple());
1473 GlobalObject *GV = unwrap<GlobalObject>(V);
1474 if (!TargetTriple.isOSBinFormatMachO()) {
1475 StringRef NameRef(Name, NameLen);
1476 GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
1480 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1481 GlobalObject *GV = unwrap<GlobalObject>(V);
1482 GV->setComdat(nullptr);
1485 enum class LLVMRustLinkage {
1486 ExternalLinkage = 0,
1487 AvailableExternallyLinkage = 1,
1488 LinkOnceAnyLinkage = 2,
1489 LinkOnceODRLinkage = 3,
1492 AppendingLinkage = 6,
1493 InternalLinkage = 7,
1495 ExternalWeakLinkage = 9,
1499 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1501 case LLVMExternalLinkage:
1502 return LLVMRustLinkage::ExternalLinkage;
1503 case LLVMAvailableExternallyLinkage:
1504 return LLVMRustLinkage::AvailableExternallyLinkage;
1505 case LLVMLinkOnceAnyLinkage:
1506 return LLVMRustLinkage::LinkOnceAnyLinkage;
1507 case LLVMLinkOnceODRLinkage:
1508 return LLVMRustLinkage::LinkOnceODRLinkage;
1509 case LLVMWeakAnyLinkage:
1510 return LLVMRustLinkage::WeakAnyLinkage;
1511 case LLVMWeakODRLinkage:
1512 return LLVMRustLinkage::WeakODRLinkage;
1513 case LLVMAppendingLinkage:
1514 return LLVMRustLinkage::AppendingLinkage;
1515 case LLVMInternalLinkage:
1516 return LLVMRustLinkage::InternalLinkage;
1517 case LLVMPrivateLinkage:
1518 return LLVMRustLinkage::PrivateLinkage;
1519 case LLVMExternalWeakLinkage:
1520 return LLVMRustLinkage::ExternalWeakLinkage;
1521 case LLVMCommonLinkage:
1522 return LLVMRustLinkage::CommonLinkage;
1524 report_fatal_error("Invalid LLVMRustLinkage value!");
1528 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1530 case LLVMRustLinkage::ExternalLinkage:
1531 return LLVMExternalLinkage;
1532 case LLVMRustLinkage::AvailableExternallyLinkage:
1533 return LLVMAvailableExternallyLinkage;
1534 case LLVMRustLinkage::LinkOnceAnyLinkage:
1535 return LLVMLinkOnceAnyLinkage;
1536 case LLVMRustLinkage::LinkOnceODRLinkage:
1537 return LLVMLinkOnceODRLinkage;
1538 case LLVMRustLinkage::WeakAnyLinkage:
1539 return LLVMWeakAnyLinkage;
1540 case LLVMRustLinkage::WeakODRLinkage:
1541 return LLVMWeakODRLinkage;
1542 case LLVMRustLinkage::AppendingLinkage:
1543 return LLVMAppendingLinkage;
1544 case LLVMRustLinkage::InternalLinkage:
1545 return LLVMInternalLinkage;
1546 case LLVMRustLinkage::PrivateLinkage:
1547 return LLVMPrivateLinkage;
1548 case LLVMRustLinkage::ExternalWeakLinkage:
1549 return LLVMExternalWeakLinkage;
1550 case LLVMRustLinkage::CommonLinkage:
1551 return LLVMCommonLinkage;
1553 report_fatal_error("Invalid LLVMRustLinkage value!");
1556 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1557 return toRust(LLVMGetLinkage(V));
1560 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1561 LLVMRustLinkage RustLinkage) {
1562 LLVMSetLinkage(V, fromRust(RustLinkage));
1565 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1566 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1567 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1569 auto C = unwrap<llvm::ConstantInt>(CV);
1570 if (C->getBitWidth() > 128) { return false; }
1573 AP = C->getValue().sextOrSelf(128);
1575 AP = C->getValue().zextOrSelf(128);
1577 *low = AP.getLoBits(64).getZExtValue();
1578 *high = AP.getHiBits(64).getZExtValue();
1582 enum class LLVMRustVisibility {
1588 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1590 case LLVMDefaultVisibility:
1591 return LLVMRustVisibility::Default;
1592 case LLVMHiddenVisibility:
1593 return LLVMRustVisibility::Hidden;
1594 case LLVMProtectedVisibility:
1595 return LLVMRustVisibility::Protected;
1597 report_fatal_error("Invalid LLVMRustVisibility value!");
1600 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1602 case LLVMRustVisibility::Default:
1603 return LLVMDefaultVisibility;
1604 case LLVMRustVisibility::Hidden:
1605 return LLVMHiddenVisibility;
1606 case LLVMRustVisibility::Protected:
1607 return LLVMProtectedVisibility;
1609 report_fatal_error("Invalid LLVMRustVisibility value!");
1612 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1613 return toRust(LLVMGetVisibility(V));
1616 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1617 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1618 LLVMTypeRef DestTy, bool isSigned) {
1619 return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1622 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1623 LLVMRustVisibility RustVisibility) {
1624 LLVMSetVisibility(V, fromRust(RustVisibility));
1627 struct LLVMRustModuleBuffer {
1631 extern "C" LLVMRustModuleBuffer*
1632 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1633 #if LLVM_VERSION_GE(10, 0)
1634 auto Ret = std::make_unique<LLVMRustModuleBuffer>();
1636 auto Ret = llvm::make_unique<LLVMRustModuleBuffer>();
1639 raw_string_ostream OS(Ret->data);
1641 legacy::PassManager PM;
1642 PM.add(createBitcodeWriterPass(OS));
1646 return Ret.release();
1650 LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1654 extern "C" const void*
1655 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1656 return Buffer->data.data();
1660 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1661 return Buffer->data.length();
1665 LLVMRustModuleCost(LLVMModuleRef M) {
1666 auto f = unwrap(M)->functions();
1667 return std::distance(std::begin(f), std::end(f));
1670 // Vector reductions:
1671 extern "C" LLVMValueRef
1672 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1673 return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1675 extern "C" LLVMValueRef
1676 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1677 return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1679 extern "C" LLVMValueRef
1680 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1681 return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1683 extern "C" LLVMValueRef
1684 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1685 return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1687 extern "C" LLVMValueRef
1688 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1689 return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1691 extern "C" LLVMValueRef
1692 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1693 return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1695 extern "C" LLVMValueRef
1696 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1697 return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1699 extern "C" LLVMValueRef
1700 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1701 return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1703 extern "C" LLVMValueRef
1704 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1705 return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1707 extern "C" LLVMValueRef
1708 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1709 return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN));
1711 extern "C" LLVMValueRef
1712 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1713 return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN));
1716 extern "C" LLVMValueRef
1717 LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1718 return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1720 extern "C" LLVMValueRef
1721 LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1722 return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));