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