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" void LLVMRustSetLastError(const char *Err
) {
91 free((void *)LastError
);
92 LastError
= strdup(Err
);
95 extern "C" LLVMContextRef
LLVMRustContextCreate(bool shouldDiscardNames
) {
96 auto ctx
= new LLVMContext();
97 ctx
->setDiscardValueNames(shouldDiscardNames
);
101 extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M
,
102 const char *Triple
) {
103 unwrap(M
)->setTargetTriple(Triple::normalize(Triple
));
106 extern "C" void LLVMRustPrintPassTimings() {
107 raw_fd_ostream
OS(2, false); // stderr.
108 TimerGroup::printAll(OS
);
111 extern "C" LLVMValueRef
LLVMRustGetNamedValue(LLVMModuleRef M
,
113 return wrap(unwrap(M
)->getNamedValue(Name
));
116 extern "C" LLVMValueRef
LLVMRustGetOrInsertFunction(LLVMModuleRef M
,
118 LLVMTypeRef FunctionTy
) {
120 unwrap(M
)->getOrInsertFunction(Name
, unwrap
<FunctionType
>(FunctionTy
)));
123 extern "C" LLVMValueRef
124 LLVMRustGetOrInsertGlobal(LLVMModuleRef M
, const char *Name
, LLVMTypeRef Ty
) {
125 return wrap(unwrap(M
)->getOrInsertGlobal(Name
, unwrap(Ty
)));
128 extern "C" LLVMValueRef
129 LLVMRustInsertPrivateGlobal(LLVMModuleRef M
, LLVMTypeRef Ty
) {
130 return wrap(new GlobalVariable(*unwrap(M
),
133 GlobalValue::PrivateLinkage
,
137 extern "C" LLVMTypeRef
LLVMRustMetadataTypeInContext(LLVMContextRef C
) {
138 return wrap(Type::getMetadataTy(*unwrap(C
)));
141 static Attribute::AttrKind
fromRust(LLVMRustAttribute Kind
) {
144 return Attribute::AlwaysInline
;
146 return Attribute::ByVal
;
148 return Attribute::Cold
;
150 return Attribute::InlineHint
;
152 return Attribute::MinSize
;
154 return Attribute::Naked
;
156 return Attribute::NoAlias
;
158 return Attribute::NoCapture
;
160 return Attribute::NoInline
;
162 return Attribute::NonNull
;
164 return Attribute::NoRedZone
;
166 return Attribute::NoReturn
;
168 return Attribute::NoUnwind
;
169 case OptimizeForSize
:
170 return Attribute::OptimizeForSize
;
172 return Attribute::ReadOnly
;
174 return Attribute::SExt
;
176 return Attribute::StructRet
;
178 return Attribute::UWTable
;
180 return Attribute::ZExt
;
182 return Attribute::InReg
;
184 return Attribute::SanitizeThread
;
185 case SanitizeAddress
:
186 return Attribute::SanitizeAddress
;
188 return Attribute::SanitizeMemory
;
190 return Attribute::NonLazyBind
;
192 return Attribute::OptimizeNone
;
194 return Attribute::ReturnsTwice
;
196 report_fatal_error("bad AttributeKind");
199 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr
, unsigned Index
,
200 LLVMRustAttribute RustAttr
) {
201 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
202 Attribute Attr
= Attribute::get(Call
->getContext(), fromRust(RustAttr
));
203 Call
.addAttribute(Index
, Attr
);
206 extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr
,
209 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
211 B
.addAlignmentAttr(Bytes
);
212 Call
.setAttributes(Call
.getAttributes().addAttributes(
213 Call
->getContext(), Index
, B
));
216 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr
,
219 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
221 B
.addDereferenceableAttr(Bytes
);
222 Call
.setAttributes(Call
.getAttributes().addAttributes(
223 Call
->getContext(), Index
, B
));
226 extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr
,
229 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
231 B
.addDereferenceableOrNullAttr(Bytes
);
232 Call
.setAttributes(Call
.getAttributes().addAttributes(
233 Call
->getContext(), Index
, B
));
236 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn
, unsigned Index
,
237 LLVMRustAttribute RustAttr
) {
238 Function
*A
= unwrap
<Function
>(Fn
);
239 Attribute Attr
= Attribute::get(A
->getContext(), fromRust(RustAttr
));
241 A
->addAttributes(Index
, B
);
244 extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn
,
247 Function
*A
= unwrap
<Function
>(Fn
);
249 B
.addAlignmentAttr(Bytes
);
250 A
->addAttributes(Index
, B
);
253 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn
, unsigned Index
,
255 Function
*A
= unwrap
<Function
>(Fn
);
257 B
.addDereferenceableAttr(Bytes
);
258 A
->addAttributes(Index
, B
);
261 extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn
,
264 Function
*A
= unwrap
<Function
>(Fn
);
266 B
.addDereferenceableOrNullAttr(Bytes
);
267 A
->addAttributes(Index
, B
);
270 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn
,
274 Function
*F
= unwrap
<Function
>(Fn
);
276 B
.addAttribute(Name
, Value
);
277 F
->addAttributes(Index
, B
);
280 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn
,
282 LLVMRustAttribute RustAttr
) {
283 Function
*F
= unwrap
<Function
>(Fn
);
284 Attribute Attr
= Attribute::get(F
->getContext(), fromRust(RustAttr
));
286 auto PAL
= F
->getAttributes();
287 auto PALNew
= PAL
.removeAttributes(F
->getContext(), Index
, B
);
288 F
->setAttributes(PALNew
);
291 // enable fpmath flag UnsafeAlgebra
292 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V
) {
293 if (auto I
= dyn_cast
<Instruction
>(unwrap
<Value
>(V
))) {
298 extern "C" LLVMValueRef
299 LLVMRustBuildAtomicLoad(LLVMBuilderRef B
, LLVMValueRef Source
, const char *Name
,
300 LLVMAtomicOrdering Order
) {
301 LoadInst
*LI
= new LoadInst(unwrap(Source
));
302 LI
->setAtomic(fromRust(Order
));
303 return wrap(unwrap(B
)->Insert(LI
, Name
));
306 extern "C" LLVMValueRef
LLVMRustBuildAtomicStore(LLVMBuilderRef B
,
309 LLVMAtomicOrdering Order
) {
310 StoreInst
*SI
= new StoreInst(unwrap(V
), unwrap(Target
));
311 SI
->setAtomic(fromRust(Order
));
312 return wrap(unwrap(B
)->Insert(SI
));
315 extern "C" LLVMValueRef
316 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B
, LLVMValueRef Target
,
317 LLVMValueRef Old
, LLVMValueRef Source
,
318 LLVMAtomicOrdering Order
,
319 LLVMAtomicOrdering FailureOrder
, LLVMBool Weak
) {
320 AtomicCmpXchgInst
*ACXI
= unwrap(B
)->CreateAtomicCmpXchg(
321 unwrap(Target
), unwrap(Old
), unwrap(Source
), fromRust(Order
),
322 fromRust(FailureOrder
));
327 enum class LLVMRustSynchronizationScope
{
333 static SyncScope::ID
fromRust(LLVMRustSynchronizationScope Scope
) {
335 case LLVMRustSynchronizationScope::SingleThread
:
336 return SyncScope::SingleThread
;
337 case LLVMRustSynchronizationScope::CrossThread
:
338 return SyncScope::System
;
340 report_fatal_error("bad SynchronizationScope.");
344 extern "C" LLVMValueRef
345 LLVMRustBuildAtomicFence(LLVMBuilderRef B
, LLVMAtomicOrdering Order
,
346 LLVMRustSynchronizationScope Scope
) {
347 return wrap(unwrap(B
)->CreateFence(fromRust(Order
), fromRust(Scope
)));
350 enum class LLVMRustAsmDialect
{
356 static InlineAsm::AsmDialect
fromRust(LLVMRustAsmDialect Dialect
) {
358 case LLVMRustAsmDialect::Att
:
359 return InlineAsm::AD_ATT
;
360 case LLVMRustAsmDialect::Intel
:
361 return InlineAsm::AD_Intel
;
363 report_fatal_error("bad AsmDialect.");
367 extern "C" LLVMValueRef
LLVMRustInlineAsm(LLVMTypeRef Ty
, char *AsmString
,
369 LLVMBool HasSideEffects
,
370 LLVMBool IsAlignStack
,
371 LLVMRustAsmDialect Dialect
) {
372 return wrap(InlineAsm::get(unwrap
<FunctionType
>(Ty
), AsmString
, Constraints
,
373 HasSideEffects
, IsAlignStack
, fromRust(Dialect
)));
376 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty
,
378 return InlineAsm::Verify(unwrap
<FunctionType
>(Ty
), Constraints
);
381 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M
, const char *Asm
) {
382 unwrap(M
)->appendModuleInlineAsm(StringRef(Asm
));
385 typedef DIBuilder
*LLVMRustDIBuilderRef
;
387 template <typename DIT
> DIT
*unwrapDIPtr(LLVMMetadataRef Ref
) {
388 return (DIT
*)(Ref
? unwrap
<MDNode
>(Ref
) : nullptr);
391 #define DIDescriptor DIScope
392 #define DIArray DINodeArray
393 #define unwrapDI unwrapDIPtr
395 // These values **must** match debuginfo::DIFlags! They also *happen*
396 // to match LLVM, but that isn't required as we do giant sets of
397 // matching below. The value shouldn't be directly passed to LLVM.
398 enum class LLVMRustDIFlags
: uint32_t {
403 FlagFwdDecl
= (1 << 2),
404 FlagAppleBlock
= (1 << 3),
405 FlagBlockByrefStruct
= (1 << 4),
406 FlagVirtual
= (1 << 5),
407 FlagArtificial
= (1 << 6),
408 FlagExplicit
= (1 << 7),
409 FlagPrototyped
= (1 << 8),
410 FlagObjcClassComplete
= (1 << 9),
411 FlagObjectPointer
= (1 << 10),
412 FlagVector
= (1 << 11),
413 FlagStaticMember
= (1 << 12),
414 FlagLValueReference
= (1 << 13),
415 FlagRValueReference
= (1 << 14),
416 FlagExternalTypeRef
= (1 << 15),
417 FlagIntroducedVirtual
= (1 << 18),
418 FlagBitField
= (1 << 19),
419 FlagNoReturn
= (1 << 20),
420 FlagMainSubprogram
= (1 << 21),
421 // Do not add values that are not supported by the minimum LLVM
422 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
425 inline LLVMRustDIFlags
operator&(LLVMRustDIFlags A
, LLVMRustDIFlags B
) {
426 return static_cast<LLVMRustDIFlags
>(static_cast<uint32_t>(A
) &
427 static_cast<uint32_t>(B
));
430 inline LLVMRustDIFlags
operator|(LLVMRustDIFlags A
, LLVMRustDIFlags B
) {
431 return static_cast<LLVMRustDIFlags
>(static_cast<uint32_t>(A
) |
432 static_cast<uint32_t>(B
));
435 inline LLVMRustDIFlags
&operator|=(LLVMRustDIFlags
&A
, LLVMRustDIFlags B
) {
439 inline bool isSet(LLVMRustDIFlags F
) { return F
!= LLVMRustDIFlags::FlagZero
; }
441 inline LLVMRustDIFlags
visibility(LLVMRustDIFlags F
) {
442 return static_cast<LLVMRustDIFlags
>(static_cast<uint32_t>(F
) & 0x3);
445 static DINode::DIFlags
fromRust(LLVMRustDIFlags Flags
) {
446 DINode::DIFlags Result
= DINode::DIFlags::FlagZero
;
448 switch (visibility(Flags
)) {
449 case LLVMRustDIFlags::FlagPrivate
:
450 Result
|= DINode::DIFlags::FlagPrivate
;
452 case LLVMRustDIFlags::FlagProtected
:
453 Result
|= DINode::DIFlags::FlagProtected
;
455 case LLVMRustDIFlags::FlagPublic
:
456 Result
|= DINode::DIFlags::FlagPublic
;
459 // The rest are handled below
463 if (isSet(Flags
& LLVMRustDIFlags::FlagFwdDecl
)) {
464 Result
|= DINode::DIFlags::FlagFwdDecl
;
466 if (isSet(Flags
& LLVMRustDIFlags::FlagAppleBlock
)) {
467 Result
|= DINode::DIFlags::FlagAppleBlock
;
469 if (isSet(Flags
& LLVMRustDIFlags::FlagBlockByrefStruct
)) {
470 Result
|= DINode::DIFlags::FlagBlockByrefStruct
;
472 if (isSet(Flags
& LLVMRustDIFlags::FlagVirtual
)) {
473 Result
|= DINode::DIFlags::FlagVirtual
;
475 if (isSet(Flags
& LLVMRustDIFlags::FlagArtificial
)) {
476 Result
|= DINode::DIFlags::FlagArtificial
;
478 if (isSet(Flags
& LLVMRustDIFlags::FlagExplicit
)) {
479 Result
|= DINode::DIFlags::FlagExplicit
;
481 if (isSet(Flags
& LLVMRustDIFlags::FlagPrototyped
)) {
482 Result
|= DINode::DIFlags::FlagPrototyped
;
484 if (isSet(Flags
& LLVMRustDIFlags::FlagObjcClassComplete
)) {
485 Result
|= DINode::DIFlags::FlagObjcClassComplete
;
487 if (isSet(Flags
& LLVMRustDIFlags::FlagObjectPointer
)) {
488 Result
|= DINode::DIFlags::FlagObjectPointer
;
490 if (isSet(Flags
& LLVMRustDIFlags::FlagVector
)) {
491 Result
|= DINode::DIFlags::FlagVector
;
493 if (isSet(Flags
& LLVMRustDIFlags::FlagStaticMember
)) {
494 Result
|= DINode::DIFlags::FlagStaticMember
;
496 if (isSet(Flags
& LLVMRustDIFlags::FlagLValueReference
)) {
497 Result
|= DINode::DIFlags::FlagLValueReference
;
499 if (isSet(Flags
& LLVMRustDIFlags::FlagRValueReference
)) {
500 Result
|= DINode::DIFlags::FlagRValueReference
;
502 if (isSet(Flags
& LLVMRustDIFlags::FlagIntroducedVirtual
)) {
503 Result
|= DINode::DIFlags::FlagIntroducedVirtual
;
505 if (isSet(Flags
& LLVMRustDIFlags::FlagBitField
)) {
506 Result
|= DINode::DIFlags::FlagBitField
;
508 if (isSet(Flags
& LLVMRustDIFlags::FlagNoReturn
)) {
509 Result
|= DINode::DIFlags::FlagNoReturn
;
511 if (isSet(Flags
& LLVMRustDIFlags::FlagMainSubprogram
)) {
512 Result
|= DINode::DIFlags::FlagMainSubprogram
;
518 // These values **must** match debuginfo::DISPFlags! They also *happen*
519 // to match LLVM, but that isn't required as we do giant sets of
520 // matching below. The value shouldn't be directly passed to LLVM.
521 enum class LLVMRustDISPFlags
: uint32_t {
524 SPFlagPureVirtual
= 2,
525 SPFlagLocalToUnit
= (1 << 2),
526 SPFlagDefinition
= (1 << 3),
527 SPFlagOptimized
= (1 << 4),
528 // Do not add values that are not supported by the minimum LLVM
529 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
530 // (In LLVM < 8, createFunction supported these as separate bool arguments.)
533 inline LLVMRustDISPFlags
operator&(LLVMRustDISPFlags A
, LLVMRustDISPFlags B
) {
534 return static_cast<LLVMRustDISPFlags
>(static_cast<uint32_t>(A
) &
535 static_cast<uint32_t>(B
));
538 inline LLVMRustDISPFlags
operator|(LLVMRustDISPFlags A
, LLVMRustDISPFlags B
) {
539 return static_cast<LLVMRustDISPFlags
>(static_cast<uint32_t>(A
) |
540 static_cast<uint32_t>(B
));
543 inline LLVMRustDISPFlags
&operator|=(LLVMRustDISPFlags
&A
, LLVMRustDISPFlags B
) {
547 inline bool isSet(LLVMRustDISPFlags F
) { return F
!= LLVMRustDISPFlags::SPFlagZero
; }
549 inline LLVMRustDISPFlags
virtuality(LLVMRustDISPFlags F
) {
550 return static_cast<LLVMRustDISPFlags
>(static_cast<uint32_t>(F
) & 0x3);
553 #if LLVM_VERSION_GE(8, 0)
554 static DISubprogram::DISPFlags
fromRust(LLVMRustDISPFlags SPFlags
) {
555 DISubprogram::DISPFlags Result
= DISubprogram::DISPFlags::SPFlagZero
;
557 switch (virtuality(SPFlags
)) {
558 case LLVMRustDISPFlags::SPFlagVirtual
:
559 Result
|= DISubprogram::DISPFlags::SPFlagVirtual
;
561 case LLVMRustDISPFlags::SPFlagPureVirtual
:
562 Result
|= DISubprogram::DISPFlags::SPFlagPureVirtual
;
565 // The rest are handled below
569 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagLocalToUnit
)) {
570 Result
|= DISubprogram::DISPFlags::SPFlagLocalToUnit
;
572 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagDefinition
)) {
573 Result
|= DISubprogram::DISPFlags::SPFlagDefinition
;
575 if (isSet(SPFlags
& LLVMRustDISPFlags::SPFlagOptimized
)) {
576 Result
|= DISubprogram::DISPFlags::SPFlagOptimized
;
583 enum class LLVMRustDebugEmissionKind
{
589 static DICompileUnit::DebugEmissionKind
fromRust(LLVMRustDebugEmissionKind Kind
) {
591 case LLVMRustDebugEmissionKind::NoDebug
:
592 return DICompileUnit::DebugEmissionKind::NoDebug
;
593 case LLVMRustDebugEmissionKind::FullDebug
:
594 return DICompileUnit::DebugEmissionKind::FullDebug
;
595 case LLVMRustDebugEmissionKind::LineTablesOnly
:
596 return DICompileUnit::DebugEmissionKind::LineTablesOnly
;
598 report_fatal_error("bad DebugEmissionKind.");
602 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
603 return DEBUG_METADATA_VERSION
;
606 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR
; }
608 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR
; }
610 extern "C" bool LLVMRustIsRustLLVM() {
618 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M
, const char *Name
,
620 unwrap(M
)->addModuleFlag(Module::Warning
, Name
, Value
);
623 extern "C" LLVMValueRef
LLVMRustMetadataAsValue(LLVMContextRef C
, LLVMMetadataRef MD
) {
624 return wrap(MetadataAsValue::get(*unwrap(C
), unwrap(MD
)));
627 extern "C" LLVMRustDIBuilderRef
LLVMRustDIBuilderCreate(LLVMModuleRef M
) {
628 return new DIBuilder(*unwrap(M
));
631 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder
) {
635 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder
) {
639 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateCompileUnit(
640 LLVMRustDIBuilderRef Builder
, unsigned Lang
, LLVMMetadataRef FileRef
,
641 const char *Producer
, bool isOptimized
, const char *Flags
,
642 unsigned RuntimeVer
, const char *SplitName
,
643 LLVMRustDebugEmissionKind Kind
) {
644 auto *File
= unwrapDI
<DIFile
>(FileRef
);
646 return wrap(Builder
->createCompileUnit(Lang
, File
, Producer
, isOptimized
,
647 Flags
, RuntimeVer
, SplitName
,
651 extern "C" LLVMMetadataRef
652 LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder
, const char *Filename
,
653 const char *Directory
) {
654 return wrap(Builder
->createFile(Filename
, Directory
));
657 extern "C" LLVMMetadataRef
658 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder
,
659 LLVMMetadataRef File
,
660 LLVMMetadataRef ParameterTypes
) {
661 return wrap(Builder
->createSubroutineType(
662 DITypeRefArray(unwrap
<MDTuple
>(ParameterTypes
))));
665 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateFunction(
666 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
667 const char *LinkageName
, LLVMMetadataRef File
, unsigned LineNo
,
668 LLVMMetadataRef Ty
, unsigned ScopeLine
, LLVMRustDIFlags Flags
,
669 LLVMRustDISPFlags SPFlags
, LLVMValueRef Fn
, LLVMMetadataRef TParam
,
670 LLVMMetadataRef Decl
) {
671 DITemplateParameterArray TParams
=
672 DITemplateParameterArray(unwrap
<MDTuple
>(TParam
));
673 #if LLVM_VERSION_GE(8, 0)
674 DISubprogram
*Sub
= Builder
->createFunction(
675 unwrapDI
<DIScope
>(Scope
), Name
, LinkageName
, unwrapDI
<DIFile
>(File
),
676 LineNo
, unwrapDI
<DISubroutineType
>(Ty
), ScopeLine
, fromRust(Flags
),
677 fromRust(SPFlags
), TParams
, unwrapDIPtr
<DISubprogram
>(Decl
));
679 bool IsLocalToUnit
= isSet(SPFlags
& LLVMRustDISPFlags::SPFlagLocalToUnit
);
680 bool IsDefinition
= isSet(SPFlags
& LLVMRustDISPFlags::SPFlagDefinition
);
681 bool IsOptimized
= isSet(SPFlags
& LLVMRustDISPFlags::SPFlagOptimized
);
682 DISubprogram
*Sub
= Builder
->createFunction(
683 unwrapDI
<DIScope
>(Scope
), Name
, LinkageName
, unwrapDI
<DIFile
>(File
),
684 LineNo
, unwrapDI
<DISubroutineType
>(Ty
), IsLocalToUnit
, IsDefinition
,
685 ScopeLine
, fromRust(Flags
), IsOptimized
, TParams
,
686 unwrapDIPtr
<DISubprogram
>(Decl
));
688 unwrap
<Function
>(Fn
)->setSubprogram(Sub
);
692 extern "C" LLVMMetadataRef
693 LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder
, const char *Name
,
694 uint64_t SizeInBits
, uint32_t AlignInBits
,
696 return wrap(Builder
->createBasicType(Name
, SizeInBits
, Encoding
));
699 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreatePointerType(
700 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef PointeeTy
,
701 uint64_t SizeInBits
, uint32_t AlignInBits
, const char *Name
) {
702 return wrap(Builder
->createPointerType(unwrapDI
<DIType
>(PointeeTy
),
703 SizeInBits
, AlignInBits
,
704 /* DWARFAddressSpace */ None
,
708 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateStructType(
709 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
710 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
711 uint32_t AlignInBits
, LLVMRustDIFlags Flags
,
712 LLVMMetadataRef DerivedFrom
, LLVMMetadataRef Elements
,
713 unsigned RunTimeLang
, LLVMMetadataRef VTableHolder
,
714 const char *UniqueId
) {
715 return wrap(Builder
->createStructType(
716 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
717 SizeInBits
, AlignInBits
, fromRust(Flags
), unwrapDI
<DIType
>(DerivedFrom
),
718 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), RunTimeLang
,
719 unwrapDI
<DIType
>(VTableHolder
), UniqueId
));
722 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateVariantPart(
723 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
724 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
725 uint32_t AlignInBits
, LLVMRustDIFlags Flags
, LLVMMetadataRef Discriminator
,
726 LLVMMetadataRef Elements
, const char *UniqueId
) {
727 #if LLVM_VERSION_GE(7, 0)
728 return wrap(Builder
->createVariantPart(
729 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
730 SizeInBits
, AlignInBits
, fromRust(Flags
), unwrapDI
<DIDerivedType
>(Discriminator
),
731 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), UniqueId
));
737 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateMemberType(
738 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
739 LLVMMetadataRef File
, unsigned LineNo
, uint64_t SizeInBits
,
740 uint32_t AlignInBits
, uint64_t OffsetInBits
, LLVMRustDIFlags Flags
,
741 LLVMMetadataRef Ty
) {
742 return wrap(Builder
->createMemberType(unwrapDI
<DIDescriptor
>(Scope
), Name
,
743 unwrapDI
<DIFile
>(File
), LineNo
,
744 SizeInBits
, AlignInBits
, OffsetInBits
,
745 fromRust(Flags
), unwrapDI
<DIType
>(Ty
)));
748 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateVariantMemberType(
749 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
750 const char *Name
, LLVMMetadataRef File
, unsigned LineNo
, uint64_t SizeInBits
,
751 uint32_t AlignInBits
, uint64_t OffsetInBits
, LLVMValueRef Discriminant
,
752 LLVMRustDIFlags Flags
, LLVMMetadataRef Ty
) {
753 #if LLVM_VERSION_GE(7, 0)
754 llvm::ConstantInt
* D
= nullptr;
756 D
= unwrap
<llvm::ConstantInt
>(Discriminant
);
758 return wrap(Builder
->createVariantMemberType(unwrapDI
<DIDescriptor
>(Scope
), Name
,
759 unwrapDI
<DIFile
>(File
), LineNo
,
760 SizeInBits
, AlignInBits
, OffsetInBits
, D
,
761 fromRust(Flags
), unwrapDI
<DIType
>(Ty
)));
763 return wrap(Builder
->createMemberType(unwrapDI
<DIDescriptor
>(Scope
), Name
,
764 unwrapDI
<DIFile
>(File
), LineNo
,
765 SizeInBits
, AlignInBits
, OffsetInBits
,
766 fromRust(Flags
), unwrapDI
<DIType
>(Ty
)));
770 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateLexicalBlock(
771 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
772 LLVMMetadataRef File
, unsigned Line
, unsigned Col
) {
773 return wrap(Builder
->createLexicalBlock(unwrapDI
<DIDescriptor
>(Scope
),
774 unwrapDI
<DIFile
>(File
), Line
, Col
));
777 extern "C" LLVMMetadataRef
778 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder
,
779 LLVMMetadataRef Scope
,
780 LLVMMetadataRef File
) {
781 return wrap(Builder
->createLexicalBlockFile(unwrapDI
<DIDescriptor
>(Scope
),
782 unwrapDI
<DIFile
>(File
)));
785 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateStaticVariable(
786 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Context
, const char *Name
,
787 const char *LinkageName
, LLVMMetadataRef File
, unsigned LineNo
,
788 LLVMMetadataRef Ty
, bool IsLocalToUnit
, LLVMValueRef V
,
789 LLVMMetadataRef Decl
= nullptr, uint32_t AlignInBits
= 0) {
790 llvm::GlobalVariable
*InitVal
= cast
<llvm::GlobalVariable
>(unwrap(V
));
792 llvm::DIExpression
*InitExpr
= nullptr;
793 if (llvm::ConstantInt
*IntVal
= llvm::dyn_cast
<llvm::ConstantInt
>(InitVal
)) {
794 InitExpr
= Builder
->createConstantValueExpression(
795 IntVal
->getValue().getSExtValue());
796 } else if (llvm::ConstantFP
*FPVal
=
797 llvm::dyn_cast
<llvm::ConstantFP
>(InitVal
)) {
798 InitExpr
= Builder
->createConstantValueExpression(
799 FPVal
->getValueAPF().bitcastToAPInt().getZExtValue());
802 llvm::DIGlobalVariableExpression
*VarExpr
= Builder
->createGlobalVariableExpression(
803 unwrapDI
<DIDescriptor
>(Context
), Name
, LinkageName
,
804 unwrapDI
<DIFile
>(File
), LineNo
, unwrapDI
<DIType
>(Ty
), IsLocalToUnit
,
805 InitExpr
, unwrapDIPtr
<MDNode
>(Decl
),
806 #if LLVM_VERSION_GE(8, 0)
807 /* templateParams */ nullptr,
811 InitVal
->setMetadata("dbg", VarExpr
);
813 return wrap(VarExpr
);
816 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateVariable(
817 LLVMRustDIBuilderRef Builder
, unsigned Tag
, LLVMMetadataRef Scope
,
818 const char *Name
, LLVMMetadataRef File
, unsigned LineNo
,
819 LLVMMetadataRef Ty
, bool AlwaysPreserve
, LLVMRustDIFlags Flags
,
820 unsigned ArgNo
, uint32_t AlignInBits
) {
821 if (Tag
== 0x100) { // DW_TAG_auto_variable
822 return wrap(Builder
->createAutoVariable(
823 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNo
,
824 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, fromRust(Flags
), AlignInBits
));
826 return wrap(Builder
->createParameterVariable(
827 unwrapDI
<DIDescriptor
>(Scope
), Name
, ArgNo
, unwrapDI
<DIFile
>(File
),
828 LineNo
, unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, fromRust(Flags
)));
832 extern "C" LLVMMetadataRef
833 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder
, uint64_t Size
,
834 uint32_t AlignInBits
, LLVMMetadataRef Ty
,
835 LLVMMetadataRef Subscripts
) {
837 Builder
->createArrayType(Size
, AlignInBits
, unwrapDI
<DIType
>(Ty
),
838 DINodeArray(unwrapDI
<MDTuple
>(Subscripts
))));
841 extern "C" LLVMMetadataRef
842 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder
, int64_t Lo
,
844 return wrap(Builder
->getOrCreateSubrange(Lo
, Count
));
847 extern "C" LLVMMetadataRef
848 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder
,
849 LLVMMetadataRef
*Ptr
, unsigned Count
) {
850 Metadata
**DataValue
= unwrap(Ptr
);
852 Builder
->getOrCreateArray(ArrayRef
<Metadata
*>(DataValue
, Count
)).get());
855 extern "C" LLVMValueRef
LLVMRustDIBuilderInsertDeclareAtEnd(
856 LLVMRustDIBuilderRef Builder
, LLVMValueRef V
, LLVMMetadataRef VarInfo
,
857 int64_t *AddrOps
, unsigned AddrOpsCount
, LLVMValueRef DL
,
858 LLVMBasicBlockRef InsertAtEnd
) {
859 return wrap(Builder
->insertDeclare(
860 unwrap(V
), unwrap
<DILocalVariable
>(VarInfo
),
861 Builder
->createExpression(llvm::ArrayRef
<int64_t>(AddrOps
, AddrOpsCount
)),
862 DebugLoc(cast
<MDNode
>(unwrap
<MetadataAsValue
>(DL
)->getMetadata())),
863 unwrap(InsertAtEnd
)));
866 extern "C" LLVMMetadataRef
867 LLVMRustDIBuilderCreateEnumerator(LLVMRustDIBuilderRef Builder
,
868 const char *Name
, uint64_t Val
) {
869 return wrap(Builder
->createEnumerator(Name
, Val
));
872 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateEnumerationType(
873 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
874 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
875 uint32_t AlignInBits
, LLVMMetadataRef Elements
,
876 LLVMMetadataRef ClassTy
, bool IsScoped
) {
877 #if LLVM_VERSION_GE(7, 0)
878 return wrap(Builder
->createEnumerationType(
879 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
880 SizeInBits
, AlignInBits
, DINodeArray(unwrapDI
<MDTuple
>(Elements
)),
881 unwrapDI
<DIType
>(ClassTy
), "", IsScoped
));
883 // Ignore IsScoped on older LLVM.
884 return wrap(Builder
->createEnumerationType(
885 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
886 SizeInBits
, AlignInBits
, DINodeArray(unwrapDI
<MDTuple
>(Elements
)),
887 unwrapDI
<DIType
>(ClassTy
), ""));
891 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateUnionType(
892 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
893 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
894 uint32_t AlignInBits
, LLVMRustDIFlags Flags
, LLVMMetadataRef Elements
,
895 unsigned RunTimeLang
, const char *UniqueId
) {
896 return wrap(Builder
->createUnionType(
897 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
898 SizeInBits
, AlignInBits
, fromRust(Flags
),
899 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), RunTimeLang
, UniqueId
));
902 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateTemplateTypeParameter(
903 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
904 LLVMMetadataRef Ty
, LLVMMetadataRef File
, unsigned LineNo
,
906 return wrap(Builder
->createTemplateTypeParameter(
907 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIType
>(Ty
)));
910 extern "C" LLVMMetadataRef
911 LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder
,
912 LLVMMetadataRef Scope
, const char *Name
,
913 LLVMMetadataRef File
, unsigned LineNo
) {
914 return wrap(Builder
->createNameSpace(
915 unwrapDI
<DIDescriptor
>(Scope
), Name
,
916 false // ExportSymbols (only relevant for C++ anonymous namespaces)
921 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder
,
922 LLVMMetadataRef CompositeTy
,
923 LLVMMetadataRef Elements
,
924 LLVMMetadataRef Params
) {
925 DICompositeType
*Tmp
= unwrapDI
<DICompositeType
>(CompositeTy
);
926 Builder
->replaceArrays(Tmp
, DINodeArray(unwrap
<MDTuple
>(Elements
)),
927 DINodeArray(unwrap
<MDTuple
>(Params
)));
930 extern "C" LLVMValueRef
931 LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef
, unsigned Line
,
932 unsigned Column
, LLVMMetadataRef Scope
,
933 LLVMMetadataRef InlinedAt
) {
934 LLVMContext
&Context
= *unwrap(ContextRef
);
936 DebugLoc debug_loc
= DebugLoc::get(Line
, Column
, unwrapDIPtr
<MDNode
>(Scope
),
937 unwrapDIPtr
<MDNode
>(InlinedAt
));
939 return wrap(MetadataAsValue::get(Context
, debug_loc
.getAsMDNode()));
942 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
943 return dwarf::DW_OP_deref
;
946 extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
947 return dwarf::DW_OP_plus_uconst
;
950 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty
, RustStringRef Str
) {
951 RawRustStringOstream
OS(Str
);
952 unwrap
<llvm::Type
>(Ty
)->print(OS
);
955 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V
,
957 RawRustStringOstream
OS(Str
);
962 unwrap
<llvm::Value
>(V
)->getType()->print(OS
);
964 unwrap
<llvm::Value
>(V
)->print(OS
);
969 // Note that the two following functions look quite similar to the
970 // LLVMGetSectionName function. Sadly, it appears that this function only
971 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
972 // function provided by LLVM doesn't return the length, so we've created our own
973 // function which returns the length as well as the data pointer.
975 // For an example of this not returning a null terminated string, see
976 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
977 // branches explicitly creates a StringRef without a null terminator, and then
980 inline section_iterator
*unwrap(LLVMSectionIteratorRef SI
) {
981 return reinterpret_cast<section_iterator
*>(SI
);
984 extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI
,
987 if (std::error_code EC
= (*unwrap(SI
))->getName(Ret
))
988 report_fatal_error(EC
.message());
993 // LLVMArrayType function does not support 64-bit ElementCount
994 extern "C" LLVMTypeRef
LLVMRustArrayType(LLVMTypeRef ElementTy
,
995 uint64_t ElementCount
) {
996 return wrap(ArrayType::get(unwrap(ElementTy
), ElementCount
));
999 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine
, LLVMTwineRef
)
1001 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T
, RustStringRef Str
) {
1002 RawRustStringOstream
OS(Str
);
1003 unwrap(T
)->print(OS
);
1006 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
1007 LLVMDiagnosticInfoRef DI
, RustStringRef PassNameOut
,
1008 LLVMValueRef
*FunctionOut
, unsigned* Line
, unsigned* Column
,
1009 RustStringRef FilenameOut
, RustStringRef MessageOut
) {
1010 // Undefined to call this not on an optimization diagnostic!
1011 llvm::DiagnosticInfoOptimizationBase
*Opt
=
1012 static_cast<llvm::DiagnosticInfoOptimizationBase
*>(unwrap(DI
));
1014 RawRustStringOstream
PassNameOS(PassNameOut
);
1015 PassNameOS
<< Opt
->getPassName();
1016 *FunctionOut
= wrap(&Opt
->getFunction());
1018 RawRustStringOstream
FilenameOS(FilenameOut
);
1019 DiagnosticLocation loc
= Opt
->getLocation();
1020 if (loc
.isValid()) {
1021 *Line
= loc
.getLine();
1022 *Column
= loc
.getColumn();
1023 #if LLVM_VERSION_GE(8, 0)
1024 FilenameOS
<< loc
.getAbsolutePath();
1026 FilenameOS
<< loc
.getFilename();
1030 RawRustStringOstream
MessageOS(MessageOut
);
1031 MessageOS
<< Opt
->getMsg();
1035 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI
, unsigned *CookieOut
,
1036 LLVMTwineRef
*MessageOut
,
1037 LLVMValueRef
*InstructionOut
) {
1038 // Undefined to call this not on an inline assembly diagnostic!
1039 llvm::DiagnosticInfoInlineAsm
*IA
=
1040 static_cast<llvm::DiagnosticInfoInlineAsm
*>(unwrap(DI
));
1042 *CookieOut
= IA
->getLocCookie();
1043 *MessageOut
= wrap(&IA
->getMsgStr());
1044 *InstructionOut
= wrap(IA
->getInstruction());
1047 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI
,
1048 RustStringRef Str
) {
1049 RawRustStringOstream
OS(Str
);
1050 DiagnosticPrinterRawOStream
DP(OS
);
1051 unwrap(DI
)->print(DP
);
1054 enum class LLVMRustDiagnosticKind
{
1058 DebugMetadataVersion
,
1061 OptimizationRemarkMissed
,
1062 OptimizationRemarkAnalysis
,
1063 OptimizationRemarkAnalysisFPCommute
,
1064 OptimizationRemarkAnalysisAliasing
,
1065 OptimizationRemarkOther
,
1066 OptimizationFailure
,
1071 static LLVMRustDiagnosticKind
toRust(DiagnosticKind Kind
) {
1074 return LLVMRustDiagnosticKind::InlineAsm
;
1076 return LLVMRustDiagnosticKind::StackSize
;
1077 case DK_DebugMetadataVersion
:
1078 return LLVMRustDiagnosticKind::DebugMetadataVersion
;
1079 case DK_SampleProfile
:
1080 return LLVMRustDiagnosticKind::SampleProfile
;
1081 case DK_OptimizationRemark
:
1082 return LLVMRustDiagnosticKind::OptimizationRemark
;
1083 case DK_OptimizationRemarkMissed
:
1084 return LLVMRustDiagnosticKind::OptimizationRemarkMissed
;
1085 case DK_OptimizationRemarkAnalysis
:
1086 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis
;
1087 case DK_OptimizationRemarkAnalysisFPCommute
:
1088 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute
;
1089 case DK_OptimizationRemarkAnalysisAliasing
:
1090 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing
;
1092 return LLVMRustDiagnosticKind::PGOProfile
;
1094 return LLVMRustDiagnosticKind::Linker
;
1096 return (Kind
>= DK_FirstRemark
&& Kind
<= DK_LastRemark
)
1097 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1098 : LLVMRustDiagnosticKind::Other
;
1102 extern "C" LLVMRustDiagnosticKind
1103 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI
) {
1104 return toRust((DiagnosticKind
)unwrap(DI
)->getKind());
1106 // This is kept distinct from LLVMGetTypeKind, because when
1107 // a new type kind is added, the Rust-side enum must be
1108 // updated or UB will result.
1109 extern "C" LLVMTypeKind
LLVMRustGetTypeKind(LLVMTypeRef Ty
) {
1110 switch (unwrap(Ty
)->getTypeID()) {
1111 case Type::VoidTyID
:
1112 return LLVMVoidTypeKind
;
1113 case Type::HalfTyID
:
1114 return LLVMHalfTypeKind
;
1115 case Type::FloatTyID
:
1116 return LLVMFloatTypeKind
;
1117 case Type::DoubleTyID
:
1118 return LLVMDoubleTypeKind
;
1119 case Type::X86_FP80TyID
:
1120 return LLVMX86_FP80TypeKind
;
1121 case Type::FP128TyID
:
1122 return LLVMFP128TypeKind
;
1123 case Type::PPC_FP128TyID
:
1124 return LLVMPPC_FP128TypeKind
;
1125 case Type::LabelTyID
:
1126 return LLVMLabelTypeKind
;
1127 case Type::MetadataTyID
:
1128 return LLVMMetadataTypeKind
;
1129 case Type::IntegerTyID
:
1130 return LLVMIntegerTypeKind
;
1131 case Type::FunctionTyID
:
1132 return LLVMFunctionTypeKind
;
1133 case Type::StructTyID
:
1134 return LLVMStructTypeKind
;
1135 case Type::ArrayTyID
:
1136 return LLVMArrayTypeKind
;
1137 case Type::PointerTyID
:
1138 return LLVMPointerTypeKind
;
1139 case Type::VectorTyID
:
1140 return LLVMVectorTypeKind
;
1141 case Type::X86_MMXTyID
:
1142 return LLVMX86_MMXTypeKind
;
1143 case Type::TokenTyID
:
1144 return LLVMTokenTypeKind
;
1146 report_fatal_error("Unhandled TypeID.");
1149 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic
, LLVMSMDiagnosticRef
)
1151 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1152 LLVMContextRef C
, LLVMContext::InlineAsmDiagHandlerTy H
, void *CX
) {
1153 unwrap(C
)->setInlineAsmDiagnosticHandler(H
, CX
);
1156 extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef D
,
1157 RustStringRef Str
) {
1158 RawRustStringOstream
OS(Str
);
1159 unwrap(D
)->print("", OS
);
1162 extern "C" LLVMValueRef
LLVMRustBuildCleanupPad(LLVMBuilderRef B
,
1163 LLVMValueRef ParentPad
,
1165 LLVMValueRef
*LLArgs
,
1167 Value
**Args
= unwrap(LLArgs
);
1168 if (ParentPad
== nullptr) {
1169 Type
*Ty
= Type::getTokenTy(unwrap(B
)->getContext());
1170 ParentPad
= wrap(Constant::getNullValue(Ty
));
1172 return wrap(unwrap(B
)->CreateCleanupPad(
1173 unwrap(ParentPad
), ArrayRef
<Value
*>(Args
, ArgCount
), Name
));
1176 extern "C" LLVMValueRef
LLVMRustBuildCleanupRet(LLVMBuilderRef B
,
1177 LLVMValueRef CleanupPad
,
1178 LLVMBasicBlockRef UnwindBB
) {
1179 CleanupPadInst
*Inst
= cast
<CleanupPadInst
>(unwrap(CleanupPad
));
1180 return wrap(unwrap(B
)->CreateCleanupRet(Inst
, unwrap(UnwindBB
)));
1183 extern "C" LLVMValueRef
1184 LLVMRustBuildCatchPad(LLVMBuilderRef B
, LLVMValueRef ParentPad
,
1185 unsigned ArgCount
, LLVMValueRef
*LLArgs
, const char *Name
) {
1186 Value
**Args
= unwrap(LLArgs
);
1187 return wrap(unwrap(B
)->CreateCatchPad(
1188 unwrap(ParentPad
), ArrayRef
<Value
*>(Args
, ArgCount
), Name
));
1191 extern "C" LLVMValueRef
LLVMRustBuildCatchRet(LLVMBuilderRef B
,
1193 LLVMBasicBlockRef BB
) {
1194 return wrap(unwrap(B
)->CreateCatchRet(cast
<CatchPadInst
>(unwrap(Pad
)),
1198 extern "C" LLVMValueRef
LLVMRustBuildCatchSwitch(LLVMBuilderRef B
,
1199 LLVMValueRef ParentPad
,
1200 LLVMBasicBlockRef BB
,
1201 unsigned NumHandlers
,
1203 if (ParentPad
== nullptr) {
1204 Type
*Ty
= Type::getTokenTy(unwrap(B
)->getContext());
1205 ParentPad
= wrap(Constant::getNullValue(Ty
));
1207 return wrap(unwrap(B
)->CreateCatchSwitch(unwrap(ParentPad
), unwrap(BB
),
1208 NumHandlers
, Name
));
1211 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef
,
1212 LLVMBasicBlockRef Handler
) {
1213 Value
*CatchSwitch
= unwrap(CatchSwitchRef
);
1214 cast
<CatchSwitchInst
>(CatchSwitch
)->addHandler(unwrap(Handler
));
1217 extern "C" OperandBundleDef
*LLVMRustBuildOperandBundleDef(const char *Name
,
1218 LLVMValueRef
*Inputs
,
1219 unsigned NumInputs
) {
1220 return new OperandBundleDef(Name
, makeArrayRef(unwrap(Inputs
), NumInputs
));
1223 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef
*Bundle
) {
1227 extern "C" LLVMValueRef
LLVMRustBuildCall(LLVMBuilderRef B
, LLVMValueRef Fn
,
1228 LLVMValueRef
*Args
, unsigned NumArgs
,
1229 OperandBundleDef
*Bundle
,
1231 unsigned Len
= Bundle
? 1 : 0;
1232 ArrayRef
<OperandBundleDef
> Bundles
= makeArrayRef(Bundle
, Len
);
1233 return wrap(unwrap(B
)->CreateCall(
1234 unwrap(Fn
), makeArrayRef(unwrap(Args
), NumArgs
), Bundles
, Name
));
1237 extern "C" LLVMValueRef
LLVMRustBuildMemCpy(LLVMBuilderRef B
,
1238 LLVMValueRef Dst
, unsigned DstAlign
,
1239 LLVMValueRef Src
, unsigned SrcAlign
,
1240 LLVMValueRef Size
, bool IsVolatile
) {
1241 #if LLVM_VERSION_GE(7, 0)
1242 return wrap(unwrap(B
)->CreateMemCpy(
1243 unwrap(Dst
), DstAlign
,
1244 unwrap(Src
), SrcAlign
,
1245 unwrap(Size
), IsVolatile
));
1247 unsigned Align
= std::min(DstAlign
, SrcAlign
);
1248 return wrap(unwrap(B
)->CreateMemCpy(
1249 unwrap(Dst
), unwrap(Src
),
1250 unwrap(Size
), Align
, IsVolatile
));
1254 extern "C" LLVMValueRef
LLVMRustBuildMemMove(LLVMBuilderRef B
,
1255 LLVMValueRef Dst
, unsigned DstAlign
,
1256 LLVMValueRef Src
, unsigned SrcAlign
,
1257 LLVMValueRef Size
, bool IsVolatile
) {
1258 #if LLVM_VERSION_GE(7, 0)
1259 return wrap(unwrap(B
)->CreateMemMove(
1260 unwrap(Dst
), DstAlign
,
1261 unwrap(Src
), SrcAlign
,
1262 unwrap(Size
), IsVolatile
));
1264 unsigned Align
= std::min(DstAlign
, SrcAlign
);
1265 return wrap(unwrap(B
)->CreateMemMove(
1266 unwrap(Dst
), unwrap(Src
),
1267 unwrap(Size
), Align
, IsVolatile
));
1271 extern "C" LLVMValueRef
1272 LLVMRustBuildInvoke(LLVMBuilderRef B
, LLVMValueRef Fn
, LLVMValueRef
*Args
,
1273 unsigned NumArgs
, LLVMBasicBlockRef Then
,
1274 LLVMBasicBlockRef Catch
, OperandBundleDef
*Bundle
,
1276 unsigned Len
= Bundle
? 1 : 0;
1277 ArrayRef
<OperandBundleDef
> Bundles
= makeArrayRef(Bundle
, Len
);
1278 return wrap(unwrap(B
)->CreateInvoke(unwrap(Fn
), unwrap(Then
), unwrap(Catch
),
1279 makeArrayRef(unwrap(Args
), NumArgs
),
1283 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B
,
1284 LLVMBasicBlockRef BB
) {
1285 auto Point
= unwrap(BB
)->getFirstInsertionPt();
1286 unwrap(B
)->SetInsertPoint(unwrap(BB
), Point
);
1289 extern "C" void LLVMRustSetComdat(LLVMModuleRef M
, LLVMValueRef V
,
1291 Triple
TargetTriple(unwrap(M
)->getTargetTriple());
1292 GlobalObject
*GV
= unwrap
<GlobalObject
>(V
);
1293 if (!TargetTriple
.isOSBinFormatMachO()) {
1294 GV
->setComdat(unwrap(M
)->getOrInsertComdat(Name
));
1298 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V
) {
1299 GlobalObject
*GV
= unwrap
<GlobalObject
>(V
);
1300 GV
->setComdat(nullptr);
1303 enum class LLVMRustLinkage
{
1304 ExternalLinkage
= 0,
1305 AvailableExternallyLinkage
= 1,
1306 LinkOnceAnyLinkage
= 2,
1307 LinkOnceODRLinkage
= 3,
1310 AppendingLinkage
= 6,
1311 InternalLinkage
= 7,
1313 ExternalWeakLinkage
= 9,
1317 static LLVMRustLinkage
toRust(LLVMLinkage Linkage
) {
1319 case LLVMExternalLinkage
:
1320 return LLVMRustLinkage::ExternalLinkage
;
1321 case LLVMAvailableExternallyLinkage
:
1322 return LLVMRustLinkage::AvailableExternallyLinkage
;
1323 case LLVMLinkOnceAnyLinkage
:
1324 return LLVMRustLinkage::LinkOnceAnyLinkage
;
1325 case LLVMLinkOnceODRLinkage
:
1326 return LLVMRustLinkage::LinkOnceODRLinkage
;
1327 case LLVMWeakAnyLinkage
:
1328 return LLVMRustLinkage::WeakAnyLinkage
;
1329 case LLVMWeakODRLinkage
:
1330 return LLVMRustLinkage::WeakODRLinkage
;
1331 case LLVMAppendingLinkage
:
1332 return LLVMRustLinkage::AppendingLinkage
;
1333 case LLVMInternalLinkage
:
1334 return LLVMRustLinkage::InternalLinkage
;
1335 case LLVMPrivateLinkage
:
1336 return LLVMRustLinkage::PrivateLinkage
;
1337 case LLVMExternalWeakLinkage
:
1338 return LLVMRustLinkage::ExternalWeakLinkage
;
1339 case LLVMCommonLinkage
:
1340 return LLVMRustLinkage::CommonLinkage
;
1342 report_fatal_error("Invalid LLVMRustLinkage value!");
1346 static LLVMLinkage
fromRust(LLVMRustLinkage Linkage
) {
1348 case LLVMRustLinkage::ExternalLinkage
:
1349 return LLVMExternalLinkage
;
1350 case LLVMRustLinkage::AvailableExternallyLinkage
:
1351 return LLVMAvailableExternallyLinkage
;
1352 case LLVMRustLinkage::LinkOnceAnyLinkage
:
1353 return LLVMLinkOnceAnyLinkage
;
1354 case LLVMRustLinkage::LinkOnceODRLinkage
:
1355 return LLVMLinkOnceODRLinkage
;
1356 case LLVMRustLinkage::WeakAnyLinkage
:
1357 return LLVMWeakAnyLinkage
;
1358 case LLVMRustLinkage::WeakODRLinkage
:
1359 return LLVMWeakODRLinkage
;
1360 case LLVMRustLinkage::AppendingLinkage
:
1361 return LLVMAppendingLinkage
;
1362 case LLVMRustLinkage::InternalLinkage
:
1363 return LLVMInternalLinkage
;
1364 case LLVMRustLinkage::PrivateLinkage
:
1365 return LLVMPrivateLinkage
;
1366 case LLVMRustLinkage::ExternalWeakLinkage
:
1367 return LLVMExternalWeakLinkage
;
1368 case LLVMRustLinkage::CommonLinkage
:
1369 return LLVMCommonLinkage
;
1371 report_fatal_error("Invalid LLVMRustLinkage value!");
1374 extern "C" LLVMRustLinkage
LLVMRustGetLinkage(LLVMValueRef V
) {
1375 return toRust(LLVMGetLinkage(V
));
1378 extern "C" void LLVMRustSetLinkage(LLVMValueRef V
,
1379 LLVMRustLinkage RustLinkage
) {
1380 LLVMSetLinkage(V
, fromRust(RustLinkage
));
1383 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1384 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1385 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV
, bool sext
, uint64_t *high
, uint64_t *low
)
1387 auto C
= unwrap
<llvm::ConstantInt
>(CV
);
1388 if (C
->getBitWidth() > 128) { return false; }
1391 AP
= C
->getValue().sextOrSelf(128);
1393 AP
= C
->getValue().zextOrSelf(128);
1395 *low
= AP
.getLoBits(64).getZExtValue();
1396 *high
= AP
.getHiBits(64).getZExtValue();
1400 enum class LLVMRustVisibility
{
1406 static LLVMRustVisibility
toRust(LLVMVisibility Vis
) {
1408 case LLVMDefaultVisibility
:
1409 return LLVMRustVisibility::Default
;
1410 case LLVMHiddenVisibility
:
1411 return LLVMRustVisibility::Hidden
;
1412 case LLVMProtectedVisibility
:
1413 return LLVMRustVisibility::Protected
;
1415 report_fatal_error("Invalid LLVMRustVisibility value!");
1418 static LLVMVisibility
fromRust(LLVMRustVisibility Vis
) {
1420 case LLVMRustVisibility::Default
:
1421 return LLVMDefaultVisibility
;
1422 case LLVMRustVisibility::Hidden
:
1423 return LLVMHiddenVisibility
;
1424 case LLVMRustVisibility::Protected
:
1425 return LLVMProtectedVisibility
;
1427 report_fatal_error("Invalid LLVMRustVisibility value!");
1430 extern "C" LLVMRustVisibility
LLVMRustGetVisibility(LLVMValueRef V
) {
1431 return toRust(LLVMGetVisibility(V
));
1434 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1435 extern "C" LLVMValueRef
LLVMRustBuildIntCast(LLVMBuilderRef B
, LLVMValueRef Val
,
1436 LLVMTypeRef DestTy
, bool isSigned
) {
1437 return wrap(unwrap(B
)->CreateIntCast(unwrap(Val
), unwrap(DestTy
), isSigned
, ""));
1440 extern "C" void LLVMRustSetVisibility(LLVMValueRef V
,
1441 LLVMRustVisibility RustVisibility
) {
1442 LLVMSetVisibility(V
, fromRust(RustVisibility
));
1445 struct LLVMRustModuleBuffer
{
1449 extern "C" LLVMRustModuleBuffer
*
1450 LLVMRustModuleBufferCreate(LLVMModuleRef M
) {
1451 auto Ret
= llvm::make_unique
<LLVMRustModuleBuffer
>();
1453 raw_string_ostream
OS(Ret
->data
);
1455 legacy::PassManager PM
;
1456 PM
.add(createBitcodeWriterPass(OS
));
1460 return Ret
.release();
1464 LLVMRustModuleBufferFree(LLVMRustModuleBuffer
*Buffer
) {
1468 extern "C" const void*
1469 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer
*Buffer
) {
1470 return Buffer
->data
.data();
1474 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer
*Buffer
) {
1475 return Buffer
->data
.length();
1479 LLVMRustModuleCost(LLVMModuleRef M
) {
1480 auto f
= unwrap(M
)->functions();
1481 return std::distance(std::begin(f
), std::end(f
));
1484 // Vector reductions:
1485 extern "C" LLVMValueRef
1486 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B
, LLVMValueRef Acc
, LLVMValueRef Src
) {
1487 return wrap(unwrap(B
)->CreateFAddReduce(unwrap(Acc
),unwrap(Src
)));
1489 extern "C" LLVMValueRef
1490 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B
, LLVMValueRef Acc
, LLVMValueRef Src
) {
1491 return wrap(unwrap(B
)->CreateFMulReduce(unwrap(Acc
),unwrap(Src
)));
1493 extern "C" LLVMValueRef
1494 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B
, LLVMValueRef Src
) {
1495 return wrap(unwrap(B
)->CreateAddReduce(unwrap(Src
)));
1497 extern "C" LLVMValueRef
1498 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B
, LLVMValueRef Src
) {
1499 return wrap(unwrap(B
)->CreateMulReduce(unwrap(Src
)));
1501 extern "C" LLVMValueRef
1502 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B
, LLVMValueRef Src
) {
1503 return wrap(unwrap(B
)->CreateAndReduce(unwrap(Src
)));
1505 extern "C" LLVMValueRef
1506 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B
, LLVMValueRef Src
) {
1507 return wrap(unwrap(B
)->CreateOrReduce(unwrap(Src
)));
1509 extern "C" LLVMValueRef
1510 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B
, LLVMValueRef Src
) {
1511 return wrap(unwrap(B
)->CreateXorReduce(unwrap(Src
)));
1513 extern "C" LLVMValueRef
1514 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B
, LLVMValueRef Src
, bool IsSigned
) {
1515 return wrap(unwrap(B
)->CreateIntMinReduce(unwrap(Src
), IsSigned
));
1517 extern "C" LLVMValueRef
1518 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B
, LLVMValueRef Src
, bool IsSigned
) {
1519 return wrap(unwrap(B
)->CreateIntMaxReduce(unwrap(Src
), IsSigned
));
1521 extern "C" LLVMValueRef
1522 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B
, LLVMValueRef Src
, bool NoNaN
) {
1523 return wrap(unwrap(B
)->CreateFPMinReduce(unwrap(Src
), NoNaN
));
1525 extern "C" LLVMValueRef
1526 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B
, LLVMValueRef Src
, bool NoNaN
) {
1527 return wrap(unwrap(B
)->CreateFPMaxReduce(unwrap(Src
), NoNaN
));
1530 extern "C" LLVMValueRef
1531 LLVMRustBuildMinNum(LLVMBuilderRef B
, LLVMValueRef LHS
, LLVMValueRef RHS
) {
1532 return wrap(unwrap(B
)->CreateMinNum(unwrap(LHS
),unwrap(RHS
)));
1534 extern "C" LLVMValueRef
1535 LLVMRustBuildMaxNum(LLVMBuilderRef B
, LLVMValueRef LHS
, LLVMValueRef RHS
) {
1536 return wrap(unwrap(B
)->CreateMaxNum(unwrap(LHS
),unwrap(RHS
)));