1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 #include "llvm/IR/DebugInfoMetadata.h"
13 #include "llvm/IR/DiagnosticInfo.h"
14 #include "llvm/IR/DiagnosticPrinter.h"
15 #include "llvm/IR/Instructions.h"
16 #include "llvm/Object/Archive.h"
17 #include "llvm/Object/ObjectFile.h"
18 #include "llvm/Bitcode/BitcodeWriterPass.h"
20 #include "llvm/IR/CallSite.h"
22 #if LLVM_VERSION_GE(5, 0)
23 #include "llvm/ADT/Optional.h"
26 //===----------------------------------------------------------------------===
28 // This file defines alternate interfaces to core functions that are more
29 // readily callable by Rust's FFI.
31 //===----------------------------------------------------------------------===
34 using namespace llvm::sys
;
35 using namespace llvm::object
;
37 // LLVMAtomicOrdering is already an enum - don't create another
39 static AtomicOrdering
fromRust(LLVMAtomicOrdering Ordering
) {
41 case LLVMAtomicOrderingNotAtomic
:
42 return AtomicOrdering::NotAtomic
;
43 case LLVMAtomicOrderingUnordered
:
44 return AtomicOrdering::Unordered
;
45 case LLVMAtomicOrderingMonotonic
:
46 return AtomicOrdering::Monotonic
;
47 case LLVMAtomicOrderingAcquire
:
48 return AtomicOrdering::Acquire
;
49 case LLVMAtomicOrderingRelease
:
50 return AtomicOrdering::Release
;
51 case LLVMAtomicOrderingAcquireRelease
:
52 return AtomicOrdering::AcquireRelease
;
53 case LLVMAtomicOrderingSequentiallyConsistent
:
54 return AtomicOrdering::SequentiallyConsistent
;
57 llvm_unreachable("Invalid LLVMAtomicOrdering value!");
60 static LLVM_THREAD_LOCAL
char *LastError
;
62 extern "C" LLVMMemoryBufferRef
63 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path
) {
64 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> BufOr
=
65 MemoryBuffer::getFile(Path
, -1, false);
67 LLVMRustSetLastError(BufOr
.getError().message().c_str());
70 return wrap(BufOr
.get().release());
73 extern "C" char *LLVMRustGetLastError(void) {
74 char *Ret
= LastError
;
79 void LLVMRustSetLastError(const char *Err
) {
80 free((void *)LastError
);
81 LastError
= strdup(Err
);
84 extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M
,
86 unwrap(M
)->setTargetTriple(Triple::normalize(Triple
));
89 extern "C" void LLVMRustPrintPassTimings() {
90 raw_fd_ostream
OS(2, false); // stderr.
91 TimerGroup::printAll(OS
);
94 extern "C" LLVMValueRef
LLVMRustGetNamedValue(LLVMModuleRef M
,
96 return wrap(unwrap(M
)->getNamedValue(Name
));
99 extern "C" LLVMValueRef
LLVMRustGetOrInsertFunction(LLVMModuleRef M
,
101 LLVMTypeRef FunctionTy
) {
103 unwrap(M
)->getOrInsertFunction(Name
, unwrap
<FunctionType
>(FunctionTy
)));
106 extern "C" LLVMValueRef
107 LLVMRustGetOrInsertGlobal(LLVMModuleRef M
, const char *Name
, LLVMTypeRef Ty
) {
108 return wrap(unwrap(M
)->getOrInsertGlobal(Name
, unwrap(Ty
)));
111 extern "C" LLVMTypeRef
LLVMRustMetadataTypeInContext(LLVMContextRef C
) {
112 return wrap(Type::getMetadataTy(*unwrap(C
)));
115 static Attribute::AttrKind
fromRust(LLVMRustAttribute Kind
) {
118 return Attribute::AlwaysInline
;
120 return Attribute::ByVal
;
122 return Attribute::Cold
;
124 return Attribute::InlineHint
;
126 return Attribute::MinSize
;
128 return Attribute::Naked
;
130 return Attribute::NoAlias
;
132 return Attribute::NoCapture
;
134 return Attribute::NoInline
;
136 return Attribute::NonNull
;
138 return Attribute::NoRedZone
;
140 return Attribute::NoReturn
;
142 return Attribute::NoUnwind
;
143 case OptimizeForSize
:
144 return Attribute::OptimizeForSize
;
146 return Attribute::ReadOnly
;
148 return Attribute::SExt
;
150 return Attribute::StructRet
;
152 return Attribute::UWTable
;
154 return Attribute::ZExt
;
156 return Attribute::InReg
;
158 return Attribute::SanitizeThread
;
159 case SanitizeAddress
:
160 return Attribute::SanitizeAddress
;
162 return Attribute::SanitizeMemory
;
164 llvm_unreachable("bad AttributeKind");
167 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr
, unsigned Index
,
168 LLVMRustAttribute RustAttr
) {
169 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
170 Attribute Attr
= Attribute::get(Call
->getContext(), fromRust(RustAttr
));
171 #if LLVM_VERSION_GE(5, 0)
172 Call
.addAttribute(Index
, Attr
);
175 Call
.setAttributes(Call
.getAttributes().addAttributes(
176 Call
->getContext(), Index
,
177 AttributeSet::get(Call
->getContext(), Index
, B
)));
181 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr
,
184 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
186 B
.addDereferenceableAttr(Bytes
);
187 #if LLVM_VERSION_GE(5, 0)
188 Call
.setAttributes(Call
.getAttributes().addAttributes(
189 Call
->getContext(), Index
, B
));
191 Call
.setAttributes(Call
.getAttributes().addAttributes(
192 Call
->getContext(), Index
,
193 AttributeSet::get(Call
->getContext(), Index
, B
)));
197 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn
, unsigned Index
,
198 LLVMRustAttribute RustAttr
) {
199 Function
*A
= unwrap
<Function
>(Fn
);
200 Attribute Attr
= Attribute::get(A
->getContext(), fromRust(RustAttr
));
202 #if LLVM_VERSION_GE(5, 0)
203 A
->addAttributes(Index
, B
);
205 A
->addAttributes(Index
, AttributeSet::get(A
->getContext(), Index
, B
));
209 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn
, unsigned Index
,
211 Function
*A
= unwrap
<Function
>(Fn
);
213 B
.addDereferenceableAttr(Bytes
);
214 #if LLVM_VERSION_GE(5, 0)
215 A
->addAttributes(Index
, B
);
217 A
->addAttributes(Index
, AttributeSet::get(A
->getContext(), Index
, B
));
221 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn
,
225 Function
*F
= unwrap
<Function
>(Fn
);
227 B
.addAttribute(Name
, Value
);
228 #if LLVM_VERSION_GE(5, 0)
229 F
->addAttributes(Index
, B
);
231 F
->addAttributes(Index
, AttributeSet::get(F
->getContext(), Index
, B
));
235 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn
,
237 LLVMRustAttribute RustAttr
) {
238 Function
*F
= unwrap
<Function
>(Fn
);
239 Attribute Attr
= Attribute::get(F
->getContext(), fromRust(RustAttr
));
241 auto PAL
= F
->getAttributes();
242 #if LLVM_VERSION_GE(5, 0)
243 auto PALNew
= PAL
.removeAttributes(F
->getContext(), Index
, B
);
245 const AttributeSet PALNew
= PAL
.removeAttributes(
246 F
->getContext(), Index
, AttributeSet::get(F
->getContext(), Index
, B
));
248 F
->setAttributes(PALNew
);
251 // enable fpmath flag UnsafeAlgebra
252 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V
) {
253 if (auto I
= dyn_cast
<Instruction
>(unwrap
<Value
>(V
))) {
254 I
->setHasUnsafeAlgebra(true);
258 extern "C" LLVMValueRef
259 LLVMRustBuildAtomicLoad(LLVMBuilderRef B
, LLVMValueRef Source
, const char *Name
,
260 LLVMAtomicOrdering Order
, unsigned Alignment
) {
261 LoadInst
*LI
= new LoadInst(unwrap(Source
), 0);
262 LI
->setAtomic(fromRust(Order
));
263 LI
->setAlignment(Alignment
);
264 return wrap(unwrap(B
)->Insert(LI
, Name
));
267 extern "C" LLVMValueRef
LLVMRustBuildAtomicStore(LLVMBuilderRef B
,
270 LLVMAtomicOrdering Order
,
271 unsigned Alignment
) {
272 StoreInst
*SI
= new StoreInst(unwrap(V
), unwrap(Target
));
273 SI
->setAtomic(fromRust(Order
));
274 SI
->setAlignment(Alignment
);
275 return wrap(unwrap(B
)->Insert(SI
));
278 extern "C" LLVMValueRef
279 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B
, LLVMValueRef Target
,
280 LLVMValueRef Old
, LLVMValueRef Source
,
281 LLVMAtomicOrdering Order
,
282 LLVMAtomicOrdering FailureOrder
, LLVMBool Weak
) {
283 AtomicCmpXchgInst
*ACXI
= unwrap(B
)->CreateAtomicCmpXchg(
284 unwrap(Target
), unwrap(Old
), unwrap(Source
), fromRust(Order
),
285 fromRust(FailureOrder
));
290 enum class LLVMRustSynchronizationScope
{
296 #if LLVM_VERSION_GE(5, 0)
297 static SyncScope::ID
fromRust(LLVMRustSynchronizationScope Scope
) {
299 case LLVMRustSynchronizationScope::SingleThread
:
300 return SyncScope::SingleThread
;
301 case LLVMRustSynchronizationScope::CrossThread
:
302 return SyncScope::System
;
304 llvm_unreachable("bad SynchronizationScope.");
308 static SynchronizationScope
fromRust(LLVMRustSynchronizationScope Scope
) {
310 case LLVMRustSynchronizationScope::SingleThread
:
312 case LLVMRustSynchronizationScope::CrossThread
:
315 llvm_unreachable("bad SynchronizationScope.");
320 extern "C" LLVMValueRef
321 LLVMRustBuildAtomicFence(LLVMBuilderRef B
, LLVMAtomicOrdering Order
,
322 LLVMRustSynchronizationScope Scope
) {
323 return wrap(unwrap(B
)->CreateFence(fromRust(Order
), fromRust(Scope
)));
326 extern "C" void LLVMRustSetDebug(int Enabled
) {
332 enum class LLVMRustAsmDialect
{
338 static InlineAsm::AsmDialect
fromRust(LLVMRustAsmDialect Dialect
) {
340 case LLVMRustAsmDialect::Att
:
341 return InlineAsm::AD_ATT
;
342 case LLVMRustAsmDialect::Intel
:
343 return InlineAsm::AD_Intel
;
345 llvm_unreachable("bad AsmDialect.");
349 extern "C" LLVMValueRef
LLVMRustInlineAsm(LLVMTypeRef Ty
, char *AsmString
,
351 LLVMBool HasSideEffects
,
352 LLVMBool IsAlignStack
,
353 LLVMRustAsmDialect Dialect
) {
354 return wrap(InlineAsm::get(unwrap
<FunctionType
>(Ty
), AsmString
, Constraints
,
355 HasSideEffects
, IsAlignStack
, fromRust(Dialect
)));
358 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M
, const char *Asm
) {
359 unwrap(M
)->appendModuleInlineAsm(StringRef(Asm
));
362 typedef DIBuilder
*LLVMRustDIBuilderRef
;
364 #if LLVM_VERSION_LT(5, 0)
365 typedef struct LLVMOpaqueMetadata
*LLVMMetadataRef
;
368 DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata
, LLVMMetadataRef
)
370 inline Metadata
**unwrap(LLVMMetadataRef
*Vals
) {
371 return reinterpret_cast<Metadata
**>(Vals
);
376 template <typename DIT
> DIT
*unwrapDIPtr(LLVMMetadataRef Ref
) {
377 return (DIT
*)(Ref
? unwrap
<MDNode
>(Ref
) : nullptr);
380 #define DIDescriptor DIScope
381 #define DIArray DINodeArray
382 #define unwrapDI unwrapDIPtr
384 // These values **must** match debuginfo::DIFlags! They also *happen*
385 // to match LLVM, but that isn't required as we do giant sets of
386 // matching below. The value shouldn't be directly passed to LLVM.
387 enum class LLVMRustDIFlags
: uint32_t {
392 FlagFwdDecl
= (1 << 2),
393 FlagAppleBlock
= (1 << 3),
394 FlagBlockByrefStruct
= (1 << 4),
395 FlagVirtual
= (1 << 5),
396 FlagArtificial
= (1 << 6),
397 FlagExplicit
= (1 << 7),
398 FlagPrototyped
= (1 << 8),
399 FlagObjcClassComplete
= (1 << 9),
400 FlagObjectPointer
= (1 << 10),
401 FlagVector
= (1 << 11),
402 FlagStaticMember
= (1 << 12),
403 FlagLValueReference
= (1 << 13),
404 FlagRValueReference
= (1 << 14),
405 FlagMainSubprogram
= (1 << 21),
406 // Do not add values that are not supported by the minimum LLVM
407 // version we support!
410 inline LLVMRustDIFlags
operator&(LLVMRustDIFlags A
, LLVMRustDIFlags B
) {
411 return static_cast<LLVMRustDIFlags
>(static_cast<uint32_t>(A
) &
412 static_cast<uint32_t>(B
));
415 inline LLVMRustDIFlags
operator|(LLVMRustDIFlags A
, LLVMRustDIFlags B
) {
416 return static_cast<LLVMRustDIFlags
>(static_cast<uint32_t>(A
) |
417 static_cast<uint32_t>(B
));
420 inline LLVMRustDIFlags
&operator|=(LLVMRustDIFlags
&A
, LLVMRustDIFlags B
) {
424 inline bool isSet(LLVMRustDIFlags F
) { return F
!= LLVMRustDIFlags::FlagZero
; }
426 inline LLVMRustDIFlags
visibility(LLVMRustDIFlags F
) {
427 return static_cast<LLVMRustDIFlags
>(static_cast<uint32_t>(F
) & 0x3);
430 #if LLVM_VERSION_GE(4, 0)
431 static DINode::DIFlags
fromRust(LLVMRustDIFlags Flags
) {
432 DINode::DIFlags Result
= DINode::DIFlags::FlagZero
;
434 static unsigned fromRust(LLVMRustDIFlags Flags
) {
438 switch (visibility(Flags
)) {
439 case LLVMRustDIFlags::FlagPrivate
:
440 Result
|= DINode::DIFlags::FlagPrivate
;
442 case LLVMRustDIFlags::FlagProtected
:
443 Result
|= DINode::DIFlags::FlagProtected
;
445 case LLVMRustDIFlags::FlagPublic
:
446 Result
|= DINode::DIFlags::FlagPublic
;
449 // The rest are handled below
453 if (isSet(Flags
& LLVMRustDIFlags::FlagFwdDecl
)) {
454 Result
|= DINode::DIFlags::FlagFwdDecl
;
456 if (isSet(Flags
& LLVMRustDIFlags::FlagAppleBlock
)) {
457 Result
|= DINode::DIFlags::FlagAppleBlock
;
459 if (isSet(Flags
& LLVMRustDIFlags::FlagBlockByrefStruct
)) {
460 Result
|= DINode::DIFlags::FlagBlockByrefStruct
;
462 if (isSet(Flags
& LLVMRustDIFlags::FlagVirtual
)) {
463 Result
|= DINode::DIFlags::FlagVirtual
;
465 if (isSet(Flags
& LLVMRustDIFlags::FlagArtificial
)) {
466 Result
|= DINode::DIFlags::FlagArtificial
;
468 if (isSet(Flags
& LLVMRustDIFlags::FlagExplicit
)) {
469 Result
|= DINode::DIFlags::FlagExplicit
;
471 if (isSet(Flags
& LLVMRustDIFlags::FlagPrototyped
)) {
472 Result
|= DINode::DIFlags::FlagPrototyped
;
474 if (isSet(Flags
& LLVMRustDIFlags::FlagObjcClassComplete
)) {
475 Result
|= DINode::DIFlags::FlagObjcClassComplete
;
477 if (isSet(Flags
& LLVMRustDIFlags::FlagObjectPointer
)) {
478 Result
|= DINode::DIFlags::FlagObjectPointer
;
480 if (isSet(Flags
& LLVMRustDIFlags::FlagVector
)) {
481 Result
|= DINode::DIFlags::FlagVector
;
483 if (isSet(Flags
& LLVMRustDIFlags::FlagStaticMember
)) {
484 Result
|= DINode::DIFlags::FlagStaticMember
;
486 if (isSet(Flags
& LLVMRustDIFlags::FlagLValueReference
)) {
487 Result
|= DINode::DIFlags::FlagLValueReference
;
489 if (isSet(Flags
& LLVMRustDIFlags::FlagRValueReference
)) {
490 Result
|= DINode::DIFlags::FlagRValueReference
;
492 #if LLVM_RUSTLLVM || LLVM_VERSION_GE(4, 0)
493 if (isSet(Flags
& LLVMRustDIFlags::FlagMainSubprogram
)) {
494 Result
|= DINode::DIFlags::FlagMainSubprogram
;
501 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
502 return DEBUG_METADATA_VERSION
;
505 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR
; }
507 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR
; }
509 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M
, const char *Name
,
511 unwrap(M
)->addModuleFlag(Module::Warning
, Name
, Value
);
514 extern "C" void LLVMRustMetadataAsValue(LLVMContextRef C
, LLVMMetadataRef MD
) {
515 wrap(MetadataAsValue::get(*unwrap(C
), unwrap(MD
)));
518 extern "C" LLVMRustDIBuilderRef
LLVMRustDIBuilderCreate(LLVMModuleRef M
) {
519 return new DIBuilder(*unwrap(M
));
522 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder
) {
526 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder
) {
530 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateCompileUnit(
531 LLVMRustDIBuilderRef Builder
, unsigned Lang
, LLVMMetadataRef FileRef
,
532 const char *Producer
, bool isOptimized
, const char *Flags
,
533 unsigned RuntimeVer
, const char *SplitName
) {
534 auto *File
= unwrapDI
<DIFile
>(FileRef
);
536 #if LLVM_VERSION_GE(4, 0)
537 return wrap(Builder
->createCompileUnit(Lang
, File
, Producer
, isOptimized
,
538 Flags
, RuntimeVer
, SplitName
));
540 return wrap(Builder
->createCompileUnit(Lang
, File
->getFilename(),
541 File
->getDirectory(), Producer
, isOptimized
,
542 Flags
, RuntimeVer
, SplitName
));
546 extern "C" LLVMMetadataRef
547 LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder
, const char *Filename
,
548 const char *Directory
) {
549 return wrap(Builder
->createFile(Filename
, Directory
));
552 extern "C" LLVMMetadataRef
553 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder
,
554 LLVMMetadataRef File
,
555 LLVMMetadataRef ParameterTypes
) {
556 return wrap(Builder
->createSubroutineType(
557 #if LLVM_VERSION_EQ(3, 7)
558 unwrapDI
<DIFile
>(File
),
560 DITypeRefArray(unwrap
<MDTuple
>(ParameterTypes
))));
563 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateFunction(
564 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
565 const char *LinkageName
, LLVMMetadataRef File
, unsigned LineNo
,
566 LLVMMetadataRef Ty
, bool IsLocalToUnit
, bool IsDefinition
,
567 unsigned ScopeLine
, LLVMRustDIFlags Flags
, bool IsOptimized
,
568 LLVMValueRef Fn
, LLVMMetadataRef TParam
, LLVMMetadataRef Decl
) {
569 #if LLVM_VERSION_GE(3, 8)
570 DITemplateParameterArray TParams
=
571 DITemplateParameterArray(unwrap
<MDTuple
>(TParam
));
572 DISubprogram
*Sub
= Builder
->createFunction(
573 unwrapDI
<DIScope
>(Scope
), Name
, LinkageName
, unwrapDI
<DIFile
>(File
),
574 LineNo
, unwrapDI
<DISubroutineType
>(Ty
), IsLocalToUnit
, IsDefinition
,
575 ScopeLine
, fromRust(Flags
), IsOptimized
, TParams
,
576 unwrapDIPtr
<DISubprogram
>(Decl
));
577 unwrap
<Function
>(Fn
)->setSubprogram(Sub
);
580 return wrap(Builder
->createFunction(
581 unwrapDI
<DIScope
>(Scope
), Name
, LinkageName
, unwrapDI
<DIFile
>(File
),
582 LineNo
, unwrapDI
<DISubroutineType
>(Ty
), IsLocalToUnit
, IsDefinition
,
583 ScopeLine
, fromRust(Flags
), IsOptimized
, unwrap
<Function
>(Fn
),
584 unwrapDIPtr
<MDNode
>(TParam
), unwrapDIPtr
<MDNode
>(Decl
)));
588 extern "C" LLVMMetadataRef
589 LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder
, const char *Name
,
590 uint64_t SizeInBits
, uint32_t AlignInBits
,
592 return wrap(Builder
->createBasicType(Name
, SizeInBits
,
593 #if LLVM_VERSION_LE(3, 9)
599 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreatePointerType(
600 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef PointeeTy
,
601 uint64_t SizeInBits
, uint32_t AlignInBits
, const char *Name
) {
602 return wrap(Builder
->createPointerType(unwrapDI
<DIType
>(PointeeTy
),
603 SizeInBits
, AlignInBits
,
604 #if LLVM_VERSION_GE(5, 0)
605 /* DWARFAddressSpace */ None
,
610 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateStructType(
611 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
612 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
613 uint32_t AlignInBits
, LLVMRustDIFlags Flags
,
614 LLVMMetadataRef DerivedFrom
, LLVMMetadataRef Elements
,
615 unsigned RunTimeLang
, LLVMMetadataRef VTableHolder
,
616 const char *UniqueId
) {
617 return wrap(Builder
->createStructType(
618 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
619 SizeInBits
, AlignInBits
, fromRust(Flags
), unwrapDI
<DIType
>(DerivedFrom
),
620 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), RunTimeLang
,
621 unwrapDI
<DIType
>(VTableHolder
), UniqueId
));
624 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateMemberType(
625 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
626 LLVMMetadataRef File
, unsigned LineNo
, uint64_t SizeInBits
,
627 uint32_t AlignInBits
, uint64_t OffsetInBits
, LLVMRustDIFlags Flags
,
628 LLVMMetadataRef Ty
) {
629 return wrap(Builder
->createMemberType(unwrapDI
<DIDescriptor
>(Scope
), Name
,
630 unwrapDI
<DIFile
>(File
), LineNo
,
631 SizeInBits
, AlignInBits
, OffsetInBits
,
632 fromRust(Flags
), unwrapDI
<DIType
>(Ty
)));
635 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateLexicalBlock(
636 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
,
637 LLVMMetadataRef File
, unsigned Line
, unsigned Col
) {
638 return wrap(Builder
->createLexicalBlock(unwrapDI
<DIDescriptor
>(Scope
),
639 unwrapDI
<DIFile
>(File
), Line
, Col
));
642 extern "C" LLVMMetadataRef
643 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder
,
644 LLVMMetadataRef Scope
,
645 LLVMMetadataRef File
) {
646 return wrap(Builder
->createLexicalBlockFile(unwrapDI
<DIDescriptor
>(Scope
),
647 unwrapDI
<DIFile
>(File
)));
650 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateStaticVariable(
651 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Context
, const char *Name
,
652 const char *LinkageName
, LLVMMetadataRef File
, unsigned LineNo
,
653 LLVMMetadataRef Ty
, bool IsLocalToUnit
, LLVMValueRef V
,
654 LLVMMetadataRef Decl
= nullptr, uint32_t AlignInBits
= 0) {
655 llvm::GlobalVariable
*InitVal
= cast
<llvm::GlobalVariable
>(unwrap(V
));
657 #if LLVM_VERSION_GE(4, 0)
658 llvm::DIExpression
*InitExpr
= nullptr;
659 if (llvm::ConstantInt
*IntVal
= llvm::dyn_cast
<llvm::ConstantInt
>(InitVal
)) {
660 InitExpr
= Builder
->createConstantValueExpression(
661 IntVal
->getValue().getSExtValue());
662 } else if (llvm::ConstantFP
*FPVal
=
663 llvm::dyn_cast
<llvm::ConstantFP
>(InitVal
)) {
664 InitExpr
= Builder
->createConstantValueExpression(
665 FPVal
->getValueAPF().bitcastToAPInt().getZExtValue());
668 llvm::DIGlobalVariableExpression
*VarExpr
= Builder
->createGlobalVariableExpression(
669 unwrapDI
<DIDescriptor
>(Context
), Name
, LinkageName
,
670 unwrapDI
<DIFile
>(File
), LineNo
, unwrapDI
<DIType
>(Ty
), IsLocalToUnit
,
671 InitExpr
, unwrapDIPtr
<MDNode
>(Decl
), AlignInBits
);
673 InitVal
->setMetadata("dbg", VarExpr
);
675 return wrap(VarExpr
);
677 return wrap(Builder
->createGlobalVariable(
678 unwrapDI
<DIDescriptor
>(Context
), Name
, LinkageName
,
679 unwrapDI
<DIFile
>(File
), LineNo
, unwrapDI
<DIType
>(Ty
), IsLocalToUnit
,
680 InitVal
, unwrapDIPtr
<MDNode
>(Decl
)));
684 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateVariable(
685 LLVMRustDIBuilderRef Builder
, unsigned Tag
, LLVMMetadataRef Scope
,
686 const char *Name
, LLVMMetadataRef File
, unsigned LineNo
,
687 LLVMMetadataRef Ty
, bool AlwaysPreserve
, LLVMRustDIFlags Flags
,
688 unsigned ArgNo
, uint32_t AlignInBits
) {
689 #if LLVM_VERSION_GE(3, 8)
690 if (Tag
== 0x100) { // DW_TAG_auto_variable
691 return wrap(Builder
->createAutoVariable(
692 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNo
,
693 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, fromRust(Flags
)
694 #if LLVM_VERSION_GE(4, 0)
700 return wrap(Builder
->createParameterVariable(
701 unwrapDI
<DIDescriptor
>(Scope
), Name
, ArgNo
, unwrapDI
<DIFile
>(File
),
702 LineNo
, unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, fromRust(Flags
)));
705 return wrap(Builder
->createLocalVariable(
706 Tag
, unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNo
,
707 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, fromRust(Flags
), ArgNo
));
711 extern "C" LLVMMetadataRef
712 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder
, uint64_t Size
,
713 uint32_t AlignInBits
, LLVMMetadataRef Ty
,
714 LLVMMetadataRef Subscripts
) {
716 Builder
->createArrayType(Size
, AlignInBits
, unwrapDI
<DIType
>(Ty
),
717 DINodeArray(unwrapDI
<MDTuple
>(Subscripts
))));
720 extern "C" LLVMMetadataRef
721 LLVMRustDIBuilderCreateVectorType(LLVMRustDIBuilderRef Builder
, uint64_t Size
,
722 uint32_t AlignInBits
, LLVMMetadataRef Ty
,
723 LLVMMetadataRef Subscripts
) {
725 Builder
->createVectorType(Size
, AlignInBits
, unwrapDI
<DIType
>(Ty
),
726 DINodeArray(unwrapDI
<MDTuple
>(Subscripts
))));
729 extern "C" LLVMMetadataRef
730 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder
, int64_t Lo
,
732 return wrap(Builder
->getOrCreateSubrange(Lo
, Count
));
735 extern "C" LLVMMetadataRef
736 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder
,
737 LLVMMetadataRef
*Ptr
, unsigned Count
) {
738 Metadata
**DataValue
= unwrap(Ptr
);
740 Builder
->getOrCreateArray(ArrayRef
<Metadata
*>(DataValue
, Count
)).get());
743 extern "C" LLVMValueRef
LLVMRustDIBuilderInsertDeclareAtEnd(
744 LLVMRustDIBuilderRef Builder
, LLVMValueRef V
, LLVMMetadataRef VarInfo
,
745 int64_t *AddrOps
, unsigned AddrOpsCount
, LLVMValueRef DL
,
746 LLVMBasicBlockRef InsertAtEnd
) {
747 return wrap(Builder
->insertDeclare(
748 unwrap(V
), unwrap
<DILocalVariable
>(VarInfo
),
749 Builder
->createExpression(llvm::ArrayRef
<int64_t>(AddrOps
, AddrOpsCount
)),
750 DebugLoc(cast
<MDNode
>(unwrap
<MetadataAsValue
>(DL
)->getMetadata())),
751 unwrap(InsertAtEnd
)));
754 extern "C" LLVMMetadataRef
755 LLVMRustDIBuilderCreateEnumerator(LLVMRustDIBuilderRef Builder
,
756 const char *Name
, uint64_t Val
) {
757 return wrap(Builder
->createEnumerator(Name
, Val
));
760 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateEnumerationType(
761 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
762 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
763 uint32_t AlignInBits
, LLVMMetadataRef Elements
,
764 LLVMMetadataRef ClassTy
) {
765 return wrap(Builder
->createEnumerationType(
766 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
767 SizeInBits
, AlignInBits
, DINodeArray(unwrapDI
<MDTuple
>(Elements
)),
768 unwrapDI
<DIType
>(ClassTy
)));
771 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateUnionType(
772 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
773 LLVMMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
774 uint32_t AlignInBits
, LLVMRustDIFlags Flags
, LLVMMetadataRef Elements
,
775 unsigned RunTimeLang
, const char *UniqueId
) {
776 return wrap(Builder
->createUnionType(
777 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
778 SizeInBits
, AlignInBits
, fromRust(Flags
),
779 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), RunTimeLang
, UniqueId
));
782 extern "C" LLVMMetadataRef
LLVMRustDIBuilderCreateTemplateTypeParameter(
783 LLVMRustDIBuilderRef Builder
, LLVMMetadataRef Scope
, const char *Name
,
784 LLVMMetadataRef Ty
, LLVMMetadataRef File
, unsigned LineNo
,
786 return wrap(Builder
->createTemplateTypeParameter(
787 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIType
>(Ty
)));
790 extern "C" LLVMMetadataRef
791 LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder
,
792 LLVMMetadataRef Scope
, const char *Name
,
793 LLVMMetadataRef File
, unsigned LineNo
) {
794 return wrap(Builder
->createNameSpace(
795 unwrapDI
<DIDescriptor
>(Scope
), Name
796 #if LLVM_VERSION_LT(5, 0)
798 unwrapDI
<DIFile
>(File
), LineNo
800 #if LLVM_VERSION_GE(4, 0)
802 false // ExportSymbols (only relevant for C++ anonymous namespaces)
808 LLVMRustDICompositeTypeSetTypeArray(LLVMRustDIBuilderRef Builder
,
809 LLVMMetadataRef CompositeTy
,
810 LLVMMetadataRef TyArray
) {
811 DICompositeType
*Tmp
= unwrapDI
<DICompositeType
>(CompositeTy
);
812 Builder
->replaceArrays(Tmp
, DINodeArray(unwrap
<MDTuple
>(TyArray
)));
815 extern "C" LLVMValueRef
816 LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef
, unsigned Line
,
817 unsigned Column
, LLVMMetadataRef Scope
,
818 LLVMMetadataRef InlinedAt
) {
819 LLVMContext
&Context
= *unwrap(ContextRef
);
821 DebugLoc debug_loc
= DebugLoc::get(Line
, Column
, unwrapDIPtr
<MDNode
>(Scope
),
822 unwrapDIPtr
<MDNode
>(InlinedAt
));
824 return wrap(MetadataAsValue::get(Context
, debug_loc
.getAsMDNode()));
827 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
828 return dwarf::DW_OP_deref
;
831 extern "C" int64_t LLVMRustDIBuilderCreateOpPlus() { return dwarf::DW_OP_plus
; }
833 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty
, RustStringRef Str
) {
834 RawRustStringOstream
OS(Str
);
835 unwrap
<llvm::Type
>(Ty
)->print(OS
);
838 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V
,
840 RawRustStringOstream
OS(Str
);
845 unwrap
<llvm::Value
>(V
)->getType()->print(OS
);
847 unwrap
<llvm::Value
>(V
)->print(OS
);
852 extern "C" bool LLVMRustLinkInExternalBitcode(LLVMModuleRef DstRef
, char *BC
,
854 Module
*Dst
= unwrap(DstRef
);
856 std::unique_ptr
<MemoryBuffer
> Buf
=
857 MemoryBuffer::getMemBufferCopy(StringRef(BC
, Len
));
859 #if LLVM_VERSION_GE(4, 0)
860 Expected
<std::unique_ptr
<Module
>> SrcOrError
=
861 llvm::getLazyBitcodeModule(Buf
->getMemBufferRef(), Dst
->getContext());
863 LLVMRustSetLastError(toString(SrcOrError
.takeError()).c_str());
867 auto Src
= std::move(*SrcOrError
);
869 ErrorOr
<std::unique_ptr
<Module
>> Src
=
870 llvm::getLazyBitcodeModule(std::move(Buf
), Dst
->getContext());
872 LLVMRustSetLastError(Src
.getError().message().c_str());
879 raw_string_ostream
Stream(Err
);
880 DiagnosticPrinterRawOStream
DP(Stream
);
881 #if LLVM_VERSION_GE(4, 0)
882 if (Linker::linkModules(*Dst
, std::move(Src
))) {
883 #elif LLVM_VERSION_GE(3, 8)
884 if (Linker::linkModules(*Dst
, std::move(Src
.get()))) {
886 if (Linker::LinkModules(Dst
, Src
->get(),
887 [&](const DiagnosticInfo
&DI
) { DI
.print(DP
); })) {
889 LLVMRustSetLastError(Err
.c_str());
895 extern "C" bool LLVMRustLinkInParsedExternalBitcode(
896 LLVMModuleRef DstRef
, LLVMModuleRef SrcRef
) {
897 #if LLVM_VERSION_GE(4, 0)
898 Module
*Dst
= unwrap(DstRef
);
899 std::unique_ptr
<Module
> Src(unwrap(SrcRef
));
901 if (Linker::linkModules(*Dst
, std::move(Src
))) {
902 LLVMRustSetLastError("failed to link modules");
907 LLVMRustSetLastError("can't link parsed modules on this LLVM");
912 // Note that the two following functions look quite similar to the
913 // LLVMGetSectionName function. Sadly, it appears that this function only
914 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
915 // function provided by LLVM doesn't return the length, so we've created our own
916 // function which returns the length as well as the data pointer.
918 // For an example of this not returning a null terminated string, see
919 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
920 // branches explicitly creates a StringRef without a null terminator, and then
923 inline section_iterator
*unwrap(LLVMSectionIteratorRef SI
) {
924 return reinterpret_cast<section_iterator
*>(SI
);
927 extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI
,
930 if (std::error_code EC
= (*unwrap(SI
))->getName(Ret
))
931 report_fatal_error(EC
.message());
936 // LLVMArrayType function does not support 64-bit ElementCount
937 extern "C" LLVMTypeRef
LLVMRustArrayType(LLVMTypeRef ElementTy
,
938 uint64_t ElementCount
) {
939 return wrap(ArrayType::get(unwrap(ElementTy
), ElementCount
));
942 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine
, LLVMTwineRef
)
943 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc
, LLVMDebugLocRef
)
945 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T
, RustStringRef Str
) {
946 RawRustStringOstream
OS(Str
);
947 unwrap(T
)->print(OS
);
950 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
951 LLVMDiagnosticInfoRef DI
, RustStringRef PassNameOut
,
952 LLVMValueRef
*FunctionOut
, unsigned* Line
, unsigned* Column
,
953 RustStringRef FilenameOut
, RustStringRef MessageOut
) {
954 // Undefined to call this not on an optimization diagnostic!
955 llvm::DiagnosticInfoOptimizationBase
*Opt
=
956 static_cast<llvm::DiagnosticInfoOptimizationBase
*>(unwrap(DI
));
958 RawRustStringOstream
PassNameOS(PassNameOut
);
959 PassNameOS
<< Opt
->getPassName();
960 *FunctionOut
= wrap(&Opt
->getFunction());
962 RawRustStringOstream
FilenameOS(FilenameOut
);
963 #if LLVM_VERSION_GE(5,0)
964 DiagnosticLocation loc
= Opt
->getLocation();
966 *Line
= loc
.getLine();
967 *Column
= loc
.getColumn();
968 FilenameOS
<< loc
.getFilename();
971 const DebugLoc
&loc
= Opt
->getDebugLoc();
973 *Line
= loc
.getLine();
974 *Column
= loc
.getCol();
975 FilenameOS
<< cast
<DIScope
>(loc
.getScope())->getFilename();
979 RawRustStringOstream
MessageOS(MessageOut
);
980 MessageOS
<< Opt
->getMsg();
984 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI
, unsigned *CookieOut
,
985 LLVMTwineRef
*MessageOut
,
986 LLVMValueRef
*InstructionOut
) {
987 // Undefined to call this not on an inline assembly diagnostic!
988 llvm::DiagnosticInfoInlineAsm
*IA
=
989 static_cast<llvm::DiagnosticInfoInlineAsm
*>(unwrap(DI
));
991 *CookieOut
= IA
->getLocCookie();
992 *MessageOut
= wrap(&IA
->getMsgStr());
993 *InstructionOut
= wrap(IA
->getInstruction());
996 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI
,
998 RawRustStringOstream
OS(Str
);
999 DiagnosticPrinterRawOStream
DP(OS
);
1000 unwrap(DI
)->print(DP
);
1003 enum class LLVMRustDiagnosticKind
{
1007 DebugMetadataVersion
,
1010 OptimizationRemarkMissed
,
1011 OptimizationRemarkAnalysis
,
1012 OptimizationRemarkAnalysisFPCommute
,
1013 OptimizationRemarkAnalysisAliasing
,
1014 OptimizationRemarkOther
,
1015 OptimizationFailure
,
1018 static LLVMRustDiagnosticKind
toRust(DiagnosticKind Kind
) {
1021 return LLVMRustDiagnosticKind::InlineAsm
;
1023 return LLVMRustDiagnosticKind::StackSize
;
1024 case DK_DebugMetadataVersion
:
1025 return LLVMRustDiagnosticKind::DebugMetadataVersion
;
1026 case DK_SampleProfile
:
1027 return LLVMRustDiagnosticKind::SampleProfile
;
1028 case DK_OptimizationRemark
:
1029 return LLVMRustDiagnosticKind::OptimizationRemark
;
1030 case DK_OptimizationRemarkMissed
:
1031 return LLVMRustDiagnosticKind::OptimizationRemarkMissed
;
1032 case DK_OptimizationRemarkAnalysis
:
1033 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis
;
1034 #if LLVM_VERSION_GE(3, 8)
1035 case DK_OptimizationRemarkAnalysisFPCommute
:
1036 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute
;
1037 case DK_OptimizationRemarkAnalysisAliasing
:
1038 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing
;
1041 #if LLVM_VERSION_GE(3, 9)
1042 return (Kind
>= DK_FirstRemark
&& Kind
<= DK_LastRemark
)
1043 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1044 : LLVMRustDiagnosticKind::Other
;
1046 return LLVMRustDiagnosticKind::Other
;
1051 extern "C" LLVMRustDiagnosticKind
1052 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI
) {
1053 return toRust((DiagnosticKind
)unwrap(DI
)->getKind());
1055 // This is kept distinct from LLVMGetTypeKind, because when
1056 // a new type kind is added, the Rust-side enum must be
1057 // updated or UB will result.
1058 extern "C" LLVMTypeKind
LLVMRustGetTypeKind(LLVMTypeRef Ty
) {
1059 switch (unwrap(Ty
)->getTypeID()) {
1060 case Type::VoidTyID
:
1061 return LLVMVoidTypeKind
;
1062 case Type::HalfTyID
:
1063 return LLVMHalfTypeKind
;
1064 case Type::FloatTyID
:
1065 return LLVMFloatTypeKind
;
1066 case Type::DoubleTyID
:
1067 return LLVMDoubleTypeKind
;
1068 case Type::X86_FP80TyID
:
1069 return LLVMX86_FP80TypeKind
;
1070 case Type::FP128TyID
:
1071 return LLVMFP128TypeKind
;
1072 case Type::PPC_FP128TyID
:
1073 return LLVMPPC_FP128TypeKind
;
1074 case Type::LabelTyID
:
1075 return LLVMLabelTypeKind
;
1076 case Type::MetadataTyID
:
1077 return LLVMMetadataTypeKind
;
1078 case Type::IntegerTyID
:
1079 return LLVMIntegerTypeKind
;
1080 case Type::FunctionTyID
:
1081 return LLVMFunctionTypeKind
;
1082 case Type::StructTyID
:
1083 return LLVMStructTypeKind
;
1084 case Type::ArrayTyID
:
1085 return LLVMArrayTypeKind
;
1086 case Type::PointerTyID
:
1087 return LLVMPointerTypeKind
;
1088 case Type::VectorTyID
:
1089 return LLVMVectorTypeKind
;
1090 case Type::X86_MMXTyID
:
1091 return LLVMX86_MMXTypeKind
;
1092 #if LLVM_VERSION_GE(3, 8)
1093 case Type::TokenTyID
:
1094 return LLVMTokenTypeKind
;
1097 llvm_unreachable("Unhandled TypeID.");
1100 extern "C" void LLVMRustWriteDebugLocToString(LLVMContextRef C
,
1102 RustStringRef Str
) {
1103 RawRustStringOstream
OS(Str
);
1104 unwrap(DL
)->print(OS
);
1107 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic
, LLVMSMDiagnosticRef
)
1109 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1110 LLVMContextRef C
, LLVMContext::InlineAsmDiagHandlerTy H
, void *CX
) {
1111 unwrap(C
)->setInlineAsmDiagnosticHandler(H
, CX
);
1114 extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef D
,
1115 RustStringRef Str
) {
1116 RawRustStringOstream
OS(Str
);
1117 unwrap(D
)->print("", OS
);
1120 extern "C" LLVMValueRef
1121 LLVMRustBuildLandingPad(LLVMBuilderRef B
, LLVMTypeRef Ty
,
1122 LLVMValueRef PersFn
, unsigned NumClauses
,
1123 const char *Name
, LLVMValueRef F
) {
1124 return LLVMBuildLandingPad(B
, Ty
, PersFn
, NumClauses
, Name
);
1127 extern "C" LLVMValueRef
LLVMRustBuildCleanupPad(LLVMBuilderRef B
,
1128 LLVMValueRef ParentPad
,
1130 LLVMValueRef
*LLArgs
,
1132 #if LLVM_VERSION_GE(3, 8)
1133 Value
**Args
= unwrap(LLArgs
);
1134 if (ParentPad
== nullptr) {
1135 Type
*Ty
= Type::getTokenTy(unwrap(B
)->getContext());
1136 ParentPad
= wrap(Constant::getNullValue(Ty
));
1138 return wrap(unwrap(B
)->CreateCleanupPad(
1139 unwrap(ParentPad
), ArrayRef
<Value
*>(Args
, ArgCount
), Name
));
1145 extern "C" LLVMValueRef
LLVMRustBuildCleanupRet(LLVMBuilderRef B
,
1146 LLVMValueRef CleanupPad
,
1147 LLVMBasicBlockRef UnwindBB
) {
1148 #if LLVM_VERSION_GE(3, 8)
1149 CleanupPadInst
*Inst
= cast
<CleanupPadInst
>(unwrap(CleanupPad
));
1150 return wrap(unwrap(B
)->CreateCleanupRet(Inst
, unwrap(UnwindBB
)));
1156 extern "C" LLVMValueRef
1157 LLVMRustBuildCatchPad(LLVMBuilderRef B
, LLVMValueRef ParentPad
,
1158 unsigned ArgCount
, LLVMValueRef
*LLArgs
, const char *Name
) {
1159 #if LLVM_VERSION_GE(3, 8)
1160 Value
**Args
= unwrap(LLArgs
);
1161 return wrap(unwrap(B
)->CreateCatchPad(
1162 unwrap(ParentPad
), ArrayRef
<Value
*>(Args
, ArgCount
), Name
));
1168 extern "C" LLVMValueRef
LLVMRustBuildCatchRet(LLVMBuilderRef B
,
1170 LLVMBasicBlockRef BB
) {
1171 #if LLVM_VERSION_GE(3, 8)
1172 return wrap(unwrap(B
)->CreateCatchRet(cast
<CatchPadInst
>(unwrap(Pad
)),
1179 extern "C" LLVMValueRef
LLVMRustBuildCatchSwitch(LLVMBuilderRef B
,
1180 LLVMValueRef ParentPad
,
1181 LLVMBasicBlockRef BB
,
1182 unsigned NumHandlers
,
1184 #if LLVM_VERSION_GE(3, 8)
1185 if (ParentPad
== nullptr) {
1186 Type
*Ty
= Type::getTokenTy(unwrap(B
)->getContext());
1187 ParentPad
= wrap(Constant::getNullValue(Ty
));
1189 return wrap(unwrap(B
)->CreateCatchSwitch(unwrap(ParentPad
), unwrap(BB
),
1190 NumHandlers
, Name
));
1196 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef
,
1197 LLVMBasicBlockRef Handler
) {
1198 #if LLVM_VERSION_GE(3, 8)
1199 Value
*CatchSwitch
= unwrap(CatchSwitchRef
);
1200 cast
<CatchSwitchInst
>(CatchSwitch
)->addHandler(unwrap(Handler
));
1204 #if LLVM_VERSION_GE(3, 8)
1205 extern "C" OperandBundleDef
*LLVMRustBuildOperandBundleDef(const char *Name
,
1206 LLVMValueRef
*Inputs
,
1207 unsigned NumInputs
) {
1208 return new OperandBundleDef(Name
, makeArrayRef(unwrap(Inputs
), NumInputs
));
1211 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef
*Bundle
) {
1215 extern "C" LLVMValueRef
LLVMRustBuildCall(LLVMBuilderRef B
, LLVMValueRef Fn
,
1216 LLVMValueRef
*Args
, unsigned NumArgs
,
1217 OperandBundleDef
*Bundle
,
1219 unsigned Len
= Bundle
? 1 : 0;
1220 ArrayRef
<OperandBundleDef
> Bundles
= makeArrayRef(Bundle
, Len
);
1221 return wrap(unwrap(B
)->CreateCall(
1222 unwrap(Fn
), makeArrayRef(unwrap(Args
), NumArgs
), Bundles
, Name
));
1225 extern "C" LLVMValueRef
1226 LLVMRustBuildInvoke(LLVMBuilderRef B
, LLVMValueRef Fn
, LLVMValueRef
*Args
,
1227 unsigned NumArgs
, LLVMBasicBlockRef Then
,
1228 LLVMBasicBlockRef Catch
, OperandBundleDef
*Bundle
,
1230 unsigned Len
= Bundle
? 1 : 0;
1231 ArrayRef
<OperandBundleDef
> Bundles
= makeArrayRef(Bundle
, Len
);
1232 return wrap(unwrap(B
)->CreateInvoke(unwrap(Fn
), unwrap(Then
), unwrap(Catch
),
1233 makeArrayRef(unwrap(Args
), NumArgs
),
1237 extern "C" void *LLVMRustBuildOperandBundleDef(const char *Name
,
1238 LLVMValueRef
*Inputs
,
1239 unsigned NumInputs
) {
1243 extern "C" void LLVMRustFreeOperandBundleDef(void *Bundle
) {}
1245 extern "C" LLVMValueRef
LLVMRustBuildCall(LLVMBuilderRef B
, LLVMValueRef Fn
,
1246 LLVMValueRef
*Args
, unsigned NumArgs
,
1247 void *Bundle
, const char *Name
) {
1248 return LLVMBuildCall(B
, Fn
, Args
, NumArgs
, Name
);
1251 extern "C" LLVMValueRef
1252 LLVMRustBuildInvoke(LLVMBuilderRef B
, LLVMValueRef Fn
, LLVMValueRef
*Args
,
1253 unsigned NumArgs
, LLVMBasicBlockRef Then
,
1254 LLVMBasicBlockRef Catch
, void *Bundle
, const char *Name
) {
1255 return LLVMBuildInvoke(B
, Fn
, Args
, NumArgs
, Then
, Catch
, Name
);
1259 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B
,
1260 LLVMBasicBlockRef BB
) {
1261 auto Point
= unwrap(BB
)->getFirstInsertionPt();
1262 unwrap(B
)->SetInsertPoint(unwrap(BB
), Point
);
1265 extern "C" void LLVMRustSetComdat(LLVMModuleRef M
, LLVMValueRef V
,
1267 Triple
TargetTriple(unwrap(M
)->getTargetTriple());
1268 GlobalObject
*GV
= unwrap
<GlobalObject
>(V
);
1269 if (!TargetTriple
.isOSBinFormatMachO()) {
1270 GV
->setComdat(unwrap(M
)->getOrInsertComdat(Name
));
1274 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V
) {
1275 GlobalObject
*GV
= unwrap
<GlobalObject
>(V
);
1276 GV
->setComdat(nullptr);
1279 enum class LLVMRustLinkage
{
1280 ExternalLinkage
= 0,
1281 AvailableExternallyLinkage
= 1,
1282 LinkOnceAnyLinkage
= 2,
1283 LinkOnceODRLinkage
= 3,
1286 AppendingLinkage
= 6,
1287 InternalLinkage
= 7,
1289 ExternalWeakLinkage
= 9,
1293 static LLVMRustLinkage
toRust(LLVMLinkage Linkage
) {
1295 case LLVMExternalLinkage
:
1296 return LLVMRustLinkage::ExternalLinkage
;
1297 case LLVMAvailableExternallyLinkage
:
1298 return LLVMRustLinkage::AvailableExternallyLinkage
;
1299 case LLVMLinkOnceAnyLinkage
:
1300 return LLVMRustLinkage::LinkOnceAnyLinkage
;
1301 case LLVMLinkOnceODRLinkage
:
1302 return LLVMRustLinkage::LinkOnceODRLinkage
;
1303 case LLVMWeakAnyLinkage
:
1304 return LLVMRustLinkage::WeakAnyLinkage
;
1305 case LLVMWeakODRLinkage
:
1306 return LLVMRustLinkage::WeakODRLinkage
;
1307 case LLVMAppendingLinkage
:
1308 return LLVMRustLinkage::AppendingLinkage
;
1309 case LLVMInternalLinkage
:
1310 return LLVMRustLinkage::InternalLinkage
;
1311 case LLVMPrivateLinkage
:
1312 return LLVMRustLinkage::PrivateLinkage
;
1313 case LLVMExternalWeakLinkage
:
1314 return LLVMRustLinkage::ExternalWeakLinkage
;
1315 case LLVMCommonLinkage
:
1316 return LLVMRustLinkage::CommonLinkage
;
1318 llvm_unreachable("Invalid LLVMRustLinkage value!");
1322 static LLVMLinkage
fromRust(LLVMRustLinkage Linkage
) {
1324 case LLVMRustLinkage::ExternalLinkage
:
1325 return LLVMExternalLinkage
;
1326 case LLVMRustLinkage::AvailableExternallyLinkage
:
1327 return LLVMAvailableExternallyLinkage
;
1328 case LLVMRustLinkage::LinkOnceAnyLinkage
:
1329 return LLVMLinkOnceAnyLinkage
;
1330 case LLVMRustLinkage::LinkOnceODRLinkage
:
1331 return LLVMLinkOnceODRLinkage
;
1332 case LLVMRustLinkage::WeakAnyLinkage
:
1333 return LLVMWeakAnyLinkage
;
1334 case LLVMRustLinkage::WeakODRLinkage
:
1335 return LLVMWeakODRLinkage
;
1336 case LLVMRustLinkage::AppendingLinkage
:
1337 return LLVMAppendingLinkage
;
1338 case LLVMRustLinkage::InternalLinkage
:
1339 return LLVMInternalLinkage
;
1340 case LLVMRustLinkage::PrivateLinkage
:
1341 return LLVMPrivateLinkage
;
1342 case LLVMRustLinkage::ExternalWeakLinkage
:
1343 return LLVMExternalWeakLinkage
;
1344 case LLVMRustLinkage::CommonLinkage
:
1345 return LLVMCommonLinkage
;
1347 llvm_unreachable("Invalid LLVMRustLinkage value!");
1350 extern "C" LLVMRustLinkage
LLVMRustGetLinkage(LLVMValueRef V
) {
1351 return toRust(LLVMGetLinkage(V
));
1354 extern "C" void LLVMRustSetLinkage(LLVMValueRef V
,
1355 LLVMRustLinkage RustLinkage
) {
1356 LLVMSetLinkage(V
, fromRust(RustLinkage
));
1359 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1360 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1361 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV
, bool sext
, uint64_t *high
, uint64_t *low
)
1363 auto C
= unwrap
<llvm::ConstantInt
>(CV
);
1364 if (C
->getBitWidth() > 128) { return false; }
1367 AP
= C
->getValue().sextOrSelf(128);
1369 AP
= C
->getValue().zextOrSelf(128);
1371 *low
= AP
.getLoBits(64).getZExtValue();
1372 *high
= AP
.getHiBits(64).getZExtValue();
1376 extern "C" LLVMContextRef
LLVMRustGetValueContext(LLVMValueRef V
) {
1377 return wrap(&unwrap(V
)->getContext());
1380 enum class LLVMRustVisibility
{
1386 static LLVMRustVisibility
toRust(LLVMVisibility Vis
) {
1388 case LLVMDefaultVisibility
:
1389 return LLVMRustVisibility::Default
;
1390 case LLVMHiddenVisibility
:
1391 return LLVMRustVisibility::Hidden
;
1392 case LLVMProtectedVisibility
:
1393 return LLVMRustVisibility::Protected
;
1395 llvm_unreachable("Invalid LLVMRustVisibility value!");
1398 static LLVMVisibility
fromRust(LLVMRustVisibility Vis
) {
1400 case LLVMRustVisibility::Default
:
1401 return LLVMDefaultVisibility
;
1402 case LLVMRustVisibility::Hidden
:
1403 return LLVMHiddenVisibility
;
1404 case LLVMRustVisibility::Protected
:
1405 return LLVMProtectedVisibility
;
1407 llvm_unreachable("Invalid LLVMRustVisibility value!");
1410 extern "C" LLVMRustVisibility
LLVMRustGetVisibility(LLVMValueRef V
) {
1411 return toRust(LLVMGetVisibility(V
));
1414 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1415 extern "C" LLVMValueRef
LLVMRustBuildIntCast(LLVMBuilderRef B
, LLVMValueRef Val
,
1416 LLVMTypeRef DestTy
, bool isSigned
) {
1417 return wrap(unwrap(B
)->CreateIntCast(unwrap(Val
), unwrap(DestTy
), isSigned
, ""));
1420 extern "C" void LLVMRustSetVisibility(LLVMValueRef V
,
1421 LLVMRustVisibility RustVisibility
) {
1422 LLVMSetVisibility(V
, fromRust(RustVisibility
));
1425 struct LLVMRustModuleBuffer
{
1429 extern "C" LLVMRustModuleBuffer
*
1430 LLVMRustModuleBufferCreate(LLVMModuleRef M
) {
1431 auto Ret
= llvm::make_unique
<LLVMRustModuleBuffer
>();
1433 raw_string_ostream
OS(Ret
->data
);
1435 legacy::PassManager PM
;
1436 PM
.add(createBitcodeWriterPass(OS
));
1440 return Ret
.release();
1444 LLVMRustModuleBufferFree(LLVMRustModuleBuffer
*Buffer
) {
1448 extern "C" const void*
1449 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer
*Buffer
) {
1450 return Buffer
->data
.data();
1454 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer
*Buffer
) {
1455 return Buffer
->data
.length();
1459 LLVMRustModuleCost(LLVMModuleRef M
) {
1460 Module
&Mod
= *unwrap(M
);
1462 for (auto &F
: Mod
.functions()) {