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"
17 #include "llvm/IR/CallSite.h"
19 //===----------------------------------------------------------------------===
21 // This file defines alternate interfaces to core functions that are more
22 // readily callable by Rust's FFI.
24 //===----------------------------------------------------------------------===
27 using namespace llvm::sys
;
28 using namespace llvm::object
;
30 static char *LastError
;
32 extern "C" LLVMMemoryBufferRef
33 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path
) {
34 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> buf_or
= MemoryBuffer::getFile(Path
,
38 LLVMRustSetLastError(buf_or
.getError().message().c_str());
41 return wrap(buf_or
.get().release());
44 extern "C" char *LLVMRustGetLastError(void) {
45 char *ret
= LastError
;
50 void LLVMRustSetLastError(const char *err
) {
51 free((void*) LastError
);
52 LastError
= strdup(err
);
56 LLVMRustSetNormalizedTarget(LLVMModuleRef M
, const char *triple
) {
57 unwrap(M
)->setTargetTriple(Triple::normalize(triple
));
60 extern "C" LLVMValueRef
LLVMRustConstSmallInt(LLVMTypeRef IntTy
, unsigned N
,
61 LLVMBool SignExtend
) {
62 return LLVMConstInt(IntTy
, (unsigned long long)N
, SignExtend
);
65 extern "C" LLVMValueRef
LLVMRustConstInt(LLVMTypeRef IntTy
,
68 LLVMBool SignExtend
) {
69 unsigned long long N
= N_hi
;
72 return LLVMConstInt(IntTy
, N
, SignExtend
);
75 extern "C" void LLVMRustPrintPassTimings() {
76 raw_fd_ostream
OS (2, false); // stderr.
77 TimerGroup::printAll(OS
);
80 extern "C" LLVMValueRef
LLVMGetNamedValue(LLVMModuleRef M
,
82 return wrap(unwrap(M
)->getNamedValue(Name
));
85 extern "C" LLVMValueRef
LLVMGetOrInsertFunction(LLVMModuleRef M
,
87 LLVMTypeRef FunctionTy
) {
88 return wrap(unwrap(M
)->getOrInsertFunction(Name
,
89 unwrap
<FunctionType
>(FunctionTy
)));
92 extern "C" LLVMValueRef
LLVMGetOrInsertGlobal(LLVMModuleRef M
,
95 return wrap(unwrap(M
)->getOrInsertGlobal(Name
, unwrap(Ty
)));
98 extern "C" LLVMTypeRef
LLVMMetadataTypeInContext(LLVMContextRef C
) {
99 return wrap(Type::getMetadataTy(*unwrap(C
)));
102 extern "C" void LLVMAddCallSiteAttribute(LLVMValueRef Instr
, unsigned index
, uint64_t Val
) {
103 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
107 Call
.getAttributes().addAttributes(Call
->getContext(), index
,
108 AttributeSet::get(Call
->getContext(),
113 extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr
, unsigned idx
, uint64_t b
) {
114 CallSite Call
= CallSite(unwrap
<Instruction
>(Instr
));
116 B
.addDereferenceableAttr(b
);
118 Call
.getAttributes().addAttributes(Call
->getContext(), idx
,
119 AttributeSet::get(Call
->getContext(),
123 extern "C" void LLVMAddFunctionAttribute(LLVMValueRef Fn
, unsigned index
,
125 Function
*A
= unwrap
<Function
>(Fn
);
128 A
->addAttributes(index
, AttributeSet::get(A
->getContext(), index
, B
));
131 extern "C" void LLVMAddDereferenceableAttr(LLVMValueRef Fn
, unsigned index
, uint64_t bytes
) {
132 Function
*A
= unwrap
<Function
>(Fn
);
134 B
.addDereferenceableAttr(bytes
);
135 A
->addAttributes(index
, AttributeSet::get(A
->getContext(), index
, B
));
138 extern "C" void LLVMAddFunctionAttrString(LLVMValueRef Fn
, unsigned index
, const char *Name
) {
139 Function
*F
= unwrap
<Function
>(Fn
);
141 B
.addAttribute(Name
);
142 F
->addAttributes(index
, AttributeSet::get(F
->getContext(), index
, B
));
145 extern "C" void LLVMAddFunctionAttrStringValue(LLVMValueRef Fn
, unsigned index
,
148 Function
*F
= unwrap
<Function
>(Fn
);
150 B
.addAttribute(Name
, Value
);
151 F
->addAttributes(index
, AttributeSet::get(F
->getContext(), index
, B
));
154 extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn
, unsigned index
, const char *Name
) {
155 Function
*f
= unwrap
<Function
>(fn
);
156 LLVMContext
&C
= f
->getContext();
158 B
.addAttribute(Name
);
159 AttributeSet to_remove
= AttributeSet::get(C
, index
, B
);
161 AttributeSet attrs
= f
->getAttributes();
162 f
->setAttributes(attrs
.removeAttributes(f
->getContext(),
167 extern "C" LLVMValueRef
LLVMBuildAtomicLoad(LLVMBuilderRef B
,
170 AtomicOrdering order
,
171 unsigned alignment
) {
172 LoadInst
* li
= new LoadInst(unwrap(source
),0);
173 li
->setVolatile(true);
174 li
->setAtomic(order
);
175 li
->setAlignment(alignment
);
176 return wrap(unwrap(B
)->Insert(li
, Name
));
179 extern "C" LLVMValueRef
LLVMBuildAtomicStore(LLVMBuilderRef B
,
182 AtomicOrdering order
,
183 unsigned alignment
) {
184 StoreInst
* si
= new StoreInst(unwrap(val
),unwrap(target
));
185 si
->setVolatile(true);
186 si
->setAtomic(order
);
187 si
->setAlignment(alignment
);
188 return wrap(unwrap(B
)->Insert(si
));
191 extern "C" LLVMValueRef
LLVMBuildAtomicCmpXchg(LLVMBuilderRef B
,
195 AtomicOrdering order
,
196 AtomicOrdering failure_order
) {
197 return wrap(unwrap(B
)->CreateAtomicCmpXchg(unwrap(target
), unwrap(old
),
198 unwrap(source
), order
,
202 extern "C" LLVMValueRef
LLVMBuildAtomicFence(LLVMBuilderRef B
,
203 AtomicOrdering order
,
204 SynchronizationScope scope
) {
205 return wrap(unwrap(B
)->CreateFence(order
, scope
));
208 extern "C" void LLVMSetDebug(int Enabled
) {
214 extern "C" LLVMValueRef
LLVMInlineAsm(LLVMTypeRef Ty
,
217 LLVMBool HasSideEffects
,
218 LLVMBool IsAlignStack
,
220 return wrap(InlineAsm::get(unwrap
<FunctionType
>(Ty
), AsmString
,
221 Constraints
, HasSideEffects
,
222 IsAlignStack
, (InlineAsm::AsmDialect
) Dialect
));
225 typedef DIBuilder
* DIBuilderRef
;
227 #if LLVM_VERSION_MINOR >= 6
228 typedef struct LLVMOpaqueMetadata
*LLVMMetadataRef
;
231 DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata
, LLVMMetadataRef
)
233 inline Metadata
**unwrap(LLVMMetadataRef
*Vals
) {
234 return reinterpret_cast<Metadata
**>(Vals
);
238 typedef LLVMValueRef LLVMMetadataRef
;
241 template<typename DIT
>
242 DIT
* unwrapDIptr(LLVMMetadataRef ref
) {
243 return (DIT
*) (ref
? unwrap
<MDNode
>(ref
) : NULL
);
246 #if LLVM_VERSION_MINOR <= 6
247 template<typename DIT
>
248 DIT
unwrapDI(LLVMMetadataRef ref
) {
249 return DIT(ref
? unwrap
<MDNode
>(ref
) : NULL
);
252 #define DIDescriptor DIScope
253 #define DIArray DINodeArray
254 #define unwrapDI unwrapDIptr
257 #if LLVM_VERSION_MINOR <= 5
258 #define DISubroutineType DICompositeType
261 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
262 return DEBUG_METADATA_VERSION
;
265 extern "C" uint32_t LLVMVersionMinor() {
266 return LLVM_VERSION_MINOR
;
269 extern "C" uint32_t LLVMVersionMajor() {
270 return LLVM_VERSION_MAJOR
;
273 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M
,
276 unwrap(M
)->addModuleFlag(Module::Warning
, name
, value
);
279 extern "C" DIBuilderRef
LLVMDIBuilderCreate(LLVMModuleRef M
) {
280 return new DIBuilder(*unwrap(M
));
283 extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder
) {
287 extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder
) {
291 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateCompileUnit(
292 DIBuilderRef Builder
,
296 const char* Producer
,
300 const char* SplitName
) {
301 return wrap(Builder
->createCompileUnit(Lang
,
311 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateFile(
312 DIBuilderRef Builder
,
313 const char* Filename
,
314 const char* Directory
) {
315 return wrap(Builder
->createFile(Filename
, Directory
));
318 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateSubroutineType(
319 DIBuilderRef Builder
,
320 LLVMMetadataRef File
,
321 LLVMMetadataRef ParameterTypes
) {
322 return wrap(Builder
->createSubroutineType(
323 unwrapDI
<DIFile
>(File
),
324 #if LLVM_VERSION_MINOR >= 7
325 DITypeRefArray(unwrap
<MDTuple
>(ParameterTypes
))));
326 #elif LLVM_VERSION_MINOR >= 6
327 unwrapDI
<DITypeArray
>(ParameterTypes
)));
329 unwrapDI
<DIArray
>(ParameterTypes
)));
333 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateFunction(
334 DIBuilderRef Builder
,
335 LLVMMetadataRef Scope
,
337 const char* LinkageName
,
338 LLVMMetadataRef File
,
347 LLVMMetadataRef TParam
,
348 LLVMMetadataRef Decl
) {
349 return wrap(Builder
->createFunction(
350 unwrapDI
<DIScope
>(Scope
), Name
, LinkageName
,
351 unwrapDI
<DIFile
>(File
), LineNo
,
352 unwrapDI
<DISubroutineType
>(Ty
), isLocalToUnit
, isDefinition
, ScopeLine
,
354 unwrap
<Function
>(Fn
),
355 unwrapDIptr
<MDNode
>(TParam
),
356 unwrapDIptr
<MDNode
>(Decl
)));
359 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateBasicType(
360 DIBuilderRef Builder
,
363 uint64_t AlignInBits
,
365 return wrap(Builder
->createBasicType(
367 AlignInBits
, Encoding
));
370 extern "C" LLVMMetadataRef
LLVMDIBuilderCreatePointerType(
371 DIBuilderRef Builder
,
372 LLVMMetadataRef PointeeTy
,
374 uint64_t AlignInBits
,
376 return wrap(Builder
->createPointerType(
377 unwrapDI
<DIType
>(PointeeTy
), SizeInBits
, AlignInBits
, Name
));
380 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateStructType(
381 DIBuilderRef Builder
,
382 LLVMMetadataRef Scope
,
384 LLVMMetadataRef File
,
387 uint64_t AlignInBits
,
389 LLVMMetadataRef DerivedFrom
,
390 LLVMMetadataRef Elements
,
391 unsigned RunTimeLang
,
392 LLVMMetadataRef VTableHolder
,
393 const char *UniqueId
) {
394 return wrap(Builder
->createStructType(
395 unwrapDI
<DIDescriptor
>(Scope
),
397 unwrapDI
<DIFile
>(File
),
402 unwrapDI
<DIType
>(DerivedFrom
),
403 #if LLVM_VERSION_MINOR >= 7
404 DINodeArray(unwrapDI
<MDTuple
>(Elements
)),
406 unwrapDI
<DIArray
>(Elements
),
409 unwrapDI
<DIType
>(VTableHolder
),
414 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateMemberType(
415 DIBuilderRef Builder
,
416 LLVMMetadataRef Scope
,
418 LLVMMetadataRef File
,
421 uint64_t AlignInBits
,
422 uint64_t OffsetInBits
,
424 LLVMMetadataRef Ty
) {
425 return wrap(Builder
->createMemberType(
426 unwrapDI
<DIDescriptor
>(Scope
), Name
,
427 unwrapDI
<DIFile
>(File
), LineNo
,
428 SizeInBits
, AlignInBits
, OffsetInBits
, Flags
,
429 unwrapDI
<DIType
>(Ty
)));
432 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateLexicalBlock(
433 DIBuilderRef Builder
,
434 LLVMMetadataRef Scope
,
435 LLVMMetadataRef File
,
438 return wrap(Builder
->createLexicalBlock(
439 unwrapDI
<DIDescriptor
>(Scope
),
440 unwrapDI
<DIFile
>(File
), Line
, Col
441 #if LLVM_VERSION_MINOR == 5
447 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateStaticVariable(
448 DIBuilderRef Builder
,
449 LLVMMetadataRef Context
,
451 const char* LinkageName
,
452 LLVMMetadataRef File
,
457 LLVMMetadataRef Decl
= NULL
) {
458 #if LLVM_VERSION_MINOR >= 6
459 return wrap(Builder
->createGlobalVariable(unwrapDI
<DIDescriptor
>(Context
),
461 return wrap(Builder
->createStaticVariable(unwrapDI
<DIDescriptor
>(Context
),
465 unwrapDI
<DIFile
>(File
),
467 unwrapDI
<DIType
>(Ty
),
469 cast
<Constant
>(unwrap(Val
)),
470 unwrapDIptr
<MDNode
>(Decl
)));
473 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateVariable(
474 DIBuilderRef Builder
,
476 LLVMMetadataRef Scope
,
478 LLVMMetadataRef File
,
484 unsigned AddrOpsCount
,
486 #if LLVM_VERSION_MINOR == 5
487 if (AddrOpsCount
> 0) {
488 SmallVector
<llvm::Value
*, 16> addr_ops
;
489 llvm::Type
*Int64Ty
= Type::getInt64Ty(unwrap
<MDNode
>(Scope
)->getContext());
490 for (unsigned i
= 0; i
< AddrOpsCount
; ++i
)
491 addr_ops
.push_back(ConstantInt::get(Int64Ty
, AddrOps
[i
]));
493 return wrap(Builder
->createComplexVariable(
495 unwrapDI
<DIDescriptor
>(Scope
),
497 unwrapDI
<DIFile
>(File
),
499 unwrapDI
<DIType
>(Ty
),
505 return wrap(Builder
->createLocalVariable(Tag
,
506 unwrapDI
<DIDescriptor
>(Scope
), Name
,
507 unwrapDI
<DIFile
>(File
),
509 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, Flags
, ArgNo
));
512 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateArrayType(
513 DIBuilderRef Builder
,
515 uint64_t AlignInBits
,
517 LLVMMetadataRef Subscripts
) {
518 return wrap(Builder
->createArrayType(Size
, AlignInBits
,
519 unwrapDI
<DIType
>(Ty
),
520 #if LLVM_VERSION_MINOR >= 7
521 DINodeArray(unwrapDI
<MDTuple
>(Subscripts
))
523 unwrapDI
<DIArray
>(Subscripts
)
528 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateVectorType(
529 DIBuilderRef Builder
,
531 uint64_t AlignInBits
,
533 LLVMMetadataRef Subscripts
) {
534 return wrap(Builder
->createVectorType(Size
, AlignInBits
,
535 unwrapDI
<DIType
>(Ty
),
536 #if LLVM_VERSION_MINOR >= 7
537 DINodeArray(unwrapDI
<MDTuple
>(Subscripts
))
539 unwrapDI
<DIArray
>(Subscripts
)
544 extern "C" LLVMMetadataRef
LLVMDIBuilderGetOrCreateSubrange(
545 DIBuilderRef Builder
,
548 return wrap(Builder
->getOrCreateSubrange(Lo
, Count
));
551 extern "C" LLVMMetadataRef
LLVMDIBuilderGetOrCreateArray(
552 DIBuilderRef Builder
,
553 LLVMMetadataRef
* Ptr
,
555 #if LLVM_VERSION_MINOR >= 7
556 Metadata
**DataValue
= unwrap(Ptr
);
557 return wrap(Builder
->getOrCreateArray(
558 ArrayRef
<Metadata
*>(DataValue
, Count
)).get());
560 return wrap(Builder
->getOrCreateArray(
561 #if LLVM_VERSION_MINOR >= 6
562 ArrayRef
<Metadata
*>(unwrap(Ptr
), Count
)));
564 ArrayRef
<Value
*>(reinterpret_cast<Value
**>(Ptr
), Count
)));
569 extern "C" LLVMValueRef
LLVMDIBuilderInsertDeclareAtEnd(
570 DIBuilderRef Builder
,
572 LLVMMetadataRef VarInfo
,
574 unsigned AddrOpsCount
,
576 LLVMBasicBlockRef InsertAtEnd
) {
577 return wrap(Builder
->insertDeclare(
579 #if LLVM_VERSION_MINOR >= 7
580 unwrap
<DILocalVariable
>(VarInfo
),
582 unwrapDI
<DIVariable
>(VarInfo
),
584 #if LLVM_VERSION_MINOR >= 6
585 Builder
->createExpression(
586 llvm::ArrayRef
<int64_t>(AddrOps
, AddrOpsCount
)),
588 #if LLVM_VERSION_MINOR >= 7
589 DebugLoc(cast
<MDNode
>(unwrap
<MetadataAsValue
>(DL
)->getMetadata())),
591 unwrap(InsertAtEnd
)));
594 extern "C" LLVMValueRef
LLVMDIBuilderInsertDeclareBefore(
595 DIBuilderRef Builder
,
597 LLVMMetadataRef VarInfo
,
599 unsigned AddrOpsCount
,
601 LLVMValueRef InsertBefore
) {
602 #if LLVM_VERSION_MINOR >= 6
604 return wrap(Builder
->insertDeclare(
606 #if LLVM_VERSION_MINOR >= 7
607 unwrap
<DILocalVariable
>(VarInfo
),
609 unwrapDI
<DIVariable
>(VarInfo
),
611 #if LLVM_VERSION_MINOR >= 6
612 Builder
->createExpression(
613 llvm::ArrayRef
<int64_t>(AddrOps
, AddrOpsCount
)),
615 #if LLVM_VERSION_MINOR >= 7
616 DebugLoc(cast
<MDNode
>(unwrap
<MetadataAsValue
>(DL
)->getMetadata())),
618 unwrap
<Instruction
>(InsertBefore
)));
621 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateEnumerator(
622 DIBuilderRef Builder
,
626 return wrap(Builder
->createEnumerator(Name
, Val
));
629 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateEnumerationType(
630 DIBuilderRef Builder
,
631 LLVMMetadataRef Scope
,
633 LLVMMetadataRef File
,
636 uint64_t AlignInBits
,
637 LLVMMetadataRef Elements
,
638 LLVMMetadataRef ClassType
)
640 return wrap(Builder
->createEnumerationType(
641 unwrapDI
<DIDescriptor
>(Scope
),
643 unwrapDI
<DIFile
>(File
),
647 #if LLVM_VERSION_MINOR >= 7
648 DINodeArray(unwrapDI
<MDTuple
>(Elements
)),
650 unwrapDI
<DIArray
>(Elements
),
652 unwrapDI
<DIType
>(ClassType
)));
655 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateUnionType(
656 DIBuilderRef Builder
,
657 LLVMMetadataRef Scope
,
659 LLVMMetadataRef File
,
662 uint64_t AlignInBits
,
664 LLVMMetadataRef Elements
,
665 unsigned RunTimeLang
,
666 const char* UniqueId
)
668 return wrap(Builder
->createUnionType(
669 unwrapDI
<DIDescriptor
>(Scope
),
671 unwrapDI
<DIFile
>(File
),
676 #if LLVM_VERSION_MINOR >= 7
677 DINodeArray(unwrapDI
<MDTuple
>(Elements
)),
679 unwrapDI
<DIArray
>(Elements
),
686 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateTemplateTypeParameter(
687 DIBuilderRef Builder
,
688 LLVMMetadataRef Scope
,
691 LLVMMetadataRef File
,
695 return wrap(Builder
->createTemplateTypeParameter(
696 unwrapDI
<DIDescriptor
>(Scope
),
699 #if LLVM_VERSION_MINOR <= 6
701 unwrapDI
<MDNode
*>(File
),
708 extern "C" int64_t LLVMDIBuilderCreateOpDeref()
710 return dwarf::DW_OP_deref
;
713 extern "C" int64_t LLVMDIBuilderCreateOpPlus()
715 return dwarf::DW_OP_plus
;
718 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateNameSpace(
719 DIBuilderRef Builder
,
720 LLVMMetadataRef Scope
,
722 LLVMMetadataRef File
,
725 return wrap(Builder
->createNameSpace(
726 unwrapDI
<DIDescriptor
>(Scope
),
728 unwrapDI
<DIFile
>(File
),
732 extern "C" void LLVMDICompositeTypeSetTypeArray(
733 DIBuilderRef Builder
,
734 LLVMMetadataRef CompositeType
,
735 LLVMMetadataRef TypeArray
)
737 #if LLVM_VERSION_MINOR >= 7
738 DICompositeType
*tmp
= unwrapDI
<DICompositeType
>(CompositeType
);
739 Builder
->replaceArrays(tmp
, DINodeArray(unwrap
<MDTuple
>(TypeArray
)));
740 #elif LLVM_VERSION_MINOR >= 6
741 DICompositeType tmp
= unwrapDI
<DICompositeType
>(CompositeType
);
742 Builder
->replaceArrays(tmp
, unwrapDI
<DIArray
>(TypeArray
));
744 unwrapDI
<DICompositeType
>(CompositeType
).setTypeArray(unwrapDI
<DIArray
>(TypeArray
));
748 extern "C" LLVMValueRef
LLVMDIBuilderCreateDebugLocation(
749 LLVMContextRef Context
,
752 LLVMMetadataRef Scope
,
753 LLVMMetadataRef InlinedAt
) {
755 LLVMContext
& context
= *unwrap(Context
);
757 DebugLoc debug_loc
= DebugLoc::get(Line
,
759 unwrapDIptr
<MDNode
>(Scope
),
760 unwrapDIptr
<MDNode
>(InlinedAt
));
762 #if LLVM_VERSION_MINOR >= 6
763 return wrap(MetadataAsValue::get(context
, debug_loc
.getAsMDNode(
764 #if LLVM_VERSION_MINOR <= 6
769 return wrap(debug_loc
.getAsMDNode(context
));
773 extern "C" void LLVMWriteTypeToString(LLVMTypeRef Type
, RustStringRef str
) {
774 raw_rust_string_ostream
os(str
);
775 unwrap
<llvm::Type
>(Type
)->print(os
);
778 extern "C" void LLVMWriteValueToString(LLVMValueRef Value
, RustStringRef str
) {
779 raw_rust_string_ostream
os(str
);
781 unwrap
<llvm::Value
>(Value
)->getType()->print(os
);
783 unwrap
<llvm::Value
>(Value
)->print(os
);
788 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst
, char *bc
, size_t len
) {
789 Module
*Dst
= unwrap(dst
);
790 #if LLVM_VERSION_MINOR >= 6
791 std::unique_ptr
<MemoryBuffer
> buf
= MemoryBuffer::getMemBufferCopy(StringRef(bc
, len
));
792 #if LLVM_VERSION_MINOR >= 7
793 ErrorOr
<std::unique_ptr
<Module
>> Src
=
794 llvm::getLazyBitcodeModule(std::move(buf
), Dst
->getContext());
796 ErrorOr
<Module
*> Src
= llvm::getLazyBitcodeModule(std::move(buf
), Dst
->getContext());
799 MemoryBuffer
* buf
= MemoryBuffer::getMemBufferCopy(StringRef(bc
, len
));
800 ErrorOr
<Module
*> Src
= llvm::getLazyBitcodeModule(buf
, Dst
->getContext());
803 LLVMRustSetLastError(Src
.getError().message().c_str());
804 #if LLVM_VERSION_MINOR == 5
812 #if LLVM_VERSION_MINOR >= 6
813 raw_string_ostream
Stream(Err
);
814 DiagnosticPrinterRawOStream
DP(Stream
);
815 #if LLVM_VERSION_MINOR >= 7
816 if (Linker::LinkModules(Dst
, Src
->get(), [&](const DiagnosticInfo
&DI
) { DI
.print(DP
); })) {
818 if (Linker::LinkModules(Dst
, *Src
, [&](const DiagnosticInfo
&DI
) { DI
.print(DP
); })) {
821 if (Linker::LinkModules(Dst
, *Src
, Linker::DestroySource
, &Err
)) {
823 LLVMRustSetLastError(Err
.c_str());
830 LLVMRustSetDLLStorageClass(LLVMValueRef Value
,
831 GlobalValue::DLLStorageClassTypes Class
) {
832 GlobalValue
*V
= unwrap
<GlobalValue
>(Value
);
833 V
->setDLLStorageClass(Class
);
836 // Note that the two following functions look quite similar to the
837 // LLVMGetSectionName function. Sadly, it appears that this function only
838 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
839 // function provided by LLVM doesn't return the length, so we've created our own
840 // function which returns the length as well as the data pointer.
842 // For an example of this not returning a null terminated string, see
843 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
844 // branches explicitly creates a StringRef without a null terminator, and then
847 inline section_iterator
*unwrap(LLVMSectionIteratorRef SI
) {
848 return reinterpret_cast<section_iterator
*>(SI
);
852 LLVMRustGetSectionName(LLVMSectionIteratorRef SI
, const char **ptr
) {
854 if (std::error_code ec
= (*unwrap(SI
))->getName(ret
))
855 report_fatal_error(ec
.message());
860 // LLVMArrayType function does not support 64-bit ElementCount
861 extern "C" LLVMTypeRef
862 LLVMRustArrayType(LLVMTypeRef ElementType
, uint64_t ElementCount
) {
863 return wrap(ArrayType::get(unwrap(ElementType
), ElementCount
));
866 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine
, LLVMTwineRef
)
867 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc
, LLVMDebugLocRef
)
870 LLVMWriteTwineToString(LLVMTwineRef T
, RustStringRef str
) {
871 raw_rust_string_ostream
os(str
);
872 unwrap(T
)->print(os
);
876 LLVMUnpackOptimizationDiagnostic(
877 LLVMDiagnosticInfoRef di
,
878 const char **pass_name_out
,
879 LLVMValueRef
*function_out
,
880 LLVMDebugLocRef
*debugloc_out
,
881 LLVMTwineRef
*message_out
)
883 // Undefined to call this not on an optimization diagnostic!
884 llvm::DiagnosticInfoOptimizationBase
*opt
885 = static_cast<llvm::DiagnosticInfoOptimizationBase
*>(unwrap(di
));
887 *pass_name_out
= opt
->getPassName();
888 *function_out
= wrap(&opt
->getFunction());
889 *debugloc_out
= wrap(&opt
->getDebugLoc());
890 *message_out
= wrap(&opt
->getMsg());
894 LLVMUnpackInlineAsmDiagnostic(
895 LLVMDiagnosticInfoRef di
,
896 unsigned *cookie_out
,
897 LLVMTwineRef
*message_out
,
898 LLVMValueRef
*instruction_out
)
900 // Undefined to call this not on an inline assembly diagnostic!
901 llvm::DiagnosticInfoInlineAsm
*ia
902 = static_cast<llvm::DiagnosticInfoInlineAsm
*>(unwrap(di
));
904 *cookie_out
= ia
->getLocCookie();
905 *message_out
= wrap(&ia
->getMsgStr());
906 *instruction_out
= wrap(ia
->getInstruction());
909 extern "C" void LLVMWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di
, RustStringRef str
) {
910 raw_rust_string_ostream
os(str
);
911 DiagnosticPrinterRawOStream
dp(os
);
912 unwrap(di
)->print(dp
);
915 extern "C" int LLVMGetDiagInfoKind(LLVMDiagnosticInfoRef di
) {
916 return unwrap(di
)->getKind();
919 extern "C" void LLVMWriteDebugLocToString(
924 raw_rust_string_ostream
os(str
);
925 #if LLVM_VERSION_MINOR >= 7
926 unwrap(dl
)->print(os
);
928 unwrap(dl
)->print(*unwrap(C
), os
);
932 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic
, LLVMSMDiagnosticRef
)
934 extern "C" void LLVMSetInlineAsmDiagnosticHandler(
936 LLVMContext::InlineAsmDiagHandlerTy H
,
939 unwrap(C
)->setInlineAsmDiagnosticHandler(H
, CX
);
942 extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d
, RustStringRef str
) {
943 raw_rust_string_ostream
os(str
);
944 unwrap(d
)->print("", os
);
947 extern "C" LLVMValueRef
948 LLVMRustBuildLandingPad(LLVMBuilderRef Builder
,
954 #if LLVM_VERSION_MINOR >= 7
955 unwrap
<Function
>(F
)->setPersonalityFn(unwrap
<Constant
>(PersFn
));
956 return LLVMBuildLandingPad(Builder
, Ty
, NumClauses
, Name
);
958 return LLVMBuildLandingPad(Builder
, Ty
, PersFn
, NumClauses
, Name
);