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" uint32_t LLVMRustDebugMetadataVersion() {
237 return DEBUG_METADATA_VERSION;
240 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
243 unwrap(M)->addModuleFlag(Module::Warning, name, value);
246 extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
247 return new DIBuilder(*unwrap(M));
250 extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) {
254 extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) {
258 extern "C" LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
259 DIBuilderRef Builder,
263 const char* Producer,
267 const char* SplitName) {
268 return wrap(Builder->createCompileUnit(Lang,
278 extern "C" LLVMMetadataRef LLVMDIBuilderCreateFile(
279 DIBuilderRef Builder,
280 const char* Filename,
281 const char* Directory) {
282 return wrap(Builder->createFile(Filename, Directory));
285 extern "C" LLVMMetadataRef LLVMDIBuilderCreateSubroutineType(
286 DIBuilderRef Builder,
287 LLVMMetadataRef File,
288 LLVMMetadataRef ParameterTypes) {
289 return wrap(Builder->createSubroutineType(
290 unwrapDI<DIFile>(File),
291 #if LLVM_VERSION_MINOR >= 6
292 unwrapDI<DITypeArray>(ParameterTypes)));
294 unwrapDI<DIArray>(ParameterTypes)));
298 extern "C" LLVMMetadataRef LLVMDIBuilderCreateFunction(
299 DIBuilderRef Builder,
300 LLVMMetadataRef Scope,
302 const char* LinkageName,
303 LLVMMetadataRef File,
312 LLVMMetadataRef TParam,
313 LLVMMetadataRef Decl) {
314 return wrap(Builder->createFunction(
315 unwrapDI<DIScope>(Scope), Name, LinkageName,
316 unwrapDI<DIFile>(File), LineNo,
317 unwrapDI<DICompositeType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
319 unwrap<Function>(Fn),
320 unwrapDI<MDNode*>(TParam),
321 unwrapDI<MDNode*>(Decl)));
324 extern "C" LLVMMetadataRef LLVMDIBuilderCreateBasicType(
325 DIBuilderRef Builder,
328 uint64_t AlignInBits,
330 return wrap(Builder->createBasicType(
332 AlignInBits, Encoding));
335 extern "C" LLVMMetadataRef LLVMDIBuilderCreatePointerType(
336 DIBuilderRef Builder,
337 LLVMMetadataRef PointeeTy,
339 uint64_t AlignInBits,
341 return wrap(Builder->createPointerType(
342 unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
345 extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType(
346 DIBuilderRef Builder,
347 LLVMMetadataRef Scope,
349 LLVMMetadataRef File,
352 uint64_t AlignInBits,
354 LLVMMetadataRef DerivedFrom,
355 LLVMMetadataRef Elements,
356 unsigned RunTimeLang,
357 LLVMMetadataRef VTableHolder,
358 const char *UniqueId) {
359 return wrap(Builder->createStructType(
360 unwrapDI<DIDescriptor>(Scope),
362 unwrapDI<DIFile>(File),
367 unwrapDI<DIType>(DerivedFrom),
368 unwrapDI<DIArray>(Elements),
370 unwrapDI<DIType>(VTableHolder),
375 extern "C" LLVMMetadataRef LLVMDIBuilderCreateMemberType(
376 DIBuilderRef Builder,
377 LLVMMetadataRef Scope,
379 LLVMMetadataRef File,
382 uint64_t AlignInBits,
383 uint64_t OffsetInBits,
385 LLVMMetadataRef Ty) {
386 return wrap(Builder->createMemberType(
387 unwrapDI<DIDescriptor>(Scope), Name,
388 unwrapDI<DIFile>(File), LineNo,
389 SizeInBits, AlignInBits, OffsetInBits, Flags,
390 unwrapDI<DIType>(Ty)));
393 extern "C" LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(
394 DIBuilderRef Builder,
395 LLVMMetadataRef Scope,
396 LLVMMetadataRef File,
399 return wrap(Builder->createLexicalBlock(
400 unwrapDI<DIDescriptor>(Scope),
401 unwrapDI<DIFile>(File), Line, Col
402 #if LLVM_VERSION_MINOR == 5
408 extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable(
409 DIBuilderRef Builder,
410 LLVMMetadataRef Context,
412 const char* LinkageName,
413 LLVMMetadataRef File,
418 LLVMMetadataRef Decl = NULL) {
419 #if LLVM_VERSION_MINOR >= 6
420 return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context),
422 return wrap(Builder->createStaticVariable(unwrapDI<DIDescriptor>(Context),
426 unwrapDI<DIFile>(File),
428 unwrapDI<DIType>(Ty),
430 cast<Constant>(unwrap(Val)),
431 unwrapDI<MDNode*>(Decl)));
434 extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
435 DIBuilderRef Builder,
437 LLVMMetadataRef Scope,
439 LLVMMetadataRef File,
445 unsigned AddrOpsCount,
447 #if LLVM_VERSION_MINOR == 5
448 if (AddrOpsCount > 0) {
449 SmallVector<llvm::Value *, 16> addr_ops;
450 llvm::Type *Int64Ty = Type::getInt64Ty(unwrap<MDNode>(Scope)->getContext());
451 for (unsigned i = 0; i < AddrOpsCount; ++i)
452 addr_ops.push_back(ConstantInt::get(Int64Ty, AddrOps[i]));
454 return wrap(Builder->createComplexVariable(
456 unwrapDI<DIDescriptor>(Scope),
458 unwrapDI<DIFile>(File),
460 unwrapDI<DIType>(Ty),
466 return wrap(Builder->createLocalVariable(Tag,
467 unwrapDI<DIDescriptor>(Scope), Name,
468 unwrapDI<DIFile>(File),
470 unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
473 extern "C" LLVMMetadataRef LLVMDIBuilderCreateArrayType(
474 DIBuilderRef Builder,
476 uint64_t AlignInBits,
478 LLVMMetadataRef Subscripts) {
479 return wrap(Builder->createArrayType(Size, AlignInBits,
480 unwrapDI<DIType>(Ty),
481 unwrapDI<DIArray>(Subscripts)));
484 extern "C" LLVMMetadataRef LLVMDIBuilderCreateVectorType(
485 DIBuilderRef Builder,
487 uint64_t AlignInBits,
489 LLVMMetadataRef Subscripts) {
490 return wrap(Builder->createVectorType(Size, AlignInBits,
491 unwrapDI<DIType>(Ty),
492 unwrapDI<DIArray>(Subscripts)));
495 extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(
496 DIBuilderRef Builder,
499 return wrap(Builder->getOrCreateSubrange(Lo, Count));
502 extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(
503 DIBuilderRef Builder,
504 LLVMMetadataRef* Ptr,
506 return wrap(Builder->getOrCreateArray(
507 #if LLVM_VERSION_MINOR >= 6
508 ArrayRef<Metadata*>(unwrap(Ptr), Count)));
510 ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
514 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
515 DIBuilderRef Builder,
517 LLVMMetadataRef VarInfo,
519 unsigned AddrOpsCount,
520 LLVMBasicBlockRef InsertAtEnd) {
521 #if LLVM_VERSION_MINOR >= 6
523 if (AddrOpsCount == 0) {
524 Expr = Builder->createExpression();
526 llvm::ArrayRef<int64_t> addr_ops(AddrOps, AddrOpsCount);
527 Expr = Builder->createExpression(addr_ops);
530 return wrap(Builder->insertDeclare(
532 unwrapDI<DIVariable>(VarInfo),
533 #if LLVM_VERSION_MINOR >= 6
536 unwrap(InsertAtEnd)));
539 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
540 DIBuilderRef Builder,
542 LLVMMetadataRef VarInfo,
544 unsigned AddrOpsCount,
545 LLVMValueRef InsertBefore) {
546 #if LLVM_VERSION_MINOR >= 6
548 if (AddrOpsCount == 0) {
549 Expr = Builder->createExpression();
551 llvm::ArrayRef<int64_t> addr_ops(AddrOps, AddrOpsCount);
552 Expr = Builder->createExpression(addr_ops);
555 return wrap(Builder->insertDeclare(
557 unwrapDI<DIVariable>(VarInfo),
558 #if LLVM_VERSION_MINOR >= 6
561 unwrap<Instruction>(InsertBefore)));
564 extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerator(
565 DIBuilderRef Builder,
569 return wrap(Builder->createEnumerator(Name, Val));
572 extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
573 DIBuilderRef Builder,
574 LLVMMetadataRef Scope,
576 LLVMMetadataRef File,
579 uint64_t AlignInBits,
580 LLVMMetadataRef Elements,
581 LLVMMetadataRef ClassType)
583 return wrap(Builder->createEnumerationType(
584 unwrapDI<DIDescriptor>(Scope),
586 unwrapDI<DIFile>(File),
590 unwrapDI<DIArray>(Elements),
591 unwrapDI<DIType>(ClassType)));
594 extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType(
595 DIBuilderRef Builder,
596 LLVMMetadataRef Scope,
598 LLVMMetadataRef File,
601 uint64_t AlignInBits,
603 LLVMMetadataRef Elements,
604 unsigned RunTimeLang,
605 const char* UniqueId)
607 return wrap(Builder->createUnionType(
608 unwrapDI<DIDescriptor>(Scope),
610 unwrapDI<DIFile>(File),
615 unwrapDI<DIArray>(Elements),
621 extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter(
622 DIBuilderRef Builder,
623 LLVMMetadataRef Scope,
626 LLVMMetadataRef File,
630 return wrap(Builder->createTemplateTypeParameter(
631 unwrapDI<DIDescriptor>(Scope),
633 unwrapDI<DIType>(Ty),
634 unwrapDI<MDNode*>(File),
639 extern "C" int64_t LLVMDIBuilderCreateOpDeref()
641 return dwarf::DW_OP_deref;
644 extern "C" int64_t LLVMDIBuilderCreateOpPlus()
646 return dwarf::DW_OP_plus;
649 extern "C" LLVMMetadataRef LLVMDIBuilderCreateNameSpace(
650 DIBuilderRef Builder,
651 LLVMMetadataRef Scope,
653 LLVMMetadataRef File,
656 return wrap(Builder->createNameSpace(
657 unwrapDI<DIDescriptor>(Scope),
659 unwrapDI<DIFile>(File),
663 extern "C" void LLVMDICompositeTypeSetTypeArray(
664 DIBuilderRef Builder,
665 LLVMMetadataRef CompositeType,
666 LLVMMetadataRef TypeArray)
668 #if LLVM_VERSION_MINOR >= 6
669 DICompositeType tmp = unwrapDI<DICompositeType>(CompositeType);
670 Builder->replaceArrays(tmp, unwrapDI<DIArray>(TypeArray));
672 unwrapDI<DICompositeType>(CompositeType).setTypeArray(unwrapDI<DIArray>(TypeArray));
676 extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation(
677 LLVMContextRef Context,
680 LLVMMetadataRef Scope,
681 LLVMMetadataRef InlinedAt) {
683 LLVMContext& context = *unwrap(Context);
685 DebugLoc debug_loc = DebugLoc::get(Line,
687 unwrapDI<MDNode*>(Scope),
688 unwrapDI<MDNode*>(InlinedAt));
690 #if LLVM_VERSION_MINOR >= 6
691 return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode(context)));
693 return wrap(debug_loc.getAsMDNode(context));
697 extern "C" void LLVMWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
698 raw_rust_string_ostream os(str);
699 unwrap<llvm::Type>(Type)->print(os);
702 extern "C" void LLVMWriteValueToString(LLVMValueRef Value, RustStringRef str) {
703 raw_rust_string_ostream os(str);
705 unwrap<llvm::Value>(Value)->getType()->print(os);
707 unwrap<llvm::Value>(Value)->print(os);
712 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
713 Module *Dst = unwrap(dst);
714 #if LLVM_VERSION_MINOR >= 6
715 std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
716 ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
718 MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
719 ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
722 LLVMRustSetLastError(Src.getError().message().c_str());
723 #if LLVM_VERSION_MINOR == 5
731 #if LLVM_VERSION_MINOR >= 6
732 raw_string_ostream Stream(Err);
733 DiagnosticPrinterRawOStream DP(Stream);
734 if (Linker::LinkModules(Dst, *Src, [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
736 if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
738 LLVMRustSetLastError(Err.c_str());
745 LLVMRustOpenArchive(char *path) {
746 ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path,
750 LLVMRustSetLastError(buf_or.getError().message().c_str());
754 #if LLVM_VERSION_MINOR >= 6
755 ErrorOr<std::unique_ptr<Archive>> archive_or =
756 Archive::create(buf_or.get()->getMemBufferRef());
759 LLVMRustSetLastError(archive_or.getError().message().c_str());
763 OwningBinary<Archive> *ret = new OwningBinary<Archive>(
764 std::move(archive_or.get()), std::move(buf_or.get()));
767 Archive *ret = new Archive(std::move(buf_or.get()), err);
769 LLVMRustSetLastError(err.message().c_str());
777 #if LLVM_VERSION_MINOR >= 6
778 typedef OwningBinary<Archive> RustArchive;
779 #define GET_ARCHIVE(a) ((a)->getBinary())
781 typedef Archive RustArchive;
782 #define GET_ARCHIVE(a) (a)
786 LLVMRustDestroyArchive(RustArchive *ar) {
790 struct RustArchiveIterator {
791 Archive::child_iterator cur;
792 Archive::child_iterator end;
795 extern "C" RustArchiveIterator*
796 LLVMRustArchiveIteratorNew(RustArchive *ra) {
797 Archive *ar = GET_ARCHIVE(ra);
798 RustArchiveIterator *rai = new RustArchiveIterator();
799 rai->cur = ar->child_begin();
800 rai->end = ar->child_end();
804 extern "C" const Archive::Child*
805 LLVMRustArchiveIteratorCurrent(RustArchiveIterator *rai) {
806 if (rai->cur == rai->end)
808 const Archive::Child &ret = *rai->cur;
813 LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) {
814 if (rai->cur == rai->end)
820 LLVMRustArchiveIteratorFree(RustArchiveIterator *rai) {
824 extern "C" const char*
825 LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
826 ErrorOr<StringRef> name_or_err = child->getName();
827 if (name_or_err.getError())
829 StringRef name = name_or_err.get();
834 extern "C" const char*
835 LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
836 StringRef buf = child->getBuffer();
842 LLVMRustSetDLLStorageClass(LLVMValueRef Value,
843 GlobalValue::DLLStorageClassTypes Class) {
844 GlobalValue *V = unwrap<GlobalValue>(Value);
845 V->setDLLStorageClass(Class);
848 // Note that the two following functions look quite similar to the
849 // LLVMGetSectionName function. Sadly, it appears that this function only
850 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
851 // function provided by LLVM doesn't return the length, so we've created our own
852 // function which returns the length as well as the data pointer.
854 // For an example of this not returning a null terminated string, see
855 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
856 // branches explicitly creates a StringRef without a null terminator, and then
859 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
860 return reinterpret_cast<section_iterator*>(SI);
864 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
866 if (std::error_code ec = (*unwrap(SI))->getName(ret))
867 report_fatal_error(ec.message());
872 // LLVMArrayType function does not support 64-bit ElementCount
873 extern "C" LLVMTypeRef
874 LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {
875 return wrap(ArrayType::get(unwrap(ElementType), ElementCount));
878 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
879 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
882 LLVMWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
883 raw_rust_string_ostream os(str);
884 unwrap(T)->print(os);
888 LLVMUnpackOptimizationDiagnostic(
889 LLVMDiagnosticInfoRef di,
890 const char **pass_name_out,
891 LLVMValueRef *function_out,
892 LLVMDebugLocRef *debugloc_out,
893 LLVMTwineRef *message_out)
895 // Undefined to call this not on an optimization diagnostic!
896 llvm::DiagnosticInfoOptimizationBase *opt
897 = static_cast<llvm::DiagnosticInfoOptimizationBase*>(unwrap(di));
899 *pass_name_out = opt->getPassName();
900 *function_out = wrap(&opt->getFunction());
901 *debugloc_out = wrap(&opt->getDebugLoc());
902 *message_out = wrap(&opt->getMsg());
906 LLVMUnpackInlineAsmDiagnostic(
907 LLVMDiagnosticInfoRef di,
908 unsigned *cookie_out,
909 LLVMTwineRef *message_out,
910 LLVMValueRef *instruction_out)
912 // Undefined to call this not on an inline assembly diagnostic!
913 llvm::DiagnosticInfoInlineAsm *ia
914 = static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di));
916 *cookie_out = ia->getLocCookie();
917 *message_out = wrap(&ia->getMsgStr());
918 *instruction_out = wrap(ia->getInstruction());
921 extern "C" void LLVMWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
922 raw_rust_string_ostream os(str);
923 DiagnosticPrinterRawOStream dp(os);
924 unwrap(di)->print(dp);
927 extern "C" int LLVMGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
928 return unwrap(di)->getKind();
931 extern "C" void LLVMWriteDebugLocToString(
936 raw_rust_string_ostream os(str);
937 unwrap(dl)->print(*unwrap(C), os);
940 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
942 extern "C" void LLVMSetInlineAsmDiagnosticHandler(
944 LLVMContext::InlineAsmDiagHandlerTy H,
947 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
950 extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, RustStringRef str) {
951 raw_rust_string_ostream os(str);
952 unwrap(d)->print("", os);