]> git.proxmox.com Git - rustc.git/blob - src/rustllvm/RustWrapper.cpp
Imported Upstream version 1.3.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,
124 uint64_t Val) {
125 Function *A = unwrap<Function>(Fn);
126 AttrBuilder B;
127 B.addRawValue(Val);
128 A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
129 }
130
131 extern "C" void LLVMAddDereferenceableAttr(LLVMValueRef Fn, unsigned index, uint64_t bytes) {
132 Function *A = unwrap<Function>(Fn);
133 AttrBuilder B;
134 B.addDereferenceableAttr(bytes);
135 A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
136 }
137
138 extern "C" void LLVMAddFunctionAttrString(LLVMValueRef Fn, unsigned index, const char *Name) {
139 Function *F = unwrap<Function>(Fn);
140 AttrBuilder B;
141 B.addAttribute(Name);
142 F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
143 }
144
145 extern "C" void LLVMAddFunctionAttrStringValue(LLVMValueRef Fn, unsigned index,
146 const char *Name,
147 const char *Value) {
148 Function *F = unwrap<Function>(Fn);
149 AttrBuilder B;
150 B.addAttribute(Name, Value);
151 F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
152 }
153
154 extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, unsigned index, const char *Name) {
155 Function *f = unwrap<Function>(fn);
156 LLVMContext &C = f->getContext();
157 AttrBuilder B;
158 B.addAttribute(Name);
159 AttributeSet to_remove = AttributeSet::get(C, index, B);
160
161 AttributeSet attrs = f->getAttributes();
162 f->setAttributes(attrs.removeAttributes(f->getContext(),
163 index,
164 to_remove));
165 }
166
167 extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
168 LLVMValueRef source,
169 const char* Name,
170 AtomicOrdering order,
171 unsigned alignment) {
172 LoadInst* li = new LoadInst(unwrap(source),0);
173 li->setVolatile(true);
174 li->setAtomic(order);
175 li->setAlignment(alignment);
176 return wrap(unwrap(B)->Insert(li, Name));
177 }
178
179 extern "C" LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef B,
180 LLVMValueRef val,
181 LLVMValueRef target,
182 AtomicOrdering order,
183 unsigned alignment) {
184 StoreInst* si = new StoreInst(unwrap(val),unwrap(target));
185 si->setVolatile(true);
186 si->setAtomic(order);
187 si->setAlignment(alignment);
188 return wrap(unwrap(B)->Insert(si));
189 }
190
191 extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
192 LLVMValueRef target,
193 LLVMValueRef old,
194 LLVMValueRef source,
195 AtomicOrdering order,
196 AtomicOrdering failure_order) {
197 return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
198 unwrap(source), order,
199 failure_order
200 ));
201 }
202 extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B,
203 AtomicOrdering order,
204 SynchronizationScope scope) {
205 return wrap(unwrap(B)->CreateFence(order, scope));
206 }
207
208 extern "C" void LLVMSetDebug(int Enabled) {
209 #ifndef NDEBUG
210 DebugFlag = Enabled;
211 #endif
212 }
213
214 extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty,
215 char *AsmString,
216 char *Constraints,
217 LLVMBool HasSideEffects,
218 LLVMBool IsAlignStack,
219 unsigned Dialect) {
220 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
221 Constraints, HasSideEffects,
222 IsAlignStack, (InlineAsm::AsmDialect) Dialect));
223 }
224
225 typedef DIBuilder* DIBuilderRef;
226
227 #if LLVM_VERSION_MINOR >= 6
228 typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
229
230 namespace llvm {
231 DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef)
232
233 inline Metadata **unwrap(LLVMMetadataRef *Vals) {
234 return reinterpret_cast<Metadata**>(Vals);
235 }
236 }
237 #else
238 typedef LLVMValueRef LLVMMetadataRef;
239 #endif
240
241 template<typename DIT>
242 DIT* unwrapDIptr(LLVMMetadataRef ref) {
243 return (DIT*) (ref ? unwrap<MDNode>(ref) : NULL);
244 }
245
246 #if LLVM_VERSION_MINOR <= 6
247 template<typename DIT>
248 DIT unwrapDI(LLVMMetadataRef ref) {
249 return DIT(ref ? unwrap<MDNode>(ref) : NULL);
250 }
251 #else
252 #define DIDescriptor DIScope
253 #define DIArray DINodeArray
254 #define unwrapDI unwrapDIptr
255 #endif
256
257 #if LLVM_VERSION_MINOR <= 5
258 #define DISubroutineType DICompositeType
259 #endif
260
261 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
262 return DEBUG_METADATA_VERSION;
263 }
264
265 extern "C" uint32_t LLVMVersionMinor() {
266 return LLVM_VERSION_MINOR;
267 }
268
269 extern "C" uint32_t LLVMVersionMajor() {
270 return LLVM_VERSION_MAJOR;
271 }
272
273 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
274 const char *name,
275 uint32_t value) {
276 unwrap(M)->addModuleFlag(Module::Warning, name, value);
277 }
278
279 extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
280 return new DIBuilder(*unwrap(M));
281 }
282
283 extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) {
284 delete Builder;
285 }
286
287 extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) {
288 Builder->finalize();
289 }
290
291 extern "C" LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
292 DIBuilderRef Builder,
293 unsigned Lang,
294 const char* File,
295 const char* Dir,
296 const char* Producer,
297 bool isOptimized,
298 const char* Flags,
299 unsigned RuntimeVer,
300 const char* SplitName) {
301 return wrap(Builder->createCompileUnit(Lang,
302 File,
303 Dir,
304 Producer,
305 isOptimized,
306 Flags,
307 RuntimeVer,
308 SplitName));
309 }
310
311 extern "C" LLVMMetadataRef LLVMDIBuilderCreateFile(
312 DIBuilderRef Builder,
313 const char* Filename,
314 const char* Directory) {
315 return wrap(Builder->createFile(Filename, Directory));
316 }
317
318 extern "C" LLVMMetadataRef LLVMDIBuilderCreateSubroutineType(
319 DIBuilderRef Builder,
320 LLVMMetadataRef File,
321 LLVMMetadataRef ParameterTypes) {
322 return wrap(Builder->createSubroutineType(
323 unwrapDI<DIFile>(File),
324 #if LLVM_VERSION_MINOR >= 7
325 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
326 #elif LLVM_VERSION_MINOR >= 6
327 unwrapDI<DITypeArray>(ParameterTypes)));
328 #else
329 unwrapDI<DIArray>(ParameterTypes)));
330 #endif
331 }
332
333 extern "C" LLVMMetadataRef LLVMDIBuilderCreateFunction(
334 DIBuilderRef Builder,
335 LLVMMetadataRef Scope,
336 const char* Name,
337 const char* LinkageName,
338 LLVMMetadataRef File,
339 unsigned LineNo,
340 LLVMMetadataRef Ty,
341 bool isLocalToUnit,
342 bool isDefinition,
343 unsigned ScopeLine,
344 unsigned Flags,
345 bool isOptimized,
346 LLVMValueRef Fn,
347 LLVMMetadataRef TParam,
348 LLVMMetadataRef Decl) {
349 return wrap(Builder->createFunction(
350 unwrapDI<DIScope>(Scope), Name, LinkageName,
351 unwrapDI<DIFile>(File), LineNo,
352 unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
353 Flags, isOptimized,
354 unwrap<Function>(Fn),
355 unwrapDIptr<MDNode>(TParam),
356 unwrapDIptr<MDNode>(Decl)));
357 }
358
359 extern "C" LLVMMetadataRef LLVMDIBuilderCreateBasicType(
360 DIBuilderRef Builder,
361 const char* Name,
362 uint64_t SizeInBits,
363 uint64_t AlignInBits,
364 unsigned Encoding) {
365 return wrap(Builder->createBasicType(
366 Name, SizeInBits,
367 AlignInBits, Encoding));
368 }
369
370 extern "C" LLVMMetadataRef LLVMDIBuilderCreatePointerType(
371 DIBuilderRef Builder,
372 LLVMMetadataRef PointeeTy,
373 uint64_t SizeInBits,
374 uint64_t AlignInBits,
375 const char* Name) {
376 return wrap(Builder->createPointerType(
377 unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
378 }
379
380 extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType(
381 DIBuilderRef Builder,
382 LLVMMetadataRef Scope,
383 const char* Name,
384 LLVMMetadataRef File,
385 unsigned LineNumber,
386 uint64_t SizeInBits,
387 uint64_t AlignInBits,
388 unsigned Flags,
389 LLVMMetadataRef DerivedFrom,
390 LLVMMetadataRef Elements,
391 unsigned RunTimeLang,
392 LLVMMetadataRef VTableHolder,
393 const char *UniqueId) {
394 return wrap(Builder->createStructType(
395 unwrapDI<DIDescriptor>(Scope),
396 Name,
397 unwrapDI<DIFile>(File),
398 LineNumber,
399 SizeInBits,
400 AlignInBits,
401 Flags,
402 unwrapDI<DIType>(DerivedFrom),
403 #if LLVM_VERSION_MINOR >= 7
404 DINodeArray(unwrapDI<MDTuple>(Elements)),
405 #else
406 unwrapDI<DIArray>(Elements),
407 #endif
408 RunTimeLang,
409 unwrapDI<DIType>(VTableHolder),
410 UniqueId
411 ));
412 }
413
414 extern "C" LLVMMetadataRef LLVMDIBuilderCreateMemberType(
415 DIBuilderRef Builder,
416 LLVMMetadataRef Scope,
417 const char* Name,
418 LLVMMetadataRef File,
419 unsigned LineNo,
420 uint64_t SizeInBits,
421 uint64_t AlignInBits,
422 uint64_t OffsetInBits,
423 unsigned Flags,
424 LLVMMetadataRef Ty) {
425 return wrap(Builder->createMemberType(
426 unwrapDI<DIDescriptor>(Scope), Name,
427 unwrapDI<DIFile>(File), LineNo,
428 SizeInBits, AlignInBits, OffsetInBits, Flags,
429 unwrapDI<DIType>(Ty)));
430 }
431
432 extern "C" LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(
433 DIBuilderRef Builder,
434 LLVMMetadataRef Scope,
435 LLVMMetadataRef File,
436 unsigned Line,
437 unsigned Col) {
438 return wrap(Builder->createLexicalBlock(
439 unwrapDI<DIDescriptor>(Scope),
440 unwrapDI<DIFile>(File), Line, Col
441 #if LLVM_VERSION_MINOR == 5
442 , 0
443 #endif
444 ));
445 }
446
447 extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable(
448 DIBuilderRef Builder,
449 LLVMMetadataRef Context,
450 const char* Name,
451 const char* LinkageName,
452 LLVMMetadataRef File,
453 unsigned LineNo,
454 LLVMMetadataRef Ty,
455 bool isLocalToUnit,
456 LLVMValueRef Val,
457 LLVMMetadataRef Decl = NULL) {
458 #if LLVM_VERSION_MINOR >= 6
459 return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context),
460 #else
461 return wrap(Builder->createStaticVariable(unwrapDI<DIDescriptor>(Context),
462 #endif
463 Name,
464 LinkageName,
465 unwrapDI<DIFile>(File),
466 LineNo,
467 unwrapDI<DIType>(Ty),
468 isLocalToUnit,
469 cast<Constant>(unwrap(Val)),
470 unwrapDIptr<MDNode>(Decl)));
471 }
472
473 extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
474 DIBuilderRef Builder,
475 unsigned Tag,
476 LLVMMetadataRef Scope,
477 const char* Name,
478 LLVMMetadataRef File,
479 unsigned LineNo,
480 LLVMMetadataRef Ty,
481 bool AlwaysPreserve,
482 unsigned Flags,
483 int64_t* AddrOps,
484 unsigned AddrOpsCount,
485 unsigned ArgNo) {
486 #if LLVM_VERSION_MINOR == 5
487 if (AddrOpsCount > 0) {
488 SmallVector<llvm::Value *, 16> addr_ops;
489 llvm::Type *Int64Ty = Type::getInt64Ty(unwrap<MDNode>(Scope)->getContext());
490 for (unsigned i = 0; i < AddrOpsCount; ++i)
491 addr_ops.push_back(ConstantInt::get(Int64Ty, AddrOps[i]));
492
493 return wrap(Builder->createComplexVariable(
494 Tag,
495 unwrapDI<DIDescriptor>(Scope),
496 Name,
497 unwrapDI<DIFile>(File),
498 LineNo,
499 unwrapDI<DIType>(Ty),
500 addr_ops,
501 ArgNo
502 ));
503 }
504 #endif
505 return wrap(Builder->createLocalVariable(Tag,
506 unwrapDI<DIDescriptor>(Scope), Name,
507 unwrapDI<DIFile>(File),
508 LineNo,
509 unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
510 }
511
512 extern "C" LLVMMetadataRef LLVMDIBuilderCreateArrayType(
513 DIBuilderRef Builder,
514 uint64_t Size,
515 uint64_t AlignInBits,
516 LLVMMetadataRef Ty,
517 LLVMMetadataRef Subscripts) {
518 return wrap(Builder->createArrayType(Size, AlignInBits,
519 unwrapDI<DIType>(Ty),
520 #if LLVM_VERSION_MINOR >= 7
521 DINodeArray(unwrapDI<MDTuple>(Subscripts))
522 #else
523 unwrapDI<DIArray>(Subscripts)
524 #endif
525 ));
526 }
527
528 extern "C" LLVMMetadataRef LLVMDIBuilderCreateVectorType(
529 DIBuilderRef Builder,
530 uint64_t Size,
531 uint64_t AlignInBits,
532 LLVMMetadataRef Ty,
533 LLVMMetadataRef Subscripts) {
534 return wrap(Builder->createVectorType(Size, AlignInBits,
535 unwrapDI<DIType>(Ty),
536 #if LLVM_VERSION_MINOR >= 7
537 DINodeArray(unwrapDI<MDTuple>(Subscripts))
538 #else
539 unwrapDI<DIArray>(Subscripts)
540 #endif
541 ));
542 }
543
544 extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(
545 DIBuilderRef Builder,
546 int64_t Lo,
547 int64_t Count) {
548 return wrap(Builder->getOrCreateSubrange(Lo, Count));
549 }
550
551 extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(
552 DIBuilderRef Builder,
553 LLVMMetadataRef* Ptr,
554 unsigned Count) {
555 #if LLVM_VERSION_MINOR >= 7
556 Metadata **DataValue = unwrap(Ptr);
557 return wrap(Builder->getOrCreateArray(
558 ArrayRef<Metadata*>(DataValue, Count)).get());
559 #else
560 return wrap(Builder->getOrCreateArray(
561 #if LLVM_VERSION_MINOR >= 6
562 ArrayRef<Metadata*>(unwrap(Ptr), Count)));
563 #else
564 ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
565 #endif
566 #endif
567 }
568
569 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
570 DIBuilderRef Builder,
571 LLVMValueRef Val,
572 LLVMMetadataRef VarInfo,
573 int64_t* AddrOps,
574 unsigned AddrOpsCount,
575 LLVMValueRef DL,
576 LLVMBasicBlockRef InsertAtEnd) {
577 return wrap(Builder->insertDeclare(
578 unwrap(Val),
579 #if LLVM_VERSION_MINOR >= 7
580 unwrap<DILocalVariable>(VarInfo),
581 #else
582 unwrapDI<DIVariable>(VarInfo),
583 #endif
584 #if LLVM_VERSION_MINOR >= 6
585 Builder->createExpression(
586 llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
587 #endif
588 #if LLVM_VERSION_MINOR >= 7
589 DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
590 #endif
591 unwrap(InsertAtEnd)));
592 }
593
594 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
595 DIBuilderRef Builder,
596 LLVMValueRef Val,
597 LLVMMetadataRef VarInfo,
598 int64_t* AddrOps,
599 unsigned AddrOpsCount,
600 LLVMValueRef DL,
601 LLVMValueRef InsertBefore) {
602 #if LLVM_VERSION_MINOR >= 6
603 #endif
604 return wrap(Builder->insertDeclare(
605 unwrap(Val),
606 #if LLVM_VERSION_MINOR >= 7
607 unwrap<DILocalVariable>(VarInfo),
608 #else
609 unwrapDI<DIVariable>(VarInfo),
610 #endif
611 #if LLVM_VERSION_MINOR >= 6
612 Builder->createExpression(
613 llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
614 #endif
615 #if LLVM_VERSION_MINOR >= 7
616 DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
617 #endif
618 unwrap<Instruction>(InsertBefore)));
619 }
620
621 extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerator(
622 DIBuilderRef Builder,
623 const char* Name,
624 uint64_t Val)
625 {
626 return wrap(Builder->createEnumerator(Name, Val));
627 }
628
629 extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
630 DIBuilderRef Builder,
631 LLVMMetadataRef Scope,
632 const char* Name,
633 LLVMMetadataRef File,
634 unsigned LineNumber,
635 uint64_t SizeInBits,
636 uint64_t AlignInBits,
637 LLVMMetadataRef Elements,
638 LLVMMetadataRef ClassType)
639 {
640 return wrap(Builder->createEnumerationType(
641 unwrapDI<DIDescriptor>(Scope),
642 Name,
643 unwrapDI<DIFile>(File),
644 LineNumber,
645 SizeInBits,
646 AlignInBits,
647 #if LLVM_VERSION_MINOR >= 7
648 DINodeArray(unwrapDI<MDTuple>(Elements)),
649 #else
650 unwrapDI<DIArray>(Elements),
651 #endif
652 unwrapDI<DIType>(ClassType)));
653 }
654
655 extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType(
656 DIBuilderRef Builder,
657 LLVMMetadataRef Scope,
658 const char* Name,
659 LLVMMetadataRef File,
660 unsigned LineNumber,
661 uint64_t SizeInBits,
662 uint64_t AlignInBits,
663 unsigned Flags,
664 LLVMMetadataRef Elements,
665 unsigned RunTimeLang,
666 const char* UniqueId)
667 {
668 return wrap(Builder->createUnionType(
669 unwrapDI<DIDescriptor>(Scope),
670 Name,
671 unwrapDI<DIFile>(File),
672 LineNumber,
673 SizeInBits,
674 AlignInBits,
675 Flags,
676 #if LLVM_VERSION_MINOR >= 7
677 DINodeArray(unwrapDI<MDTuple>(Elements)),
678 #else
679 unwrapDI<DIArray>(Elements),
680 #endif
681 RunTimeLang,
682 UniqueId
683 ));
684 }
685
686 extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter(
687 DIBuilderRef Builder,
688 LLVMMetadataRef Scope,
689 const char* Name,
690 LLVMMetadataRef Ty,
691 LLVMMetadataRef File,
692 unsigned LineNo,
693 unsigned ColumnNo)
694 {
695 return wrap(Builder->createTemplateTypeParameter(
696 unwrapDI<DIDescriptor>(Scope),
697 Name,
698 unwrapDI<DIType>(Ty)
699 #if LLVM_VERSION_MINOR <= 6
700 ,
701 unwrapDI<MDNode*>(File),
702 LineNo,
703 ColumnNo
704 #endif
705 ));
706 }
707
708 extern "C" int64_t LLVMDIBuilderCreateOpDeref()
709 {
710 return dwarf::DW_OP_deref;
711 }
712
713 extern "C" int64_t LLVMDIBuilderCreateOpPlus()
714 {
715 return dwarf::DW_OP_plus;
716 }
717
718 extern "C" LLVMMetadataRef LLVMDIBuilderCreateNameSpace(
719 DIBuilderRef Builder,
720 LLVMMetadataRef Scope,
721 const char* Name,
722 LLVMMetadataRef File,
723 unsigned LineNo)
724 {
725 return wrap(Builder->createNameSpace(
726 unwrapDI<DIDescriptor>(Scope),
727 Name,
728 unwrapDI<DIFile>(File),
729 LineNo));
730 }
731
732 extern "C" void LLVMDICompositeTypeSetTypeArray(
733 DIBuilderRef Builder,
734 LLVMMetadataRef CompositeType,
735 LLVMMetadataRef TypeArray)
736 {
737 #if LLVM_VERSION_MINOR >= 7
738 DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType);
739 Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray)));
740 #elif LLVM_VERSION_MINOR >= 6
741 DICompositeType tmp = unwrapDI<DICompositeType>(CompositeType);
742 Builder->replaceArrays(tmp, unwrapDI<DIArray>(TypeArray));
743 #else
744 unwrapDI<DICompositeType>(CompositeType).setTypeArray(unwrapDI<DIArray>(TypeArray));
745 #endif
746 }
747
748 extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation(
749 LLVMContextRef Context,
750 unsigned Line,
751 unsigned Column,
752 LLVMMetadataRef Scope,
753 LLVMMetadataRef InlinedAt) {
754
755 LLVMContext& context = *unwrap(Context);
756
757 DebugLoc debug_loc = DebugLoc::get(Line,
758 Column,
759 unwrapDIptr<MDNode>(Scope),
760 unwrapDIptr<MDNode>(InlinedAt));
761
762 #if LLVM_VERSION_MINOR >= 6
763 return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode(
764 #if LLVM_VERSION_MINOR <= 6
765 context
766 #endif
767 )));
768 #else
769 return wrap(debug_loc.getAsMDNode(context));
770 #endif
771 }
772
773 extern "C" void LLVMWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
774 raw_rust_string_ostream os(str);
775 unwrap<llvm::Type>(Type)->print(os);
776 }
777
778 extern "C" void LLVMWriteValueToString(LLVMValueRef Value, RustStringRef str) {
779 raw_rust_string_ostream os(str);
780 os << "(";
781 unwrap<llvm::Value>(Value)->getType()->print(os);
782 os << ":";
783 unwrap<llvm::Value>(Value)->print(os);
784 os << ")";
785 }
786
787 extern "C" bool
788 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
789 Module *Dst = unwrap(dst);
790 #if LLVM_VERSION_MINOR >= 6
791 std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
792 #if LLVM_VERSION_MINOR >= 7
793 ErrorOr<std::unique_ptr<Module>> Src =
794 llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
795 #else
796 ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
797 #endif
798 #else
799 MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
800 ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
801 #endif
802 if (!Src) {
803 LLVMRustSetLastError(Src.getError().message().c_str());
804 #if LLVM_VERSION_MINOR == 5
805 delete buf;
806 #endif
807 return false;
808 }
809
810 std::string Err;
811
812 #if LLVM_VERSION_MINOR >= 6
813 raw_string_ostream Stream(Err);
814 DiagnosticPrinterRawOStream DP(Stream);
815 #if LLVM_VERSION_MINOR >= 7
816 if (Linker::LinkModules(Dst, Src->get(), [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
817 #else
818 if (Linker::LinkModules(Dst, *Src, [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
819 #endif
820 #else
821 if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
822 #endif
823 LLVMRustSetLastError(Err.c_str());
824 return false;
825 }
826 return true;
827 }
828
829 extern "C" void
830 LLVMRustSetDLLStorageClass(LLVMValueRef Value,
831 GlobalValue::DLLStorageClassTypes Class) {
832 GlobalValue *V = unwrap<GlobalValue>(Value);
833 V->setDLLStorageClass(Class);
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
847 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
848 return reinterpret_cast<section_iterator*>(SI);
849 }
850
851 extern "C" int
852 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
853 StringRef ret;
854 if (std::error_code ec = (*unwrap(SI))->getName(ret))
855 report_fatal_error(ec.message());
856 *ptr = ret.data();
857 return ret.size();
858 }
859
860 // LLVMArrayType function does not support 64-bit ElementCount
861 extern "C" LLVMTypeRef
862 LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {
863 return wrap(ArrayType::get(unwrap(ElementType), ElementCount));
864 }
865
866 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
867 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
868
869 extern "C" void
870 LLVMWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
871 raw_rust_string_ostream os(str);
872 unwrap(T)->print(os);
873 }
874
875 extern "C" void
876 LLVMUnpackOptimizationDiagnostic(
877 LLVMDiagnosticInfoRef di,
878 const char **pass_name_out,
879 LLVMValueRef *function_out,
880 LLVMDebugLocRef *debugloc_out,
881 LLVMTwineRef *message_out)
882 {
883 // Undefined to call this not on an optimization diagnostic!
884 llvm::DiagnosticInfoOptimizationBase *opt
885 = static_cast<llvm::DiagnosticInfoOptimizationBase*>(unwrap(di));
886
887 *pass_name_out = opt->getPassName();
888 *function_out = wrap(&opt->getFunction());
889 *debugloc_out = wrap(&opt->getDebugLoc());
890 *message_out = wrap(&opt->getMsg());
891 }
892
893 extern "C" void
894 LLVMUnpackInlineAsmDiagnostic(
895 LLVMDiagnosticInfoRef di,
896 unsigned *cookie_out,
897 LLVMTwineRef *message_out,
898 LLVMValueRef *instruction_out)
899 {
900 // Undefined to call this not on an inline assembly diagnostic!
901 llvm::DiagnosticInfoInlineAsm *ia
902 = static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di));
903
904 *cookie_out = ia->getLocCookie();
905 *message_out = wrap(&ia->getMsgStr());
906 *instruction_out = wrap(ia->getInstruction());
907 }
908
909 extern "C" void LLVMWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
910 raw_rust_string_ostream os(str);
911 DiagnosticPrinterRawOStream dp(os);
912 unwrap(di)->print(dp);
913 }
914
915 extern "C" int LLVMGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
916 return unwrap(di)->getKind();
917 }
918
919 extern "C" void LLVMWriteDebugLocToString(
920 LLVMContextRef C,
921 LLVMDebugLocRef dl,
922 RustStringRef str)
923 {
924 raw_rust_string_ostream os(str);
925 #if LLVM_VERSION_MINOR >= 7
926 unwrap(dl)->print(os);
927 #else
928 unwrap(dl)->print(*unwrap(C), os);
929 #endif
930 }
931
932 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
933
934 extern "C" void LLVMSetInlineAsmDiagnosticHandler(
935 LLVMContextRef C,
936 LLVMContext::InlineAsmDiagHandlerTy H,
937 void *CX)
938 {
939 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
940 }
941
942 extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, RustStringRef str) {
943 raw_rust_string_ostream os(str);
944 unwrap(d)->print("", os);
945 }
946
947 extern "C" LLVMValueRef
948 LLVMRustBuildLandingPad(LLVMBuilderRef Builder,
949 LLVMTypeRef Ty,
950 LLVMValueRef PersFn,
951 unsigned NumClauses,
952 const char* Name,
953 LLVMValueRef F) {
954 #if LLVM_VERSION_MINOR >= 7
955 unwrap<Function>(F)->setPersonalityFn(unwrap<Constant>(PersFn));
956 return LLVMBuildLandingPad(Builder, Ty, NumClauses, Name);
957 #else
958 return LLVMBuildLandingPad(Builder, Ty, PersFn, NumClauses, Name);
959 #endif
960 }