]> git.proxmox.com Git - rustc.git/blame - src/rustllvm/RustWrapper.cpp
Imported Upstream version 1.0.0~beta
[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"
1a4d82fc
JJ
12#include "llvm/Object/Archive.h"
13#include "llvm/Object/ObjectFile.h"
14#include "llvm/IR/DiagnosticInfo.h"
15#include "llvm/IR/DiagnosticPrinter.h"
16
1a4d82fc 17#include "llvm/IR/CallSite.h"
970d7e83 18
223e47cc
LB
19//===----------------------------------------------------------------------===
20//
21// This file defines alternate interfaces to core functions that are more
22// readily callable by Rust's FFI.
23//
24//===----------------------------------------------------------------------===
25
223e47cc
LB
26using namespace llvm;
27using namespace llvm::sys;
1a4d82fc 28using namespace llvm::object;
223e47cc 29
1a4d82fc 30static char *LastError;
970d7e83 31
223e47cc
LB
32extern "C" LLVMMemoryBufferRef
33LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
1a4d82fc
JJ
34 ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(Path,
35 -1,
36 false);
37 if (!buf_or) {
38 LLVMRustSetLastError(buf_or.getError().message().c_str());
39 return nullptr;
223e47cc 40 }
1a4d82fc 41 return wrap(buf_or.get().release());
970d7e83 42}
223e47cc 43
1a4d82fc
JJ
44extern "C" char *LLVMRustGetLastError(void) {
45 char *ret = LastError;
46 LastError = NULL;
47 return ret;
223e47cc
LB
48}
49
1a4d82fc
JJ
50void LLVMRustSetLastError(const char *err) {
51 free((void*) LastError);
52 LastError = strdup(err);
223e47cc
LB
53}
54
1a4d82fc
JJ
55extern "C" void
56LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) {
57 unwrap(M)->setTargetTriple(Triple::normalize(triple));
223e47cc
LB
58}
59
60extern "C" LLVMValueRef LLVMRustConstSmallInt(LLVMTypeRef IntTy, unsigned N,
61 LLVMBool SignExtend) {
62 return LLVMConstInt(IntTy, (unsigned long long)N, SignExtend);
63}
64
970d7e83
LB
65extern "C" LLVMValueRef LLVMRustConstInt(LLVMTypeRef IntTy,
66 unsigned N_hi,
67 unsigned N_lo,
68 LLVMBool SignExtend) {
223e47cc
LB
69 unsigned long long N = N_hi;
70 N <<= 32;
71 N |= N_lo;
72 return LLVMConstInt(IntTy, N, SignExtend);
73}
74
223e47cc
LB
75extern "C" void LLVMRustPrintPassTimings() {
76 raw_fd_ostream OS (2, false); // stderr.
77 TimerGroup::printAll(OS);
78}
79
80extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M,
81 const char* Name,
82 LLVMTypeRef FunctionTy) {
83 return wrap(unwrap(M)->getOrInsertFunction(Name,
84 unwrap<FunctionType>(FunctionTy)));
85}
86
87extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) {
88 return wrap(Type::getMetadataTy(*unwrap(C)));
89}
970d7e83 90
1a4d82fc
JJ
91extern "C" void LLVMAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uint64_t Val) {
92 CallSite Call = CallSite(unwrap<Instruction>(Instr));
93 AttrBuilder B;
94 B.addRawValue(Val);
95 Call.setAttributes(
96 Call.getAttributes().addAttributes(Call->getContext(), index,
97 AttributeSet::get(Call->getContext(),
98 index, B)));
99}
100
101
1a4d82fc
JJ
102extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr, unsigned idx, uint64_t b) {
103 CallSite Call = CallSite(unwrap<Instruction>(Instr));
104 AttrBuilder B;
105 B.addDereferenceableAttr(b);
106 Call.setAttributes(
107 Call.getAttributes().addAttributes(Call->getContext(), idx,
108 AttributeSet::get(Call->getContext(),
109 idx, B)));
110}
1a4d82fc
JJ
111
112extern "C" void LLVMAddFunctionAttribute(LLVMValueRef Fn, unsigned index, uint64_t Val) {
113 Function *A = unwrap<Function>(Fn);
114 AttrBuilder B;
115 B.addRawValue(Val);
116 A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
117}
118
1a4d82fc
JJ
119extern "C" void LLVMAddDereferenceableAttr(LLVMValueRef Fn, unsigned index, uint64_t bytes) {
120 Function *A = unwrap<Function>(Fn);
121 AttrBuilder B;
122 B.addDereferenceableAttr(bytes);
123 A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
124}
1a4d82fc
JJ
125
126extern "C" void LLVMAddFunctionAttrString(LLVMValueRef Fn, unsigned index, const char *Name) {
127 Function *F = unwrap<Function>(Fn);
128 AttrBuilder B;
129 B.addAttribute(Name);
130 F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
131}
132
133extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, unsigned index, const char *Name) {
134 Function *f = unwrap<Function>(fn);
135 LLVMContext &C = f->getContext();
136 AttrBuilder B;
137 B.addAttribute(Name);
138 AttributeSet to_remove = AttributeSet::get(C, index, B);
139
140 AttributeSet attrs = f->getAttributes();
141 f->setAttributes(attrs.removeAttributes(f->getContext(),
142 index,
143 to_remove));
144}
145
970d7e83
LB
146extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
147 LLVMValueRef source,
148 const char* Name,
149 AtomicOrdering order,
150 unsigned alignment) {
151 LoadInst* li = new LoadInst(unwrap(source),0);
152 li->setVolatile(true);
153 li->setAtomic(order);
154 li->setAlignment(alignment);
155 return wrap(unwrap(B)->Insert(li, Name));
156}
157
158extern "C" LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef B,
159 LLVMValueRef val,
160 LLVMValueRef target,
161 AtomicOrdering order,
162 unsigned alignment) {
163 StoreInst* si = new StoreInst(unwrap(val),unwrap(target));
164 si->setVolatile(true);
165 si->setAtomic(order);
166 si->setAlignment(alignment);
167 return wrap(unwrap(B)->Insert(si));
223e47cc
LB
168}
169
170extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
171 LLVMValueRef target,
172 LLVMValueRef old,
173 LLVMValueRef source,
1a4d82fc
JJ
174 AtomicOrdering order,
175 AtomicOrdering failure_order) {
223e47cc 176 return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
c34b1796
AL
177 unwrap(source), order,
178 failure_order
1a4d82fc 179 ));
223e47cc 180}
1a4d82fc
JJ
181extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B, AtomicOrdering order) {
182 return wrap(unwrap(B)->CreateFence(order));
223e47cc
LB
183}
184
185extern "C" void LLVMSetDebug(int Enabled) {
186#ifndef NDEBUG
187 DebugFlag = Enabled;
188#endif
189}
190
191extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty,
192 char *AsmString,
193 char *Constraints,
194 LLVMBool HasSideEffects,
195 LLVMBool IsAlignStack,
196 unsigned Dialect) {
197 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
198 Constraints, HasSideEffects,
199 IsAlignStack, (InlineAsm::AsmDialect) Dialect));
200}
970d7e83 201
970d7e83
LB
202typedef DIBuilder* DIBuilderRef;
203
85aaf69f
SL
204#if LLVM_VERSION_MINOR >= 6
205typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
206
207namespace llvm {
208DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef)
209
210inline Metadata **unwrap(LLVMMetadataRef *Vals) {
211 return reinterpret_cast<Metadata**>(Vals);
212}
213}
214#else
215typedef LLVMValueRef LLVMMetadataRef;
216#endif
217
970d7e83 218template<typename DIT>
85aaf69f 219DIT unwrapDI(LLVMMetadataRef ref) {
1a4d82fc
JJ
220 return DIT(ref ? unwrap<MDNode>(ref) : NULL);
221}
222
1a4d82fc 223extern "C" const uint32_t LLVMRustDebugMetadataVersion = DEBUG_METADATA_VERSION;
1a4d82fc
JJ
224
225extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
226 const char *name,
227 uint32_t value) {
228 unwrap(M)->addModuleFlag(Module::Warning, name, value);
970d7e83
LB
229}
230
231extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
232 return new DIBuilder(*unwrap(M));
233}
234
235extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) {
236 delete Builder;
237}
238
239extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) {
240 Builder->finalize();
241}
242
85aaf69f 243extern "C" LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
970d7e83
LB
244 DIBuilderRef Builder,
245 unsigned Lang,
246 const char* File,
247 const char* Dir,
248 const char* Producer,
249 bool isOptimized,
250 const char* Flags,
251 unsigned RuntimeVer,
252 const char* SplitName) {
1a4d82fc
JJ
253 return wrap(Builder->createCompileUnit(Lang,
254 File,
255 Dir,
256 Producer,
257 isOptimized,
258 Flags,
259 RuntimeVer,
260 SplitName));
970d7e83
LB
261}
262
85aaf69f 263extern "C" LLVMMetadataRef LLVMDIBuilderCreateFile(
970d7e83
LB
264 DIBuilderRef Builder,
265 const char* Filename,
266 const char* Directory) {
267 return wrap(Builder->createFile(Filename, Directory));
268}
269
85aaf69f 270extern "C" LLVMMetadataRef LLVMDIBuilderCreateSubroutineType(
970d7e83 271 DIBuilderRef Builder,
85aaf69f
SL
272 LLVMMetadataRef File,
273 LLVMMetadataRef ParameterTypes) {
970d7e83 274 return wrap(Builder->createSubroutineType(
1a4d82fc
JJ
275 unwrapDI<DIFile>(File),
276#if LLVM_VERSION_MINOR >= 6
277 unwrapDI<DITypeArray>(ParameterTypes)));
278#else
970d7e83 279 unwrapDI<DIArray>(ParameterTypes)));
1a4d82fc 280#endif
970d7e83
LB
281}
282
85aaf69f 283extern "C" LLVMMetadataRef LLVMDIBuilderCreateFunction(
970d7e83 284 DIBuilderRef Builder,
85aaf69f 285 LLVMMetadataRef Scope,
970d7e83
LB
286 const char* Name,
287 const char* LinkageName,
85aaf69f 288 LLVMMetadataRef File,
970d7e83 289 unsigned LineNo,
85aaf69f 290 LLVMMetadataRef Ty,
970d7e83
LB
291 bool isLocalToUnit,
292 bool isDefinition,
293 unsigned ScopeLine,
294 unsigned Flags,
295 bool isOptimized,
296 LLVMValueRef Fn,
85aaf69f
SL
297 LLVMMetadataRef TParam,
298 LLVMMetadataRef Decl) {
970d7e83 299 return wrap(Builder->createFunction(
1a4d82fc
JJ
300 unwrapDI<DIScope>(Scope), Name, LinkageName,
301 unwrapDI<DIFile>(File), LineNo,
302 unwrapDI<DICompositeType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
970d7e83 303 Flags, isOptimized,
1a4d82fc 304 unwrap<Function>(Fn),
970d7e83
LB
305 unwrapDI<MDNode*>(TParam),
306 unwrapDI<MDNode*>(Decl)));
307}
308
85aaf69f 309extern "C" LLVMMetadataRef LLVMDIBuilderCreateBasicType(
970d7e83
LB
310 DIBuilderRef Builder,
311 const char* Name,
312 uint64_t SizeInBits,
313 uint64_t AlignInBits,
314 unsigned Encoding) {
315 return wrap(Builder->createBasicType(
1a4d82fc 316 Name, SizeInBits,
970d7e83
LB
317 AlignInBits, Encoding));
318}
1a4d82fc 319
85aaf69f 320extern "C" LLVMMetadataRef LLVMDIBuilderCreatePointerType(
970d7e83 321 DIBuilderRef Builder,
85aaf69f 322 LLVMMetadataRef PointeeTy,
970d7e83
LB
323 uint64_t SizeInBits,
324 uint64_t AlignInBits,
325 const char* Name) {
326 return wrap(Builder->createPointerType(
327 unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
328}
329
85aaf69f 330extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType(
970d7e83 331 DIBuilderRef Builder,
85aaf69f 332 LLVMMetadataRef Scope,
970d7e83 333 const char* Name,
85aaf69f 334 LLVMMetadataRef File,
970d7e83
LB
335 unsigned LineNumber,
336 uint64_t SizeInBits,
337 uint64_t AlignInBits,
338 unsigned Flags,
85aaf69f
SL
339 LLVMMetadataRef DerivedFrom,
340 LLVMMetadataRef Elements,
970d7e83 341 unsigned RunTimeLang,
85aaf69f 342 LLVMMetadataRef VTableHolder,
1a4d82fc 343 const char *UniqueId) {
970d7e83 344 return wrap(Builder->createStructType(
1a4d82fc
JJ
345 unwrapDI<DIDescriptor>(Scope),
346 Name,
347 unwrapDI<DIFile>(File),
348 LineNumber,
349 SizeInBits,
350 AlignInBits,
351 Flags,
352 unwrapDI<DIType>(DerivedFrom),
353 unwrapDI<DIArray>(Elements),
354 RunTimeLang,
c34b1796
AL
355 unwrapDI<DIType>(VTableHolder),
356 UniqueId
1a4d82fc 357 ));
970d7e83
LB
358}
359
85aaf69f 360extern "C" LLVMMetadataRef LLVMDIBuilderCreateMemberType(
970d7e83 361 DIBuilderRef Builder,
85aaf69f 362 LLVMMetadataRef Scope,
970d7e83 363 const char* Name,
85aaf69f 364 LLVMMetadataRef File,
970d7e83
LB
365 unsigned LineNo,
366 uint64_t SizeInBits,
367 uint64_t AlignInBits,
368 uint64_t OffsetInBits,
369 unsigned Flags,
85aaf69f 370 LLVMMetadataRef Ty) {
970d7e83 371 return wrap(Builder->createMemberType(
1a4d82fc 372 unwrapDI<DIDescriptor>(Scope), Name,
970d7e83 373 unwrapDI<DIFile>(File), LineNo,
1a4d82fc 374 SizeInBits, AlignInBits, OffsetInBits, Flags,
970d7e83
LB
375 unwrapDI<DIType>(Ty)));
376}
1a4d82fc 377
85aaf69f 378extern "C" LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(
970d7e83 379 DIBuilderRef Builder,
85aaf69f
SL
380 LLVMMetadataRef Scope,
381 LLVMMetadataRef File,
970d7e83
LB
382 unsigned Line,
383 unsigned Col) {
384 return wrap(Builder->createLexicalBlock(
1a4d82fc
JJ
385 unwrapDI<DIDescriptor>(Scope),
386 unwrapDI<DIFile>(File), Line, Col
387#if LLVM_VERSION_MINOR == 5
388 , 0
389#endif
390 ));
391}
392
85aaf69f 393extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable(
1a4d82fc 394 DIBuilderRef Builder,
85aaf69f 395 LLVMMetadataRef Context,
1a4d82fc
JJ
396 const char* Name,
397 const char* LinkageName,
85aaf69f 398 LLVMMetadataRef File,
1a4d82fc 399 unsigned LineNo,
85aaf69f 400 LLVMMetadataRef Ty,
1a4d82fc
JJ
401 bool isLocalToUnit,
402 LLVMValueRef Val,
85aaf69f 403 LLVMMetadataRef Decl = NULL) {
1a4d82fc
JJ
404#if LLVM_VERSION_MINOR == 6
405 return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context),
406#else
407 return wrap(Builder->createStaticVariable(unwrapDI<DIDescriptor>(Context),
408#endif
409 Name,
410 LinkageName,
411 unwrapDI<DIFile>(File),
412 LineNo,
413 unwrapDI<DIType>(Ty),
414 isLocalToUnit,
85aaf69f 415 cast<Constant>(unwrap(Val)),
1a4d82fc 416 unwrapDI<MDNode*>(Decl)));
970d7e83 417}
1a4d82fc 418
85aaf69f 419extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
970d7e83
LB
420 DIBuilderRef Builder,
421 unsigned Tag,
85aaf69f 422 LLVMMetadataRef Scope,
970d7e83 423 const char* Name,
85aaf69f 424 LLVMMetadataRef File,
970d7e83 425 unsigned LineNo,
85aaf69f 426 LLVMMetadataRef Ty,
970d7e83
LB
427 bool AlwaysPreserve,
428 unsigned Flags,
85aaf69f
SL
429 int64_t* AddrOps,
430 unsigned AddrOpsCount,
970d7e83 431 unsigned ArgNo) {
85aaf69f
SL
432#if LLVM_VERSION_MINOR < 6
433 if (AddrOpsCount > 0) {
434 SmallVector<llvm::Value *, 16> addr_ops;
c34b1796
AL
435 llvm::Type *Int64Ty = Type::getInt64Ty(unwrap<MDNode>(Scope)->getContext());
436 for (unsigned i = 0; i < AddrOpsCount; ++i)
85aaf69f
SL
437 addr_ops.push_back(ConstantInt::get(Int64Ty, AddrOps[i]));
438
439 return wrap(Builder->createComplexVariable(
440 Tag,
441 unwrapDI<DIDescriptor>(Scope),
442 Name,
443 unwrapDI<DIFile>(File),
444 LineNo,
445 unwrapDI<DIType>(Ty),
446 addr_ops,
447 ArgNo
448 ));
449 }
450#endif
1a4d82fc
JJ
451 return wrap(Builder->createLocalVariable(Tag,
452 unwrapDI<DIDescriptor>(Scope), Name,
453 unwrapDI<DIFile>(File),
454 LineNo,
970d7e83
LB
455 unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
456}
457
85aaf69f 458extern "C" LLVMMetadataRef LLVMDIBuilderCreateArrayType(
970d7e83 459 DIBuilderRef Builder,
1a4d82fc
JJ
460 uint64_t Size,
461 uint64_t AlignInBits,
85aaf69f
SL
462 LLVMMetadataRef Ty,
463 LLVMMetadataRef Subscripts) {
970d7e83 464 return wrap(Builder->createArrayType(Size, AlignInBits,
1a4d82fc 465 unwrapDI<DIType>(Ty),
970d7e83
LB
466 unwrapDI<DIArray>(Subscripts)));
467}
468
85aaf69f 469extern "C" LLVMMetadataRef LLVMDIBuilderCreateVectorType(
970d7e83 470 DIBuilderRef Builder,
1a4d82fc
JJ
471 uint64_t Size,
472 uint64_t AlignInBits,
85aaf69f
SL
473 LLVMMetadataRef Ty,
474 LLVMMetadataRef Subscripts) {
970d7e83 475 return wrap(Builder->createVectorType(Size, AlignInBits,
1a4d82fc 476 unwrapDI<DIType>(Ty),
970d7e83
LB
477 unwrapDI<DIArray>(Subscripts)));
478}
479
85aaf69f 480extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(
1a4d82fc
JJ
481 DIBuilderRef Builder,
482 int64_t Lo,
970d7e83
LB
483 int64_t Count) {
484 return wrap(Builder->getOrCreateSubrange(Lo, Count));
485}
486
85aaf69f 487extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(
970d7e83 488 DIBuilderRef Builder,
85aaf69f 489 LLVMMetadataRef* Ptr,
970d7e83
LB
490 unsigned Count) {
491 return wrap(Builder->getOrCreateArray(
c34b1796 492#if LLVM_VERSION_MINOR >= 6
85aaf69f 493 ArrayRef<Metadata*>(unwrap(Ptr), Count)));
c34b1796
AL
494#else
495 ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
496#endif
970d7e83
LB
497}
498
499extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
500 DIBuilderRef Builder,
501 LLVMValueRef Val,
85aaf69f
SL
502 LLVMMetadataRef VarInfo,
503 int64_t* AddrOps,
504 unsigned AddrOpsCount,
970d7e83 505 LLVMBasicBlockRef InsertAtEnd) {
85aaf69f
SL
506#if LLVM_VERSION_MINOR >= 6
507 DIExpression Expr;
508 if (AddrOpsCount == 0) {
509 Expr = Builder->createExpression();
510 } else {
511 llvm::ArrayRef<int64_t> addr_ops(AddrOps, AddrOpsCount);
512 Expr = Builder->createExpression(addr_ops);
513 }
514#endif
970d7e83 515 return wrap(Builder->insertDeclare(
1a4d82fc
JJ
516 unwrap(Val),
517 unwrapDI<DIVariable>(VarInfo),
85aaf69f
SL
518#if LLVM_VERSION_MINOR >= 6
519 Expr,
520#endif
970d7e83
LB
521 unwrap(InsertAtEnd)));
522}
523
524extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
525 DIBuilderRef Builder,
526 LLVMValueRef Val,
85aaf69f
SL
527 LLVMMetadataRef VarInfo,
528 int64_t* AddrOps,
529 unsigned AddrOpsCount,
970d7e83 530 LLVMValueRef InsertBefore) {
85aaf69f
SL
531#if LLVM_VERSION_MINOR >= 6
532 DIExpression Expr;
533 if (AddrOpsCount == 0) {
534 Expr = Builder->createExpression();
535 } else {
536 llvm::ArrayRef<int64_t> addr_ops(AddrOps, AddrOpsCount);
537 Expr = Builder->createExpression(addr_ops);
538 }
539#endif
970d7e83 540 return wrap(Builder->insertDeclare(
1a4d82fc
JJ
541 unwrap(Val),
542 unwrapDI<DIVariable>(VarInfo),
85aaf69f
SL
543#if LLVM_VERSION_MINOR >= 6
544 Expr,
545#endif
970d7e83
LB
546 unwrap<Instruction>(InsertBefore)));
547}
1a4d82fc 548
85aaf69f 549extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerator(
1a4d82fc
JJ
550 DIBuilderRef Builder,
551 const char* Name,
552 uint64_t Val)
553{
554 return wrap(Builder->createEnumerator(Name, Val));
555}
556
85aaf69f 557extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
1a4d82fc 558 DIBuilderRef Builder,
85aaf69f 559 LLVMMetadataRef Scope,
1a4d82fc 560 const char* Name,
85aaf69f 561 LLVMMetadataRef File,
1a4d82fc
JJ
562 unsigned LineNumber,
563 uint64_t SizeInBits,
564 uint64_t AlignInBits,
85aaf69f
SL
565 LLVMMetadataRef Elements,
566 LLVMMetadataRef ClassType)
1a4d82fc
JJ
567{
568 return wrap(Builder->createEnumerationType(
569 unwrapDI<DIDescriptor>(Scope),
570 Name,
571 unwrapDI<DIFile>(File),
572 LineNumber,
573 SizeInBits,
574 AlignInBits,
575 unwrapDI<DIArray>(Elements),
576 unwrapDI<DIType>(ClassType)));
577}
578
85aaf69f 579extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType(
1a4d82fc 580 DIBuilderRef Builder,
85aaf69f 581 LLVMMetadataRef Scope,
1a4d82fc 582 const char* Name,
85aaf69f 583 LLVMMetadataRef File,
1a4d82fc
JJ
584 unsigned LineNumber,
585 uint64_t SizeInBits,
586 uint64_t AlignInBits,
587 unsigned Flags,
85aaf69f 588 LLVMMetadataRef Elements,
1a4d82fc
JJ
589 unsigned RunTimeLang,
590 const char* UniqueId)
591{
592 return wrap(Builder->createUnionType(
593 unwrapDI<DIDescriptor>(Scope),
594 Name,
595 unwrapDI<DIFile>(File),
596 LineNumber,
597 SizeInBits,
598 AlignInBits,
599 Flags,
600 unwrapDI<DIArray>(Elements),
c34b1796
AL
601 RunTimeLang,
602 UniqueId
1a4d82fc
JJ
603 ));
604}
605
85aaf69f 606extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter(
1a4d82fc 607 DIBuilderRef Builder,
85aaf69f 608 LLVMMetadataRef Scope,
1a4d82fc 609 const char* Name,
85aaf69f
SL
610 LLVMMetadataRef Ty,
611 LLVMMetadataRef File,
1a4d82fc
JJ
612 unsigned LineNo,
613 unsigned ColumnNo)
614{
615 return wrap(Builder->createTemplateTypeParameter(
616 unwrapDI<DIDescriptor>(Scope),
617 Name,
618 unwrapDI<DIType>(Ty),
619 unwrapDI<MDNode*>(File),
620 LineNo,
621 ColumnNo));
622}
623
85aaf69f 624extern "C" int64_t LLVMDIBuilderCreateOpDeref()
1a4d82fc 625{
85aaf69f 626 return dwarf::DW_OP_deref;
1a4d82fc
JJ
627}
628
85aaf69f 629extern "C" int64_t LLVMDIBuilderCreateOpPlus()
1a4d82fc 630{
85aaf69f 631 return dwarf::DW_OP_plus;
1a4d82fc
JJ
632}
633
85aaf69f 634extern "C" LLVMMetadataRef LLVMDIBuilderCreateNameSpace(
1a4d82fc 635 DIBuilderRef Builder,
85aaf69f 636 LLVMMetadataRef Scope,
1a4d82fc 637 const char* Name,
85aaf69f 638 LLVMMetadataRef File,
1a4d82fc
JJ
639 unsigned LineNo)
640{
641 return wrap(Builder->createNameSpace(
642 unwrapDI<DIDescriptor>(Scope),
643 Name,
644 unwrapDI<DIFile>(File),
645 LineNo));
646}
647
648extern "C" void LLVMDICompositeTypeSetTypeArray(
85aaf69f
SL
649 DIBuilderRef Builder,
650 LLVMMetadataRef CompositeType,
651 LLVMMetadataRef TypeArray)
1a4d82fc
JJ
652{
653#if LLVM_VERSION_MINOR >= 6
85aaf69f
SL
654 DICompositeType tmp = unwrapDI<DICompositeType>(CompositeType);
655 Builder->replaceArrays(tmp, unwrapDI<DIArray>(TypeArray));
1a4d82fc
JJ
656#else
657 unwrapDI<DICompositeType>(CompositeType).setTypeArray(unwrapDI<DIArray>(TypeArray));
658#endif
659}
660
85aaf69f
SL
661extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation(
662 LLVMContextRef Context,
663 unsigned Line,
664 unsigned Column,
665 LLVMMetadataRef Scope,
666 LLVMMetadataRef InlinedAt) {
667
668 LLVMContext& context = *unwrap(Context);
669
670 DebugLoc debug_loc = DebugLoc::get(Line,
671 Column,
672 unwrapDI<MDNode*>(Scope),
673 unwrapDI<MDNode*>(InlinedAt));
674
675#if LLVM_VERSION_MINOR >= 6
676 return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode(context)));
677#else
678 return wrap(debug_loc.getAsMDNode(context));
679#endif
680}
681
1a4d82fc
JJ
682extern "C" void LLVMWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
683 raw_rust_string_ostream os(str);
684 unwrap<llvm::Type>(Type)->print(os);
685}
686
687extern "C" void LLVMWriteValueToString(LLVMValueRef Value, RustStringRef str) {
688 raw_rust_string_ostream os(str);
689 os << "(";
690 unwrap<llvm::Value>(Value)->getType()->print(os);
691 os << ":";
692 unwrap<llvm::Value>(Value)->print(os);
693 os << ")";
694}
695
1a4d82fc
JJ
696extern "C" bool
697LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
698 Module *Dst = unwrap(dst);
699#if LLVM_VERSION_MINOR == 5
700 MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
701 ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
702#else
703 std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
704 ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
705#endif
706 if (!Src) {
707 LLVMRustSetLastError(Src.getError().message().c_str());
708#if LLVM_VERSION_MINOR == 5
709 delete buf;
710#endif
711 return false;
712 }
713
714 std::string Err;
85aaf69f
SL
715
716#if LLVM_VERSION_MINOR >= 6
717 raw_string_ostream Stream(Err);
718 DiagnosticPrinterRawOStream DP(Stream);
719 if (Linker::LinkModules(Dst, *Src, [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
720#else
1a4d82fc 721 if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
85aaf69f 722#endif
1a4d82fc
JJ
723 LLVMRustSetLastError(Err.c_str());
724 return false;
725 }
726 return true;
727}
1a4d82fc 728
1a4d82fc
JJ
729extern "C" void*
730LLVMRustOpenArchive(char *path) {
731 ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path,
732 -1,
733 false);
734 if (!buf_or) {
735 LLVMRustSetLastError(buf_or.getError().message().c_str());
736 return nullptr;
737 }
738
739#if LLVM_VERSION_MINOR >= 6
740 ErrorOr<std::unique_ptr<Archive>> archive_or =
741 Archive::create(buf_or.get()->getMemBufferRef());
742
743 if (!archive_or) {
744 LLVMRustSetLastError(archive_or.getError().message().c_str());
745 return nullptr;
746 }
747
748 OwningBinary<Archive> *ret = new OwningBinary<Archive>(
749 std::move(archive_or.get()), std::move(buf_or.get()));
750#else
751 std::error_code err;
752 Archive *ret = new Archive(std::move(buf_or.get()), err);
753 if (err) {
754 LLVMRustSetLastError(err.message().c_str());
755 return nullptr;
756 }
757#endif
758
759 return ret;
760}
1a4d82fc
JJ
761
762extern "C" const char*
763#if LLVM_VERSION_MINOR >= 6
764LLVMRustArchiveReadSection(OwningBinary<Archive> *ob, char *name, size_t *size) {
765
85aaf69f 766 Archive *ar = ob->getBinary();
1a4d82fc
JJ
767#else
768LLVMRustArchiveReadSection(Archive *ar, char *name, size_t *size) {
769#endif
770
1a4d82fc
JJ
771 Archive::child_iterator child = ar->child_begin(),
772 end = ar->child_end();
773 for (; child != end; ++child) {
774 ErrorOr<StringRef> name_or_err = child->getName();
775 if (name_or_err.getError()) continue;
776 StringRef sect_name = name_or_err.get();
1a4d82fc
JJ
777 if (sect_name.trim(" ") == name) {
778 StringRef buf = child->getBuffer();
779 *size = buf.size();
780 return buf.data();
781 }
782 }
783 return NULL;
784}
785
786extern "C" void
787#if LLVM_VERSION_MINOR >= 6
788LLVMRustDestroyArchive(OwningBinary<Archive> *ar) {
789#else
790LLVMRustDestroyArchive(Archive *ar) {
791#endif
792 delete ar;
793}
794
1a4d82fc
JJ
795extern "C" void
796LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
797 GlobalValue *V = unwrap<GlobalValue>(Value);
798 V->setDLLStorageClass(GlobalValue::DLLExportStorageClass);
799}
1a4d82fc
JJ
800
801extern "C" int
802LLVMVersionMinor() {
803 return LLVM_VERSION_MINOR;
804}
805
806extern "C" int
807LLVMVersionMajor() {
808 return LLVM_VERSION_MAJOR;
809}
810
811// Note that the two following functions look quite similar to the
812// LLVMGetSectionName function. Sadly, it appears that this function only
813// returns a char* pointer, which isn't guaranteed to be null-terminated. The
814// function provided by LLVM doesn't return the length, so we've created our own
815// function which returns the length as well as the data pointer.
816//
817// For an example of this not returning a null terminated string, see
818// lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
819// branches explicitly creates a StringRef without a null terminator, and then
820// that's returned.
821
822inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
823 return reinterpret_cast<section_iterator*>(SI);
824}
825
826extern "C" int
827LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
828 StringRef ret;
1a4d82fc 829 if (std::error_code ec = (*unwrap(SI))->getName(ret))
1a4d82fc
JJ
830 report_fatal_error(ec.message());
831 *ptr = ret.data();
832 return ret.size();
833}
834
835// LLVMArrayType function does not support 64-bit ElementCount
836extern "C" LLVMTypeRef
837LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {
838 return wrap(ArrayType::get(unwrap(ElementType), ElementCount));
839}
840
841DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
842DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
843
844extern "C" void
845LLVMWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
846 raw_rust_string_ostream os(str);
847 unwrap(T)->print(os);
848}
849
850extern "C" void
851LLVMUnpackOptimizationDiagnostic(
852 LLVMDiagnosticInfoRef di,
853 const char **pass_name_out,
854 LLVMValueRef *function_out,
855 LLVMDebugLocRef *debugloc_out,
856 LLVMTwineRef *message_out)
857{
858 // Undefined to call this not on an optimization diagnostic!
859 llvm::DiagnosticInfoOptimizationBase *opt
860 = static_cast<llvm::DiagnosticInfoOptimizationBase*>(unwrap(di));
861
862 *pass_name_out = opt->getPassName();
863 *function_out = wrap(&opt->getFunction());
864 *debugloc_out = wrap(&opt->getDebugLoc());
865 *message_out = wrap(&opt->getMsg());
866}
867
85aaf69f
SL
868extern "C" void
869LLVMUnpackInlineAsmDiagnostic(
870 LLVMDiagnosticInfoRef di,
871 unsigned *cookie_out,
872 LLVMTwineRef *message_out,
873 LLVMValueRef *instruction_out)
874{
875 // Undefined to call this not on an inline assembly diagnostic!
876 llvm::DiagnosticInfoInlineAsm *ia
877 = static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di));
878
879 *cookie_out = ia->getLocCookie();
880 *message_out = wrap(&ia->getMsgStr());
881 *instruction_out = wrap(ia->getInstruction());
882}
883
1a4d82fc
JJ
884extern "C" void LLVMWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
885 raw_rust_string_ostream os(str);
886 DiagnosticPrinterRawOStream dp(os);
887 unwrap(di)->print(dp);
888}
889
890extern "C" int LLVMGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
891 return unwrap(di)->getKind();
892}
893
894extern "C" void LLVMWriteDebugLocToString(
895 LLVMContextRef C,
896 LLVMDebugLocRef dl,
897 RustStringRef str)
898{
899 raw_rust_string_ostream os(str);
900 unwrap(dl)->print(*unwrap(C), os);
901}
902
903DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
904
905extern "C" void LLVMSetInlineAsmDiagnosticHandler(
906 LLVMContextRef C,
907 LLVMContext::InlineAsmDiagHandlerTy H,
908 void *CX)
909{
910 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
911}
912
913extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, RustStringRef str) {
914 raw_rust_string_ostream os(str);
915 unwrap(d)->print("", os);
916}