1 #include "LLVMWrapper.h"
2 #include "llvm/IR/DebugInfoMetadata.h"
3 #include "llvm/IR/DiagnosticHandler.h"
4 #include "llvm/IR/DiagnosticInfo.h"
5 #include "llvm/IR/DiagnosticPrinter.h"
6 #include "llvm/IR/GlobalVariable.h"
7 #include "llvm/IR/Instructions.h"
8 #include "llvm/IR/Intrinsics.h"
9 #include "llvm/Object/Archive.h"
10 #include "llvm/Object/COFFImportFile.h"
11 #include "llvm/Object/ObjectFile.h"
12 #include "llvm/Pass.h"
13 #include "llvm/Bitcode/BitcodeWriterPass.h"
14 #include "llvm/Support/Signals.h"
15 #include "llvm/ADT/Optional.h"
19 //===----------------------------------------------------------------------===
21 // This file defines alternate interfaces to core functions that are more
22 // readily callable by Rust's FFI.
24 //===----------------------------------------------------------------------===
27 using namespace llvm::sys;
28 using namespace llvm::object;
30 // LLVMAtomicOrdering is already an enum - don't create another
32 static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
34 case LLVMAtomicOrderingNotAtomic:
35 return AtomicOrdering::NotAtomic;
36 case LLVMAtomicOrderingUnordered:
37 return AtomicOrdering::Unordered;
38 case LLVMAtomicOrderingMonotonic:
39 return AtomicOrdering::Monotonic;
40 case LLVMAtomicOrderingAcquire:
41 return AtomicOrdering::Acquire;
42 case LLVMAtomicOrderingRelease:
43 return AtomicOrdering::Release;
44 case LLVMAtomicOrderingAcquireRelease:
45 return AtomicOrdering::AcquireRelease;
46 case LLVMAtomicOrderingSequentiallyConsistent:
47 return AtomicOrdering::SequentiallyConsistent;
50 report_fatal_error("Invalid LLVMAtomicOrdering value!");
53 static LLVM_THREAD_LOCAL char *LastError;
55 // Custom error handler for fatal LLVM errors.
57 // Notably it exits the process with code 101, unlike LLVM's default of 1.
58 static void FatalErrorHandler(void *UserData,
59 #if LLVM_VERSION_LT(14, 0)
60 const std::string& Reason,
65 // Do the same thing that the default error handler does.
66 std::cerr << "LLVM ERROR: " << Reason << std::endl;
68 // Since this error handler exits the process, we have to run any cleanup that
69 // LLVM would run after handling the error. This might change with an LLVM
71 sys::RunInterruptHandlers();
76 extern "C" void LLVMRustInstallFatalErrorHandler() {
77 install_fatal_error_handler(FatalErrorHandler);
80 extern "C" void LLVMRustDisableSystemDialogsOnCrash() {
81 sys::DisableSystemDialogsOnCrash();
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 Module *Mod = unwrap(M);
134 StringRef NameRef(Name, NameLen);
136 // We don't use Module::getOrInsertGlobal because that returns a Constant*,
137 // which may either be the real GlobalVariable*, or a constant bitcast of it
138 // if our type doesn't match the original declaration. We always want the
139 // GlobalVariable* so we can access linkage, visibility, etc.
140 GlobalVariable *GV = Mod->getGlobalVariable(NameRef, true);
142 GV = new GlobalVariable(*Mod, unwrap(Ty), false,
143 GlobalValue::ExternalLinkage, nullptr, NameRef);
147 extern "C" LLVMValueRef
148 LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) {
149 return wrap(new GlobalVariable(*unwrap(M),
152 GlobalValue::PrivateLinkage,
156 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
157 return wrap(Type::getMetadataTy(*unwrap(C)));
160 static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
163 return Attribute::AlwaysInline;
165 return Attribute::ByVal;
167 return Attribute::Cold;
169 return Attribute::InlineHint;
171 return Attribute::MinSize;
173 return Attribute::Naked;
175 return Attribute::NoAlias;
177 return Attribute::NoCapture;
179 return Attribute::NoInline;
181 return Attribute::NonNull;
183 return Attribute::NoRedZone;
185 return Attribute::NoReturn;
187 return Attribute::NoUnwind;
188 case OptimizeForSize:
189 return Attribute::OptimizeForSize;
191 return Attribute::ReadOnly;
193 return Attribute::SExt;
195 return Attribute::StructRet;
197 return Attribute::UWTable;
199 return Attribute::ZExt;
201 return Attribute::InReg;
203 return Attribute::SanitizeThread;
204 case SanitizeAddress:
205 return Attribute::SanitizeAddress;
207 return Attribute::SanitizeMemory;
209 return Attribute::NonLazyBind;
211 return Attribute::OptimizeNone;
213 return Attribute::ReturnsTwice;
215 return Attribute::ReadNone;
216 case InaccessibleMemOnly:
217 return Attribute::InaccessibleMemOnly;
218 case SanitizeHWAddress:
219 return Attribute::SanitizeHWAddress;
221 return Attribute::WillReturn;
222 case StackProtectReq:
223 return Attribute::StackProtectReq;
224 case StackProtectStrong:
225 return Attribute::StackProtectStrong;
227 return Attribute::StackProtect;
229 return Attribute::NoUndef;
231 return Attribute::SanitizeMemTag;
233 report_fatal_error("bad AttributeKind");
236 template<typename T> static inline void AddAttributes(T *t, unsigned Index,
237 LLVMAttributeRef *Attrs, size_t AttrsLen) {
238 AttributeList PAL = t->getAttributes();
239 AttributeList PALNew;
240 #if LLVM_VERSION_LT(14, 0)
242 for (LLVMAttributeRef Attr : makeArrayRef(Attrs, AttrsLen))
243 B.addAttribute(unwrap(Attr));
244 PALNew = PAL.addAttributes(t->getContext(), Index, B);
246 AttrBuilder B(t->getContext());
247 for (LLVMAttributeRef Attr : makeArrayRef(Attrs, AttrsLen))
248 B.addAttribute(unwrap(Attr));
249 PALNew = PAL.addAttributesAtIndex(t->getContext(), Index, B);
251 t->setAttributes(PALNew);
254 extern "C" void LLVMRustAddFunctionAttributes(LLVMValueRef Fn, unsigned Index,
255 LLVMAttributeRef *Attrs, size_t AttrsLen) {
256 Function *F = unwrap<Function>(Fn);
257 AddAttributes(F, Index, Attrs, AttrsLen);
260 extern "C" void LLVMRustAddCallSiteAttributes(LLVMValueRef Instr, unsigned Index,
261 LLVMAttributeRef *Attrs, size_t AttrsLen) {
262 CallBase *Call = unwrap<CallBase>(Instr);
263 AddAttributes(Call, Index, Attrs, AttrsLen);
266 extern "C" LLVMAttributeRef LLVMRustCreateAttrNoValue(LLVMContextRef C,
267 LLVMRustAttribute RustAttr) {
268 return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr)));
271 extern "C" LLVMAttributeRef LLVMRustCreateAlignmentAttr(LLVMContextRef C,
273 return wrap(Attribute::getWithAlignment(*unwrap(C), llvm::Align(Bytes)));
276 extern "C" LLVMAttributeRef LLVMRustCreateDereferenceableAttr(LLVMContextRef C,
278 return wrap(Attribute::getWithDereferenceableBytes(*unwrap(C), Bytes));
281 extern "C" LLVMAttributeRef LLVMRustCreateDereferenceableOrNullAttr(LLVMContextRef C,
283 return wrap(Attribute::getWithDereferenceableOrNullBytes(*unwrap(C), Bytes));
286 extern "C" LLVMAttributeRef LLVMRustCreateByValAttr(LLVMContextRef C, LLVMTypeRef Ty) {
287 return wrap(Attribute::getWithByValType(*unwrap(C), unwrap(Ty)));
290 extern "C" LLVMAttributeRef LLVMRustCreateStructRetAttr(LLVMContextRef C, LLVMTypeRef Ty) {
291 return wrap(Attribute::getWithStructRetType(*unwrap(C), unwrap(Ty)));
294 extern "C" LLVMAttributeRef LLVMRustCreateUWTableAttr(LLVMContextRef C, bool Async) {
295 #if LLVM_VERSION_LT(15, 0)
296 return wrap(Attribute::get(*unwrap(C), Attribute::UWTable));
298 return wrap(Attribute::getWithUWTableKind(
299 *unwrap(C), Async ? UWTableKind::Async : UWTableKind::Sync));
303 // Enable a fast-math flag
305 // https://llvm.org/docs/LangRef.html#fast-math-flags
306 extern "C" void LLVMRustSetFastMath(LLVMValueRef V) {
307 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
312 extern "C" LLVMValueRef
313 LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Source,
314 const char *Name, LLVMAtomicOrdering Order) {
315 Value *Ptr = unwrap(Source);
316 LoadInst *LI = unwrap(B)->CreateLoad(unwrap(Ty), Ptr, Name);
317 LI->setAtomic(fromRust(Order));
321 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
324 LLVMAtomicOrdering Order) {
325 StoreInst *SI = unwrap(B)->CreateStore(unwrap(V), unwrap(Target));
326 SI->setAtomic(fromRust(Order));
330 // FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak
331 // once we raise our minimum support to LLVM 10.
332 extern "C" LLVMValueRef
333 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
334 LLVMValueRef Old, LLVMValueRef Source,
335 LLVMAtomicOrdering Order,
336 LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
337 #if LLVM_VERSION_GE(13,0)
338 // Rust probably knows the alignment of the target value and should be able to
339 // specify something more precise than MaybeAlign here. See also
340 // https://reviews.llvm.org/D97224 which may be a useful reference.
341 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
342 unwrap(Target), unwrap(Old), unwrap(Source), llvm::MaybeAlign(), fromRust(Order),
343 fromRust(FailureOrder));
345 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
346 unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
347 fromRust(FailureOrder));
353 enum class LLVMRustSynchronizationScope {
358 static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
360 case LLVMRustSynchronizationScope::SingleThread:
361 return SyncScope::SingleThread;
362 case LLVMRustSynchronizationScope::CrossThread:
363 return SyncScope::System;
365 report_fatal_error("bad SynchronizationScope.");
369 extern "C" LLVMValueRef
370 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
371 LLVMRustSynchronizationScope Scope) {
372 return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
375 enum class LLVMRustAsmDialect {
380 static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
382 case LLVMRustAsmDialect::Att:
383 return InlineAsm::AD_ATT;
384 case LLVMRustAsmDialect::Intel:
385 return InlineAsm::AD_Intel;
387 report_fatal_error("bad AsmDialect.");
391 extern "C" LLVMValueRef
392 LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
393 char *Constraints, size_t ConstraintsLen,
394 LLVMBool HasSideEffects, LLVMBool IsAlignStack,
395 LLVMRustAsmDialect Dialect, LLVMBool CanThrow) {
396 #if LLVM_VERSION_GE(13, 0)
397 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
398 StringRef(AsmString, AsmStringLen),
399 StringRef(Constraints, ConstraintsLen),
400 HasSideEffects, IsAlignStack,
401 fromRust(Dialect), CanThrow));
403 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
404 StringRef(AsmString, AsmStringLen),
405 StringRef(Constraints, ConstraintsLen),
406 HasSideEffects, IsAlignStack,
411 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
412 size_t ConstraintsLen) {
413 return InlineAsm::Verify(unwrap<FunctionType>(Ty),
414 StringRef(Constraints, ConstraintsLen));
417 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
419 unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen));
422 typedef DIBuilder *LLVMRustDIBuilderRef;
424 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
425 return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
428 #define DIDescriptor DIScope
429 #define DIArray DINodeArray
430 #define unwrapDI unwrapDIPtr
432 // These values **must** match debuginfo::DIFlags! They also *happen*
433 // to match LLVM, but that isn't required as we do giant sets of
434 // matching below. The value shouldn't be directly passed to LLVM.
435 enum class LLVMRustDIFlags : uint32_t {
440 FlagFwdDecl = (1 << 2),
441 FlagAppleBlock = (1 << 3),
442 FlagBlockByrefStruct = (1 << 4),
443 FlagVirtual = (1 << 5),
444 FlagArtificial = (1 << 6),
445 FlagExplicit = (1 << 7),
446 FlagPrototyped = (1 << 8),
447 FlagObjcClassComplete = (1 << 9),
448 FlagObjectPointer = (1 << 10),
449 FlagVector = (1 << 11),
450 FlagStaticMember = (1 << 12),
451 FlagLValueReference = (1 << 13),
452 FlagRValueReference = (1 << 14),
453 FlagExternalTypeRef = (1 << 15),
454 FlagIntroducedVirtual = (1 << 18),
455 FlagBitField = (1 << 19),
456 FlagNoReturn = (1 << 20),
457 // Do not add values that are not supported by the minimum LLVM
458 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
461 inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
462 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
463 static_cast<uint32_t>(B));
466 inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
467 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
468 static_cast<uint32_t>(B));
471 inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
475 inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
477 inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
478 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
481 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
482 DINode::DIFlags Result = DINode::DIFlags::FlagZero;
484 switch (visibility(Flags)) {
485 case LLVMRustDIFlags::FlagPrivate:
486 Result |= DINode::DIFlags::FlagPrivate;
488 case LLVMRustDIFlags::FlagProtected:
489 Result |= DINode::DIFlags::FlagProtected;
491 case LLVMRustDIFlags::FlagPublic:
492 Result |= DINode::DIFlags::FlagPublic;
495 // The rest are handled below
499 if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
500 Result |= DINode::DIFlags::FlagFwdDecl;
502 if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
503 Result |= DINode::DIFlags::FlagAppleBlock;
505 if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
506 Result |= DINode::DIFlags::FlagVirtual;
508 if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
509 Result |= DINode::DIFlags::FlagArtificial;
511 if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
512 Result |= DINode::DIFlags::FlagExplicit;
514 if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
515 Result |= DINode::DIFlags::FlagPrototyped;
517 if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
518 Result |= DINode::DIFlags::FlagObjcClassComplete;
520 if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
521 Result |= DINode::DIFlags::FlagObjectPointer;
523 if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
524 Result |= DINode::DIFlags::FlagVector;
526 if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
527 Result |= DINode::DIFlags::FlagStaticMember;
529 if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
530 Result |= DINode::DIFlags::FlagLValueReference;
532 if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
533 Result |= DINode::DIFlags::FlagRValueReference;
535 if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
536 Result |= DINode::DIFlags::FlagIntroducedVirtual;
538 if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
539 Result |= DINode::DIFlags::FlagBitField;
541 if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
542 Result |= DINode::DIFlags::FlagNoReturn;
548 // These values **must** match debuginfo::DISPFlags! They also *happen*
549 // to match LLVM, but that isn't required as we do giant sets of
550 // matching below. The value shouldn't be directly passed to LLVM.
551 enum class LLVMRustDISPFlags : uint32_t {
554 SPFlagPureVirtual = 2,
555 SPFlagLocalToUnit = (1 << 2),
556 SPFlagDefinition = (1 << 3),
557 SPFlagOptimized = (1 << 4),
558 SPFlagMainSubprogram = (1 << 5),
559 // Do not add values that are not supported by the minimum LLVM
560 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
561 // (In LLVM < 8, createFunction supported these as separate bool arguments.)
564 inline LLVMRustDISPFlags operator&(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
565 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) &
566 static_cast<uint32_t>(B));
569 inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
570 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) |
571 static_cast<uint32_t>(B));
574 inline LLVMRustDISPFlags &operator|=(LLVMRustDISPFlags &A, LLVMRustDISPFlags B) {
578 inline bool isSet(LLVMRustDISPFlags F) { return F != LLVMRustDISPFlags::SPFlagZero; }
580 inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) {
581 return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(F) & 0x3);
584 static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) {
585 DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero;
587 switch (virtuality(SPFlags)) {
588 case LLVMRustDISPFlags::SPFlagVirtual:
589 Result |= DISubprogram::DISPFlags::SPFlagVirtual;
591 case LLVMRustDISPFlags::SPFlagPureVirtual:
592 Result |= DISubprogram::DISPFlags::SPFlagPureVirtual;
595 // The rest are handled below
599 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit)) {
600 Result |= DISubprogram::DISPFlags::SPFlagLocalToUnit;
602 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition)) {
603 Result |= DISubprogram::DISPFlags::SPFlagDefinition;
605 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) {
606 Result |= DISubprogram::DISPFlags::SPFlagOptimized;
608 if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) {
609 Result |= DISubprogram::DISPFlags::SPFlagMainSubprogram;
615 enum class LLVMRustDebugEmissionKind {
621 static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
623 case LLVMRustDebugEmissionKind::NoDebug:
624 return DICompileUnit::DebugEmissionKind::NoDebug;
625 case LLVMRustDebugEmissionKind::FullDebug:
626 return DICompileUnit::DebugEmissionKind::FullDebug;
627 case LLVMRustDebugEmissionKind::LineTablesOnly:
628 return DICompileUnit::DebugEmissionKind::LineTablesOnly;
630 report_fatal_error("bad DebugEmissionKind.");
634 enum class LLVMRustChecksumKind {
641 static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
643 case LLVMRustChecksumKind::None:
645 case LLVMRustChecksumKind::MD5:
646 return DIFile::ChecksumKind::CSK_MD5;
647 case LLVMRustChecksumKind::SHA1:
648 return DIFile::ChecksumKind::CSK_SHA1;
649 case LLVMRustChecksumKind::SHA256:
650 return DIFile::ChecksumKind::CSK_SHA256;
652 report_fatal_error("bad ChecksumKind.");
656 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
657 return DEBUG_METADATA_VERSION;
660 extern "C" uint32_t LLVMRustVersionPatch() { return LLVM_VERSION_PATCH; }
662 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
664 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
666 extern "C" void LLVMRustAddModuleFlag(
668 Module::ModFlagBehavior MergeBehavior,
671 unwrap(M)->addModuleFlag(MergeBehavior, Name, Value);
674 extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
675 return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
678 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
679 return new DIBuilder(*unwrap(M));
682 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
686 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
690 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
691 LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
692 const char *Producer, size_t ProducerLen, bool isOptimized,
693 const char *Flags, unsigned RuntimeVer,
694 const char *SplitName, size_t SplitNameLen,
695 LLVMRustDebugEmissionKind Kind,
696 uint64_t DWOId, bool SplitDebugInlining) {
697 auto *File = unwrapDI<DIFile>(FileRef);
699 return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
700 isOptimized, Flags, RuntimeVer,
701 StringRef(SplitName, SplitNameLen),
702 fromRust(Kind), DWOId, SplitDebugInlining));
705 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
706 LLVMRustDIBuilderRef Builder,
707 const char *Filename, size_t FilenameLen,
708 const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
709 const char *Checksum, size_t ChecksumLen) {
710 Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
711 Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
713 CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
714 return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
715 StringRef(Directory, DirectoryLen),
719 extern "C" LLVMMetadataRef
720 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
721 LLVMMetadataRef ParameterTypes) {
722 return wrap(Builder->createSubroutineType(
723 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
726 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
727 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
728 const char *Name, size_t NameLen,
729 const char *LinkageName, size_t LinkageNameLen,
730 LLVMMetadataRef File, unsigned LineNo,
731 LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
732 LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam,
733 LLVMMetadataRef Decl) {
734 DITemplateParameterArray TParams =
735 DITemplateParameterArray(unwrap<MDTuple>(TParam));
736 DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
737 DINode::DIFlags llvmFlags = fromRust(Flags);
738 DISubprogram *Sub = Builder->createFunction(
739 unwrapDI<DIScope>(Scope),
740 StringRef(Name, NameLen),
741 StringRef(LinkageName, LinkageNameLen),
742 unwrapDI<DIFile>(File), LineNo,
743 unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
744 llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
746 unwrap<Function>(MaybeFn)->setSubprogram(Sub);
750 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
751 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
752 uint64_t SizeInBits, unsigned Encoding) {
753 return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
756 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
757 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
758 LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
759 return wrap(Builder->createTypedef(
760 unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
761 LineNo, unwrapDIPtr<DIScope>(Scope)));
764 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
765 LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
766 uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
767 const char *Name, size_t NameLen) {
768 return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
769 SizeInBits, AlignInBits,
771 StringRef(Name, NameLen)));
774 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
775 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
776 const char *Name, size_t NameLen,
777 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
778 uint32_t AlignInBits, LLVMRustDIFlags Flags,
779 LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
780 unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
781 const char *UniqueId, size_t UniqueIdLen) {
782 return wrap(Builder->createStructType(
783 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
784 unwrapDI<DIFile>(File), LineNumber,
785 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
786 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
787 unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen)));
790 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
791 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
792 const char *Name, size_t NameLen,
793 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
794 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
795 LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) {
796 return wrap(Builder->createVariantPart(
797 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
798 unwrapDI<DIFile>(File), LineNumber,
799 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
800 DINodeArray(unwrapDI<MDTuple>(Elements)), StringRef(UniqueId, UniqueIdLen)));
803 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
804 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
805 const char *Name, size_t NameLen,
806 LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
807 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
808 LLVMMetadataRef Ty) {
809 return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope),
810 StringRef(Name, NameLen),
811 unwrapDI<DIFile>(File), LineNo,
812 SizeInBits, AlignInBits, OffsetInBits,
813 fromRust(Flags), unwrapDI<DIType>(Ty)));
816 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
817 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
818 const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
819 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
820 LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
821 llvm::ConstantInt* D = nullptr;
823 D = unwrap<llvm::ConstantInt>(Discriminant);
825 return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope),
826 StringRef(Name, NameLen),
827 unwrapDI<DIFile>(File), LineNo,
828 SizeInBits, AlignInBits, OffsetInBits, D,
829 fromRust(Flags), unwrapDI<DIType>(Ty)));
832 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
833 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
834 LLVMMetadataRef File, unsigned Line, unsigned Col) {
835 return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
836 unwrapDI<DIFile>(File), Line, Col));
839 extern "C" LLVMMetadataRef
840 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
841 LLVMMetadataRef Scope,
842 LLVMMetadataRef File) {
843 return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
844 unwrapDI<DIFile>(File)));
847 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
848 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context,
849 const char *Name, size_t NameLen,
850 const char *LinkageName, size_t LinkageNameLen,
851 LLVMMetadataRef File, unsigned LineNo,
852 LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
853 LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
854 llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
856 llvm::DIExpression *InitExpr = nullptr;
857 if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
858 InitExpr = Builder->createConstantValueExpression(
859 IntVal->getValue().getSExtValue());
860 } else if (llvm::ConstantFP *FPVal =
861 llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
862 InitExpr = Builder->createConstantValueExpression(
863 FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
866 llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
867 unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
868 StringRef(LinkageName, LinkageNameLen),
869 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
870 /* isDefined */ true,
871 InitExpr, unwrapDIPtr<MDNode>(Decl),
872 /* templateParams */ nullptr,
875 InitVal->setMetadata("dbg", VarExpr);
877 return wrap(VarExpr);
880 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
881 LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
882 const char *Name, size_t NameLen,
883 LLVMMetadataRef File, unsigned LineNo,
884 LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
885 unsigned ArgNo, uint32_t AlignInBits) {
886 if (Tag == 0x100) { // DW_TAG_auto_variable
887 return wrap(Builder->createAutoVariable(
888 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
889 unwrapDI<DIFile>(File), LineNo,
890 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
892 return wrap(Builder->createParameterVariable(
893 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
894 unwrapDI<DIFile>(File), LineNo,
895 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
899 extern "C" LLVMMetadataRef
900 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
901 uint32_t AlignInBits, LLVMMetadataRef Ty,
902 LLVMMetadataRef Subscripts) {
904 Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
905 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
908 extern "C" LLVMMetadataRef
909 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
911 return wrap(Builder->getOrCreateSubrange(Lo, Count));
914 extern "C" LLVMMetadataRef
915 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
916 LLVMMetadataRef *Ptr, unsigned Count) {
917 Metadata **DataValue = unwrap(Ptr);
919 Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
922 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
923 LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
924 uint64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
925 LLVMBasicBlockRef InsertAtEnd) {
926 return wrap(Builder->insertDeclare(
927 unwrap(V), unwrap<DILocalVariable>(VarInfo),
928 Builder->createExpression(llvm::ArrayRef<uint64_t>(AddrOps, AddrOpsCount)),
929 DebugLoc(cast<MDNode>(unwrap(DL))),
930 unwrap(InsertAtEnd)));
933 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
934 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
935 int64_t Value, bool IsUnsigned) {
936 return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
939 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
940 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
941 const char *Name, size_t NameLen,
942 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
943 uint32_t AlignInBits, LLVMMetadataRef Elements,
944 LLVMMetadataRef ClassTy, bool IsScoped) {
945 return wrap(Builder->createEnumerationType(
946 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
947 unwrapDI<DIFile>(File), LineNumber,
948 SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
949 unwrapDI<DIType>(ClassTy), "", IsScoped));
952 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
953 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
954 const char *Name, size_t NameLen,
955 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
956 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
957 unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) {
958 return wrap(Builder->createUnionType(
959 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File),
960 LineNumber, SizeInBits, AlignInBits, fromRust(Flags),
961 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
962 StringRef(UniqueId, UniqueIdLen)));
965 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
966 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
967 const char *Name, size_t NameLen, LLVMMetadataRef Ty) {
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));
973 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateNameSpace(
974 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
975 const char *Name, size_t NameLen, bool ExportSymbols) {
976 return wrap(Builder->createNameSpace(
977 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols
982 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
983 LLVMMetadataRef CompositeTy,
984 LLVMMetadataRef Elements,
985 LLVMMetadataRef Params) {
986 DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
987 Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
988 DINodeArray(unwrap<MDTuple>(Params)));
991 extern "C" LLVMMetadataRef
992 LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
993 LLVMMetadataRef ScopeRef,
994 LLVMMetadataRef InlinedAt) {
995 MDNode *Scope = unwrapDIPtr<MDNode>(ScopeRef);
996 DILocation *Loc = DILocation::get(
997 Scope->getContext(), Line, Column, Scope,
998 unwrapDIPtr<MDNode>(InlinedAt));
1002 extern "C" uint64_t LLVMRustDIBuilderCreateOpDeref() {
1003 return dwarf::DW_OP_deref;
1006 extern "C" uint64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1007 return dwarf::DW_OP_plus_uconst;
1010 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
1011 RawRustStringOstream OS(Str);
1012 unwrap<llvm::Type>(Ty)->print(OS);
1015 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
1016 RustStringRef Str) {
1017 RawRustStringOstream OS(Str);
1022 unwrap<llvm::Value>(V)->getType()->print(OS);
1024 unwrap<llvm::Value>(V)->print(OS);
1029 // LLVMArrayType function does not support 64-bit ElementCount
1030 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
1031 uint64_t ElementCount) {
1032 return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
1035 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1037 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
1038 RawRustStringOstream OS(Str);
1039 unwrap(T)->print(OS);
1042 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1043 LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
1044 LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
1045 RustStringRef FilenameOut, RustStringRef MessageOut) {
1046 // Undefined to call this not on an optimization diagnostic!
1047 llvm::DiagnosticInfoOptimizationBase *Opt =
1048 static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
1050 RawRustStringOstream PassNameOS(PassNameOut);
1051 PassNameOS << Opt->getPassName();
1052 *FunctionOut = wrap(&Opt->getFunction());
1054 RawRustStringOstream FilenameOS(FilenameOut);
1055 DiagnosticLocation loc = Opt->getLocation();
1056 if (loc.isValid()) {
1057 *Line = loc.getLine();
1058 *Column = loc.getColumn();
1059 FilenameOS << loc.getAbsolutePath();
1062 RawRustStringOstream MessageOS(MessageOut);
1063 MessageOS << Opt->getMsg();
1066 enum class LLVMRustDiagnosticLevel {
1074 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
1075 LLVMRustDiagnosticLevel *LevelOut,
1076 unsigned *CookieOut,
1077 LLVMTwineRef *MessageOut) {
1078 // Undefined to call this not on an inline assembly diagnostic!
1079 llvm::DiagnosticInfoInlineAsm *IA =
1080 static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
1082 *CookieOut = IA->getLocCookie();
1083 *MessageOut = wrap(&IA->getMsgStr());
1085 switch (IA->getSeverity()) {
1087 *LevelOut = LLVMRustDiagnosticLevel::Error;
1090 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1093 *LevelOut = LLVMRustDiagnosticLevel::Note;
1096 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1099 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1103 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
1104 RustStringRef Str) {
1105 RawRustStringOstream OS(Str);
1106 DiagnosticPrinterRawOStream DP(OS);
1107 unwrap(DI)->print(DP);
1110 enum class LLVMRustDiagnosticKind {
1114 DebugMetadataVersion,
1117 OptimizationRemarkMissed,
1118 OptimizationRemarkAnalysis,
1119 OptimizationRemarkAnalysisFPCommute,
1120 OptimizationRemarkAnalysisAliasing,
1121 OptimizationRemarkOther,
1122 OptimizationFailure,
1129 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1132 return LLVMRustDiagnosticKind::InlineAsm;
1134 return LLVMRustDiagnosticKind::StackSize;
1135 case DK_DebugMetadataVersion:
1136 return LLVMRustDiagnosticKind::DebugMetadataVersion;
1137 case DK_SampleProfile:
1138 return LLVMRustDiagnosticKind::SampleProfile;
1139 case DK_OptimizationRemark:
1140 case DK_MachineOptimizationRemark:
1141 return LLVMRustDiagnosticKind::OptimizationRemark;
1142 case DK_OptimizationRemarkMissed:
1143 case DK_MachineOptimizationRemarkMissed:
1144 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1145 case DK_OptimizationRemarkAnalysis:
1146 case DK_MachineOptimizationRemarkAnalysis:
1147 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1148 case DK_OptimizationRemarkAnalysisFPCommute:
1149 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1150 case DK_OptimizationRemarkAnalysisAliasing:
1151 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1153 return LLVMRustDiagnosticKind::PGOProfile;
1155 return LLVMRustDiagnosticKind::Linker;
1156 case DK_Unsupported:
1157 return LLVMRustDiagnosticKind::Unsupported;
1158 #if LLVM_VERSION_GE(13, 0)
1160 return LLVMRustDiagnosticKind::SrcMgr;
1163 return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1164 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1165 : LLVMRustDiagnosticKind::Other;
1169 extern "C" LLVMRustDiagnosticKind
1170 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1171 return toRust((DiagnosticKind)unwrap(DI)->getKind());
1174 // This is kept distinct from LLVMGetTypeKind, because when
1175 // a new type kind is added, the Rust-side enum must be
1176 // updated or UB will result.
1177 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1178 switch (unwrap(Ty)->getTypeID()) {
1179 case Type::VoidTyID:
1180 return LLVMVoidTypeKind;
1181 case Type::HalfTyID:
1182 return LLVMHalfTypeKind;
1183 case Type::FloatTyID:
1184 return LLVMFloatTypeKind;
1185 case Type::DoubleTyID:
1186 return LLVMDoubleTypeKind;
1187 case Type::X86_FP80TyID:
1188 return LLVMX86_FP80TypeKind;
1189 case Type::FP128TyID:
1190 return LLVMFP128TypeKind;
1191 case Type::PPC_FP128TyID:
1192 return LLVMPPC_FP128TypeKind;
1193 case Type::LabelTyID:
1194 return LLVMLabelTypeKind;
1195 case Type::MetadataTyID:
1196 return LLVMMetadataTypeKind;
1197 case Type::IntegerTyID:
1198 return LLVMIntegerTypeKind;
1199 case Type::FunctionTyID:
1200 return LLVMFunctionTypeKind;
1201 case Type::StructTyID:
1202 return LLVMStructTypeKind;
1203 case Type::ArrayTyID:
1204 return LLVMArrayTypeKind;
1205 case Type::PointerTyID:
1206 return LLVMPointerTypeKind;
1207 case Type::FixedVectorTyID:
1208 return LLVMVectorTypeKind;
1209 case Type::X86_MMXTyID:
1210 return LLVMX86_MMXTypeKind;
1211 case Type::TokenTyID:
1212 return LLVMTokenTypeKind;
1213 case Type::ScalableVectorTyID:
1214 return LLVMScalableVectorTypeKind;
1215 case Type::BFloatTyID:
1216 return LLVMBFloatTypeKind;
1217 case Type::X86_AMXTyID:
1218 return LLVMX86_AMXTypeKind;
1220 report_fatal_error("Unhandled TypeID.");
1223 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1225 #if LLVM_VERSION_LT(13, 0)
1226 using LLVMInlineAsmDiagHandlerTy = LLVMContext::InlineAsmDiagHandlerTy;
1228 using LLVMInlineAsmDiagHandlerTy = void*;
1231 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1232 LLVMContextRef C, LLVMInlineAsmDiagHandlerTy H, void *CX) {
1233 // Diagnostic handlers were unified in LLVM change 5de2d189e6ad, so starting
1234 // with LLVM 13 this function is gone.
1235 #if LLVM_VERSION_LT(13, 0)
1236 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1240 extern "C" LLVMSMDiagnosticRef LLVMRustGetSMDiagnostic(
1241 LLVMDiagnosticInfoRef DI, unsigned *Cookie) {
1242 #if LLVM_VERSION_GE(13, 0)
1243 llvm::DiagnosticInfoSrcMgr *SM = static_cast<llvm::DiagnosticInfoSrcMgr *>(unwrap(DI));
1244 *Cookie = SM->getLocCookie();
1245 return wrap(&SM->getSMDiag());
1247 report_fatal_error("Shouldn't get called on older versions");
1251 extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
1252 RustStringRef MessageOut,
1253 RustStringRef BufferOut,
1254 LLVMRustDiagnosticLevel* LevelOut,
1256 unsigned* RangesOut,
1257 size_t* NumRanges) {
1258 SMDiagnostic& D = *unwrap(DRef);
1259 RawRustStringOstream MessageOS(MessageOut);
1260 MessageOS << D.getMessage();
1262 switch (D.getKind()) {
1263 case SourceMgr::DK_Error:
1264 *LevelOut = LLVMRustDiagnosticLevel::Error;
1266 case SourceMgr::DK_Warning:
1267 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1269 case SourceMgr::DK_Note:
1270 *LevelOut = LLVMRustDiagnosticLevel::Note;
1272 case SourceMgr::DK_Remark:
1273 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1276 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1279 if (D.getLoc() == SMLoc())
1282 const SourceMgr &LSM = *D.getSourceMgr();
1283 const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
1284 LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), LBuf->getBufferSize());
1286 *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
1288 *NumRanges = std::min(*NumRanges, D.getRanges().size());
1289 size_t LineStart = *LocOut - (size_t)D.getColumnNo();
1290 for (size_t i = 0; i < *NumRanges; i++) {
1291 RangesOut[i * 2] = LineStart + D.getRanges()[i].first;
1292 RangesOut[i * 2 + 1] = LineStart + D.getRanges()[i].second;
1298 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1299 LLVMValueRef ParentPad,
1301 LLVMValueRef *LLArgs,
1303 Value **Args = unwrap(LLArgs);
1304 if (ParentPad == nullptr) {
1305 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1306 ParentPad = wrap(Constant::getNullValue(Ty));
1308 return wrap(unwrap(B)->CreateCleanupPad(
1309 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1312 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1313 LLVMValueRef CleanupPad,
1314 LLVMBasicBlockRef UnwindBB) {
1315 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1316 return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1319 extern "C" LLVMValueRef
1320 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1321 unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1322 Value **Args = unwrap(LLArgs);
1323 return wrap(unwrap(B)->CreateCatchPad(
1324 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1327 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1329 LLVMBasicBlockRef BB) {
1330 return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1334 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1335 LLVMValueRef ParentPad,
1336 LLVMBasicBlockRef BB,
1337 unsigned NumHandlers,
1339 if (ParentPad == nullptr) {
1340 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1341 ParentPad = wrap(Constant::getNullValue(Ty));
1343 return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1344 NumHandlers, Name));
1347 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1348 LLVMBasicBlockRef Handler) {
1349 Value *CatchSwitch = unwrap(CatchSwitchRef);
1350 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1353 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1354 LLVMValueRef *Inputs,
1355 unsigned NumInputs) {
1356 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1359 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1363 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
1364 LLVMValueRef *Args, unsigned NumArgs,
1365 OperandBundleDef *Bundle) {
1366 Value *Callee = unwrap(Fn);
1367 FunctionType *FTy = unwrap<FunctionType>(Ty);
1368 unsigned Len = Bundle ? 1 : 0;
1369 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1370 return wrap(unwrap(B)->CreateCall(
1371 FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles));
1374 extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
1375 return wrap(llvm::Intrinsic::getDeclaration(unwrap(M),
1376 (llvm::Intrinsic::ID)llvm::Intrinsic::instrprof_increment));
1379 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
1380 LLVMValueRef Dst, unsigned DstAlign,
1381 LLVMValueRef Src, unsigned SrcAlign,
1382 LLVMValueRef Size, bool IsVolatile) {
1383 return wrap(unwrap(B)->CreateMemCpy(
1384 unwrap(Dst), MaybeAlign(DstAlign),
1385 unwrap(Src), MaybeAlign(SrcAlign),
1386 unwrap(Size), IsVolatile));
1389 extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
1390 LLVMValueRef Dst, unsigned DstAlign,
1391 LLVMValueRef Src, unsigned SrcAlign,
1392 LLVMValueRef Size, bool IsVolatile) {
1393 return wrap(unwrap(B)->CreateMemMove(
1394 unwrap(Dst), MaybeAlign(DstAlign),
1395 unwrap(Src), MaybeAlign(SrcAlign),
1396 unwrap(Size), IsVolatile));
1399 extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
1400 LLVMValueRef Dst, unsigned DstAlign,
1402 LLVMValueRef Size, bool IsVolatile) {
1403 return wrap(unwrap(B)->CreateMemSet(
1404 unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
1407 extern "C" LLVMValueRef
1408 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
1409 LLVMValueRef *Args, unsigned NumArgs,
1410 LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
1411 OperandBundleDef *Bundle, const char *Name) {
1412 Value *Callee = unwrap(Fn);
1413 FunctionType *FTy = unwrap<FunctionType>(Ty);
1414 unsigned Len = Bundle ? 1 : 0;
1415 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1416 return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
1417 makeArrayRef(unwrap(Args), NumArgs),
1421 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1422 LLVMBasicBlockRef BB) {
1423 auto Point = unwrap(BB)->getFirstInsertionPt();
1424 unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1427 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1428 const char *Name, size_t NameLen) {
1429 Triple TargetTriple(unwrap(M)->getTargetTriple());
1430 GlobalObject *GV = unwrap<GlobalObject>(V);
1431 if (TargetTriple.supportsCOMDAT()) {
1432 StringRef NameRef(Name, NameLen);
1433 GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
1437 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1438 GlobalObject *GV = unwrap<GlobalObject>(V);
1439 GV->setComdat(nullptr);
1442 enum class LLVMRustLinkage {
1443 ExternalLinkage = 0,
1444 AvailableExternallyLinkage = 1,
1445 LinkOnceAnyLinkage = 2,
1446 LinkOnceODRLinkage = 3,
1449 AppendingLinkage = 6,
1450 InternalLinkage = 7,
1452 ExternalWeakLinkage = 9,
1456 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1458 case LLVMExternalLinkage:
1459 return LLVMRustLinkage::ExternalLinkage;
1460 case LLVMAvailableExternallyLinkage:
1461 return LLVMRustLinkage::AvailableExternallyLinkage;
1462 case LLVMLinkOnceAnyLinkage:
1463 return LLVMRustLinkage::LinkOnceAnyLinkage;
1464 case LLVMLinkOnceODRLinkage:
1465 return LLVMRustLinkage::LinkOnceODRLinkage;
1466 case LLVMWeakAnyLinkage:
1467 return LLVMRustLinkage::WeakAnyLinkage;
1468 case LLVMWeakODRLinkage:
1469 return LLVMRustLinkage::WeakODRLinkage;
1470 case LLVMAppendingLinkage:
1471 return LLVMRustLinkage::AppendingLinkage;
1472 case LLVMInternalLinkage:
1473 return LLVMRustLinkage::InternalLinkage;
1474 case LLVMPrivateLinkage:
1475 return LLVMRustLinkage::PrivateLinkage;
1476 case LLVMExternalWeakLinkage:
1477 return LLVMRustLinkage::ExternalWeakLinkage;
1478 case LLVMCommonLinkage:
1479 return LLVMRustLinkage::CommonLinkage;
1481 report_fatal_error("Invalid LLVMRustLinkage value!");
1485 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1487 case LLVMRustLinkage::ExternalLinkage:
1488 return LLVMExternalLinkage;
1489 case LLVMRustLinkage::AvailableExternallyLinkage:
1490 return LLVMAvailableExternallyLinkage;
1491 case LLVMRustLinkage::LinkOnceAnyLinkage:
1492 return LLVMLinkOnceAnyLinkage;
1493 case LLVMRustLinkage::LinkOnceODRLinkage:
1494 return LLVMLinkOnceODRLinkage;
1495 case LLVMRustLinkage::WeakAnyLinkage:
1496 return LLVMWeakAnyLinkage;
1497 case LLVMRustLinkage::WeakODRLinkage:
1498 return LLVMWeakODRLinkage;
1499 case LLVMRustLinkage::AppendingLinkage:
1500 return LLVMAppendingLinkage;
1501 case LLVMRustLinkage::InternalLinkage:
1502 return LLVMInternalLinkage;
1503 case LLVMRustLinkage::PrivateLinkage:
1504 return LLVMPrivateLinkage;
1505 case LLVMRustLinkage::ExternalWeakLinkage:
1506 return LLVMExternalWeakLinkage;
1507 case LLVMRustLinkage::CommonLinkage:
1508 return LLVMCommonLinkage;
1510 report_fatal_error("Invalid LLVMRustLinkage value!");
1513 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1514 return toRust(LLVMGetLinkage(V));
1517 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1518 LLVMRustLinkage RustLinkage) {
1519 LLVMSetLinkage(V, fromRust(RustLinkage));
1522 extern "C" LLVMValueRef LLVMRustConstInBoundsGEP2(LLVMTypeRef Ty,
1523 LLVMValueRef ConstantVal,
1524 LLVMValueRef *ConstantIndices,
1525 unsigned NumIndices) {
1526 ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
1528 Constant *Val = unwrap<Constant>(ConstantVal);
1529 return wrap(ConstantExpr::getInBoundsGetElementPtr(unwrap(Ty), Val, IdxList));
1532 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1533 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1534 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1536 auto C = unwrap<llvm::ConstantInt>(CV);
1537 if (C->getBitWidth() > 128) { return false; }
1540 AP = C->getValue().sextOrSelf(128);
1542 AP = C->getValue().zextOrSelf(128);
1544 *low = AP.getLoBits(64).getZExtValue();
1545 *high = AP.getHiBits(64).getZExtValue();
1549 enum class LLVMRustVisibility {
1555 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1557 case LLVMDefaultVisibility:
1558 return LLVMRustVisibility::Default;
1559 case LLVMHiddenVisibility:
1560 return LLVMRustVisibility::Hidden;
1561 case LLVMProtectedVisibility:
1562 return LLVMRustVisibility::Protected;
1564 report_fatal_error("Invalid LLVMRustVisibility value!");
1567 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1569 case LLVMRustVisibility::Default:
1570 return LLVMDefaultVisibility;
1571 case LLVMRustVisibility::Hidden:
1572 return LLVMHiddenVisibility;
1573 case LLVMRustVisibility::Protected:
1574 return LLVMProtectedVisibility;
1576 report_fatal_error("Invalid LLVMRustVisibility value!");
1579 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1580 return toRust(LLVMGetVisibility(V));
1583 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1584 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1585 LLVMTypeRef DestTy, bool isSigned) {
1586 return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1589 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1590 LLVMRustVisibility RustVisibility) {
1591 LLVMSetVisibility(V, fromRust(RustVisibility));
1594 extern "C" void LLVMRustSetDSOLocal(LLVMValueRef Global, bool is_dso_local) {
1595 unwrap<GlobalValue>(Global)->setDSOLocal(is_dso_local);
1598 struct LLVMRustModuleBuffer {
1602 extern "C" LLVMRustModuleBuffer*
1603 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1604 auto Ret = std::make_unique<LLVMRustModuleBuffer>();
1606 raw_string_ostream OS(Ret->data);
1608 legacy::PassManager PM;
1609 PM.add(createBitcodeWriterPass(OS));
1613 return Ret.release();
1617 LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1621 extern "C" const void*
1622 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1623 return Buffer->data.data();
1627 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1628 return Buffer->data.length();
1632 LLVMRustModuleCost(LLVMModuleRef M) {
1633 auto f = unwrap(M)->functions();
1634 return std::distance(std::begin(f), std::end(f));
1637 // Vector reductions:
1638 extern "C" LLVMValueRef
1639 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1640 return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1642 extern "C" LLVMValueRef
1643 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1644 return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1646 extern "C" LLVMValueRef
1647 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1648 return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1650 extern "C" LLVMValueRef
1651 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1652 return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1654 extern "C" LLVMValueRef
1655 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1656 return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1658 extern "C" LLVMValueRef
1659 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1660 return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1662 extern "C" LLVMValueRef
1663 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1664 return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1666 extern "C" LLVMValueRef
1667 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1668 return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1670 extern "C" LLVMValueRef
1671 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1672 return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1674 extern "C" LLVMValueRef
1675 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1676 Instruction *I = unwrap(B)->CreateFPMinReduce(unwrap(Src));
1677 I->setHasNoNaNs(NoNaN);
1680 extern "C" LLVMValueRef
1681 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1682 Instruction *I = unwrap(B)->CreateFPMaxReduce(unwrap(Src));
1683 I->setHasNoNaNs(NoNaN);
1687 extern "C" LLVMValueRef
1688 LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1689 return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1691 extern "C" LLVMValueRef
1692 LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1693 return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));
1696 // This struct contains all necessary info about a symbol exported from a DLL.
1697 struct LLVMRustCOFFShortExport {
1699 bool ordinal_present;
1700 // The value of `ordinal` is only meaningful if `ordinal_present` is true.
1704 // Machine must be a COFF machine type, as defined in PE specs.
1705 extern "C" LLVMRustResult LLVMRustWriteImportLibrary(
1706 const char* ImportName,
1708 const LLVMRustCOFFShortExport* Exports,
1713 std::vector<llvm::object::COFFShortExport> ConvertedExports;
1714 ConvertedExports.reserve(NumExports);
1716 for (size_t i = 0; i < NumExports; ++i) {
1717 bool ordinal_present = Exports[i].ordinal_present;
1718 uint16_t ordinal = ordinal_present ? Exports[i].ordinal : 0;
1719 ConvertedExports.push_back(llvm::object::COFFShortExport{
1720 Exports[i].name, // Name
1721 std::string{}, // ExtName
1722 std::string{}, // SymbolName
1723 std::string{}, // AliasTarget
1725 ordinal_present, // Noname
1732 auto Error = llvm::object::writeImportLibrary(
1736 static_cast<llvm::COFF::MachineTypes>(Machine),
1739 std::string errorString;
1740 llvm::raw_string_ostream stream(errorString);
1743 LLVMRustSetLastError(errorString.c_str());
1744 return LLVMRustResult::Failure;
1746 return LLVMRustResult::Success;
1750 // Transfers ownership of DiagnosticHandler unique_ptr to the caller.
1751 extern "C" DiagnosticHandler *
1752 LLVMRustContextGetDiagnosticHandler(LLVMContextRef C) {
1753 std::unique_ptr<DiagnosticHandler> DH = unwrap(C)->getDiagnosticHandler();
1754 return DH.release();
1757 // Sets unique_ptr to object of DiagnosticHandler to provide custom diagnostic
1758 // handling. Ownership of the handler is moved to the LLVMContext.
1759 extern "C" void LLVMRustContextSetDiagnosticHandler(LLVMContextRef C,
1760 DiagnosticHandler *DH) {
1761 unwrap(C)->setDiagnosticHandler(std::unique_ptr<DiagnosticHandler>(DH));
1764 using LLVMDiagnosticHandlerTy = DiagnosticHandler::DiagnosticHandlerTy;
1766 // Configures a diagnostic handler that invokes provided callback when a
1767 // backend needs to emit a diagnostic.
1769 // When RemarkAllPasses is true, remarks are enabled for all passes. Otherwise
1770 // the RemarkPasses array specifies individual passes for which remarks will be
1772 extern "C" void LLVMRustContextConfigureDiagnosticHandler(
1773 LLVMContextRef C, LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
1774 void *DiagnosticHandlerContext, bool RemarkAllPasses,
1775 const char * const * RemarkPasses, size_t RemarkPassesLen) {
1777 class RustDiagnosticHandler final : public DiagnosticHandler {
1779 RustDiagnosticHandler(LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
1780 void *DiagnosticHandlerContext,
1781 bool RemarkAllPasses,
1782 std::vector<std::string> RemarkPasses)
1783 : DiagnosticHandlerCallback(DiagnosticHandlerCallback),
1784 DiagnosticHandlerContext(DiagnosticHandlerContext),
1785 RemarkAllPasses(RemarkAllPasses),
1786 RemarkPasses(RemarkPasses) {}
1788 virtual bool handleDiagnostics(const DiagnosticInfo &DI) override {
1789 if (DiagnosticHandlerCallback) {
1790 DiagnosticHandlerCallback(DI, DiagnosticHandlerContext);
1796 bool isAnalysisRemarkEnabled(StringRef PassName) const override {
1797 return isRemarkEnabled(PassName);
1800 bool isMissedOptRemarkEnabled(StringRef PassName) const override {
1801 return isRemarkEnabled(PassName);
1804 bool isPassedOptRemarkEnabled(StringRef PassName) const override {
1805 return isRemarkEnabled(PassName);
1808 bool isAnyRemarkEnabled() const override {
1809 return RemarkAllPasses || !RemarkPasses.empty();
1813 bool isRemarkEnabled(StringRef PassName) const {
1814 if (RemarkAllPasses)
1817 for (auto &Pass : RemarkPasses)
1818 if (Pass == PassName)
1824 LLVMDiagnosticHandlerTy DiagnosticHandlerCallback = nullptr;
1825 void *DiagnosticHandlerContext = nullptr;
1827 bool RemarkAllPasses = false;
1828 std::vector<std::string> RemarkPasses;
1831 std::vector<std::string> Passes;
1832 for (size_t I = 0; I != RemarkPassesLen; ++I)
1833 Passes.push_back(RemarkPasses[I]);
1835 unwrap(C)->setDiagnosticHandler(std::make_unique<RustDiagnosticHandler>(
1836 DiagnosticHandlerCallback, DiagnosticHandlerContext, RemarkAllPasses, Passes));
1839 extern "C" void LLVMRustGetMangledName(LLVMValueRef V, RustStringRef Str) {
1840 RawRustStringOstream OS(Str);
1841 GlobalValue *GV = unwrap<GlobalValue>(V);
1842 Mangler().getNameWithPrefix(OS, GV, true);