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 LLVMAddFunctionAttrStringValue(LLVMValueRef Fn, unsigned index,
147 Function *F = unwrap<Function>(Fn);
149 B.addAttribute(Name, Value);
150 F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
153 extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, unsigned index, const char *Name) {
154 Function *f = unwrap<Function>(fn);
155 LLVMContext &C = f->getContext();
157 B.addAttribute(Name);
158 AttributeSet to_remove = AttributeSet::get(C, index, B);
160 AttributeSet attrs = f->getAttributes();
161 f->setAttributes(attrs.removeAttributes(f->getContext(),
166 extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
169 AtomicOrdering order,
170 unsigned alignment) {
171 LoadInst* li = new LoadInst(unwrap(source),0);
172 li->setVolatile(true);
173 li->setAtomic(order);
174 li->setAlignment(alignment);
175 return wrap(unwrap(B)->Insert(li, Name));
178 extern "C" LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef B,
181 AtomicOrdering order,
182 unsigned alignment) {
183 StoreInst* si = new StoreInst(unwrap(val),unwrap(target));
184 si->setVolatile(true);
185 si->setAtomic(order);
186 si->setAlignment(alignment);
187 return wrap(unwrap(B)->Insert(si));
190 extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
194 AtomicOrdering order,
195 AtomicOrdering failure_order) {
196 return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
197 unwrap(source), order,
201 extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B,
202 AtomicOrdering order,
203 SynchronizationScope scope) {
204 return wrap(unwrap(B)->CreateFence(order, scope));
207 extern "C" void LLVMSetDebug(int Enabled) {
213 extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty,
216 LLVMBool HasSideEffects,
217 LLVMBool IsAlignStack,
219 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
220 Constraints, HasSideEffects,
221 IsAlignStack, (InlineAsm::AsmDialect) Dialect));
224 typedef DIBuilder* DIBuilderRef;
226 #if LLVM_VERSION_MINOR >= 6
227 typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
230 DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef)
232 inline Metadata **unwrap(LLVMMetadataRef *Vals) {
233 return reinterpret_cast<Metadata**>(Vals);
237 typedef LLVMValueRef LLVMMetadataRef;
240 template<typename DIT>
241 DIT* unwrapDIptr(LLVMMetadataRef ref) {
242 return (DIT*) (ref ? unwrap<MDNode>(ref) : NULL);
245 #if LLVM_VERSION_MINOR <= 6
246 template<typename DIT>
247 DIT unwrapDI(LLVMMetadataRef ref) {
248 return DIT(ref ? unwrap<MDNode>(ref) : NULL);
251 #define DIDescriptor DIScope
252 #define DIArray DINodeArray
253 #define unwrapDI unwrapDIptr
256 #if LLVM_VERSION_MINOR <= 5
257 #define DISubroutineType DICompositeType
260 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
261 return DEBUG_METADATA_VERSION;
264 extern "C" uint32_t LLVMVersionMinor() {
265 return LLVM_VERSION_MINOR;
268 extern "C" uint32_t LLVMVersionMajor() {
269 return LLVM_VERSION_MAJOR;
272 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
275 unwrap(M)->addModuleFlag(Module::Warning, name, value);
278 extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
279 return new DIBuilder(*unwrap(M));
282 extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) {
286 extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) {
290 extern "C" LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
291 DIBuilderRef Builder,
295 const char* Producer,
299 const char* SplitName) {
300 return wrap(Builder->createCompileUnit(Lang,
310 extern "C" LLVMMetadataRef LLVMDIBuilderCreateFile(
311 DIBuilderRef Builder,
312 const char* Filename,
313 const char* Directory) {
314 return wrap(Builder->createFile(Filename, Directory));
317 extern "C" LLVMMetadataRef LLVMDIBuilderCreateSubroutineType(
318 DIBuilderRef Builder,
319 LLVMMetadataRef File,
320 LLVMMetadataRef ParameterTypes) {
321 return wrap(Builder->createSubroutineType(
322 unwrapDI<DIFile>(File),
323 #if LLVM_VERSION_MINOR >= 7
324 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
325 #elif LLVM_VERSION_MINOR >= 6
326 unwrapDI<DITypeArray>(ParameterTypes)));
328 unwrapDI<DIArray>(ParameterTypes)));
332 extern "C" LLVMMetadataRef LLVMDIBuilderCreateFunction(
333 DIBuilderRef Builder,
334 LLVMMetadataRef Scope,
336 const char* LinkageName,
337 LLVMMetadataRef File,
346 LLVMMetadataRef TParam,
347 LLVMMetadataRef Decl) {
348 return wrap(Builder->createFunction(
349 unwrapDI<DIScope>(Scope), Name, LinkageName,
350 unwrapDI<DIFile>(File), LineNo,
351 unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
353 unwrap<Function>(Fn),
354 unwrapDIptr<MDNode>(TParam),
355 unwrapDIptr<MDNode>(Decl)));
358 extern "C" LLVMMetadataRef LLVMDIBuilderCreateBasicType(
359 DIBuilderRef Builder,
362 uint64_t AlignInBits,
364 return wrap(Builder->createBasicType(
366 AlignInBits, Encoding));
369 extern "C" LLVMMetadataRef LLVMDIBuilderCreatePointerType(
370 DIBuilderRef Builder,
371 LLVMMetadataRef PointeeTy,
373 uint64_t AlignInBits,
375 return wrap(Builder->createPointerType(
376 unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
379 extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType(
380 DIBuilderRef Builder,
381 LLVMMetadataRef Scope,
383 LLVMMetadataRef File,
386 uint64_t AlignInBits,
388 LLVMMetadataRef DerivedFrom,
389 LLVMMetadataRef Elements,
390 unsigned RunTimeLang,
391 LLVMMetadataRef VTableHolder,
392 const char *UniqueId) {
393 return wrap(Builder->createStructType(
394 unwrapDI<DIDescriptor>(Scope),
396 unwrapDI<DIFile>(File),
401 unwrapDI<DIType>(DerivedFrom),
402 #if LLVM_VERSION_MINOR >= 7
403 DINodeArray(unwrapDI<MDTuple>(Elements)),
405 unwrapDI<DIArray>(Elements),
408 unwrapDI<DIType>(VTableHolder),
413 extern "C" LLVMMetadataRef LLVMDIBuilderCreateMemberType(
414 DIBuilderRef Builder,
415 LLVMMetadataRef Scope,
417 LLVMMetadataRef File,
420 uint64_t AlignInBits,
421 uint64_t OffsetInBits,
423 LLVMMetadataRef Ty) {
424 return wrap(Builder->createMemberType(
425 unwrapDI<DIDescriptor>(Scope), Name,
426 unwrapDI<DIFile>(File), LineNo,
427 SizeInBits, AlignInBits, OffsetInBits, Flags,
428 unwrapDI<DIType>(Ty)));
431 extern "C" LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(
432 DIBuilderRef Builder,
433 LLVMMetadataRef Scope,
434 LLVMMetadataRef File,
437 return wrap(Builder->createLexicalBlock(
438 unwrapDI<DIDescriptor>(Scope),
439 unwrapDI<DIFile>(File), Line, Col
440 #if LLVM_VERSION_MINOR == 5
446 extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable(
447 DIBuilderRef Builder,
448 LLVMMetadataRef Context,
450 const char* LinkageName,
451 LLVMMetadataRef File,
456 LLVMMetadataRef Decl = NULL) {
457 #if LLVM_VERSION_MINOR >= 6
458 return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context),
460 return wrap(Builder->createStaticVariable(unwrapDI<DIDescriptor>(Context),
464 unwrapDI<DIFile>(File),
466 unwrapDI<DIType>(Ty),
468 cast<Constant>(unwrap(Val)),
469 unwrapDIptr<MDNode>(Decl)));
472 extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
473 DIBuilderRef Builder,
475 LLVMMetadataRef Scope,
477 LLVMMetadataRef File,
483 unsigned AddrOpsCount,
485 #if LLVM_VERSION_MINOR == 5
486 if (AddrOpsCount > 0) {
487 SmallVector<llvm::Value *, 16> addr_ops;
488 llvm::Type *Int64Ty = Type::getInt64Ty(unwrap<MDNode>(Scope)->getContext());
489 for (unsigned i = 0; i < AddrOpsCount; ++i)
490 addr_ops.push_back(ConstantInt::get(Int64Ty, AddrOps[i]));
492 return wrap(Builder->createComplexVariable(
494 unwrapDI<DIDescriptor>(Scope),
496 unwrapDI<DIFile>(File),
498 unwrapDI<DIType>(Ty),
504 return wrap(Builder->createLocalVariable(Tag,
505 unwrapDI<DIDescriptor>(Scope), Name,
506 unwrapDI<DIFile>(File),
508 unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
511 extern "C" LLVMMetadataRef LLVMDIBuilderCreateArrayType(
512 DIBuilderRef Builder,
514 uint64_t AlignInBits,
516 LLVMMetadataRef Subscripts) {
517 return wrap(Builder->createArrayType(Size, AlignInBits,
518 unwrapDI<DIType>(Ty),
519 #if LLVM_VERSION_MINOR >= 7
520 DINodeArray(unwrapDI<MDTuple>(Subscripts))
522 unwrapDI<DIArray>(Subscripts)
527 extern "C" LLVMMetadataRef LLVMDIBuilderCreateVectorType(
528 DIBuilderRef Builder,
530 uint64_t AlignInBits,
532 LLVMMetadataRef Subscripts) {
533 return wrap(Builder->createVectorType(Size, AlignInBits,
534 unwrapDI<DIType>(Ty),
535 #if LLVM_VERSION_MINOR >= 7
536 DINodeArray(unwrapDI<MDTuple>(Subscripts))
538 unwrapDI<DIArray>(Subscripts)
543 extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(
544 DIBuilderRef Builder,
547 return wrap(Builder->getOrCreateSubrange(Lo, Count));
550 extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(
551 DIBuilderRef Builder,
552 LLVMMetadataRef* Ptr,
554 #if LLVM_VERSION_MINOR >= 7
555 Metadata **DataValue = unwrap(Ptr);
556 return wrap(Builder->getOrCreateArray(
557 ArrayRef<Metadata*>(DataValue, Count)).get());
559 return wrap(Builder->getOrCreateArray(
560 #if LLVM_VERSION_MINOR >= 6
561 ArrayRef<Metadata*>(unwrap(Ptr), Count)));
563 ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
568 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
569 DIBuilderRef Builder,
571 LLVMMetadataRef VarInfo,
573 unsigned AddrOpsCount,
575 LLVMBasicBlockRef InsertAtEnd) {
576 return wrap(Builder->insertDeclare(
578 #if LLVM_VERSION_MINOR >= 7
579 unwrap<DILocalVariable>(VarInfo),
581 unwrapDI<DIVariable>(VarInfo),
583 #if LLVM_VERSION_MINOR >= 6
584 Builder->createExpression(
585 llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
587 #if LLVM_VERSION_MINOR >= 7
588 DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
590 unwrap(InsertAtEnd)));
593 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
594 DIBuilderRef Builder,
596 LLVMMetadataRef VarInfo,
598 unsigned AddrOpsCount,
600 LLVMValueRef InsertBefore) {
601 #if LLVM_VERSION_MINOR >= 6
603 return wrap(Builder->insertDeclare(
605 #if LLVM_VERSION_MINOR >= 7
606 unwrap<DILocalVariable>(VarInfo),
608 unwrapDI<DIVariable>(VarInfo),
610 #if LLVM_VERSION_MINOR >= 6
611 Builder->createExpression(
612 llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
614 #if LLVM_VERSION_MINOR >= 7
615 DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
617 unwrap<Instruction>(InsertBefore)));
620 extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerator(
621 DIBuilderRef Builder,
625 return wrap(Builder->createEnumerator(Name, Val));
628 extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
629 DIBuilderRef Builder,
630 LLVMMetadataRef Scope,
632 LLVMMetadataRef File,
635 uint64_t AlignInBits,
636 LLVMMetadataRef Elements,
637 LLVMMetadataRef ClassType)
639 return wrap(Builder->createEnumerationType(
640 unwrapDI<DIDescriptor>(Scope),
642 unwrapDI<DIFile>(File),
646 #if LLVM_VERSION_MINOR >= 7
647 DINodeArray(unwrapDI<MDTuple>(Elements)),
649 unwrapDI<DIArray>(Elements),
651 unwrapDI<DIType>(ClassType)));
654 extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType(
655 DIBuilderRef Builder,
656 LLVMMetadataRef Scope,
658 LLVMMetadataRef File,
661 uint64_t AlignInBits,
663 LLVMMetadataRef Elements,
664 unsigned RunTimeLang,
665 const char* UniqueId)
667 return wrap(Builder->createUnionType(
668 unwrapDI<DIDescriptor>(Scope),
670 unwrapDI<DIFile>(File),
675 #if LLVM_VERSION_MINOR >= 7
676 DINodeArray(unwrapDI<MDTuple>(Elements)),
678 unwrapDI<DIArray>(Elements),
685 extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter(
686 DIBuilderRef Builder,
687 LLVMMetadataRef Scope,
690 LLVMMetadataRef File,
694 return wrap(Builder->createTemplateTypeParameter(
695 unwrapDI<DIDescriptor>(Scope),
698 #if LLVM_VERSION_MINOR <= 6
700 unwrapDI<MDNode*>(File),
707 extern "C" int64_t LLVMDIBuilderCreateOpDeref()
709 return dwarf::DW_OP_deref;
712 extern "C" int64_t LLVMDIBuilderCreateOpPlus()
714 return dwarf::DW_OP_plus;
717 extern "C" LLVMMetadataRef LLVMDIBuilderCreateNameSpace(
718 DIBuilderRef Builder,
719 LLVMMetadataRef Scope,
721 LLVMMetadataRef File,
724 return wrap(Builder->createNameSpace(
725 unwrapDI<DIDescriptor>(Scope),
727 unwrapDI<DIFile>(File),
731 extern "C" void LLVMDICompositeTypeSetTypeArray(
732 DIBuilderRef Builder,
733 LLVMMetadataRef CompositeType,
734 LLVMMetadataRef TypeArray)
736 #if LLVM_VERSION_MINOR >= 7
737 DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType);
738 Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray)));
739 #elif LLVM_VERSION_MINOR >= 6
740 DICompositeType tmp = unwrapDI<DICompositeType>(CompositeType);
741 Builder->replaceArrays(tmp, unwrapDI<DIArray>(TypeArray));
743 unwrapDI<DICompositeType>(CompositeType).setTypeArray(unwrapDI<DIArray>(TypeArray));
747 extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation(
748 LLVMContextRef Context,
751 LLVMMetadataRef Scope,
752 LLVMMetadataRef InlinedAt) {
754 LLVMContext& context = *unwrap(Context);
756 DebugLoc debug_loc = DebugLoc::get(Line,
758 unwrapDIptr<MDNode>(Scope),
759 unwrapDIptr<MDNode>(InlinedAt));
761 #if LLVM_VERSION_MINOR >= 6
762 return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode(
763 #if LLVM_VERSION_MINOR <= 6
768 return wrap(debug_loc.getAsMDNode(context));
772 extern "C" void LLVMWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
773 raw_rust_string_ostream os(str);
774 unwrap<llvm::Type>(Type)->print(os);
777 extern "C" void LLVMWriteValueToString(LLVMValueRef Value, RustStringRef str) {
778 raw_rust_string_ostream os(str);
780 unwrap<llvm::Value>(Value)->getType()->print(os);
782 unwrap<llvm::Value>(Value)->print(os);
787 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
788 Module *Dst = unwrap(dst);
789 #if LLVM_VERSION_MINOR >= 6
790 std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
791 #if LLVM_VERSION_MINOR >= 7
792 ErrorOr<std::unique_ptr<Module>> Src =
793 llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
795 ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
798 MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
799 ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
802 LLVMRustSetLastError(Src.getError().message().c_str());
803 #if LLVM_VERSION_MINOR == 5
811 #if LLVM_VERSION_MINOR >= 6
812 raw_string_ostream Stream(Err);
813 DiagnosticPrinterRawOStream DP(Stream);
814 #if LLVM_VERSION_MINOR >= 7
815 if (Linker::LinkModules(Dst, Src->get(), [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
817 if (Linker::LinkModules(Dst, *Src, [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
820 if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
822 LLVMRustSetLastError(Err.c_str());
829 LLVMRustOpenArchive(char *path) {
830 ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path,
834 LLVMRustSetLastError(buf_or.getError().message().c_str());
838 #if LLVM_VERSION_MINOR >= 6
839 ErrorOr<std::unique_ptr<Archive>> archive_or =
840 Archive::create(buf_or.get()->getMemBufferRef());
843 LLVMRustSetLastError(archive_or.getError().message().c_str());
847 OwningBinary<Archive> *ret = new OwningBinary<Archive>(
848 std::move(archive_or.get()), std::move(buf_or.get()));
851 Archive *ret = new Archive(std::move(buf_or.get()), err);
853 LLVMRustSetLastError(err.message().c_str());
861 #if LLVM_VERSION_MINOR >= 6
862 typedef OwningBinary<Archive> RustArchive;
863 #define GET_ARCHIVE(a) ((a)->getBinary())
865 typedef Archive RustArchive;
866 #define GET_ARCHIVE(a) (a)
870 LLVMRustDestroyArchive(RustArchive *ar) {
874 struct RustArchiveIterator {
875 Archive::child_iterator cur;
876 Archive::child_iterator end;
879 extern "C" RustArchiveIterator*
880 LLVMRustArchiveIteratorNew(RustArchive *ra) {
881 Archive *ar = GET_ARCHIVE(ra);
882 RustArchiveIterator *rai = new RustArchiveIterator();
883 rai->cur = ar->child_begin();
884 rai->end = ar->child_end();
888 extern "C" const Archive::Child*
889 LLVMRustArchiveIteratorCurrent(RustArchiveIterator *rai) {
890 if (rai->cur == rai->end)
892 #if LLVM_VERSION_MINOR >= 6
893 const Archive::Child &ret = *rai->cur;
896 return rai->cur.operator->();
901 LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) {
902 if (rai->cur == rai->end)
908 LLVMRustArchiveIteratorFree(RustArchiveIterator *rai) {
912 extern "C" const char*
913 LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
914 ErrorOr<StringRef> name_or_err = child->getName();
915 if (name_or_err.getError())
917 StringRef name = name_or_err.get();
922 extern "C" const char*
923 LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
924 StringRef buf = child->getBuffer();
930 LLVMRustSetDLLStorageClass(LLVMValueRef Value,
931 GlobalValue::DLLStorageClassTypes Class) {
932 GlobalValue *V = unwrap<GlobalValue>(Value);
933 V->setDLLStorageClass(Class);
936 // Note that the two following functions look quite similar to the
937 // LLVMGetSectionName function. Sadly, it appears that this function only
938 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
939 // function provided by LLVM doesn't return the length, so we've created our own
940 // function which returns the length as well as the data pointer.
942 // For an example of this not returning a null terminated string, see
943 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
944 // branches explicitly creates a StringRef without a null terminator, and then
947 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
948 return reinterpret_cast<section_iterator*>(SI);
952 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
954 if (std::error_code ec = (*unwrap(SI))->getName(ret))
955 report_fatal_error(ec.message());
960 // LLVMArrayType function does not support 64-bit ElementCount
961 extern "C" LLVMTypeRef
962 LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {
963 return wrap(ArrayType::get(unwrap(ElementType), ElementCount));
966 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
967 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
970 LLVMWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
971 raw_rust_string_ostream os(str);
972 unwrap(T)->print(os);
976 LLVMUnpackOptimizationDiagnostic(
977 LLVMDiagnosticInfoRef di,
978 const char **pass_name_out,
979 LLVMValueRef *function_out,
980 LLVMDebugLocRef *debugloc_out,
981 LLVMTwineRef *message_out)
983 // Undefined to call this not on an optimization diagnostic!
984 llvm::DiagnosticInfoOptimizationBase *opt
985 = static_cast<llvm::DiagnosticInfoOptimizationBase*>(unwrap(di));
987 *pass_name_out = opt->getPassName();
988 *function_out = wrap(&opt->getFunction());
989 *debugloc_out = wrap(&opt->getDebugLoc());
990 *message_out = wrap(&opt->getMsg());
994 LLVMUnpackInlineAsmDiagnostic(
995 LLVMDiagnosticInfoRef di,
996 unsigned *cookie_out,
997 LLVMTwineRef *message_out,
998 LLVMValueRef *instruction_out)
1000 // Undefined to call this not on an inline assembly diagnostic!
1001 llvm::DiagnosticInfoInlineAsm *ia
1002 = static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di));
1004 *cookie_out = ia->getLocCookie();
1005 *message_out = wrap(&ia->getMsgStr());
1006 *instruction_out = wrap(ia->getInstruction());
1009 extern "C" void LLVMWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
1010 raw_rust_string_ostream os(str);
1011 DiagnosticPrinterRawOStream dp(os);
1012 unwrap(di)->print(dp);
1015 extern "C" int LLVMGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
1016 return unwrap(di)->getKind();
1019 extern "C" void LLVMWriteDebugLocToString(
1024 raw_rust_string_ostream os(str);
1025 #if LLVM_VERSION_MINOR >= 7
1026 unwrap(dl)->print(os);
1028 unwrap(dl)->print(*unwrap(C), os);
1032 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1034 extern "C" void LLVMSetInlineAsmDiagnosticHandler(
1036 LLVMContext::InlineAsmDiagHandlerTy H,
1039 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1042 extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, RustStringRef str) {
1043 raw_rust_string_ostream os(str);
1044 unwrap(d)->print("", os);