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/IR/Mangler.h"
10 #include "llvm/Object/Archive.h"
11 #include "llvm/Object/COFFImportFile.h"
12 #include "llvm/Object/ObjectFile.h"
13 #include "llvm/Pass.h"
14 #include "llvm/Bitcode/BitcodeWriterPass.h"
15 #include "llvm/Support/Signals.h"
16 #include "llvm/ADT/Optional.h"
20 //===----------------------------------------------------------------------===
22 // This file defines alternate interfaces to core functions that are more
23 // readily callable by Rust's FFI.
25 //===----------------------------------------------------------------------===
28 using namespace llvm::sys;
29 using namespace llvm::object;
31 // LLVMAtomicOrdering is already an enum - don't create another
33 static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
35 case LLVMAtomicOrderingNotAtomic:
36 return AtomicOrdering::NotAtomic;
37 case LLVMAtomicOrderingUnordered:
38 return AtomicOrdering::Unordered;
39 case LLVMAtomicOrderingMonotonic:
40 return AtomicOrdering::Monotonic;
41 case LLVMAtomicOrderingAcquire:
42 return AtomicOrdering::Acquire;
43 case LLVMAtomicOrderingRelease:
44 return AtomicOrdering::Release;
45 case LLVMAtomicOrderingAcquireRelease:
46 return AtomicOrdering::AcquireRelease;
47 case LLVMAtomicOrderingSequentiallyConsistent:
48 return AtomicOrdering::SequentiallyConsistent;
51 report_fatal_error("Invalid LLVMAtomicOrdering value!");
54 static LLVM_THREAD_LOCAL char *LastError;
56 // Custom error handler for fatal LLVM errors.
58 // Notably it exits the process with code 101, unlike LLVM's default of 1.
59 static void FatalErrorHandler(void *UserData,
60 #if LLVM_VERSION_LT(14, 0)
61 const std::string& Reason,
66 // Do the same thing that the default error handler does.
67 std::cerr << "LLVM ERROR: " << Reason << std::endl;
69 // Since this error handler exits the process, we have to run any cleanup that
70 // LLVM would run after handling the error. This might change with an LLVM
72 sys::RunInterruptHandlers();
77 extern "C" void LLVMRustInstallFatalErrorHandler() {
78 install_fatal_error_handler(FatalErrorHandler);
81 extern "C" void LLVMRustDisableSystemDialogsOnCrash() {
82 sys::DisableSystemDialogsOnCrash();
85 extern "C" char *LLVMRustGetLastError(void) {
86 char *Ret = LastError;
91 extern "C" unsigned int LLVMRustGetInstructionCount(LLVMModuleRef M) {
92 return unwrap(M)->getInstructionCount();
95 extern "C" void LLVMRustSetLastError(const char *Err) {
96 free((void *)LastError);
97 LastError = strdup(Err);
100 extern "C" LLVMContextRef LLVMRustContextCreate(bool shouldDiscardNames) {
101 auto ctx = new LLVMContext();
102 ctx->setDiscardValueNames(shouldDiscardNames);
106 extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M,
107 const char *Triple) {
108 unwrap(M)->setTargetTriple(Triple::normalize(Triple));
111 extern "C" void LLVMRustPrintPassTimings() {
112 raw_fd_ostream OS(2, false); // stderr.
113 TimerGroup::printAll(OS);
116 extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
118 return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen)));
121 extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
124 LLVMTypeRef FunctionTy) {
125 return wrap(unwrap(M)
126 ->getOrInsertFunction(StringRef(Name, NameLen),
127 unwrap<FunctionType>(FunctionTy))
132 extern "C" LLVMValueRef
133 LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) {
134 Module *Mod = unwrap(M);
135 StringRef NameRef(Name, NameLen);
137 // We don't use Module::getOrInsertGlobal because that returns a Constant*,
138 // which may either be the real GlobalVariable*, or a constant bitcast of it
139 // if our type doesn't match the original declaration. We always want the
140 // GlobalVariable* so we can access linkage, visibility, etc.
141 GlobalVariable *GV = Mod->getGlobalVariable(NameRef, true);
143 GV = new GlobalVariable(*Mod, unwrap(Ty), false,
144 GlobalValue::ExternalLinkage, nullptr, NameRef);
148 extern "C" LLVMValueRef
149 LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) {
150 return wrap(new GlobalVariable(*unwrap(M),
153 GlobalValue::PrivateLinkage,
157 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
158 return wrap(Type::getMetadataTy(*unwrap(C)));
161 static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
164 return Attribute::AlwaysInline;
166 return Attribute::ByVal;
168 return Attribute::Cold;
170 return Attribute::InlineHint;
172 return Attribute::MinSize;
174 return Attribute::Naked;
176 return Attribute::NoAlias;
178 return Attribute::NoCapture;
180 return Attribute::NoInline;
182 return Attribute::NonNull;
184 return Attribute::NoRedZone;
186 return Attribute::NoReturn;
188 return Attribute::NoUnwind;
189 case OptimizeForSize:
190 return Attribute::OptimizeForSize;
192 return Attribute::ReadOnly;
194 return Attribute::SExt;
196 return Attribute::StructRet;
198 return Attribute::UWTable;
200 return Attribute::ZExt;
202 return Attribute::InReg;
204 return Attribute::SanitizeThread;
205 case SanitizeAddress:
206 return Attribute::SanitizeAddress;
208 return Attribute::SanitizeMemory;
210 return Attribute::NonLazyBind;
212 return Attribute::OptimizeNone;
214 return Attribute::ReturnsTwice;
216 return Attribute::ReadNone;
217 case InaccessibleMemOnly:
218 return Attribute::InaccessibleMemOnly;
219 case SanitizeHWAddress:
220 return Attribute::SanitizeHWAddress;
222 return Attribute::WillReturn;
223 case StackProtectReq:
224 return Attribute::StackProtectReq;
225 case StackProtectStrong:
226 return Attribute::StackProtectStrong;
228 return Attribute::StackProtect;
230 return Attribute::NoUndef;
232 return Attribute::SanitizeMemTag;
234 report_fatal_error("bad AttributeKind");
237 template<typename T> static inline void AddAttributes(T *t, unsigned Index,
238 LLVMAttributeRef *Attrs, size_t AttrsLen) {
239 AttributeList PAL = t->getAttributes();
240 AttributeList PALNew;
241 #if LLVM_VERSION_LT(14, 0)
243 for (LLVMAttributeRef Attr : makeArrayRef(Attrs, AttrsLen))
244 B.addAttribute(unwrap(Attr));
245 PALNew = PAL.addAttributes(t->getContext(), Index, B);
247 AttrBuilder B(t->getContext());
248 for (LLVMAttributeRef Attr : makeArrayRef(Attrs, AttrsLen))
249 B.addAttribute(unwrap(Attr));
250 PALNew = PAL.addAttributesAtIndex(t->getContext(), Index, B);
252 t->setAttributes(PALNew);
255 extern "C" void LLVMRustAddFunctionAttributes(LLVMValueRef Fn, unsigned Index,
256 LLVMAttributeRef *Attrs, size_t AttrsLen) {
257 Function *F = unwrap<Function>(Fn);
258 AddAttributes(F, Index, Attrs, AttrsLen);
261 extern "C" void LLVMRustAddCallSiteAttributes(LLVMValueRef Instr, unsigned Index,
262 LLVMAttributeRef *Attrs, size_t AttrsLen) {
263 CallBase *Call = unwrap<CallBase>(Instr);
264 AddAttributes(Call, Index, Attrs, AttrsLen);
267 extern "C" LLVMAttributeRef LLVMRustCreateAttrNoValue(LLVMContextRef C,
268 LLVMRustAttribute RustAttr) {
269 return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr)));
272 extern "C" LLVMAttributeRef LLVMRustCreateAlignmentAttr(LLVMContextRef C,
274 return wrap(Attribute::getWithAlignment(*unwrap(C), llvm::Align(Bytes)));
277 extern "C" LLVMAttributeRef LLVMRustCreateDereferenceableAttr(LLVMContextRef C,
279 return wrap(Attribute::getWithDereferenceableBytes(*unwrap(C), Bytes));
282 extern "C" LLVMAttributeRef LLVMRustCreateDereferenceableOrNullAttr(LLVMContextRef C,
284 return wrap(Attribute::getWithDereferenceableOrNullBytes(*unwrap(C), Bytes));
287 extern "C" LLVMAttributeRef LLVMRustCreateByValAttr(LLVMContextRef C, LLVMTypeRef Ty) {
288 return wrap(Attribute::getWithByValType(*unwrap(C), unwrap(Ty)));
291 extern "C" LLVMAttributeRef LLVMRustCreateStructRetAttr(LLVMContextRef C, LLVMTypeRef Ty) {
292 return wrap(Attribute::getWithStructRetType(*unwrap(C), unwrap(Ty)));
295 extern "C" LLVMAttributeRef LLVMRustCreateUWTableAttr(LLVMContextRef C, bool Async) {
296 #if LLVM_VERSION_LT(15, 0)
297 return wrap(Attribute::get(*unwrap(C), Attribute::UWTable));
299 return wrap(Attribute::getWithUWTableKind(
300 *unwrap(C), Async ? UWTableKind::Async : UWTableKind::Sync));
304 // Enable a fast-math flag
306 // https://llvm.org/docs/LangRef.html#fast-math-flags
307 extern "C" void LLVMRustSetFastMath(LLVMValueRef V) {
308 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
313 extern "C" LLVMValueRef
314 LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Source,
315 const char *Name, LLVMAtomicOrdering Order) {
316 Value *Ptr = unwrap(Source);
317 LoadInst *LI = unwrap(B)->CreateLoad(unwrap(Ty), Ptr, Name);
318 LI->setAtomic(fromRust(Order));
322 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
325 LLVMAtomicOrdering Order) {
326 StoreInst *SI = unwrap(B)->CreateStore(unwrap(V), unwrap(Target));
327 SI->setAtomic(fromRust(Order));
331 // FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak
332 // once we raise our minimum support to LLVM 10.
333 extern "C" LLVMValueRef
334 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
335 LLVMValueRef Old, LLVMValueRef Source,
336 LLVMAtomicOrdering Order,
337 LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
338 #if LLVM_VERSION_GE(13,0)
339 // Rust probably knows the alignment of the target value and should be able to
340 // specify something more precise than MaybeAlign here. See also
341 // https://reviews.llvm.org/D97224 which may be a useful reference.
342 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
343 unwrap(Target), unwrap(Old), unwrap(Source), llvm::MaybeAlign(), fromRust(Order),
344 fromRust(FailureOrder));
346 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
347 unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
348 fromRust(FailureOrder));
354 enum class LLVMRustSynchronizationScope {
359 static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
361 case LLVMRustSynchronizationScope::SingleThread:
362 return SyncScope::SingleThread;
363 case LLVMRustSynchronizationScope::CrossThread:
364 return SyncScope::System;
366 report_fatal_error("bad SynchronizationScope.");
370 extern "C" LLVMValueRef
371 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
372 LLVMRustSynchronizationScope Scope) {
373 return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
376 enum class LLVMRustAsmDialect {
381 static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
383 case LLVMRustAsmDialect::Att:
384 return InlineAsm::AD_ATT;
385 case LLVMRustAsmDialect::Intel:
386 return InlineAsm::AD_Intel;
388 report_fatal_error("bad AsmDialect.");
392 extern "C" LLVMValueRef
393 LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
394 char *Constraints, size_t ConstraintsLen,
395 LLVMBool HasSideEffects, LLVMBool IsAlignStack,
396 LLVMRustAsmDialect Dialect, LLVMBool CanThrow) {
397 #if LLVM_VERSION_GE(13, 0)
398 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
399 StringRef(AsmString, AsmStringLen),
400 StringRef(Constraints, ConstraintsLen),
401 HasSideEffects, IsAlignStack,
402 fromRust(Dialect), CanThrow));
404 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
405 StringRef(AsmString, AsmStringLen),
406 StringRef(Constraints, ConstraintsLen),
407 HasSideEffects, IsAlignStack,
412 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
413 size_t ConstraintsLen) {
414 return InlineAsm::Verify(unwrap<FunctionType>(Ty),
415 StringRef(Constraints, ConstraintsLen));
418 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
420 unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen));
423 typedef DIBuilder *LLVMRustDIBuilderRef;
425 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
426 return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
429 #define DIDescriptor DIScope
430 #define DIArray DINodeArray
431 #define unwrapDI unwrapDIPtr
433 // These values **must** match debuginfo::DIFlags! They also *happen*
434 // to match LLVM, but that isn't required as we do giant sets of
435 // matching below. The value shouldn't be directly passed to LLVM.
436 enum class LLVMRustDIFlags : uint32_t {
441 FlagFwdDecl = (1 << 2),
442 FlagAppleBlock = (1 << 3),
443 FlagBlockByrefStruct = (1 << 4),
444 FlagVirtual = (1 << 5),
445 FlagArtificial = (1 << 6),
446 FlagExplicit = (1 << 7),
447 FlagPrototyped = (1 << 8),
448 FlagObjcClassComplete = (1 << 9),
449 FlagObjectPointer = (1 << 10),
450 FlagVector = (1 << 11),
451 FlagStaticMember = (1 << 12),
452 FlagLValueReference = (1 << 13),
453 FlagRValueReference = (1 << 14),
454 FlagExternalTypeRef = (1 << 15),
455 FlagIntroducedVirtual = (1 << 18),
456 FlagBitField = (1 << 19),
457 FlagNoReturn = (1 << 20),
458 // Do not add values that are not supported by the minimum LLVM
459 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
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) {
468 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
469 static_cast<uint32_t>(B));
472 inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
476 inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
478 inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
479 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
482 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
483 DINode::DIFlags Result = DINode::DIFlags::FlagZero;
485 switch (visibility(Flags)) {
486 case LLVMRustDIFlags::FlagPrivate:
487 Result |= DINode::DIFlags::FlagPrivate;
489 case LLVMRustDIFlags::FlagProtected:
490 Result |= DINode::DIFlags::FlagProtected;
492 case LLVMRustDIFlags::FlagPublic:
493 Result |= DINode::DIFlags::FlagPublic;
496 // The rest are handled below
500 if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
501 Result |= DINode::DIFlags::FlagFwdDecl;
503 if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
504 Result |= DINode::DIFlags::FlagAppleBlock;
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 case LLVMRustChecksumKind::SHA256:
651 return DIFile::ChecksumKind::CSK_SHA256;
653 report_fatal_error("bad ChecksumKind.");
657 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
658 return DEBUG_METADATA_VERSION;
661 extern "C" uint32_t LLVMRustVersionPatch() { return LLVM_VERSION_PATCH; }
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(
669 Module::ModFlagBehavior MergeBehavior,
672 unwrap(M)->addModuleFlag(MergeBehavior, Name, Value);
675 extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
676 return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
679 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
680 return new DIBuilder(*unwrap(M));
683 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
687 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
691 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
692 LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
693 const char *Producer, size_t ProducerLen, bool isOptimized,
694 const char *Flags, unsigned RuntimeVer,
695 const char *SplitName, size_t SplitNameLen,
696 LLVMRustDebugEmissionKind Kind,
697 uint64_t DWOId, bool SplitDebugInlining) {
698 auto *File = unwrapDI<DIFile>(FileRef);
700 return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
701 isOptimized, Flags, RuntimeVer,
702 StringRef(SplitName, SplitNameLen),
703 fromRust(Kind), DWOId, SplitDebugInlining));
706 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
707 LLVMRustDIBuilderRef Builder,
708 const char *Filename, size_t FilenameLen,
709 const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
710 const char *Checksum, size_t ChecksumLen) {
711 Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
712 Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
714 CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
715 return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
716 StringRef(Directory, DirectoryLen),
720 extern "C" LLVMMetadataRef
721 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
722 LLVMMetadataRef ParameterTypes) {
723 return wrap(Builder->createSubroutineType(
724 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
727 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
728 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
729 const char *Name, size_t NameLen,
730 const char *LinkageName, size_t LinkageNameLen,
731 LLVMMetadataRef File, unsigned LineNo,
732 LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
733 LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam,
734 LLVMMetadataRef Decl) {
735 DITemplateParameterArray TParams =
736 DITemplateParameterArray(unwrap<MDTuple>(TParam));
737 DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
738 DINode::DIFlags llvmFlags = fromRust(Flags);
739 DISubprogram *Sub = Builder->createFunction(
740 unwrapDI<DIScope>(Scope),
741 StringRef(Name, NameLen),
742 StringRef(LinkageName, LinkageNameLen),
743 unwrapDI<DIFile>(File), LineNo,
744 unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
745 llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
747 unwrap<Function>(MaybeFn)->setSubprogram(Sub);
751 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
752 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
753 uint64_t SizeInBits, unsigned Encoding) {
754 return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
757 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
758 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
759 LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
760 return wrap(Builder->createTypedef(
761 unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
762 LineNo, unwrapDIPtr<DIScope>(Scope)));
765 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
766 LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
767 uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
768 const char *Name, size_t NameLen) {
769 return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
770 SizeInBits, AlignInBits,
772 StringRef(Name, NameLen)));
775 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
776 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
777 const char *Name, size_t NameLen,
778 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
779 uint32_t AlignInBits, LLVMRustDIFlags Flags,
780 LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
781 unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
782 const char *UniqueId, size_t UniqueIdLen) {
783 return wrap(Builder->createStructType(
784 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
785 unwrapDI<DIFile>(File), LineNumber,
786 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
787 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
788 unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen)));
791 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
792 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
793 const char *Name, size_t NameLen,
794 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
795 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
796 LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) {
797 return wrap(Builder->createVariantPart(
798 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
799 unwrapDI<DIFile>(File), LineNumber,
800 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
801 DINodeArray(unwrapDI<MDTuple>(Elements)), StringRef(UniqueId, UniqueIdLen)));
804 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
805 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
806 const char *Name, size_t NameLen,
807 LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
808 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
809 LLVMMetadataRef Ty) {
810 return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope),
811 StringRef(Name, NameLen),
812 unwrapDI<DIFile>(File), LineNo,
813 SizeInBits, AlignInBits, OffsetInBits,
814 fromRust(Flags), unwrapDI<DIType>(Ty)));
817 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
818 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
819 const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
820 uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
821 LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
822 llvm::ConstantInt* D = nullptr;
824 D = unwrap<llvm::ConstantInt>(Discriminant);
826 return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope),
827 StringRef(Name, NameLen),
828 unwrapDI<DIFile>(File), LineNo,
829 SizeInBits, AlignInBits, OffsetInBits, D,
830 fromRust(Flags), unwrapDI<DIType>(Ty)));
833 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
834 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
835 LLVMMetadataRef File, unsigned Line, unsigned Col) {
836 return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
837 unwrapDI<DIFile>(File), Line, Col));
840 extern "C" LLVMMetadataRef
841 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
842 LLVMMetadataRef Scope,
843 LLVMMetadataRef File) {
844 return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
845 unwrapDI<DIFile>(File)));
848 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
849 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context,
850 const char *Name, size_t NameLen,
851 const char *LinkageName, size_t LinkageNameLen,
852 LLVMMetadataRef File, unsigned LineNo,
853 LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
854 LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
855 llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
857 llvm::DIExpression *InitExpr = nullptr;
858 if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
859 InitExpr = Builder->createConstantValueExpression(
860 IntVal->getValue().getSExtValue());
861 } else if (llvm::ConstantFP *FPVal =
862 llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
863 InitExpr = Builder->createConstantValueExpression(
864 FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
867 llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
868 unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
869 StringRef(LinkageName, LinkageNameLen),
870 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
871 /* isDefined */ true,
872 InitExpr, unwrapDIPtr<MDNode>(Decl),
873 /* templateParams */ nullptr,
876 InitVal->setMetadata("dbg", VarExpr);
878 return wrap(VarExpr);
881 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
882 LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
883 const char *Name, size_t NameLen,
884 LLVMMetadataRef File, unsigned LineNo,
885 LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
886 unsigned ArgNo, uint32_t AlignInBits) {
887 if (Tag == 0x100) { // DW_TAG_auto_variable
888 return wrap(Builder->createAutoVariable(
889 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
890 unwrapDI<DIFile>(File), LineNo,
891 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
893 return wrap(Builder->createParameterVariable(
894 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
895 unwrapDI<DIFile>(File), LineNo,
896 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
900 extern "C" LLVMMetadataRef
901 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
902 uint32_t AlignInBits, LLVMMetadataRef Ty,
903 LLVMMetadataRef Subscripts) {
905 Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
906 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
909 extern "C" LLVMMetadataRef
910 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
912 return wrap(Builder->getOrCreateSubrange(Lo, Count));
915 extern "C" LLVMMetadataRef
916 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
917 LLVMMetadataRef *Ptr, unsigned Count) {
918 Metadata **DataValue = unwrap(Ptr);
920 Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
923 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
924 LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
925 uint64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
926 LLVMBasicBlockRef InsertAtEnd) {
927 return wrap(Builder->insertDeclare(
928 unwrap(V), unwrap<DILocalVariable>(VarInfo),
929 Builder->createExpression(llvm::ArrayRef<uint64_t>(AddrOps, AddrOpsCount)),
930 DebugLoc(cast<MDNode>(unwrap(DL))),
931 unwrap(InsertAtEnd)));
934 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
935 LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
936 int64_t Value, bool IsUnsigned) {
937 return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
940 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
941 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
942 const char *Name, size_t NameLen,
943 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
944 uint32_t AlignInBits, LLVMMetadataRef Elements,
945 LLVMMetadataRef ClassTy, bool IsScoped) {
946 return wrap(Builder->createEnumerationType(
947 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
948 unwrapDI<DIFile>(File), LineNumber,
949 SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
950 unwrapDI<DIType>(ClassTy), "", IsScoped));
953 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
954 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
955 const char *Name, size_t NameLen,
956 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
957 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
958 unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) {
959 return wrap(Builder->createUnionType(
960 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File),
961 LineNumber, SizeInBits, AlignInBits, fromRust(Flags),
962 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
963 StringRef(UniqueId, UniqueIdLen)));
966 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
967 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
968 const char *Name, size_t NameLen, LLVMMetadataRef Ty) {
969 bool IsDefault = false; // FIXME: should we ever set this true?
970 return wrap(Builder->createTemplateTypeParameter(
971 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty), IsDefault));
974 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateNameSpace(
975 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
976 const char *Name, size_t NameLen, bool ExportSymbols) {
977 return wrap(Builder->createNameSpace(
978 unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols
983 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
984 LLVMMetadataRef CompositeTy,
985 LLVMMetadataRef Elements,
986 LLVMMetadataRef Params) {
987 DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
988 Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
989 DINodeArray(unwrap<MDTuple>(Params)));
992 extern "C" LLVMMetadataRef
993 LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
994 LLVMMetadataRef ScopeRef,
995 LLVMMetadataRef InlinedAt) {
996 MDNode *Scope = unwrapDIPtr<MDNode>(ScopeRef);
997 DILocation *Loc = DILocation::get(
998 Scope->getContext(), Line, Column, Scope,
999 unwrapDIPtr<MDNode>(InlinedAt));
1003 extern "C" uint64_t LLVMRustDIBuilderCreateOpDeref() {
1004 return dwarf::DW_OP_deref;
1007 extern "C" uint64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1008 return dwarf::DW_OP_plus_uconst;
1011 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
1012 RawRustStringOstream OS(Str);
1013 unwrap<llvm::Type>(Ty)->print(OS);
1016 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
1017 RustStringRef Str) {
1018 RawRustStringOstream OS(Str);
1023 unwrap<llvm::Value>(V)->getType()->print(OS);
1025 unwrap<llvm::Value>(V)->print(OS);
1030 // LLVMArrayType function does not support 64-bit ElementCount
1031 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
1032 uint64_t ElementCount) {
1033 return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
1036 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1038 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
1039 RawRustStringOstream OS(Str);
1040 unwrap(T)->print(OS);
1043 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1044 LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
1045 LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
1046 RustStringRef FilenameOut, RustStringRef MessageOut) {
1047 // Undefined to call this not on an optimization diagnostic!
1048 llvm::DiagnosticInfoOptimizationBase *Opt =
1049 static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
1051 RawRustStringOstream PassNameOS(PassNameOut);
1052 PassNameOS << Opt->getPassName();
1053 *FunctionOut = wrap(&Opt->getFunction());
1055 RawRustStringOstream FilenameOS(FilenameOut);
1056 DiagnosticLocation loc = Opt->getLocation();
1057 if (loc.isValid()) {
1058 *Line = loc.getLine();
1059 *Column = loc.getColumn();
1060 FilenameOS << loc.getAbsolutePath();
1063 RawRustStringOstream MessageOS(MessageOut);
1064 MessageOS << Opt->getMsg();
1067 enum class LLVMRustDiagnosticLevel {
1075 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
1076 LLVMRustDiagnosticLevel *LevelOut,
1077 unsigned *CookieOut,
1078 LLVMTwineRef *MessageOut) {
1079 // Undefined to call this not on an inline assembly diagnostic!
1080 llvm::DiagnosticInfoInlineAsm *IA =
1081 static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
1083 *CookieOut = IA->getLocCookie();
1084 *MessageOut = wrap(&IA->getMsgStr());
1086 switch (IA->getSeverity()) {
1088 *LevelOut = LLVMRustDiagnosticLevel::Error;
1091 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1094 *LevelOut = LLVMRustDiagnosticLevel::Note;
1097 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1100 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1104 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
1105 RustStringRef Str) {
1106 RawRustStringOstream OS(Str);
1107 DiagnosticPrinterRawOStream DP(OS);
1108 unwrap(DI)->print(DP);
1111 enum class LLVMRustDiagnosticKind {
1115 DebugMetadataVersion,
1118 OptimizationRemarkMissed,
1119 OptimizationRemarkAnalysis,
1120 OptimizationRemarkAnalysisFPCommute,
1121 OptimizationRemarkAnalysisAliasing,
1122 OptimizationRemarkOther,
1123 OptimizationFailure,
1130 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1133 return LLVMRustDiagnosticKind::InlineAsm;
1135 return LLVMRustDiagnosticKind::StackSize;
1136 case DK_DebugMetadataVersion:
1137 return LLVMRustDiagnosticKind::DebugMetadataVersion;
1138 case DK_SampleProfile:
1139 return LLVMRustDiagnosticKind::SampleProfile;
1140 case DK_OptimizationRemark:
1141 case DK_MachineOptimizationRemark:
1142 return LLVMRustDiagnosticKind::OptimizationRemark;
1143 case DK_OptimizationRemarkMissed:
1144 case DK_MachineOptimizationRemarkMissed:
1145 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1146 case DK_OptimizationRemarkAnalysis:
1147 case DK_MachineOptimizationRemarkAnalysis:
1148 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1149 case DK_OptimizationRemarkAnalysisFPCommute:
1150 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1151 case DK_OptimizationRemarkAnalysisAliasing:
1152 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1154 return LLVMRustDiagnosticKind::PGOProfile;
1156 return LLVMRustDiagnosticKind::Linker;
1157 case DK_Unsupported:
1158 return LLVMRustDiagnosticKind::Unsupported;
1159 #if LLVM_VERSION_GE(13, 0)
1161 return LLVMRustDiagnosticKind::SrcMgr;
1164 return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1165 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1166 : LLVMRustDiagnosticKind::Other;
1170 extern "C" LLVMRustDiagnosticKind
1171 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1172 return toRust((DiagnosticKind)unwrap(DI)->getKind());
1175 // This is kept distinct from LLVMGetTypeKind, because when
1176 // a new type kind is added, the Rust-side enum must be
1177 // updated or UB will result.
1178 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1179 switch (unwrap(Ty)->getTypeID()) {
1180 case Type::VoidTyID:
1181 return LLVMVoidTypeKind;
1182 case Type::HalfTyID:
1183 return LLVMHalfTypeKind;
1184 case Type::FloatTyID:
1185 return LLVMFloatTypeKind;
1186 case Type::DoubleTyID:
1187 return LLVMDoubleTypeKind;
1188 case Type::X86_FP80TyID:
1189 return LLVMX86_FP80TypeKind;
1190 case Type::FP128TyID:
1191 return LLVMFP128TypeKind;
1192 case Type::PPC_FP128TyID:
1193 return LLVMPPC_FP128TypeKind;
1194 case Type::LabelTyID:
1195 return LLVMLabelTypeKind;
1196 case Type::MetadataTyID:
1197 return LLVMMetadataTypeKind;
1198 case Type::IntegerTyID:
1199 return LLVMIntegerTypeKind;
1200 case Type::FunctionTyID:
1201 return LLVMFunctionTypeKind;
1202 case Type::StructTyID:
1203 return LLVMStructTypeKind;
1204 case Type::ArrayTyID:
1205 return LLVMArrayTypeKind;
1206 case Type::PointerTyID:
1207 return LLVMPointerTypeKind;
1208 case Type::FixedVectorTyID:
1209 return LLVMVectorTypeKind;
1210 case Type::X86_MMXTyID:
1211 return LLVMX86_MMXTypeKind;
1212 case Type::TokenTyID:
1213 return LLVMTokenTypeKind;
1214 case Type::ScalableVectorTyID:
1215 return LLVMScalableVectorTypeKind;
1216 case Type::BFloatTyID:
1217 return LLVMBFloatTypeKind;
1218 case Type::X86_AMXTyID:
1219 return LLVMX86_AMXTypeKind;
1220 #if LLVM_VERSION_GE(15, 0)
1221 case Type::DXILPointerTyID:
1222 report_fatal_error("Rust does not support DirectX typed pointers.");
1226 report_fatal_error("Unhandled TypeID.");
1229 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1231 #if LLVM_VERSION_LT(13, 0)
1232 using LLVMInlineAsmDiagHandlerTy = LLVMContext::InlineAsmDiagHandlerTy;
1234 using LLVMInlineAsmDiagHandlerTy = void*;
1237 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1238 LLVMContextRef C, LLVMInlineAsmDiagHandlerTy H, void *CX) {
1239 // Diagnostic handlers were unified in LLVM change 5de2d189e6ad, so starting
1240 // with LLVM 13 this function is gone.
1241 #if LLVM_VERSION_LT(13, 0)
1242 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1246 extern "C" LLVMSMDiagnosticRef LLVMRustGetSMDiagnostic(
1247 LLVMDiagnosticInfoRef DI, unsigned *Cookie) {
1248 #if LLVM_VERSION_GE(13, 0)
1249 llvm::DiagnosticInfoSrcMgr *SM = static_cast<llvm::DiagnosticInfoSrcMgr *>(unwrap(DI));
1250 *Cookie = SM->getLocCookie();
1251 return wrap(&SM->getSMDiag());
1253 report_fatal_error("Shouldn't get called on older versions");
1257 extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
1258 RustStringRef MessageOut,
1259 RustStringRef BufferOut,
1260 LLVMRustDiagnosticLevel* LevelOut,
1262 unsigned* RangesOut,
1263 size_t* NumRanges) {
1264 SMDiagnostic& D = *unwrap(DRef);
1265 RawRustStringOstream MessageOS(MessageOut);
1266 MessageOS << D.getMessage();
1268 switch (D.getKind()) {
1269 case SourceMgr::DK_Error:
1270 *LevelOut = LLVMRustDiagnosticLevel::Error;
1272 case SourceMgr::DK_Warning:
1273 *LevelOut = LLVMRustDiagnosticLevel::Warning;
1275 case SourceMgr::DK_Note:
1276 *LevelOut = LLVMRustDiagnosticLevel::Note;
1278 case SourceMgr::DK_Remark:
1279 *LevelOut = LLVMRustDiagnosticLevel::Remark;
1282 report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
1285 if (D.getLoc() == SMLoc())
1288 const SourceMgr &LSM = *D.getSourceMgr();
1289 const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
1290 LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), LBuf->getBufferSize());
1292 *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
1294 *NumRanges = std::min(*NumRanges, D.getRanges().size());
1295 size_t LineStart = *LocOut - (size_t)D.getColumnNo();
1296 for (size_t i = 0; i < *NumRanges; i++) {
1297 RangesOut[i * 2] = LineStart + D.getRanges()[i].first;
1298 RangesOut[i * 2 + 1] = LineStart + D.getRanges()[i].second;
1304 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1305 LLVMValueRef ParentPad,
1307 LLVMValueRef *LLArgs,
1309 Value **Args = unwrap(LLArgs);
1310 if (ParentPad == nullptr) {
1311 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1312 ParentPad = wrap(Constant::getNullValue(Ty));
1314 return wrap(unwrap(B)->CreateCleanupPad(
1315 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1318 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1319 LLVMValueRef CleanupPad,
1320 LLVMBasicBlockRef UnwindBB) {
1321 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1322 return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1325 extern "C" LLVMValueRef
1326 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1327 unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1328 Value **Args = unwrap(LLArgs);
1329 return wrap(unwrap(B)->CreateCatchPad(
1330 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1333 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1335 LLVMBasicBlockRef BB) {
1336 return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1340 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1341 LLVMValueRef ParentPad,
1342 LLVMBasicBlockRef BB,
1343 unsigned NumHandlers,
1345 if (ParentPad == nullptr) {
1346 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1347 ParentPad = wrap(Constant::getNullValue(Ty));
1349 return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1350 NumHandlers, Name));
1353 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1354 LLVMBasicBlockRef Handler) {
1355 Value *CatchSwitch = unwrap(CatchSwitchRef);
1356 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1359 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1360 LLVMValueRef *Inputs,
1361 unsigned NumInputs) {
1362 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1365 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1369 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
1370 LLVMValueRef *Args, unsigned NumArgs,
1371 OperandBundleDef *Bundle) {
1372 Value *Callee = unwrap(Fn);
1373 FunctionType *FTy = unwrap<FunctionType>(Ty);
1374 unsigned Len = Bundle ? 1 : 0;
1375 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1376 return wrap(unwrap(B)->CreateCall(
1377 FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles));
1380 extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
1381 return wrap(llvm::Intrinsic::getDeclaration(unwrap(M),
1382 (llvm::Intrinsic::ID)llvm::Intrinsic::instrprof_increment));
1385 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
1386 LLVMValueRef Dst, unsigned DstAlign,
1387 LLVMValueRef Src, unsigned SrcAlign,
1388 LLVMValueRef Size, bool IsVolatile) {
1389 return wrap(unwrap(B)->CreateMemCpy(
1390 unwrap(Dst), MaybeAlign(DstAlign),
1391 unwrap(Src), MaybeAlign(SrcAlign),
1392 unwrap(Size), IsVolatile));
1395 extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
1396 LLVMValueRef Dst, unsigned DstAlign,
1397 LLVMValueRef Src, unsigned SrcAlign,
1398 LLVMValueRef Size, bool IsVolatile) {
1399 return wrap(unwrap(B)->CreateMemMove(
1400 unwrap(Dst), MaybeAlign(DstAlign),
1401 unwrap(Src), MaybeAlign(SrcAlign),
1402 unwrap(Size), IsVolatile));
1405 extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
1406 LLVMValueRef Dst, unsigned DstAlign,
1408 LLVMValueRef Size, bool IsVolatile) {
1409 return wrap(unwrap(B)->CreateMemSet(
1410 unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
1413 extern "C" LLVMValueRef
1414 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
1415 LLVMValueRef *Args, unsigned NumArgs,
1416 LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
1417 OperandBundleDef *Bundle, const char *Name) {
1418 Value *Callee = unwrap(Fn);
1419 FunctionType *FTy = unwrap<FunctionType>(Ty);
1420 unsigned Len = Bundle ? 1 : 0;
1421 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1422 return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
1423 makeArrayRef(unwrap(Args), NumArgs),
1427 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1428 LLVMBasicBlockRef BB) {
1429 auto Point = unwrap(BB)->getFirstInsertionPt();
1430 unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1433 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1434 const char *Name, size_t NameLen) {
1435 Triple TargetTriple(unwrap(M)->getTargetTriple());
1436 GlobalObject *GV = unwrap<GlobalObject>(V);
1437 if (TargetTriple.supportsCOMDAT()) {
1438 StringRef NameRef(Name, NameLen);
1439 GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
1443 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1444 GlobalObject *GV = unwrap<GlobalObject>(V);
1445 GV->setComdat(nullptr);
1448 enum class LLVMRustLinkage {
1449 ExternalLinkage = 0,
1450 AvailableExternallyLinkage = 1,
1451 LinkOnceAnyLinkage = 2,
1452 LinkOnceODRLinkage = 3,
1455 AppendingLinkage = 6,
1456 InternalLinkage = 7,
1458 ExternalWeakLinkage = 9,
1462 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1464 case LLVMExternalLinkage:
1465 return LLVMRustLinkage::ExternalLinkage;
1466 case LLVMAvailableExternallyLinkage:
1467 return LLVMRustLinkage::AvailableExternallyLinkage;
1468 case LLVMLinkOnceAnyLinkage:
1469 return LLVMRustLinkage::LinkOnceAnyLinkage;
1470 case LLVMLinkOnceODRLinkage:
1471 return LLVMRustLinkage::LinkOnceODRLinkage;
1472 case LLVMWeakAnyLinkage:
1473 return LLVMRustLinkage::WeakAnyLinkage;
1474 case LLVMWeakODRLinkage:
1475 return LLVMRustLinkage::WeakODRLinkage;
1476 case LLVMAppendingLinkage:
1477 return LLVMRustLinkage::AppendingLinkage;
1478 case LLVMInternalLinkage:
1479 return LLVMRustLinkage::InternalLinkage;
1480 case LLVMPrivateLinkage:
1481 return LLVMRustLinkage::PrivateLinkage;
1482 case LLVMExternalWeakLinkage:
1483 return LLVMRustLinkage::ExternalWeakLinkage;
1484 case LLVMCommonLinkage:
1485 return LLVMRustLinkage::CommonLinkage;
1487 report_fatal_error("Invalid LLVMRustLinkage value!");
1491 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1493 case LLVMRustLinkage::ExternalLinkage:
1494 return LLVMExternalLinkage;
1495 case LLVMRustLinkage::AvailableExternallyLinkage:
1496 return LLVMAvailableExternallyLinkage;
1497 case LLVMRustLinkage::LinkOnceAnyLinkage:
1498 return LLVMLinkOnceAnyLinkage;
1499 case LLVMRustLinkage::LinkOnceODRLinkage:
1500 return LLVMLinkOnceODRLinkage;
1501 case LLVMRustLinkage::WeakAnyLinkage:
1502 return LLVMWeakAnyLinkage;
1503 case LLVMRustLinkage::WeakODRLinkage:
1504 return LLVMWeakODRLinkage;
1505 case LLVMRustLinkage::AppendingLinkage:
1506 return LLVMAppendingLinkage;
1507 case LLVMRustLinkage::InternalLinkage:
1508 return LLVMInternalLinkage;
1509 case LLVMRustLinkage::PrivateLinkage:
1510 return LLVMPrivateLinkage;
1511 case LLVMRustLinkage::ExternalWeakLinkage:
1512 return LLVMExternalWeakLinkage;
1513 case LLVMRustLinkage::CommonLinkage:
1514 return LLVMCommonLinkage;
1516 report_fatal_error("Invalid LLVMRustLinkage value!");
1519 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1520 return toRust(LLVMGetLinkage(V));
1523 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1524 LLVMRustLinkage RustLinkage) {
1525 LLVMSetLinkage(V, fromRust(RustLinkage));
1528 extern "C" LLVMValueRef LLVMRustConstInBoundsGEP2(LLVMTypeRef Ty,
1529 LLVMValueRef ConstantVal,
1530 LLVMValueRef *ConstantIndices,
1531 unsigned NumIndices) {
1532 ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
1534 Constant *Val = unwrap<Constant>(ConstantVal);
1535 return wrap(ConstantExpr::getInBoundsGetElementPtr(unwrap(Ty), Val, IdxList));
1538 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1539 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1540 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1542 auto C = unwrap<llvm::ConstantInt>(CV);
1543 if (C->getBitWidth() > 128) { return false; }
1546 AP = C->getValue().sextOrSelf(128);
1548 AP = C->getValue().zextOrSelf(128);
1550 *low = AP.getLoBits(64).getZExtValue();
1551 *high = AP.getHiBits(64).getZExtValue();
1555 enum class LLVMRustVisibility {
1561 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1563 case LLVMDefaultVisibility:
1564 return LLVMRustVisibility::Default;
1565 case LLVMHiddenVisibility:
1566 return LLVMRustVisibility::Hidden;
1567 case LLVMProtectedVisibility:
1568 return LLVMRustVisibility::Protected;
1570 report_fatal_error("Invalid LLVMRustVisibility value!");
1573 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1575 case LLVMRustVisibility::Default:
1576 return LLVMDefaultVisibility;
1577 case LLVMRustVisibility::Hidden:
1578 return LLVMHiddenVisibility;
1579 case LLVMRustVisibility::Protected:
1580 return LLVMProtectedVisibility;
1582 report_fatal_error("Invalid LLVMRustVisibility value!");
1585 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1586 return toRust(LLVMGetVisibility(V));
1589 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1590 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1591 LLVMTypeRef DestTy, bool isSigned) {
1592 return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1595 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1596 LLVMRustVisibility RustVisibility) {
1597 LLVMSetVisibility(V, fromRust(RustVisibility));
1600 extern "C" void LLVMRustSetDSOLocal(LLVMValueRef Global, bool is_dso_local) {
1601 unwrap<GlobalValue>(Global)->setDSOLocal(is_dso_local);
1604 struct LLVMRustModuleBuffer {
1608 extern "C" LLVMRustModuleBuffer*
1609 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1610 auto Ret = std::make_unique<LLVMRustModuleBuffer>();
1612 raw_string_ostream OS(Ret->data);
1614 legacy::PassManager PM;
1615 PM.add(createBitcodeWriterPass(OS));
1619 return Ret.release();
1623 LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1627 extern "C" const void*
1628 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1629 return Buffer->data.data();
1633 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1634 return Buffer->data.length();
1638 LLVMRustModuleCost(LLVMModuleRef M) {
1639 auto f = unwrap(M)->functions();
1640 return std::distance(std::begin(f), std::end(f));
1643 // Vector reductions:
1644 extern "C" LLVMValueRef
1645 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1646 return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1648 extern "C" LLVMValueRef
1649 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1650 return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1652 extern "C" LLVMValueRef
1653 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1654 return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1656 extern "C" LLVMValueRef
1657 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1658 return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1660 extern "C" LLVMValueRef
1661 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1662 return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1664 extern "C" LLVMValueRef
1665 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1666 return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1668 extern "C" LLVMValueRef
1669 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1670 return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1672 extern "C" LLVMValueRef
1673 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1674 return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1676 extern "C" LLVMValueRef
1677 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1678 return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1680 extern "C" LLVMValueRef
1681 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1682 Instruction *I = unwrap(B)->CreateFPMinReduce(unwrap(Src));
1683 I->setHasNoNaNs(NoNaN);
1686 extern "C" LLVMValueRef
1687 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1688 Instruction *I = unwrap(B)->CreateFPMaxReduce(unwrap(Src));
1689 I->setHasNoNaNs(NoNaN);
1693 extern "C" LLVMValueRef
1694 LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1695 return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1697 extern "C" LLVMValueRef
1698 LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1699 return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));
1702 // This struct contains all necessary info about a symbol exported from a DLL.
1703 struct LLVMRustCOFFShortExport {
1705 bool ordinal_present;
1706 // The value of `ordinal` is only meaningful if `ordinal_present` is true.
1710 // Machine must be a COFF machine type, as defined in PE specs.
1711 extern "C" LLVMRustResult LLVMRustWriteImportLibrary(
1712 const char* ImportName,
1714 const LLVMRustCOFFShortExport* Exports,
1719 std::vector<llvm::object::COFFShortExport> ConvertedExports;
1720 ConvertedExports.reserve(NumExports);
1722 for (size_t i = 0; i < NumExports; ++i) {
1723 bool ordinal_present = Exports[i].ordinal_present;
1724 uint16_t ordinal = ordinal_present ? Exports[i].ordinal : 0;
1725 ConvertedExports.push_back(llvm::object::COFFShortExport{
1726 Exports[i].name, // Name
1727 std::string{}, // ExtName
1728 std::string{}, // SymbolName
1729 std::string{}, // AliasTarget
1731 ordinal_present, // Noname
1738 auto Error = llvm::object::writeImportLibrary(
1742 static_cast<llvm::COFF::MachineTypes>(Machine),
1745 std::string errorString;
1746 llvm::raw_string_ostream stream(errorString);
1749 LLVMRustSetLastError(errorString.c_str());
1750 return LLVMRustResult::Failure;
1752 return LLVMRustResult::Success;
1756 // Transfers ownership of DiagnosticHandler unique_ptr to the caller.
1757 extern "C" DiagnosticHandler *
1758 LLVMRustContextGetDiagnosticHandler(LLVMContextRef C) {
1759 std::unique_ptr<DiagnosticHandler> DH = unwrap(C)->getDiagnosticHandler();
1760 return DH.release();
1763 // Sets unique_ptr to object of DiagnosticHandler to provide custom diagnostic
1764 // handling. Ownership of the handler is moved to the LLVMContext.
1765 extern "C" void LLVMRustContextSetDiagnosticHandler(LLVMContextRef C,
1766 DiagnosticHandler *DH) {
1767 unwrap(C)->setDiagnosticHandler(std::unique_ptr<DiagnosticHandler>(DH));
1770 using LLVMDiagnosticHandlerTy = DiagnosticHandler::DiagnosticHandlerTy;
1772 // Configures a diagnostic handler that invokes provided callback when a
1773 // backend needs to emit a diagnostic.
1775 // When RemarkAllPasses is true, remarks are enabled for all passes. Otherwise
1776 // the RemarkPasses array specifies individual passes for which remarks will be
1778 extern "C" void LLVMRustContextConfigureDiagnosticHandler(
1779 LLVMContextRef C, LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
1780 void *DiagnosticHandlerContext, bool RemarkAllPasses,
1781 const char * const * RemarkPasses, size_t RemarkPassesLen) {
1783 class RustDiagnosticHandler final : public DiagnosticHandler {
1785 RustDiagnosticHandler(LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
1786 void *DiagnosticHandlerContext,
1787 bool RemarkAllPasses,
1788 std::vector<std::string> RemarkPasses)
1789 : DiagnosticHandlerCallback(DiagnosticHandlerCallback),
1790 DiagnosticHandlerContext(DiagnosticHandlerContext),
1791 RemarkAllPasses(RemarkAllPasses),
1792 RemarkPasses(RemarkPasses) {}
1794 virtual bool handleDiagnostics(const DiagnosticInfo &DI) override {
1795 if (DiagnosticHandlerCallback) {
1796 DiagnosticHandlerCallback(DI, DiagnosticHandlerContext);
1802 bool isAnalysisRemarkEnabled(StringRef PassName) const override {
1803 return isRemarkEnabled(PassName);
1806 bool isMissedOptRemarkEnabled(StringRef PassName) const override {
1807 return isRemarkEnabled(PassName);
1810 bool isPassedOptRemarkEnabled(StringRef PassName) const override {
1811 return isRemarkEnabled(PassName);
1814 bool isAnyRemarkEnabled() const override {
1815 return RemarkAllPasses || !RemarkPasses.empty();
1819 bool isRemarkEnabled(StringRef PassName) const {
1820 if (RemarkAllPasses)
1823 for (auto &Pass : RemarkPasses)
1824 if (Pass == PassName)
1830 LLVMDiagnosticHandlerTy DiagnosticHandlerCallback = nullptr;
1831 void *DiagnosticHandlerContext = nullptr;
1833 bool RemarkAllPasses = false;
1834 std::vector<std::string> RemarkPasses;
1837 std::vector<std::string> Passes;
1838 for (size_t I = 0; I != RemarkPassesLen; ++I)
1839 Passes.push_back(RemarkPasses[I]);
1841 unwrap(C)->setDiagnosticHandler(std::make_unique<RustDiagnosticHandler>(
1842 DiagnosticHandlerCallback, DiagnosticHandlerContext, RemarkAllPasses, Passes));
1845 extern "C" void LLVMRustGetMangledName(LLVMValueRef V, RustStringRef Str) {
1846 RawRustStringOstream OS(Str);
1847 GlobalValue *GV = unwrap<GlobalValue>(V);
1848 Mangler().getNameWithPrefix(OS, GV, true);