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