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"
19 #include "llvm/IR/CallSite.h"
21 //===----------------------------------------------------------------------===
23 // This file defines alternate interfaces to core functions that are more
24 // readily callable by Rust's FFI.
26 //===----------------------------------------------------------------------===
29 using namespace llvm::sys
;
30 using namespace llvm::object
;
32 // LLVMAtomicOrdering is already an enum - don't create another
34 static AtomicOrdering
fromRust(LLVMAtomicOrdering Ordering
) {
36 case LLVMAtomicOrderingNotAtomic
:
37 return AtomicOrdering::NotAtomic
;
38 case LLVMAtomicOrderingUnordered
:
39 return AtomicOrdering::Unordered
;
40 case LLVMAtomicOrderingMonotonic
:
41 return AtomicOrdering::Monotonic
;
42 case LLVMAtomicOrderingAcquire
:
43 return AtomicOrdering::Acquire
;
44 case LLVMAtomicOrderingRelease
:
45 return AtomicOrdering::Release
;
46 case LLVMAtomicOrderingAcquireRelease
:
47 return AtomicOrdering::AcquireRelease
;
48 case LLVMAtomicOrderingSequentiallyConsistent
:
49 return AtomicOrdering::SequentiallyConsistent
;
52 llvm_unreachable("Invalid LLVMAtomicOrdering value!");
55 static char *LastError
;
57 extern "C" LLVMMemoryBufferRef
58 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path
) {
59 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> BufOr
=
60 MemoryBuffer::getFile(Path
, -1, false);
62 LLVMRustSetLastError(BufOr
.getError().message().c_str());
65 return wrap(BufOr
.get().release());
68 extern "C" char *LLVMRustGetLastError(void) {
69 char *Ret
= LastError
;
74 void LLVMRustSetLastError(const char *Err
) {
75 free((void *)LastError
);
76 LastError
= strdup(Err
);
79 extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M
,
81 unwrap(M
)->setTargetTriple(Triple::normalize(Triple
));
84 extern "C" void LLVMRustPrintPassTimings() {
85 raw_fd_ostream
OS(2, false); // stderr.
86 TimerGroup::printAll(OS
);
89 extern "C" LLVMValueRef
LLVMRustGetNamedValue(LLVMModuleRef M
,
91 return wrap(unwrap(M
)->getNamedValue(Name
));
94 extern "C" LLVMValueRef
LLVMRustGetOrInsertFunction(LLVMModuleRef M
,
96 LLVMTypeRef FunctionTy
) {
98 unwrap(M
)->getOrInsertFunction(Name
, unwrap
<FunctionType
>(FunctionTy
)));
101 extern "C" LLVMValueRef
102 LLVMRustGetOrInsertGlobal(LLVMModuleRef M
, const char *Name
, LLVMTypeRef Ty
) {
103 return wrap(unwrap(M
)->getOrInsertGlobal(Name
, unwrap(Ty
)));
106 extern "C" LLVMTypeRef
LLVMRustMetadataTypeInContext(LLVMContextRef C
) {
107 return wrap(Type::getMetadataTy(*unwrap(C
)));
110 static Attribute::AttrKind
fromRust(LLVMRustAttribute Kind
) {
113 return Attribute::AlwaysInline
;
115 return Attribute::ByVal
;
117 return Attribute::Cold
;
119 return Attribute::InlineHint
;
121 return Attribute::MinSize
;
123 return Attribute::Naked
;
125 return Attribute::NoAlias
;
127 return Attribute::NoCapture
;
129 return Attribute::NoInline
;
131 return Attribute::NonNull
;
133 return Attribute::NoRedZone
;
135 return Attribute::NoReturn
;
137 return Attribute::NoUnwind
;
138 case OptimizeForSize
:
139 return Attribute::OptimizeForSize
;
141 return Attribute::ReadOnly
;
143 return Attribute::SExt
;
145 return Attribute::StructRet
;
147 return Attribute::UWTable
;
149 return Attribute::ZExt
;
151 return Attribute::InReg
;
153 return Attribute::SanitizeThread
;
154 case SanitizeAddress
:
155 return Attribute::SanitizeAddress
;
157 return Attribute::SanitizeMemory
;
159 llvm_unreachable("bad AttributeKind");
162 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr
, unsigned Index
,
163 LLVMRustAttribute RustAttr
) {
164 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
165 Attribute Attr
= Attribute::get(Call
->getContext(), fromRust(RustAttr
));
167 Call
.setAttributes(Call
.getAttributes().addAttributes(
168 Call
->getContext(), Index
,
169 AttributeSet::get(Call
->getContext(), Index
, B
)));
172 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr
,
175 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
177 B
.addDereferenceableAttr(Bytes
);
178 Call
.setAttributes(Call
.getAttributes().addAttributes(
179 Call
->getContext(), Index
,
180 AttributeSet::get(Call
->getContext(), Index
, B
)));
183 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn
, unsigned Index
,
184 LLVMRustAttribute RustAttr
) {
185 Function
*A
= unwrap
<Function
>(Fn
);
186 Attribute Attr
= Attribute::get(A
->getContext(), fromRust(RustAttr
));
188 A
->addAttributes(Index
, AttributeSet::get(A
->getContext(), Index
, B
));
191 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn
, unsigned Index
,
193 Function
*A
= unwrap
<Function
>(Fn
);
195 B
.addDereferenceableAttr(Bytes
);
196 A
->addAttributes(Index
, AttributeSet::get(A
->getContext(), Index
, B
));
199 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn
,
203 Function
*F
= unwrap
<Function
>(Fn
);
205 B
.addAttribute(Name
, Value
);
206 F
->addAttributes(Index
, AttributeSet::get(F
->getContext(), Index
, B
));
209 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn
,
211 LLVMRustAttribute RustAttr
) {
212 Function
*F
= unwrap
<Function
>(Fn
);
213 const AttributeSet PAL
= F
->getAttributes();
214 Attribute Attr
= Attribute::get(F
->getContext(), fromRust(RustAttr
));
216 const AttributeSet PALNew
= PAL
.removeAttributes(
217 F
->getContext(), Index
, AttributeSet::get(F
->getContext(), Index
, B
));
218 F
->setAttributes(PALNew
);
221 // enable fpmath flag UnsafeAlgebra
222 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V
) {
223 if (auto I
= dyn_cast
<Instruction
>(unwrap
<Value
>(V
))) {
224 I
->setHasUnsafeAlgebra(true);
228 extern "C" LLVMValueRef
229 LLVMRustBuildAtomicLoad(LLVMBuilderRef B
, LLVMValueRef Source
, const char *Name
,
230 LLVMAtomicOrdering Order
, unsigned Alignment
) {
231 LoadInst
*LI
= new LoadInst(unwrap(Source
), 0);
232 LI
->setAtomic(fromRust(Order
));
233 LI
->setAlignment(Alignment
);
234 return wrap(unwrap(B
)->Insert(LI
, Name
));
237 extern "C" LLVMValueRef
LLVMRustBuildAtomicStore(LLVMBuilderRef B
,
240 LLVMAtomicOrdering Order
,
241 unsigned Alignment
) {
242 StoreInst
*SI
= new StoreInst(unwrap(V
), unwrap(Target
));
243 SI
->setAtomic(fromRust(Order
));
244 SI
->setAlignment(Alignment
);
245 return wrap(unwrap(B
)->Insert(SI
));
248 extern "C" LLVMValueRef
249 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B
, LLVMValueRef Target
,
250 LLVMValueRef Old
, LLVMValueRef Source
,
251 LLVMAtomicOrdering Order
,
252 LLVMAtomicOrdering FailureOrder
, LLVMBool Weak
) {
253 AtomicCmpXchgInst
*ACXI
= unwrap(B
)->CreateAtomicCmpXchg(
254 unwrap(Target
), unwrap(Old
), unwrap(Source
), fromRust(Order
),
255 fromRust(FailureOrder
));
260 enum class LLVMRustSynchronizationScope
{
266 static SynchronizationScope
fromRust(LLVMRustSynchronizationScope Scope
) {
268 case LLVMRustSynchronizationScope::SingleThread
:
270 case LLVMRustSynchronizationScope::CrossThread
:
273 llvm_unreachable("bad SynchronizationScope.");
277 extern "C" LLVMValueRef
278 LLVMRustBuildAtomicFence(LLVMBuilderRef B
, LLVMAtomicOrdering Order
,
279 LLVMRustSynchronizationScope Scope
) {
280 return wrap(unwrap(B
)->CreateFence(fromRust(Order
), fromRust(Scope
)));
283 extern "C" void LLVMRustSetDebug(int Enabled
) {
289 enum class LLVMRustAsmDialect
{
295 static InlineAsm::AsmDialect
fromRust(LLVMRustAsmDialect Dialect
) {
297 case LLVMRustAsmDialect::Att
:
298 return InlineAsm::AD_ATT
;
299 case LLVMRustAsmDialect::Intel
:
300 return InlineAsm::AD_Intel
;
302 llvm_unreachable("bad AsmDialect.");
306 extern "C" LLVMValueRef
LLVMRustInlineAsm(LLVMTypeRef Ty
, char *AsmString
,
308 LLVMBool HasSideEffects
,
309 LLVMBool IsAlignStack
,
310 LLVMRustAsmDialect Dialect
) {
311 return wrap(InlineAsm::get(unwrap
<FunctionType
>(Ty
), AsmString
, Constraints
,
312 HasSideEffects
, IsAlignStack
, fromRust(Dialect
)));
315 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M
, const char *Asm
) {
316 unwrap(M
)->appendModuleInlineAsm(StringRef(Asm
));
319 typedef DIBuilder
*LLVMRustDIBuilderRef
;
321 typedef struct LLVMOpaqueMetadata
*LLVMRustMetadataRef
;
324 DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata
, LLVMRustMetadataRef
)
326 inline Metadata
**unwrap(LLVMRustMetadataRef
*Vals
) {
327 return reinterpret_cast<Metadata
**>(Vals
);
331 template <typename DIT
> DIT
*unwrapDIPtr(LLVMRustMetadataRef Ref
) {
332 return (DIT
*)(Ref
? unwrap
<MDNode
>(Ref
) : nullptr);
335 #define DIDescriptor DIScope
336 #define DIArray DINodeArray
337 #define unwrapDI unwrapDIPtr
339 // These values **must** match debuginfo::DIFlags! They also *happen*
340 // to match LLVM, but that isn't required as we do giant sets of
341 // matching below. The value shouldn't be directly passed to LLVM.
342 enum class LLVMRustDIFlags
: uint32_t {
347 FlagFwdDecl
= (1 << 2),
348 FlagAppleBlock
= (1 << 3),
349 FlagBlockByrefStruct
= (1 << 4),
350 FlagVirtual
= (1 << 5),
351 FlagArtificial
= (1 << 6),
352 FlagExplicit
= (1 << 7),
353 FlagPrototyped
= (1 << 8),
354 FlagObjcClassComplete
= (1 << 9),
355 FlagObjectPointer
= (1 << 10),
356 FlagVector
= (1 << 11),
357 FlagStaticMember
= (1 << 12),
358 FlagLValueReference
= (1 << 13),
359 FlagRValueReference
= (1 << 14),
360 FlagMainSubprogram
= (1 << 21),
361 // Do not add values that are not supported by the minimum LLVM
362 // version we support!
365 inline LLVMRustDIFlags
operator&(LLVMRustDIFlags A
, LLVMRustDIFlags B
) {
366 return static_cast<LLVMRustDIFlags
>(static_cast<uint32_t>(A
) &
367 static_cast<uint32_t>(B
));
370 inline LLVMRustDIFlags
operator|(LLVMRustDIFlags A
, LLVMRustDIFlags B
) {
371 return static_cast<LLVMRustDIFlags
>(static_cast<uint32_t>(A
) |
372 static_cast<uint32_t>(B
));
375 inline LLVMRustDIFlags
&operator|=(LLVMRustDIFlags
&A
, LLVMRustDIFlags B
) {
379 inline bool isSet(LLVMRustDIFlags F
) { return F
!= LLVMRustDIFlags::FlagZero
; }
381 inline LLVMRustDIFlags
visibility(LLVMRustDIFlags F
) {
382 return static_cast<LLVMRustDIFlags
>(static_cast<uint32_t>(F
) & 0x3);
385 #if LLVM_VERSION_GE(4, 0)
386 static DINode::DIFlags
fromRust(LLVMRustDIFlags Flags
) {
387 DINode::DIFlags Result
= DINode::DIFlags::FlagZero
;
389 static unsigned fromRust(LLVMRustDIFlags Flags
) {
393 switch (visibility(Flags
)) {
394 case LLVMRustDIFlags::FlagPrivate
:
395 Result
|= DINode::DIFlags::FlagPrivate
;
397 case LLVMRustDIFlags::FlagProtected
:
398 Result
|= DINode::DIFlags::FlagProtected
;
400 case LLVMRustDIFlags::FlagPublic
:
401 Result
|= DINode::DIFlags::FlagPublic
;
404 // The rest are handled below
408 if (isSet(Flags
& LLVMRustDIFlags::FlagFwdDecl
)) {
409 Result
|= DINode::DIFlags::FlagFwdDecl
;
411 if (isSet(Flags
& LLVMRustDIFlags::FlagAppleBlock
)) {
412 Result
|= DINode::DIFlags::FlagAppleBlock
;
414 if (isSet(Flags
& LLVMRustDIFlags::FlagBlockByrefStruct
)) {
415 Result
|= DINode::DIFlags::FlagBlockByrefStruct
;
417 if (isSet(Flags
& LLVMRustDIFlags::FlagVirtual
)) {
418 Result
|= DINode::DIFlags::FlagVirtual
;
420 if (isSet(Flags
& LLVMRustDIFlags::FlagArtificial
)) {
421 Result
|= DINode::DIFlags::FlagArtificial
;
423 if (isSet(Flags
& LLVMRustDIFlags::FlagExplicit
)) {
424 Result
|= DINode::DIFlags::FlagExplicit
;
426 if (isSet(Flags
& LLVMRustDIFlags::FlagPrototyped
)) {
427 Result
|= DINode::DIFlags::FlagPrototyped
;
429 if (isSet(Flags
& LLVMRustDIFlags::FlagObjcClassComplete
)) {
430 Result
|= DINode::DIFlags::FlagObjcClassComplete
;
432 if (isSet(Flags
& LLVMRustDIFlags::FlagObjectPointer
)) {
433 Result
|= DINode::DIFlags::FlagObjectPointer
;
435 if (isSet(Flags
& LLVMRustDIFlags::FlagVector
)) {
436 Result
|= DINode::DIFlags::FlagVector
;
438 if (isSet(Flags
& LLVMRustDIFlags::FlagStaticMember
)) {
439 Result
|= DINode::DIFlags::FlagStaticMember
;
441 if (isSet(Flags
& LLVMRustDIFlags::FlagLValueReference
)) {
442 Result
|= DINode::DIFlags::FlagLValueReference
;
444 if (isSet(Flags
& LLVMRustDIFlags::FlagRValueReference
)) {
445 Result
|= DINode::DIFlags::FlagRValueReference
;
447 #if LLVM_RUSTLLVM || LLVM_VERSION_GE(4, 0)
448 if (isSet(Flags
& LLVMRustDIFlags::FlagMainSubprogram
)) {
449 Result
|= DINode::DIFlags::FlagMainSubprogram
;
456 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
457 return DEBUG_METADATA_VERSION
;
460 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR
; }
462 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR
; }
464 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M
, const char *Name
,
466 unwrap(M
)->addModuleFlag(Module::Warning
, Name
, Value
);
469 extern "C" void LLVMRustMetadataAsValue(LLVMContextRef C
, LLVMRustMetadataRef MD
) {
470 wrap(MetadataAsValue::get(*unwrap(C
), unwrap(MD
)));
473 extern "C" LLVMRustDIBuilderRef
LLVMRustDIBuilderCreate(LLVMModuleRef M
) {
474 return new DIBuilder(*unwrap(M
));
477 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder
) {
481 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder
) {
485 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateCompileUnit(
486 LLVMRustDIBuilderRef Builder
, unsigned Lang
, LLVMRustMetadataRef FileRef
,
487 const char *Producer
, bool isOptimized
, const char *Flags
,
488 unsigned RuntimeVer
, const char *SplitName
) {
489 auto *File
= unwrapDI
<DIFile
>(FileRef
);
491 #if LLVM_VERSION_GE(4, 0)
492 return wrap(Builder
->createCompileUnit(Lang
, File
, Producer
, isOptimized
,
493 Flags
, RuntimeVer
, SplitName
));
495 return wrap(Builder
->createCompileUnit(Lang
, File
->getFilename(),
496 File
->getDirectory(), Producer
, isOptimized
,
497 Flags
, RuntimeVer
, SplitName
));
501 extern "C" LLVMRustMetadataRef
502 LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder
, const char *Filename
,
503 const char *Directory
) {
504 return wrap(Builder
->createFile(Filename
, Directory
));
507 extern "C" LLVMRustMetadataRef
508 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder
,
509 LLVMRustMetadataRef File
,
510 LLVMRustMetadataRef ParameterTypes
) {
511 return wrap(Builder
->createSubroutineType(
512 #if LLVM_VERSION_EQ(3, 7)
513 unwrapDI
<DIFile
>(File
),
515 DITypeRefArray(unwrap
<MDTuple
>(ParameterTypes
))));
518 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateFunction(
519 LLVMRustDIBuilderRef Builder
, LLVMRustMetadataRef Scope
, const char *Name
,
520 const char *LinkageName
, LLVMRustMetadataRef File
, unsigned LineNo
,
521 LLVMRustMetadataRef Ty
, bool IsLocalToUnit
, bool IsDefinition
,
522 unsigned ScopeLine
, LLVMRustDIFlags Flags
, bool IsOptimized
,
523 LLVMValueRef Fn
, LLVMRustMetadataRef TParam
, LLVMRustMetadataRef Decl
) {
524 #if LLVM_VERSION_GE(3, 8)
525 DITemplateParameterArray TParams
=
526 DITemplateParameterArray(unwrap
<MDTuple
>(TParam
));
527 DISubprogram
*Sub
= Builder
->createFunction(
528 unwrapDI
<DIScope
>(Scope
), Name
, LinkageName
, unwrapDI
<DIFile
>(File
),
529 LineNo
, unwrapDI
<DISubroutineType
>(Ty
), IsLocalToUnit
, IsDefinition
,
530 ScopeLine
, fromRust(Flags
), IsOptimized
, TParams
,
531 unwrapDIPtr
<DISubprogram
>(Decl
));
532 unwrap
<Function
>(Fn
)->setSubprogram(Sub
);
535 return wrap(Builder
->createFunction(
536 unwrapDI
<DIScope
>(Scope
), Name
, LinkageName
, unwrapDI
<DIFile
>(File
),
537 LineNo
, unwrapDI
<DISubroutineType
>(Ty
), IsLocalToUnit
, IsDefinition
,
538 ScopeLine
, fromRust(Flags
), IsOptimized
, unwrap
<Function
>(Fn
),
539 unwrapDIPtr
<MDNode
>(TParam
), unwrapDIPtr
<MDNode
>(Decl
)));
543 extern "C" LLVMRustMetadataRef
544 LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder
, const char *Name
,
545 uint64_t SizeInBits
, uint32_t AlignInBits
,
547 return wrap(Builder
->createBasicType(Name
, SizeInBits
,
548 #if LLVM_VERSION_LE(3, 9)
554 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreatePointerType(
555 LLVMRustDIBuilderRef Builder
, LLVMRustMetadataRef PointeeTy
,
556 uint64_t SizeInBits
, uint32_t AlignInBits
, const char *Name
) {
557 return wrap(Builder
->createPointerType(unwrapDI
<DIType
>(PointeeTy
),
558 SizeInBits
, AlignInBits
, Name
));
561 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateStructType(
562 LLVMRustDIBuilderRef Builder
, LLVMRustMetadataRef Scope
, const char *Name
,
563 LLVMRustMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
564 uint32_t AlignInBits
, LLVMRustDIFlags Flags
,
565 LLVMRustMetadataRef DerivedFrom
, LLVMRustMetadataRef Elements
,
566 unsigned RunTimeLang
, LLVMRustMetadataRef VTableHolder
,
567 const char *UniqueId
) {
568 return wrap(Builder
->createStructType(
569 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
570 SizeInBits
, AlignInBits
, fromRust(Flags
), unwrapDI
<DIType
>(DerivedFrom
),
571 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), RunTimeLang
,
572 unwrapDI
<DIType
>(VTableHolder
), UniqueId
));
575 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateMemberType(
576 LLVMRustDIBuilderRef Builder
, LLVMRustMetadataRef Scope
, const char *Name
,
577 LLVMRustMetadataRef File
, unsigned LineNo
, uint64_t SizeInBits
,
578 uint32_t AlignInBits
, uint64_t OffsetInBits
, LLVMRustDIFlags Flags
,
579 LLVMRustMetadataRef Ty
) {
580 return wrap(Builder
->createMemberType(unwrapDI
<DIDescriptor
>(Scope
), Name
,
581 unwrapDI
<DIFile
>(File
), LineNo
,
582 SizeInBits
, AlignInBits
, OffsetInBits
,
583 fromRust(Flags
), unwrapDI
<DIType
>(Ty
)));
586 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateLexicalBlock(
587 LLVMRustDIBuilderRef Builder
, LLVMRustMetadataRef Scope
,
588 LLVMRustMetadataRef File
, unsigned Line
, unsigned Col
) {
589 return wrap(Builder
->createLexicalBlock(unwrapDI
<DIDescriptor
>(Scope
),
590 unwrapDI
<DIFile
>(File
), Line
, Col
));
593 extern "C" LLVMRustMetadataRef
594 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder
,
595 LLVMRustMetadataRef Scope
,
596 LLVMRustMetadataRef File
) {
597 return wrap(Builder
->createLexicalBlockFile(unwrapDI
<DIDescriptor
>(Scope
),
598 unwrapDI
<DIFile
>(File
)));
601 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateStaticVariable(
602 LLVMRustDIBuilderRef Builder
, LLVMRustMetadataRef Context
, const char *Name
,
603 const char *LinkageName
, LLVMRustMetadataRef File
, unsigned LineNo
,
604 LLVMRustMetadataRef Ty
, bool IsLocalToUnit
, LLVMValueRef V
,
605 LLVMRustMetadataRef Decl
= nullptr, uint32_t AlignInBits
= 0) {
606 llvm::GlobalVariable
*InitVal
= cast
<llvm::GlobalVariable
>(unwrap(V
));
608 #if LLVM_VERSION_GE(4, 0)
609 llvm::DIExpression
*InitExpr
= nullptr;
610 if (llvm::ConstantInt
*IntVal
= llvm::dyn_cast
<llvm::ConstantInt
>(InitVal
)) {
611 InitExpr
= Builder
->createConstantValueExpression(
612 IntVal
->getValue().getSExtValue());
613 } else if (llvm::ConstantFP
*FPVal
=
614 llvm::dyn_cast
<llvm::ConstantFP
>(InitVal
)) {
615 InitExpr
= Builder
->createConstantValueExpression(
616 FPVal
->getValueAPF().bitcastToAPInt().getZExtValue());
619 llvm::DIGlobalVariableExpression
*VarExpr
= Builder
->createGlobalVariableExpression(
620 unwrapDI
<DIDescriptor
>(Context
), Name
, LinkageName
,
621 unwrapDI
<DIFile
>(File
), LineNo
, unwrapDI
<DIType
>(Ty
), IsLocalToUnit
,
622 InitExpr
, unwrapDIPtr
<MDNode
>(Decl
), AlignInBits
);
624 InitVal
->setMetadata("dbg", VarExpr
);
626 return wrap(VarExpr
);
628 return wrap(Builder
->createGlobalVariable(
629 unwrapDI
<DIDescriptor
>(Context
), Name
, LinkageName
,
630 unwrapDI
<DIFile
>(File
), LineNo
, unwrapDI
<DIType
>(Ty
), IsLocalToUnit
,
631 InitVal
, unwrapDIPtr
<MDNode
>(Decl
)));
635 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateVariable(
636 LLVMRustDIBuilderRef Builder
, unsigned Tag
, LLVMRustMetadataRef Scope
,
637 const char *Name
, LLVMRustMetadataRef File
, unsigned LineNo
,
638 LLVMRustMetadataRef Ty
, bool AlwaysPreserve
, LLVMRustDIFlags Flags
,
639 unsigned ArgNo
, uint32_t AlignInBits
) {
640 #if LLVM_VERSION_GE(3, 8)
641 if (Tag
== 0x100) { // DW_TAG_auto_variable
642 return wrap(Builder
->createAutoVariable(
643 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNo
,
644 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, fromRust(Flags
)
645 #if LLVM_VERSION_GE(4, 0)
651 return wrap(Builder
->createParameterVariable(
652 unwrapDI
<DIDescriptor
>(Scope
), Name
, ArgNo
, unwrapDI
<DIFile
>(File
),
653 LineNo
, unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, fromRust(Flags
)));
656 return wrap(Builder
->createLocalVariable(
657 Tag
, unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNo
,
658 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, fromRust(Flags
), ArgNo
));
662 extern "C" LLVMRustMetadataRef
663 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder
, uint64_t Size
,
664 uint32_t AlignInBits
, LLVMRustMetadataRef Ty
,
665 LLVMRustMetadataRef Subscripts
) {
667 Builder
->createArrayType(Size
, AlignInBits
, unwrapDI
<DIType
>(Ty
),
668 DINodeArray(unwrapDI
<MDTuple
>(Subscripts
))));
671 extern "C" LLVMRustMetadataRef
672 LLVMRustDIBuilderCreateVectorType(LLVMRustDIBuilderRef Builder
, uint64_t Size
,
673 uint32_t AlignInBits
, LLVMRustMetadataRef Ty
,
674 LLVMRustMetadataRef Subscripts
) {
676 Builder
->createVectorType(Size
, AlignInBits
, unwrapDI
<DIType
>(Ty
),
677 DINodeArray(unwrapDI
<MDTuple
>(Subscripts
))));
680 extern "C" LLVMRustMetadataRef
681 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder
, int64_t Lo
,
683 return wrap(Builder
->getOrCreateSubrange(Lo
, Count
));
686 extern "C" LLVMRustMetadataRef
687 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder
,
688 LLVMRustMetadataRef
*Ptr
, unsigned Count
) {
689 Metadata
**DataValue
= unwrap(Ptr
);
691 Builder
->getOrCreateArray(ArrayRef
<Metadata
*>(DataValue
, Count
)).get());
694 extern "C" LLVMValueRef
LLVMRustDIBuilderInsertDeclareAtEnd(
695 LLVMRustDIBuilderRef Builder
, LLVMValueRef V
, LLVMRustMetadataRef VarInfo
,
696 int64_t *AddrOps
, unsigned AddrOpsCount
, LLVMValueRef DL
,
697 LLVMBasicBlockRef InsertAtEnd
) {
698 return wrap(Builder
->insertDeclare(
699 unwrap(V
), unwrap
<DILocalVariable
>(VarInfo
),
700 Builder
->createExpression(llvm::ArrayRef
<int64_t>(AddrOps
, AddrOpsCount
)),
701 DebugLoc(cast
<MDNode
>(unwrap
<MetadataAsValue
>(DL
)->getMetadata())),
702 unwrap(InsertAtEnd
)));
705 extern "C" LLVMRustMetadataRef
706 LLVMRustDIBuilderCreateEnumerator(LLVMRustDIBuilderRef Builder
,
707 const char *Name
, uint64_t Val
) {
708 return wrap(Builder
->createEnumerator(Name
, Val
));
711 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateEnumerationType(
712 LLVMRustDIBuilderRef Builder
, LLVMRustMetadataRef Scope
, const char *Name
,
713 LLVMRustMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
714 uint32_t AlignInBits
, LLVMRustMetadataRef Elements
,
715 LLVMRustMetadataRef ClassTy
) {
716 return wrap(Builder
->createEnumerationType(
717 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
718 SizeInBits
, AlignInBits
, DINodeArray(unwrapDI
<MDTuple
>(Elements
)),
719 unwrapDI
<DIType
>(ClassTy
)));
722 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateUnionType(
723 LLVMRustDIBuilderRef Builder
, LLVMRustMetadataRef Scope
, const char *Name
,
724 LLVMRustMetadataRef File
, unsigned LineNumber
, uint64_t SizeInBits
,
725 uint32_t AlignInBits
, LLVMRustDIFlags Flags
, LLVMRustMetadataRef Elements
,
726 unsigned RunTimeLang
, const char *UniqueId
) {
727 return wrap(Builder
->createUnionType(
728 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNumber
,
729 SizeInBits
, AlignInBits
, fromRust(Flags
),
730 DINodeArray(unwrapDI
<MDTuple
>(Elements
)), RunTimeLang
, UniqueId
));
733 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateTemplateTypeParameter(
734 LLVMRustDIBuilderRef Builder
, LLVMRustMetadataRef Scope
, const char *Name
,
735 LLVMRustMetadataRef Ty
, LLVMRustMetadataRef File
, unsigned LineNo
,
737 return wrap(Builder
->createTemplateTypeParameter(
738 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIType
>(Ty
)));
741 extern "C" LLVMRustMetadataRef
742 LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder
,
743 LLVMRustMetadataRef Scope
, const char *Name
,
744 LLVMRustMetadataRef File
, unsigned LineNo
) {
745 return wrap(Builder
->createNameSpace(
746 unwrapDI
<DIDescriptor
>(Scope
), Name
, unwrapDI
<DIFile
>(File
), LineNo
747 #if LLVM_VERSION_GE(4, 0)
749 false // ExportSymbols (only relevant for C++ anonymous namespaces)
755 LLVMRustDICompositeTypeSetTypeArray(LLVMRustDIBuilderRef Builder
,
756 LLVMRustMetadataRef CompositeTy
,
757 LLVMRustMetadataRef TyArray
) {
758 DICompositeType
*Tmp
= unwrapDI
<DICompositeType
>(CompositeTy
);
759 Builder
->replaceArrays(Tmp
, DINodeArray(unwrap
<MDTuple
>(TyArray
)));
762 extern "C" LLVMValueRef
763 LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef
, unsigned Line
,
764 unsigned Column
, LLVMRustMetadataRef Scope
,
765 LLVMRustMetadataRef InlinedAt
) {
766 LLVMContext
&Context
= *unwrap(ContextRef
);
768 DebugLoc debug_loc
= DebugLoc::get(Line
, Column
, unwrapDIPtr
<MDNode
>(Scope
),
769 unwrapDIPtr
<MDNode
>(InlinedAt
));
771 return wrap(MetadataAsValue::get(Context
, debug_loc
.getAsMDNode()));
774 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
775 return dwarf::DW_OP_deref
;
778 extern "C" int64_t LLVMRustDIBuilderCreateOpPlus() { return dwarf::DW_OP_plus
; }
780 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty
, RustStringRef Str
) {
781 RawRustStringOstream
OS(Str
);
782 unwrap
<llvm::Type
>(Ty
)->print(OS
);
785 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V
,
787 RawRustStringOstream
OS(Str
);
792 unwrap
<llvm::Value
>(V
)->getType()->print(OS
);
794 unwrap
<llvm::Value
>(V
)->print(OS
);
799 extern "C" bool LLVMRustLinkInExternalBitcode(LLVMModuleRef DstRef
, char *BC
,
801 Module
*Dst
= unwrap(DstRef
);
803 std::unique_ptr
<MemoryBuffer
> Buf
=
804 MemoryBuffer::getMemBufferCopy(StringRef(BC
, Len
));
806 #if LLVM_VERSION_GE(4, 0)
807 Expected
<std::unique_ptr
<Module
>> SrcOrError
=
808 llvm::getLazyBitcodeModule(Buf
->getMemBufferRef(), Dst
->getContext());
810 LLVMRustSetLastError(toString(SrcOrError
.takeError()).c_str());
814 auto Src
= std::move(*SrcOrError
);
816 ErrorOr
<std::unique_ptr
<Module
>> Src
=
817 llvm::getLazyBitcodeModule(std::move(Buf
), Dst
->getContext());
819 LLVMRustSetLastError(Src
.getError().message().c_str());
826 raw_string_ostream
Stream(Err
);
827 DiagnosticPrinterRawOStream
DP(Stream
);
828 #if LLVM_VERSION_GE(4, 0)
829 if (Linker::linkModules(*Dst
, std::move(Src
))) {
830 #elif LLVM_VERSION_GE(3, 8)
831 if (Linker::linkModules(*Dst
, std::move(Src
.get()))) {
833 if (Linker::LinkModules(Dst
, Src
->get(),
834 [&](const DiagnosticInfo
&DI
) { DI
.print(DP
); })) {
836 LLVMRustSetLastError(Err
.c_str());
842 // Note that the two following functions look quite similar to the
843 // LLVMGetSectionName function. Sadly, it appears that this function only
844 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
845 // function provided by LLVM doesn't return the length, so we've created our own
846 // function which returns the length as well as the data pointer.
848 // For an example of this not returning a null terminated string, see
849 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
850 // branches explicitly creates a StringRef without a null terminator, and then
853 inline section_iterator
*unwrap(LLVMSectionIteratorRef SI
) {
854 return reinterpret_cast<section_iterator
*>(SI
);
857 extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI
,
860 if (std::error_code EC
= (*unwrap(SI
))->getName(Ret
))
861 report_fatal_error(EC
.message());
866 // LLVMArrayType function does not support 64-bit ElementCount
867 extern "C" LLVMTypeRef
LLVMRustArrayType(LLVMTypeRef ElementTy
,
868 uint64_t ElementCount
) {
869 return wrap(ArrayType::get(unwrap(ElementTy
), ElementCount
));
872 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine
, LLVMTwineRef
)
873 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc
, LLVMDebugLocRef
)
875 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T
, RustStringRef Str
) {
876 RawRustStringOstream
OS(Str
);
877 unwrap(T
)->print(OS
);
880 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
881 LLVMDiagnosticInfoRef DI
, RustStringRef PassNameOut
,
882 LLVMValueRef
*FunctionOut
, LLVMDebugLocRef
*DebugLocOut
,
883 RustStringRef MessageOut
) {
884 // Undefined to call this not on an optimization diagnostic!
885 llvm::DiagnosticInfoOptimizationBase
*Opt
=
886 static_cast<llvm::DiagnosticInfoOptimizationBase
*>(unwrap(DI
));
888 RawRustStringOstream
PassNameOS(PassNameOut
);
889 PassNameOS
<< Opt
->getPassName();
890 *FunctionOut
= wrap(&Opt
->getFunction());
891 *DebugLocOut
= wrap(&Opt
->getDebugLoc());
892 RawRustStringOstream
MessageOS(MessageOut
);
893 MessageOS
<< Opt
->getMsg();
897 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI
, unsigned *CookieOut
,
898 LLVMTwineRef
*MessageOut
,
899 LLVMValueRef
*InstructionOut
) {
900 // Undefined to call this not on an inline assembly diagnostic!
901 llvm::DiagnosticInfoInlineAsm
*IA
=
902 static_cast<llvm::DiagnosticInfoInlineAsm
*>(unwrap(DI
));
904 *CookieOut
= IA
->getLocCookie();
905 *MessageOut
= wrap(&IA
->getMsgStr());
906 *InstructionOut
= wrap(IA
->getInstruction());
909 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI
,
911 RawRustStringOstream
OS(Str
);
912 DiagnosticPrinterRawOStream
DP(OS
);
913 unwrap(DI
)->print(DP
);
916 enum class LLVMRustDiagnosticKind
{
920 DebugMetadataVersion
,
923 OptimizationRemarkMissed
,
924 OptimizationRemarkAnalysis
,
925 OptimizationRemarkAnalysisFPCommute
,
926 OptimizationRemarkAnalysisAliasing
,
927 OptimizationRemarkOther
,
931 static LLVMRustDiagnosticKind
toRust(DiagnosticKind Kind
) {
934 return LLVMRustDiagnosticKind::InlineAsm
;
936 return LLVMRustDiagnosticKind::StackSize
;
937 case DK_DebugMetadataVersion
:
938 return LLVMRustDiagnosticKind::DebugMetadataVersion
;
939 case DK_SampleProfile
:
940 return LLVMRustDiagnosticKind::SampleProfile
;
941 case DK_OptimizationRemark
:
942 return LLVMRustDiagnosticKind::OptimizationRemark
;
943 case DK_OptimizationRemarkMissed
:
944 return LLVMRustDiagnosticKind::OptimizationRemarkMissed
;
945 case DK_OptimizationRemarkAnalysis
:
946 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis
;
947 #if LLVM_VERSION_GE(3, 8)
948 case DK_OptimizationRemarkAnalysisFPCommute
:
949 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute
;
950 case DK_OptimizationRemarkAnalysisAliasing
:
951 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing
;
954 #if LLVM_VERSION_GE(3, 9)
955 return (Kind
>= DK_FirstRemark
&& Kind
<= DK_LastRemark
)
956 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
957 : LLVMRustDiagnosticKind::Other
;
959 return LLVMRustDiagnosticKind::Other
;
964 extern "C" LLVMRustDiagnosticKind
965 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI
) {
966 return toRust((DiagnosticKind
)unwrap(DI
)->getKind());
968 // This is kept distinct from LLVMGetTypeKind, because when
969 // a new type kind is added, the Rust-side enum must be
970 // updated or UB will result.
971 extern "C" LLVMTypeKind
LLVMRustGetTypeKind(LLVMTypeRef Ty
) {
972 switch (unwrap(Ty
)->getTypeID()) {
974 return LLVMVoidTypeKind
;
976 return LLVMHalfTypeKind
;
977 case Type::FloatTyID
:
978 return LLVMFloatTypeKind
;
979 case Type::DoubleTyID
:
980 return LLVMDoubleTypeKind
;
981 case Type::X86_FP80TyID
:
982 return LLVMX86_FP80TypeKind
;
983 case Type::FP128TyID
:
984 return LLVMFP128TypeKind
;
985 case Type::PPC_FP128TyID
:
986 return LLVMPPC_FP128TypeKind
;
987 case Type::LabelTyID
:
988 return LLVMLabelTypeKind
;
989 case Type::MetadataTyID
:
990 return LLVMMetadataTypeKind
;
991 case Type::IntegerTyID
:
992 return LLVMIntegerTypeKind
;
993 case Type::FunctionTyID
:
994 return LLVMFunctionTypeKind
;
995 case Type::StructTyID
:
996 return LLVMStructTypeKind
;
997 case Type::ArrayTyID
:
998 return LLVMArrayTypeKind
;
999 case Type::PointerTyID
:
1000 return LLVMPointerTypeKind
;
1001 case Type::VectorTyID
:
1002 return LLVMVectorTypeKind
;
1003 case Type::X86_MMXTyID
:
1004 return LLVMX86_MMXTypeKind
;
1005 #if LLVM_VERSION_GE(3, 8)
1006 case Type::TokenTyID
:
1007 return LLVMTokenTypeKind
;
1010 llvm_unreachable("Unhandled TypeID.");
1013 extern "C" void LLVMRustWriteDebugLocToString(LLVMContextRef C
,
1015 RustStringRef Str
) {
1016 RawRustStringOstream
OS(Str
);
1017 unwrap(DL
)->print(OS
);
1020 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic
, LLVMSMDiagnosticRef
)
1022 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1023 LLVMContextRef C
, LLVMContext::InlineAsmDiagHandlerTy H
, void *CX
) {
1024 unwrap(C
)->setInlineAsmDiagnosticHandler(H
, CX
);
1027 extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef D
,
1028 RustStringRef Str
) {
1029 RawRustStringOstream
OS(Str
);
1030 unwrap(D
)->print("", OS
);
1033 extern "C" LLVMValueRef
1034 LLVMRustBuildLandingPad(LLVMBuilderRef B
, LLVMTypeRef Ty
,
1035 LLVMValueRef PersFn
, unsigned NumClauses
,
1036 const char *Name
, LLVMValueRef F
) {
1037 return LLVMBuildLandingPad(B
, Ty
, PersFn
, NumClauses
, Name
);
1040 extern "C" LLVMValueRef
LLVMRustBuildCleanupPad(LLVMBuilderRef B
,
1041 LLVMValueRef ParentPad
,
1043 LLVMValueRef
*LLArgs
,
1045 #if LLVM_VERSION_GE(3, 8)
1046 Value
**Args
= unwrap(LLArgs
);
1047 if (ParentPad
== nullptr) {
1048 Type
*Ty
= Type::getTokenTy(unwrap(B
)->getContext());
1049 ParentPad
= wrap(Constant::getNullValue(Ty
));
1051 return wrap(unwrap(B
)->CreateCleanupPad(
1052 unwrap(ParentPad
), ArrayRef
<Value
*>(Args
, ArgCount
), Name
));
1058 extern "C" LLVMValueRef
LLVMRustBuildCleanupRet(LLVMBuilderRef B
,
1059 LLVMValueRef CleanupPad
,
1060 LLVMBasicBlockRef UnwindBB
) {
1061 #if LLVM_VERSION_GE(3, 8)
1062 CleanupPadInst
*Inst
= cast
<CleanupPadInst
>(unwrap(CleanupPad
));
1063 return wrap(unwrap(B
)->CreateCleanupRet(Inst
, unwrap(UnwindBB
)));
1069 extern "C" LLVMValueRef
1070 LLVMRustBuildCatchPad(LLVMBuilderRef B
, LLVMValueRef ParentPad
,
1071 unsigned ArgCount
, LLVMValueRef
*LLArgs
, const char *Name
) {
1072 #if LLVM_VERSION_GE(3, 8)
1073 Value
**Args
= unwrap(LLArgs
);
1074 return wrap(unwrap(B
)->CreateCatchPad(
1075 unwrap(ParentPad
), ArrayRef
<Value
*>(Args
, ArgCount
), Name
));
1081 extern "C" LLVMValueRef
LLVMRustBuildCatchRet(LLVMBuilderRef B
,
1083 LLVMBasicBlockRef BB
) {
1084 #if LLVM_VERSION_GE(3, 8)
1085 return wrap(unwrap(B
)->CreateCatchRet(cast
<CatchPadInst
>(unwrap(Pad
)),
1092 extern "C" LLVMValueRef
LLVMRustBuildCatchSwitch(LLVMBuilderRef B
,
1093 LLVMValueRef ParentPad
,
1094 LLVMBasicBlockRef BB
,
1095 unsigned NumHandlers
,
1097 #if LLVM_VERSION_GE(3, 8)
1098 if (ParentPad
== nullptr) {
1099 Type
*Ty
= Type::getTokenTy(unwrap(B
)->getContext());
1100 ParentPad
= wrap(Constant::getNullValue(Ty
));
1102 return wrap(unwrap(B
)->CreateCatchSwitch(unwrap(ParentPad
), unwrap(BB
),
1103 NumHandlers
, Name
));
1109 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef
,
1110 LLVMBasicBlockRef Handler
) {
1111 #if LLVM_VERSION_GE(3, 8)
1112 Value
*CatchSwitch
= unwrap(CatchSwitchRef
);
1113 cast
<CatchSwitchInst
>(CatchSwitch
)->addHandler(unwrap(Handler
));
1117 #if LLVM_VERSION_GE(3, 8)
1118 extern "C" OperandBundleDef
*LLVMRustBuildOperandBundleDef(const char *Name
,
1119 LLVMValueRef
*Inputs
,
1120 unsigned NumInputs
) {
1121 return new OperandBundleDef(Name
, makeArrayRef(unwrap(Inputs
), NumInputs
));
1124 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef
*Bundle
) {
1128 extern "C" LLVMValueRef
LLVMRustBuildCall(LLVMBuilderRef B
, LLVMValueRef Fn
,
1129 LLVMValueRef
*Args
, unsigned NumArgs
,
1130 OperandBundleDef
*Bundle
,
1132 unsigned Len
= Bundle
? 1 : 0;
1133 ArrayRef
<OperandBundleDef
> Bundles
= makeArrayRef(Bundle
, Len
);
1134 return wrap(unwrap(B
)->CreateCall(
1135 unwrap(Fn
), makeArrayRef(unwrap(Args
), NumArgs
), Bundles
, Name
));
1138 extern "C" LLVMValueRef
1139 LLVMRustBuildInvoke(LLVMBuilderRef B
, LLVMValueRef Fn
, LLVMValueRef
*Args
,
1140 unsigned NumArgs
, LLVMBasicBlockRef Then
,
1141 LLVMBasicBlockRef Catch
, OperandBundleDef
*Bundle
,
1143 unsigned Len
= Bundle
? 1 : 0;
1144 ArrayRef
<OperandBundleDef
> Bundles
= makeArrayRef(Bundle
, Len
);
1145 return wrap(unwrap(B
)->CreateInvoke(unwrap(Fn
), unwrap(Then
), unwrap(Catch
),
1146 makeArrayRef(unwrap(Args
), NumArgs
),
1150 extern "C" void *LLVMRustBuildOperandBundleDef(const char *Name
,
1151 LLVMValueRef
*Inputs
,
1152 unsigned NumInputs
) {
1156 extern "C" void LLVMRustFreeOperandBundleDef(void *Bundle
) {}
1158 extern "C" LLVMValueRef
LLVMRustBuildCall(LLVMBuilderRef B
, LLVMValueRef Fn
,
1159 LLVMValueRef
*Args
, unsigned NumArgs
,
1160 void *Bundle
, const char *Name
) {
1161 return LLVMBuildCall(B
, Fn
, Args
, NumArgs
, Name
);
1164 extern "C" LLVMValueRef
1165 LLVMRustBuildInvoke(LLVMBuilderRef B
, LLVMValueRef Fn
, LLVMValueRef
*Args
,
1166 unsigned NumArgs
, LLVMBasicBlockRef Then
,
1167 LLVMBasicBlockRef Catch
, void *Bundle
, const char *Name
) {
1168 return LLVMBuildInvoke(B
, Fn
, Args
, NumArgs
, Then
, Catch
, Name
);
1172 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B
,
1173 LLVMBasicBlockRef BB
) {
1174 auto Point
= unwrap(BB
)->getFirstInsertionPt();
1175 unwrap(B
)->SetInsertPoint(unwrap(BB
), Point
);
1178 extern "C" void LLVMRustSetComdat(LLVMModuleRef M
, LLVMValueRef V
,
1180 Triple
TargetTriple(unwrap(M
)->getTargetTriple());
1181 GlobalObject
*GV
= unwrap
<GlobalObject
>(V
);
1182 if (!TargetTriple
.isOSBinFormatMachO()) {
1183 GV
->setComdat(unwrap(M
)->getOrInsertComdat(Name
));
1187 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V
) {
1188 GlobalObject
*GV
= unwrap
<GlobalObject
>(V
);
1189 GV
->setComdat(nullptr);
1192 enum class LLVMRustLinkage
{
1193 ExternalLinkage
= 0,
1194 AvailableExternallyLinkage
= 1,
1195 LinkOnceAnyLinkage
= 2,
1196 LinkOnceODRLinkage
= 3,
1199 AppendingLinkage
= 6,
1200 InternalLinkage
= 7,
1202 ExternalWeakLinkage
= 9,
1206 static LLVMRustLinkage
toRust(LLVMLinkage Linkage
) {
1208 case LLVMExternalLinkage
:
1209 return LLVMRustLinkage::ExternalLinkage
;
1210 case LLVMAvailableExternallyLinkage
:
1211 return LLVMRustLinkage::AvailableExternallyLinkage
;
1212 case LLVMLinkOnceAnyLinkage
:
1213 return LLVMRustLinkage::LinkOnceAnyLinkage
;
1214 case LLVMLinkOnceODRLinkage
:
1215 return LLVMRustLinkage::LinkOnceODRLinkage
;
1216 case LLVMWeakAnyLinkage
:
1217 return LLVMRustLinkage::WeakAnyLinkage
;
1218 case LLVMWeakODRLinkage
:
1219 return LLVMRustLinkage::WeakODRLinkage
;
1220 case LLVMAppendingLinkage
:
1221 return LLVMRustLinkage::AppendingLinkage
;
1222 case LLVMInternalLinkage
:
1223 return LLVMRustLinkage::InternalLinkage
;
1224 case LLVMPrivateLinkage
:
1225 return LLVMRustLinkage::PrivateLinkage
;
1226 case LLVMExternalWeakLinkage
:
1227 return LLVMRustLinkage::ExternalWeakLinkage
;
1228 case LLVMCommonLinkage
:
1229 return LLVMRustLinkage::CommonLinkage
;
1231 llvm_unreachable("Invalid LLVMRustLinkage value!");
1235 static LLVMLinkage
fromRust(LLVMRustLinkage Linkage
) {
1237 case LLVMRustLinkage::ExternalLinkage
:
1238 return LLVMExternalLinkage
;
1239 case LLVMRustLinkage::AvailableExternallyLinkage
:
1240 return LLVMAvailableExternallyLinkage
;
1241 case LLVMRustLinkage::LinkOnceAnyLinkage
:
1242 return LLVMLinkOnceAnyLinkage
;
1243 case LLVMRustLinkage::LinkOnceODRLinkage
:
1244 return LLVMLinkOnceODRLinkage
;
1245 case LLVMRustLinkage::WeakAnyLinkage
:
1246 return LLVMWeakAnyLinkage
;
1247 case LLVMRustLinkage::WeakODRLinkage
:
1248 return LLVMWeakODRLinkage
;
1249 case LLVMRustLinkage::AppendingLinkage
:
1250 return LLVMAppendingLinkage
;
1251 case LLVMRustLinkage::InternalLinkage
:
1252 return LLVMInternalLinkage
;
1253 case LLVMRustLinkage::PrivateLinkage
:
1254 return LLVMPrivateLinkage
;
1255 case LLVMRustLinkage::ExternalWeakLinkage
:
1256 return LLVMExternalWeakLinkage
;
1257 case LLVMRustLinkage::CommonLinkage
:
1258 return LLVMCommonLinkage
;
1260 llvm_unreachable("Invalid LLVMRustLinkage value!");
1263 extern "C" LLVMRustLinkage
LLVMRustGetLinkage(LLVMValueRef V
) {
1264 return toRust(LLVMGetLinkage(V
));
1267 extern "C" void LLVMRustSetLinkage(LLVMValueRef V
,
1268 LLVMRustLinkage RustLinkage
) {
1269 LLVMSetLinkage(V
, fromRust(RustLinkage
));
1272 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1273 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1274 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV
, bool sext
, uint64_t *high
, uint64_t *low
)
1276 auto C
= unwrap
<llvm::ConstantInt
>(CV
);
1277 if (C
->getBitWidth() > 128) { return false; }
1280 AP
= C
->getValue().sextOrSelf(128);
1282 AP
= C
->getValue().zextOrSelf(128);
1284 *low
= AP
.getLoBits(64).getZExtValue();
1285 *high
= AP
.getHiBits(64).getZExtValue();
1289 extern "C" LLVMContextRef
LLVMRustGetValueContext(LLVMValueRef V
) {
1290 return wrap(&unwrap(V
)->getContext());
1293 enum class LLVMRustVisibility
{
1299 static LLVMRustVisibility
toRust(LLVMVisibility Vis
) {
1301 case LLVMDefaultVisibility
:
1302 return LLVMRustVisibility::Default
;
1303 case LLVMHiddenVisibility
:
1304 return LLVMRustVisibility::Hidden
;
1305 case LLVMProtectedVisibility
:
1306 return LLVMRustVisibility::Protected
;
1308 llvm_unreachable("Invalid LLVMRustVisibility value!");
1311 static LLVMVisibility
fromRust(LLVMRustVisibility Vis
) {
1313 case LLVMRustVisibility::Default
:
1314 return LLVMDefaultVisibility
;
1315 case LLVMRustVisibility::Hidden
:
1316 return LLVMHiddenVisibility
;
1317 case LLVMRustVisibility::Protected
:
1318 return LLVMProtectedVisibility
;
1320 llvm_unreachable("Invalid LLVMRustVisibility value!");
1323 extern "C" LLVMRustVisibility
LLVMRustGetVisibility(LLVMValueRef V
) {
1324 return toRust(LLVMGetVisibility(V
));
1327 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1328 extern "C" LLVMValueRef
LLVMRustBuildIntCast(LLVMBuilderRef B
, LLVMValueRef Val
,
1329 LLVMTypeRef DestTy
, bool isSigned
) {
1330 return wrap(unwrap(B
)->CreateIntCast(unwrap(Val
), unwrap(DestTy
), isSigned
, ""));
1333 extern "C" void LLVMRustSetVisibility(LLVMValueRef V
,
1334 LLVMRustVisibility RustVisibility
) {
1335 LLVMSetVisibility(V
, fromRust(RustVisibility
));