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" 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))
131 extern "C" LLVMValueRef
132 LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) {
133 StringRef NameRef(Name, NameLen);
134 return wrap(unwrap(M)->getOrInsertGlobal(NameRef, unwrap(Ty)));
137 extern "C" LLVMValueRef
138 LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) {
139 return wrap(new GlobalVariable(*unwrap(M),
142 GlobalValue::PrivateLinkage,
146 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
147 return wrap(Type::getMetadataTy(*unwrap(C)));
150 static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
153 return Attribute::AlwaysInline;
155 return Attribute::ByVal;
157 return Attribute::Cold;
159 return Attribute::InlineHint;
161 return Attribute::MinSize;
163 return Attribute::Naked;
165 return Attribute::NoAlias;
167 return Attribute::NoCapture;
169 return Attribute::NoInline;
171 return Attribute::NonNull;
173 return Attribute::NoRedZone;
175 return Attribute::NoReturn;
177 return Attribute::NoUnwind;
178 case OptimizeForSize:
179 return Attribute::OptimizeForSize;
181 return Attribute::ReadOnly;
183 return Attribute::SExt;
185 return Attribute::StructRet;
187 return Attribute::UWTable;
189 return Attribute::ZExt;
191 return Attribute::InReg;
193 return Attribute::SanitizeThread;
194 case SanitizeAddress:
195 return Attribute::SanitizeAddress;
197 return Attribute::SanitizeMemory;
199 return Attribute::NonLazyBind;
201 return Attribute::OptimizeNone;
203 return Attribute::ReturnsTwice;
205 return Attribute::ReadNone;
206 case InaccessibleMemOnly:
207 return Attribute::InaccessibleMemOnly;
209 report_fatal_error("bad AttributeKind");
212 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
213 LLVMRustAttribute RustAttr) {
214 CallBase *Call = unwrap<CallBase>(Instr);
215 Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
216 Call->addAttribute(Index, Attr);
219 extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
222 CallBase *Call = unwrap<CallBase>(Instr);
224 B.addAlignmentAttr(Bytes);
225 Call->setAttributes(Call->getAttributes().addAttributes(
226 Call->getContext(), Index, B));
229 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
232 CallBase *Call = unwrap<CallBase>(Instr);
234 B.addDereferenceableAttr(Bytes);
235 Call->setAttributes(Call->getAttributes().addAttributes(
236 Call->getContext(), Index, B));
239 extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
242 CallBase *Call = unwrap<CallBase>(Instr);
244 B.addDereferenceableOrNullAttr(Bytes);
245 Call->setAttributes(Call->getAttributes().addAttributes(
246 Call->getContext(), Index, B));
249 extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index,
251 CallBase *Call = unwrap<CallBase>(Instr);
252 Attribute Attr = Attribute::getWithByValType(Call->getContext(), unwrap(Ty));
253 Call->addAttribute(Index, Attr);
256 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
257 LLVMRustAttribute RustAttr) {
258 Function *A = unwrap<Function>(Fn);
259 Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
261 A->addAttributes(Index, B);
264 extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn,
267 Function *A = unwrap<Function>(Fn);
269 B.addAlignmentAttr(Bytes);
270 A->addAttributes(Index, B);
273 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
275 Function *A = unwrap<Function>(Fn);
277 B.addDereferenceableAttr(Bytes);
278 A->addAttributes(Index, B);
281 extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
284 Function *A = unwrap<Function>(Fn);
286 B.addDereferenceableOrNullAttr(Bytes);
287 A->addAttributes(Index, B);
290 extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index,
292 Function *F = unwrap<Function>(Fn);
293 Attribute Attr = Attribute::getWithByValType(F->getContext(), unwrap(Ty));
294 F->addAttribute(Index, Attr);
297 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
301 Function *F = unwrap<Function>(Fn);
303 B.addAttribute(Name, Value);
304 F->addAttributes(Index, B);
307 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
309 LLVMRustAttribute RustAttr) {
310 Function *F = unwrap<Function>(Fn);
311 Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
313 auto PAL = F->getAttributes();
314 auto PALNew = PAL.removeAttributes(F->getContext(), Index, B);
315 F->setAttributes(PALNew);
318 // enable fpmath flag UnsafeAlgebra
319 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
320 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
325 extern "C" LLVMValueRef
326 LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef Source, const char *Name,
327 LLVMAtomicOrdering Order) {
328 Value *Ptr = unwrap(Source);
329 Type *Ty = Ptr->getType()->getPointerElementType();
330 LoadInst *LI = unwrap(B)->CreateLoad(Ty, Ptr, Name);
331 LI->setAtomic(fromRust(Order));
335 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
338 LLVMAtomicOrdering Order) {
339 StoreInst *SI = unwrap(B)->CreateStore(unwrap(V), unwrap(Target));
340 SI->setAtomic(fromRust(Order));
344 // FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak
345 // once we raise our minimum support to LLVM 10.
346 extern "C" LLVMValueRef
347 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
348 LLVMValueRef Old, LLVMValueRef Source,
349 LLVMAtomicOrdering Order,
350 LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
351 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
352 unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
353 fromRust(FailureOrder));
358 enum class LLVMRustSynchronizationScope {
363 static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
365 case LLVMRustSynchronizationScope::SingleThread:
366 return SyncScope::SingleThread;
367 case LLVMRustSynchronizationScope::CrossThread:
368 return SyncScope::System;
370 report_fatal_error("bad SynchronizationScope.");
374 extern "C" LLVMValueRef
375 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
376 LLVMRustSynchronizationScope Scope) {
377 return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
380 enum class LLVMRustAsmDialect {
385 static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
387 case LLVMRustAsmDialect::Att:
388 return InlineAsm::AD_ATT;
389 case LLVMRustAsmDialect::Intel:
390 return InlineAsm::AD_Intel;
392 report_fatal_error("bad AsmDialect.");
396 extern "C" LLVMValueRef
397 LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
398 char *Constraints, size_t ConstraintsLen,
399 LLVMBool HasSideEffects, LLVMBool IsAlignStack,
400 LLVMRustAsmDialect Dialect) {
401 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
402 StringRef(AsmString, AsmStringLen),
403 StringRef(Constraints, ConstraintsLen),
404 HasSideEffects, IsAlignStack, fromRust(Dialect)));
407 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
408 size_t ConstraintsLen) {
409 return InlineAsm::Verify(unwrap<FunctionType>(Ty),
410 StringRef(Constraints, ConstraintsLen));
413 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
415 unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen));
418 typedef DIBuilder *LLVMRustDIBuilderRef;
420 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
421 return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
424 #define DIDescriptor DIScope
425 #define DIArray DINodeArray
426 #define unwrapDI unwrapDIPtr
428 // These values **must** match debuginfo::DIFlags! They also *happen*
429 // to match LLVM, but that isn't required as we do giant sets of
430 // matching below. The value shouldn't be directly passed to LLVM.
431 enum class LLVMRustDIFlags : uint32_t {
436 FlagFwdDecl = (1 << 2),
437 FlagAppleBlock = (1 << 3),
438 FlagBlockByrefStruct = (1 << 4),
439 FlagVirtual = (1 << 5),
440 FlagArtificial = (1 << 6),
441 FlagExplicit = (1 << 7),
442 FlagPrototyped = (1 << 8),
443 FlagObjcClassComplete = (1 << 9),
444 FlagObjectPointer = (1 << 10),
445 FlagVector = (1 << 11),
446 FlagStaticMember = (1 << 12),
447 FlagLValueReference = (1 << 13),
448 FlagRValueReference = (1 << 14),
449 FlagExternalTypeRef = (1 << 15),
450 FlagIntroducedVirtual = (1 << 18),
451 FlagBitField = (1 << 19),
452 FlagNoReturn = (1 << 20),
453 // Do not add values that are not supported by the minimum LLVM
454 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
457 inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
458 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
459 static_cast<uint32_t>(B));
462 inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
463 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
464 static_cast<uint32_t>(B));
467 inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
471 inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
473 inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
474 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
477 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
478 DINode::DIFlags Result = DINode::DIFlags::FlagZero;
480 switch (visibility(Flags)) {
481 case LLVMRustDIFlags::FlagPrivate:
482 Result |= DINode::DIFlags::FlagPrivate;
484 case LLVMRustDIFlags::FlagProtected:
485 Result |= DINode::DIFlags::FlagProtected;
487 case LLVMRustDIFlags::FlagPublic:
488 Result |= DINode::DIFlags::FlagPublic;
491 // The rest are handled below
495 if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
496 Result |= DINode::DIFlags::FlagFwdDecl;
498 if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
499 Result |= DINode::DIFlags::FlagAppleBlock;
501 #if LLVM_VERSION_LT(10, 0)
502 if (isSet(Flags & LLVMRustDIFlags::FlagBlockByrefStruct)) {
503 Result |= DINode::DIFlags::FlagBlockByrefStruct;
506 if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
507 Result |= DINode::DIFlags::FlagVirtual;
509 if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
510 Result |= DINode::DIFlags::FlagArtificial;
512 if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
513 Result |= DINode::DIFlags::FlagExplicit;
515 if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
516 Result |= DINode::DIFlags::FlagPrototyped;
518 if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
519 Result |= DINode::DIFlags::FlagObjcClassComplete;
521 if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
522 Result |= DINode::DIFlags::FlagObjectPointer;
524 if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
525 Result |= DINode::DIFlags::FlagVector;
527 if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
528 Result |= DINode::DIFlags::FlagStaticMember;
530 if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
531 Result |= DINode::DIFlags::FlagLValueReference;
533 if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
534 Result |= DINode::DIFlags::FlagRValueReference;
536 if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
537 Result |= DINode::DIFlags::FlagIntroducedVirtual;
539 if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
540 Result |= DINode::DIFlags::FlagBitField;
542 if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
543 Result |= DINode::DIFlags::FlagNoReturn;
549 // These values **must** match debuginfo::DISPFlags! They also *happen*
550 // to match LLVM, but that isn't required as we do giant sets of
551 // matching below. The value shouldn't be directly passed to LLVM.
552 enum class LLVMRustDISPFlags : uint32_t {
555 SPFlagPureVirtual = 2,
556 SPFlagLocalToUnit = (1 << 2),
557 SPFlagDefinition = (1 << 3),
558 SPFlagOptimized = (1 << 4),
559 SPFlagMainSubprogram = (1 << 5),
560 // Do not add values that are not supported by the minimum LLVM
561 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
562 // (In LLVM < 8, createFunction supported these as separate bool arguments.)
565 inline LLVMRustDISPFlags operator&(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
566 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) &
567 static_cast<uint32_t>(B));
570 inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
571 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) |
572 static_cast<uint32_t>(B));
575 inline LLVMRustDISPFlags &operator|=(LLVMRustDISPFlags &A, LLVMRustDISPFlags B) {
579 inline bool isSet(LLVMRustDISPFlags F) { return F != LLVMRustDISPFlags::SPFlagZero; }
581 inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) {
582 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(F) & 0x3);
585 static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) {
586 DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero;
588 switch (virtuality(SPFlags)) {
589 case LLVMRustDISPFlags::SPFlagVirtual:
590 Result |= DISubprogram::DISPFlags::SPFlagVirtual;
592 case LLVMRustDISPFlags::SPFlagPureVirtual:
593 Result |= DISubprogram::DISPFlags::SPFlagPureVirtual;
596 // The rest are handled below
600 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit)) {
601 Result |= DISubprogram::DISPFlags::SPFlagLocalToUnit;
603 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition)) {
604 Result |= DISubprogram::DISPFlags::SPFlagDefinition;
606 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) {
607 Result |= DISubprogram::DISPFlags::SPFlagOptimized;
609 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) {
610 Result |= DISubprogram::DISPFlags::SPFlagMainSubprogram;
616 enum class LLVMRustDebugEmissionKind {
622 static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
624 case LLVMRustDebugEmissionKind::NoDebug:
625 return DICompileUnit::DebugEmissionKind::NoDebug;
626 case LLVMRustDebugEmissionKind::FullDebug:
627 return DICompileUnit::DebugEmissionKind::FullDebug;
628 case LLVMRustDebugEmissionKind::LineTablesOnly:
629 return DICompileUnit::DebugEmissionKind::LineTablesOnly;
631 report_fatal_error("bad DebugEmissionKind.");
635 enum class LLVMRustChecksumKind {
642 static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
644 case LLVMRustChecksumKind::None:
646 case LLVMRustChecksumKind::MD5:
647 return DIFile::ChecksumKind::CSK_MD5;
648 case LLVMRustChecksumKind::SHA1:
649 return DIFile::ChecksumKind::CSK_SHA1;
650 #if (LLVM_VERSION_MAJOR >= 11)
651 case LLVMRustChecksumKind::SHA256:
652 return DIFile::ChecksumKind::CSK_SHA256;
655 report_fatal_error("bad ChecksumKind.");
659 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
660 return DEBUG_METADATA_VERSION;
663 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
665 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
667 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
669 unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
672 extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
673 return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
676 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
677 return new DIBuilder(*unwrap(M));
680 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
684 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
688 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
689 LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
690 const char *Producer, size_t ProducerLen, bool isOptimized,
691 const char *Flags, unsigned RuntimeVer,
692 const char *SplitName, size_t SplitNameLen,
693 LLVMRustDebugEmissionKind Kind) {
694 auto *File = unwrapDI<DIFile>(FileRef);
696 return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
697 isOptimized, Flags, RuntimeVer,
698 StringRef(SplitName, SplitNameLen),
702 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
703 LLVMRustDIBuilderRef Builder,
704 const char *Filename, size_t FilenameLen,
705 const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
706 const char *Checksum, size_t ChecksumLen) {
707 Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
708 Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
710 CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
711 return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
712 StringRef(Directory, DirectoryLen),
716 extern "C" LLVMMetadataRef
717 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
718 LLVMMetadataRef ParameterTypes) {
719 return wrap(Builder->createSubroutineType(
720 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
723 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
724 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
725 const char *Name, size_t NameLen,
726 const char *LinkageName, size_t LinkageNameLen,
727 LLVMMetadataRef File, unsigned LineNo,
728 LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
729 LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam,
730 LLVMMetadataRef Decl) {
731 DITemplateParameterArray TParams =
732 DITemplateParameterArray(unwrap<MDTuple>(TParam));
733 DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
734 DINode::DIFlags llvmFlags = fromRust(Flags);
735 DISubprogram *Sub = Builder->createFunction(
736 unwrapDI<DIScope>(Scope),
737 StringRef(Name, NameLen),
738 StringRef(LinkageName, LinkageNameLen),
739 unwrapDI<DIFile>(File), LineNo,
740 unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
741 llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
743 unwrap<Function>(MaybeFn)->setSubprogram(Sub);
747 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
748 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
749 uint64_t SizeInBits, unsigned Encoding) {
750 return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
753 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
754 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
755 LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
756 return wrap(Builder->createTypedef(
757 unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
758 LineNo, unwrapDIPtr<DIScope>(Scope)));
761 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
762 LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
763 uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
764 const char *Name, size_t NameLen) {
765 return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
766 SizeInBits, AlignInBits,
768 StringRef(Name, NameLen)));
771 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
772 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
773 const char *Name, size_t NameLen,
774 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
775 uint32_t AlignInBits, LLVMRustDIFlags Flags,
776 LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
777 unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
778 const char *UniqueId, size_t UniqueIdLen) {
779 return wrap(Builder->createStructType(
780 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
781 unwrapDI<DIFile>(File), LineNumber,
782 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
783 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
784 unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen)));
787 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
788 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
789 const char *Name, size_t NameLen,
790 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
791 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
792 LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) {
793 return wrap(Builder->createVariantPart(
794 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
795 unwrapDI<DIFile>(File), LineNumber,
796 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
797 DINodeArray(unwrapDI<MDTuple>(Elements)), StringRef(UniqueId, UniqueIdLen)));
800 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
801 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
802 const char *Name, size_t NameLen,
803 LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
804 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
805 LLVMMetadataRef Ty) {
806 return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope),
807 StringRef(Name, NameLen),
808 unwrapDI<DIFile>(File), LineNo,
809 SizeInBits, AlignInBits, OffsetInBits,
810 fromRust(Flags), unwrapDI<DIType>(Ty)));
813 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
814 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
815 const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
816 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
817 LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
818 llvm::ConstantInt* D = nullptr;
820 D = unwrap<llvm::ConstantInt>(Discriminant);
822 return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope),
823 StringRef(Name, NameLen),
824 unwrapDI<DIFile>(File), LineNo,
825 SizeInBits, AlignInBits, OffsetInBits, D,
826 fromRust(Flags), unwrapDI<DIType>(Ty)));
829 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
830 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
831 LLVMMetadataRef File, unsigned Line, unsigned Col) {
832 return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
833 unwrapDI<DIFile>(File), Line, Col));
836 extern "C" LLVMMetadataRef
837 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
838 LLVMMetadataRef Scope,
839 LLVMMetadataRef File) {
840 return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
841 unwrapDI<DIFile>(File)));
844 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
845 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context,
846 const char *Name, size_t NameLen,
847 const char *LinkageName, size_t LinkageNameLen,
848 LLVMMetadataRef File, unsigned LineNo,
849 LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
850 LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
851 llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
853 llvm::DIExpression *InitExpr = nullptr;
854 if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
855 InitExpr = Builder->createConstantValueExpression(
856 IntVal->getValue().getSExtValue());
857 } else if (llvm::ConstantFP *FPVal =
858 llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
859 InitExpr = Builder->createConstantValueExpression(
860 FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
863 llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
864 unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
865 StringRef(LinkageName, LinkageNameLen),
866 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
867 #if LLVM_VERSION_GE(10, 0)
868 /* isDefined */ true,
870 InitExpr, unwrapDIPtr<MDNode>(Decl),
871 /* templateParams */ nullptr,
874 InitVal->setMetadata("dbg", VarExpr);
876 return wrap(VarExpr);
879 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
880 LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
881 const char *Name, size_t NameLen,
882 LLVMMetadataRef File, unsigned LineNo,
883 LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
884 unsigned ArgNo, uint32_t AlignInBits) {
885 if (Tag == 0x100) { // DW_TAG_auto_variable
886 return wrap(Builder->createAutoVariable(
887 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
888 unwrapDI<DIFile>(File), LineNo,
889 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
891 return wrap(Builder->createParameterVariable(
892 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
893 unwrapDI<DIFile>(File), LineNo,
894 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
898 extern "C" LLVMMetadataRef
899 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
900 uint32_t AlignInBits, LLVMMetadataRef Ty,
901 LLVMMetadataRef Subscripts) {
903 Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
904 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
907 extern "C" LLVMMetadataRef
908 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
910 return wrap(Builder->getOrCreateSubrange(Lo, Count));
913 extern "C" LLVMMetadataRef
914 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
915 LLVMMetadataRef *Ptr, unsigned Count) {
916 Metadata **DataValue = unwrap(Ptr);
918 Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
921 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
922 LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
923 int64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
924 LLVMBasicBlockRef InsertAtEnd) {
925 return wrap(Builder->insertDeclare(
926 unwrap(V), unwrap<DILocalVariable>(VarInfo),
927 Builder->createExpression(llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
928 DebugLoc(cast<MDNode>(unwrap(DL))),
929 unwrap(InsertAtEnd)));
932 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
933 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
934 int64_t Value, bool IsUnsigned) {
935 return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
938 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
939 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
940 const char *Name, size_t NameLen,
941 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
942 uint32_t AlignInBits, LLVMMetadataRef Elements,
943 LLVMMetadataRef ClassTy, bool IsScoped) {
944 return wrap(Builder->createEnumerationType(
945 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
946 unwrapDI<DIFile>(File), LineNumber,
947 SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
948 unwrapDI<DIType>(ClassTy), "", IsScoped));
951 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
952 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
953 const char *Name, size_t NameLen,
954 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
955 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
956 unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) {
957 return wrap(Builder->createUnionType(
958 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File),
959 LineNumber, SizeInBits, AlignInBits, fromRust(Flags),
960 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
961 StringRef(UniqueId, UniqueIdLen)));
964 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
965 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
966 const char *Name, size_t NameLen, LLVMMetadataRef Ty) {
967 #if LLVM_VERSION_GE(11, 0)
968 bool IsDefault = false; // FIXME: should we ever set this true?
969 return wrap(Builder->createTemplateTypeParameter(
970 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty), IsDefault));
972 return wrap(Builder->createTemplateTypeParameter(
973 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty)));
977 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateNameSpace(
978 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
979 const char *Name, size_t NameLen, bool ExportSymbols) {
980 return wrap(Builder->createNameSpace(
981 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols
986 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
987 LLVMMetadataRef CompositeTy,
988 LLVMMetadataRef Elements,
989 LLVMMetadataRef Params) {
990 DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
991 Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
992 DINodeArray(unwrap<MDTuple>(Params)));
995 extern "C" LLVMMetadataRef
996 LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef, unsigned Line,
997 unsigned Column, LLVMMetadataRef Scope,
998 LLVMMetadataRef InlinedAt) {
999 LLVMContext &Context = *unwrap(ContextRef);
1001 DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(Scope),
1002 unwrapDIPtr<MDNode>(InlinedAt));
1004 return wrap(debug_loc.getAsMDNode());
1007 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
1008 return dwarf::DW_OP_deref;
1011 extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1012 return dwarf::DW_OP_plus_uconst;
1015 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
1016 RawRustStringOstream OS(Str);
1017 unwrap<llvm::Type>(Ty)->print(OS);
1020 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
1021 RustStringRef Str) {
1022 RawRustStringOstream OS(Str);
1027 unwrap<llvm::Value>(V)->getType()->print(OS);
1029 unwrap<llvm::Value>(V)->print(OS);
1034 // Note that the two following functions look quite similar to the
1035 // LLVMGetSectionName function. Sadly, it appears that this function only
1036 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
1037 // function provided by LLVM doesn't return the length, so we've created our own
1038 // function which returns the length as well as the data pointer.
1040 // For an example of this not returning a null terminated string, see
1041 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
1042 // branches explicitly creates a StringRef without a null terminator, and then
1045 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
1046 return reinterpret_cast<section_iterator *>(SI);
1049 extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI,
1051 #if LLVM_VERSION_GE(10, 0)
1052 auto NameOrErr = (*unwrap(SI))->getName();
1054 report_fatal_error(NameOrErr.takeError());
1055 *Ptr = NameOrErr->data();
1056 return NameOrErr->size();
1059 if (std::error_code EC = (*unwrap(SI))->getName(Ret))
1060 report_fatal_error(EC.message());
1066 // LLVMArrayType function does not support 64-bit ElementCount
1067 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
1068 uint64_t ElementCount) {
1069 return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
1072 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1074 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
1075 RawRustStringOstream OS(Str);
1076 unwrap(T)->print(OS);
1079 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1080 LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
1081 LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
1082 RustStringRef FilenameOut, RustStringRef MessageOut) {
1083 // Undefined to call this not on an optimization diagnostic!
1084 llvm::DiagnosticInfoOptimizationBase *Opt =
1085 static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
1087 RawRustStringOstream PassNameOS(PassNameOut);
1088 PassNameOS << Opt->getPassName();
1089 *FunctionOut = wrap(&Opt->getFunction());
1091 RawRustStringOstream FilenameOS(FilenameOut);
1092 DiagnosticLocation loc = Opt->getLocation();
1093 if (loc.isValid()) {
1094 *Line = loc.getLine();
1095 *Column = loc.getColumn();
1096 FilenameOS << loc.getAbsolutePath();
1099 RawRustStringOstream MessageOS(MessageOut);
1100 MessageOS << Opt->getMsg();
1103 enum class LLVMRustDiagnosticLevel {
1111 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
1112 LLVMRustDiagnosticLevel *LevelOut,
1113 unsigned *CookieOut,
1114 LLVMTwineRef *MessageOut,
1115 LLVMValueRef *InstructionOut) {
1116 // Undefined to call this not on an inline assembly diagnostic!
1117 llvm::DiagnosticInfoInlineAsm *IA =
1118 static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
1120 *CookieOut = IA->getLocCookie();
1121 *MessageOut = wrap(&IA->getMsgStr());
1122 *InstructionOut = wrap(IA->getInstruction());
1124 switch (IA->getSeverity()) {
1126 *LevelOut = LLVMRustDiagnosticLevel::Error;
1129 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1132 *LevelOut = LLVMRustDiagnosticLevel::Note;
1135 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1138 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1142 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
1143 RustStringRef Str) {
1144 RawRustStringOstream OS(Str);
1145 DiagnosticPrinterRawOStream DP(OS);
1146 unwrap(DI)->print(DP);
1149 enum class LLVMRustDiagnosticKind {
1153 DebugMetadataVersion,
1156 OptimizationRemarkMissed,
1157 OptimizationRemarkAnalysis,
1158 OptimizationRemarkAnalysisFPCommute,
1159 OptimizationRemarkAnalysisAliasing,
1160 OptimizationRemarkOther,
1161 OptimizationFailure,
1167 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1170 return LLVMRustDiagnosticKind::InlineAsm;
1172 return LLVMRustDiagnosticKind::StackSize;
1173 case DK_DebugMetadataVersion:
1174 return LLVMRustDiagnosticKind::DebugMetadataVersion;
1175 case DK_SampleProfile:
1176 return LLVMRustDiagnosticKind::SampleProfile;
1177 case DK_OptimizationRemark:
1178 return LLVMRustDiagnosticKind::OptimizationRemark;
1179 case DK_OptimizationRemarkMissed:
1180 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1181 case DK_OptimizationRemarkAnalysis:
1182 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1183 case DK_OptimizationRemarkAnalysisFPCommute:
1184 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1185 case DK_OptimizationRemarkAnalysisAliasing:
1186 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1188 return LLVMRustDiagnosticKind::PGOProfile;
1190 return LLVMRustDiagnosticKind::Linker;
1191 case DK_Unsupported:
1192 return LLVMRustDiagnosticKind::Unsupported;
1194 return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1195 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1196 : LLVMRustDiagnosticKind::Other;
1200 extern "C" LLVMRustDiagnosticKind
1201 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1202 return toRust((DiagnosticKind)unwrap(DI)->getKind());
1205 // This is kept distinct from LLVMGetTypeKind, because when
1206 // a new type kind is added, the Rust-side enum must be
1207 // updated or UB will result.
1208 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1209 switch (unwrap(Ty)->getTypeID()) {
1210 case Type::VoidTyID:
1211 return LLVMVoidTypeKind;
1212 case Type::HalfTyID:
1213 return LLVMHalfTypeKind;
1214 case Type::FloatTyID:
1215 return LLVMFloatTypeKind;
1216 case Type::DoubleTyID:
1217 return LLVMDoubleTypeKind;
1218 case Type::X86_FP80TyID:
1219 return LLVMX86_FP80TypeKind;
1220 case Type::FP128TyID:
1221 return LLVMFP128TypeKind;
1222 case Type::PPC_FP128TyID:
1223 return LLVMPPC_FP128TypeKind;
1224 case Type::LabelTyID:
1225 return LLVMLabelTypeKind;
1226 case Type::MetadataTyID:
1227 return LLVMMetadataTypeKind;
1228 case Type::IntegerTyID:
1229 return LLVMIntegerTypeKind;
1230 case Type::FunctionTyID:
1231 return LLVMFunctionTypeKind;
1232 case Type::StructTyID:
1233 return LLVMStructTypeKind;
1234 case Type::ArrayTyID:
1235 return LLVMArrayTypeKind;
1236 case Type::PointerTyID:
1237 return LLVMPointerTypeKind;
1238 #if LLVM_VERSION_GE(11, 0)
1239 case Type::FixedVectorTyID:
1240 return LLVMVectorTypeKind;
1242 case Type::VectorTyID:
1243 return LLVMVectorTypeKind;
1245 case Type::X86_MMXTyID:
1246 return LLVMX86_MMXTypeKind;
1247 case Type::TokenTyID:
1248 return LLVMTokenTypeKind;
1249 #if LLVM_VERSION_GE(11, 0)
1250 case Type::ScalableVectorTyID:
1251 return LLVMScalableVectorTypeKind;
1252 case Type::BFloatTyID:
1253 return LLVMBFloatTypeKind;
1256 report_fatal_error("Unhandled TypeID.");
1259 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1261 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1262 LLVMContextRef C, LLVMContext::InlineAsmDiagHandlerTy H, void *CX) {
1263 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1266 extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
1267 RustStringRef MessageOut,
1268 RustStringRef BufferOut,
1269 LLVMRustDiagnosticLevel* LevelOut,
1271 unsigned* RangesOut,
1272 size_t* NumRanges) {
1273 SMDiagnostic& D = *unwrap(DRef);
1274 RawRustStringOstream MessageOS(MessageOut);
1275 MessageOS << D.getMessage();
1277 switch (D.getKind()) {
1278 case SourceMgr::DK_Error:
1279 *LevelOut = LLVMRustDiagnosticLevel::Error;
1281 case SourceMgr::DK_Warning:
1282 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1284 case SourceMgr::DK_Note:
1285 *LevelOut = LLVMRustDiagnosticLevel::Note;
1287 case SourceMgr::DK_Remark:
1288 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1291 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1294 if (D.getLoc() == SMLoc())
1297 const SourceMgr &LSM = *D.getSourceMgr();
1298 const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
1299 LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), LBuf->getBufferSize());
1301 *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
1303 *NumRanges = std::min(*NumRanges, D.getRanges().size());
1304 size_t LineStart = *LocOut - (size_t)D.getColumnNo();
1305 for (size_t i = 0; i < *NumRanges; i++) {
1306 RangesOut[i * 2] = LineStart + D.getRanges()[i].first;
1307 RangesOut[i * 2 + 1] = LineStart + D.getRanges()[i].second;
1313 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1314 LLVMValueRef ParentPad,
1316 LLVMValueRef *LLArgs,
1318 Value **Args = unwrap(LLArgs);
1319 if (ParentPad == nullptr) {
1320 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1321 ParentPad = wrap(Constant::getNullValue(Ty));
1323 return wrap(unwrap(B)->CreateCleanupPad(
1324 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1327 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1328 LLVMValueRef CleanupPad,
1329 LLVMBasicBlockRef UnwindBB) {
1330 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1331 return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1334 extern "C" LLVMValueRef
1335 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1336 unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1337 Value **Args = unwrap(LLArgs);
1338 return wrap(unwrap(B)->CreateCatchPad(
1339 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1342 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1344 LLVMBasicBlockRef BB) {
1345 return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1349 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1350 LLVMValueRef ParentPad,
1351 LLVMBasicBlockRef BB,
1352 unsigned NumHandlers,
1354 if (ParentPad == nullptr) {
1355 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1356 ParentPad = wrap(Constant::getNullValue(Ty));
1358 return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1359 NumHandlers, Name));
1362 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1363 LLVMBasicBlockRef Handler) {
1364 Value *CatchSwitch = unwrap(CatchSwitchRef);
1365 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1368 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1369 LLVMValueRef *Inputs,
1370 unsigned NumInputs) {
1371 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1374 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1378 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
1379 LLVMValueRef *Args, unsigned NumArgs,
1380 OperandBundleDef *Bundle) {
1381 Value *Callee = unwrap(Fn);
1382 FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1383 unsigned Len = Bundle ? 1 : 0;
1384 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1385 return wrap(unwrap(B)->CreateCall(
1386 FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles));
1389 extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
1390 return wrap(llvm::Intrinsic::getDeclaration(unwrap(M),
1391 (llvm::Intrinsic::ID)llvm::Intrinsic::instrprof_increment));
1394 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
1395 LLVMValueRef Dst, unsigned DstAlign,
1396 LLVMValueRef Src, unsigned SrcAlign,
1397 LLVMValueRef Size, bool IsVolatile) {
1398 #if LLVM_VERSION_GE(10, 0)
1399 return wrap(unwrap(B)->CreateMemCpy(
1400 unwrap(Dst), MaybeAlign(DstAlign),
1401 unwrap(Src), MaybeAlign(SrcAlign),
1402 unwrap(Size), IsVolatile));
1404 return wrap(unwrap(B)->CreateMemCpy(
1405 unwrap(Dst), DstAlign,
1406 unwrap(Src), SrcAlign,
1407 unwrap(Size), IsVolatile));
1411 extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
1412 LLVMValueRef Dst, unsigned DstAlign,
1413 LLVMValueRef Src, unsigned SrcAlign,
1414 LLVMValueRef Size, bool IsVolatile) {
1415 #if LLVM_VERSION_GE(10, 0)
1416 return wrap(unwrap(B)->CreateMemMove(
1417 unwrap(Dst), MaybeAlign(DstAlign),
1418 unwrap(Src), MaybeAlign(SrcAlign),
1419 unwrap(Size), IsVolatile));
1421 return wrap(unwrap(B)->CreateMemMove(
1422 unwrap(Dst), DstAlign,
1423 unwrap(Src), SrcAlign,
1424 unwrap(Size), IsVolatile));
1428 extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
1429 LLVMValueRef Dst, unsigned DstAlign,
1431 LLVMValueRef Size, bool IsVolatile) {
1432 #if LLVM_VERSION_GE(10, 0)
1433 return wrap(unwrap(B)->CreateMemSet(
1434 unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
1436 return wrap(unwrap(B)->CreateMemSet(
1437 unwrap(Dst), unwrap(Val), unwrap(Size), DstAlign, IsVolatile));
1441 extern "C" LLVMValueRef
1442 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
1443 unsigned NumArgs, LLVMBasicBlockRef Then,
1444 LLVMBasicBlockRef Catch, OperandBundleDef *Bundle,
1446 Value *Callee = unwrap(Fn);
1447 FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
1448 unsigned Len = Bundle ? 1 : 0;
1449 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1450 return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
1451 makeArrayRef(unwrap(Args), NumArgs),
1455 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1456 LLVMBasicBlockRef BB) {
1457 auto Point = unwrap(BB)->getFirstInsertionPt();
1458 unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1461 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1462 const char *Name, size_t NameLen) {
1463 Triple TargetTriple(unwrap(M)->getTargetTriple());
1464 GlobalObject *GV = unwrap<GlobalObject>(V);
1465 if (TargetTriple.supportsCOMDAT()) {
1466 StringRef NameRef(Name, NameLen);
1467 GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
1471 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1472 GlobalObject *GV = unwrap<GlobalObject>(V);
1473 GV->setComdat(nullptr);
1476 enum class LLVMRustLinkage {
1477 ExternalLinkage = 0,
1478 AvailableExternallyLinkage = 1,
1479 LinkOnceAnyLinkage = 2,
1480 LinkOnceODRLinkage = 3,
1483 AppendingLinkage = 6,
1484 InternalLinkage = 7,
1486 ExternalWeakLinkage = 9,
1490 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1492 case LLVMExternalLinkage:
1493 return LLVMRustLinkage::ExternalLinkage;
1494 case LLVMAvailableExternallyLinkage:
1495 return LLVMRustLinkage::AvailableExternallyLinkage;
1496 case LLVMLinkOnceAnyLinkage:
1497 return LLVMRustLinkage::LinkOnceAnyLinkage;
1498 case LLVMLinkOnceODRLinkage:
1499 return LLVMRustLinkage::LinkOnceODRLinkage;
1500 case LLVMWeakAnyLinkage:
1501 return LLVMRustLinkage::WeakAnyLinkage;
1502 case LLVMWeakODRLinkage:
1503 return LLVMRustLinkage::WeakODRLinkage;
1504 case LLVMAppendingLinkage:
1505 return LLVMRustLinkage::AppendingLinkage;
1506 case LLVMInternalLinkage:
1507 return LLVMRustLinkage::InternalLinkage;
1508 case LLVMPrivateLinkage:
1509 return LLVMRustLinkage::PrivateLinkage;
1510 case LLVMExternalWeakLinkage:
1511 return LLVMRustLinkage::ExternalWeakLinkage;
1512 case LLVMCommonLinkage:
1513 return LLVMRustLinkage::CommonLinkage;
1515 report_fatal_error("Invalid LLVMRustLinkage value!");
1519 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1521 case LLVMRustLinkage::ExternalLinkage:
1522 return LLVMExternalLinkage;
1523 case LLVMRustLinkage::AvailableExternallyLinkage:
1524 return LLVMAvailableExternallyLinkage;
1525 case LLVMRustLinkage::LinkOnceAnyLinkage:
1526 return LLVMLinkOnceAnyLinkage;
1527 case LLVMRustLinkage::LinkOnceODRLinkage:
1528 return LLVMLinkOnceODRLinkage;
1529 case LLVMRustLinkage::WeakAnyLinkage:
1530 return LLVMWeakAnyLinkage;
1531 case LLVMRustLinkage::WeakODRLinkage:
1532 return LLVMWeakODRLinkage;
1533 case LLVMRustLinkage::AppendingLinkage:
1534 return LLVMAppendingLinkage;
1535 case LLVMRustLinkage::InternalLinkage:
1536 return LLVMInternalLinkage;
1537 case LLVMRustLinkage::PrivateLinkage:
1538 return LLVMPrivateLinkage;
1539 case LLVMRustLinkage::ExternalWeakLinkage:
1540 return LLVMExternalWeakLinkage;
1541 case LLVMRustLinkage::CommonLinkage:
1542 return LLVMCommonLinkage;
1544 report_fatal_error("Invalid LLVMRustLinkage value!");
1547 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1548 return toRust(LLVMGetLinkage(V));
1551 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1552 LLVMRustLinkage RustLinkage) {
1553 LLVMSetLinkage(V, fromRust(RustLinkage));
1556 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1557 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1558 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1560 auto C = unwrap<llvm::ConstantInt>(CV);
1561 if (C->getBitWidth() > 128) { return false; }
1564 AP = C->getValue().sextOrSelf(128);
1566 AP = C->getValue().zextOrSelf(128);
1568 *low = AP.getLoBits(64).getZExtValue();
1569 *high = AP.getHiBits(64).getZExtValue();
1573 enum class LLVMRustVisibility {
1579 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1581 case LLVMDefaultVisibility:
1582 return LLVMRustVisibility::Default;
1583 case LLVMHiddenVisibility:
1584 return LLVMRustVisibility::Hidden;
1585 case LLVMProtectedVisibility:
1586 return LLVMRustVisibility::Protected;
1588 report_fatal_error("Invalid LLVMRustVisibility value!");
1591 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1593 case LLVMRustVisibility::Default:
1594 return LLVMDefaultVisibility;
1595 case LLVMRustVisibility::Hidden:
1596 return LLVMHiddenVisibility;
1597 case LLVMRustVisibility::Protected:
1598 return LLVMProtectedVisibility;
1600 report_fatal_error("Invalid LLVMRustVisibility value!");
1603 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1604 return toRust(LLVMGetVisibility(V));
1607 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1608 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1609 LLVMTypeRef DestTy, bool isSigned) {
1610 return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1613 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1614 LLVMRustVisibility RustVisibility) {
1615 LLVMSetVisibility(V, fromRust(RustVisibility));
1618 struct LLVMRustModuleBuffer {
1622 extern "C" LLVMRustModuleBuffer*
1623 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1624 #if LLVM_VERSION_GE(10, 0)
1625 auto Ret = std::make_unique<LLVMRustModuleBuffer>();
1627 auto Ret = llvm::make_unique<LLVMRustModuleBuffer>();
1630 raw_string_ostream OS(Ret->data);
1632 legacy::PassManager PM;
1633 PM.add(createBitcodeWriterPass(OS));
1637 return Ret.release();
1641 LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1645 extern "C" const void*
1646 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1647 return Buffer->data.data();
1651 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1652 return Buffer->data.length();
1656 LLVMRustModuleCost(LLVMModuleRef M) {
1657 auto f = unwrap(M)->functions();
1658 return std::distance(std::begin(f), std::end(f));
1661 // Vector reductions:
1662 extern "C" LLVMValueRef
1663 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1664 return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1666 extern "C" LLVMValueRef
1667 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1668 return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1670 extern "C" LLVMValueRef
1671 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1672 return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1674 extern "C" LLVMValueRef
1675 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1676 return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1678 extern "C" LLVMValueRef
1679 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1680 return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1682 extern "C" LLVMValueRef
1683 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1684 return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1686 extern "C" LLVMValueRef
1687 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1688 return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1690 extern "C" LLVMValueRef
1691 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1692 return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1694 extern "C" LLVMValueRef
1695 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1696 return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1698 extern "C" LLVMValueRef
1699 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1700 return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN));
1702 extern "C" LLVMValueRef
1703 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1704 return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN));
1707 extern "C" LLVMValueRef
1708 LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1709 return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1711 extern "C" LLVMValueRef
1712 LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1713 return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));