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/IR/DebugInfoMetadata.h"
13 #include "llvm/IR/DiagnosticInfo.h"
14 #include "llvm/IR/DiagnosticPrinter.h"
15 #include "llvm/IR/Instructions.h"
16 #include "llvm/Object/Archive.h"
17 #include "llvm/Object/ObjectFile.h"
19 #include "llvm/IR/CallSite.h"
21 #if LLVM_VERSION_GE(5, 0)
22 #include "llvm/ADT/Optional.h"
25 //===----------------------------------------------------------------------===
27 // This file defines alternate interfaces to core functions that are more
28 // readily callable by Rust's FFI.
30 //===----------------------------------------------------------------------===
33 using namespace llvm::sys;
34 using namespace llvm::object;
36 // LLVMAtomicOrdering is already an enum - don't create another
38 static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
40 case LLVMAtomicOrderingNotAtomic:
41 return AtomicOrdering::NotAtomic;
42 case LLVMAtomicOrderingUnordered:
43 return AtomicOrdering::Unordered;
44 case LLVMAtomicOrderingMonotonic:
45 return AtomicOrdering::Monotonic;
46 case LLVMAtomicOrderingAcquire:
47 return AtomicOrdering::Acquire;
48 case LLVMAtomicOrderingRelease:
49 return AtomicOrdering::Release;
50 case LLVMAtomicOrderingAcquireRelease:
51 return AtomicOrdering::AcquireRelease;
52 case LLVMAtomicOrderingSequentiallyConsistent:
53 return AtomicOrdering::SequentiallyConsistent;
56 llvm_unreachable("Invalid LLVMAtomicOrdering value!");
59 static char *LastError;
61 extern "C" LLVMMemoryBufferRef
62 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
63 ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =
64 MemoryBuffer::getFile(Path, -1, false);
66 LLVMRustSetLastError(BufOr.getError().message().c_str());
69 return wrap(BufOr.get().release());
72 extern "C" char *LLVMRustGetLastError(void) {
73 char *Ret = LastError;
78 void LLVMRustSetLastError(const char *Err) {
79 free((void *)LastError);
80 LastError = strdup(Err);
83 extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M,
85 unwrap(M)->setTargetTriple(Triple::normalize(Triple));
88 extern "C" void LLVMRustPrintPassTimings() {
89 raw_fd_ostream OS(2, false); // stderr.
90 TimerGroup::printAll(OS);
93 extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M,
95 return wrap(unwrap(M)->getNamedValue(Name));
98 extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
100 LLVMTypeRef FunctionTy) {
102 unwrap(M)->getOrInsertFunction(Name, unwrap<FunctionType>(FunctionTy)));
105 extern "C" LLVMValueRef
106 LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty) {
107 return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty)));
110 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
111 return wrap(Type::getMetadataTy(*unwrap(C)));
114 static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
117 return Attribute::AlwaysInline;
119 return Attribute::ByVal;
121 return Attribute::Cold;
123 return Attribute::InlineHint;
125 return Attribute::MinSize;
127 return Attribute::Naked;
129 return Attribute::NoAlias;
131 return Attribute::NoCapture;
133 return Attribute::NoInline;
135 return Attribute::NonNull;
137 return Attribute::NoRedZone;
139 return Attribute::NoReturn;
141 return Attribute::NoUnwind;
142 case OptimizeForSize:
143 return Attribute::OptimizeForSize;
145 return Attribute::ReadOnly;
147 return Attribute::SExt;
149 return Attribute::StructRet;
151 return Attribute::UWTable;
153 return Attribute::ZExt;
155 return Attribute::InReg;
157 return Attribute::SanitizeThread;
158 case SanitizeAddress:
159 return Attribute::SanitizeAddress;
161 return Attribute::SanitizeMemory;
163 llvm_unreachable("bad AttributeKind");
166 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
167 LLVMRustAttribute RustAttr) {
168 CallSite Call = CallSite(unwrap<Instruction>(Instr));
169 Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
170 #if LLVM_VERSION_GE(5, 0)
171 Call.addAttribute(Index, Attr);
174 Call.setAttributes(Call.getAttributes().addAttributes(
175 Call->getContext(), Index,
176 AttributeSet::get(Call->getContext(), Index, B)));
180 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
183 CallSite Call = CallSite(unwrap<Instruction>(Instr));
185 B.addDereferenceableAttr(Bytes);
186 #if LLVM_VERSION_GE(5, 0)
187 Call.setAttributes(Call.getAttributes().addAttributes(
188 Call->getContext(), Index, B));
190 Call.setAttributes(Call.getAttributes().addAttributes(
191 Call->getContext(), Index,
192 AttributeSet::get(Call->getContext(), Index, B)));
196 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
197 LLVMRustAttribute RustAttr) {
198 Function *A = unwrap<Function>(Fn);
199 Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
201 #if LLVM_VERSION_GE(5, 0)
202 A->addAttributes(Index, B);
204 A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B));
208 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
210 Function *A = unwrap<Function>(Fn);
212 B.addDereferenceableAttr(Bytes);
213 #if LLVM_VERSION_GE(5, 0)
214 A->addAttributes(Index, B);
216 A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B));
220 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
224 Function *F = unwrap<Function>(Fn);
226 B.addAttribute(Name, Value);
227 #if LLVM_VERSION_GE(5, 0)
228 F->addAttributes(Index, B);
230 F->addAttributes(Index, AttributeSet::get(F->getContext(), Index, B));
234 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
236 LLVMRustAttribute RustAttr) {
237 Function *F = unwrap<Function>(Fn);
238 Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
240 auto PAL = F->getAttributes();
241 #if LLVM_VERSION_GE(5, 0)
242 auto PALNew = PAL.removeAttributes(F->getContext(), Index, B);
244 const AttributeSet PALNew = PAL.removeAttributes(
245 F->getContext(), Index, AttributeSet::get(F->getContext(), Index, B));
247 F->setAttributes(PALNew);
250 // enable fpmath flag UnsafeAlgebra
251 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
252 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
253 I->setHasUnsafeAlgebra(true);
257 extern "C" LLVMValueRef
258 LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef Source, const char *Name,
259 LLVMAtomicOrdering Order, unsigned Alignment) {
260 LoadInst *LI = new LoadInst(unwrap(Source), 0);
261 LI->setAtomic(fromRust(Order));
262 LI->setAlignment(Alignment);
263 return wrap(unwrap(B)->Insert(LI, Name));
266 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
269 LLVMAtomicOrdering Order,
270 unsigned Alignment) {
271 StoreInst *SI = new StoreInst(unwrap(V), unwrap(Target));
272 SI->setAtomic(fromRust(Order));
273 SI->setAlignment(Alignment);
274 return wrap(unwrap(B)->Insert(SI));
277 extern "C" LLVMValueRef
278 LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
279 LLVMValueRef Old, LLVMValueRef Source,
280 LLVMAtomicOrdering Order,
281 LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
282 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
283 unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
284 fromRust(FailureOrder));
289 enum class LLVMRustSynchronizationScope {
295 #if LLVM_VERSION_GE(5, 0)
296 static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
298 case LLVMRustSynchronizationScope::SingleThread:
299 return SyncScope::SingleThread;
300 case LLVMRustSynchronizationScope::CrossThread:
301 return SyncScope::System;
303 llvm_unreachable("bad SynchronizationScope.");
307 static SynchronizationScope fromRust(LLVMRustSynchronizationScope Scope) {
309 case LLVMRustSynchronizationScope::SingleThread:
311 case LLVMRustSynchronizationScope::CrossThread:
314 llvm_unreachable("bad SynchronizationScope.");
319 extern "C" LLVMValueRef
320 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
321 LLVMRustSynchronizationScope Scope) {
322 return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
325 extern "C" void LLVMRustSetDebug(int Enabled) {
331 enum class LLVMRustAsmDialect {
337 static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
339 case LLVMRustAsmDialect::Att:
340 return InlineAsm::AD_ATT;
341 case LLVMRustAsmDialect::Intel:
342 return InlineAsm::AD_Intel;
344 llvm_unreachable("bad AsmDialect.");
348 extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString,
350 LLVMBool HasSideEffects,
351 LLVMBool IsAlignStack,
352 LLVMRustAsmDialect Dialect) {
353 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString, Constraints,
354 HasSideEffects, IsAlignStack, fromRust(Dialect)));
357 extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm) {
358 unwrap(M)->appendModuleInlineAsm(StringRef(Asm));
361 typedef DIBuilder *LLVMRustDIBuilderRef;
363 #if LLVM_VERSION_LT(5, 0)
364 typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
367 DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef)
369 inline Metadata **unwrap(LLVMMetadataRef *Vals) {
370 return reinterpret_cast<Metadata **>(Vals);
375 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
376 return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
379 #define DIDescriptor DIScope
380 #define DIArray DINodeArray
381 #define unwrapDI unwrapDIPtr
383 // These values **must** match debuginfo::DIFlags! They also *happen*
384 // to match LLVM, but that isn't required as we do giant sets of
385 // matching below. The value shouldn't be directly passed to LLVM.
386 enum class LLVMRustDIFlags : uint32_t {
391 FlagFwdDecl = (1 << 2),
392 FlagAppleBlock = (1 << 3),
393 FlagBlockByrefStruct = (1 << 4),
394 FlagVirtual = (1 << 5),
395 FlagArtificial = (1 << 6),
396 FlagExplicit = (1 << 7),
397 FlagPrototyped = (1 << 8),
398 FlagObjcClassComplete = (1 << 9),
399 FlagObjectPointer = (1 << 10),
400 FlagVector = (1 << 11),
401 FlagStaticMember = (1 << 12),
402 FlagLValueReference = (1 << 13),
403 FlagRValueReference = (1 << 14),
404 FlagMainSubprogram = (1 << 21),
405 // Do not add values that are not supported by the minimum LLVM
406 // version we support!
409 inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
410 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
411 static_cast<uint32_t>(B));
414 inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
415 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
416 static_cast<uint32_t>(B));
419 inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
423 inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
425 inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
426 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
429 #if LLVM_VERSION_GE(4, 0)
430 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
431 DINode::DIFlags Result = DINode::DIFlags::FlagZero;
433 static unsigned fromRust(LLVMRustDIFlags Flags) {
437 switch (visibility(Flags)) {
438 case LLVMRustDIFlags::FlagPrivate:
439 Result |= DINode::DIFlags::FlagPrivate;
441 case LLVMRustDIFlags::FlagProtected:
442 Result |= DINode::DIFlags::FlagProtected;
444 case LLVMRustDIFlags::FlagPublic:
445 Result |= DINode::DIFlags::FlagPublic;
448 // The rest are handled below
452 if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
453 Result |= DINode::DIFlags::FlagFwdDecl;
455 if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
456 Result |= DINode::DIFlags::FlagAppleBlock;
458 if (isSet(Flags & LLVMRustDIFlags::FlagBlockByrefStruct)) {
459 Result |= DINode::DIFlags::FlagBlockByrefStruct;
461 if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
462 Result |= DINode::DIFlags::FlagVirtual;
464 if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
465 Result |= DINode::DIFlags::FlagArtificial;
467 if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
468 Result |= DINode::DIFlags::FlagExplicit;
470 if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
471 Result |= DINode::DIFlags::FlagPrototyped;
473 if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
474 Result |= DINode::DIFlags::FlagObjcClassComplete;
476 if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
477 Result |= DINode::DIFlags::FlagObjectPointer;
479 if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
480 Result |= DINode::DIFlags::FlagVector;
482 if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
483 Result |= DINode::DIFlags::FlagStaticMember;
485 if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
486 Result |= DINode::DIFlags::FlagLValueReference;
488 if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
489 Result |= DINode::DIFlags::FlagRValueReference;
491 #if LLVM_RUSTLLVM || LLVM_VERSION_GE(4, 0)
492 if (isSet(Flags & LLVMRustDIFlags::FlagMainSubprogram)) {
493 Result |= DINode::DIFlags::FlagMainSubprogram;
500 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
501 return DEBUG_METADATA_VERSION;
504 extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
506 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
508 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
510 unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
513 extern "C" void LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
514 wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
517 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
518 return new DIBuilder(*unwrap(M));
521 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
525 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
529 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
530 LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
531 const char *Producer, bool isOptimized, const char *Flags,
532 unsigned RuntimeVer, const char *SplitName) {
533 auto *File = unwrapDI<DIFile>(FileRef);
535 #if LLVM_VERSION_GE(4, 0)
536 return wrap(Builder->createCompileUnit(Lang, File, Producer, isOptimized,
537 Flags, RuntimeVer, SplitName));
539 return wrap(Builder->createCompileUnit(Lang, File->getFilename(),
540 File->getDirectory(), Producer, isOptimized,
541 Flags, RuntimeVer, SplitName));
545 extern "C" LLVMMetadataRef
546 LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename,
547 const char *Directory) {
548 return wrap(Builder->createFile(Filename, Directory));
551 extern "C" LLVMMetadataRef
552 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
553 LLVMMetadataRef File,
554 LLVMMetadataRef ParameterTypes) {
555 return wrap(Builder->createSubroutineType(
556 #if LLVM_VERSION_EQ(3, 7)
557 unwrapDI<DIFile>(File),
559 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
562 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
563 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
564 const char *LinkageName, LLVMMetadataRef File, unsigned LineNo,
565 LLVMMetadataRef Ty, bool IsLocalToUnit, bool IsDefinition,
566 unsigned ScopeLine, LLVMRustDIFlags Flags, bool IsOptimized,
567 LLVMValueRef Fn, LLVMMetadataRef TParam, LLVMMetadataRef Decl) {
568 #if LLVM_VERSION_GE(3, 8)
569 DITemplateParameterArray TParams =
570 DITemplateParameterArray(unwrap<MDTuple>(TParam));
571 DISubprogram *Sub = Builder->createFunction(
572 unwrapDI<DIScope>(Scope), Name, LinkageName, unwrapDI<DIFile>(File),
573 LineNo, unwrapDI<DISubroutineType>(Ty), IsLocalToUnit, IsDefinition,
574 ScopeLine, fromRust(Flags), IsOptimized, TParams,
575 unwrapDIPtr<DISubprogram>(Decl));
576 unwrap<Function>(Fn)->setSubprogram(Sub);
579 return wrap(Builder->createFunction(
580 unwrapDI<DIScope>(Scope), Name, LinkageName, unwrapDI<DIFile>(File),
581 LineNo, unwrapDI<DISubroutineType>(Ty), IsLocalToUnit, IsDefinition,
582 ScopeLine, fromRust(Flags), IsOptimized, unwrap<Function>(Fn),
583 unwrapDIPtr<MDNode>(TParam), unwrapDIPtr<MDNode>(Decl)));
587 extern "C" LLVMMetadataRef
588 LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder, const char *Name,
589 uint64_t SizeInBits, uint32_t AlignInBits,
591 return wrap(Builder->createBasicType(Name, SizeInBits,
592 #if LLVM_VERSION_LE(3, 9)
598 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
599 LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
600 uint64_t SizeInBits, uint32_t AlignInBits, const char *Name) {
601 return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
602 SizeInBits, AlignInBits,
603 #if LLVM_VERSION_GE(5, 0)
604 /* DWARFAddressSpace */ None,
609 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
610 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
611 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
612 uint32_t AlignInBits, LLVMRustDIFlags Flags,
613 LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
614 unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
615 const char *UniqueId) {
616 return wrap(Builder->createStructType(
617 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
618 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
619 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
620 unwrapDI<DIType>(VTableHolder), UniqueId));
623 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
624 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
625 LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
626 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
627 LLVMMetadataRef Ty) {
628 return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope), Name,
629 unwrapDI<DIFile>(File), LineNo,
630 SizeInBits, AlignInBits, OffsetInBits,
631 fromRust(Flags), unwrapDI<DIType>(Ty)));
634 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
635 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
636 LLVMMetadataRef File, unsigned Line, unsigned Col) {
637 return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
638 unwrapDI<DIFile>(File), Line, Col));
641 extern "C" LLVMMetadataRef
642 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
643 LLVMMetadataRef Scope,
644 LLVMMetadataRef File) {
645 return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
646 unwrapDI<DIFile>(File)));
649 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
650 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name,
651 const char *LinkageName, LLVMMetadataRef File, unsigned LineNo,
652 LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
653 LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
654 llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
656 #if LLVM_VERSION_GE(4, 0)
657 llvm::DIExpression *InitExpr = nullptr;
658 if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
659 InitExpr = Builder->createConstantValueExpression(
660 IntVal->getValue().getSExtValue());
661 } else if (llvm::ConstantFP *FPVal =
662 llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
663 InitExpr = Builder->createConstantValueExpression(
664 FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
667 llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
668 unwrapDI<DIDescriptor>(Context), Name, LinkageName,
669 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
670 InitExpr, unwrapDIPtr<MDNode>(Decl), AlignInBits);
672 InitVal->setMetadata("dbg", VarExpr);
674 return wrap(VarExpr);
676 return wrap(Builder->createGlobalVariable(
677 unwrapDI<DIDescriptor>(Context), Name, LinkageName,
678 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
679 InitVal, unwrapDIPtr<MDNode>(Decl)));
683 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
684 LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
685 const char *Name, LLVMMetadataRef File, unsigned LineNo,
686 LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
687 unsigned ArgNo, uint32_t AlignInBits) {
688 #if LLVM_VERSION_GE(3, 8)
689 if (Tag == 0x100) { // DW_TAG_auto_variable
690 return wrap(Builder->createAutoVariable(
691 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNo,
692 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)
693 #if LLVM_VERSION_GE(4, 0)
699 return wrap(Builder->createParameterVariable(
700 unwrapDI<DIDescriptor>(Scope), Name, ArgNo, unwrapDI<DIFile>(File),
701 LineNo, unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
704 return wrap(Builder->createLocalVariable(
705 Tag, unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNo,
706 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), ArgNo));
710 extern "C" LLVMMetadataRef
711 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
712 uint32_t AlignInBits, LLVMMetadataRef Ty,
713 LLVMMetadataRef Subscripts) {
715 Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
716 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
719 extern "C" LLVMMetadataRef
720 LLVMRustDIBuilderCreateVectorType(LLVMRustDIBuilderRef Builder, uint64_t Size,
721 uint32_t AlignInBits, LLVMMetadataRef Ty,
722 LLVMMetadataRef Subscripts) {
724 Builder->createVectorType(Size, AlignInBits, unwrapDI<DIType>(Ty),
725 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
728 extern "C" LLVMMetadataRef
729 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
731 return wrap(Builder->getOrCreateSubrange(Lo, Count));
734 extern "C" LLVMMetadataRef
735 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
736 LLVMMetadataRef *Ptr, unsigned Count) {
737 Metadata **DataValue = unwrap(Ptr);
739 Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
742 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
743 LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
744 int64_t *AddrOps, unsigned AddrOpsCount, LLVMValueRef DL,
745 LLVMBasicBlockRef InsertAtEnd) {
746 return wrap(Builder->insertDeclare(
747 unwrap(V), unwrap<DILocalVariable>(VarInfo),
748 Builder->createExpression(llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
749 DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
750 unwrap(InsertAtEnd)));
753 extern "C" LLVMMetadataRef
754 LLVMRustDIBuilderCreateEnumerator(LLVMRustDIBuilderRef Builder,
755 const char *Name, uint64_t Val) {
756 return wrap(Builder->createEnumerator(Name, Val));
759 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
760 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
761 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
762 uint32_t AlignInBits, LLVMMetadataRef Elements,
763 LLVMMetadataRef ClassTy) {
764 return wrap(Builder->createEnumerationType(
765 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
766 SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
767 unwrapDI<DIType>(ClassTy)));
770 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
771 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
772 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
773 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
774 unsigned RunTimeLang, const char *UniqueId) {
775 return wrap(Builder->createUnionType(
776 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
777 SizeInBits, AlignInBits, fromRust(Flags),
778 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang, UniqueId));
781 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
782 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
783 LLVMMetadataRef Ty, LLVMMetadataRef File, unsigned LineNo,
785 return wrap(Builder->createTemplateTypeParameter(
786 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIType>(Ty)));
789 extern "C" LLVMMetadataRef
790 LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder,
791 LLVMMetadataRef Scope, const char *Name,
792 LLVMMetadataRef File, unsigned LineNo) {
793 return wrap(Builder->createNameSpace(
794 unwrapDI<DIDescriptor>(Scope), Name
795 #if LLVM_VERSION_LT(5, 0)
797 unwrapDI<DIFile>(File), LineNo
799 #if LLVM_VERSION_GE(4, 0)
801 false // ExportSymbols (only relevant for C++ anonymous namespaces)
807 LLVMRustDICompositeTypeSetTypeArray(LLVMRustDIBuilderRef Builder,
808 LLVMMetadataRef CompositeTy,
809 LLVMMetadataRef TyArray) {
810 DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
811 Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(TyArray)));
814 extern "C" LLVMValueRef
815 LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef, unsigned Line,
816 unsigned Column, LLVMMetadataRef Scope,
817 LLVMMetadataRef InlinedAt) {
818 LLVMContext &Context = *unwrap(ContextRef);
820 DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(Scope),
821 unwrapDIPtr<MDNode>(InlinedAt));
823 return wrap(MetadataAsValue::get(Context, debug_loc.getAsMDNode()));
826 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
827 return dwarf::DW_OP_deref;
830 extern "C" int64_t LLVMRustDIBuilderCreateOpPlus() { return dwarf::DW_OP_plus; }
832 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
833 RawRustStringOstream OS(Str);
834 unwrap<llvm::Type>(Ty)->print(OS);
837 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
839 RawRustStringOstream OS(Str);
844 unwrap<llvm::Value>(V)->getType()->print(OS);
846 unwrap<llvm::Value>(V)->print(OS);
851 extern "C" bool LLVMRustLinkInExternalBitcode(LLVMModuleRef DstRef, char *BC,
853 Module *Dst = unwrap(DstRef);
855 std::unique_ptr<MemoryBuffer> Buf =
856 MemoryBuffer::getMemBufferCopy(StringRef(BC, Len));
858 #if LLVM_VERSION_GE(4, 0)
859 Expected<std::unique_ptr<Module>> SrcOrError =
860 llvm::getLazyBitcodeModule(Buf->getMemBufferRef(), Dst->getContext());
862 LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
866 auto Src = std::move(*SrcOrError);
868 ErrorOr<std::unique_ptr<Module>> Src =
869 llvm::getLazyBitcodeModule(std::move(Buf), Dst->getContext());
871 LLVMRustSetLastError(Src.getError().message().c_str());
878 raw_string_ostream Stream(Err);
879 DiagnosticPrinterRawOStream DP(Stream);
880 #if LLVM_VERSION_GE(4, 0)
881 if (Linker::linkModules(*Dst, std::move(Src))) {
882 #elif LLVM_VERSION_GE(3, 8)
883 if (Linker::linkModules(*Dst, std::move(Src.get()))) {
885 if (Linker::LinkModules(Dst, Src->get(),
886 [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
888 LLVMRustSetLastError(Err.c_str());
894 // Note that the two following functions look quite similar to the
895 // LLVMGetSectionName function. Sadly, it appears that this function only
896 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
897 // function provided by LLVM doesn't return the length, so we've created our own
898 // function which returns the length as well as the data pointer.
900 // For an example of this not returning a null terminated string, see
901 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
902 // branches explicitly creates a StringRef without a null terminator, and then
905 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
906 return reinterpret_cast<section_iterator *>(SI);
909 extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI,
912 if (std::error_code EC = (*unwrap(SI))->getName(Ret))
913 report_fatal_error(EC.message());
918 // LLVMArrayType function does not support 64-bit ElementCount
919 extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
920 uint64_t ElementCount) {
921 return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
924 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
925 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
927 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
928 RawRustStringOstream OS(Str);
929 unwrap(T)->print(OS);
932 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
933 LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
934 LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
935 RustStringRef FilenameOut, RustStringRef MessageOut) {
936 // Undefined to call this not on an optimization diagnostic!
937 llvm::DiagnosticInfoOptimizationBase *Opt =
938 static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
940 RawRustStringOstream PassNameOS(PassNameOut);
941 PassNameOS << Opt->getPassName();
942 *FunctionOut = wrap(&Opt->getFunction());
944 RawRustStringOstream FilenameOS(FilenameOut);
945 #if LLVM_VERSION_GE(5,0)
946 DiagnosticLocation loc = Opt->getLocation();
948 *Line = loc.getLine();
949 *Column = loc.getColumn();
950 FilenameOS << loc.getFilename();
953 const DebugLoc &loc = Opt->getDebugLoc();
955 *Line = loc.getLine();
956 *Column = loc.getCol();
957 FilenameOS << cast<DIScope>(loc.getScope())->getFilename();
961 RawRustStringOstream MessageOS(MessageOut);
962 MessageOS << Opt->getMsg();
966 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI, unsigned *CookieOut,
967 LLVMTwineRef *MessageOut,
968 LLVMValueRef *InstructionOut) {
969 // Undefined to call this not on an inline assembly diagnostic!
970 llvm::DiagnosticInfoInlineAsm *IA =
971 static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
973 *CookieOut = IA->getLocCookie();
974 *MessageOut = wrap(&IA->getMsgStr());
975 *InstructionOut = wrap(IA->getInstruction());
978 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
980 RawRustStringOstream OS(Str);
981 DiagnosticPrinterRawOStream DP(OS);
982 unwrap(DI)->print(DP);
985 enum class LLVMRustDiagnosticKind {
989 DebugMetadataVersion,
992 OptimizationRemarkMissed,
993 OptimizationRemarkAnalysis,
994 OptimizationRemarkAnalysisFPCommute,
995 OptimizationRemarkAnalysisAliasing,
996 OptimizationRemarkOther,
1000 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1003 return LLVMRustDiagnosticKind::InlineAsm;
1005 return LLVMRustDiagnosticKind::StackSize;
1006 case DK_DebugMetadataVersion:
1007 return LLVMRustDiagnosticKind::DebugMetadataVersion;
1008 case DK_SampleProfile:
1009 return LLVMRustDiagnosticKind::SampleProfile;
1010 case DK_OptimizationRemark:
1011 return LLVMRustDiagnosticKind::OptimizationRemark;
1012 case DK_OptimizationRemarkMissed:
1013 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1014 case DK_OptimizationRemarkAnalysis:
1015 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
1016 #if LLVM_VERSION_GE(3, 8)
1017 case DK_OptimizationRemarkAnalysisFPCommute:
1018 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1019 case DK_OptimizationRemarkAnalysisAliasing:
1020 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
1023 #if LLVM_VERSION_GE(3, 9)
1024 return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1025 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1026 : LLVMRustDiagnosticKind::Other;
1028 return LLVMRustDiagnosticKind::Other;
1033 extern "C" LLVMRustDiagnosticKind
1034 LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1035 return toRust((DiagnosticKind)unwrap(DI)->getKind());
1037 // This is kept distinct from LLVMGetTypeKind, because when
1038 // a new type kind is added, the Rust-side enum must be
1039 // updated or UB will result.
1040 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1041 switch (unwrap(Ty)->getTypeID()) {
1042 case Type::VoidTyID:
1043 return LLVMVoidTypeKind;
1044 case Type::HalfTyID:
1045 return LLVMHalfTypeKind;
1046 case Type::FloatTyID:
1047 return LLVMFloatTypeKind;
1048 case Type::DoubleTyID:
1049 return LLVMDoubleTypeKind;
1050 case Type::X86_FP80TyID:
1051 return LLVMX86_FP80TypeKind;
1052 case Type::FP128TyID:
1053 return LLVMFP128TypeKind;
1054 case Type::PPC_FP128TyID:
1055 return LLVMPPC_FP128TypeKind;
1056 case Type::LabelTyID:
1057 return LLVMLabelTypeKind;
1058 case Type::MetadataTyID:
1059 return LLVMMetadataTypeKind;
1060 case Type::IntegerTyID:
1061 return LLVMIntegerTypeKind;
1062 case Type::FunctionTyID:
1063 return LLVMFunctionTypeKind;
1064 case Type::StructTyID:
1065 return LLVMStructTypeKind;
1066 case Type::ArrayTyID:
1067 return LLVMArrayTypeKind;
1068 case Type::PointerTyID:
1069 return LLVMPointerTypeKind;
1070 case Type::VectorTyID:
1071 return LLVMVectorTypeKind;
1072 case Type::X86_MMXTyID:
1073 return LLVMX86_MMXTypeKind;
1074 #if LLVM_VERSION_GE(3, 8)
1075 case Type::TokenTyID:
1076 return LLVMTokenTypeKind;
1079 llvm_unreachable("Unhandled TypeID.");
1082 extern "C" void LLVMRustWriteDebugLocToString(LLVMContextRef C,
1084 RustStringRef Str) {
1085 RawRustStringOstream OS(Str);
1086 unwrap(DL)->print(OS);
1089 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1091 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1092 LLVMContextRef C, LLVMContext::InlineAsmDiagHandlerTy H, void *CX) {
1093 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1096 extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef D,
1097 RustStringRef Str) {
1098 RawRustStringOstream OS(Str);
1099 unwrap(D)->print("", OS);
1102 extern "C" LLVMValueRef
1103 LLVMRustBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty,
1104 LLVMValueRef PersFn, unsigned NumClauses,
1105 const char *Name, LLVMValueRef F) {
1106 return LLVMBuildLandingPad(B, Ty, PersFn, NumClauses, Name);
1109 extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1110 LLVMValueRef ParentPad,
1112 LLVMValueRef *LLArgs,
1114 #if LLVM_VERSION_GE(3, 8)
1115 Value **Args = unwrap(LLArgs);
1116 if (ParentPad == nullptr) {
1117 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1118 ParentPad = wrap(Constant::getNullValue(Ty));
1120 return wrap(unwrap(B)->CreateCleanupPad(
1121 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1127 extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1128 LLVMValueRef CleanupPad,
1129 LLVMBasicBlockRef UnwindBB) {
1130 #if LLVM_VERSION_GE(3, 8)
1131 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1132 return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1138 extern "C" LLVMValueRef
1139 LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1140 unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
1141 #if LLVM_VERSION_GE(3, 8)
1142 Value **Args = unwrap(LLArgs);
1143 return wrap(unwrap(B)->CreateCatchPad(
1144 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
1150 extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1152 LLVMBasicBlockRef BB) {
1153 #if LLVM_VERSION_GE(3, 8)
1154 return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1161 extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1162 LLVMValueRef ParentPad,
1163 LLVMBasicBlockRef BB,
1164 unsigned NumHandlers,
1166 #if LLVM_VERSION_GE(3, 8)
1167 if (ParentPad == nullptr) {
1168 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1169 ParentPad = wrap(Constant::getNullValue(Ty));
1171 return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1172 NumHandlers, Name));
1178 extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1179 LLVMBasicBlockRef Handler) {
1180 #if LLVM_VERSION_GE(3, 8)
1181 Value *CatchSwitch = unwrap(CatchSwitchRef);
1182 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1186 #if LLVM_VERSION_GE(3, 8)
1187 extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1188 LLVMValueRef *Inputs,
1189 unsigned NumInputs) {
1190 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1193 extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
1197 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
1198 LLVMValueRef *Args, unsigned NumArgs,
1199 OperandBundleDef *Bundle,
1201 unsigned Len = Bundle ? 1 : 0;
1202 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1203 return wrap(unwrap(B)->CreateCall(
1204 unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Bundles, Name));
1207 extern "C" LLVMValueRef
1208 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
1209 unsigned NumArgs, LLVMBasicBlockRef Then,
1210 LLVMBasicBlockRef Catch, OperandBundleDef *Bundle,
1212 unsigned Len = Bundle ? 1 : 0;
1213 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1214 return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch),
1215 makeArrayRef(unwrap(Args), NumArgs),
1219 extern "C" void *LLVMRustBuildOperandBundleDef(const char *Name,
1220 LLVMValueRef *Inputs,
1221 unsigned NumInputs) {
1225 extern "C" void LLVMRustFreeOperandBundleDef(void *Bundle) {}
1227 extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
1228 LLVMValueRef *Args, unsigned NumArgs,
1229 void *Bundle, const char *Name) {
1230 return LLVMBuildCall(B, Fn, Args, NumArgs, Name);
1233 extern "C" LLVMValueRef
1234 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
1235 unsigned NumArgs, LLVMBasicBlockRef Then,
1236 LLVMBasicBlockRef Catch, void *Bundle, const char *Name) {
1237 return LLVMBuildInvoke(B, Fn, Args, NumArgs, Then, Catch, Name);
1241 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1242 LLVMBasicBlockRef BB) {
1243 auto Point = unwrap(BB)->getFirstInsertionPt();
1244 unwrap(B)->SetInsertPoint(unwrap(BB), Point);
1247 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1249 Triple TargetTriple(unwrap(M)->getTargetTriple());
1250 GlobalObject *GV = unwrap<GlobalObject>(V);
1251 if (!TargetTriple.isOSBinFormatMachO()) {
1252 GV->setComdat(unwrap(M)->getOrInsertComdat(Name));
1256 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1257 GlobalObject *GV = unwrap<GlobalObject>(V);
1258 GV->setComdat(nullptr);
1261 enum class LLVMRustLinkage {
1262 ExternalLinkage = 0,
1263 AvailableExternallyLinkage = 1,
1264 LinkOnceAnyLinkage = 2,
1265 LinkOnceODRLinkage = 3,
1268 AppendingLinkage = 6,
1269 InternalLinkage = 7,
1271 ExternalWeakLinkage = 9,
1275 static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1277 case LLVMExternalLinkage:
1278 return LLVMRustLinkage::ExternalLinkage;
1279 case LLVMAvailableExternallyLinkage:
1280 return LLVMRustLinkage::AvailableExternallyLinkage;
1281 case LLVMLinkOnceAnyLinkage:
1282 return LLVMRustLinkage::LinkOnceAnyLinkage;
1283 case LLVMLinkOnceODRLinkage:
1284 return LLVMRustLinkage::LinkOnceODRLinkage;
1285 case LLVMWeakAnyLinkage:
1286 return LLVMRustLinkage::WeakAnyLinkage;
1287 case LLVMWeakODRLinkage:
1288 return LLVMRustLinkage::WeakODRLinkage;
1289 case LLVMAppendingLinkage:
1290 return LLVMRustLinkage::AppendingLinkage;
1291 case LLVMInternalLinkage:
1292 return LLVMRustLinkage::InternalLinkage;
1293 case LLVMPrivateLinkage:
1294 return LLVMRustLinkage::PrivateLinkage;
1295 case LLVMExternalWeakLinkage:
1296 return LLVMRustLinkage::ExternalWeakLinkage;
1297 case LLVMCommonLinkage:
1298 return LLVMRustLinkage::CommonLinkage;
1300 llvm_unreachable("Invalid LLVMRustLinkage value!");
1304 static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1306 case LLVMRustLinkage::ExternalLinkage:
1307 return LLVMExternalLinkage;
1308 case LLVMRustLinkage::AvailableExternallyLinkage:
1309 return LLVMAvailableExternallyLinkage;
1310 case LLVMRustLinkage::LinkOnceAnyLinkage:
1311 return LLVMLinkOnceAnyLinkage;
1312 case LLVMRustLinkage::LinkOnceODRLinkage:
1313 return LLVMLinkOnceODRLinkage;
1314 case LLVMRustLinkage::WeakAnyLinkage:
1315 return LLVMWeakAnyLinkage;
1316 case LLVMRustLinkage::WeakODRLinkage:
1317 return LLVMWeakODRLinkage;
1318 case LLVMRustLinkage::AppendingLinkage:
1319 return LLVMAppendingLinkage;
1320 case LLVMRustLinkage::InternalLinkage:
1321 return LLVMInternalLinkage;
1322 case LLVMRustLinkage::PrivateLinkage:
1323 return LLVMPrivateLinkage;
1324 case LLVMRustLinkage::ExternalWeakLinkage:
1325 return LLVMExternalWeakLinkage;
1326 case LLVMRustLinkage::CommonLinkage:
1327 return LLVMCommonLinkage;
1329 llvm_unreachable("Invalid LLVMRustLinkage value!");
1332 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1333 return toRust(LLVMGetLinkage(V));
1336 extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1337 LLVMRustLinkage RustLinkage) {
1338 LLVMSetLinkage(V, fromRust(RustLinkage));
1341 // Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1342 // the common sizes (1, 8, 16, 32, 64, 128 bits)
1343 extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1345 auto C = unwrap<llvm::ConstantInt>(CV);
1346 if (C->getBitWidth() > 128) { return false; }
1349 AP = C->getValue().sextOrSelf(128);
1351 AP = C->getValue().zextOrSelf(128);
1353 *low = AP.getLoBits(64).getZExtValue();
1354 *high = AP.getHiBits(64).getZExtValue();
1358 extern "C" LLVMContextRef LLVMRustGetValueContext(LLVMValueRef V) {
1359 return wrap(&unwrap(V)->getContext());
1362 enum class LLVMRustVisibility {
1368 static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1370 case LLVMDefaultVisibility:
1371 return LLVMRustVisibility::Default;
1372 case LLVMHiddenVisibility:
1373 return LLVMRustVisibility::Hidden;
1374 case LLVMProtectedVisibility:
1375 return LLVMRustVisibility::Protected;
1377 llvm_unreachable("Invalid LLVMRustVisibility value!");
1380 static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1382 case LLVMRustVisibility::Default:
1383 return LLVMDefaultVisibility;
1384 case LLVMRustVisibility::Hidden:
1385 return LLVMHiddenVisibility;
1386 case LLVMRustVisibility::Protected:
1387 return LLVMProtectedVisibility;
1389 llvm_unreachable("Invalid LLVMRustVisibility value!");
1392 extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
1393 return toRust(LLVMGetVisibility(V));
1396 // Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1397 extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1398 LLVMTypeRef DestTy, bool isSigned) {
1399 return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1402 extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1403 LLVMRustVisibility RustVisibility) {
1404 LLVMSetVisibility(V, fromRust(RustVisibility));