]> git.proxmox.com Git - rustc.git/blame - src/rustllvm/RustWrapper.cpp
New upstream version 1.31.0+dfsg1
[rustc.git] / src / rustllvm / RustWrapper.cpp
CommitLineData
970d7e83 1// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
223e47cc
LB
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
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.
10
970d7e83 11#include "rustllvm.h"
cc61c64b 12#include "llvm/IR/DebugInfoMetadata.h"
1a4d82fc
JJ
13#include "llvm/IR/DiagnosticInfo.h"
14#include "llvm/IR/DiagnosticPrinter.h"
b7449926 15#include "llvm/IR/GlobalVariable.h"
5bcae85e 16#include "llvm/IR/Instructions.h"
32a655c1
SL
17#include "llvm/Object/Archive.h"
18#include "llvm/Object/ObjectFile.h"
ea8adc8c 19#include "llvm/Bitcode/BitcodeWriterPass.h"
0bf4aa26 20#include "llvm/Support/Signals.h"
1a4d82fc 21
1a4d82fc 22#include "llvm/IR/CallSite.h"
970d7e83 23
3b2f2976
XL
24#if LLVM_VERSION_GE(5, 0)
25#include "llvm/ADT/Optional.h"
0531ce1d
XL
26#else
27#include <cstdlib>
3b2f2976
XL
28#endif
29
0bf4aa26
XL
30#include <iostream>
31
223e47cc
LB
32//===----------------------------------------------------------------------===
33//
34// This file defines alternate interfaces to core functions that are more
35// readily callable by Rust's FFI.
36//
37//===----------------------------------------------------------------------===
38
223e47cc
LB
39using namespace llvm;
40using namespace llvm::sys;
1a4d82fc 41using namespace llvm::object;
223e47cc 42
5bcae85e
SL
43// LLVMAtomicOrdering is already an enum - don't create another
44// one.
32a655c1 45static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
5bcae85e 46 switch (Ordering) {
32a655c1
SL
47 case LLVMAtomicOrderingNotAtomic:
48 return AtomicOrdering::NotAtomic;
49 case LLVMAtomicOrderingUnordered:
50 return AtomicOrdering::Unordered;
51 case LLVMAtomicOrderingMonotonic:
52 return AtomicOrdering::Monotonic;
53 case LLVMAtomicOrderingAcquire:
54 return AtomicOrdering::Acquire;
55 case LLVMAtomicOrderingRelease:
56 return AtomicOrdering::Release;
57 case LLVMAtomicOrderingAcquireRelease:
58 return AtomicOrdering::AcquireRelease;
59 case LLVMAtomicOrderingSequentiallyConsistent:
60 return AtomicOrdering::SequentiallyConsistent;
5bcae85e
SL
61 }
62
ff7c6d11 63 report_fatal_error("Invalid LLVMAtomicOrdering value!");
5bcae85e
SL
64}
65
abe05a73 66static LLVM_THREAD_LOCAL char *LastError;
970d7e83 67
0bf4aa26
XL
68// Custom error handler for fatal LLVM errors.
69//
70// Notably it exits the process with code 101, unlike LLVM's default of 1.
71static void FatalErrorHandler(void *UserData,
72 const std::string& Reason,
73 bool GenCrashDiag) {
74 // Do the same thing that the default error handler does.
75 std::cerr << "LLVM ERROR: " << Reason << std::endl;
76
77 // Since this error handler exits the process, we have to run any cleanup that
78 // LLVM would run after handling the error. This might change with an LLVM
79 // upgrade.
80 sys::RunInterruptHandlers();
81
82 exit(101);
83}
84
85extern "C" void LLVMRustInstallFatalErrorHandler() {
86 install_fatal_error_handler(FatalErrorHandler);
87}
88
223e47cc
LB
89extern "C" LLVMMemoryBufferRef
90LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
32a655c1
SL
91 ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =
92 MemoryBuffer::getFile(Path, -1, false);
93 if (!BufOr) {
94 LLVMRustSetLastError(BufOr.getError().message().c_str());
95 return nullptr;
223e47cc 96 }
32a655c1 97 return wrap(BufOr.get().release());
970d7e83 98}
223e47cc 99
1a4d82fc 100extern "C" char *LLVMRustGetLastError(void) {
32a655c1
SL
101 char *Ret = LastError;
102 LastError = nullptr;
103 return Ret;
223e47cc
LB
104}
105
ff7c6d11 106extern "C" void LLVMRustSetLastError(const char *Err) {
32a655c1
SL
107 free((void *)LastError);
108 LastError = strdup(Err);
223e47cc
LB
109}
110
ff7c6d11
XL
111extern "C" LLVMContextRef LLVMRustContextCreate(bool shouldDiscardNames) {
112 auto ctx = new LLVMContext();
113 ctx->setDiscardValueNames(shouldDiscardNames);
114 return wrap(ctx);
115}
116
32a655c1
SL
117extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M,
118 const char *Triple) {
119 unwrap(M)->setTargetTriple(Triple::normalize(Triple));
223e47cc
LB
120}
121
223e47cc 122extern "C" void LLVMRustPrintPassTimings() {
32a655c1 123 raw_fd_ostream OS(2, false); // stderr.
223e47cc
LB
124 TimerGroup::printAll(OS);
125}
126
5bcae85e 127extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M,
32a655c1
SL
128 const char *Name) {
129 return wrap(unwrap(M)->getNamedValue(Name));
9346a6ac
AL
130}
131
5bcae85e 132extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
32a655c1
SL
133 const char *Name,
134 LLVMTypeRef FunctionTy) {
135 return wrap(
136 unwrap(M)->getOrInsertFunction(Name, unwrap<FunctionType>(FunctionTy)));
223e47cc
LB
137}
138
32a655c1
SL
139extern "C" LLVMValueRef
140LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty) {
9346a6ac
AL
141 return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty)));
142}
143
b7449926
XL
144extern "C" LLVMValueRef
145LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) {
146 return wrap(new GlobalVariable(*unwrap(M),
147 unwrap(Ty),
148 false,
149 GlobalValue::PrivateLinkage,
150 nullptr));
151}
152
5bcae85e 153extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
223e47cc
LB
154 return wrap(Type::getMetadataTy(*unwrap(C)));
155}
970d7e83 156
32a655c1
SL
157static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
158 switch (Kind) {
159 case AlwaysInline:
160 return Attribute::AlwaysInline;
161 case ByVal:
162 return Attribute::ByVal;
163 case Cold:
164 return Attribute::Cold;
165 case InlineHint:
166 return Attribute::InlineHint;
167 case MinSize:
168 return Attribute::MinSize;
169 case Naked:
170 return Attribute::Naked;
171 case NoAlias:
172 return Attribute::NoAlias;
173 case NoCapture:
174 return Attribute::NoCapture;
175 case NoInline:
176 return Attribute::NoInline;
177 case NonNull:
178 return Attribute::NonNull;
179 case NoRedZone:
180 return Attribute::NoRedZone;
181 case NoReturn:
182 return Attribute::NoReturn;
183 case NoUnwind:
184 return Attribute::NoUnwind;
185 case OptimizeForSize:
186 return Attribute::OptimizeForSize;
187 case ReadOnly:
188 return Attribute::ReadOnly;
189 case SExt:
190 return Attribute::SExt;
191 case StructRet:
192 return Attribute::StructRet;
193 case UWTable:
194 return Attribute::UWTable;
195 case ZExt:
196 return Attribute::ZExt;
197 case InReg:
198 return Attribute::InReg;
8bb4bdeb
XL
199 case SanitizeThread:
200 return Attribute::SanitizeThread;
201 case SanitizeAddress:
202 return Attribute::SanitizeAddress;
203 case SanitizeMemory:
204 return Attribute::SanitizeMemory;
0bf4aa26
XL
205 case NonLazyBind:
206 return Attribute::NonLazyBind;
476ff2be 207 }
ff7c6d11 208 report_fatal_error("bad AttributeKind");
476ff2be
SL
209}
210
32a655c1
SL
211extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
212 LLVMRustAttribute RustAttr) {
1a4d82fc 213 CallSite Call = CallSite(unwrap<Instruction>(Instr));
32a655c1 214 Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
3b2f2976
XL
215#if LLVM_VERSION_GE(5, 0)
216 Call.addAttribute(Index, Attr);
217#else
476ff2be 218 AttrBuilder B(Attr);
32a655c1
SL
219 Call.setAttributes(Call.getAttributes().addAttributes(
220 Call->getContext(), Index,
221 AttributeSet::get(Call->getContext(), Index, B)));
3b2f2976 222#endif
1a4d82fc
JJ
223}
224
ff7c6d11
XL
225extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
226 unsigned Index,
227 uint32_t Bytes) {
228 CallSite Call = CallSite(unwrap<Instruction>(Instr));
229 AttrBuilder B;
230 B.addAlignmentAttr(Bytes);
231#if LLVM_VERSION_GE(5, 0)
232 Call.setAttributes(Call.getAttributes().addAttributes(
233 Call->getContext(), Index, B));
234#else
235 Call.setAttributes(Call.getAttributes().addAttributes(
236 Call->getContext(), Index,
237 AttributeSet::get(Call->getContext(), Index, B)));
238#endif
239}
240
5bcae85e 241extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
32a655c1
SL
242 unsigned Index,
243 uint64_t Bytes) {
1a4d82fc
JJ
244 CallSite Call = CallSite(unwrap<Instruction>(Instr));
245 AttrBuilder B;
32a655c1 246 B.addDereferenceableAttr(Bytes);
3b2f2976
XL
247#if LLVM_VERSION_GE(5, 0)
248 Call.setAttributes(Call.getAttributes().addAttributes(
249 Call->getContext(), Index, B));
250#else
32a655c1
SL
251 Call.setAttributes(Call.getAttributes().addAttributes(
252 Call->getContext(), Index,
253 AttributeSet::get(Call->getContext(), Index, B)));
3b2f2976 254#endif
1a4d82fc 255}
1a4d82fc 256
ff7c6d11
XL
257extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
258 unsigned Index,
259 uint64_t Bytes) {
260 CallSite Call = CallSite(unwrap<Instruction>(Instr));
261 AttrBuilder B;
262 B.addDereferenceableOrNullAttr(Bytes);
263#if LLVM_VERSION_GE(5, 0)
264 Call.setAttributes(Call.getAttributes().addAttributes(
265 Call->getContext(), Index, B));
266#else
267 Call.setAttributes(Call.getAttributes().addAttributes(
268 Call->getContext(), Index,
269 AttributeSet::get(Call->getContext(), Index, B)));
270#endif
271}
272
32a655c1
SL
273extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
274 LLVMRustAttribute RustAttr) {
1a4d82fc 275 Function *A = unwrap<Function>(Fn);
32a655c1 276 Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
476ff2be 277 AttrBuilder B(Attr);
3b2f2976
XL
278#if LLVM_VERSION_GE(5, 0)
279 A->addAttributes(Index, B);
280#else
32a655c1 281 A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B));
3b2f2976 282#endif
1a4d82fc
JJ
283}
284
ff7c6d11
XL
285extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn,
286 unsigned Index,
287 uint32_t Bytes) {
288 Function *A = unwrap<Function>(Fn);
289 AttrBuilder B;
290 B.addAlignmentAttr(Bytes);
291#if LLVM_VERSION_GE(5, 0)
292 A->addAttributes(Index, B);
293#else
294 A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B));
295#endif
296}
297
32a655c1
SL
298extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
299 uint64_t Bytes) {
1a4d82fc
JJ
300 Function *A = unwrap<Function>(Fn);
301 AttrBuilder B;
32a655c1 302 B.addDereferenceableAttr(Bytes);
3b2f2976
XL
303#if LLVM_VERSION_GE(5, 0)
304 A->addAttributes(Index, B);
305#else
32a655c1 306 A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B));
3b2f2976 307#endif
1a4d82fc 308}
1a4d82fc 309
ff7c6d11
XL
310extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
311 unsigned Index,
312 uint64_t Bytes) {
313 Function *A = unwrap<Function>(Fn);
314 AttrBuilder B;
315 B.addDereferenceableOrNullAttr(Bytes);
316#if LLVM_VERSION_GE(5, 0)
317 A->addAttributes(Index, B);
318#else
319 A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B));
320#endif
321}
322
5bcae85e 323extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
32a655c1
SL
324 unsigned Index,
325 const char *Name,
326 const char *Value) {
62682a34
SL
327 Function *F = unwrap<Function>(Fn);
328 AttrBuilder B;
329 B.addAttribute(Name, Value);
3b2f2976
XL
330#if LLVM_VERSION_GE(5, 0)
331 F->addAttributes(Index, B);
332#else
32a655c1 333 F->addAttributes(Index, AttributeSet::get(F->getContext(), Index, B));
3b2f2976 334#endif
62682a34
SL
335}
336
5bcae85e 337extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
32a655c1
SL
338 unsigned Index,
339 LLVMRustAttribute RustAttr) {
476ff2be 340 Function *F = unwrap<Function>(Fn);
32a655c1 341 Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
476ff2be 342 AttrBuilder B(Attr);
3b2f2976
XL
343 auto PAL = F->getAttributes();
344#if LLVM_VERSION_GE(5, 0)
345 auto PALNew = PAL.removeAttributes(F->getContext(), Index, B);
346#else
32a655c1
SL
347 const AttributeSet PALNew = PAL.removeAttributes(
348 F->getContext(), Index, AttributeSet::get(F->getContext(), Index, B));
3b2f2976 349#endif
32a655c1 350 F->setAttributes(PALNew);
1a4d82fc
JJ
351}
352
54a0048b
SL
353// enable fpmath flag UnsafeAlgebra
354extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
32a655c1 355 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
2c00a5a8
XL
356#if LLVM_VERSION_GE(6, 0)
357 I->setFast(true);
358#else
32a655c1 359 I->setHasUnsafeAlgebra(true);
2c00a5a8 360#endif
32a655c1 361 }
54a0048b
SL
362}
363
32a655c1
SL
364extern "C" LLVMValueRef
365LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef Source, const char *Name,
ff7c6d11 366 LLVMAtomicOrdering Order) {
32a655c1
SL
367 LoadInst *LI = new LoadInst(unwrap(Source), 0);
368 LI->setAtomic(fromRust(Order));
32a655c1 369 return wrap(unwrap(B)->Insert(LI, Name));
970d7e83
LB
370}
371
5bcae85e 372extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
32a655c1
SL
373 LLVMValueRef V,
374 LLVMValueRef Target,
ff7c6d11 375 LLVMAtomicOrdering Order) {
32a655c1
SL
376 StoreInst *SI = new StoreInst(unwrap(V), unwrap(Target));
377 SI->setAtomic(fromRust(Order));
32a655c1
SL
378 return wrap(unwrap(B)->Insert(SI));
379}
380
381extern "C" LLVMValueRef
382LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
383 LLVMValueRef Old, LLVMValueRef Source,
384 LLVMAtomicOrdering Order,
385 LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
386 AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
387 unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
388 fromRust(FailureOrder));
389 ACXI->setWeak(Weak);
390 return wrap(ACXI);
223e47cc 391}
5bcae85e
SL
392
393enum class LLVMRustSynchronizationScope {
32a655c1
SL
394 Other,
395 SingleThread,
396 CrossThread,
5bcae85e
SL
397};
398
3b2f2976
XL
399#if LLVM_VERSION_GE(5, 0)
400static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
401 switch (Scope) {
402 case LLVMRustSynchronizationScope::SingleThread:
403 return SyncScope::SingleThread;
404 case LLVMRustSynchronizationScope::CrossThread:
405 return SyncScope::System;
406 default:
ff7c6d11 407 report_fatal_error("bad SynchronizationScope.");
3b2f2976
XL
408 }
409}
410#else
32a655c1
SL
411static SynchronizationScope fromRust(LLVMRustSynchronizationScope Scope) {
412 switch (Scope) {
413 case LLVMRustSynchronizationScope::SingleThread:
414 return SingleThread;
415 case LLVMRustSynchronizationScope::CrossThread:
416 return CrossThread;
417 default:
ff7c6d11 418 report_fatal_error("bad SynchronizationScope.");
32a655c1 419 }
223e47cc 420}
3b2f2976 421#endif
223e47cc 422
32a655c1
SL
423extern "C" LLVMValueRef
424LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
425 LLVMRustSynchronizationScope Scope) {
426 return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
5bcae85e
SL
427}
428
5bcae85e 429enum class LLVMRustAsmDialect {
32a655c1
SL
430 Other,
431 Att,
432 Intel,
5bcae85e
SL
433};
434
32a655c1
SL
435static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
436 switch (Dialect) {
437 case LLVMRustAsmDialect::Att:
438 return InlineAsm::AD_ATT;
439 case LLVMRustAsmDialect::Intel:
440 return InlineAsm::AD_Intel;
441 default:
ff7c6d11 442 report_fatal_error("bad AsmDialect.");
32a655c1 443 }
5bcae85e
SL
444}
445
32a655c1
SL
446extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString,
447 char *Constraints,
448 LLVMBool HasSideEffects,
449 LLVMBool IsAlignStack,
450 LLVMRustAsmDialect Dialect) {
451 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString, Constraints,
452 HasSideEffects, IsAlignStack, fromRust(Dialect)));
223e47cc 453}
970d7e83 454
0bf4aa26
XL
455extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty,
456 char *Constraints) {
457 return InlineAsm::Verify(unwrap<FunctionType>(Ty), Constraints);
458}
459
cc61c64b
XL
460extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm) {
461 unwrap(M)->appendModuleInlineAsm(StringRef(Asm));
462}
463
32a655c1 464typedef DIBuilder *LLVMRustDIBuilderRef;
970d7e83 465
3b2f2976
XL
466#if LLVM_VERSION_LT(5, 0)
467typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
85aaf69f
SL
468
469namespace llvm {
3b2f2976 470DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef)
85aaf69f 471
3b2f2976 472inline Metadata **unwrap(LLVMMetadataRef *Vals) {
32a655c1 473 return reinterpret_cast<Metadata **>(Vals);
85aaf69f
SL
474}
475}
3b2f2976 476#endif
85aaf69f 477
3b2f2976 478template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
32a655c1 479 return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
62682a34
SL
480}
481
62682a34
SL
482#define DIDescriptor DIScope
483#define DIArray DINodeArray
32a655c1 484#define unwrapDI unwrapDIPtr
62682a34 485
476ff2be
SL
486// These values **must** match debuginfo::DIFlags! They also *happen*
487// to match LLVM, but that isn't required as we do giant sets of
488// matching below. The value shouldn't be directly passed to LLVM.
489enum class LLVMRustDIFlags : uint32_t {
32a655c1
SL
490 FlagZero = 0,
491 FlagPrivate = 1,
492 FlagProtected = 2,
493 FlagPublic = 3,
494 FlagFwdDecl = (1 << 2),
495 FlagAppleBlock = (1 << 3),
496 FlagBlockByrefStruct = (1 << 4),
497 FlagVirtual = (1 << 5),
498 FlagArtificial = (1 << 6),
499 FlagExplicit = (1 << 7),
500 FlagPrototyped = (1 << 8),
501 FlagObjcClassComplete = (1 << 9),
502 FlagObjectPointer = (1 << 10),
503 FlagVector = (1 << 11),
504 FlagStaticMember = (1 << 12),
505 FlagLValueReference = (1 << 13),
506 FlagRValueReference = (1 << 14),
2c00a5a8
XL
507 FlagExternalTypeRef = (1 << 15),
508 FlagIntroducedVirtual = (1 << 18),
509 FlagBitField = (1 << 19),
510 FlagNoReturn = (1 << 20),
511 FlagMainSubprogram = (1 << 21),
32a655c1 512 // Do not add values that are not supported by the minimum LLVM
2c00a5a8 513 // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
476ff2be
SL
514};
515
32a655c1
SL
516inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
517 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
518 static_cast<uint32_t>(B));
476ff2be
SL
519}
520
32a655c1
SL
521inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
522 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
523 static_cast<uint32_t>(B));
476ff2be
SL
524}
525
32a655c1
SL
526inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
527 return A = A | B;
476ff2be
SL
528}
529
32a655c1 530inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
476ff2be 531
32a655c1
SL
532inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
533 return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
476ff2be
SL
534}
535
32a655c1
SL
536static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
537 DINode::DIFlags Result = DINode::DIFlags::FlagZero;
476ff2be 538
32a655c1
SL
539 switch (visibility(Flags)) {
540 case LLVMRustDIFlags::FlagPrivate:
541 Result |= DINode::DIFlags::FlagPrivate;
542 break;
543 case LLVMRustDIFlags::FlagProtected:
544 Result |= DINode::DIFlags::FlagProtected;
545 break;
546 case LLVMRustDIFlags::FlagPublic:
547 Result |= DINode::DIFlags::FlagPublic;
548 break;
549 default:
550 // The rest are handled below
551 break;
552 }
476ff2be 553
32a655c1
SL
554 if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
555 Result |= DINode::DIFlags::FlagFwdDecl;
556 }
557 if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
558 Result |= DINode::DIFlags::FlagAppleBlock;
559 }
560 if (isSet(Flags & LLVMRustDIFlags::FlagBlockByrefStruct)) {
561 Result |= DINode::DIFlags::FlagBlockByrefStruct;
562 }
563 if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
564 Result |= DINode::DIFlags::FlagVirtual;
565 }
566 if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
567 Result |= DINode::DIFlags::FlagArtificial;
568 }
569 if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
570 Result |= DINode::DIFlags::FlagExplicit;
571 }
572 if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
573 Result |= DINode::DIFlags::FlagPrototyped;
574 }
575 if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
576 Result |= DINode::DIFlags::FlagObjcClassComplete;
577 }
578 if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
579 Result |= DINode::DIFlags::FlagObjectPointer;
580 }
581 if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
582 Result |= DINode::DIFlags::FlagVector;
583 }
584 if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
585 Result |= DINode::DIFlags::FlagStaticMember;
586 }
587 if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
588 Result |= DINode::DIFlags::FlagLValueReference;
589 }
590 if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
591 Result |= DINode::DIFlags::FlagRValueReference;
592 }
2c00a5a8
XL
593#if LLVM_VERSION_LE(4, 0)
594 if (isSet(Flags & LLVMRustDIFlags::FlagExternalTypeRef)) {
595 Result |= DINode::DIFlags::FlagExternalTypeRef;
596 }
597#endif
598 if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
599 Result |= DINode::DIFlags::FlagIntroducedVirtual;
600 }
601 if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
602 Result |= DINode::DIFlags::FlagBitField;
603 }
2c00a5a8
XL
604 if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
605 Result |= DINode::DIFlags::FlagNoReturn;
606 }
8bb4bdeb
XL
607 if (isSet(Flags & LLVMRustDIFlags::FlagMainSubprogram)) {
608 Result |= DINode::DIFlags::FlagMainSubprogram;
609 }
476ff2be 610
32a655c1 611 return Result;
476ff2be
SL
612}
613
62682a34 614extern "C" uint32_t LLVMRustDebugMetadataVersion() {
32a655c1 615 return DEBUG_METADATA_VERSION;
62682a34
SL
616}
617
32a655c1 618extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
62682a34 619
32a655c1 620extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
1a4d82fc 621
32a655c1
SL
622extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
623 uint32_t Value) {
624 unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
970d7e83
LB
625}
626
ff7c6d11
XL
627extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
628 return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
041b39d2
XL
629}
630
5bcae85e 631extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
32a655c1 632 return new DIBuilder(*unwrap(M));
970d7e83
LB
633}
634
5bcae85e 635extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
32a655c1 636 delete Builder;
970d7e83
LB
637}
638
5bcae85e 639extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
32a655c1 640 Builder->finalize();
970d7e83
LB
641}
642
3b2f2976
XL
643extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
644 LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
8bb4bdeb 645 const char *Producer, bool isOptimized, const char *Flags,
32a655c1 646 unsigned RuntimeVer, const char *SplitName) {
8bb4bdeb
XL
647 auto *File = unwrapDI<DIFile>(FileRef);
648
8bb4bdeb 649 return wrap(Builder->createCompileUnit(Lang, File, Producer, isOptimized,
32a655c1
SL
650 Flags, RuntimeVer, SplitName));
651}
652
3b2f2976 653extern "C" LLVMMetadataRef
32a655c1
SL
654LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename,
655 const char *Directory) {
656 return wrap(Builder->createFile(Filename, Directory));
657}
658
3b2f2976 659extern "C" LLVMMetadataRef
32a655c1 660LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
3b2f2976
XL
661 LLVMMetadataRef File,
662 LLVMMetadataRef ParameterTypes) {
32a655c1 663 return wrap(Builder->createSubroutineType(
32a655c1 664 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
970d7e83
LB
665}
666
3b2f2976
XL
667extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
668 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
669 const char *LinkageName, LLVMMetadataRef File, unsigned LineNo,
670 LLVMMetadataRef Ty, bool IsLocalToUnit, bool IsDefinition,
32a655c1 671 unsigned ScopeLine, LLVMRustDIFlags Flags, bool IsOptimized,
3b2f2976 672 LLVMValueRef Fn, LLVMMetadataRef TParam, LLVMMetadataRef Decl) {
32a655c1
SL
673 DITemplateParameterArray TParams =
674 DITemplateParameterArray(unwrap<MDTuple>(TParam));
675 DISubprogram *Sub = Builder->createFunction(
676 unwrapDI<DIScope>(Scope), Name, LinkageName, unwrapDI<DIFile>(File),
677 LineNo, unwrapDI<DISubroutineType>(Ty), IsLocalToUnit, IsDefinition,
678 ScopeLine, fromRust(Flags), IsOptimized, TParams,
679 unwrapDIPtr<DISubprogram>(Decl));
680 unwrap<Function>(Fn)->setSubprogram(Sub);
681 return wrap(Sub);
970d7e83
LB
682}
683
3b2f2976 684extern "C" LLVMMetadataRef
32a655c1 685LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder, const char *Name,
8bb4bdeb 686 uint64_t SizeInBits, uint32_t AlignInBits,
32a655c1 687 unsigned Encoding) {
8faf50e0 688 return wrap(Builder->createBasicType(Name, SizeInBits, Encoding));
970d7e83 689}
1a4d82fc 690
3b2f2976
XL
691extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
692 LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
8bb4bdeb 693 uint64_t SizeInBits, uint32_t AlignInBits, const char *Name) {
32a655c1 694 return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
3b2f2976
XL
695 SizeInBits, AlignInBits,
696#if LLVM_VERSION_GE(5, 0)
697 /* DWARFAddressSpace */ None,
698#endif
699 Name));
970d7e83
LB
700}
701
3b2f2976
XL
702extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
703 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
704 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
8bb4bdeb 705 uint32_t AlignInBits, LLVMRustDIFlags Flags,
3b2f2976
XL
706 LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
707 unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
1a4d82fc 708 const char *UniqueId) {
32a655c1
SL
709 return wrap(Builder->createStructType(
710 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
711 SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
712 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
713 unwrapDI<DIType>(VTableHolder), UniqueId));
970d7e83
LB
714}
715
3b2f2976
XL
716extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
717 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
718 LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
8bb4bdeb 719 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
3b2f2976 720 LLVMMetadataRef Ty) {
32a655c1
SL
721 return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope), Name,
722 unwrapDI<DIFile>(File), LineNo,
723 SizeInBits, AlignInBits, OffsetInBits,
724 fromRust(Flags), unwrapDI<DIType>(Ty)));
970d7e83 725}
1a4d82fc 726
3b2f2976
XL
727extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
728 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
729 LLVMMetadataRef File, unsigned Line, unsigned Col) {
32a655c1
SL
730 return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
731 unwrapDI<DIFile>(File), Line, Col));
1a4d82fc
JJ
732}
733
3b2f2976 734extern "C" LLVMMetadataRef
32a655c1 735LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
3b2f2976
XL
736 LLVMMetadataRef Scope,
737 LLVMMetadataRef File) {
32a655c1
SL
738 return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
739 unwrapDI<DIFile>(File)));
9e0c209e
SL
740}
741
3b2f2976
XL
742extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
743 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name,
744 const char *LinkageName, LLVMMetadataRef File, unsigned LineNo,
745 LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
746 LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
cc61c64b 747 llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
476ff2be 748
32a655c1
SL
749 llvm::DIExpression *InitExpr = nullptr;
750 if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
751 InitExpr = Builder->createConstantValueExpression(
752 IntVal->getValue().getSExtValue());
753 } else if (llvm::ConstantFP *FPVal =
754 llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
755 InitExpr = Builder->createConstantValueExpression(
756 FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
757 }
476ff2be 758
cc61c64b
XL
759 llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
760 unwrapDI<DIDescriptor>(Context), Name, LinkageName,
761 unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
762 InitExpr, unwrapDIPtr<MDNode>(Decl), AlignInBits);
763
764 InitVal->setMetadata("dbg", VarExpr);
765
766 return wrap(VarExpr);
970d7e83 767}
1a4d82fc 768
3b2f2976
XL
769extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
770 LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
771 const char *Name, LLVMMetadataRef File, unsigned LineNo,
772 LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
8bb4bdeb 773 unsigned ArgNo, uint32_t AlignInBits) {
32a655c1
SL
774 if (Tag == 0x100) { // DW_TAG_auto_variable
775 return wrap(Builder->createAutoVariable(
776 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNo,
8faf50e0 777 unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
32a655c1
SL
778 } else {
779 return wrap(Builder->createParameterVariable(
780 unwrapDI<DIDescriptor>(Scope), Name, ArgNo, unwrapDI<DIFile>(File),
781 LineNo, unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
782 }
970d7e83
LB
783}
784
3b2f2976 785extern "C" LLVMMetadataRef
32a655c1 786LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
3b2f2976
XL
787 uint32_t AlignInBits, LLVMMetadataRef Ty,
788 LLVMMetadataRef Subscripts) {
32a655c1
SL
789 return wrap(
790 Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
791 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
970d7e83
LB
792}
793
3b2f2976 794extern "C" LLVMMetadataRef
32a655c1
SL
795LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
796 int64_t Count) {
797 return wrap(Builder->getOrCreateSubrange(Lo, Count));
970d7e83
LB
798}
799
3b2f2976 800extern "C" LLVMMetadataRef
32a655c1 801LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
3b2f2976 802 LLVMMetadataRef *Ptr, unsigned Count) {
32a655c1
SL
803 Metadata **DataValue = unwrap(Ptr);
804 return wrap(
805 Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
970d7e83
LB
806}
807
5bcae85e 808extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
3b2f2976 809 LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
32a655c1 810 int64_t *AddrOps, unsigned AddrOpsCount, LLVMValueRef DL,
970d7e83 811 LLVMBasicBlockRef InsertAtEnd) {
32a655c1
SL
812 return wrap(Builder->insertDeclare(
813 unwrap(V), unwrap<DILocalVariable>(VarInfo),
814 Builder->createExpression(llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
815 DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
816 unwrap(InsertAtEnd)));
817}
818
3b2f2976 819extern "C" LLVMMetadataRef
32a655c1
SL
820LLVMRustDIBuilderCreateEnumerator(LLVMRustDIBuilderRef Builder,
821 const char *Name, uint64_t Val) {
822 return wrap(Builder->createEnumerator(Name, Val));
1a4d82fc
JJ
823}
824
3b2f2976
XL
825extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
826 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
827 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
828 uint32_t AlignInBits, LLVMMetadataRef Elements,
829 LLVMMetadataRef ClassTy) {
32a655c1
SL
830 return wrap(Builder->createEnumerationType(
831 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
832 SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
833 unwrapDI<DIType>(ClassTy)));
1a4d82fc
JJ
834}
835
3b2f2976
XL
836extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
837 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
838 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
839 uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
32a655c1
SL
840 unsigned RunTimeLang, const char *UniqueId) {
841 return wrap(Builder->createUnionType(
842 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
843 SizeInBits, AlignInBits, fromRust(Flags),
844 DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang, UniqueId));
1a4d82fc
JJ
845}
846
3b2f2976
XL
847extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
848 LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
849 LLVMMetadataRef Ty, LLVMMetadataRef File, unsigned LineNo,
32a655c1
SL
850 unsigned ColumnNo) {
851 return wrap(Builder->createTemplateTypeParameter(
852 unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIType>(Ty)));
853}
854
3b2f2976 855extern "C" LLVMMetadataRef
32a655c1 856LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder,
3b2f2976
XL
857 LLVMMetadataRef Scope, const char *Name,
858 LLVMMetadataRef File, unsigned LineNo) {
32a655c1 859 return wrap(Builder->createNameSpace(
3b2f2976
XL
860 unwrapDI<DIDescriptor>(Scope), Name
861#if LLVM_VERSION_LT(5, 0)
862 ,
863 unwrapDI<DIFile>(File), LineNo
864#endif
476ff2be 865#if LLVM_VERSION_GE(4, 0)
32a655c1
SL
866 ,
867 false // ExportSymbols (only relevant for C++ anonymous namespaces)
476ff2be 868#endif
32a655c1 869 ));
1a4d82fc
JJ
870}
871
32a655c1
SL
872extern "C" void
873LLVMRustDICompositeTypeSetTypeArray(LLVMRustDIBuilderRef Builder,
3b2f2976
XL
874 LLVMMetadataRef CompositeTy,
875 LLVMMetadataRef TyArray) {
32a655c1
SL
876 DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
877 Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(TyArray)));
1a4d82fc
JJ
878}
879
32a655c1
SL
880extern "C" LLVMValueRef
881LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef, unsigned Line,
3b2f2976
XL
882 unsigned Column, LLVMMetadataRef Scope,
883 LLVMMetadataRef InlinedAt) {
32a655c1 884 LLVMContext &Context = *unwrap(ContextRef);
85aaf69f 885
32a655c1
SL
886 DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(Scope),
887 unwrapDIPtr<MDNode>(InlinedAt));
85aaf69f 888
32a655c1 889 return wrap(MetadataAsValue::get(Context, debug_loc.getAsMDNode()));
85aaf69f
SL
890}
891
32a655c1
SL
892extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
893 return dwarf::DW_OP_deref;
5bcae85e
SL
894}
895
2c00a5a8
XL
896extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
897#if LLVM_VERSION_GE(5, 0)
898 return dwarf::DW_OP_plus_uconst;
899#else
900 // older LLVM used `plus` to behave like `plus_uconst`.
901 return dwarf::DW_OP_plus;
902#endif
903}
5bcae85e 904
32a655c1
SL
905extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
906 RawRustStringOstream OS(Str);
907 unwrap<llvm::Type>(Ty)->print(OS);
1a4d82fc
JJ
908}
909
32a655c1
SL
910extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
911 RustStringRef Str) {
912 RawRustStringOstream OS(Str);
7cac9316
XL
913 if (!V) {
914 OS << "(null)";
915 } else {
916 OS << "(";
917 unwrap<llvm::Value>(V)->getType()->print(OS);
918 OS << ":";
919 unwrap<llvm::Value>(V)->print(OS);
920 OS << ")";
921 }
1a4d82fc
JJ
922}
923
1a4d82fc
JJ
924// Note that the two following functions look quite similar to the
925// LLVMGetSectionName function. Sadly, it appears that this function only
926// returns a char* pointer, which isn't guaranteed to be null-terminated. The
927// function provided by LLVM doesn't return the length, so we've created our own
928// function which returns the length as well as the data pointer.
929//
930// For an example of this not returning a null terminated string, see
931// lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
932// branches explicitly creates a StringRef without a null terminator, and then
933// that's returned.
934
935inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
32a655c1 936 return reinterpret_cast<section_iterator *>(SI);
1a4d82fc
JJ
937}
938
32a655c1
SL
939extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI,
940 const char **Ptr) {
941 StringRef Ret;
942 if (std::error_code EC = (*unwrap(SI))->getName(Ret))
943 report_fatal_error(EC.message());
944 *Ptr = Ret.data();
945 return Ret.size();
1a4d82fc
JJ
946}
947
948// LLVMArrayType function does not support 64-bit ElementCount
32a655c1
SL
949extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
950 uint64_t ElementCount) {
951 return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
1a4d82fc
JJ
952}
953
954DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
1a4d82fc 955
32a655c1
SL
956extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
957 RawRustStringOstream OS(Str);
958 unwrap(T)->print(OS);
1a4d82fc
JJ
959}
960
32a655c1
SL
961extern "C" void LLVMRustUnpackOptimizationDiagnostic(
962 LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
3b2f2976
XL
963 LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
964 RustStringRef FilenameOut, RustStringRef MessageOut) {
32a655c1
SL
965 // Undefined to call this not on an optimization diagnostic!
966 llvm::DiagnosticInfoOptimizationBase *Opt =
967 static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
1a4d82fc 968
32a655c1
SL
969 RawRustStringOstream PassNameOS(PassNameOut);
970 PassNameOS << Opt->getPassName();
971 *FunctionOut = wrap(&Opt->getFunction());
3b2f2976
XL
972
973 RawRustStringOstream FilenameOS(FilenameOut);
974#if LLVM_VERSION_GE(5,0)
975 DiagnosticLocation loc = Opt->getLocation();
976 if (loc.isValid()) {
977 *Line = loc.getLine();
978 *Column = loc.getColumn();
979 FilenameOS << loc.getFilename();
980 }
981#else
982 const DebugLoc &loc = Opt->getDebugLoc();
983 if (loc) {
984 *Line = loc.getLine();
985 *Column = loc.getCol();
986 FilenameOS << cast<DIScope>(loc.getScope())->getFilename();
987 }
988#endif
989
32a655c1
SL
990 RawRustStringOstream MessageOS(MessageOut);
991 MessageOS << Opt->getMsg();
1a4d82fc
JJ
992}
993
85aaf69f 994extern "C" void
32a655c1
SL
995LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI, unsigned *CookieOut,
996 LLVMTwineRef *MessageOut,
997 LLVMValueRef *InstructionOut) {
998 // Undefined to call this not on an inline assembly diagnostic!
999 llvm::DiagnosticInfoInlineAsm *IA =
1000 static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
85aaf69f 1001
32a655c1
SL
1002 *CookieOut = IA->getLocCookie();
1003 *MessageOut = wrap(&IA->getMsgStr());
1004 *InstructionOut = wrap(IA->getInstruction());
85aaf69f
SL
1005}
1006
32a655c1
SL
1007extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
1008 RustStringRef Str) {
1009 RawRustStringOstream OS(Str);
1010 DiagnosticPrinterRawOStream DP(OS);
1011 unwrap(DI)->print(DP);
1a4d82fc
JJ
1012}
1013
5bcae85e 1014enum class LLVMRustDiagnosticKind {
32a655c1
SL
1015 Other,
1016 InlineAsm,
1017 StackSize,
1018 DebugMetadataVersion,
1019 SampleProfile,
1020 OptimizationRemark,
1021 OptimizationRemarkMissed,
1022 OptimizationRemarkAnalysis,
1023 OptimizationRemarkAnalysisFPCommute,
1024 OptimizationRemarkAnalysisAliasing,
1025 OptimizationRemarkOther,
1026 OptimizationFailure,
0531ce1d 1027 PGOProfile,
b7449926 1028 Linker,
5bcae85e
SL
1029};
1030
32a655c1
SL
1031static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
1032 switch (Kind) {
1033 case DK_InlineAsm:
1034 return LLVMRustDiagnosticKind::InlineAsm;
1035 case DK_StackSize:
1036 return LLVMRustDiagnosticKind::StackSize;
1037 case DK_DebugMetadataVersion:
1038 return LLVMRustDiagnosticKind::DebugMetadataVersion;
1039 case DK_SampleProfile:
1040 return LLVMRustDiagnosticKind::SampleProfile;
1041 case DK_OptimizationRemark:
1042 return LLVMRustDiagnosticKind::OptimizationRemark;
1043 case DK_OptimizationRemarkMissed:
1044 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
1045 case DK_OptimizationRemarkAnalysis:
1046 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
32a655c1
SL
1047 case DK_OptimizationRemarkAnalysisFPCommute:
1048 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
1049 case DK_OptimizationRemarkAnalysisAliasing:
1050 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
0531ce1d
XL
1051 case DK_PGOProfile:
1052 return LLVMRustDiagnosticKind::PGOProfile;
b7449926
XL
1053 case DK_Linker:
1054 return LLVMRustDiagnosticKind::Linker;
32a655c1 1055 default:
32a655c1
SL
1056 return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
1057 ? LLVMRustDiagnosticKind::OptimizationRemarkOther
1058 : LLVMRustDiagnosticKind::Other;
5bcae85e
SL
1059 }
1060}
1061
32a655c1
SL
1062extern "C" LLVMRustDiagnosticKind
1063LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
1064 return toRust((DiagnosticKind)unwrap(DI)->getKind());
5bcae85e
SL
1065}
1066// This is kept distinct from LLVMGetTypeKind, because when
1067// a new type kind is added, the Rust-side enum must be
1068// updated or UB will result.
1069extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1070 switch (unwrap(Ty)->getTypeID()) {
1071 case Type::VoidTyID:
1072 return LLVMVoidTypeKind;
1073 case Type::HalfTyID:
1074 return LLVMHalfTypeKind;
1075 case Type::FloatTyID:
1076 return LLVMFloatTypeKind;
1077 case Type::DoubleTyID:
1078 return LLVMDoubleTypeKind;
1079 case Type::X86_FP80TyID:
1080 return LLVMX86_FP80TypeKind;
1081 case Type::FP128TyID:
1082 return LLVMFP128TypeKind;
1083 case Type::PPC_FP128TyID:
1084 return LLVMPPC_FP128TypeKind;
1085 case Type::LabelTyID:
1086 return LLVMLabelTypeKind;
1087 case Type::MetadataTyID:
1088 return LLVMMetadataTypeKind;
1089 case Type::IntegerTyID:
1090 return LLVMIntegerTypeKind;
1091 case Type::FunctionTyID:
1092 return LLVMFunctionTypeKind;
1093 case Type::StructTyID:
1094 return LLVMStructTypeKind;
1095 case Type::ArrayTyID:
1096 return LLVMArrayTypeKind;
1097 case Type::PointerTyID:
1098 return LLVMPointerTypeKind;
1099 case Type::VectorTyID:
1100 return LLVMVectorTypeKind;
1101 case Type::X86_MMXTyID:
1102 return LLVMX86_MMXTypeKind;
5bcae85e
SL
1103 case Type::TokenTyID:
1104 return LLVMTokenTypeKind;
5bcae85e 1105 }
ff7c6d11 1106 report_fatal_error("Unhandled TypeID.");
1a4d82fc
JJ
1107}
1108
1a4d82fc
JJ
1109DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1110
5bcae85e 1111extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
32a655c1
SL
1112 LLVMContextRef C, LLVMContext::InlineAsmDiagHandlerTy H, void *CX) {
1113 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1a4d82fc
JJ
1114}
1115
32a655c1
SL
1116extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef D,
1117 RustStringRef Str) {
1118 RawRustStringOstream OS(Str);
1119 unwrap(D)->print("", OS);
1a4d82fc 1120}
c1a9b12d 1121
32a655c1
SL
1122extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
1123 LLVMValueRef ParentPad,
1124 unsigned ArgCount,
1125 LLVMValueRef *LLArgs,
1126 const char *Name) {
32a655c1
SL
1127 Value **Args = unwrap(LLArgs);
1128 if (ParentPad == nullptr) {
1129 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1130 ParentPad = wrap(Constant::getNullValue(Ty));
1131 }
1132 return wrap(unwrap(B)->CreateCleanupPad(
1133 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
7453a54e
SL
1134}
1135
32a655c1
SL
1136extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
1137 LLVMValueRef CleanupPad,
1138 LLVMBasicBlockRef UnwindBB) {
32a655c1
SL
1139 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1140 return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
7453a54e
SL
1141}
1142
1143extern "C" LLVMValueRef
32a655c1
SL
1144LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
1145 unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
32a655c1
SL
1146 Value **Args = unwrap(LLArgs);
1147 return wrap(unwrap(B)->CreateCatchPad(
1148 unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
7453a54e
SL
1149}
1150
32a655c1
SL
1151extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
1152 LLVMValueRef Pad,
1153 LLVMBasicBlockRef BB) {
32a655c1
SL
1154 return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1155 unwrap(BB)));
7453a54e
SL
1156}
1157
32a655c1
SL
1158extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
1159 LLVMValueRef ParentPad,
1160 LLVMBasicBlockRef BB,
1161 unsigned NumHandlers,
1162 const char *Name) {
32a655c1
SL
1163 if (ParentPad == nullptr) {
1164 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
1165 ParentPad = wrap(Constant::getNullValue(Ty));
1166 }
1167 return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
1168 NumHandlers, Name));
7453a54e
SL
1169}
1170
32a655c1
SL
1171extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1172 LLVMBasicBlockRef Handler) {
32a655c1
SL
1173 Value *CatchSwitch = unwrap(CatchSwitchRef);
1174 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
7453a54e
SL
1175}
1176
32a655c1
SL
1177extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
1178 LLVMValueRef *Inputs,
1179 unsigned NumInputs) {
7453a54e
SL
1180 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1181}
1182
32a655c1 1183extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
7453a54e
SL
1184 delete Bundle;
1185}
1186
32a655c1
SL
1187extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
1188 LLVMValueRef *Args, unsigned NumArgs,
1189 OperandBundleDef *Bundle,
1190 const char *Name) {
1191 unsigned Len = Bundle ? 1 : 0;
1192 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1193 return wrap(unwrap(B)->CreateCall(
1194 unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Bundles, Name));
7453a54e
SL
1195}
1196
1197extern "C" LLVMValueRef
32a655c1
SL
1198LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
1199 unsigned NumArgs, LLVMBasicBlockRef Then,
1200 LLVMBasicBlockRef Catch, OperandBundleDef *Bundle,
7453a54e 1201 const char *Name) {
32a655c1
SL
1202 unsigned Len = Bundle ? 1 : 0;
1203 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
1204 return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch),
1205 makeArrayRef(unwrap(Args), NumArgs),
1206 Bundles, Name));
7453a54e 1207}
54a0048b 1208
32a655c1
SL
1209extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
1210 LLVMBasicBlockRef BB) {
1211 auto Point = unwrap(BB)->getFirstInsertionPt();
1212 unwrap(B)->SetInsertPoint(unwrap(BB), Point);
54a0048b
SL
1213}
1214
32a655c1
SL
1215extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
1216 const char *Name) {
1217 Triple TargetTriple(unwrap(M)->getTargetTriple());
1218 GlobalObject *GV = unwrap<GlobalObject>(V);
1219 if (!TargetTriple.isOSBinFormatMachO()) {
1220 GV->setComdat(unwrap(M)->getOrInsertComdat(Name));
1221 }
54a0048b
SL
1222}
1223
1224extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
32a655c1
SL
1225 GlobalObject *GV = unwrap<GlobalObject>(V);
1226 GV->setComdat(nullptr);
54a0048b 1227}
9e0c209e
SL
1228
1229enum class LLVMRustLinkage {
32a655c1
SL
1230 ExternalLinkage = 0,
1231 AvailableExternallyLinkage = 1,
1232 LinkOnceAnyLinkage = 2,
1233 LinkOnceODRLinkage = 3,
1234 WeakAnyLinkage = 4,
1235 WeakODRLinkage = 5,
1236 AppendingLinkage = 6,
1237 InternalLinkage = 7,
1238 PrivateLinkage = 8,
1239 ExternalWeakLinkage = 9,
1240 CommonLinkage = 10,
9e0c209e
SL
1241};
1242
32a655c1
SL
1243static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
1244 switch (Linkage) {
1245 case LLVMExternalLinkage:
1246 return LLVMRustLinkage::ExternalLinkage;
1247 case LLVMAvailableExternallyLinkage:
1248 return LLVMRustLinkage::AvailableExternallyLinkage;
1249 case LLVMLinkOnceAnyLinkage:
1250 return LLVMRustLinkage::LinkOnceAnyLinkage;
1251 case LLVMLinkOnceODRLinkage:
1252 return LLVMRustLinkage::LinkOnceODRLinkage;
1253 case LLVMWeakAnyLinkage:
1254 return LLVMRustLinkage::WeakAnyLinkage;
1255 case LLVMWeakODRLinkage:
1256 return LLVMRustLinkage::WeakODRLinkage;
1257 case LLVMAppendingLinkage:
1258 return LLVMRustLinkage::AppendingLinkage;
1259 case LLVMInternalLinkage:
1260 return LLVMRustLinkage::InternalLinkage;
1261 case LLVMPrivateLinkage:
1262 return LLVMRustLinkage::PrivateLinkage;
1263 case LLVMExternalWeakLinkage:
1264 return LLVMRustLinkage::ExternalWeakLinkage;
1265 case LLVMCommonLinkage:
1266 return LLVMRustLinkage::CommonLinkage;
1267 default:
ff7c6d11 1268 report_fatal_error("Invalid LLVMRustLinkage value!");
32a655c1 1269 }
9e0c209e
SL
1270}
1271
32a655c1
SL
1272static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
1273 switch (Linkage) {
1274 case LLVMRustLinkage::ExternalLinkage:
1275 return LLVMExternalLinkage;
1276 case LLVMRustLinkage::AvailableExternallyLinkage:
1277 return LLVMAvailableExternallyLinkage;
1278 case LLVMRustLinkage::LinkOnceAnyLinkage:
1279 return LLVMLinkOnceAnyLinkage;
1280 case LLVMRustLinkage::LinkOnceODRLinkage:
1281 return LLVMLinkOnceODRLinkage;
1282 case LLVMRustLinkage::WeakAnyLinkage:
1283 return LLVMWeakAnyLinkage;
1284 case LLVMRustLinkage::WeakODRLinkage:
1285 return LLVMWeakODRLinkage;
1286 case LLVMRustLinkage::AppendingLinkage:
1287 return LLVMAppendingLinkage;
1288 case LLVMRustLinkage::InternalLinkage:
1289 return LLVMInternalLinkage;
1290 case LLVMRustLinkage::PrivateLinkage:
1291 return LLVMPrivateLinkage;
1292 case LLVMRustLinkage::ExternalWeakLinkage:
1293 return LLVMExternalWeakLinkage;
1294 case LLVMRustLinkage::CommonLinkage:
1295 return LLVMCommonLinkage;
1296 }
ff7c6d11 1297 report_fatal_error("Invalid LLVMRustLinkage value!");
9e0c209e
SL
1298}
1299
1300extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
32a655c1 1301 return toRust(LLVMGetLinkage(V));
9e0c209e
SL
1302}
1303
32a655c1
SL
1304extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
1305 LLVMRustLinkage RustLinkage) {
1306 LLVMSetLinkage(V, fromRust(RustLinkage));
1307}
1308
1309// Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
1310// the common sizes (1, 8, 16, 32, 64, 128 bits)
1311extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
1312{
1313 auto C = unwrap<llvm::ConstantInt>(CV);
1314 if (C->getBitWidth() > 128) { return false; }
1315 APInt AP;
1316 if (sext) {
1317 AP = C->getValue().sextOrSelf(128);
1318 } else {
1319 AP = C->getValue().zextOrSelf(128);
1320 }
1321 *low = AP.getLoBits(64).getZExtValue();
1322 *high = AP.getHiBits(64).getZExtValue();
1323 return true;
9e0c209e 1324}
476ff2be 1325
476ff2be 1326enum class LLVMRustVisibility {
32a655c1
SL
1327 Default = 0,
1328 Hidden = 1,
1329 Protected = 2,
476ff2be
SL
1330};
1331
32a655c1
SL
1332static LLVMRustVisibility toRust(LLVMVisibility Vis) {
1333 switch (Vis) {
1334 case LLVMDefaultVisibility:
1335 return LLVMRustVisibility::Default;
1336 case LLVMHiddenVisibility:
1337 return LLVMRustVisibility::Hidden;
1338 case LLVMProtectedVisibility:
1339 return LLVMRustVisibility::Protected;
1340 }
ff7c6d11 1341 report_fatal_error("Invalid LLVMRustVisibility value!");
476ff2be
SL
1342}
1343
32a655c1
SL
1344static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
1345 switch (Vis) {
1346 case LLVMRustVisibility::Default:
1347 return LLVMDefaultVisibility;
1348 case LLVMRustVisibility::Hidden:
1349 return LLVMHiddenVisibility;
1350 case LLVMRustVisibility::Protected:
1351 return LLVMProtectedVisibility;
1352 }
ff7c6d11 1353 report_fatal_error("Invalid LLVMRustVisibility value!");
476ff2be
SL
1354}
1355
1356extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
32a655c1 1357 return toRust(LLVMGetVisibility(V));
476ff2be
SL
1358}
1359
8bb4bdeb
XL
1360// Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
1361extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
1362 LLVMTypeRef DestTy, bool isSigned) {
1363 return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
1364}
1365
32a655c1
SL
1366extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
1367 LLVMRustVisibility RustVisibility) {
1368 LLVMSetVisibility(V, fromRust(RustVisibility));
476ff2be 1369}
ea8adc8c
XL
1370
1371struct LLVMRustModuleBuffer {
1372 std::string data;
1373};
1374
1375extern "C" LLVMRustModuleBuffer*
1376LLVMRustModuleBufferCreate(LLVMModuleRef M) {
1377 auto Ret = llvm::make_unique<LLVMRustModuleBuffer>();
1378 {
1379 raw_string_ostream OS(Ret->data);
1380 {
1381 legacy::PassManager PM;
1382 PM.add(createBitcodeWriterPass(OS));
1383 PM.run(*unwrap(M));
1384 }
1385 }
1386 return Ret.release();
1387}
1388
1389extern "C" void
1390LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
1391 delete Buffer;
1392}
1393
1394extern "C" const void*
1395LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
1396 return Buffer->data.data();
1397}
1398
1399extern "C" size_t
1400LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
1401 return Buffer->data.length();
1402}
1403
1404extern "C" uint64_t
1405LLVMRustModuleCost(LLVMModuleRef M) {
2c00a5a8
XL
1406 auto f = unwrap(M)->functions();
1407 return std::distance(std::begin(f), std::end(f));
ea8adc8c 1408}
0531ce1d
XL
1409
1410// Vector reductions:
1411#if LLVM_VERSION_GE(5, 0)
1412extern "C" LLVMValueRef
1413LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1414 return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
1415}
1416extern "C" LLVMValueRef
1417LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
1418 return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
1419}
1420extern "C" LLVMValueRef
1421LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
1422 return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
1423}
1424extern "C" LLVMValueRef
1425LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
1426 return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
1427}
1428extern "C" LLVMValueRef
1429LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
1430 return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
1431}
1432extern "C" LLVMValueRef
1433LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
1434 return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
1435}
1436extern "C" LLVMValueRef
1437LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
1438 return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
1439}
1440extern "C" LLVMValueRef
1441LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1442 return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
1443}
1444extern "C" LLVMValueRef
1445LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
1446 return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
1447}
1448extern "C" LLVMValueRef
1449LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1450 return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN));
1451}
1452extern "C" LLVMValueRef
1453LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
1454 return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN));
1455}
1456
1457#else
1458
1459extern "C" LLVMValueRef
1460LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) {
1461 return nullptr;
1462}
1463extern "C" LLVMValueRef
1464LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) {
1465 return nullptr;
1466}
1467extern "C" LLVMValueRef
1468LLVMRustBuildVectorReduceAdd(LLVMBuilderRef, LLVMValueRef) {
1469 return nullptr;
1470}
1471extern "C" LLVMValueRef
1472LLVMRustBuildVectorReduceMul(LLVMBuilderRef, LLVMValueRef) {
1473 return nullptr;
1474}
1475extern "C" LLVMValueRef
1476LLVMRustBuildVectorReduceAnd(LLVMBuilderRef, LLVMValueRef) {
1477 return nullptr;
1478}
1479extern "C" LLVMValueRef
1480LLVMRustBuildVectorReduceOr(LLVMBuilderRef, LLVMValueRef) {
1481 return nullptr;
1482}
1483extern "C" LLVMValueRef
1484LLVMRustBuildVectorReduceXor(LLVMBuilderRef, LLVMValueRef) {
1485 return nullptr;
1486}
1487extern "C" LLVMValueRef
1488LLVMRustBuildVectorReduceMin(LLVMBuilderRef, LLVMValueRef, bool) {
1489 return nullptr;
1490}
1491extern "C" LLVMValueRef
1492LLVMRustBuildVectorReduceMax(LLVMBuilderRef, LLVMValueRef, bool) {
1493 return nullptr;
1494}
1495extern "C" LLVMValueRef
1496LLVMRustBuildVectorReduceFMin(LLVMBuilderRef, LLVMValueRef, bool) {
1497 return nullptr;
1498}
1499extern "C" LLVMValueRef
1500LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef, bool) {
1501 return nullptr;
1502}
1503#endif
1504
1505#if LLVM_VERSION_LT(4, 0)
1506extern "C" LLVMValueRef
1507LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS,
1508 LLVMValueRef RHS, const char *Name) {
1509 return wrap(unwrap(B)->CreateExactUDiv(unwrap(LHS), unwrap(RHS), Name));
1510}
1511#endif
1512
1513#if LLVM_VERSION_GE(6, 0)
1514extern "C" LLVMValueRef
1515LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1516 return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
1517}
1518extern "C" LLVMValueRef
1519LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
1520 return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));
1521}
1522#else
1523extern "C" LLVMValueRef
1524LLVMRustBuildMinNum(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) {
1525 return nullptr;
1526}
1527extern "C" LLVMValueRef
1528LLVMRustBuildMaxNum(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) {
1529 return nullptr;
1530}
1531#endif