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
,
117 return wrap(unwrap(M
)->getNamedValue(Name
));
120 extern "C" LLVMValueRef
LLVMRustGetOrInsertFunction(LLVMModuleRef M
,
122 LLVMTypeRef FunctionTy
) {
124 unwrap(M
)->getOrInsertFunction(Name
, unwrap
<FunctionType
>(FunctionTy
))
125 #if LLVM_VERSION_GE(9, 0)
131 extern "C" LLVMValueRef
132 LLVMRustGetOrInsertGlobal(LLVMModuleRef M
, const char *Name
, size_t NameLen
, LLVMTypeRef Ty
) {
133 StringRef
NameRef(Name
, NameLen
);
134 return wrap(unwrap(M
)->getOrInsertGlobal(NameRef
, unwrap(Ty
)));
137 extern "C" LLVMValueRef
138 LLVMRustInsertPrivateGlobal(LLVMModuleRef M
, LLVMTypeRef Ty
) {
139 return wrap(new GlobalVariable(*unwrap(M
),
142 GlobalValue::PrivateLinkage
,
146 extern "C" LLVMTypeRef
LLVMRustMetadataTypeInContext(LLVMContextRef C
) {
147 return wrap(Type::getMetadataTy(*unwrap(C
)));
150 static Attribute::AttrKind
fromRust(LLVMRustAttribute Kind
) {
153 return Attribute::AlwaysInline
;
155 return Attribute::ByVal
;
157 return Attribute::Cold
;
159 return Attribute::InlineHint
;
161 return Attribute::MinSize
;
163 return Attribute::Naked
;
165 return Attribute::NoAlias
;
167 return Attribute::NoCapture
;
169 return Attribute::NoInline
;
171 return Attribute::NonNull
;
173 return Attribute::NoRedZone
;
175 return Attribute::NoReturn
;
177 return Attribute::NoUnwind
;
178 case OptimizeForSize
:
179 return Attribute::OptimizeForSize
;
181 return Attribute::ReadOnly
;
183 return Attribute::SExt
;
185 return Attribute::StructRet
;
187 return Attribute::UWTable
;
189 return Attribute::ZExt
;
191 return Attribute::InReg
;
193 return Attribute::SanitizeThread
;
194 case SanitizeAddress
:
195 return Attribute::SanitizeAddress
;
197 return Attribute::SanitizeMemory
;
199 return Attribute::NonLazyBind
;
201 return Attribute::OptimizeNone
;
203 return Attribute::ReturnsTwice
;
205 report_fatal_error("bad AttributeKind");
208 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr
, unsigned Index
,
209 LLVMRustAttribute RustAttr
) {
210 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
211 Attribute Attr
= Attribute::get(Call
->getContext(), fromRust(RustAttr
));
212 Call
.addAttribute(Index
, Attr
);
215 extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr
,
218 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
220 B
.addAlignmentAttr(Bytes
);
221 Call
.setAttributes(Call
.getAttributes().addAttributes(
222 Call
->getContext(), Index
, B
));
225 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr
,
228 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
230 B
.addDereferenceableAttr(Bytes
);
231 Call
.setAttributes(Call
.getAttributes().addAttributes(
232 Call
->getContext(), Index
, B
));
235 extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr
,
238 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
240 B
.addDereferenceableOrNullAttr(Bytes
);
241 Call
.setAttributes(Call
.getAttributes().addAttributes(
242 Call
->getContext(), Index
, B
));
245 extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr
, unsigned Index
,
247 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
248 #if LLVM_VERSION_GE(9, 0)
249 Attribute Attr
= Attribute::getWithByValType(Call
->getContext(), unwrap(Ty
));
251 Attribute Attr
= Attribute::get(Call
->getContext(), Attribute::ByVal
);
253 Call
.addAttribute(Index
, Attr
);
256 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn
, unsigned Index
,
257 LLVMRustAttribute RustAttr
) {
258 Function
*A
= unwrap
<Function
>(Fn
);
259 Attribute Attr
= Attribute::get(A
->getContext(), fromRust(RustAttr
));
261 A
->addAttributes(Index
, B
);
264 extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn
,
267 Function
*A
= unwrap
<Function
>(Fn
);
269 B
.addAlignmentAttr(Bytes
);
270 A
->addAttributes(Index
, B
);
273 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn
, unsigned Index
,
275 Function
*A
= unwrap
<Function
>(Fn
);
277 B
.addDereferenceableAttr(Bytes
);
278 A
->addAttributes(Index
, B
);
281 extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn
,
284 Function
*A
= unwrap
<Function
>(Fn
);
286 B
.addDereferenceableOrNullAttr(Bytes
);
287 A
->addAttributes(Index
, B
);
290 extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn
, unsigned Index
,
292 Function
*F
= unwrap
<Function
>(Fn
);
293 #if LLVM_VERSION_GE(9, 0)
294 Attribute Attr
= Attribute::getWithByValType(F
->getContext(), unwrap(Ty
));
296 Attribute Attr
= Attribute::get(F
->getContext(), Attribute::ByVal
);
298 F
->addAttribute(Index
, Attr
);
301 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn
,
305 Function
*F
= unwrap
<Function
>(Fn
);
307 B
.addAttribute(Name
, Value
);
308 F
->addAttributes(Index
, B
);
311 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn
,
313 LLVMRustAttribute RustAttr
) {
314 Function
*F
= unwrap
<Function
>(Fn
);
315 Attribute Attr
= Attribute::get(F
->getContext(), fromRust(RustAttr
));
317 auto PAL
= F
->getAttributes();
318 auto PALNew
= PAL
.removeAttributes(F
->getContext(), Index
, B
);
319 F
->setAttributes(PALNew
);
322 // enable fpmath flag UnsafeAlgebra
323 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V
) {
324 if (auto I
= dyn_cast
<Instruction
>(unwrap
<Value
>(V
))) {
329 extern "C" LLVMValueRef
330 LLVMRustBuildAtomicLoad(LLVMBuilderRef B
, LLVMValueRef Source
, const char *Name
,
331 LLVMAtomicOrdering Order
) {
332 LoadInst
*LI
= new LoadInst(unwrap(Source
));
333 LI
->setAtomic(fromRust(Order
));
334 return wrap(unwrap(B
)->Insert(LI
, Name
));
337 extern "C" LLVMValueRef
LLVMRustBuildAtomicStore(LLVMBuilderRef B
,
340 LLVMAtomicOrdering Order
) {
341 StoreInst
*SI
= new StoreInst(unwrap(V
), unwrap(Target
));
342 SI
->setAtomic(fromRust(Order
));
343 return wrap(unwrap(B
)->Insert(SI
));
346 extern "C" LLVMValueRef
347 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B
, LLVMValueRef Target
,
348 LLVMValueRef Old
, LLVMValueRef Source
,
349 LLVMAtomicOrdering Order
,
350 LLVMAtomicOrdering FailureOrder
, LLVMBool Weak
) {
351 AtomicCmpXchgInst
*ACXI
= unwrap(B
)->CreateAtomicCmpXchg(
352 unwrap(Target
), unwrap(Old
), unwrap(Source
), fromRust(Order
),
353 fromRust(FailureOrder
));
358 enum class LLVMRustSynchronizationScope
{
364 static SyncScope::ID
fromRust(LLVMRustSynchronizationScope Scope
) {
366 case LLVMRustSynchronizationScope::SingleThread
:
367 return SyncScope::SingleThread
;
368 case LLVMRustSynchronizationScope::CrossThread
:
369 return SyncScope::System
;
371 report_fatal_error("bad SynchronizationScope.");
375 extern "C" LLVMValueRef
376 LLVMRustBuildAtomicFence(LLVMBuilderRef B
, LLVMAtomicOrdering Order
,
377 LLVMRustSynchronizationScope Scope
) {
378 return wrap(unwrap(B
)->CreateFence(fromRust(Order
), fromRust(Scope
)));
381 enum class LLVMRustAsmDialect
{
387 static InlineAsm::AsmDialect
fromRust(LLVMRustAsmDialect Dialect
) {
389 case LLVMRustAsmDialect::Att
:
390 return InlineAsm::AD_ATT
;
391 case LLVMRustAsmDialect::Intel
:
392 return InlineAsm::AD_Intel
;
394 report_fatal_error("bad AsmDialect.");
398 extern "C" LLVMValueRef
LLVMRustInlineAsm(LLVMTypeRef Ty
, char *AsmString
,
400 LLVMBool HasSideEffects
,
401 LLVMBool IsAlignStack
,
402 LLVMRustAsmDialect Dialect
) {
403 return wrap(InlineAsm::get(unwrap
<FunctionType
>(Ty
), AsmString
, Constraints
,
404 HasSideEffects
, IsAlignStack
, fromRust(Dialect
)));
407 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty
,
409 return InlineAsm::Verify(unwrap
<FunctionType
>(Ty
), Constraints
);
412 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M
, const char *Asm
) {
413 unwrap(M
)->appendModuleInlineAsm(StringRef(Asm
));
416 typedef DIBuilder
*LLVMRustDIBuilderRef
;
418 template <typename DIT
> DIT
*unwrapDIPtr(LLVMMetadataRef Ref
) {
419 return (DIT
*)(Ref
? unwrap
<MDNode
>(Ref
) : nullptr);
422 #define DIDescriptor DIScope
423 #define DIArray DINodeArray
424 #define unwrapDI unwrapDIPtr
426 // These values **must** match debuginfo::DIFlags! They also *happen*
427 // to match LLVM, but that isn't required as we do giant sets of
428 // matching below. The value shouldn't be directly passed to LLVM.
429 enum class LLVMRustDIFlags
: uint32_t {
434 FlagFwdDecl
= (1 << 2),
435 FlagAppleBlock
= (1 << 3),
436 FlagBlockByrefStruct
= (1 << 4),
437 FlagVirtual
= (1 << 5),
438 FlagArtificial
= (1 << 6),
439 FlagExplicit
= (1 << 7),
440 FlagPrototyped
= (1 << 8),
441 FlagObjcClassComplete
= (1 << 9),
442 FlagObjectPointer
= (1 << 10),
443 FlagVector
= (1 << 11),
444 FlagStaticMember
= (1 << 12),
445 FlagLValueReference
= (1 << 13),
446 FlagRValueReference
= (1 << 14),
447 FlagExternalTypeRef
= (1 << 15),
448 FlagIntroducedVirtual
= (1 << 18),
449 FlagBitField
= (1 << 19),
450 FlagNoReturn
= (1 << 20),
451 // Do not add values that are not supported by the minimum LLVM
452 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
455 inline LLVMRustDIFlags
operator&(LLVMRustDIFlags A
, LLVMRustDIFlags B
) {
456 return static_cast<LLVMRustDIFlags
>(static_cast<uint32_t>(A
) &
457 static_cast<uint32_t>(B
));
460 inline LLVMRustDIFlags
operator|(LLVMRustDIFlags A
, LLVMRustDIFlags B
) {
461 return static_cast<LLVMRustDIFlags
>(static_cast<uint32_t>(A
) |
462 static_cast<uint32_t>(B
));
465 inline LLVMRustDIFlags
&operator|=(LLVMRustDIFlags
&A
, LLVMRustDIFlags B
) {
469 inline bool isSet(LLVMRustDIFlags F
) { return F
!= LLVMRustDIFlags::FlagZero
; }
471 inline LLVMRustDIFlags
visibility(LLVMRustDIFlags F
) {
472 return static_cast<LLVMRustDIFlags
>(static_cast<uint32_t>(F
) & 0x3);
475 static DINode::DIFlags
fromRust(LLVMRustDIFlags Flags
) {
476 DINode::DIFlags Result
= DINode::DIFlags::FlagZero
;
478 switch (visibility(Flags
)) {
479 case LLVMRustDIFlags::FlagPrivate
:
480 Result
|= DINode::DIFlags::FlagPrivate
;
482 case LLVMRustDIFlags::FlagProtected
:
483 Result
|= DINode::DIFlags::FlagProtected
;
485 case LLVMRustDIFlags::FlagPublic
:
486 Result
|= DINode::DIFlags::FlagPublic
;
489 // The rest are handled below
493 if (isSet(Flags
& LLVMRustDIFlags::FlagFwdDecl
)) {
494 Result
|= DINode::DIFlags::FlagFwdDecl
;
496 if (isSet(Flags
& LLVMRustDIFlags::FlagAppleBlock
)) {
497 Result
|= DINode::DIFlags::FlagAppleBlock
;
499 #if LLVM_VERSION_LT(10, 0)
500 if (isSet(Flags
& LLVMRustDIFlags::FlagBlockByrefStruct
)) {
501 Result
|= DINode::DIFlags::FlagBlockByrefStruct
;
504 if (isSet(Flags
& LLVMRustDIFlags::FlagVirtual
)) {
505 Result
|= DINode::DIFlags::FlagVirtual
;
507 if (isSet(Flags
& LLVMRustDIFlags::FlagArtificial
)) {
508 Result
|= DINode::DIFlags::FlagArtificial
;
510 if (isSet(Flags
& LLVMRustDIFlags::FlagExplicit
)) {
511 Result
|= DINode::DIFlags::FlagExplicit
;
513 if (isSet(Flags
& LLVMRustDIFlags::FlagPrototyped
)) {
514 Result
|= DINode::DIFlags::FlagPrototyped
;
516 if (isSet(Flags
& LLVMRustDIFlags::FlagObjcClassComplete
)) {
517 Result
|= DINode::DIFlags::FlagObjcClassComplete
;
519 if (isSet(Flags
& LLVMRustDIFlags::FlagObjectPointer
)) {
520 Result
|= DINode::DIFlags::FlagObjectPointer
;
522 if (isSet(Flags
& LLVMRustDIFlags::FlagVector
)) {
523 Result
|= DINode::DIFlags::FlagVector
;
525 if (isSet(Flags
& LLVMRustDIFlags::FlagStaticMember
)) {
526 Result
|= DINode::DIFlags::FlagStaticMember
;
528 if (isSet(Flags
& LLVMRustDIFlags::FlagLValueReference
)) {
529 Result
|= DINode::DIFlags::FlagLValueReference
;
531 if (isSet(Flags
& LLVMRustDIFlags::FlagRValueReference
)) {
532 Result
|= DINode::DIFlags::FlagRValueReference
;
534 if (isSet(Flags
& LLVMRustDIFlags::FlagIntroducedVirtual
)) {
535 Result
|= DINode::DIFlags::FlagIntroducedVirtual
;
537 if (isSet(Flags
& LLVMRustDIFlags::FlagBitField
)) {
538 Result
|= DINode::DIFlags::FlagBitField
;
540 if (isSet(Flags
& LLVMRustDIFlags::FlagNoReturn
)) {
541 Result
|= DINode::DIFlags::FlagNoReturn
;
547 // These values **must** match debuginfo::DISPFlags! They also *happen*
548 // to match LLVM, but that isn't required as we do giant sets of
549 // matching below. The value shouldn't be directly passed to LLVM.
550 enum class LLVMRustDISPFlags
: uint32_t {
553 SPFlagPureVirtual
= 2,
554 SPFlagLocalToUnit
= (1 << 2),
555 SPFlagDefinition
= (1 << 3),
556 SPFlagOptimized
= (1 << 4),
557 SPFlagMainSubprogram
= (1 << 5),
558 // Do not add values that are not supported by the minimum LLVM
559 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
560 // (In LLVM < 8, createFunction supported these as separate bool arguments.)
563 inline LLVMRustDISPFlags
operator&(LLVMRustDISPFlags A
, LLVMRustDISPFlags B
) {
564 return static_cast<LLVMRustDISPFlags
>(static_cast<uint32_t>(A
) &
565 static_cast<uint32_t>(B
));
568 inline LLVMRustDISPFlags
operator|(LLVMRustDISPFlags A
, LLVMRustDISPFlags B
) {
569 return static_cast<LLVMRustDISPFlags
>(static_cast<uint32_t>(A
) |
570 static_cast<uint32_t>(B
));
573 inline LLVMRustDISPFlags
&operator|=(LLVMRustDISPFlags
&A
, LLVMRustDISPFlags B
) {
577 inline bool isSet(LLVMRustDISPFlags F
) { return F
!= LLVMRustDISPFlags::SPFlagZero
; }
579 inline LLVMRustDISPFlags
virtuality(LLVMRustDISPFlags F
) {
580 return static_cast<LLVMRustDISPFlags
>(static_cast<uint32_t>(F
) & 0x3);
583 #if LLVM_VERSION_GE(8, 0)
584 static DISubprogram::DISPFlags
fromRust(LLVMRustDISPFlags SPFlags
) {
585 DISubprogram::DISPFlags Result
= DISubprogram::DISPFlags::SPFlagZero
;
587 switch (virtuality(SPFlags
)) {
588 case LLVMRustDISPFlags::SPFlagVirtual
:
589 Result
|= DISubprogram::DISPFlags::SPFlagVirtual
;
591 case LLVMRustDISPFlags::SPFlagPureVirtual
:
592 Result
|= DISubprogram::DISPFlags::SPFlagPureVirtual
;
595 // The rest are handled below
599 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagLocalToUnit
)) {
600 Result
|= DISubprogram::DISPFlags::SPFlagLocalToUnit
;
602 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagDefinition
)) {
603 Result
|= DISubprogram::DISPFlags::SPFlagDefinition
;
605 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagOptimized
)) {
606 Result
|= DISubprogram::DISPFlags::SPFlagOptimized
;
608 #if LLVM_VERSION_GE(9, 0)
609 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagMainSubprogram
)) {
610 Result
|= DISubprogram::DISPFlags::SPFlagMainSubprogram
;
618 enum class LLVMRustDebugEmissionKind
{
624 static DICompileUnit::DebugEmissionKind
fromRust(LLVMRustDebugEmissionKind Kind
) {
626 case LLVMRustDebugEmissionKind::NoDebug
:
627 return DICompileUnit::DebugEmissionKind::NoDebug
;
628 case LLVMRustDebugEmissionKind::FullDebug
:
629 return DICompileUnit::DebugEmissionKind::FullDebug
;
630 case LLVMRustDebugEmissionKind::LineTablesOnly
:
631 return DICompileUnit::DebugEmissionKind::LineTablesOnly
;
633 report_fatal_error("bad DebugEmissionKind.");
637 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
638 return DEBUG_METADATA_VERSION
;
641 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR
; }
643 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR
; }
645 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M
, const char *Name
,
647 unwrap(M
)->addModuleFlag(Module::Warning
, Name
, Value
);
650 extern "C" LLVMValueRef
LLVMRustMetadataAsValue(LLVMContextRef C
, LLVMMetadataRef MD
) {
651 return wrap(MetadataAsValue::get(*unwrap(C
), unwrap(MD
)));
654 extern "C" LLVMRustDIBuilderRef
LLVMRustDIBuilderCreate(LLVMModuleRef M
) {
655 return new DIBuilder(*unwrap(M
));
658 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder
) {
662 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder
) {
666 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateCompileUnit(
667 LLVMRustDIBuilderRef Builder
, unsigned Lang
, LLVMMetadataRef FileRef
,
668 const char *Producer
, bool isOptimized
, const char *Flags
,
669 unsigned RuntimeVer
, const char *SplitName
,
670 LLVMRustDebugEmissionKind Kind
) {
671 auto *File
= unwrapDI
<DIFile
>(FileRef
);
673 return wrap(Builder
->createCompileUnit(Lang
, File
, Producer
, isOptimized
,
674 Flags
, RuntimeVer
, SplitName
,
678 extern "C" LLVMMetadataRef
679 LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder
, const char *Filename
,
680 const char *Directory
) {
681 return wrap(Builder
->createFile(Filename
, Directory
));
684 extern "C" LLVMMetadataRef
685 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder
,
686 LLVMMetadataRef File
,
687 LLVMMetadataRef ParameterTypes
) {
688 return wrap(Builder
->createSubroutineType(
689 DITypeRefArray(unwrap
<MDTuple
>(ParameterTypes
))));
692 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateFunction(
693 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
694 const char *LinkageName
, LLVMMetadataRef File
, unsigned LineNo
,
695 LLVMMetadataRef Ty
, unsigned ScopeLine
, LLVMRustDIFlags Flags
,
696 LLVMRustDISPFlags SPFlags
, LLVMValueRef Fn
, LLVMMetadataRef TParam
,
697 LLVMMetadataRef Decl
) {
698 DITemplateParameterArray TParams
=
699 DITemplateParameterArray(unwrap
<MDTuple
>(TParam
));
700 #if LLVM_VERSION_GE(8, 0)
701 DISubprogram::DISPFlags llvmSPFlags
= fromRust(SPFlags
);
702 DINode::DIFlags llvmFlags
= fromRust(Flags
);
703 #if LLVM_VERSION_LT(9, 0)
704 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagMainSubprogram
))
705 llvmFlags
|= DINode::DIFlags::FlagMainSubprogram
;
707 DISubprogram
*Sub
= Builder
->createFunction(
708 unwrapDI
<DIScope
>(Scope
), Name
, LinkageName
, unwrapDI
<DIFile
>(File
),
709 LineNo
, unwrapDI
<DISubroutineType
>(Ty
), ScopeLine
, llvmFlags
,
710 llvmSPFlags
, TParams
, unwrapDIPtr
<DISubprogram
>(Decl
));
712 bool IsLocalToUnit
= isSet(SPFlags
& LLVMRustDISPFlags::SPFlagLocalToUnit
);
713 bool IsDefinition
= isSet(SPFlags
& LLVMRustDISPFlags::SPFlagDefinition
);
714 bool IsOptimized
= isSet(SPFlags
& LLVMRustDISPFlags::SPFlagOptimized
);
715 DINode::DIFlags llvmFlags
= fromRust(Flags
);
716 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagMainSubprogram
))
717 llvmFlags
|= DINode::DIFlags::FlagMainSubprogram
;
718 DISubprogram
*Sub
= Builder
->createFunction(
719 unwrapDI
<DIScope
>(Scope
), Name
, LinkageName
, unwrapDI
<DIFile
>(File
),
720 LineNo
, unwrapDI
<DISubroutineType
>(Ty
), IsLocalToUnit
, IsDefinition
,
721 ScopeLine
, llvmFlags
, IsOptimized
, TParams
,
722 unwrapDIPtr
<DISubprogram
>(Decl
));
724 unwrap
<Function
>(Fn
)->setSubprogram(Sub
);
728 extern "C" LLVMMetadataRef
729 LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder
, const char *Name
,
730 uint64_t SizeInBits
, uint32_t AlignInBits
,
732 return wrap(Builder
->createBasicType(Name
, SizeInBits
, Encoding
));
735 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreatePointerType(
736 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef PointeeTy
,
737 uint64_t SizeInBits
, uint32_t AlignInBits
, const char *Name
) {
738 return wrap(Builder
->createPointerType(unwrapDI
<DIType
>(PointeeTy
),
739 SizeInBits
, AlignInBits
,
740 /* DWARFAddressSpace */ None
,
744 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateStructType(
745 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
746 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
747 uint32_t AlignInBits
, LLVMRustDIFlags Flags
,
748 LLVMMetadataRef DerivedFrom
, LLVMMetadataRef Elements
,
749 unsigned RunTimeLang
, LLVMMetadataRef VTableHolder
,
750 const char *UniqueId
) {
751 return wrap(Builder
->createStructType(
752 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
753 SizeInBits
, AlignInBits
, fromRust(Flags
), unwrapDI
<DIType
>(DerivedFrom
),
754 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), RunTimeLang
,
755 unwrapDI
<DIType
>(VTableHolder
), UniqueId
));
758 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateVariantPart(
759 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
760 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
761 uint32_t AlignInBits
, LLVMRustDIFlags Flags
, LLVMMetadataRef Discriminator
,
762 LLVMMetadataRef Elements
, const char *UniqueId
) {
763 return wrap(Builder
->createVariantPart(
764 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
765 SizeInBits
, AlignInBits
, fromRust(Flags
), unwrapDI
<DIDerivedType
>(Discriminator
),
766 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), UniqueId
));
769 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateMemberType(
770 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
771 LLVMMetadataRef File
, unsigned LineNo
, uint64_t SizeInBits
,
772 uint32_t AlignInBits
, uint64_t OffsetInBits
, LLVMRustDIFlags Flags
,
773 LLVMMetadataRef Ty
) {
774 return wrap(Builder
->createMemberType(unwrapDI
<DIDescriptor
>(Scope
), Name
,
775 unwrapDI
<DIFile
>(File
), LineNo
,
776 SizeInBits
, AlignInBits
, OffsetInBits
,
777 fromRust(Flags
), unwrapDI
<DIType
>(Ty
)));
780 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateVariantMemberType(
781 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
782 const char *Name
, LLVMMetadataRef File
, unsigned LineNo
, uint64_t SizeInBits
,
783 uint32_t AlignInBits
, uint64_t OffsetInBits
, LLVMValueRef Discriminant
,
784 LLVMRustDIFlags Flags
, LLVMMetadataRef Ty
) {
785 llvm::ConstantInt
* D
= nullptr;
787 D
= unwrap
<llvm::ConstantInt
>(Discriminant
);
789 return wrap(Builder
->createVariantMemberType(unwrapDI
<DIDescriptor
>(Scope
), Name
,
790 unwrapDI
<DIFile
>(File
), LineNo
,
791 SizeInBits
, AlignInBits
, OffsetInBits
, D
,
792 fromRust(Flags
), unwrapDI
<DIType
>(Ty
)));
795 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateLexicalBlock(
796 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
797 LLVMMetadataRef File
, unsigned Line
, unsigned Col
) {
798 return wrap(Builder
->createLexicalBlock(unwrapDI
<DIDescriptor
>(Scope
),
799 unwrapDI
<DIFile
>(File
), Line
, Col
));
802 extern "C" LLVMMetadataRef
803 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder
,
804 LLVMMetadataRef Scope
,
805 LLVMMetadataRef File
) {
806 return wrap(Builder
->createLexicalBlockFile(unwrapDI
<DIDescriptor
>(Scope
),
807 unwrapDI
<DIFile
>(File
)));
810 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateStaticVariable(
811 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Context
, const char *Name
,
812 const char *LinkageName
, LLVMMetadataRef File
, unsigned LineNo
,
813 LLVMMetadataRef Ty
, bool IsLocalToUnit
, LLVMValueRef V
,
814 LLVMMetadataRef Decl
= nullptr, uint32_t AlignInBits
= 0) {
815 llvm::GlobalVariable
*InitVal
= cast
<llvm::GlobalVariable
>(unwrap(V
));
817 llvm::DIExpression
*InitExpr
= nullptr;
818 if (llvm::ConstantInt
*IntVal
= llvm::dyn_cast
<llvm::ConstantInt
>(InitVal
)) {
819 InitExpr
= Builder
->createConstantValueExpression(
820 IntVal
->getValue().getSExtValue());
821 } else if (llvm::ConstantFP
*FPVal
=
822 llvm::dyn_cast
<llvm::ConstantFP
>(InitVal
)) {
823 InitExpr
= Builder
->createConstantValueExpression(
824 FPVal
->getValueAPF().bitcastToAPInt().getZExtValue());
827 llvm::DIGlobalVariableExpression
*VarExpr
= Builder
->createGlobalVariableExpression(
828 unwrapDI
<DIDescriptor
>(Context
), Name
, LinkageName
,
829 unwrapDI
<DIFile
>(File
), LineNo
, unwrapDI
<DIType
>(Ty
), IsLocalToUnit
,
830 #if LLVM_VERSION_GE(10, 0)
831 /* isDefined */ true,
833 InitExpr
, unwrapDIPtr
<MDNode
>(Decl
),
834 #if LLVM_VERSION_GE(8, 0)
835 /* templateParams */ nullptr,
839 InitVal
->setMetadata("dbg", VarExpr
);
841 return wrap(VarExpr
);
844 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateVariable(
845 LLVMRustDIBuilderRef Builder
, unsigned Tag
, LLVMMetadataRef Scope
,
846 const char *Name
, LLVMMetadataRef File
, unsigned LineNo
,
847 LLVMMetadataRef Ty
, bool AlwaysPreserve
, LLVMRustDIFlags Flags
,
848 unsigned ArgNo
, uint32_t AlignInBits
) {
849 if (Tag
== 0x100) { // DW_TAG_auto_variable
850 return wrap(Builder
->createAutoVariable(
851 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNo
,
852 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, fromRust(Flags
), AlignInBits
));
854 return wrap(Builder
->createParameterVariable(
855 unwrapDI
<DIDescriptor
>(Scope
), Name
, ArgNo
, unwrapDI
<DIFile
>(File
),
856 LineNo
, unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, fromRust(Flags
)));
860 extern "C" LLVMMetadataRef
861 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder
, uint64_t Size
,
862 uint32_t AlignInBits
, LLVMMetadataRef Ty
,
863 LLVMMetadataRef Subscripts
) {
865 Builder
->createArrayType(Size
, AlignInBits
, unwrapDI
<DIType
>(Ty
),
866 DINodeArray(unwrapDI
<MDTuple
>(Subscripts
))));
869 extern "C" LLVMMetadataRef
870 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder
, int64_t Lo
,
872 return wrap(Builder
->getOrCreateSubrange(Lo
, Count
));
875 extern "C" LLVMMetadataRef
876 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder
,
877 LLVMMetadataRef
*Ptr
, unsigned Count
) {
878 Metadata
**DataValue
= unwrap(Ptr
);
880 Builder
->getOrCreateArray(ArrayRef
<Metadata
*>(DataValue
, Count
)).get());
883 extern "C" LLVMValueRef
LLVMRustDIBuilderInsertDeclareAtEnd(
884 LLVMRustDIBuilderRef Builder
, LLVMValueRef V
, LLVMMetadataRef VarInfo
,
885 int64_t *AddrOps
, unsigned AddrOpsCount
, LLVMValueRef DL
,
886 LLVMBasicBlockRef InsertAtEnd
) {
887 return wrap(Builder
->insertDeclare(
888 unwrap(V
), unwrap
<DILocalVariable
>(VarInfo
),
889 Builder
->createExpression(llvm::ArrayRef
<int64_t>(AddrOps
, AddrOpsCount
)),
890 DebugLoc(cast
<MDNode
>(unwrap
<MetadataAsValue
>(DL
)->getMetadata())),
891 unwrap(InsertAtEnd
)));
894 extern "C" LLVMMetadataRef
895 LLVMRustDIBuilderCreateEnumerator(LLVMRustDIBuilderRef Builder
,
896 const char *Name
, uint64_t Val
) {
897 return wrap(Builder
->createEnumerator(Name
, Val
));
900 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateEnumerationType(
901 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
902 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
903 uint32_t AlignInBits
, LLVMMetadataRef Elements
,
904 LLVMMetadataRef ClassTy
, bool IsScoped
) {
905 return wrap(Builder
->createEnumerationType(
906 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
907 SizeInBits
, AlignInBits
, DINodeArray(unwrapDI
<MDTuple
>(Elements
)),
908 unwrapDI
<DIType
>(ClassTy
), "", IsScoped
));
911 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateUnionType(
912 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
913 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
914 uint32_t AlignInBits
, LLVMRustDIFlags Flags
, LLVMMetadataRef Elements
,
915 unsigned RunTimeLang
, const char *UniqueId
) {
916 return wrap(Builder
->createUnionType(
917 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
918 SizeInBits
, AlignInBits
, fromRust(Flags
),
919 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), RunTimeLang
, UniqueId
));
922 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateTemplateTypeParameter(
923 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
924 LLVMMetadataRef Ty
, LLVMMetadataRef File
, unsigned LineNo
,
926 return wrap(Builder
->createTemplateTypeParameter(
927 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIType
>(Ty
)));
930 extern "C" LLVMMetadataRef
931 LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder
,
932 LLVMMetadataRef Scope
, const char *Name
,
933 LLVMMetadataRef File
, unsigned LineNo
) {
934 return wrap(Builder
->createNameSpace(
935 unwrapDI
<DIDescriptor
>(Scope
), Name
,
936 false // ExportSymbols (only relevant for C++ anonymous namespaces)
941 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder
,
942 LLVMMetadataRef CompositeTy
,
943 LLVMMetadataRef Elements
,
944 LLVMMetadataRef Params
) {
945 DICompositeType
*Tmp
= unwrapDI
<DICompositeType
>(CompositeTy
);
946 Builder
->replaceArrays(Tmp
, DINodeArray(unwrap
<MDTuple
>(Elements
)),
947 DINodeArray(unwrap
<MDTuple
>(Params
)));
950 extern "C" LLVMValueRef
951 LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef
, unsigned Line
,
952 unsigned Column
, LLVMMetadataRef Scope
,
953 LLVMMetadataRef InlinedAt
) {
954 LLVMContext
&Context
= *unwrap(ContextRef
);
956 DebugLoc debug_loc
= DebugLoc::get(Line
, Column
, unwrapDIPtr
<MDNode
>(Scope
),
957 unwrapDIPtr
<MDNode
>(InlinedAt
));
959 return wrap(MetadataAsValue::get(Context
, debug_loc
.getAsMDNode()));
962 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
963 return dwarf::DW_OP_deref
;
966 extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
967 return dwarf::DW_OP_plus_uconst
;
970 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty
, RustStringRef Str
) {
971 RawRustStringOstream
OS(Str
);
972 unwrap
<llvm::Type
>(Ty
)->print(OS
);
975 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V
,
977 RawRustStringOstream
OS(Str
);
982 unwrap
<llvm::Value
>(V
)->getType()->print(OS
);
984 unwrap
<llvm::Value
>(V
)->print(OS
);
989 // Note that the two following functions look quite similar to the
990 // LLVMGetSectionName function. Sadly, it appears that this function only
991 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
992 // function provided by LLVM doesn't return the length, so we've created our own
993 // function which returns the length as well as the data pointer.
995 // For an example of this not returning a null terminated string, see
996 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
997 // branches explicitly creates a StringRef without a null terminator, and then
1000 inline section_iterator
*unwrap(LLVMSectionIteratorRef SI
) {
1001 return reinterpret_cast<section_iterator
*>(SI
);
1004 extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI
,
1006 #if LLVM_VERSION_GE(10, 0)
1007 auto NameOrErr
= (*unwrap(SI
))->getName();
1009 report_fatal_error(NameOrErr
.takeError());
1010 *Ptr
= NameOrErr
->data();
1011 return NameOrErr
->size();
1014 if (std::error_code EC
= (*unwrap(SI
))->getName(Ret
))
1015 report_fatal_error(EC
.message());
1021 // LLVMArrayType function does not support 64-bit ElementCount
1022 extern "C" LLVMTypeRef
LLVMRustArrayType(LLVMTypeRef ElementTy
,
1023 uint64_t ElementCount
) {
1024 return wrap(ArrayType::get(unwrap(ElementTy
), ElementCount
));
1027 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine
, LLVMTwineRef
)
1029 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T
, RustStringRef Str
) {
1030 RawRustStringOstream
OS(Str
);
1031 unwrap(T
)->print(OS
);
1034 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1035 LLVMDiagnosticInfoRef DI
, RustStringRef PassNameOut
,
1036 LLVMValueRef
*FunctionOut
, unsigned* Line
, unsigned* Column
,
1037 RustStringRef FilenameOut
, RustStringRef MessageOut
) {
1038 // Undefined to call this not on an optimization diagnostic!
1039 llvm::DiagnosticInfoOptimizationBase
*Opt
=
1040 static_cast<llvm::DiagnosticInfoOptimizationBase
*>(unwrap(DI
));
1042 RawRustStringOstream
PassNameOS(PassNameOut
);
1043 PassNameOS
<< Opt
->getPassName();
1044 *FunctionOut
= wrap(&Opt
->getFunction());
1046 RawRustStringOstream
FilenameOS(FilenameOut
);
1047 DiagnosticLocation loc
= Opt
->getLocation();
1048 if (loc
.isValid()) {
1049 *Line
= loc
.getLine();
1050 *Column
= loc
.getColumn();
1051 #if LLVM_VERSION_GE(8, 0)
1052 FilenameOS
<< loc
.getAbsolutePath();
1054 FilenameOS
<< loc
.getFilename();
1058 RawRustStringOstream
MessageOS(MessageOut
);
1059 MessageOS
<< Opt
->getMsg();
1063 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI
, unsigned *CookieOut
,
1064 LLVMTwineRef
*MessageOut
,
1065 LLVMValueRef
*InstructionOut
) {
1066 // Undefined to call this not on an inline assembly diagnostic!
1067 llvm::DiagnosticInfoInlineAsm
*IA
=
1068 static_cast<llvm::DiagnosticInfoInlineAsm
*>(unwrap(DI
));
1070 *CookieOut
= IA
->getLocCookie();
1071 *MessageOut
= wrap(&IA
->getMsgStr());
1072 *InstructionOut
= wrap(IA
->getInstruction());
1075 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI
,
1076 RustStringRef Str
) {
1077 RawRustStringOstream
OS(Str
);
1078 DiagnosticPrinterRawOStream
DP(OS
);
1079 unwrap(DI
)->print(DP
);
1082 enum class LLVMRustDiagnosticKind
{
1086 DebugMetadataVersion
,
1089 OptimizationRemarkMissed
,
1090 OptimizationRemarkAnalysis
,
1091 OptimizationRemarkAnalysisFPCommute
,
1092 OptimizationRemarkAnalysisAliasing
,
1093 OptimizationRemarkOther
,
1094 OptimizationFailure
,
1099 static LLVMRustDiagnosticKind
toRust(DiagnosticKind Kind
) {
1102 return LLVMRustDiagnosticKind::InlineAsm
;
1104 return LLVMRustDiagnosticKind::StackSize
;
1105 case DK_DebugMetadataVersion
:
1106 return LLVMRustDiagnosticKind::DebugMetadataVersion
;
1107 case DK_SampleProfile
:
1108 return LLVMRustDiagnosticKind::SampleProfile
;
1109 case DK_OptimizationRemark
:
1110 return LLVMRustDiagnosticKind::OptimizationRemark
;
1111 case DK_OptimizationRemarkMissed
:
1112 return LLVMRustDiagnosticKind::OptimizationRemarkMissed
;
1113 case DK_OptimizationRemarkAnalysis
:
1114 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis
;
1115 case DK_OptimizationRemarkAnalysisFPCommute
:
1116 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute
;
1117 case DK_OptimizationRemarkAnalysisAliasing
:
1118 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing
;
1120 return LLVMRustDiagnosticKind::PGOProfile
;
1122 return LLVMRustDiagnosticKind::Linker
;
1124 return (Kind
>= DK_FirstRemark
&& Kind
<= DK_LastRemark
)
1125 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1126 : LLVMRustDiagnosticKind::Other
;
1130 extern "C" LLVMRustDiagnosticKind
1131 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI
) {
1132 return toRust((DiagnosticKind
)unwrap(DI
)->getKind());
1134 // This is kept distinct from LLVMGetTypeKind, because when
1135 // a new type kind is added, the Rust-side enum must be
1136 // updated or UB will result.
1137 extern "C" LLVMTypeKind
LLVMRustGetTypeKind(LLVMTypeRef Ty
) {
1138 switch (unwrap(Ty
)->getTypeID()) {
1139 case Type::VoidTyID
:
1140 return LLVMVoidTypeKind
;
1141 case Type::HalfTyID
:
1142 return LLVMHalfTypeKind
;
1143 case Type::FloatTyID
:
1144 return LLVMFloatTypeKind
;
1145 case Type::DoubleTyID
:
1146 return LLVMDoubleTypeKind
;
1147 case Type::X86_FP80TyID
:
1148 return LLVMX86_FP80TypeKind
;
1149 case Type::FP128TyID
:
1150 return LLVMFP128TypeKind
;
1151 case Type::PPC_FP128TyID
:
1152 return LLVMPPC_FP128TypeKind
;
1153 case Type::LabelTyID
:
1154 return LLVMLabelTypeKind
;
1155 case Type::MetadataTyID
:
1156 return LLVMMetadataTypeKind
;
1157 case Type::IntegerTyID
:
1158 return LLVMIntegerTypeKind
;
1159 case Type::FunctionTyID
:
1160 return LLVMFunctionTypeKind
;
1161 case Type::StructTyID
:
1162 return LLVMStructTypeKind
;
1163 case Type::ArrayTyID
:
1164 return LLVMArrayTypeKind
;
1165 case Type::PointerTyID
:
1166 return LLVMPointerTypeKind
;
1167 case Type::VectorTyID
:
1168 return LLVMVectorTypeKind
;
1169 case Type::X86_MMXTyID
:
1170 return LLVMX86_MMXTypeKind
;
1171 case Type::TokenTyID
:
1172 return LLVMTokenTypeKind
;
1174 report_fatal_error("Unhandled TypeID.");
1177 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic
, LLVMSMDiagnosticRef
)
1179 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1180 LLVMContextRef C
, LLVMContext::InlineAsmDiagHandlerTy H
, void *CX
) {
1181 unwrap(C
)->setInlineAsmDiagnosticHandler(H
, CX
);
1184 extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef D
,
1185 RustStringRef Str
) {
1186 RawRustStringOstream
OS(Str
);
1187 unwrap(D
)->print("", OS
);
1190 extern "C" LLVMValueRef
LLVMRustBuildCleanupPad(LLVMBuilderRef B
,
1191 LLVMValueRef ParentPad
,
1193 LLVMValueRef
*LLArgs
,
1195 Value
**Args
= unwrap(LLArgs
);
1196 if (ParentPad
== nullptr) {
1197 Type
*Ty
= Type::getTokenTy(unwrap(B
)->getContext());
1198 ParentPad
= wrap(Constant::getNullValue(Ty
));
1200 return wrap(unwrap(B
)->CreateCleanupPad(
1201 unwrap(ParentPad
), ArrayRef
<Value
*>(Args
, ArgCount
), Name
));
1204 extern "C" LLVMValueRef
LLVMRustBuildCleanupRet(LLVMBuilderRef B
,
1205 LLVMValueRef CleanupPad
,
1206 LLVMBasicBlockRef UnwindBB
) {
1207 CleanupPadInst
*Inst
= cast
<CleanupPadInst
>(unwrap(CleanupPad
));
1208 return wrap(unwrap(B
)->CreateCleanupRet(Inst
, unwrap(UnwindBB
)));
1211 extern "C" LLVMValueRef
1212 LLVMRustBuildCatchPad(LLVMBuilderRef B
, LLVMValueRef ParentPad
,
1213 unsigned ArgCount
, LLVMValueRef
*LLArgs
, const char *Name
) {
1214 Value
**Args
= unwrap(LLArgs
);
1215 return wrap(unwrap(B
)->CreateCatchPad(
1216 unwrap(ParentPad
), ArrayRef
<Value
*>(Args
, ArgCount
), Name
));
1219 extern "C" LLVMValueRef
LLVMRustBuildCatchRet(LLVMBuilderRef B
,
1221 LLVMBasicBlockRef BB
) {
1222 return wrap(unwrap(B
)->CreateCatchRet(cast
<CatchPadInst
>(unwrap(Pad
)),
1226 extern "C" LLVMValueRef
LLVMRustBuildCatchSwitch(LLVMBuilderRef B
,
1227 LLVMValueRef ParentPad
,
1228 LLVMBasicBlockRef BB
,
1229 unsigned NumHandlers
,
1231 if (ParentPad
== nullptr) {
1232 Type
*Ty
= Type::getTokenTy(unwrap(B
)->getContext());
1233 ParentPad
= wrap(Constant::getNullValue(Ty
));
1235 return wrap(unwrap(B
)->CreateCatchSwitch(unwrap(ParentPad
), unwrap(BB
),
1236 NumHandlers
, Name
));
1239 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef
,
1240 LLVMBasicBlockRef Handler
) {
1241 Value
*CatchSwitch
= unwrap(CatchSwitchRef
);
1242 cast
<CatchSwitchInst
>(CatchSwitch
)->addHandler(unwrap(Handler
));
1245 extern "C" OperandBundleDef
*LLVMRustBuildOperandBundleDef(const char *Name
,
1246 LLVMValueRef
*Inputs
,
1247 unsigned NumInputs
) {
1248 return new OperandBundleDef(Name
, makeArrayRef(unwrap(Inputs
), NumInputs
));
1251 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef
*Bundle
) {
1255 extern "C" LLVMValueRef
LLVMRustBuildCall(LLVMBuilderRef B
, LLVMValueRef Fn
,
1256 LLVMValueRef
*Args
, unsigned NumArgs
,
1257 OperandBundleDef
*Bundle
,
1259 unsigned Len
= Bundle
? 1 : 0;
1260 ArrayRef
<OperandBundleDef
> Bundles
= makeArrayRef(Bundle
, Len
);
1261 return wrap(unwrap(B
)->CreateCall(
1262 unwrap(Fn
), makeArrayRef(unwrap(Args
), NumArgs
), Bundles
, Name
));
1265 extern "C" LLVMValueRef
LLVMRustBuildMemCpy(LLVMBuilderRef B
,
1266 LLVMValueRef Dst
, unsigned DstAlign
,
1267 LLVMValueRef Src
, unsigned SrcAlign
,
1268 LLVMValueRef Size
, bool IsVolatile
) {
1269 #if LLVM_VERSION_GE(10, 0)
1270 return wrap(unwrap(B
)->CreateMemCpy(
1271 unwrap(Dst
), MaybeAlign(DstAlign
),
1272 unwrap(Src
), MaybeAlign(SrcAlign
),
1273 unwrap(Size
), IsVolatile
));
1275 return wrap(unwrap(B
)->CreateMemCpy(
1276 unwrap(Dst
), DstAlign
,
1277 unwrap(Src
), SrcAlign
,
1278 unwrap(Size
), IsVolatile
));
1282 extern "C" LLVMValueRef
LLVMRustBuildMemMove(LLVMBuilderRef B
,
1283 LLVMValueRef Dst
, unsigned DstAlign
,
1284 LLVMValueRef Src
, unsigned SrcAlign
,
1285 LLVMValueRef Size
, bool IsVolatile
) {
1286 #if LLVM_VERSION_GE(10, 0)
1287 return wrap(unwrap(B
)->CreateMemMove(
1288 unwrap(Dst
), MaybeAlign(DstAlign
),
1289 unwrap(Src
), MaybeAlign(SrcAlign
),
1290 unwrap(Size
), IsVolatile
));
1292 return wrap(unwrap(B
)->CreateMemMove(
1293 unwrap(Dst
), DstAlign
,
1294 unwrap(Src
), SrcAlign
,
1295 unwrap(Size
), IsVolatile
));
1299 extern "C" LLVMValueRef
1300 LLVMRustBuildInvoke(LLVMBuilderRef B
, LLVMValueRef Fn
, LLVMValueRef
*Args
,
1301 unsigned NumArgs
, LLVMBasicBlockRef Then
,
1302 LLVMBasicBlockRef Catch
, OperandBundleDef
*Bundle
,
1304 unsigned Len
= Bundle
? 1 : 0;
1305 ArrayRef
<OperandBundleDef
> Bundles
= makeArrayRef(Bundle
, Len
);
1306 return wrap(unwrap(B
)->CreateInvoke(unwrap(Fn
), unwrap(Then
), unwrap(Catch
),
1307 makeArrayRef(unwrap(Args
), NumArgs
),
1311 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B
,
1312 LLVMBasicBlockRef BB
) {
1313 auto Point
= unwrap(BB
)->getFirstInsertionPt();
1314 unwrap(B
)->SetInsertPoint(unwrap(BB
), Point
);
1317 extern "C" void LLVMRustSetComdat(LLVMModuleRef M
, LLVMValueRef V
,
1318 const char *Name
, size_t NameLen
) {
1319 Triple
TargetTriple(unwrap(M
)->getTargetTriple());
1320 GlobalObject
*GV
= unwrap
<GlobalObject
>(V
);
1321 if (!TargetTriple
.isOSBinFormatMachO()) {
1322 StringRef
NameRef(Name
, NameLen
);
1323 GV
->setComdat(unwrap(M
)->getOrInsertComdat(NameRef
));
1327 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V
) {
1328 GlobalObject
*GV
= unwrap
<GlobalObject
>(V
);
1329 GV
->setComdat(nullptr);
1332 enum class LLVMRustLinkage
{
1333 ExternalLinkage
= 0,
1334 AvailableExternallyLinkage
= 1,
1335 LinkOnceAnyLinkage
= 2,
1336 LinkOnceODRLinkage
= 3,
1339 AppendingLinkage
= 6,
1340 InternalLinkage
= 7,
1342 ExternalWeakLinkage
= 9,
1346 static LLVMRustLinkage
toRust(LLVMLinkage Linkage
) {
1348 case LLVMExternalLinkage
:
1349 return LLVMRustLinkage::ExternalLinkage
;
1350 case LLVMAvailableExternallyLinkage
:
1351 return LLVMRustLinkage::AvailableExternallyLinkage
;
1352 case LLVMLinkOnceAnyLinkage
:
1353 return LLVMRustLinkage::LinkOnceAnyLinkage
;
1354 case LLVMLinkOnceODRLinkage
:
1355 return LLVMRustLinkage::LinkOnceODRLinkage
;
1356 case LLVMWeakAnyLinkage
:
1357 return LLVMRustLinkage::WeakAnyLinkage
;
1358 case LLVMWeakODRLinkage
:
1359 return LLVMRustLinkage::WeakODRLinkage
;
1360 case LLVMAppendingLinkage
:
1361 return LLVMRustLinkage::AppendingLinkage
;
1362 case LLVMInternalLinkage
:
1363 return LLVMRustLinkage::InternalLinkage
;
1364 case LLVMPrivateLinkage
:
1365 return LLVMRustLinkage::PrivateLinkage
;
1366 case LLVMExternalWeakLinkage
:
1367 return LLVMRustLinkage::ExternalWeakLinkage
;
1368 case LLVMCommonLinkage
:
1369 return LLVMRustLinkage::CommonLinkage
;
1371 report_fatal_error("Invalid LLVMRustLinkage value!");
1375 static LLVMLinkage
fromRust(LLVMRustLinkage Linkage
) {
1377 case LLVMRustLinkage::ExternalLinkage
:
1378 return LLVMExternalLinkage
;
1379 case LLVMRustLinkage::AvailableExternallyLinkage
:
1380 return LLVMAvailableExternallyLinkage
;
1381 case LLVMRustLinkage::LinkOnceAnyLinkage
:
1382 return LLVMLinkOnceAnyLinkage
;
1383 case LLVMRustLinkage::LinkOnceODRLinkage
:
1384 return LLVMLinkOnceODRLinkage
;
1385 case LLVMRustLinkage::WeakAnyLinkage
:
1386 return LLVMWeakAnyLinkage
;
1387 case LLVMRustLinkage::WeakODRLinkage
:
1388 return LLVMWeakODRLinkage
;
1389 case LLVMRustLinkage::AppendingLinkage
:
1390 return LLVMAppendingLinkage
;
1391 case LLVMRustLinkage::InternalLinkage
:
1392 return LLVMInternalLinkage
;
1393 case LLVMRustLinkage::PrivateLinkage
:
1394 return LLVMPrivateLinkage
;
1395 case LLVMRustLinkage::ExternalWeakLinkage
:
1396 return LLVMExternalWeakLinkage
;
1397 case LLVMRustLinkage::CommonLinkage
:
1398 return LLVMCommonLinkage
;
1400 report_fatal_error("Invalid LLVMRustLinkage value!");
1403 extern "C" LLVMRustLinkage
LLVMRustGetLinkage(LLVMValueRef V
) {
1404 return toRust(LLVMGetLinkage(V
));
1407 extern "C" void LLVMRustSetLinkage(LLVMValueRef V
,
1408 LLVMRustLinkage RustLinkage
) {
1409 LLVMSetLinkage(V
, fromRust(RustLinkage
));
1412 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1413 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1414 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV
, bool sext
, uint64_t *high
, uint64_t *low
)
1416 auto C
= unwrap
<llvm::ConstantInt
>(CV
);
1417 if (C
->getBitWidth() > 128) { return false; }
1420 AP
= C
->getValue().sextOrSelf(128);
1422 AP
= C
->getValue().zextOrSelf(128);
1424 *low
= AP
.getLoBits(64).getZExtValue();
1425 *high
= AP
.getHiBits(64).getZExtValue();
1429 enum class LLVMRustVisibility
{
1435 static LLVMRustVisibility
toRust(LLVMVisibility Vis
) {
1437 case LLVMDefaultVisibility
:
1438 return LLVMRustVisibility::Default
;
1439 case LLVMHiddenVisibility
:
1440 return LLVMRustVisibility::Hidden
;
1441 case LLVMProtectedVisibility
:
1442 return LLVMRustVisibility::Protected
;
1444 report_fatal_error("Invalid LLVMRustVisibility value!");
1447 static LLVMVisibility
fromRust(LLVMRustVisibility Vis
) {
1449 case LLVMRustVisibility::Default
:
1450 return LLVMDefaultVisibility
;
1451 case LLVMRustVisibility::Hidden
:
1452 return LLVMHiddenVisibility
;
1453 case LLVMRustVisibility::Protected
:
1454 return LLVMProtectedVisibility
;
1456 report_fatal_error("Invalid LLVMRustVisibility value!");
1459 extern "C" LLVMRustVisibility
LLVMRustGetVisibility(LLVMValueRef V
) {
1460 return toRust(LLVMGetVisibility(V
));
1463 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1464 extern "C" LLVMValueRef
LLVMRustBuildIntCast(LLVMBuilderRef B
, LLVMValueRef Val
,
1465 LLVMTypeRef DestTy
, bool isSigned
) {
1466 return wrap(unwrap(B
)->CreateIntCast(unwrap(Val
), unwrap(DestTy
), isSigned
, ""));
1469 extern "C" void LLVMRustSetVisibility(LLVMValueRef V
,
1470 LLVMRustVisibility RustVisibility
) {
1471 LLVMSetVisibility(V
, fromRust(RustVisibility
));
1474 struct LLVMRustModuleBuffer
{
1478 extern "C" LLVMRustModuleBuffer
*
1479 LLVMRustModuleBufferCreate(LLVMModuleRef M
) {
1480 #if LLVM_VERSION_GE(10, 0)
1481 auto Ret
= std::make_unique
<LLVMRustModuleBuffer
>();
1483 auto Ret
= llvm::make_unique
<LLVMRustModuleBuffer
>();
1486 raw_string_ostream
OS(Ret
->data
);
1488 legacy::PassManager PM
;
1489 PM
.add(createBitcodeWriterPass(OS
));
1493 return Ret
.release();
1497 LLVMRustModuleBufferFree(LLVMRustModuleBuffer
*Buffer
) {
1501 extern "C" const void*
1502 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer
*Buffer
) {
1503 return Buffer
->data
.data();
1507 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer
*Buffer
) {
1508 return Buffer
->data
.length();
1512 LLVMRustModuleCost(LLVMModuleRef M
) {
1513 auto f
= unwrap(M
)->functions();
1514 return std::distance(std::begin(f
), std::end(f
));
1517 // Vector reductions:
1518 extern "C" LLVMValueRef
1519 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B
, LLVMValueRef Acc
, LLVMValueRef Src
) {
1520 return wrap(unwrap(B
)->CreateFAddReduce(unwrap(Acc
),unwrap(Src
)));
1522 extern "C" LLVMValueRef
1523 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B
, LLVMValueRef Acc
, LLVMValueRef Src
) {
1524 return wrap(unwrap(B
)->CreateFMulReduce(unwrap(Acc
),unwrap(Src
)));
1526 extern "C" LLVMValueRef
1527 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B
, LLVMValueRef Src
) {
1528 return wrap(unwrap(B
)->CreateAddReduce(unwrap(Src
)));
1530 extern "C" LLVMValueRef
1531 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B
, LLVMValueRef Src
) {
1532 return wrap(unwrap(B
)->CreateMulReduce(unwrap(Src
)));
1534 extern "C" LLVMValueRef
1535 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B
, LLVMValueRef Src
) {
1536 return wrap(unwrap(B
)->CreateAndReduce(unwrap(Src
)));
1538 extern "C" LLVMValueRef
1539 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B
, LLVMValueRef Src
) {
1540 return wrap(unwrap(B
)->CreateOrReduce(unwrap(Src
)));
1542 extern "C" LLVMValueRef
1543 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B
, LLVMValueRef Src
) {
1544 return wrap(unwrap(B
)->CreateXorReduce(unwrap(Src
)));
1546 extern "C" LLVMValueRef
1547 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B
, LLVMValueRef Src
, bool IsSigned
) {
1548 return wrap(unwrap(B
)->CreateIntMinReduce(unwrap(Src
), IsSigned
));
1550 extern "C" LLVMValueRef
1551 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B
, LLVMValueRef Src
, bool IsSigned
) {
1552 return wrap(unwrap(B
)->CreateIntMaxReduce(unwrap(Src
), IsSigned
));
1554 extern "C" LLVMValueRef
1555 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B
, LLVMValueRef Src
, bool NoNaN
) {
1556 return wrap(unwrap(B
)->CreateFPMinReduce(unwrap(Src
), NoNaN
));
1558 extern "C" LLVMValueRef
1559 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B
, LLVMValueRef Src
, bool NoNaN
) {
1560 return wrap(unwrap(B
)->CreateFPMaxReduce(unwrap(Src
), NoNaN
));
1563 extern "C" LLVMValueRef
1564 LLVMRustBuildMinNum(LLVMBuilderRef B
, LLVMValueRef LHS
, LLVMValueRef RHS
) {
1565 return wrap(unwrap(B
)->CreateMinNum(unwrap(LHS
),unwrap(RHS
)));
1567 extern "C" LLVMValueRef
1568 LLVMRustBuildMaxNum(LLVMBuilderRef B
, LLVMValueRef LHS
, LLVMValueRef RHS
) {
1569 return wrap(unwrap(B
)->CreateMaxNum(unwrap(LHS
),unwrap(RHS
)));