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/Object/Archive.h"
13 #include "llvm/Object/ObjectFile.h"
14 #include "llvm/IR/DiagnosticInfo.h"
15 #include "llvm/IR/DiagnosticPrinter.h"
16 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/CallSite.h"
20 //===----------------------------------------------------------------------===
22 // This file defines alternate interfaces to core functions that are more
23 // readily callable by Rust's FFI.
25 //===----------------------------------------------------------------------===
28 using namespace llvm::sys
;
29 using namespace llvm::object
;
31 // LLVMAtomicOrdering is already an enum - don't create another
33 static AtomicOrdering
from_rust(LLVMAtomicOrdering Ordering
) {
35 case LLVMAtomicOrderingNotAtomic
:
36 return AtomicOrdering::NotAtomic
;
37 case LLVMAtomicOrderingUnordered
:
38 return AtomicOrdering::Unordered
;
39 case LLVMAtomicOrderingMonotonic
:
40 return AtomicOrdering::Monotonic
;
41 case LLVMAtomicOrderingAcquire
:
42 return AtomicOrdering::Acquire
;
43 case LLVMAtomicOrderingRelease
:
44 return AtomicOrdering::Release
;
45 case LLVMAtomicOrderingAcquireRelease
:
46 return AtomicOrdering::AcquireRelease
;
47 case LLVMAtomicOrderingSequentiallyConsistent
:
48 return AtomicOrdering::SequentiallyConsistent
;
51 llvm_unreachable("Invalid LLVMAtomicOrdering value!");
55 static char *LastError
;
57 extern "C" LLVMMemoryBufferRef
58 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path
) {
59 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> buf_or
= MemoryBuffer::getFile(Path
,
63 LLVMRustSetLastError(buf_or
.getError().message().c_str());
66 return wrap(buf_or
.get().release());
69 extern "C" char *LLVMRustGetLastError(void) {
70 char *ret
= LastError
;
75 void LLVMRustSetLastError(const char *err
) {
76 free((void*) LastError
);
77 LastError
= strdup(err
);
81 LLVMRustSetNormalizedTarget(LLVMModuleRef M
, const char *triple
) {
82 unwrap(M
)->setTargetTriple(Triple::normalize(triple
));
85 extern "C" void LLVMRustPrintPassTimings() {
86 raw_fd_ostream
OS (2, false); // stderr.
87 TimerGroup::printAll(OS
);
90 extern "C" LLVMValueRef
LLVMRustGetNamedValue(LLVMModuleRef M
,
92 return wrap(unwrap(M
)->getNamedValue(Name
));
95 extern "C" LLVMValueRef
LLVMRustGetOrInsertFunction(LLVMModuleRef M
,
97 LLVMTypeRef FunctionTy
) {
98 return wrap(unwrap(M
)->getOrInsertFunction(Name
,
99 unwrap
<FunctionType
>(FunctionTy
)));
102 extern "C" LLVMValueRef
LLVMRustGetOrInsertGlobal(LLVMModuleRef M
,
105 return wrap(unwrap(M
)->getOrInsertGlobal(Name
, unwrap(Ty
)));
108 extern "C" LLVMTypeRef
LLVMRustMetadataTypeInContext(LLVMContextRef C
) {
109 return wrap(Type::getMetadataTy(*unwrap(C
)));
112 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr
, unsigned index
, uint64_t Val
) {
113 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
117 Call
.getAttributes().addAttributes(Call
->getContext(), index
,
118 AttributeSet::get(Call
->getContext(),
123 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr
,
127 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
129 B
.addDereferenceableAttr(b
);
131 Call
.getAttributes().addAttributes(Call
->getContext(), idx
,
132 AttributeSet::get(Call
->getContext(),
136 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn
,
140 Function
*A
= unwrap
<Function
>(Fn
);
143 A
->addAttributes(index
, AttributeSet::get(A
->getContext(), index
, B
));
146 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn
,
150 Function
*A
= unwrap
<Function
>(Fn
);
152 B
.addDereferenceableAttr(bytes
);
153 A
->addAttributes(index
, AttributeSet::get(A
->getContext(), index
, B
));
156 extern "C" void LLVMRustAddFunctionAttrString(LLVMValueRef Fn
,
160 Function
*F
= unwrap
<Function
>(Fn
);
162 B
.addAttribute(Name
);
163 F
->addAttributes(index
, AttributeSet::get(F
->getContext(), index
, B
));
166 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn
,
170 Function
*F
= unwrap
<Function
>(Fn
);
172 B
.addAttribute(Name
, Value
);
173 F
->addAttributes(index
, AttributeSet::get(F
->getContext(), index
, B
));
176 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn
,
180 Function
*A
= unwrap
<Function
>(Fn
);
181 const AttributeSet PAL
= A
->getAttributes();
183 const AttributeSet PALnew
=
184 PAL
.removeAttributes(A
->getContext(), index
,
185 AttributeSet::get(A
->getContext(), index
, B
));
186 A
->setAttributes(PALnew
);
189 extern "C" void LLVMRustRemoveFunctionAttrString(LLVMValueRef fn
,
193 Function
*f
= unwrap
<Function
>(fn
);
194 LLVMContext
&C
= f
->getContext();
196 B
.addAttribute(Name
);
197 AttributeSet to_remove
= AttributeSet::get(C
, index
, B
);
199 AttributeSet attrs
= f
->getAttributes();
200 f
->setAttributes(attrs
.removeAttributes(f
->getContext(),
205 // enable fpmath flag UnsafeAlgebra
206 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V
) {
207 if (auto I
= dyn_cast
<Instruction
>(unwrap
<Value
>(V
))) {
208 I
->setHasUnsafeAlgebra(true);
212 extern "C" LLVMValueRef
LLVMRustBuildAtomicLoad(LLVMBuilderRef B
,
215 LLVMAtomicOrdering order
,
216 unsigned alignment
) {
217 LoadInst
* li
= new LoadInst(unwrap(source
),0);
218 li
->setAtomic(from_rust(order
));
219 li
->setAlignment(alignment
);
220 return wrap(unwrap(B
)->Insert(li
, Name
));
223 extern "C" LLVMValueRef
LLVMRustBuildAtomicStore(LLVMBuilderRef B
,
226 LLVMAtomicOrdering order
,
227 unsigned alignment
) {
228 StoreInst
* si
= new StoreInst(unwrap(val
),unwrap(target
));
229 si
->setAtomic(from_rust(order
));
230 si
->setAlignment(alignment
);
231 return wrap(unwrap(B
)->Insert(si
));
234 extern "C" LLVMValueRef
LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B
,
238 LLVMAtomicOrdering order
,
239 LLVMAtomicOrdering failure_order
,
241 AtomicCmpXchgInst
* acxi
= unwrap(B
)->CreateAtomicCmpXchg(
246 from_rust(failure_order
));
251 enum class LLVMRustSynchronizationScope
{
257 static SynchronizationScope
258 from_rust(LLVMRustSynchronizationScope scope
)
261 case LLVMRustSynchronizationScope::SingleThread
:
263 case LLVMRustSynchronizationScope::CrossThread
:
266 llvm_unreachable("bad SynchronizationScope.");
270 extern "C" LLVMValueRef
LLVMRustBuildAtomicFence(
272 LLVMAtomicOrdering order
,
273 LLVMRustSynchronizationScope scope
)
275 return wrap(unwrap(B
)->CreateFence(from_rust(order
), from_rust(scope
)));
278 extern "C" void LLVMRustSetDebug(int Enabled
) {
284 enum class LLVMRustAsmDialect
{
290 static InlineAsm::AsmDialect
291 from_rust(LLVMRustAsmDialect dialect
)
294 case LLVMRustAsmDialect::Att
:
295 return InlineAsm::AD_ATT
;
296 case LLVMRustAsmDialect::Intel
:
297 return InlineAsm::AD_Intel
;
299 llvm_unreachable("bad AsmDialect.");
303 extern "C" LLVMValueRef
LLVMRustInlineAsm(LLVMTypeRef Ty
,
306 LLVMBool HasSideEffects
,
307 LLVMBool IsAlignStack
,
308 LLVMRustAsmDialect Dialect
) {
309 return wrap(InlineAsm::get(unwrap
<FunctionType
>(Ty
), AsmString
,
310 Constraints
, HasSideEffects
,
311 IsAlignStack
, from_rust(Dialect
)));
314 typedef DIBuilder
* LLVMRustDIBuilderRef
;
316 typedef struct LLVMOpaqueMetadata
*LLVMRustMetadataRef
;
319 DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata
, LLVMRustMetadataRef
)
321 inline Metadata
**unwrap(LLVMRustMetadataRef
*Vals
) {
322 return reinterpret_cast<Metadata
**>(Vals
);
326 template<typename DIT
>
327 DIT
* unwrapDIptr(LLVMRustMetadataRef ref
) {
328 return (DIT
*) (ref
? unwrap
<MDNode
>(ref
) : NULL
);
331 #define DIDescriptor DIScope
332 #define DIArray DINodeArray
333 #define unwrapDI unwrapDIptr
335 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
336 return DEBUG_METADATA_VERSION
;
339 extern "C" uint32_t LLVMRustVersionMinor() {
340 return LLVM_VERSION_MINOR
;
343 extern "C" uint32_t LLVMRustVersionMajor() {
344 return LLVM_VERSION_MAJOR
;
347 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M
,
350 unwrap(M
)->addModuleFlag(Module::Warning
, name
, value
);
353 extern "C" LLVMRustDIBuilderRef
LLVMRustDIBuilderCreate(LLVMModuleRef M
) {
354 return new DIBuilder(*unwrap(M
));
357 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder
) {
361 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder
) {
365 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateCompileUnit(
366 LLVMRustDIBuilderRef Builder
,
370 const char* Producer
,
374 const char* SplitName
) {
375 return wrap(Builder
->createCompileUnit(Lang
,
385 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateFile(
386 LLVMRustDIBuilderRef Builder
,
387 const char* Filename
,
388 const char* Directory
) {
389 return wrap(Builder
->createFile(Filename
, Directory
));
392 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateSubroutineType(
393 LLVMRustDIBuilderRef Builder
,
394 LLVMRustMetadataRef File
,
395 LLVMRustMetadataRef ParameterTypes
) {
396 return wrap(Builder
->createSubroutineType(
397 #if LLVM_VERSION_MINOR == 7
398 unwrapDI
<DIFile
>(File
),
400 DITypeRefArray(unwrap
<MDTuple
>(ParameterTypes
))));
403 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateFunction(
404 LLVMRustDIBuilderRef Builder
,
405 LLVMRustMetadataRef Scope
,
407 const char* LinkageName
,
408 LLVMRustMetadataRef File
,
410 LLVMRustMetadataRef Ty
,
417 LLVMRustMetadataRef TParam
,
418 LLVMRustMetadataRef Decl
) {
419 #if LLVM_VERSION_MINOR >= 8
420 DITemplateParameterArray TParams
=
421 DITemplateParameterArray(unwrap
<MDTuple
>(TParam
));
422 DISubprogram
*Sub
= Builder
->createFunction(
423 unwrapDI
<DIScope
>(Scope
), Name
, LinkageName
,
424 unwrapDI
<DIFile
>(File
), LineNo
,
425 unwrapDI
<DISubroutineType
>(Ty
), isLocalToUnit
, isDefinition
, ScopeLine
,
428 unwrapDIptr
<DISubprogram
>(Decl
));
429 unwrap
<Function
>(Fn
)->setSubprogram(Sub
);
432 return wrap(Builder
->createFunction(
433 unwrapDI
<DIScope
>(Scope
), Name
, LinkageName
,
434 unwrapDI
<DIFile
>(File
), LineNo
,
435 unwrapDI
<DISubroutineType
>(Ty
), isLocalToUnit
, isDefinition
, ScopeLine
,
437 unwrap
<Function
>(Fn
),
438 unwrapDIptr
<MDNode
>(TParam
),
439 unwrapDIptr
<MDNode
>(Decl
)));
443 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateBasicType(
444 LLVMRustDIBuilderRef Builder
,
447 uint64_t AlignInBits
,
449 return wrap(Builder
->createBasicType(
451 AlignInBits
, Encoding
));
454 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreatePointerType(
455 LLVMRustDIBuilderRef Builder
,
456 LLVMRustMetadataRef PointeeTy
,
458 uint64_t AlignInBits
,
460 return wrap(Builder
->createPointerType(
461 unwrapDI
<DIType
>(PointeeTy
), SizeInBits
, AlignInBits
, Name
));
464 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateStructType(
465 LLVMRustDIBuilderRef Builder
,
466 LLVMRustMetadataRef Scope
,
468 LLVMRustMetadataRef File
,
471 uint64_t AlignInBits
,
473 LLVMRustMetadataRef DerivedFrom
,
474 LLVMRustMetadataRef Elements
,
475 unsigned RunTimeLang
,
476 LLVMRustMetadataRef VTableHolder
,
477 const char *UniqueId
) {
478 return wrap(Builder
->createStructType(
479 unwrapDI
<DIDescriptor
>(Scope
),
481 unwrapDI
<DIFile
>(File
),
486 unwrapDI
<DIType
>(DerivedFrom
),
487 DINodeArray(unwrapDI
<MDTuple
>(Elements
)),
489 unwrapDI
<DIType
>(VTableHolder
),
494 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateMemberType(
495 LLVMRustDIBuilderRef Builder
,
496 LLVMRustMetadataRef Scope
,
498 LLVMRustMetadataRef File
,
501 uint64_t AlignInBits
,
502 uint64_t OffsetInBits
,
504 LLVMRustMetadataRef Ty
) {
505 return wrap(Builder
->createMemberType(
506 unwrapDI
<DIDescriptor
>(Scope
), Name
,
507 unwrapDI
<DIFile
>(File
), LineNo
,
508 SizeInBits
, AlignInBits
, OffsetInBits
, Flags
,
509 unwrapDI
<DIType
>(Ty
)));
512 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateLexicalBlock(
513 LLVMRustDIBuilderRef Builder
,
514 LLVMRustMetadataRef Scope
,
515 LLVMRustMetadataRef File
,
518 return wrap(Builder
->createLexicalBlock(
519 unwrapDI
<DIDescriptor
>(Scope
),
520 unwrapDI
<DIFile
>(File
), Line
, Col
524 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateStaticVariable(
525 LLVMRustDIBuilderRef Builder
,
526 LLVMRustMetadataRef Context
,
528 const char* LinkageName
,
529 LLVMRustMetadataRef File
,
531 LLVMRustMetadataRef Ty
,
534 LLVMRustMetadataRef Decl
= NULL
) {
535 return wrap(Builder
->createGlobalVariable(unwrapDI
<DIDescriptor
>(Context
),
538 unwrapDI
<DIFile
>(File
),
540 unwrapDI
<DIType
>(Ty
),
542 cast
<Constant
>(unwrap(Val
)),
543 unwrapDIptr
<MDNode
>(Decl
)));
546 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateVariable(
547 LLVMRustDIBuilderRef Builder
,
549 LLVMRustMetadataRef Scope
,
551 LLVMRustMetadataRef File
,
553 LLVMRustMetadataRef Ty
,
557 unsigned AddrOpsCount
,
559 #if LLVM_VERSION_MINOR >= 8
560 if (Tag
== 0x100) { // DW_TAG_auto_variable
561 return wrap(Builder
->createAutoVariable(
562 unwrapDI
<DIDescriptor
>(Scope
), Name
,
563 unwrapDI
<DIFile
>(File
),
565 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, Flags
));
567 return wrap(Builder
->createParameterVariable(
568 unwrapDI
<DIDescriptor
>(Scope
), Name
, ArgNo
,
569 unwrapDI
<DIFile
>(File
),
571 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, Flags
));
574 return wrap(Builder
->createLocalVariable(Tag
,
575 unwrapDI
<DIDescriptor
>(Scope
), Name
,
576 unwrapDI
<DIFile
>(File
),
578 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, Flags
, ArgNo
));
582 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateArrayType(
583 LLVMRustDIBuilderRef Builder
,
585 uint64_t AlignInBits
,
586 LLVMRustMetadataRef Ty
,
587 LLVMRustMetadataRef Subscripts
) {
588 return wrap(Builder
->createArrayType(Size
, AlignInBits
,
589 unwrapDI
<DIType
>(Ty
),
590 DINodeArray(unwrapDI
<MDTuple
>(Subscripts
))
594 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateVectorType(
595 LLVMRustDIBuilderRef Builder
,
597 uint64_t AlignInBits
,
598 LLVMRustMetadataRef Ty
,
599 LLVMRustMetadataRef Subscripts
) {
600 return wrap(Builder
->createVectorType(Size
, AlignInBits
,
601 unwrapDI
<DIType
>(Ty
),
602 DINodeArray(unwrapDI
<MDTuple
>(Subscripts
))
606 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderGetOrCreateSubrange(
607 LLVMRustDIBuilderRef Builder
,
610 return wrap(Builder
->getOrCreateSubrange(Lo
, Count
));
613 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderGetOrCreateArray(
614 LLVMRustDIBuilderRef Builder
,
615 LLVMRustMetadataRef
* Ptr
,
617 Metadata
**DataValue
= unwrap(Ptr
);
618 return wrap(Builder
->getOrCreateArray(
619 ArrayRef
<Metadata
*>(DataValue
, Count
)).get());
622 extern "C" LLVMValueRef
LLVMRustDIBuilderInsertDeclareAtEnd(
623 LLVMRustDIBuilderRef Builder
,
625 LLVMRustMetadataRef VarInfo
,
627 unsigned AddrOpsCount
,
629 LLVMBasicBlockRef InsertAtEnd
) {
630 return wrap(Builder
->insertDeclare(
632 unwrap
<DILocalVariable
>(VarInfo
),
633 Builder
->createExpression(
634 llvm::ArrayRef
<int64_t>(AddrOps
, AddrOpsCount
)),
635 DebugLoc(cast
<MDNode
>(unwrap
<MetadataAsValue
>(DL
)->getMetadata())),
636 unwrap(InsertAtEnd
)));
639 extern "C" LLVMValueRef
LLVMRustDIBuilderInsertDeclareBefore(
640 LLVMRustDIBuilderRef Builder
,
642 LLVMRustMetadataRef VarInfo
,
644 unsigned AddrOpsCount
,
646 LLVMValueRef InsertBefore
) {
647 return wrap(Builder
->insertDeclare(
649 unwrap
<DILocalVariable
>(VarInfo
),
650 Builder
->createExpression(
651 llvm::ArrayRef
<int64_t>(AddrOps
, AddrOpsCount
)),
652 DebugLoc(cast
<MDNode
>(unwrap
<MetadataAsValue
>(DL
)->getMetadata())),
653 unwrap
<Instruction
>(InsertBefore
)));
656 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateEnumerator(
657 LLVMRustDIBuilderRef Builder
,
661 return wrap(Builder
->createEnumerator(Name
, Val
));
664 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateEnumerationType(
665 LLVMRustDIBuilderRef Builder
,
666 LLVMRustMetadataRef Scope
,
668 LLVMRustMetadataRef File
,
671 uint64_t AlignInBits
,
672 LLVMRustMetadataRef Elements
,
673 LLVMRustMetadataRef ClassType
)
675 return wrap(Builder
->createEnumerationType(
676 unwrapDI
<DIDescriptor
>(Scope
),
678 unwrapDI
<DIFile
>(File
),
682 DINodeArray(unwrapDI
<MDTuple
>(Elements
)),
683 unwrapDI
<DIType
>(ClassType
)));
686 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateUnionType(
687 LLVMRustDIBuilderRef Builder
,
688 LLVMRustMetadataRef Scope
,
690 LLVMRustMetadataRef File
,
693 uint64_t AlignInBits
,
695 LLVMRustMetadataRef Elements
,
696 unsigned RunTimeLang
,
697 const char* UniqueId
)
699 return wrap(Builder
->createUnionType(
700 unwrapDI
<DIDescriptor
>(Scope
),
702 unwrapDI
<DIFile
>(File
),
707 DINodeArray(unwrapDI
<MDTuple
>(Elements
)),
713 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateTemplateTypeParameter(
714 LLVMRustDIBuilderRef Builder
,
715 LLVMRustMetadataRef Scope
,
717 LLVMRustMetadataRef Ty
,
718 LLVMRustMetadataRef File
,
722 return wrap(Builder
->createTemplateTypeParameter(
723 unwrapDI
<DIDescriptor
>(Scope
),
729 extern "C" LLVMRustMetadataRef
LLVMRustDIBuilderCreateNameSpace(
730 LLVMRustDIBuilderRef Builder
,
731 LLVMRustMetadataRef Scope
,
733 LLVMRustMetadataRef File
,
736 return wrap(Builder
->createNameSpace(
737 unwrapDI
<DIDescriptor
>(Scope
),
739 unwrapDI
<DIFile
>(File
),
743 extern "C" void LLVMRustDICompositeTypeSetTypeArray(
744 LLVMRustDIBuilderRef Builder
,
745 LLVMRustMetadataRef CompositeType
,
746 LLVMRustMetadataRef TypeArray
)
748 DICompositeType
*tmp
= unwrapDI
<DICompositeType
>(CompositeType
);
749 Builder
->replaceArrays(tmp
, DINodeArray(unwrap
<MDTuple
>(TypeArray
)));
752 extern "C" LLVMValueRef
LLVMRustDIBuilderCreateDebugLocation(
753 LLVMContextRef Context
,
756 LLVMRustMetadataRef Scope
,
757 LLVMRustMetadataRef InlinedAt
)
759 LLVMContext
& context
= *unwrap(Context
);
761 DebugLoc debug_loc
= DebugLoc::get(Line
,
763 unwrapDIptr
<MDNode
>(Scope
),
764 unwrapDIptr
<MDNode
>(InlinedAt
));
766 return wrap(MetadataAsValue::get(context
, debug_loc
.getAsMDNode()));
769 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref()
771 return dwarf::DW_OP_deref
;
774 extern "C" int64_t LLVMRustDIBuilderCreateOpPlus()
776 return dwarf::DW_OP_plus
;
779 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Type
, RustStringRef str
) {
780 raw_rust_string_ostream
os(str
);
781 unwrap
<llvm::Type
>(Type
)->print(os
);
784 extern "C" void LLVMRustWriteValueToString(LLVMValueRef Value
, RustStringRef str
) {
785 raw_rust_string_ostream
os(str
);
787 unwrap
<llvm::Value
>(Value
)->getType()->print(os
);
789 unwrap
<llvm::Value
>(Value
)->print(os
);
794 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst
, char *bc
, size_t len
) {
795 Module
*Dst
= unwrap(dst
);
796 std::unique_ptr
<MemoryBuffer
> buf
= MemoryBuffer::getMemBufferCopy(StringRef(bc
, len
));
797 ErrorOr
<std::unique_ptr
<Module
>> Src
=
798 llvm::getLazyBitcodeModule(std::move(buf
), Dst
->getContext());
800 LLVMRustSetLastError(Src
.getError().message().c_str());
806 raw_string_ostream
Stream(Err
);
807 DiagnosticPrinterRawOStream
DP(Stream
);
808 #if LLVM_VERSION_MINOR >= 8
809 if (Linker::linkModules(*Dst
, std::move(Src
.get()))) {
811 if (Linker::LinkModules(Dst
, Src
->get(), [&](const DiagnosticInfo
&DI
) { DI
.print(DP
); })) {
813 LLVMRustSetLastError(Err
.c_str());
819 // Note that the two following functions look quite similar to the
820 // LLVMGetSectionName function. Sadly, it appears that this function only
821 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
822 // function provided by LLVM doesn't return the length, so we've created our own
823 // function which returns the length as well as the data pointer.
825 // For an example of this not returning a null terminated string, see
826 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
827 // branches explicitly creates a StringRef without a null terminator, and then
830 inline section_iterator
*unwrap(LLVMSectionIteratorRef SI
) {
831 return reinterpret_cast<section_iterator
*>(SI
);
835 LLVMRustGetSectionName(LLVMSectionIteratorRef SI
, const char **ptr
) {
837 if (std::error_code ec
= (*unwrap(SI
))->getName(ret
))
838 report_fatal_error(ec
.message());
843 // LLVMArrayType function does not support 64-bit ElementCount
844 extern "C" LLVMTypeRef
845 LLVMRustArrayType(LLVMTypeRef ElementType
, uint64_t ElementCount
) {
846 return wrap(ArrayType::get(unwrap(ElementType
), ElementCount
));
849 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine
, LLVMTwineRef
)
850 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc
, LLVMDebugLocRef
)
853 LLVMRustWriteTwineToString(LLVMTwineRef T
, RustStringRef str
) {
854 raw_rust_string_ostream
os(str
);
855 unwrap(T
)->print(os
);
859 LLVMRustUnpackOptimizationDiagnostic(
860 LLVMDiagnosticInfoRef di
,
861 const char **pass_name_out
,
862 LLVMValueRef
*function_out
,
863 LLVMDebugLocRef
*debugloc_out
,
864 LLVMTwineRef
*message_out
)
866 // Undefined to call this not on an optimization diagnostic!
867 llvm::DiagnosticInfoOptimizationBase
*opt
868 = static_cast<llvm::DiagnosticInfoOptimizationBase
*>(unwrap(di
));
870 *pass_name_out
= opt
->getPassName();
871 *function_out
= wrap(&opt
->getFunction());
872 *debugloc_out
= wrap(&opt
->getDebugLoc());
873 *message_out
= wrap(&opt
->getMsg());
877 LLVMRustUnpackInlineAsmDiagnostic(
878 LLVMDiagnosticInfoRef di
,
879 unsigned *cookie_out
,
880 LLVMTwineRef
*message_out
,
881 LLVMValueRef
*instruction_out
)
883 // Undefined to call this not on an inline assembly diagnostic!
884 llvm::DiagnosticInfoInlineAsm
*ia
885 = static_cast<llvm::DiagnosticInfoInlineAsm
*>(unwrap(di
));
887 *cookie_out
= ia
->getLocCookie();
888 *message_out
= wrap(&ia
->getMsgStr());
889 *instruction_out
= wrap(ia
->getInstruction());
892 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di
, RustStringRef str
) {
893 raw_rust_string_ostream
os(str
);
894 DiagnosticPrinterRawOStream
dp(os
);
895 unwrap(di
)->print(dp
);
898 enum class LLVMRustDiagnosticKind
{
902 DebugMetadataVersion
,
905 OptimizationRemarkMissed
,
906 OptimizationRemarkAnalysis
,
907 OptimizationRemarkAnalysisFPCommute
,
908 OptimizationRemarkAnalysisAliasing
,
909 OptimizationRemarkOther
,
913 static LLVMRustDiagnosticKind
914 to_rust(DiagnosticKind kind
)
918 return LLVMRustDiagnosticKind::InlineAsm
;
920 return LLVMRustDiagnosticKind::StackSize
;
921 case DK_DebugMetadataVersion
:
922 return LLVMRustDiagnosticKind::DebugMetadataVersion
;
923 case DK_SampleProfile
:
924 return LLVMRustDiagnosticKind::SampleProfile
;
925 case DK_OptimizationRemark
:
926 return LLVMRustDiagnosticKind::OptimizationRemark
;
927 case DK_OptimizationRemarkMissed
:
928 return LLVMRustDiagnosticKind::OptimizationRemarkMissed
;
929 case DK_OptimizationRemarkAnalysis
:
930 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis
;
931 #if LLVM_VERSION_MINOR >= 8
932 case DK_OptimizationRemarkAnalysisFPCommute
:
933 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute
;
934 case DK_OptimizationRemarkAnalysisAliasing
:
935 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing
;
938 #if LLVM_VERSION_MINOR >= 9
939 return (kind
>= DK_FirstRemark
&& kind
<= DK_LastRemark
) ?
940 LLVMRustDiagnosticKind::OptimizationRemarkOther
:
941 LLVMRustDiagnosticKind::Other
;
943 return LLVMRustDiagnosticKind::Other
;
948 extern "C" LLVMRustDiagnosticKind
LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef di
) {
949 return to_rust((DiagnosticKind
) unwrap(di
)->getKind());
951 // This is kept distinct from LLVMGetTypeKind, because when
952 // a new type kind is added, the Rust-side enum must be
953 // updated or UB will result.
954 extern "C" LLVMTypeKind
LLVMRustGetTypeKind(LLVMTypeRef Ty
) {
955 switch (unwrap(Ty
)->getTypeID()) {
957 return LLVMVoidTypeKind
;
959 return LLVMHalfTypeKind
;
960 case Type::FloatTyID
:
961 return LLVMFloatTypeKind
;
962 case Type::DoubleTyID
:
963 return LLVMDoubleTypeKind
;
964 case Type::X86_FP80TyID
:
965 return LLVMX86_FP80TypeKind
;
966 case Type::FP128TyID
:
967 return LLVMFP128TypeKind
;
968 case Type::PPC_FP128TyID
:
969 return LLVMPPC_FP128TypeKind
;
970 case Type::LabelTyID
:
971 return LLVMLabelTypeKind
;
972 case Type::MetadataTyID
:
973 return LLVMMetadataTypeKind
;
974 case Type::IntegerTyID
:
975 return LLVMIntegerTypeKind
;
976 case Type::FunctionTyID
:
977 return LLVMFunctionTypeKind
;
978 case Type::StructTyID
:
979 return LLVMStructTypeKind
;
980 case Type::ArrayTyID
:
981 return LLVMArrayTypeKind
;
982 case Type::PointerTyID
:
983 return LLVMPointerTypeKind
;
984 case Type::VectorTyID
:
985 return LLVMVectorTypeKind
;
986 case Type::X86_MMXTyID
:
987 return LLVMX86_MMXTypeKind
;
988 #if LLVM_VERSION_MINOR >= 8
989 case Type::TokenTyID
:
990 return LLVMTokenTypeKind
;
993 llvm_unreachable("Unhandled TypeID.");
996 extern "C" void LLVMRustWriteDebugLocToString(
1001 raw_rust_string_ostream
os(str
);
1002 unwrap(dl
)->print(os
);
1005 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic
, LLVMSMDiagnosticRef
)
1007 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1009 LLVMContext::InlineAsmDiagHandlerTy H
,
1012 unwrap(C
)->setInlineAsmDiagnosticHandler(H
, CX
);
1015 extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef d
,
1016 RustStringRef str
) {
1017 raw_rust_string_ostream
os(str
);
1018 unwrap(d
)->print("", os
);
1021 extern "C" LLVMValueRef
1022 LLVMRustBuildLandingPad(LLVMBuilderRef Builder
,
1024 LLVMValueRef PersFn
,
1025 unsigned NumClauses
,
1028 return LLVMBuildLandingPad(Builder
, Ty
, PersFn
, NumClauses
, Name
);
1031 extern "C" LLVMValueRef
1032 LLVMRustBuildCleanupPad(LLVMBuilderRef Builder
,
1033 LLVMValueRef ParentPad
,
1035 LLVMValueRef
*LLArgs
,
1037 #if LLVM_VERSION_MINOR >= 8
1038 Value
**Args
= unwrap(LLArgs
);
1039 if (ParentPad
== NULL
) {
1040 Type
*Ty
= Type::getTokenTy(unwrap(Builder
)->getContext());
1041 ParentPad
= wrap(Constant::getNullValue(Ty
));
1043 return wrap(unwrap(Builder
)->CreateCleanupPad(unwrap(ParentPad
),
1044 ArrayRef
<Value
*>(Args
, ArgCnt
),
1051 extern "C" LLVMValueRef
1052 LLVMRustBuildCleanupRet(LLVMBuilderRef Builder
,
1053 LLVMValueRef CleanupPad
,
1054 LLVMBasicBlockRef UnwindBB
) {
1055 #if LLVM_VERSION_MINOR >= 8
1056 CleanupPadInst
*Inst
= cast
<CleanupPadInst
>(unwrap(CleanupPad
));
1057 return wrap(unwrap(Builder
)->CreateCleanupRet(Inst
, unwrap(UnwindBB
)));
1063 extern "C" LLVMValueRef
1064 LLVMRustBuildCatchPad(LLVMBuilderRef Builder
,
1065 LLVMValueRef ParentPad
,
1067 LLVMValueRef
*LLArgs
,
1069 #if LLVM_VERSION_MINOR >= 8
1070 Value
**Args
= unwrap(LLArgs
);
1071 return wrap(unwrap(Builder
)->CreateCatchPad(unwrap(ParentPad
),
1072 ArrayRef
<Value
*>(Args
, ArgCnt
),
1079 extern "C" LLVMValueRef
1080 LLVMRustBuildCatchRet(LLVMBuilderRef Builder
,
1082 LLVMBasicBlockRef BB
) {
1083 #if LLVM_VERSION_MINOR >= 8
1084 return wrap(unwrap(Builder
)->CreateCatchRet(cast
<CatchPadInst
>(unwrap(Pad
)),
1091 extern "C" LLVMValueRef
1092 LLVMRustBuildCatchSwitch(LLVMBuilderRef Builder
,
1093 LLVMValueRef ParentPad
,
1094 LLVMBasicBlockRef BB
,
1095 unsigned NumHandlers
,
1097 #if LLVM_VERSION_MINOR >= 8
1098 if (ParentPad
== NULL
) {
1099 Type
*Ty
= Type::getTokenTy(unwrap(Builder
)->getContext());
1100 ParentPad
= wrap(Constant::getNullValue(Ty
));
1102 return wrap(unwrap(Builder
)->CreateCatchSwitch(unwrap(ParentPad
),
1112 LLVMRustAddHandler(LLVMValueRef CatchSwitchRef
,
1113 LLVMBasicBlockRef Handler
) {
1114 #if LLVM_VERSION_MINOR >= 8
1115 Value
*CatchSwitch
= unwrap(CatchSwitchRef
);
1116 cast
<CatchSwitchInst
>(CatchSwitch
)->addHandler(unwrap(Handler
));
1121 LLVMRustSetPersonalityFn(LLVMBuilderRef B
,
1122 LLVMValueRef Personality
) {
1123 #if LLVM_VERSION_MINOR >= 8
1124 unwrap(B
)->GetInsertBlock()
1126 ->setPersonalityFn(cast
<Function
>(unwrap(Personality
)));
1130 #if LLVM_VERSION_MINOR >= 8
1131 extern "C" OperandBundleDef
*
1132 LLVMRustBuildOperandBundleDef(const char *Name
,
1133 LLVMValueRef
*Inputs
,
1134 unsigned NumInputs
) {
1135 return new OperandBundleDef(Name
, makeArrayRef(unwrap(Inputs
), NumInputs
));
1139 LLVMRustFreeOperandBundleDef(OperandBundleDef
* Bundle
) {
1143 extern "C" LLVMValueRef
1144 LLVMRustBuildCall(LLVMBuilderRef B
,
1148 OperandBundleDef
*Bundle
,
1150 unsigned len
= Bundle
? 1 : 0;
1151 ArrayRef
<OperandBundleDef
> Bundles
= makeArrayRef(Bundle
, len
);
1152 return wrap(unwrap(B
)->CreateCall(unwrap(Fn
),
1153 makeArrayRef(unwrap(Args
), NumArgs
),
1158 extern "C" LLVMValueRef
1159 LLVMRustBuildInvoke(LLVMBuilderRef B
,
1163 LLVMBasicBlockRef Then
,
1164 LLVMBasicBlockRef Catch
,
1165 OperandBundleDef
*Bundle
,
1167 unsigned len
= Bundle
? 1 : 0;
1168 ArrayRef
<OperandBundleDef
> Bundles
= makeArrayRef(Bundle
, len
);
1169 return wrap(unwrap(B
)->CreateInvoke(unwrap(Fn
), unwrap(Then
), unwrap(Catch
),
1170 makeArrayRef(unwrap(Args
), NumArgs
),
1176 LLVMRustBuildOperandBundleDef(const char *Name
,
1177 LLVMValueRef
*Inputs
,
1178 unsigned NumInputs
) {
1183 LLVMRustFreeOperandBundleDef(void* Bundle
) {
1186 extern "C" LLVMValueRef
1187 LLVMRustBuildCall(LLVMBuilderRef B
,
1193 return LLVMBuildCall(B
, Fn
, Args
, NumArgs
, Name
);
1196 extern "C" LLVMValueRef
1197 LLVMRustBuildInvoke(LLVMBuilderRef B
,
1201 LLVMBasicBlockRef Then
,
1202 LLVMBasicBlockRef Catch
,
1205 return LLVMBuildInvoke(B
, Fn
, Args
, NumArgs
, Then
, Catch
, Name
);
1209 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B
, LLVMBasicBlockRef BB
) {
1210 auto point
= unwrap(BB
)->getFirstInsertionPt();
1211 unwrap(B
)->SetInsertPoint(unwrap(BB
), point
);
1214 extern "C" void LLVMRustSetComdat(LLVMModuleRef M
, LLVMValueRef V
, const char *Name
) {
1215 Triple
TargetTriple(unwrap(M
)->getTargetTriple());
1216 GlobalObject
*GV
= unwrap
<GlobalObject
>(V
);
1217 if (!TargetTriple
.isOSBinFormatMachO()) {
1218 GV
->setComdat(unwrap(M
)->getOrInsertComdat(Name
));
1222 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V
) {
1223 GlobalObject
*GV
= unwrap
<GlobalObject
>(V
);
1224 GV
->setComdat(nullptr);