2 #include "llvm/IR/CallSite.h"
3 #include "llvm/IR/DebugInfoMetadata.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/Object/Archive.h"
9 #include "llvm/Object/ObjectFile.h"
10 #include "llvm/Bitcode/BitcodeWriterPass.h"
11 #include "llvm/Support/Signals.h"
12 #include "llvm/ADT/Optional.h"
16 //===----------------------------------------------------------------------===
18 // This file defines alternate interfaces to core functions that are more
19 // readily callable by Rust's FFI.
21 //===----------------------------------------------------------------------===
24 using namespace llvm::sys
;
25 using namespace llvm::object
;
27 // LLVMAtomicOrdering is already an enum - don't create another
29 static AtomicOrdering
fromRust(LLVMAtomicOrdering Ordering
) {
31 case LLVMAtomicOrderingNotAtomic
:
32 return AtomicOrdering::NotAtomic
;
33 case LLVMAtomicOrderingUnordered
:
34 return AtomicOrdering::Unordered
;
35 case LLVMAtomicOrderingMonotonic
:
36 return AtomicOrdering::Monotonic
;
37 case LLVMAtomicOrderingAcquire
:
38 return AtomicOrdering::Acquire
;
39 case LLVMAtomicOrderingRelease
:
40 return AtomicOrdering::Release
;
41 case LLVMAtomicOrderingAcquireRelease
:
42 return AtomicOrdering::AcquireRelease
;
43 case LLVMAtomicOrderingSequentiallyConsistent
:
44 return AtomicOrdering::SequentiallyConsistent
;
47 report_fatal_error("Invalid LLVMAtomicOrdering value!");
50 static LLVM_THREAD_LOCAL
char *LastError
;
52 // Custom error handler for fatal LLVM errors.
54 // Notably it exits the process with code 101, unlike LLVM's default of 1.
55 static void FatalErrorHandler(void *UserData
,
56 const std::string
& Reason
,
58 // Do the same thing that the default error handler does.
59 std::cerr
<< "LLVM ERROR: " << Reason
<< std::endl
;
61 // Since this error handler exits the process, we have to run any cleanup that
62 // LLVM would run after handling the error. This might change with an LLVM
64 sys::RunInterruptHandlers();
69 extern "C" void LLVMRustInstallFatalErrorHandler() {
70 install_fatal_error_handler(FatalErrorHandler
);
73 extern "C" LLVMMemoryBufferRef
74 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path
) {
75 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> BufOr
=
76 MemoryBuffer::getFile(Path
, -1, false);
78 LLVMRustSetLastError(BufOr
.getError().message().c_str());
81 return wrap(BufOr
.get().release());
84 extern "C" char *LLVMRustGetLastError(void) {
85 char *Ret
= LastError
;
90 extern "C" unsigned int LLVMRustGetInstructionCount(LLVMModuleRef M
) {
91 return unwrap(M
)->getInstructionCount();
94 extern "C" void LLVMRustSetLastError(const char *Err
) {
95 free((void *)LastError
);
96 LastError
= strdup(Err
);
99 extern "C" LLVMContextRef
LLVMRustContextCreate(bool shouldDiscardNames
) {
100 auto ctx
= new LLVMContext();
101 ctx
->setDiscardValueNames(shouldDiscardNames
);
105 extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M
,
106 const char *Triple
) {
107 unwrap(M
)->setTargetTriple(Triple::normalize(Triple
));
110 extern "C" void LLVMRustPrintPassTimings() {
111 raw_fd_ostream
OS(2, false); // stderr.
112 TimerGroup::printAll(OS
);
115 extern "C" LLVMValueRef
LLVMRustGetNamedValue(LLVMModuleRef M
, const char *Name
,
117 return wrap(unwrap(M
)->getNamedValue(StringRef(Name
, NameLen
)));
120 extern "C" LLVMValueRef
LLVMRustGetOrInsertFunction(LLVMModuleRef M
,
123 LLVMTypeRef FunctionTy
) {
124 return wrap(unwrap(M
)
125 ->getOrInsertFunction(StringRef(Name
, NameLen
),
126 unwrap
<FunctionType
>(FunctionTy
))
127 #if LLVM_VERSION_GE(9, 0)
133 extern "C" LLVMValueRef
134 LLVMRustGetOrInsertGlobal(LLVMModuleRef M
, const char *Name
, size_t NameLen
, LLVMTypeRef Ty
) {
135 StringRef
NameRef(Name
, NameLen
);
136 return wrap(unwrap(M
)->getOrInsertGlobal(NameRef
, unwrap(Ty
)));
139 extern "C" LLVMValueRef
140 LLVMRustInsertPrivateGlobal(LLVMModuleRef M
, LLVMTypeRef Ty
) {
141 return wrap(new GlobalVariable(*unwrap(M
),
144 GlobalValue::PrivateLinkage
,
148 extern "C" LLVMTypeRef
LLVMRustMetadataTypeInContext(LLVMContextRef C
) {
149 return wrap(Type::getMetadataTy(*unwrap(C
)));
152 static Attribute::AttrKind
fromRust(LLVMRustAttribute Kind
) {
155 return Attribute::AlwaysInline
;
157 return Attribute::ByVal
;
159 return Attribute::Cold
;
161 return Attribute::InlineHint
;
163 return Attribute::MinSize
;
165 return Attribute::Naked
;
167 return Attribute::NoAlias
;
169 return Attribute::NoCapture
;
171 return Attribute::NoInline
;
173 return Attribute::NonNull
;
175 return Attribute::NoRedZone
;
177 return Attribute::NoReturn
;
179 return Attribute::NoUnwind
;
180 case OptimizeForSize
:
181 return Attribute::OptimizeForSize
;
183 return Attribute::ReadOnly
;
185 return Attribute::SExt
;
187 return Attribute::StructRet
;
189 return Attribute::UWTable
;
191 return Attribute::ZExt
;
193 return Attribute::InReg
;
195 return Attribute::SanitizeThread
;
196 case SanitizeAddress
:
197 return Attribute::SanitizeAddress
;
199 return Attribute::SanitizeMemory
;
201 return Attribute::NonLazyBind
;
203 return Attribute::OptimizeNone
;
205 return Attribute::ReturnsTwice
;
207 report_fatal_error("bad AttributeKind");
210 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr
, unsigned Index
,
211 LLVMRustAttribute RustAttr
) {
212 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
213 Attribute Attr
= Attribute::get(Call
->getContext(), fromRust(RustAttr
));
214 Call
.addAttribute(Index
, Attr
);
217 extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr
,
220 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
222 B
.addAlignmentAttr(Bytes
);
223 Call
.setAttributes(Call
.getAttributes().addAttributes(
224 Call
->getContext(), Index
, B
));
227 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr
,
230 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
232 B
.addDereferenceableAttr(Bytes
);
233 Call
.setAttributes(Call
.getAttributes().addAttributes(
234 Call
->getContext(), Index
, B
));
237 extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr
,
240 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
242 B
.addDereferenceableOrNullAttr(Bytes
);
243 Call
.setAttributes(Call
.getAttributes().addAttributes(
244 Call
->getContext(), Index
, B
));
247 extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr
, unsigned Index
,
249 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
250 #if LLVM_VERSION_GE(9, 0)
251 Attribute Attr
= Attribute::getWithByValType(Call
->getContext(), unwrap(Ty
));
253 Attribute Attr
= Attribute::get(Call
->getContext(), Attribute::ByVal
);
255 Call
.addAttribute(Index
, Attr
);
258 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn
, unsigned Index
,
259 LLVMRustAttribute RustAttr
) {
260 Function
*A
= unwrap
<Function
>(Fn
);
261 Attribute Attr
= Attribute::get(A
->getContext(), fromRust(RustAttr
));
263 A
->addAttributes(Index
, B
);
266 extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn
,
269 Function
*A
= unwrap
<Function
>(Fn
);
271 B
.addAlignmentAttr(Bytes
);
272 A
->addAttributes(Index
, B
);
275 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn
, unsigned Index
,
277 Function
*A
= unwrap
<Function
>(Fn
);
279 B
.addDereferenceableAttr(Bytes
);
280 A
->addAttributes(Index
, B
);
283 extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn
,
286 Function
*A
= unwrap
<Function
>(Fn
);
288 B
.addDereferenceableOrNullAttr(Bytes
);
289 A
->addAttributes(Index
, B
);
292 extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn
, unsigned Index
,
294 Function
*F
= unwrap
<Function
>(Fn
);
295 #if LLVM_VERSION_GE(9, 0)
296 Attribute Attr
= Attribute::getWithByValType(F
->getContext(), unwrap(Ty
));
298 Attribute Attr
= Attribute::get(F
->getContext(), Attribute::ByVal
);
300 F
->addAttribute(Index
, Attr
);
303 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn
,
307 Function
*F
= unwrap
<Function
>(Fn
);
309 B
.addAttribute(Name
, Value
);
310 F
->addAttributes(Index
, B
);
313 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn
,
315 LLVMRustAttribute RustAttr
) {
316 Function
*F
= unwrap
<Function
>(Fn
);
317 Attribute Attr
= Attribute::get(F
->getContext(), fromRust(RustAttr
));
319 auto PAL
= F
->getAttributes();
320 auto PALNew
= PAL
.removeAttributes(F
->getContext(), Index
, B
);
321 F
->setAttributes(PALNew
);
324 // enable fpmath flag UnsafeAlgebra
325 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V
) {
326 if (auto I
= dyn_cast
<Instruction
>(unwrap
<Value
>(V
))) {
331 extern "C" LLVMValueRef
332 LLVMRustBuildAtomicLoad(LLVMBuilderRef B
, LLVMValueRef Source
, const char *Name
,
333 LLVMAtomicOrdering Order
) {
334 LoadInst
*LI
= new LoadInst(unwrap(Source
));
335 LI
->setAtomic(fromRust(Order
));
336 return wrap(unwrap(B
)->Insert(LI
, Name
));
339 extern "C" LLVMValueRef
LLVMRustBuildAtomicStore(LLVMBuilderRef B
,
342 LLVMAtomicOrdering Order
) {
343 StoreInst
*SI
= new StoreInst(unwrap(V
), unwrap(Target
));
344 SI
->setAtomic(fromRust(Order
));
345 return wrap(unwrap(B
)->Insert(SI
));
348 extern "C" LLVMValueRef
349 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B
, LLVMValueRef Target
,
350 LLVMValueRef Old
, LLVMValueRef Source
,
351 LLVMAtomicOrdering Order
,
352 LLVMAtomicOrdering FailureOrder
, LLVMBool Weak
) {
353 AtomicCmpXchgInst
*ACXI
= unwrap(B
)->CreateAtomicCmpXchg(
354 unwrap(Target
), unwrap(Old
), unwrap(Source
), fromRust(Order
),
355 fromRust(FailureOrder
));
360 enum class LLVMRustSynchronizationScope
{
366 static SyncScope::ID
fromRust(LLVMRustSynchronizationScope Scope
) {
368 case LLVMRustSynchronizationScope::SingleThread
:
369 return SyncScope::SingleThread
;
370 case LLVMRustSynchronizationScope::CrossThread
:
371 return SyncScope::System
;
373 report_fatal_error("bad SynchronizationScope.");
377 extern "C" LLVMValueRef
378 LLVMRustBuildAtomicFence(LLVMBuilderRef B
, LLVMAtomicOrdering Order
,
379 LLVMRustSynchronizationScope Scope
) {
380 return wrap(unwrap(B
)->CreateFence(fromRust(Order
), fromRust(Scope
)));
383 enum class LLVMRustAsmDialect
{
389 static InlineAsm::AsmDialect
fromRust(LLVMRustAsmDialect Dialect
) {
391 case LLVMRustAsmDialect::Att
:
392 return InlineAsm::AD_ATT
;
393 case LLVMRustAsmDialect::Intel
:
394 return InlineAsm::AD_Intel
;
396 report_fatal_error("bad AsmDialect.");
400 extern "C" LLVMValueRef
401 LLVMRustInlineAsm(LLVMTypeRef Ty
, char *AsmString
, size_t AsmStringLen
,
402 char *Constraints
, size_t ConstraintsLen
,
403 LLVMBool HasSideEffects
, LLVMBool IsAlignStack
,
404 LLVMRustAsmDialect Dialect
) {
405 return wrap(InlineAsm::get(unwrap
<FunctionType
>(Ty
),
406 StringRef(AsmString
, AsmStringLen
),
407 StringRef(Constraints
, ConstraintsLen
),
408 HasSideEffects
, IsAlignStack
, fromRust(Dialect
)));
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 LLVM_VERSION_LT(10, 0)
506 if (isSet(Flags
& LLVMRustDIFlags::FlagBlockByrefStruct
)) {
507 Result
|= DINode::DIFlags::FlagBlockByrefStruct
;
510 if (isSet(Flags
& LLVMRustDIFlags::FlagVirtual
)) {
511 Result
|= DINode::DIFlags::FlagVirtual
;
513 if (isSet(Flags
& LLVMRustDIFlags::FlagArtificial
)) {
514 Result
|= DINode::DIFlags::FlagArtificial
;
516 if (isSet(Flags
& LLVMRustDIFlags::FlagExplicit
)) {
517 Result
|= DINode::DIFlags::FlagExplicit
;
519 if (isSet(Flags
& LLVMRustDIFlags::FlagPrototyped
)) {
520 Result
|= DINode::DIFlags::FlagPrototyped
;
522 if (isSet(Flags
& LLVMRustDIFlags::FlagObjcClassComplete
)) {
523 Result
|= DINode::DIFlags::FlagObjcClassComplete
;
525 if (isSet(Flags
& LLVMRustDIFlags::FlagObjectPointer
)) {
526 Result
|= DINode::DIFlags::FlagObjectPointer
;
528 if (isSet(Flags
& LLVMRustDIFlags::FlagVector
)) {
529 Result
|= DINode::DIFlags::FlagVector
;
531 if (isSet(Flags
& LLVMRustDIFlags::FlagStaticMember
)) {
532 Result
|= DINode::DIFlags::FlagStaticMember
;
534 if (isSet(Flags
& LLVMRustDIFlags::FlagLValueReference
)) {
535 Result
|= DINode::DIFlags::FlagLValueReference
;
537 if (isSet(Flags
& LLVMRustDIFlags::FlagRValueReference
)) {
538 Result
|= DINode::DIFlags::FlagRValueReference
;
540 if (isSet(Flags
& LLVMRustDIFlags::FlagIntroducedVirtual
)) {
541 Result
|= DINode::DIFlags::FlagIntroducedVirtual
;
543 if (isSet(Flags
& LLVMRustDIFlags::FlagBitField
)) {
544 Result
|= DINode::DIFlags::FlagBitField
;
546 if (isSet(Flags
& LLVMRustDIFlags::FlagNoReturn
)) {
547 Result
|= DINode::DIFlags::FlagNoReturn
;
553 // These values **must** match debuginfo::DISPFlags! They also *happen*
554 // to match LLVM, but that isn't required as we do giant sets of
555 // matching below. The value shouldn't be directly passed to LLVM.
556 enum class LLVMRustDISPFlags
: uint32_t {
559 SPFlagPureVirtual
= 2,
560 SPFlagLocalToUnit
= (1 << 2),
561 SPFlagDefinition
= (1 << 3),
562 SPFlagOptimized
= (1 << 4),
563 SPFlagMainSubprogram
= (1 << 5),
564 // Do not add values that are not supported by the minimum LLVM
565 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
566 // (In LLVM < 8, createFunction supported these as separate bool arguments.)
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
) {
575 return static_cast<LLVMRustDISPFlags
>(static_cast<uint32_t>(A
) |
576 static_cast<uint32_t>(B
));
579 inline LLVMRustDISPFlags
&operator|=(LLVMRustDISPFlags
&A
, LLVMRustDISPFlags B
) {
583 inline bool isSet(LLVMRustDISPFlags F
) { return F
!= LLVMRustDISPFlags::SPFlagZero
; }
585 inline LLVMRustDISPFlags
virtuality(LLVMRustDISPFlags F
) {
586 return static_cast<LLVMRustDISPFlags
>(static_cast<uint32_t>(F
) & 0x3);
589 static DISubprogram::DISPFlags
fromRust(LLVMRustDISPFlags SPFlags
) {
590 DISubprogram::DISPFlags Result
= DISubprogram::DISPFlags::SPFlagZero
;
592 switch (virtuality(SPFlags
)) {
593 case LLVMRustDISPFlags::SPFlagVirtual
:
594 Result
|= DISubprogram::DISPFlags::SPFlagVirtual
;
596 case LLVMRustDISPFlags::SPFlagPureVirtual
:
597 Result
|= DISubprogram::DISPFlags::SPFlagPureVirtual
;
600 // The rest are handled below
604 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagLocalToUnit
)) {
605 Result
|= DISubprogram::DISPFlags::SPFlagLocalToUnit
;
607 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagDefinition
)) {
608 Result
|= DISubprogram::DISPFlags::SPFlagDefinition
;
610 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagOptimized
)) {
611 Result
|= DISubprogram::DISPFlags::SPFlagOptimized
;
613 #if LLVM_VERSION_GE(9, 0)
614 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagMainSubprogram
)) {
615 Result
|= DISubprogram::DISPFlags::SPFlagMainSubprogram
;
622 enum class LLVMRustDebugEmissionKind
{
628 static DICompileUnit::DebugEmissionKind
fromRust(LLVMRustDebugEmissionKind Kind
) {
630 case LLVMRustDebugEmissionKind::NoDebug
:
631 return DICompileUnit::DebugEmissionKind::NoDebug
;
632 case LLVMRustDebugEmissionKind::FullDebug
:
633 return DICompileUnit::DebugEmissionKind::FullDebug
;
634 case LLVMRustDebugEmissionKind::LineTablesOnly
:
635 return DICompileUnit::DebugEmissionKind::LineTablesOnly
;
637 report_fatal_error("bad DebugEmissionKind.");
641 enum class LLVMRustChecksumKind
{
647 static Optional
<DIFile::ChecksumKind
> fromRust(LLVMRustChecksumKind Kind
) {
649 case LLVMRustChecksumKind::None
:
651 case LLVMRustChecksumKind::MD5
:
652 return DIFile::ChecksumKind::CSK_MD5
;
653 case LLVMRustChecksumKind::SHA1
:
654 return DIFile::ChecksumKind::CSK_SHA1
;
656 report_fatal_error("bad ChecksumKind.");
660 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
661 return DEBUG_METADATA_VERSION
;
664 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR
; }
666 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR
; }
668 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M
, const char *Name
,
670 unwrap(M
)->addModuleFlag(Module::Warning
, Name
, Value
);
673 extern "C" LLVMValueRef
LLVMRustMetadataAsValue(LLVMContextRef C
, LLVMMetadataRef MD
) {
674 return wrap(MetadataAsValue::get(*unwrap(C
), unwrap(MD
)));
677 extern "C" LLVMRustDIBuilderRef
LLVMRustDIBuilderCreate(LLVMModuleRef M
) {
678 return new DIBuilder(*unwrap(M
));
681 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder
) {
685 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder
) {
689 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateCompileUnit(
690 LLVMRustDIBuilderRef Builder
, unsigned Lang
, LLVMMetadataRef FileRef
,
691 const char *Producer
, size_t ProducerLen
, bool isOptimized
,
692 const char *Flags
, unsigned RuntimeVer
,
693 const char *SplitName
, size_t SplitNameLen
,
694 LLVMRustDebugEmissionKind Kind
) {
695 auto *File
= unwrapDI
<DIFile
>(FileRef
);
697 return wrap(Builder
->createCompileUnit(Lang
, File
, StringRef(Producer
, ProducerLen
),
698 isOptimized
, Flags
, RuntimeVer
,
699 StringRef(SplitName
, SplitNameLen
),
703 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateFile(
704 LLVMRustDIBuilderRef Builder
,
705 const char *Filename
, size_t FilenameLen
,
706 const char *Directory
, size_t DirectoryLen
, LLVMRustChecksumKind CSKind
,
707 const char *Checksum
, size_t ChecksumLen
) {
708 Optional
<DIFile::ChecksumKind
> llvmCSKind
= fromRust(CSKind
);
709 Optional
<DIFile::ChecksumInfo
<StringRef
>> CSInfo
{};
711 CSInfo
.emplace(*llvmCSKind
, StringRef
{Checksum
, ChecksumLen
});
712 return wrap(Builder
->createFile(StringRef(Filename
, FilenameLen
),
713 StringRef(Directory
, DirectoryLen
),
717 extern "C" LLVMMetadataRef
718 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder
,
719 LLVMMetadataRef File
,
720 LLVMMetadataRef ParameterTypes
) {
721 return wrap(Builder
->createSubroutineType(
722 DITypeRefArray(unwrap
<MDTuple
>(ParameterTypes
))));
725 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateFunction(
726 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
727 const char *Name
, size_t NameLen
,
728 const char *LinkageName
, size_t LinkageNameLen
,
729 LLVMMetadataRef File
, unsigned LineNo
,
730 LLVMMetadataRef Ty
, unsigned ScopeLine
, LLVMRustDIFlags Flags
,
731 LLVMRustDISPFlags SPFlags
, LLVMValueRef Fn
, LLVMMetadataRef TParam
,
732 LLVMMetadataRef Decl
) {
733 DITemplateParameterArray TParams
=
734 DITemplateParameterArray(unwrap
<MDTuple
>(TParam
));
735 DISubprogram::DISPFlags llvmSPFlags
= fromRust(SPFlags
);
736 DINode::DIFlags llvmFlags
= fromRust(Flags
);
737 #if LLVM_VERSION_LT(9, 0)
738 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagMainSubprogram
))
739 llvmFlags
|= DINode::DIFlags::FlagMainSubprogram
;
741 DISubprogram
*Sub
= Builder
->createFunction(
742 unwrapDI
<DIScope
>(Scope
),
743 StringRef(Name
, NameLen
),
744 StringRef(LinkageName
, LinkageNameLen
),
745 unwrapDI
<DIFile
>(File
), LineNo
,
746 unwrapDI
<DISubroutineType
>(Ty
), ScopeLine
, llvmFlags
,
747 llvmSPFlags
, TParams
, unwrapDIPtr
<DISubprogram
>(Decl
));
748 unwrap
<Function
>(Fn
)->setSubprogram(Sub
);
752 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateBasicType(
753 LLVMRustDIBuilderRef Builder
, const char *Name
, size_t NameLen
,
754 uint64_t SizeInBits
, uint32_t AlignInBits
, unsigned Encoding
) {
755 return wrap(Builder
->createBasicType(StringRef(Name
, NameLen
), SizeInBits
, Encoding
));
758 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreatePointerType(
759 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef PointeeTy
,
760 uint64_t SizeInBits
, uint32_t AlignInBits
, unsigned AddressSpace
,
761 const char *Name
, size_t NameLen
) {
762 return wrap(Builder
->createPointerType(unwrapDI
<DIType
>(PointeeTy
),
763 SizeInBits
, AlignInBits
,
765 StringRef(Name
, NameLen
)));
768 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateStructType(
769 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
770 const char *Name
, size_t NameLen
,
771 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
772 uint32_t AlignInBits
, LLVMRustDIFlags Flags
,
773 LLVMMetadataRef DerivedFrom
, LLVMMetadataRef Elements
,
774 unsigned RunTimeLang
, LLVMMetadataRef VTableHolder
,
775 const char *UniqueId
, size_t UniqueIdLen
) {
776 return wrap(Builder
->createStructType(
777 unwrapDI
<DIDescriptor
>(Scope
), StringRef(Name
, NameLen
),
778 unwrapDI
<DIFile
>(File
), LineNumber
,
779 SizeInBits
, AlignInBits
, fromRust(Flags
), unwrapDI
<DIType
>(DerivedFrom
),
780 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), RunTimeLang
,
781 unwrapDI
<DIType
>(VTableHolder
), StringRef(UniqueId
, UniqueIdLen
)));
784 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateVariantPart(
785 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
786 const char *Name
, size_t NameLen
,
787 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
788 uint32_t AlignInBits
, LLVMRustDIFlags Flags
, LLVMMetadataRef Discriminator
,
789 LLVMMetadataRef Elements
, const char *UniqueId
, size_t UniqueIdLen
) {
790 return wrap(Builder
->createVariantPart(
791 unwrapDI
<DIDescriptor
>(Scope
), StringRef(Name
, NameLen
),
792 unwrapDI
<DIFile
>(File
), LineNumber
,
793 SizeInBits
, AlignInBits
, fromRust(Flags
), unwrapDI
<DIDerivedType
>(Discriminator
),
794 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), StringRef(UniqueId
, UniqueIdLen
)));
797 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateMemberType(
798 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
799 const char *Name
, size_t NameLen
,
800 LLVMMetadataRef File
, unsigned LineNo
, uint64_t SizeInBits
,
801 uint32_t AlignInBits
, uint64_t OffsetInBits
, LLVMRustDIFlags Flags
,
802 LLVMMetadataRef Ty
) {
803 return wrap(Builder
->createMemberType(unwrapDI
<DIDescriptor
>(Scope
),
804 StringRef(Name
, NameLen
),
805 unwrapDI
<DIFile
>(File
), LineNo
,
806 SizeInBits
, AlignInBits
, OffsetInBits
,
807 fromRust(Flags
), unwrapDI
<DIType
>(Ty
)));
810 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateVariantMemberType(
811 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
812 const char *Name
, size_t NameLen
, LLVMMetadataRef File
, unsigned LineNo
,
813 uint64_t SizeInBits
, uint32_t AlignInBits
, uint64_t OffsetInBits
, LLVMValueRef Discriminant
,
814 LLVMRustDIFlags Flags
, LLVMMetadataRef Ty
) {
815 llvm::ConstantInt
* D
= nullptr;
817 D
= unwrap
<llvm::ConstantInt
>(Discriminant
);
819 return wrap(Builder
->createVariantMemberType(unwrapDI
<DIDescriptor
>(Scope
),
820 StringRef(Name
, NameLen
),
821 unwrapDI
<DIFile
>(File
), LineNo
,
822 SizeInBits
, AlignInBits
, OffsetInBits
, D
,
823 fromRust(Flags
), unwrapDI
<DIType
>(Ty
)));
826 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateLexicalBlock(
827 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
828 LLVMMetadataRef File
, unsigned Line
, unsigned Col
) {
829 return wrap(Builder
->createLexicalBlock(unwrapDI
<DIDescriptor
>(Scope
),
830 unwrapDI
<DIFile
>(File
), Line
, Col
));
833 extern "C" LLVMMetadataRef
834 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder
,
835 LLVMMetadataRef Scope
,
836 LLVMMetadataRef File
) {
837 return wrap(Builder
->createLexicalBlockFile(unwrapDI
<DIDescriptor
>(Scope
),
838 unwrapDI
<DIFile
>(File
)));
841 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateStaticVariable(
842 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Context
,
843 const char *Name
, size_t NameLen
,
844 const char *LinkageName
, size_t LinkageNameLen
,
845 LLVMMetadataRef File
, unsigned LineNo
,
846 LLVMMetadataRef Ty
, bool IsLocalToUnit
, LLVMValueRef V
,
847 LLVMMetadataRef Decl
= nullptr, uint32_t AlignInBits
= 0) {
848 llvm::GlobalVariable
*InitVal
= cast
<llvm::GlobalVariable
>(unwrap(V
));
850 llvm::DIExpression
*InitExpr
= nullptr;
851 if (llvm::ConstantInt
*IntVal
= llvm::dyn_cast
<llvm::ConstantInt
>(InitVal
)) {
852 InitExpr
= Builder
->createConstantValueExpression(
853 IntVal
->getValue().getSExtValue());
854 } else if (llvm::ConstantFP
*FPVal
=
855 llvm::dyn_cast
<llvm::ConstantFP
>(InitVal
)) {
856 InitExpr
= Builder
->createConstantValueExpression(
857 FPVal
->getValueAPF().bitcastToAPInt().getZExtValue());
860 llvm::DIGlobalVariableExpression
*VarExpr
= Builder
->createGlobalVariableExpression(
861 unwrapDI
<DIDescriptor
>(Context
), StringRef(Name
, NameLen
),
862 StringRef(LinkageName
, LinkageNameLen
),
863 unwrapDI
<DIFile
>(File
), LineNo
, unwrapDI
<DIType
>(Ty
), IsLocalToUnit
,
864 #if LLVM_VERSION_GE(10, 0)
865 /* isDefined */ true,
867 InitExpr
, unwrapDIPtr
<MDNode
>(Decl
),
868 /* templateParams */ nullptr,
871 InitVal
->setMetadata("dbg", VarExpr
);
873 return wrap(VarExpr
);
876 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateVariable(
877 LLVMRustDIBuilderRef Builder
, unsigned Tag
, LLVMMetadataRef Scope
,
878 const char *Name
, size_t NameLen
,
879 LLVMMetadataRef File
, unsigned LineNo
,
880 LLVMMetadataRef Ty
, bool AlwaysPreserve
, LLVMRustDIFlags Flags
,
881 unsigned ArgNo
, uint32_t AlignInBits
) {
882 if (Tag
== 0x100) { // DW_TAG_auto_variable
883 return wrap(Builder
->createAutoVariable(
884 unwrapDI
<DIDescriptor
>(Scope
), StringRef(Name
, NameLen
),
885 unwrapDI
<DIFile
>(File
), LineNo
,
886 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, fromRust(Flags
), AlignInBits
));
888 return wrap(Builder
->createParameterVariable(
889 unwrapDI
<DIDescriptor
>(Scope
), StringRef(Name
, NameLen
), ArgNo
,
890 unwrapDI
<DIFile
>(File
), LineNo
,
891 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, fromRust(Flags
)));
895 extern "C" LLVMMetadataRef
896 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder
, uint64_t Size
,
897 uint32_t AlignInBits
, LLVMMetadataRef Ty
,
898 LLVMMetadataRef Subscripts
) {
900 Builder
->createArrayType(Size
, AlignInBits
, unwrapDI
<DIType
>(Ty
),
901 DINodeArray(unwrapDI
<MDTuple
>(Subscripts
))));
904 extern "C" LLVMMetadataRef
905 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder
, int64_t Lo
,
907 return wrap(Builder
->getOrCreateSubrange(Lo
, Count
));
910 extern "C" LLVMMetadataRef
911 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder
,
912 LLVMMetadataRef
*Ptr
, unsigned Count
) {
913 Metadata
**DataValue
= unwrap(Ptr
);
915 Builder
->getOrCreateArray(ArrayRef
<Metadata
*>(DataValue
, Count
)).get());
918 extern "C" LLVMValueRef
LLVMRustDIBuilderInsertDeclareAtEnd(
919 LLVMRustDIBuilderRef Builder
, LLVMValueRef V
, LLVMMetadataRef VarInfo
,
920 int64_t *AddrOps
, unsigned AddrOpsCount
, LLVMValueRef DL
,
921 LLVMBasicBlockRef InsertAtEnd
) {
922 return wrap(Builder
->insertDeclare(
923 unwrap(V
), unwrap
<DILocalVariable
>(VarInfo
),
924 Builder
->createExpression(llvm::ArrayRef
<int64_t>(AddrOps
, AddrOpsCount
)),
925 DebugLoc(cast
<MDNode
>(unwrap
<MetadataAsValue
>(DL
)->getMetadata())),
926 unwrap(InsertAtEnd
)));
929 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateEnumerator(
930 LLVMRustDIBuilderRef Builder
, const char *Name
, size_t NameLen
,
931 int64_t Value
, bool IsUnsigned
) {
932 return wrap(Builder
->createEnumerator(StringRef(Name
, NameLen
), Value
, IsUnsigned
));
935 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateEnumerationType(
936 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
937 const char *Name
, size_t NameLen
,
938 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
939 uint32_t AlignInBits
, LLVMMetadataRef Elements
,
940 LLVMMetadataRef ClassTy
, bool IsScoped
) {
941 return wrap(Builder
->createEnumerationType(
942 unwrapDI
<DIDescriptor
>(Scope
), StringRef(Name
, NameLen
),
943 unwrapDI
<DIFile
>(File
), LineNumber
,
944 SizeInBits
, AlignInBits
, DINodeArray(unwrapDI
<MDTuple
>(Elements
)),
945 unwrapDI
<DIType
>(ClassTy
), "", IsScoped
));
948 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateUnionType(
949 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
950 const char *Name
, size_t NameLen
,
951 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
952 uint32_t AlignInBits
, LLVMRustDIFlags Flags
, LLVMMetadataRef Elements
,
953 unsigned RunTimeLang
, const char *UniqueId
, size_t UniqueIdLen
) {
954 return wrap(Builder
->createUnionType(
955 unwrapDI
<DIDescriptor
>(Scope
), StringRef(Name
, NameLen
), unwrapDI
<DIFile
>(File
),
956 LineNumber
, SizeInBits
, AlignInBits
, fromRust(Flags
),
957 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), RunTimeLang
,
958 StringRef(UniqueId
, UniqueIdLen
)));
961 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateTemplateTypeParameter(
962 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
963 const char *Name
, size_t NameLen
,
964 LLVMMetadataRef Ty
, LLVMMetadataRef File
, unsigned LineNo
,
966 return wrap(Builder
->createTemplateTypeParameter(
967 unwrapDI
<DIDescriptor
>(Scope
), StringRef(Name
, NameLen
), unwrapDI
<DIType
>(Ty
)));
970 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateNameSpace(
971 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
972 const char *Name
, size_t NameLen
, bool ExportSymbols
) {
973 return wrap(Builder
->createNameSpace(
974 unwrapDI
<DIDescriptor
>(Scope
), StringRef(Name
, NameLen
), ExportSymbols
979 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder
,
980 LLVMMetadataRef CompositeTy
,
981 LLVMMetadataRef Elements
,
982 LLVMMetadataRef Params
) {
983 DICompositeType
*Tmp
= unwrapDI
<DICompositeType
>(CompositeTy
);
984 Builder
->replaceArrays(Tmp
, DINodeArray(unwrap
<MDTuple
>(Elements
)),
985 DINodeArray(unwrap
<MDTuple
>(Params
)));
988 extern "C" LLVMValueRef
989 LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef
, unsigned Line
,
990 unsigned Column
, LLVMMetadataRef Scope
,
991 LLVMMetadataRef InlinedAt
) {
992 LLVMContext
&Context
= *unwrap(ContextRef
);
994 DebugLoc debug_loc
= DebugLoc::get(Line
, Column
, unwrapDIPtr
<MDNode
>(Scope
),
995 unwrapDIPtr
<MDNode
>(InlinedAt
));
997 return wrap(MetadataAsValue::get(Context
, debug_loc
.getAsMDNode()));
1000 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
1001 return dwarf::DW_OP_deref
;
1004 extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
1005 return dwarf::DW_OP_plus_uconst
;
1008 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty
, RustStringRef Str
) {
1009 RawRustStringOstream
OS(Str
);
1010 unwrap
<llvm::Type
>(Ty
)->print(OS
);
1013 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V
,
1014 RustStringRef Str
) {
1015 RawRustStringOstream
OS(Str
);
1020 unwrap
<llvm::Value
>(V
)->getType()->print(OS
);
1022 unwrap
<llvm::Value
>(V
)->print(OS
);
1027 // Note that the two following functions look quite similar to the
1028 // LLVMGetSectionName function. Sadly, it appears that this function only
1029 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
1030 // function provided by LLVM doesn't return the length, so we've created our own
1031 // function which returns the length as well as the data pointer.
1033 // For an example of this not returning a null terminated string, see
1034 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
1035 // branches explicitly creates a StringRef without a null terminator, and then
1038 inline section_iterator
*unwrap(LLVMSectionIteratorRef SI
) {
1039 return reinterpret_cast<section_iterator
*>(SI
);
1042 extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI
,
1044 #if LLVM_VERSION_GE(10, 0)
1045 auto NameOrErr
= (*unwrap(SI
))->getName();
1047 report_fatal_error(NameOrErr
.takeError());
1048 *Ptr
= NameOrErr
->data();
1049 return NameOrErr
->size();
1052 if (std::error_code EC
= (*unwrap(SI
))->getName(Ret
))
1053 report_fatal_error(EC
.message());
1059 // LLVMArrayType function does not support 64-bit ElementCount
1060 extern "C" LLVMTypeRef
LLVMRustArrayType(LLVMTypeRef ElementTy
,
1061 uint64_t ElementCount
) {
1062 return wrap(ArrayType::get(unwrap(ElementTy
), ElementCount
));
1065 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine
, LLVMTwineRef
)
1067 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T
, RustStringRef Str
) {
1068 RawRustStringOstream
OS(Str
);
1069 unwrap(T
)->print(OS
);
1072 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1073 LLVMDiagnosticInfoRef DI
, RustStringRef PassNameOut
,
1074 LLVMValueRef
*FunctionOut
, unsigned* Line
, unsigned* Column
,
1075 RustStringRef FilenameOut
, RustStringRef MessageOut
) {
1076 // Undefined to call this not on an optimization diagnostic!
1077 llvm::DiagnosticInfoOptimizationBase
*Opt
=
1078 static_cast<llvm::DiagnosticInfoOptimizationBase
*>(unwrap(DI
));
1080 RawRustStringOstream
PassNameOS(PassNameOut
);
1081 PassNameOS
<< Opt
->getPassName();
1082 *FunctionOut
= wrap(&Opt
->getFunction());
1084 RawRustStringOstream
FilenameOS(FilenameOut
);
1085 DiagnosticLocation loc
= Opt
->getLocation();
1086 if (loc
.isValid()) {
1087 *Line
= loc
.getLine();
1088 *Column
= loc
.getColumn();
1089 FilenameOS
<< loc
.getAbsolutePath();
1092 RawRustStringOstream
MessageOS(MessageOut
);
1093 MessageOS
<< Opt
->getMsg();
1097 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI
, unsigned *CookieOut
,
1098 LLVMTwineRef
*MessageOut
,
1099 LLVMValueRef
*InstructionOut
) {
1100 // Undefined to call this not on an inline assembly diagnostic!
1101 llvm::DiagnosticInfoInlineAsm
*IA
=
1102 static_cast<llvm::DiagnosticInfoInlineAsm
*>(unwrap(DI
));
1104 *CookieOut
= IA
->getLocCookie();
1105 *MessageOut
= wrap(&IA
->getMsgStr());
1106 *InstructionOut
= wrap(IA
->getInstruction());
1109 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI
,
1110 RustStringRef Str
) {
1111 RawRustStringOstream
OS(Str
);
1112 DiagnosticPrinterRawOStream
DP(OS
);
1113 unwrap(DI
)->print(DP
);
1116 enum class LLVMRustDiagnosticKind
{
1120 DebugMetadataVersion
,
1123 OptimizationRemarkMissed
,
1124 OptimizationRemarkAnalysis
,
1125 OptimizationRemarkAnalysisFPCommute
,
1126 OptimizationRemarkAnalysisAliasing
,
1127 OptimizationRemarkOther
,
1128 OptimizationFailure
,
1133 static LLVMRustDiagnosticKind
toRust(DiagnosticKind Kind
) {
1136 return LLVMRustDiagnosticKind::InlineAsm
;
1138 return LLVMRustDiagnosticKind::StackSize
;
1139 case DK_DebugMetadataVersion
:
1140 return LLVMRustDiagnosticKind::DebugMetadataVersion
;
1141 case DK_SampleProfile
:
1142 return LLVMRustDiagnosticKind::SampleProfile
;
1143 case DK_OptimizationRemark
:
1144 return LLVMRustDiagnosticKind::OptimizationRemark
;
1145 case DK_OptimizationRemarkMissed
:
1146 return LLVMRustDiagnosticKind::OptimizationRemarkMissed
;
1147 case DK_OptimizationRemarkAnalysis
:
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
;
1158 return (Kind
>= DK_FirstRemark
&& Kind
<= DK_LastRemark
)
1159 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1160 : LLVMRustDiagnosticKind::Other
;
1164 extern "C" LLVMRustDiagnosticKind
1165 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI
) {
1166 return toRust((DiagnosticKind
)unwrap(DI
)->getKind());
1168 // This is kept distinct from LLVMGetTypeKind, because when
1169 // a new type kind is added, the Rust-side enum must be
1170 // updated or UB will result.
1171 extern "C" LLVMTypeKind
LLVMRustGetTypeKind(LLVMTypeRef Ty
) {
1172 switch (unwrap(Ty
)->getTypeID()) {
1173 case Type::VoidTyID
:
1174 return LLVMVoidTypeKind
;
1175 case Type::HalfTyID
:
1176 return LLVMHalfTypeKind
;
1177 case Type::FloatTyID
:
1178 return LLVMFloatTypeKind
;
1179 case Type::DoubleTyID
:
1180 return LLVMDoubleTypeKind
;
1181 case Type::X86_FP80TyID
:
1182 return LLVMX86_FP80TypeKind
;
1183 case Type::FP128TyID
:
1184 return LLVMFP128TypeKind
;
1185 case Type::PPC_FP128TyID
:
1186 return LLVMPPC_FP128TypeKind
;
1187 case Type::LabelTyID
:
1188 return LLVMLabelTypeKind
;
1189 case Type::MetadataTyID
:
1190 return LLVMMetadataTypeKind
;
1191 case Type::IntegerTyID
:
1192 return LLVMIntegerTypeKind
;
1193 case Type::FunctionTyID
:
1194 return LLVMFunctionTypeKind
;
1195 case Type::StructTyID
:
1196 return LLVMStructTypeKind
;
1197 case Type::ArrayTyID
:
1198 return LLVMArrayTypeKind
;
1199 case Type::PointerTyID
:
1200 return LLVMPointerTypeKind
;
1201 case Type::VectorTyID
:
1202 return LLVMVectorTypeKind
;
1203 case Type::X86_MMXTyID
:
1204 return LLVMX86_MMXTypeKind
;
1205 case Type::TokenTyID
:
1206 return LLVMTokenTypeKind
;
1208 report_fatal_error("Unhandled TypeID.");
1211 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic
, LLVMSMDiagnosticRef
)
1213 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1214 LLVMContextRef C
, LLVMContext::InlineAsmDiagHandlerTy H
, void *CX
) {
1215 unwrap(C
)->setInlineAsmDiagnosticHandler(H
, CX
);
1218 extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef D
,
1219 RustStringRef Str
) {
1220 RawRustStringOstream
OS(Str
);
1221 unwrap(D
)->print("", OS
);
1224 extern "C" LLVMValueRef
LLVMRustBuildCleanupPad(LLVMBuilderRef B
,
1225 LLVMValueRef ParentPad
,
1227 LLVMValueRef
*LLArgs
,
1229 Value
**Args
= unwrap(LLArgs
);
1230 if (ParentPad
== nullptr) {
1231 Type
*Ty
= Type::getTokenTy(unwrap(B
)->getContext());
1232 ParentPad
= wrap(Constant::getNullValue(Ty
));
1234 return wrap(unwrap(B
)->CreateCleanupPad(
1235 unwrap(ParentPad
), ArrayRef
<Value
*>(Args
, ArgCount
), Name
));
1238 extern "C" LLVMValueRef
LLVMRustBuildCleanupRet(LLVMBuilderRef B
,
1239 LLVMValueRef CleanupPad
,
1240 LLVMBasicBlockRef UnwindBB
) {
1241 CleanupPadInst
*Inst
= cast
<CleanupPadInst
>(unwrap(CleanupPad
));
1242 return wrap(unwrap(B
)->CreateCleanupRet(Inst
, unwrap(UnwindBB
)));
1245 extern "C" LLVMValueRef
1246 LLVMRustBuildCatchPad(LLVMBuilderRef B
, LLVMValueRef ParentPad
,
1247 unsigned ArgCount
, LLVMValueRef
*LLArgs
, const char *Name
) {
1248 Value
**Args
= unwrap(LLArgs
);
1249 return wrap(unwrap(B
)->CreateCatchPad(
1250 unwrap(ParentPad
), ArrayRef
<Value
*>(Args
, ArgCount
), Name
));
1253 extern "C" LLVMValueRef
LLVMRustBuildCatchRet(LLVMBuilderRef B
,
1255 LLVMBasicBlockRef BB
) {
1256 return wrap(unwrap(B
)->CreateCatchRet(cast
<CatchPadInst
>(unwrap(Pad
)),
1260 extern "C" LLVMValueRef
LLVMRustBuildCatchSwitch(LLVMBuilderRef B
,
1261 LLVMValueRef ParentPad
,
1262 LLVMBasicBlockRef BB
,
1263 unsigned NumHandlers
,
1265 if (ParentPad
== nullptr) {
1266 Type
*Ty
= Type::getTokenTy(unwrap(B
)->getContext());
1267 ParentPad
= wrap(Constant::getNullValue(Ty
));
1269 return wrap(unwrap(B
)->CreateCatchSwitch(unwrap(ParentPad
), unwrap(BB
),
1270 NumHandlers
, Name
));
1273 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef
,
1274 LLVMBasicBlockRef Handler
) {
1275 Value
*CatchSwitch
= unwrap(CatchSwitchRef
);
1276 cast
<CatchSwitchInst
>(CatchSwitch
)->addHandler(unwrap(Handler
));
1279 extern "C" OperandBundleDef
*LLVMRustBuildOperandBundleDef(const char *Name
,
1280 LLVMValueRef
*Inputs
,
1281 unsigned NumInputs
) {
1282 return new OperandBundleDef(Name
, makeArrayRef(unwrap(Inputs
), NumInputs
));
1285 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef
*Bundle
) {
1289 extern "C" LLVMValueRef
LLVMRustBuildCall(LLVMBuilderRef B
, LLVMValueRef Fn
,
1290 LLVMValueRef
*Args
, unsigned NumArgs
,
1291 OperandBundleDef
*Bundle
) {
1292 unsigned Len
= Bundle
? 1 : 0;
1293 ArrayRef
<OperandBundleDef
> Bundles
= makeArrayRef(Bundle
, Len
);
1294 return wrap(unwrap(B
)->CreateCall(
1295 unwrap(Fn
), makeArrayRef(unwrap(Args
), NumArgs
), Bundles
));
1298 extern "C" LLVMValueRef
LLVMRustBuildMemCpy(LLVMBuilderRef B
,
1299 LLVMValueRef Dst
, unsigned DstAlign
,
1300 LLVMValueRef Src
, unsigned SrcAlign
,
1301 LLVMValueRef Size
, bool IsVolatile
) {
1302 #if LLVM_VERSION_GE(10, 0)
1303 return wrap(unwrap(B
)->CreateMemCpy(
1304 unwrap(Dst
), MaybeAlign(DstAlign
),
1305 unwrap(Src
), MaybeAlign(SrcAlign
),
1306 unwrap(Size
), IsVolatile
));
1308 return wrap(unwrap(B
)->CreateMemCpy(
1309 unwrap(Dst
), DstAlign
,
1310 unwrap(Src
), SrcAlign
,
1311 unwrap(Size
), IsVolatile
));
1315 extern "C" LLVMValueRef
LLVMRustBuildMemMove(LLVMBuilderRef B
,
1316 LLVMValueRef Dst
, unsigned DstAlign
,
1317 LLVMValueRef Src
, unsigned SrcAlign
,
1318 LLVMValueRef Size
, bool IsVolatile
) {
1319 #if LLVM_VERSION_GE(10, 0)
1320 return wrap(unwrap(B
)->CreateMemMove(
1321 unwrap(Dst
), MaybeAlign(DstAlign
),
1322 unwrap(Src
), MaybeAlign(SrcAlign
),
1323 unwrap(Size
), IsVolatile
));
1325 return wrap(unwrap(B
)->CreateMemMove(
1326 unwrap(Dst
), DstAlign
,
1327 unwrap(Src
), SrcAlign
,
1328 unwrap(Size
), IsVolatile
));
1332 extern "C" LLVMValueRef
LLVMRustBuildMemSet(LLVMBuilderRef B
,
1333 LLVMValueRef Dst
, unsigned DstAlign
,
1335 LLVMValueRef Size
, bool IsVolatile
) {
1336 #if LLVM_VERSION_GE(10, 0)
1337 return wrap(unwrap(B
)->CreateMemSet(
1338 unwrap(Dst
), unwrap(Val
), unwrap(Size
), MaybeAlign(DstAlign
), IsVolatile
));
1340 return wrap(unwrap(B
)->CreateMemSet(
1341 unwrap(Dst
), unwrap(Val
), unwrap(Size
), DstAlign
, IsVolatile
));
1345 extern "C" LLVMValueRef
1346 LLVMRustBuildInvoke(LLVMBuilderRef B
, LLVMValueRef Fn
, LLVMValueRef
*Args
,
1347 unsigned NumArgs
, LLVMBasicBlockRef Then
,
1348 LLVMBasicBlockRef Catch
, OperandBundleDef
*Bundle
,
1350 unsigned Len
= Bundle
? 1 : 0;
1351 ArrayRef
<OperandBundleDef
> Bundles
= makeArrayRef(Bundle
, Len
);
1352 return wrap(unwrap(B
)->CreateInvoke(unwrap(Fn
), unwrap(Then
), unwrap(Catch
),
1353 makeArrayRef(unwrap(Args
), NumArgs
),
1357 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B
,
1358 LLVMBasicBlockRef BB
) {
1359 auto Point
= unwrap(BB
)->getFirstInsertionPt();
1360 unwrap(B
)->SetInsertPoint(unwrap(BB
), Point
);
1363 extern "C" void LLVMRustSetComdat(LLVMModuleRef M
, LLVMValueRef V
,
1364 const char *Name
, size_t NameLen
) {
1365 Triple
TargetTriple(unwrap(M
)->getTargetTriple());
1366 GlobalObject
*GV
= unwrap
<GlobalObject
>(V
);
1367 if (!TargetTriple
.isOSBinFormatMachO()) {
1368 StringRef
NameRef(Name
, NameLen
);
1369 GV
->setComdat(unwrap(M
)->getOrInsertComdat(NameRef
));
1373 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V
) {
1374 GlobalObject
*GV
= unwrap
<GlobalObject
>(V
);
1375 GV
->setComdat(nullptr);
1378 enum class LLVMRustLinkage
{
1379 ExternalLinkage
= 0,
1380 AvailableExternallyLinkage
= 1,
1381 LinkOnceAnyLinkage
= 2,
1382 LinkOnceODRLinkage
= 3,
1385 AppendingLinkage
= 6,
1386 InternalLinkage
= 7,
1388 ExternalWeakLinkage
= 9,
1392 static LLVMRustLinkage
toRust(LLVMLinkage Linkage
) {
1394 case LLVMExternalLinkage
:
1395 return LLVMRustLinkage::ExternalLinkage
;
1396 case LLVMAvailableExternallyLinkage
:
1397 return LLVMRustLinkage::AvailableExternallyLinkage
;
1398 case LLVMLinkOnceAnyLinkage
:
1399 return LLVMRustLinkage::LinkOnceAnyLinkage
;
1400 case LLVMLinkOnceODRLinkage
:
1401 return LLVMRustLinkage::LinkOnceODRLinkage
;
1402 case LLVMWeakAnyLinkage
:
1403 return LLVMRustLinkage::WeakAnyLinkage
;
1404 case LLVMWeakODRLinkage
:
1405 return LLVMRustLinkage::WeakODRLinkage
;
1406 case LLVMAppendingLinkage
:
1407 return LLVMRustLinkage::AppendingLinkage
;
1408 case LLVMInternalLinkage
:
1409 return LLVMRustLinkage::InternalLinkage
;
1410 case LLVMPrivateLinkage
:
1411 return LLVMRustLinkage::PrivateLinkage
;
1412 case LLVMExternalWeakLinkage
:
1413 return LLVMRustLinkage::ExternalWeakLinkage
;
1414 case LLVMCommonLinkage
:
1415 return LLVMRustLinkage::CommonLinkage
;
1417 report_fatal_error("Invalid LLVMRustLinkage value!");
1421 static LLVMLinkage
fromRust(LLVMRustLinkage Linkage
) {
1423 case LLVMRustLinkage::ExternalLinkage
:
1424 return LLVMExternalLinkage
;
1425 case LLVMRustLinkage::AvailableExternallyLinkage
:
1426 return LLVMAvailableExternallyLinkage
;
1427 case LLVMRustLinkage::LinkOnceAnyLinkage
:
1428 return LLVMLinkOnceAnyLinkage
;
1429 case LLVMRustLinkage::LinkOnceODRLinkage
:
1430 return LLVMLinkOnceODRLinkage
;
1431 case LLVMRustLinkage::WeakAnyLinkage
:
1432 return LLVMWeakAnyLinkage
;
1433 case LLVMRustLinkage::WeakODRLinkage
:
1434 return LLVMWeakODRLinkage
;
1435 case LLVMRustLinkage::AppendingLinkage
:
1436 return LLVMAppendingLinkage
;
1437 case LLVMRustLinkage::InternalLinkage
:
1438 return LLVMInternalLinkage
;
1439 case LLVMRustLinkage::PrivateLinkage
:
1440 return LLVMPrivateLinkage
;
1441 case LLVMRustLinkage::ExternalWeakLinkage
:
1442 return LLVMExternalWeakLinkage
;
1443 case LLVMRustLinkage::CommonLinkage
:
1444 return LLVMCommonLinkage
;
1446 report_fatal_error("Invalid LLVMRustLinkage value!");
1449 extern "C" LLVMRustLinkage
LLVMRustGetLinkage(LLVMValueRef V
) {
1450 return toRust(LLVMGetLinkage(V
));
1453 extern "C" void LLVMRustSetLinkage(LLVMValueRef V
,
1454 LLVMRustLinkage RustLinkage
) {
1455 LLVMSetLinkage(V
, fromRust(RustLinkage
));
1458 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1459 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1460 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV
, bool sext
, uint64_t *high
, uint64_t *low
)
1462 auto C
= unwrap
<llvm::ConstantInt
>(CV
);
1463 if (C
->getBitWidth() > 128) { return false; }
1466 AP
= C
->getValue().sextOrSelf(128);
1468 AP
= C
->getValue().zextOrSelf(128);
1470 *low
= AP
.getLoBits(64).getZExtValue();
1471 *high
= AP
.getHiBits(64).getZExtValue();
1475 enum class LLVMRustVisibility
{
1481 static LLVMRustVisibility
toRust(LLVMVisibility Vis
) {
1483 case LLVMDefaultVisibility
:
1484 return LLVMRustVisibility::Default
;
1485 case LLVMHiddenVisibility
:
1486 return LLVMRustVisibility::Hidden
;
1487 case LLVMProtectedVisibility
:
1488 return LLVMRustVisibility::Protected
;
1490 report_fatal_error("Invalid LLVMRustVisibility value!");
1493 static LLVMVisibility
fromRust(LLVMRustVisibility Vis
) {
1495 case LLVMRustVisibility::Default
:
1496 return LLVMDefaultVisibility
;
1497 case LLVMRustVisibility::Hidden
:
1498 return LLVMHiddenVisibility
;
1499 case LLVMRustVisibility::Protected
:
1500 return LLVMProtectedVisibility
;
1502 report_fatal_error("Invalid LLVMRustVisibility value!");
1505 extern "C" LLVMRustVisibility
LLVMRustGetVisibility(LLVMValueRef V
) {
1506 return toRust(LLVMGetVisibility(V
));
1509 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1510 extern "C" LLVMValueRef
LLVMRustBuildIntCast(LLVMBuilderRef B
, LLVMValueRef Val
,
1511 LLVMTypeRef DestTy
, bool isSigned
) {
1512 return wrap(unwrap(B
)->CreateIntCast(unwrap(Val
), unwrap(DestTy
), isSigned
, ""));
1515 extern "C" void LLVMRustSetVisibility(LLVMValueRef V
,
1516 LLVMRustVisibility RustVisibility
) {
1517 LLVMSetVisibility(V
, fromRust(RustVisibility
));
1520 struct LLVMRustModuleBuffer
{
1524 extern "C" LLVMRustModuleBuffer
*
1525 LLVMRustModuleBufferCreate(LLVMModuleRef M
) {
1526 #if LLVM_VERSION_GE(10, 0)
1527 auto Ret
= std::make_unique
<LLVMRustModuleBuffer
>();
1529 auto Ret
= llvm::make_unique
<LLVMRustModuleBuffer
>();
1532 raw_string_ostream
OS(Ret
->data
);
1534 legacy::PassManager PM
;
1535 PM
.add(createBitcodeWriterPass(OS
));
1539 return Ret
.release();
1543 LLVMRustModuleBufferFree(LLVMRustModuleBuffer
*Buffer
) {
1547 extern "C" const void*
1548 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer
*Buffer
) {
1549 return Buffer
->data
.data();
1553 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer
*Buffer
) {
1554 return Buffer
->data
.length();
1558 LLVMRustModuleCost(LLVMModuleRef M
) {
1559 auto f
= unwrap(M
)->functions();
1560 return std::distance(std::begin(f
), std::end(f
));
1563 // Vector reductions:
1564 extern "C" LLVMValueRef
1565 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B
, LLVMValueRef Acc
, LLVMValueRef Src
) {
1566 return wrap(unwrap(B
)->CreateFAddReduce(unwrap(Acc
),unwrap(Src
)));
1568 extern "C" LLVMValueRef
1569 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B
, LLVMValueRef Acc
, LLVMValueRef Src
) {
1570 return wrap(unwrap(B
)->CreateFMulReduce(unwrap(Acc
),unwrap(Src
)));
1572 extern "C" LLVMValueRef
1573 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B
, LLVMValueRef Src
) {
1574 return wrap(unwrap(B
)->CreateAddReduce(unwrap(Src
)));
1576 extern "C" LLVMValueRef
1577 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B
, LLVMValueRef Src
) {
1578 return wrap(unwrap(B
)->CreateMulReduce(unwrap(Src
)));
1580 extern "C" LLVMValueRef
1581 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B
, LLVMValueRef Src
) {
1582 return wrap(unwrap(B
)->CreateAndReduce(unwrap(Src
)));
1584 extern "C" LLVMValueRef
1585 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B
, LLVMValueRef Src
) {
1586 return wrap(unwrap(B
)->CreateOrReduce(unwrap(Src
)));
1588 extern "C" LLVMValueRef
1589 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B
, LLVMValueRef Src
) {
1590 return wrap(unwrap(B
)->CreateXorReduce(unwrap(Src
)));
1592 extern "C" LLVMValueRef
1593 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B
, LLVMValueRef Src
, bool IsSigned
) {
1594 return wrap(unwrap(B
)->CreateIntMinReduce(unwrap(Src
), IsSigned
));
1596 extern "C" LLVMValueRef
1597 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B
, LLVMValueRef Src
, bool IsSigned
) {
1598 return wrap(unwrap(B
)->CreateIntMaxReduce(unwrap(Src
), IsSigned
));
1600 extern "C" LLVMValueRef
1601 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B
, LLVMValueRef Src
, bool NoNaN
) {
1602 return wrap(unwrap(B
)->CreateFPMinReduce(unwrap(Src
), NoNaN
));
1604 extern "C" LLVMValueRef
1605 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B
, LLVMValueRef Src
, bool NoNaN
) {
1606 return wrap(unwrap(B
)->CreateFPMaxReduce(unwrap(Src
), NoNaN
));
1609 extern "C" LLVMValueRef
1610 LLVMRustBuildMinNum(LLVMBuilderRef B
, LLVMValueRef LHS
, LLVMValueRef RHS
) {
1611 return wrap(unwrap(B
)->CreateMinNum(unwrap(LHS
),unwrap(RHS
)));
1613 extern "C" LLVMValueRef
1614 LLVMRustBuildMaxNum(LLVMBuilderRef B
, LLVMValueRef LHS
, LLVMValueRef RHS
) {
1615 return wrap(unwrap(B
)->CreateMaxNum(unwrap(LHS
),unwrap(RHS
)));