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
, uint64_t Val
) {
124 Function
*A
= unwrap
<Function
>(Fn
);
127 A
->addAttributes(index
, AttributeSet::get(A
->getContext(), index
, B
));
130 extern "C" void LLVMAddDereferenceableAttr(LLVMValueRef Fn
, unsigned index
, uint64_t bytes
) {
131 Function
*A
= unwrap
<Function
>(Fn
);
133 B
.addDereferenceableAttr(bytes
);
134 A
->addAttributes(index
, AttributeSet::get(A
->getContext(), index
, B
));
137 extern "C" void LLVMAddFunctionAttrString(LLVMValueRef Fn
, unsigned index
, const char *Name
) {
138 Function
*F
= unwrap
<Function
>(Fn
);
140 B
.addAttribute(Name
);
141 F
->addAttributes(index
, AttributeSet::get(F
->getContext(), index
, B
));
144 extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn
, unsigned index
, const char *Name
) {
145 Function
*f
= unwrap
<Function
>(fn
);
146 LLVMContext
&C
= f
->getContext();
148 B
.addAttribute(Name
);
149 AttributeSet to_remove
= AttributeSet::get(C
, index
, B
);
151 AttributeSet attrs
= f
->getAttributes();
152 f
->setAttributes(attrs
.removeAttributes(f
->getContext(),
157 extern "C" LLVMValueRef
LLVMBuildAtomicLoad(LLVMBuilderRef B
,
160 AtomicOrdering order
,
161 unsigned alignment
) {
162 LoadInst
* li
= new LoadInst(unwrap(source
),0);
163 li
->setVolatile(true);
164 li
->setAtomic(order
);
165 li
->setAlignment(alignment
);
166 return wrap(unwrap(B
)->Insert(li
, Name
));
169 extern "C" LLVMValueRef
LLVMBuildAtomicStore(LLVMBuilderRef B
,
172 AtomicOrdering order
,
173 unsigned alignment
) {
174 StoreInst
* si
= new StoreInst(unwrap(val
),unwrap(target
));
175 si
->setVolatile(true);
176 si
->setAtomic(order
);
177 si
->setAlignment(alignment
);
178 return wrap(unwrap(B
)->Insert(si
));
181 extern "C" LLVMValueRef
LLVMBuildAtomicCmpXchg(LLVMBuilderRef B
,
185 AtomicOrdering order
,
186 AtomicOrdering failure_order
) {
187 return wrap(unwrap(B
)->CreateAtomicCmpXchg(unwrap(target
), unwrap(old
),
188 unwrap(source
), order
,
192 extern "C" LLVMValueRef
LLVMBuildAtomicFence(LLVMBuilderRef B
,
193 AtomicOrdering order
,
194 SynchronizationScope scope
) {
195 return wrap(unwrap(B
)->CreateFence(order
, scope
));
198 extern "C" void LLVMSetDebug(int Enabled
) {
204 extern "C" LLVMValueRef
LLVMInlineAsm(LLVMTypeRef Ty
,
207 LLVMBool HasSideEffects
,
208 LLVMBool IsAlignStack
,
210 return wrap(InlineAsm::get(unwrap
<FunctionType
>(Ty
), AsmString
,
211 Constraints
, HasSideEffects
,
212 IsAlignStack
, (InlineAsm::AsmDialect
) Dialect
));
215 typedef DIBuilder
* DIBuilderRef
;
217 #if LLVM_VERSION_MINOR >= 6
218 typedef struct LLVMOpaqueMetadata
*LLVMMetadataRef
;
221 DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata
, LLVMMetadataRef
)
223 inline Metadata
**unwrap(LLVMMetadataRef
*Vals
) {
224 return reinterpret_cast<Metadata
**>(Vals
);
228 typedef LLVMValueRef LLVMMetadataRef
;
231 template<typename DIT
>
232 DIT
unwrapDI(LLVMMetadataRef ref
) {
233 return DIT(ref
? unwrap
<MDNode
>(ref
) : NULL
);
236 extern "C" const uint32_t LLVMRustDebugMetadataVersion
= DEBUG_METADATA_VERSION
;
238 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M
,
241 unwrap(M
)->addModuleFlag(Module::Warning
, name
, value
);
244 extern "C" DIBuilderRef
LLVMDIBuilderCreate(LLVMModuleRef M
) {
245 return new DIBuilder(*unwrap(M
));
248 extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder
) {
252 extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder
) {
256 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateCompileUnit(
257 DIBuilderRef Builder
,
261 const char* Producer
,
265 const char* SplitName
) {
266 return wrap(Builder
->createCompileUnit(Lang
,
276 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateFile(
277 DIBuilderRef Builder
,
278 const char* Filename
,
279 const char* Directory
) {
280 return wrap(Builder
->createFile(Filename
, Directory
));
283 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateSubroutineType(
284 DIBuilderRef Builder
,
285 LLVMMetadataRef File
,
286 LLVMMetadataRef ParameterTypes
) {
287 return wrap(Builder
->createSubroutineType(
288 unwrapDI
<DIFile
>(File
),
289 #if LLVM_VERSION_MINOR >= 6
290 unwrapDI
<DITypeArray
>(ParameterTypes
)));
292 unwrapDI
<DIArray
>(ParameterTypes
)));
296 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateFunction(
297 DIBuilderRef Builder
,
298 LLVMMetadataRef Scope
,
300 const char* LinkageName
,
301 LLVMMetadataRef File
,
310 LLVMMetadataRef TParam
,
311 LLVMMetadataRef Decl
) {
312 return wrap(Builder
->createFunction(
313 unwrapDI
<DIScope
>(Scope
), Name
, LinkageName
,
314 unwrapDI
<DIFile
>(File
), LineNo
,
315 unwrapDI
<DICompositeType
>(Ty
), isLocalToUnit
, isDefinition
, ScopeLine
,
317 unwrap
<Function
>(Fn
),
318 unwrapDI
<MDNode
*>(TParam
),
319 unwrapDI
<MDNode
*>(Decl
)));
322 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateBasicType(
323 DIBuilderRef Builder
,
326 uint64_t AlignInBits
,
328 return wrap(Builder
->createBasicType(
330 AlignInBits
, Encoding
));
333 extern "C" LLVMMetadataRef
LLVMDIBuilderCreatePointerType(
334 DIBuilderRef Builder
,
335 LLVMMetadataRef PointeeTy
,
337 uint64_t AlignInBits
,
339 return wrap(Builder
->createPointerType(
340 unwrapDI
<DIType
>(PointeeTy
), SizeInBits
, AlignInBits
, Name
));
343 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateStructType(
344 DIBuilderRef Builder
,
345 LLVMMetadataRef Scope
,
347 LLVMMetadataRef File
,
350 uint64_t AlignInBits
,
352 LLVMMetadataRef DerivedFrom
,
353 LLVMMetadataRef Elements
,
354 unsigned RunTimeLang
,
355 LLVMMetadataRef VTableHolder
,
356 const char *UniqueId
) {
357 return wrap(Builder
->createStructType(
358 unwrapDI
<DIDescriptor
>(Scope
),
360 unwrapDI
<DIFile
>(File
),
365 unwrapDI
<DIType
>(DerivedFrom
),
366 unwrapDI
<DIArray
>(Elements
),
368 unwrapDI
<DIType
>(VTableHolder
),
373 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateMemberType(
374 DIBuilderRef Builder
,
375 LLVMMetadataRef Scope
,
377 LLVMMetadataRef File
,
380 uint64_t AlignInBits
,
381 uint64_t OffsetInBits
,
383 LLVMMetadataRef Ty
) {
384 return wrap(Builder
->createMemberType(
385 unwrapDI
<DIDescriptor
>(Scope
), Name
,
386 unwrapDI
<DIFile
>(File
), LineNo
,
387 SizeInBits
, AlignInBits
, OffsetInBits
, Flags
,
388 unwrapDI
<DIType
>(Ty
)));
391 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateLexicalBlock(
392 DIBuilderRef Builder
,
393 LLVMMetadataRef Scope
,
394 LLVMMetadataRef File
,
397 return wrap(Builder
->createLexicalBlock(
398 unwrapDI
<DIDescriptor
>(Scope
),
399 unwrapDI
<DIFile
>(File
), Line
, Col
400 #if LLVM_VERSION_MINOR == 5
406 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateStaticVariable(
407 DIBuilderRef Builder
,
408 LLVMMetadataRef Context
,
410 const char* LinkageName
,
411 LLVMMetadataRef File
,
416 LLVMMetadataRef Decl
= NULL
) {
417 #if LLVM_VERSION_MINOR >= 6
418 return wrap(Builder
->createGlobalVariable(unwrapDI
<DIDescriptor
>(Context
),
420 return wrap(Builder
->createStaticVariable(unwrapDI
<DIDescriptor
>(Context
),
424 unwrapDI
<DIFile
>(File
),
426 unwrapDI
<DIType
>(Ty
),
428 cast
<Constant
>(unwrap(Val
)),
429 unwrapDI
<MDNode
*>(Decl
)));
432 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateVariable(
433 DIBuilderRef Builder
,
435 LLVMMetadataRef Scope
,
437 LLVMMetadataRef File
,
443 unsigned AddrOpsCount
,
445 #if LLVM_VERSION_MINOR == 5
446 if (AddrOpsCount
> 0) {
447 SmallVector
<llvm::Value
*, 16> addr_ops
;
448 llvm::Type
*Int64Ty
= Type::getInt64Ty(unwrap
<MDNode
>(Scope
)->getContext());
449 for (unsigned i
= 0; i
< AddrOpsCount
; ++i
)
450 addr_ops
.push_back(ConstantInt::get(Int64Ty
, AddrOps
[i
]));
452 return wrap(Builder
->createComplexVariable(
454 unwrapDI
<DIDescriptor
>(Scope
),
456 unwrapDI
<DIFile
>(File
),
458 unwrapDI
<DIType
>(Ty
),
464 return wrap(Builder
->createLocalVariable(Tag
,
465 unwrapDI
<DIDescriptor
>(Scope
), Name
,
466 unwrapDI
<DIFile
>(File
),
468 unwrapDI
<DIType
>(Ty
), AlwaysPreserve
, Flags
, ArgNo
));
471 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateArrayType(
472 DIBuilderRef Builder
,
474 uint64_t AlignInBits
,
476 LLVMMetadataRef Subscripts
) {
477 return wrap(Builder
->createArrayType(Size
, AlignInBits
,
478 unwrapDI
<DIType
>(Ty
),
479 unwrapDI
<DIArray
>(Subscripts
)));
482 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateVectorType(
483 DIBuilderRef Builder
,
485 uint64_t AlignInBits
,
487 LLVMMetadataRef Subscripts
) {
488 return wrap(Builder
->createVectorType(Size
, AlignInBits
,
489 unwrapDI
<DIType
>(Ty
),
490 unwrapDI
<DIArray
>(Subscripts
)));
493 extern "C" LLVMMetadataRef
LLVMDIBuilderGetOrCreateSubrange(
494 DIBuilderRef Builder
,
497 return wrap(Builder
->getOrCreateSubrange(Lo
, Count
));
500 extern "C" LLVMMetadataRef
LLVMDIBuilderGetOrCreateArray(
501 DIBuilderRef Builder
,
502 LLVMMetadataRef
* Ptr
,
504 return wrap(Builder
->getOrCreateArray(
505 #if LLVM_VERSION_MINOR >= 6
506 ArrayRef
<Metadata
*>(unwrap(Ptr
), Count
)));
508 ArrayRef
<Value
*>(reinterpret_cast<Value
**>(Ptr
), Count
)));
512 extern "C" LLVMValueRef
LLVMDIBuilderInsertDeclareAtEnd(
513 DIBuilderRef Builder
,
515 LLVMMetadataRef VarInfo
,
517 unsigned AddrOpsCount
,
518 LLVMBasicBlockRef InsertAtEnd
) {
519 #if LLVM_VERSION_MINOR >= 6
521 if (AddrOpsCount
== 0) {
522 Expr
= Builder
->createExpression();
524 llvm::ArrayRef
<int64_t> addr_ops(AddrOps
, AddrOpsCount
);
525 Expr
= Builder
->createExpression(addr_ops
);
528 return wrap(Builder
->insertDeclare(
530 unwrapDI
<DIVariable
>(VarInfo
),
531 #if LLVM_VERSION_MINOR >= 6
534 unwrap(InsertAtEnd
)));
537 extern "C" LLVMValueRef
LLVMDIBuilderInsertDeclareBefore(
538 DIBuilderRef Builder
,
540 LLVMMetadataRef VarInfo
,
542 unsigned AddrOpsCount
,
543 LLVMValueRef InsertBefore
) {
544 #if LLVM_VERSION_MINOR >= 6
546 if (AddrOpsCount
== 0) {
547 Expr
= Builder
->createExpression();
549 llvm::ArrayRef
<int64_t> addr_ops(AddrOps
, AddrOpsCount
);
550 Expr
= Builder
->createExpression(addr_ops
);
553 return wrap(Builder
->insertDeclare(
555 unwrapDI
<DIVariable
>(VarInfo
),
556 #if LLVM_VERSION_MINOR >= 6
559 unwrap
<Instruction
>(InsertBefore
)));
562 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateEnumerator(
563 DIBuilderRef Builder
,
567 return wrap(Builder
->createEnumerator(Name
, Val
));
570 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateEnumerationType(
571 DIBuilderRef Builder
,
572 LLVMMetadataRef Scope
,
574 LLVMMetadataRef File
,
577 uint64_t AlignInBits
,
578 LLVMMetadataRef Elements
,
579 LLVMMetadataRef ClassType
)
581 return wrap(Builder
->createEnumerationType(
582 unwrapDI
<DIDescriptor
>(Scope
),
584 unwrapDI
<DIFile
>(File
),
588 unwrapDI
<DIArray
>(Elements
),
589 unwrapDI
<DIType
>(ClassType
)));
592 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateUnionType(
593 DIBuilderRef Builder
,
594 LLVMMetadataRef Scope
,
596 LLVMMetadataRef File
,
599 uint64_t AlignInBits
,
601 LLVMMetadataRef Elements
,
602 unsigned RunTimeLang
,
603 const char* UniqueId
)
605 return wrap(Builder
->createUnionType(
606 unwrapDI
<DIDescriptor
>(Scope
),
608 unwrapDI
<DIFile
>(File
),
613 unwrapDI
<DIArray
>(Elements
),
619 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateTemplateTypeParameter(
620 DIBuilderRef Builder
,
621 LLVMMetadataRef Scope
,
624 LLVMMetadataRef File
,
628 return wrap(Builder
->createTemplateTypeParameter(
629 unwrapDI
<DIDescriptor
>(Scope
),
631 unwrapDI
<DIType
>(Ty
),
632 unwrapDI
<MDNode
*>(File
),
637 extern "C" int64_t LLVMDIBuilderCreateOpDeref()
639 return dwarf::DW_OP_deref
;
642 extern "C" int64_t LLVMDIBuilderCreateOpPlus()
644 return dwarf::DW_OP_plus
;
647 extern "C" LLVMMetadataRef
LLVMDIBuilderCreateNameSpace(
648 DIBuilderRef Builder
,
649 LLVMMetadataRef Scope
,
651 LLVMMetadataRef File
,
654 return wrap(Builder
->createNameSpace(
655 unwrapDI
<DIDescriptor
>(Scope
),
657 unwrapDI
<DIFile
>(File
),
661 extern "C" void LLVMDICompositeTypeSetTypeArray(
662 DIBuilderRef Builder
,
663 LLVMMetadataRef CompositeType
,
664 LLVMMetadataRef TypeArray
)
666 #if LLVM_VERSION_MINOR >= 6
667 DICompositeType tmp
= unwrapDI
<DICompositeType
>(CompositeType
);
668 Builder
->replaceArrays(tmp
, unwrapDI
<DIArray
>(TypeArray
));
670 unwrapDI
<DICompositeType
>(CompositeType
).setTypeArray(unwrapDI
<DIArray
>(TypeArray
));
674 extern "C" LLVMValueRef
LLVMDIBuilderCreateDebugLocation(
675 LLVMContextRef Context
,
678 LLVMMetadataRef Scope
,
679 LLVMMetadataRef InlinedAt
) {
681 LLVMContext
& context
= *unwrap(Context
);
683 DebugLoc debug_loc
= DebugLoc::get(Line
,
685 unwrapDI
<MDNode
*>(Scope
),
686 unwrapDI
<MDNode
*>(InlinedAt
));
688 #if LLVM_VERSION_MINOR >= 6
689 return wrap(MetadataAsValue::get(context
, debug_loc
.getAsMDNode(context
)));
691 return wrap(debug_loc
.getAsMDNode(context
));
695 extern "C" void LLVMWriteTypeToString(LLVMTypeRef Type
, RustStringRef str
) {
696 raw_rust_string_ostream
os(str
);
697 unwrap
<llvm::Type
>(Type
)->print(os
);
700 extern "C" void LLVMWriteValueToString(LLVMValueRef Value
, RustStringRef str
) {
701 raw_rust_string_ostream
os(str
);
703 unwrap
<llvm::Value
>(Value
)->getType()->print(os
);
705 unwrap
<llvm::Value
>(Value
)->print(os
);
710 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst
, char *bc
, size_t len
) {
711 Module
*Dst
= unwrap(dst
);
712 #if LLVM_VERSION_MINOR >= 6
713 std::unique_ptr
<MemoryBuffer
> buf
= MemoryBuffer::getMemBufferCopy(StringRef(bc
, len
));
714 ErrorOr
<Module
*> Src
= llvm::getLazyBitcodeModule(std::move(buf
), Dst
->getContext());
716 MemoryBuffer
* buf
= MemoryBuffer::getMemBufferCopy(StringRef(bc
, len
));
717 ErrorOr
<Module
*> Src
= llvm::getLazyBitcodeModule(buf
, Dst
->getContext());
720 LLVMRustSetLastError(Src
.getError().message().c_str());
721 #if LLVM_VERSION_MINOR == 5
729 #if LLVM_VERSION_MINOR >= 6
730 raw_string_ostream
Stream(Err
);
731 DiagnosticPrinterRawOStream
DP(Stream
);
732 if (Linker::LinkModules(Dst
, *Src
, [&](const DiagnosticInfo
&DI
) { DI
.print(DP
); })) {
734 if (Linker::LinkModules(Dst
, *Src
, Linker::DestroySource
, &Err
)) {
736 LLVMRustSetLastError(Err
.c_str());
743 LLVMRustOpenArchive(char *path
) {
744 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> buf_or
= MemoryBuffer::getFile(path
,
748 LLVMRustSetLastError(buf_or
.getError().message().c_str());
752 #if LLVM_VERSION_MINOR >= 6
753 ErrorOr
<std::unique_ptr
<Archive
>> archive_or
=
754 Archive::create(buf_or
.get()->getMemBufferRef());
757 LLVMRustSetLastError(archive_or
.getError().message().c_str());
761 OwningBinary
<Archive
> *ret
= new OwningBinary
<Archive
>(
762 std::move(archive_or
.get()), std::move(buf_or
.get()));
765 Archive
*ret
= new Archive(std::move(buf_or
.get()), err
);
767 LLVMRustSetLastError(err
.message().c_str());
775 #if LLVM_VERSION_MINOR >= 6
776 typedef OwningBinary
<Archive
> RustArchive
;
777 #define GET_ARCHIVE(a) ((a)->getBinary())
779 typedef Archive RustArchive
;
780 #define GET_ARCHIVE(a) (a)
784 LLVMRustDestroyArchive(RustArchive
*ar
) {
788 struct RustArchiveIterator
{
789 Archive::child_iterator cur
;
790 Archive::child_iterator end
;
793 extern "C" RustArchiveIterator
*
794 LLVMRustArchiveIteratorNew(RustArchive
*ra
) {
795 Archive
*ar
= GET_ARCHIVE(ra
);
796 RustArchiveIterator
*rai
= new RustArchiveIterator();
797 rai
->cur
= ar
->child_begin();
798 rai
->end
= ar
->child_end();
802 extern "C" const Archive::Child
*
803 LLVMRustArchiveIteratorCurrent(RustArchiveIterator
*rai
) {
804 if (rai
->cur
== rai
->end
)
806 const Archive::Child
&ret
= *rai
->cur
;
811 LLVMRustArchiveIteratorNext(RustArchiveIterator
*rai
) {
812 if (rai
->cur
== rai
->end
)
818 LLVMRustArchiveIteratorFree(RustArchiveIterator
*rai
) {
822 extern "C" const char*
823 LLVMRustArchiveChildName(const Archive::Child
*child
, size_t *size
) {
824 ErrorOr
<StringRef
> name_or_err
= child
->getName();
825 if (name_or_err
.getError())
827 StringRef name
= name_or_err
.get();
832 extern "C" const char*
833 LLVMRustArchiveChildData(Archive::Child
*child
, size_t *size
) {
834 StringRef buf
= child
->getBuffer();
840 LLVMRustSetDLLExportStorageClass(LLVMValueRef Value
) {
841 GlobalValue
*V
= unwrap
<GlobalValue
>(Value
);
842 V
->setDLLStorageClass(GlobalValue::DLLExportStorageClass
);
845 // Note that the two following functions look quite similar to the
846 // LLVMGetSectionName function. Sadly, it appears that this function only
847 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
848 // function provided by LLVM doesn't return the length, so we've created our own
849 // function which returns the length as well as the data pointer.
851 // For an example of this not returning a null terminated string, see
852 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
853 // branches explicitly creates a StringRef without a null terminator, and then
856 inline section_iterator
*unwrap(LLVMSectionIteratorRef SI
) {
857 return reinterpret_cast<section_iterator
*>(SI
);
861 LLVMRustGetSectionName(LLVMSectionIteratorRef SI
, const char **ptr
) {
863 if (std::error_code ec
= (*unwrap(SI
))->getName(ret
))
864 report_fatal_error(ec
.message());
869 // LLVMArrayType function does not support 64-bit ElementCount
870 extern "C" LLVMTypeRef
871 LLVMRustArrayType(LLVMTypeRef ElementType
, uint64_t ElementCount
) {
872 return wrap(ArrayType::get(unwrap(ElementType
), ElementCount
));
875 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine
, LLVMTwineRef
)
876 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc
, LLVMDebugLocRef
)
879 LLVMWriteTwineToString(LLVMTwineRef T
, RustStringRef str
) {
880 raw_rust_string_ostream
os(str
);
881 unwrap(T
)->print(os
);
885 LLVMUnpackOptimizationDiagnostic(
886 LLVMDiagnosticInfoRef di
,
887 const char **pass_name_out
,
888 LLVMValueRef
*function_out
,
889 LLVMDebugLocRef
*debugloc_out
,
890 LLVMTwineRef
*message_out
)
892 // Undefined to call this not on an optimization diagnostic!
893 llvm::DiagnosticInfoOptimizationBase
*opt
894 = static_cast<llvm::DiagnosticInfoOptimizationBase
*>(unwrap(di
));
896 *pass_name_out
= opt
->getPassName();
897 *function_out
= wrap(&opt
->getFunction());
898 *debugloc_out
= wrap(&opt
->getDebugLoc());
899 *message_out
= wrap(&opt
->getMsg());
903 LLVMUnpackInlineAsmDiagnostic(
904 LLVMDiagnosticInfoRef di
,
905 unsigned *cookie_out
,
906 LLVMTwineRef
*message_out
,
907 LLVMValueRef
*instruction_out
)
909 // Undefined to call this not on an inline assembly diagnostic!
910 llvm::DiagnosticInfoInlineAsm
*ia
911 = static_cast<llvm::DiagnosticInfoInlineAsm
*>(unwrap(di
));
913 *cookie_out
= ia
->getLocCookie();
914 *message_out
= wrap(&ia
->getMsgStr());
915 *instruction_out
= wrap(ia
->getInstruction());
918 extern "C" void LLVMWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di
, RustStringRef str
) {
919 raw_rust_string_ostream
os(str
);
920 DiagnosticPrinterRawOStream
dp(os
);
921 unwrap(di
)->print(dp
);
924 extern "C" int LLVMGetDiagInfoKind(LLVMDiagnosticInfoRef di
) {
925 return unwrap(di
)->getKind();
928 extern "C" void LLVMWriteDebugLocToString(
933 raw_rust_string_ostream
os(str
);
934 unwrap(dl
)->print(*unwrap(C
), os
);
937 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic
, LLVMSMDiagnosticRef
)
939 extern "C" void LLVMSetInlineAsmDiagnosticHandler(
941 LLVMContext::InlineAsmDiagHandlerTy H
,
944 unwrap(C
)->setInlineAsmDiagnosticHandler(H
, CX
);
947 extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d
, RustStringRef str
) {
948 raw_rust_string_ostream
os(str
);
949 unwrap(d
)->print("", os
);