2 #include "llvm/IR/CallSite.h"
3 #include "llvm/IR/DebugInfoMetadata.h"
4 #include "llvm/IR/DiagnosticInfo.h"
5 #include "llvm/IR/DiagnosticPrinter.h"
6 #include "llvm/IR/GlobalVariable.h"
7 #include "llvm/IR/Instructions.h"
8 #include "llvm/Object/Archive.h"
9 #include "llvm/Object/ObjectFile.h"
10 #include "llvm/Bitcode/BitcodeWriterPass.h"
11 #include "llvm/Support/Signals.h"
12 #include "llvm/ADT/Optional.h"
16 //===----------------------------------------------------------------------===
18 // This file defines alternate interfaces to core functions that are more
19 // readily callable by Rust's FFI.
21 //===----------------------------------------------------------------------===
24 using namespace llvm::sys;
25 using namespace llvm::object;
27 // LLVMAtomicOrdering is already an enum - don't create another
29 static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
31 case LLVMAtomicOrderingNotAtomic:
32 return AtomicOrdering::NotAtomic;
33 case LLVMAtomicOrderingUnordered:
34 return AtomicOrdering::Unordered;
35 case LLVMAtomicOrderingMonotonic:
36 return AtomicOrdering::Monotonic;
37 case LLVMAtomicOrderingAcquire:
38 return AtomicOrdering::Acquire;
39 case LLVMAtomicOrderingRelease:
40 return AtomicOrdering::Release;
41 case LLVMAtomicOrderingAcquireRelease:
42 return AtomicOrdering::AcquireRelease;
43 case LLVMAtomicOrderingSequentiallyConsistent:
44 return AtomicOrdering::SequentiallyConsistent;
47 report_fatal_error("Invalid LLVMAtomicOrdering value!");
50 static LLVM_THREAD_LOCAL char *LastError;
52 // Custom error handler for fatal LLVM errors.
54 // Notably it exits the process with code 101, unlike LLVM's default of 1.
55 static void FatalErrorHandler(void *UserData,
56 const std::string& Reason,
58 // Do the same thing that the default error handler does.
59 std::cerr << "LLVM ERROR: " << Reason << std::endl;
61 // Since this error handler exits the process, we have to run any cleanup that
62 // LLVM would run after handling the error. This might change with an LLVM
64 sys::RunInterruptHandlers();
69 extern "C" void LLVMRustInstallFatalErrorHandler() {
70 install_fatal_error_handler(FatalErrorHandler);
73 extern "C" LLVMMemoryBufferRef
74 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
75 ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =
76 MemoryBuffer::getFile(Path, -1, false);
78 LLVMRustSetLastError(BufOr.getError().message().c_str());
81 return wrap(BufOr.get().release());
84 extern "C" char *LLVMRustGetLastError(void) {
85 char *Ret = LastError;
90 extern "C" void LLVMRustSetLastError(const char *Err) {
91 free((void *)LastError);
92 LastError = strdup(Err);
95 extern "C" LLVMContextRef LLVMRustContextCreate(bool shouldDiscardNames) {
96 auto ctx = new LLVMContext();
97 ctx->setDiscardValueNames(shouldDiscardNames);
101 extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M,
102 const char *Triple) {
103 unwrap(M)->setTargetTriple(Triple::normalize(Triple));
106 extern "C" void LLVMRustPrintPassTimings() {
107 raw_fd_ostream OS(2, false); // stderr.
108 TimerGroup::printAll(OS);
111 extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M,
113 return wrap(unwrap(M)->getNamedValue(Name));
116 extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
118 LLVMTypeRef FunctionTy) {
120 unwrap(M)->getOrInsertFunction(Name, unwrap<FunctionType>(FunctionTy)));
123 extern "C" LLVMValueRef
124 LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty) {
125 return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty)));
128 extern "C" LLVMValueRef
129 LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) {
130 return wrap(new GlobalVariable(*unwrap(M),
133 GlobalValue::PrivateLinkage,
137 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
138 return wrap(Type::getMetadataTy(*unwrap(C)));
141 static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
144 return Attribute::AlwaysInline;
146 return Attribute::ByVal;
148 return Attribute::Cold;
150 return Attribute::InlineHint;
152 return Attribute::MinSize;
154 return Attribute::Naked;
156 return Attribute::NoAlias;
158 return Attribute::NoCapture;
160 return Attribute::NoInline;
162 return Attribute::NonNull;
164 return Attribute::NoRedZone;
166 return Attribute::NoReturn;
168 return Attribute::NoUnwind;
169 case OptimizeForSize:
170 return Attribute::OptimizeForSize;
172 return Attribute::ReadOnly;
174 return Attribute::SExt;
176 return Attribute::StructRet;
178 return Attribute::UWTable;
180 return Attribute::ZExt;
182 return Attribute::InReg;
184 return Attribute::SanitizeThread;
185 case SanitizeAddress:
186 return Attribute::SanitizeAddress;
188 return Attribute::SanitizeMemory;
190 return Attribute::NonLazyBind;
192 report_fatal_error("bad AttributeKind");
195 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
196 LLVMRustAttribute RustAttr) {
197 CallSite Call = CallSite(unwrap<Instruction>(Instr));
198 Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
199 Call.addAttribute(Index, Attr);
202 extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
205 CallSite Call = CallSite(unwrap<Instruction>(Instr));
207 B.addAlignmentAttr(Bytes);
208 Call.setAttributes(Call.getAttributes().addAttributes(
209 Call->getContext(), Index, B));
212 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
215 CallSite Call = CallSite(unwrap<Instruction>(Instr));
217 B.addDereferenceableAttr(Bytes);
218 Call.setAttributes(Call.getAttributes().addAttributes(
219 Call->getContext(), Index, B));
222 extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
225 CallSite Call = CallSite(unwrap<Instruction>(Instr));
227 B.addDereferenceableOrNullAttr(Bytes);
228 Call.setAttributes(Call.getAttributes().addAttributes(
229 Call->getContext(), Index, B));
232 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
233 LLVMRustAttribute RustAttr) {
234 Function *A = unwrap<Function>(Fn);
235 Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
237 A->addAttributes(Index, B);
240 extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn,
243 Function *A = unwrap<Function>(Fn);
245 B.addAlignmentAttr(Bytes);
246 A->addAttributes(Index, B);
249 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
251 Function *A = unwrap<Function>(Fn);
253 B.addDereferenceableAttr(Bytes);
254 A->addAttributes(Index, B);
257 extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
260 Function *A = unwrap<Function>(Fn);
262 B.addDereferenceableOrNullAttr(Bytes);
263 A->addAttributes(Index, B);
266 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
270 Function *F = unwrap<Function>(Fn);
272 B.addAttribute(Name, Value);
273 F->addAttributes(Index, B);
276 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
278 LLVMRustAttribute RustAttr) {
279 Function *F = unwrap<Function>(Fn);
280 Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
282 auto PAL = F->getAttributes();
283 auto PALNew = PAL.removeAttributes(F->getContext(), Index, B);
284 F->setAttributes(PALNew);
287 // enable fpmath flag UnsafeAlgebra
288 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
289 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
294 extern "C" LLVMValueRef
295 LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef Source, const char *Name,
296 LLVMAtomicOrdering Order) {
297 LoadInst *LI = new LoadInst(unwrap(Source), 0);
298 LI->setAtomic(fromRust(Order));
299 return wrap(unwrap(B)->Insert(LI, Name));
302 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
305 LLVMAtomicOrdering Order) {
306 StoreInst *SI = new StoreInst(unwrap(V), unwrap(Target));
307 SI->setAtomic(fromRust(Order));
308 return wrap(unwrap(B)->Insert(SI));
311 extern "C" LLVMValueRef
312 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
313 LLVMValueRef Old, LLVMValueRef Source,
314 LLVMAtomicOrdering Order,
315 LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
316 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
317 unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
318 fromRust(FailureOrder));
323 enum class LLVMRustSynchronizationScope {
329 static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
331 case LLVMRustSynchronizationScope::SingleThread:
332 return SyncScope::SingleThread;
333 case LLVMRustSynchronizationScope::CrossThread:
334 return SyncScope::System;
336 report_fatal_error("bad SynchronizationScope.");
340 extern "C" LLVMValueRef
341 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
342 LLVMRustSynchronizationScope Scope) {
343 return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
346 enum class LLVMRustAsmDialect {
352 static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
354 case LLVMRustAsmDialect::Att:
355 return InlineAsm::AD_ATT;
356 case LLVMRustAsmDialect::Intel:
357 return InlineAsm::AD_Intel;
359 report_fatal_error("bad AsmDialect.");
363 extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString,
365 LLVMBool HasSideEffects,
366 LLVMBool IsAlignStack,
367 LLVMRustAsmDialect Dialect) {
368 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString, Constraints,
369 HasSideEffects, IsAlignStack, fromRust(Dialect)));
372 extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty,
374 return InlineAsm::Verify(unwrap<FunctionType>(Ty), Constraints);
377 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm) {
378 unwrap(M)->appendModuleInlineAsm(StringRef(Asm));
381 typedef DIBuilder *LLVMRustDIBuilderRef;
383 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
384 return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
387 #define DIDescriptor DIScope
388 #define DIArray DINodeArray
389 #define unwrapDI unwrapDIPtr
391 // These values **must** match debuginfo::DIFlags! They also *happen*
392 // to match LLVM, but that isn't required as we do giant sets of
393 // matching below. The value shouldn't be directly passed to LLVM.
394 enum class LLVMRustDIFlags : uint32_t {
399 FlagFwdDecl = (1 << 2),
400 FlagAppleBlock = (1 << 3),
401 FlagBlockByrefStruct = (1 << 4),
402 FlagVirtual = (1 << 5),
403 FlagArtificial = (1 << 6),
404 FlagExplicit = (1 << 7),
405 FlagPrototyped = (1 << 8),
406 FlagObjcClassComplete = (1 << 9),
407 FlagObjectPointer = (1 << 10),
408 FlagVector = (1 << 11),
409 FlagStaticMember = (1 << 12),
410 FlagLValueReference = (1 << 13),
411 FlagRValueReference = (1 << 14),
412 FlagExternalTypeRef = (1 << 15),
413 FlagIntroducedVirtual = (1 << 18),
414 FlagBitField = (1 << 19),
415 FlagNoReturn = (1 << 20),
416 FlagMainSubprogram = (1 << 21),
417 // Do not add values that are not supported by the minimum LLVM
418 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
421 inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
422 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
423 static_cast<uint32_t>(B));
426 inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
427 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
428 static_cast<uint32_t>(B));
431 inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
435 inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
437 inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
438 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
441 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
442 DINode::DIFlags Result = DINode::DIFlags::FlagZero;
444 switch (visibility(Flags)) {
445 case LLVMRustDIFlags::FlagPrivate:
446 Result |= DINode::DIFlags::FlagPrivate;
448 case LLVMRustDIFlags::FlagProtected:
449 Result |= DINode::DIFlags::FlagProtected;
451 case LLVMRustDIFlags::FlagPublic:
452 Result |= DINode::DIFlags::FlagPublic;
455 // The rest are handled below
459 if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
460 Result |= DINode::DIFlags::FlagFwdDecl;
462 if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
463 Result |= DINode::DIFlags::FlagAppleBlock;
465 if (isSet(Flags & LLVMRustDIFlags::FlagBlockByrefStruct)) {
466 Result |= DINode::DIFlags::FlagBlockByrefStruct;
468 if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
469 Result |= DINode::DIFlags::FlagVirtual;
471 if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
472 Result |= DINode::DIFlags::FlagArtificial;
474 if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
475 Result |= DINode::DIFlags::FlagExplicit;
477 if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
478 Result |= DINode::DIFlags::FlagPrototyped;
480 if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
481 Result |= DINode::DIFlags::FlagObjcClassComplete;
483 if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
484 Result |= DINode::DIFlags::FlagObjectPointer;
486 if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
487 Result |= DINode::DIFlags::FlagVector;
489 if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
490 Result |= DINode::DIFlags::FlagStaticMember;
492 if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
493 Result |= DINode::DIFlags::FlagLValueReference;
495 if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
496 Result |= DINode::DIFlags::FlagRValueReference;
498 if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
499 Result |= DINode::DIFlags::FlagIntroducedVirtual;
501 if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
502 Result |= DINode::DIFlags::FlagBitField;
504 if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
505 Result |= DINode::DIFlags::FlagNoReturn;
507 if (isSet(Flags & LLVMRustDIFlags::FlagMainSubprogram)) {
508 Result |= DINode::DIFlags::FlagMainSubprogram;
514 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
515 return DEBUG_METADATA_VERSION;
518 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
520 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
522 extern "C" bool LLVMRustIsRustLLVM() {
530 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
532 unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
535 extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
536 return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
539 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
540 return new DIBuilder(*unwrap(M));
543 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
547 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
551 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
552 LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
553 const char *Producer, bool isOptimized, const char *Flags,
554 unsigned RuntimeVer, const char *SplitName) {
555 auto *File = unwrapDI<DIFile>(FileRef);
557 return wrap(Builder->createCompileUnit(Lang, File, Producer, isOptimized,
558 Flags, RuntimeVer, SplitName));
561 extern "C" LLVMMetadataRef
562 LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename,
563 const char *Directory) {
564 return wrap(Builder->createFile(Filename, Directory));
567 extern "C" LLVMMetadataRef
568 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
569 LLVMMetadataRef File,
570 LLVMMetadataRef ParameterTypes) {
571 return wrap(Builder->createSubroutineType(
572 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
575 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
576 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
577 const char *LinkageName, LLVMMetadataRef File, unsigned LineNo,
578 LLVMMetadataRef Ty, bool IsLocalToUnit, bool IsDefinition,
579 unsigned ScopeLine, LLVMRustDIFlags Flags, bool IsOptimized,
580 LLVMValueRef Fn, LLVMMetadataRef TParam, LLVMMetadataRef Decl) {
581 DITemplateParameterArray TParams =
582 DITemplateParameterArray(unwrap<MDTuple>(TParam));
583 DISubprogram *Sub = Builder->createFunction(
584 unwrapDI<DIScope>(Scope), Name, LinkageName, unwrapDI<DIFile>(File),
585 LineNo, unwrapDI<DISubroutineType>(Ty), IsLocalToUnit, IsDefinition,
586 ScopeLine, fromRust(Flags), IsOptimized, TParams,
587 unwrapDIPtr<DISubprogram>(Decl));
588 unwrap<Function>(Fn)->setSubprogram(Sub);
592 extern "C" LLVMMetadataRef
593 LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder, const char *Name,
594 uint64_t SizeInBits, uint32_t AlignInBits,
596 return wrap(Builder->createBasicType(Name, SizeInBits, Encoding));
599 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
600 LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
601 uint64_t SizeInBits, uint32_t AlignInBits, const char *Name) {
602 return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
603 SizeInBits, AlignInBits,
604 /* DWARFAddressSpace */ None,
608 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
609 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
610 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
611 uint32_t AlignInBits, LLVMRustDIFlags Flags,
612 LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
613 unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
614 const char *UniqueId) {
615 return wrap(Builder->createStructType(
616 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
617 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
618 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
619 unwrapDI<DIType>(VTableHolder), UniqueId));
622 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
623 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
624 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
625 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
626 LLVMMetadataRef Elements, const char *UniqueId) {
627 #if LLVM_VERSION_GE(7, 0)
628 return wrap(Builder->createVariantPart(
629 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
630 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
631 DINodeArray(unwrapDI<MDTuple>(Elements)), UniqueId));
637 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
638 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
639 LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
640 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
641 LLVMMetadataRef Ty) {
642 return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope), Name,
643 unwrapDI<DIFile>(File), LineNo,
644 SizeInBits, AlignInBits, OffsetInBits,
645 fromRust(Flags), unwrapDI<DIType>(Ty)));
648 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
649 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
650 const char *Name, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
651 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
652 LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
653 #if LLVM_VERSION_GE(7, 0)
654 llvm::ConstantInt* D = nullptr;
656 D = unwrap<llvm::ConstantInt>(Discriminant);
658 return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope), Name,
659 unwrapDI<DIFile>(File), LineNo,
660 SizeInBits, AlignInBits, OffsetInBits, D,
661 fromRust(Flags), unwrapDI<DIType>(Ty)));
663 return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope), Name,
664 unwrapDI<DIFile>(File), LineNo,
665 SizeInBits, AlignInBits, OffsetInBits,
666 fromRust(Flags), unwrapDI<DIType>(Ty)));
670 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
671 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
672 LLVMMetadataRef File, unsigned Line, unsigned Col) {
673 return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
674 unwrapDI<DIFile>(File), Line, Col));
677 extern "C" LLVMMetadataRef
678 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
679 LLVMMetadataRef Scope,
680 LLVMMetadataRef File) {
681 return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
682 unwrapDI<DIFile>(File)));
685 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
686 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name,
687 const char *LinkageName, LLVMMetadataRef File, unsigned LineNo,
688 LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
689 LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
690 llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
692 llvm::DIExpression *InitExpr = nullptr;
693 if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
694 InitExpr = Builder->createConstantValueExpression(
695 IntVal->getValue().getSExtValue());
696 } else if (llvm::ConstantFP *FPVal =
697 llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
698 InitExpr = Builder->createConstantValueExpression(
699 FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
702 llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
703 unwrapDI<DIDescriptor>(Context), Name, LinkageName,
704 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
705 InitExpr, unwrapDIPtr<MDNode>(Decl),
706 #if LLVM_VERSION_GE(8, 0)
707 /* templateParams */ nullptr,
711 InitVal->setMetadata("dbg", VarExpr);
713 return wrap(VarExpr);
716 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
717 LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
718 const char *Name, LLVMMetadataRef File, unsigned LineNo,
719 LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
720 unsigned ArgNo, uint32_t AlignInBits) {
721 if (Tag == 0x100) { // DW_TAG_auto_variable
722 return wrap(Builder->createAutoVariable(
723 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNo,
724 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
726 return wrap(Builder->createParameterVariable(
727 unwrapDI<DIDescriptor>(Scope), Name, ArgNo, unwrapDI<DIFile>(File),
728 LineNo, unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
732 extern "C" LLVMMetadataRef
733 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
734 uint32_t AlignInBits, LLVMMetadataRef Ty,
735 LLVMMetadataRef Subscripts) {
737 Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
738 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
741 extern "C" LLVMMetadataRef
742 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
744 return wrap(Builder->getOrCreateSubrange(Lo, Count));
747 extern "C" LLVMMetadataRef
748 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
749 LLVMMetadataRef *Ptr, unsigned Count) {
750 Metadata **DataValue = unwrap(Ptr);
752 Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
755 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
756 LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
757 int64_t *AddrOps, unsigned AddrOpsCount, LLVMValueRef DL,
758 LLVMBasicBlockRef InsertAtEnd) {
759 return wrap(Builder->insertDeclare(
760 unwrap(V), unwrap<DILocalVariable>(VarInfo),
761 Builder->createExpression(llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
762 DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
763 unwrap(InsertAtEnd)));
766 extern "C" LLVMMetadataRef
767 LLVMRustDIBuilderCreateEnumerator(LLVMRustDIBuilderRef Builder,
768 const char *Name, uint64_t Val) {
769 return wrap(Builder->createEnumerator(Name, Val));
772 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
773 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
774 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
775 uint32_t AlignInBits, LLVMMetadataRef Elements,
776 LLVMMetadataRef ClassTy, bool IsFixed) {
777 #if LLVM_VERSION_GE(7, 0)
778 return wrap(Builder->createEnumerationType(
779 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
780 SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
781 unwrapDI<DIType>(ClassTy), "", IsFixed));
783 // Ignore IsFixed on older LLVM.
784 return wrap(Builder->createEnumerationType(
785 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
786 SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
787 unwrapDI<DIType>(ClassTy), ""));
791 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
792 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
793 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
794 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
795 unsigned RunTimeLang, const char *UniqueId) {
796 return wrap(Builder->createUnionType(
797 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
798 SizeInBits, AlignInBits, fromRust(Flags),
799 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang, UniqueId));
802 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
803 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
804 LLVMMetadataRef Ty, LLVMMetadataRef File, unsigned LineNo,
806 return wrap(Builder->createTemplateTypeParameter(
807 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIType>(Ty)));
810 extern "C" LLVMMetadataRef
811 LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder,
812 LLVMMetadataRef Scope, const char *Name,
813 LLVMMetadataRef File, unsigned LineNo) {
814 return wrap(Builder->createNameSpace(
815 unwrapDI<DIDescriptor>(Scope), Name,
816 false // ExportSymbols (only relevant for C++ anonymous namespaces)
821 LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
822 LLVMMetadataRef CompositeTy,
823 LLVMMetadataRef Elements,
824 LLVMMetadataRef Params) {
825 DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
826 Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
827 DINodeArray(unwrap<MDTuple>(Params)));
830 extern "C" LLVMValueRef
831 LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef, unsigned Line,
832 unsigned Column, LLVMMetadataRef Scope,
833 LLVMMetadataRef InlinedAt) {
834 LLVMContext &Context = *unwrap(ContextRef);
836 DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(Scope),
837 unwrapDIPtr<MDNode>(InlinedAt));
839 return wrap(MetadataAsValue::get(Context, debug_loc.getAsMDNode()));
842 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
843 return dwarf::DW_OP_deref;
846 extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
847 return dwarf::DW_OP_plus_uconst;
850 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
851 RawRustStringOstream OS(Str);
852 unwrap<llvm::Type>(Ty)->print(OS);
855 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
857 RawRustStringOstream OS(Str);
862 unwrap<llvm::Value>(V)->getType()->print(OS);
864 unwrap<llvm::Value>(V)->print(OS);
869 // Note that the two following functions look quite similar to the
870 // LLVMGetSectionName function. Sadly, it appears that this function only
871 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
872 // function provided by LLVM doesn't return the length, so we've created our own
873 // function which returns the length as well as the data pointer.
875 // For an example of this not returning a null terminated string, see
876 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
877 // branches explicitly creates a StringRef without a null terminator, and then
880 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
881 return reinterpret_cast<section_iterator *>(SI);
884 extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI,
887 if (std::error_code EC = (*unwrap(SI))->getName(Ret))
888 report_fatal_error(EC.message());
893 // LLVMArrayType function does not support 64-bit ElementCount
894 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
895 uint64_t ElementCount) {
896 return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
899 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
901 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
902 RawRustStringOstream OS(Str);
903 unwrap(T)->print(OS);
906 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
907 LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
908 LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
909 RustStringRef FilenameOut, RustStringRef MessageOut) {
910 // Undefined to call this not on an optimization diagnostic!
911 llvm::DiagnosticInfoOptimizationBase *Opt =
912 static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
914 RawRustStringOstream PassNameOS(PassNameOut);
915 PassNameOS << Opt->getPassName();
916 *FunctionOut = wrap(&Opt->getFunction());
918 RawRustStringOstream FilenameOS(FilenameOut);
919 DiagnosticLocation loc = Opt->getLocation();
921 *Line = loc.getLine();
922 *Column = loc.getColumn();
923 FilenameOS << loc.getFilename();
926 RawRustStringOstream MessageOS(MessageOut);
927 MessageOS << Opt->getMsg();
931 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI, unsigned *CookieOut,
932 LLVMTwineRef *MessageOut,
933 LLVMValueRef *InstructionOut) {
934 // Undefined to call this not on an inline assembly diagnostic!
935 llvm::DiagnosticInfoInlineAsm *IA =
936 static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
938 *CookieOut = IA->getLocCookie();
939 *MessageOut = wrap(&IA->getMsgStr());
940 *InstructionOut = wrap(IA->getInstruction());
943 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
945 RawRustStringOstream OS(Str);
946 DiagnosticPrinterRawOStream DP(OS);
947 unwrap(DI)->print(DP);
950 enum class LLVMRustDiagnosticKind {
954 DebugMetadataVersion,
957 OptimizationRemarkMissed,
958 OptimizationRemarkAnalysis,
959 OptimizationRemarkAnalysisFPCommute,
960 OptimizationRemarkAnalysisAliasing,
961 OptimizationRemarkOther,
967 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
970 return LLVMRustDiagnosticKind::InlineAsm;
972 return LLVMRustDiagnosticKind::StackSize;
973 case DK_DebugMetadataVersion:
974 return LLVMRustDiagnosticKind::DebugMetadataVersion;
975 case DK_SampleProfile:
976 return LLVMRustDiagnosticKind::SampleProfile;
977 case DK_OptimizationRemark:
978 return LLVMRustDiagnosticKind::OptimizationRemark;
979 case DK_OptimizationRemarkMissed:
980 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
981 case DK_OptimizationRemarkAnalysis:
982 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
983 case DK_OptimizationRemarkAnalysisFPCommute:
984 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
985 case DK_OptimizationRemarkAnalysisAliasing:
986 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
988 return LLVMRustDiagnosticKind::PGOProfile;
990 return LLVMRustDiagnosticKind::Linker;
992 return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
993 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
994 : LLVMRustDiagnosticKind::Other;
998 extern "C" LLVMRustDiagnosticKind
999 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1000 return toRust((DiagnosticKind)unwrap(DI)->getKind());
1002 // This is kept distinct from LLVMGetTypeKind, because when
1003 // a new type kind is added, the Rust-side enum must be
1004 // updated or UB will result.
1005 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1006 switch (unwrap(Ty)->getTypeID()) {
1007 case Type::VoidTyID:
1008 return LLVMVoidTypeKind;
1009 case Type::HalfTyID:
1010 return LLVMHalfTypeKind;
1011 case Type::FloatTyID:
1012 return LLVMFloatTypeKind;
1013 case Type::DoubleTyID:
1014 return LLVMDoubleTypeKind;
1015 case Type::X86_FP80TyID:
1016 return LLVMX86_FP80TypeKind;
1017 case Type::FP128TyID:
1018 return LLVMFP128TypeKind;
1019 case Type::PPC_FP128TyID:
1020 return LLVMPPC_FP128TypeKind;
1021 case Type::LabelTyID:
1022 return LLVMLabelTypeKind;
1023 case Type::MetadataTyID:
1024 return LLVMMetadataTypeKind;
1025 case Type::IntegerTyID:
1026 return LLVMIntegerTypeKind;
1027 case Type::FunctionTyID:
1028 return LLVMFunctionTypeKind;
1029 case Type::StructTyID:
1030 return LLVMStructTypeKind;
1031 case Type::ArrayTyID:
1032 return LLVMArrayTypeKind;
1033 case Type::PointerTyID:
1034 return LLVMPointerTypeKind;
1035 case Type::VectorTyID:
1036 return LLVMVectorTypeKind;
1037 case Type::X86_MMXTyID:
1038 return LLVMX86_MMXTypeKind;
1039 case Type::TokenTyID:
1040 return LLVMTokenTypeKind;
1042 report_fatal_error("Unhandled TypeID.");
1045 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1047 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1048 LLVMContextRef C, LLVMContext::InlineAsmDiagHandlerTy H, void *CX) {
1049 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1052 extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef D,
1053 RustStringRef Str) {
1054 RawRustStringOstream OS(Str);
1055 unwrap(D)->print("", OS);
1058 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1059 LLVMValueRef ParentPad,
1061 LLVMValueRef *LLArgs,
1063 Value **Args = unwrap(LLArgs);
1064 if (ParentPad == nullptr) {
1065 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1066 ParentPad = wrap(Constant::getNullValue(Ty));
1068 return wrap(unwrap(B)->CreateCleanupPad(
1069 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1072 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1073 LLVMValueRef CleanupPad,
1074 LLVMBasicBlockRef UnwindBB) {
1075 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1076 return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1079 extern "C" LLVMValueRef
1080 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1081 unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1082 Value **Args = unwrap(LLArgs);
1083 return wrap(unwrap(B)->CreateCatchPad(
1084 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1087 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1089 LLVMBasicBlockRef BB) {
1090 return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1094 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1095 LLVMValueRef ParentPad,
1096 LLVMBasicBlockRef BB,
1097 unsigned NumHandlers,
1099 if (ParentPad == nullptr) {
1100 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1101 ParentPad = wrap(Constant::getNullValue(Ty));
1103 return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1104 NumHandlers, Name));
1107 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1108 LLVMBasicBlockRef Handler) {
1109 Value *CatchSwitch = unwrap(CatchSwitchRef);
1110 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1113 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1114 LLVMValueRef *Inputs,
1115 unsigned NumInputs) {
1116 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1119 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1123 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
1124 LLVMValueRef *Args, unsigned NumArgs,
1125 OperandBundleDef *Bundle,
1127 unsigned Len = Bundle ? 1 : 0;
1128 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1129 return wrap(unwrap(B)->CreateCall(
1130 unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Bundles, Name));
1133 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
1134 LLVMValueRef Dst, unsigned DstAlign,
1135 LLVMValueRef Src, unsigned SrcAlign,
1136 LLVMValueRef Size, bool IsVolatile) {
1137 #if LLVM_VERSION_GE(7, 0)
1138 return wrap(unwrap(B)->CreateMemCpy(
1139 unwrap(Dst), DstAlign,
1140 unwrap(Src), SrcAlign,
1141 unwrap(Size), IsVolatile));
1143 unsigned Align = std::min(DstAlign, SrcAlign);
1144 return wrap(unwrap(B)->CreateMemCpy(
1145 unwrap(Dst), unwrap(Src),
1146 unwrap(Size), Align, IsVolatile));
1150 extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
1151 LLVMValueRef Dst, unsigned DstAlign,
1152 LLVMValueRef Src, unsigned SrcAlign,
1153 LLVMValueRef Size, bool IsVolatile) {
1154 #if LLVM_VERSION_GE(7, 0)
1155 return wrap(unwrap(B)->CreateMemMove(
1156 unwrap(Dst), DstAlign,
1157 unwrap(Src), SrcAlign,
1158 unwrap(Size), IsVolatile));
1160 unsigned Align = std::min(DstAlign, SrcAlign);
1161 return wrap(unwrap(B)->CreateMemMove(
1162 unwrap(Dst), unwrap(Src),
1163 unwrap(Size), Align, IsVolatile));
1167 extern "C" LLVMValueRef
1168 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
1169 unsigned NumArgs, LLVMBasicBlockRef Then,
1170 LLVMBasicBlockRef Catch, OperandBundleDef *Bundle,
1172 unsigned Len = Bundle ? 1 : 0;
1173 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1174 return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch),
1175 makeArrayRef(unwrap(Args), NumArgs),
1179 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1180 LLVMBasicBlockRef BB) {
1181 auto Point = unwrap(BB)->getFirstInsertionPt();
1182 unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1185 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1187 Triple TargetTriple(unwrap(M)->getTargetTriple());
1188 GlobalObject *GV = unwrap<GlobalObject>(V);
1189 if (!TargetTriple.isOSBinFormatMachO()) {
1190 GV->setComdat(unwrap(M)->getOrInsertComdat(Name));
1194 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1195 GlobalObject *GV = unwrap<GlobalObject>(V);
1196 GV->setComdat(nullptr);
1199 enum class LLVMRustLinkage {
1200 ExternalLinkage = 0,
1201 AvailableExternallyLinkage = 1,
1202 LinkOnceAnyLinkage = 2,
1203 LinkOnceODRLinkage = 3,
1206 AppendingLinkage = 6,
1207 InternalLinkage = 7,
1209 ExternalWeakLinkage = 9,
1213 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1215 case LLVMExternalLinkage:
1216 return LLVMRustLinkage::ExternalLinkage;
1217 case LLVMAvailableExternallyLinkage:
1218 return LLVMRustLinkage::AvailableExternallyLinkage;
1219 case LLVMLinkOnceAnyLinkage:
1220 return LLVMRustLinkage::LinkOnceAnyLinkage;
1221 case LLVMLinkOnceODRLinkage:
1222 return LLVMRustLinkage::LinkOnceODRLinkage;
1223 case LLVMWeakAnyLinkage:
1224 return LLVMRustLinkage::WeakAnyLinkage;
1225 case LLVMWeakODRLinkage:
1226 return LLVMRustLinkage::WeakODRLinkage;
1227 case LLVMAppendingLinkage:
1228 return LLVMRustLinkage::AppendingLinkage;
1229 case LLVMInternalLinkage:
1230 return LLVMRustLinkage::InternalLinkage;
1231 case LLVMPrivateLinkage:
1232 return LLVMRustLinkage::PrivateLinkage;
1233 case LLVMExternalWeakLinkage:
1234 return LLVMRustLinkage::ExternalWeakLinkage;
1235 case LLVMCommonLinkage:
1236 return LLVMRustLinkage::CommonLinkage;
1238 report_fatal_error("Invalid LLVMRustLinkage value!");
1242 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1244 case LLVMRustLinkage::ExternalLinkage:
1245 return LLVMExternalLinkage;
1246 case LLVMRustLinkage::AvailableExternallyLinkage:
1247 return LLVMAvailableExternallyLinkage;
1248 case LLVMRustLinkage::LinkOnceAnyLinkage:
1249 return LLVMLinkOnceAnyLinkage;
1250 case LLVMRustLinkage::LinkOnceODRLinkage:
1251 return LLVMLinkOnceODRLinkage;
1252 case LLVMRustLinkage::WeakAnyLinkage:
1253 return LLVMWeakAnyLinkage;
1254 case LLVMRustLinkage::WeakODRLinkage:
1255 return LLVMWeakODRLinkage;
1256 case LLVMRustLinkage::AppendingLinkage:
1257 return LLVMAppendingLinkage;
1258 case LLVMRustLinkage::InternalLinkage:
1259 return LLVMInternalLinkage;
1260 case LLVMRustLinkage::PrivateLinkage:
1261 return LLVMPrivateLinkage;
1262 case LLVMRustLinkage::ExternalWeakLinkage:
1263 return LLVMExternalWeakLinkage;
1264 case LLVMRustLinkage::CommonLinkage:
1265 return LLVMCommonLinkage;
1267 report_fatal_error("Invalid LLVMRustLinkage value!");
1270 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1271 return toRust(LLVMGetLinkage(V));
1274 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1275 LLVMRustLinkage RustLinkage) {
1276 LLVMSetLinkage(V, fromRust(RustLinkage));
1279 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1280 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1281 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1283 auto C = unwrap<llvm::ConstantInt>(CV);
1284 if (C->getBitWidth() > 128) { return false; }
1287 AP = C->getValue().sextOrSelf(128);
1289 AP = C->getValue().zextOrSelf(128);
1291 *low = AP.getLoBits(64).getZExtValue();
1292 *high = AP.getHiBits(64).getZExtValue();
1296 enum class LLVMRustVisibility {
1302 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1304 case LLVMDefaultVisibility:
1305 return LLVMRustVisibility::Default;
1306 case LLVMHiddenVisibility:
1307 return LLVMRustVisibility::Hidden;
1308 case LLVMProtectedVisibility:
1309 return LLVMRustVisibility::Protected;
1311 report_fatal_error("Invalid LLVMRustVisibility value!");
1314 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1316 case LLVMRustVisibility::Default:
1317 return LLVMDefaultVisibility;
1318 case LLVMRustVisibility::Hidden:
1319 return LLVMHiddenVisibility;
1320 case LLVMRustVisibility::Protected:
1321 return LLVMProtectedVisibility;
1323 report_fatal_error("Invalid LLVMRustVisibility value!");
1326 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1327 return toRust(LLVMGetVisibility(V));
1330 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1331 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1332 LLVMTypeRef DestTy, bool isSigned) {
1333 return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1336 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1337 LLVMRustVisibility RustVisibility) {
1338 LLVMSetVisibility(V, fromRust(RustVisibility));
1341 struct LLVMRustModuleBuffer {
1345 extern "C" LLVMRustModuleBuffer*
1346 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1347 auto Ret = llvm::make_unique<LLVMRustModuleBuffer>();
1349 raw_string_ostream OS(Ret->data);
1351 legacy::PassManager PM;
1352 PM.add(createBitcodeWriterPass(OS));
1356 return Ret.release();
1360 LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1364 extern "C" const void*
1365 LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1366 return Buffer->data.data();
1370 LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1371 return Buffer->data.length();
1375 LLVMRustModuleCost(LLVMModuleRef M) {
1376 auto f = unwrap(M)->functions();
1377 return std::distance(std::begin(f), std::end(f));
1380 // Vector reductions:
1381 extern "C" LLVMValueRef
1382 LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1383 return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1385 extern "C" LLVMValueRef
1386 LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1387 return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1389 extern "C" LLVMValueRef
1390 LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1391 return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1393 extern "C" LLVMValueRef
1394 LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1395 return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1397 extern "C" LLVMValueRef
1398 LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1399 return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1401 extern "C" LLVMValueRef
1402 LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1403 return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1405 extern "C" LLVMValueRef
1406 LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1407 return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1409 extern "C" LLVMValueRef
1410 LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1411 return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1413 extern "C" LLVMValueRef
1414 LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1415 return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1417 extern "C" LLVMValueRef
1418 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1419 return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN));
1421 extern "C" LLVMValueRef
1422 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1423 return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN));
1426 extern "C" LLVMValueRef
1427 LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1428 return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1430 extern "C" LLVMValueRef
1431 LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1432 return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));