]> git.proxmox.com Git - rustc.git/blob - src/rustllvm/RustWrapper.cpp
New upstream version 1.12.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 #include "llvm/IR/Instructions.h"
17
18 #include "llvm/IR/CallSite.h"
19
20 //===----------------------------------------------------------------------===
21 //
22 // This file defines alternate interfaces to core functions that are more
23 // readily callable by Rust's FFI.
24 //
25 //===----------------------------------------------------------------------===
26
27 using namespace llvm;
28 using namespace llvm::sys;
29 using namespace llvm::object;
30
31 // LLVMAtomicOrdering is already an enum - don't create another
32 // one.
33 static AtomicOrdering from_rust(LLVMAtomicOrdering Ordering) {
34 switch (Ordering) {
35 case LLVMAtomicOrderingNotAtomic:
36 return AtomicOrdering::NotAtomic;
37 case LLVMAtomicOrderingUnordered:
38 return AtomicOrdering::Unordered;
39 case LLVMAtomicOrderingMonotonic:
40 return AtomicOrdering::Monotonic;
41 case LLVMAtomicOrderingAcquire:
42 return AtomicOrdering::Acquire;
43 case LLVMAtomicOrderingRelease:
44 return AtomicOrdering::Release;
45 case LLVMAtomicOrderingAcquireRelease:
46 return AtomicOrdering::AcquireRelease;
47 case LLVMAtomicOrderingSequentiallyConsistent:
48 return AtomicOrdering::SequentiallyConsistent;
49 }
50
51 llvm_unreachable("Invalid LLVMAtomicOrdering value!");
52 }
53
54
55 static char *LastError;
56
57 extern "C" LLVMMemoryBufferRef
58 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
59 ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(Path,
60 -1,
61 false);
62 if (!buf_or) {
63 LLVMRustSetLastError(buf_or.getError().message().c_str());
64 return nullptr;
65 }
66 return wrap(buf_or.get().release());
67 }
68
69 extern "C" char *LLVMRustGetLastError(void) {
70 char *ret = LastError;
71 LastError = NULL;
72 return ret;
73 }
74
75 void LLVMRustSetLastError(const char *err) {
76 free((void*) LastError);
77 LastError = strdup(err);
78 }
79
80 extern "C" void
81 LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) {
82 unwrap(M)->setTargetTriple(Triple::normalize(triple));
83 }
84
85 extern "C" void LLVMRustPrintPassTimings() {
86 raw_fd_ostream OS (2, false); // stderr.
87 TimerGroup::printAll(OS);
88 }
89
90 extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M,
91 const char* Name) {
92 return wrap(unwrap(M)->getNamedValue(Name));
93 }
94
95 extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
96 const char* Name,
97 LLVMTypeRef FunctionTy) {
98 return wrap(unwrap(M)->getOrInsertFunction(Name,
99 unwrap<FunctionType>(FunctionTy)));
100 }
101
102 extern "C" LLVMValueRef LLVMRustGetOrInsertGlobal(LLVMModuleRef M,
103 const char* Name,
104 LLVMTypeRef Ty) {
105 return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty)));
106 }
107
108 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
109 return wrap(Type::getMetadataTy(*unwrap(C)));
110 }
111
112 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uint64_t Val) {
113 CallSite Call = CallSite(unwrap<Instruction>(Instr));
114 AttrBuilder B;
115 B.addRawValue(Val);
116 Call.setAttributes(
117 Call.getAttributes().addAttributes(Call->getContext(), index,
118 AttributeSet::get(Call->getContext(),
119 index, B)));
120 }
121
122
123 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
124 unsigned idx,
125 uint64_t b)
126 {
127 CallSite Call = CallSite(unwrap<Instruction>(Instr));
128 AttrBuilder B;
129 B.addDereferenceableAttr(b);
130 Call.setAttributes(
131 Call.getAttributes().addAttributes(Call->getContext(), idx,
132 AttributeSet::get(Call->getContext(),
133 idx, B)));
134 }
135
136 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn,
137 unsigned index,
138 uint64_t Val)
139 {
140 Function *A = unwrap<Function>(Fn);
141 AttrBuilder B;
142 B.addRawValue(Val);
143 A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
144 }
145
146 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn,
147 unsigned index,
148 uint64_t bytes)
149 {
150 Function *A = unwrap<Function>(Fn);
151 AttrBuilder B;
152 B.addDereferenceableAttr(bytes);
153 A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
154 }
155
156 extern "C" void LLVMRustAddFunctionAttrString(LLVMValueRef Fn,
157 unsigned index,
158 const char *Name)
159 {
160 Function *F = unwrap<Function>(Fn);
161 AttrBuilder B;
162 B.addAttribute(Name);
163 F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
164 }
165
166 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
167 unsigned index,
168 const char *Name,
169 const char *Value) {
170 Function *F = unwrap<Function>(Fn);
171 AttrBuilder B;
172 B.addAttribute(Name, Value);
173 F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
174 }
175
176 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
177 unsigned index,
178 uint64_t Val)
179 {
180 Function *A = unwrap<Function>(Fn);
181 const AttributeSet PAL = A->getAttributes();
182 AttrBuilder B(Val);
183 const AttributeSet PALnew =
184 PAL.removeAttributes(A->getContext(), index,
185 AttributeSet::get(A->getContext(), index, B));
186 A->setAttributes(PALnew);
187 }
188
189 extern "C" void LLVMRustRemoveFunctionAttrString(LLVMValueRef fn,
190 unsigned index,
191 const char *Name)
192 {
193 Function *f = unwrap<Function>(fn);
194 LLVMContext &C = f->getContext();
195 AttrBuilder B;
196 B.addAttribute(Name);
197 AttributeSet to_remove = AttributeSet::get(C, index, B);
198
199 AttributeSet attrs = f->getAttributes();
200 f->setAttributes(attrs.removeAttributes(f->getContext(),
201 index,
202 to_remove));
203 }
204
205 // enable fpmath flag UnsafeAlgebra
206 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
207 if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
208 I->setHasUnsafeAlgebra(true);
209 }
210 }
211
212 extern "C" LLVMValueRef LLVMRustBuildAtomicLoad(LLVMBuilderRef B,
213 LLVMValueRef source,
214 const char* Name,
215 LLVMAtomicOrdering order,
216 unsigned alignment) {
217 LoadInst* li = new LoadInst(unwrap(source),0);
218 li->setAtomic(from_rust(order));
219 li->setAlignment(alignment);
220 return wrap(unwrap(B)->Insert(li, Name));
221 }
222
223 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
224 LLVMValueRef val,
225 LLVMValueRef target,
226 LLVMAtomicOrdering order,
227 unsigned alignment) {
228 StoreInst* si = new StoreInst(unwrap(val),unwrap(target));
229 si->setAtomic(from_rust(order));
230 si->setAlignment(alignment);
231 return wrap(unwrap(B)->Insert(si));
232 }
233
234 extern "C" LLVMValueRef LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B,
235 LLVMValueRef target,
236 LLVMValueRef old,
237 LLVMValueRef source,
238 LLVMAtomicOrdering order,
239 LLVMAtomicOrdering failure_order,
240 LLVMBool weak) {
241 AtomicCmpXchgInst* acxi = unwrap(B)->CreateAtomicCmpXchg(
242 unwrap(target),
243 unwrap(old),
244 unwrap(source),
245 from_rust(order),
246 from_rust(failure_order));
247 acxi->setWeak(weak);
248 return wrap(acxi);
249 }
250
251 enum class LLVMRustSynchronizationScope {
252 Other,
253 SingleThread,
254 CrossThread,
255 };
256
257 static SynchronizationScope
258 from_rust(LLVMRustSynchronizationScope scope)
259 {
260 switch (scope) {
261 case LLVMRustSynchronizationScope::SingleThread:
262 return SingleThread;
263 case LLVMRustSynchronizationScope::CrossThread:
264 return CrossThread;
265 default:
266 llvm_unreachable("bad SynchronizationScope.");
267 }
268 }
269
270 extern "C" LLVMValueRef LLVMRustBuildAtomicFence(
271 LLVMBuilderRef B,
272 LLVMAtomicOrdering order,
273 LLVMRustSynchronizationScope scope)
274 {
275 return wrap(unwrap(B)->CreateFence(from_rust(order), from_rust(scope)));
276 }
277
278 extern "C" void LLVMRustSetDebug(int Enabled) {
279 #ifndef NDEBUG
280 DebugFlag = Enabled;
281 #endif
282 }
283
284 enum class LLVMRustAsmDialect {
285 Other,
286 Att,
287 Intel,
288 };
289
290 static InlineAsm::AsmDialect
291 from_rust(LLVMRustAsmDialect dialect)
292 {
293 switch (dialect) {
294 case LLVMRustAsmDialect::Att:
295 return InlineAsm::AD_ATT;
296 case LLVMRustAsmDialect::Intel:
297 return InlineAsm::AD_Intel;
298 default:
299 llvm_unreachable("bad AsmDialect.");
300 }
301 }
302
303 extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty,
304 char *AsmString,
305 char *Constraints,
306 LLVMBool HasSideEffects,
307 LLVMBool IsAlignStack,
308 LLVMRustAsmDialect Dialect) {
309 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
310 Constraints, HasSideEffects,
311 IsAlignStack, from_rust(Dialect)));
312 }
313
314 typedef DIBuilder* LLVMRustDIBuilderRef;
315
316 typedef struct LLVMOpaqueMetadata *LLVMRustMetadataRef;
317
318 namespace llvm {
319 DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMRustMetadataRef)
320
321 inline Metadata **unwrap(LLVMRustMetadataRef *Vals) {
322 return reinterpret_cast<Metadata**>(Vals);
323 }
324 }
325
326 template<typename DIT>
327 DIT* unwrapDIptr(LLVMRustMetadataRef ref) {
328 return (DIT*) (ref ? unwrap<MDNode>(ref) : NULL);
329 }
330
331 #define DIDescriptor DIScope
332 #define DIArray DINodeArray
333 #define unwrapDI unwrapDIptr
334
335 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
336 return DEBUG_METADATA_VERSION;
337 }
338
339 extern "C" uint32_t LLVMRustVersionMinor() {
340 return LLVM_VERSION_MINOR;
341 }
342
343 extern "C" uint32_t LLVMRustVersionMajor() {
344 return LLVM_VERSION_MAJOR;
345 }
346
347 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
348 const char *name,
349 uint32_t value) {
350 unwrap(M)->addModuleFlag(Module::Warning, name, value);
351 }
352
353 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
354 return new DIBuilder(*unwrap(M));
355 }
356
357 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
358 delete Builder;
359 }
360
361 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
362 Builder->finalize();
363 }
364
365 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateCompileUnit(
366 LLVMRustDIBuilderRef Builder,
367 unsigned Lang,
368 const char* File,
369 const char* Dir,
370 const char* Producer,
371 bool isOptimized,
372 const char* Flags,
373 unsigned RuntimeVer,
374 const char* SplitName) {
375 return wrap(Builder->createCompileUnit(Lang,
376 File,
377 Dir,
378 Producer,
379 isOptimized,
380 Flags,
381 RuntimeVer,
382 SplitName));
383 }
384
385 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFile(
386 LLVMRustDIBuilderRef Builder,
387 const char* Filename,
388 const char* Directory) {
389 return wrap(Builder->createFile(Filename, Directory));
390 }
391
392 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateSubroutineType(
393 LLVMRustDIBuilderRef Builder,
394 LLVMRustMetadataRef File,
395 LLVMRustMetadataRef ParameterTypes) {
396 return wrap(Builder->createSubroutineType(
397 #if LLVM_VERSION_MINOR == 7
398 unwrapDI<DIFile>(File),
399 #endif
400 DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
401 }
402
403 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction(
404 LLVMRustDIBuilderRef Builder,
405 LLVMRustMetadataRef Scope,
406 const char* Name,
407 const char* LinkageName,
408 LLVMRustMetadataRef File,
409 unsigned LineNo,
410 LLVMRustMetadataRef Ty,
411 bool isLocalToUnit,
412 bool isDefinition,
413 unsigned ScopeLine,
414 unsigned Flags,
415 bool isOptimized,
416 LLVMValueRef Fn,
417 LLVMRustMetadataRef TParam,
418 LLVMRustMetadataRef Decl) {
419 #if LLVM_VERSION_MINOR >= 8
420 DITemplateParameterArray TParams =
421 DITemplateParameterArray(unwrap<MDTuple>(TParam));
422 DISubprogram *Sub = Builder->createFunction(
423 unwrapDI<DIScope>(Scope), Name, LinkageName,
424 unwrapDI<DIFile>(File), LineNo,
425 unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
426 Flags, isOptimized,
427 TParams,
428 unwrapDIptr<DISubprogram>(Decl));
429 unwrap<Function>(Fn)->setSubprogram(Sub);
430 return wrap(Sub);
431 #else
432 return wrap(Builder->createFunction(
433 unwrapDI<DIScope>(Scope), Name, LinkageName,
434 unwrapDI<DIFile>(File), LineNo,
435 unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
436 Flags, isOptimized,
437 unwrap<Function>(Fn),
438 unwrapDIptr<MDNode>(TParam),
439 unwrapDIptr<MDNode>(Decl)));
440 #endif
441 }
442
443 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateBasicType(
444 LLVMRustDIBuilderRef Builder,
445 const char* Name,
446 uint64_t SizeInBits,
447 uint64_t AlignInBits,
448 unsigned Encoding) {
449 return wrap(Builder->createBasicType(
450 Name, SizeInBits,
451 AlignInBits, Encoding));
452 }
453
454 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreatePointerType(
455 LLVMRustDIBuilderRef Builder,
456 LLVMRustMetadataRef PointeeTy,
457 uint64_t SizeInBits,
458 uint64_t AlignInBits,
459 const char* Name) {
460 return wrap(Builder->createPointerType(
461 unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
462 }
463
464 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType(
465 LLVMRustDIBuilderRef Builder,
466 LLVMRustMetadataRef Scope,
467 const char* Name,
468 LLVMRustMetadataRef File,
469 unsigned LineNumber,
470 uint64_t SizeInBits,
471 uint64_t AlignInBits,
472 unsigned Flags,
473 LLVMRustMetadataRef DerivedFrom,
474 LLVMRustMetadataRef Elements,
475 unsigned RunTimeLang,
476 LLVMRustMetadataRef VTableHolder,
477 const char *UniqueId) {
478 return wrap(Builder->createStructType(
479 unwrapDI<DIDescriptor>(Scope),
480 Name,
481 unwrapDI<DIFile>(File),
482 LineNumber,
483 SizeInBits,
484 AlignInBits,
485 Flags,
486 unwrapDI<DIType>(DerivedFrom),
487 DINodeArray(unwrapDI<MDTuple>(Elements)),
488 RunTimeLang,
489 unwrapDI<DIType>(VTableHolder),
490 UniqueId
491 ));
492 }
493
494 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateMemberType(
495 LLVMRustDIBuilderRef Builder,
496 LLVMRustMetadataRef Scope,
497 const char* Name,
498 LLVMRustMetadataRef File,
499 unsigned LineNo,
500 uint64_t SizeInBits,
501 uint64_t AlignInBits,
502 uint64_t OffsetInBits,
503 unsigned Flags,
504 LLVMRustMetadataRef Ty) {
505 return wrap(Builder->createMemberType(
506 unwrapDI<DIDescriptor>(Scope), Name,
507 unwrapDI<DIFile>(File), LineNo,
508 SizeInBits, AlignInBits, OffsetInBits, Flags,
509 unwrapDI<DIType>(Ty)));
510 }
511
512 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
513 LLVMRustDIBuilderRef Builder,
514 LLVMRustMetadataRef Scope,
515 LLVMRustMetadataRef File,
516 unsigned Line,
517 unsigned Col) {
518 return wrap(Builder->createLexicalBlock(
519 unwrapDI<DIDescriptor>(Scope),
520 unwrapDI<DIFile>(File), Line, Col
521 ));
522 }
523
524 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable(
525 LLVMRustDIBuilderRef Builder,
526 LLVMRustMetadataRef Context,
527 const char* Name,
528 const char* LinkageName,
529 LLVMRustMetadataRef File,
530 unsigned LineNo,
531 LLVMRustMetadataRef Ty,
532 bool isLocalToUnit,
533 LLVMValueRef Val,
534 LLVMRustMetadataRef Decl = NULL) {
535 return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context),
536 Name,
537 LinkageName,
538 unwrapDI<DIFile>(File),
539 LineNo,
540 unwrapDI<DIType>(Ty),
541 isLocalToUnit,
542 cast<Constant>(unwrap(Val)),
543 unwrapDIptr<MDNode>(Decl)));
544 }
545
546 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(
547 LLVMRustDIBuilderRef Builder,
548 unsigned Tag,
549 LLVMRustMetadataRef Scope,
550 const char* Name,
551 LLVMRustMetadataRef File,
552 unsigned LineNo,
553 LLVMRustMetadataRef Ty,
554 bool AlwaysPreserve,
555 unsigned Flags,
556 int64_t* AddrOps,
557 unsigned AddrOpsCount,
558 unsigned ArgNo) {
559 #if LLVM_VERSION_MINOR >= 8
560 if (Tag == 0x100) { // DW_TAG_auto_variable
561 return wrap(Builder->createAutoVariable(
562 unwrapDI<DIDescriptor>(Scope), Name,
563 unwrapDI<DIFile>(File),
564 LineNo,
565 unwrapDI<DIType>(Ty), AlwaysPreserve, Flags));
566 } else {
567 return wrap(Builder->createParameterVariable(
568 unwrapDI<DIDescriptor>(Scope), Name, ArgNo,
569 unwrapDI<DIFile>(File),
570 LineNo,
571 unwrapDI<DIType>(Ty), AlwaysPreserve, Flags));
572 }
573 #else
574 return wrap(Builder->createLocalVariable(Tag,
575 unwrapDI<DIDescriptor>(Scope), Name,
576 unwrapDI<DIFile>(File),
577 LineNo,
578 unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
579 #endif
580 }
581
582 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateArrayType(
583 LLVMRustDIBuilderRef Builder,
584 uint64_t Size,
585 uint64_t AlignInBits,
586 LLVMRustMetadataRef Ty,
587 LLVMRustMetadataRef Subscripts) {
588 return wrap(Builder->createArrayType(Size, AlignInBits,
589 unwrapDI<DIType>(Ty),
590 DINodeArray(unwrapDI<MDTuple>(Subscripts))
591 ));
592 }
593
594 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVectorType(
595 LLVMRustDIBuilderRef Builder,
596 uint64_t Size,
597 uint64_t AlignInBits,
598 LLVMRustMetadataRef Ty,
599 LLVMRustMetadataRef Subscripts) {
600 return wrap(Builder->createVectorType(Size, AlignInBits,
601 unwrapDI<DIType>(Ty),
602 DINodeArray(unwrapDI<MDTuple>(Subscripts))
603 ));
604 }
605
606 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateSubrange(
607 LLVMRustDIBuilderRef Builder,
608 int64_t Lo,
609 int64_t Count) {
610 return wrap(Builder->getOrCreateSubrange(Lo, Count));
611 }
612
613 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateArray(
614 LLVMRustDIBuilderRef Builder,
615 LLVMRustMetadataRef* Ptr,
616 unsigned Count) {
617 Metadata **DataValue = unwrap(Ptr);
618 return wrap(Builder->getOrCreateArray(
619 ArrayRef<Metadata*>(DataValue, Count)).get());
620 }
621
622 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
623 LLVMRustDIBuilderRef Builder,
624 LLVMValueRef Val,
625 LLVMRustMetadataRef VarInfo,
626 int64_t* AddrOps,
627 unsigned AddrOpsCount,
628 LLVMValueRef DL,
629 LLVMBasicBlockRef InsertAtEnd) {
630 return wrap(Builder->insertDeclare(
631 unwrap(Val),
632 unwrap<DILocalVariable>(VarInfo),
633 Builder->createExpression(
634 llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
635 DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
636 unwrap(InsertAtEnd)));
637 }
638
639 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareBefore(
640 LLVMRustDIBuilderRef Builder,
641 LLVMValueRef Val,
642 LLVMRustMetadataRef VarInfo,
643 int64_t* AddrOps,
644 unsigned AddrOpsCount,
645 LLVMValueRef DL,
646 LLVMValueRef InsertBefore) {
647 return wrap(Builder->insertDeclare(
648 unwrap(Val),
649 unwrap<DILocalVariable>(VarInfo),
650 Builder->createExpression(
651 llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
652 DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
653 unwrap<Instruction>(InsertBefore)));
654 }
655
656 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerator(
657 LLVMRustDIBuilderRef Builder,
658 const char* Name,
659 uint64_t Val)
660 {
661 return wrap(Builder->createEnumerator(Name, Val));
662 }
663
664 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerationType(
665 LLVMRustDIBuilderRef Builder,
666 LLVMRustMetadataRef Scope,
667 const char* Name,
668 LLVMRustMetadataRef File,
669 unsigned LineNumber,
670 uint64_t SizeInBits,
671 uint64_t AlignInBits,
672 LLVMRustMetadataRef Elements,
673 LLVMRustMetadataRef ClassType)
674 {
675 return wrap(Builder->createEnumerationType(
676 unwrapDI<DIDescriptor>(Scope),
677 Name,
678 unwrapDI<DIFile>(File),
679 LineNumber,
680 SizeInBits,
681 AlignInBits,
682 DINodeArray(unwrapDI<MDTuple>(Elements)),
683 unwrapDI<DIType>(ClassType)));
684 }
685
686 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType(
687 LLVMRustDIBuilderRef Builder,
688 LLVMRustMetadataRef Scope,
689 const char* Name,
690 LLVMRustMetadataRef File,
691 unsigned LineNumber,
692 uint64_t SizeInBits,
693 uint64_t AlignInBits,
694 unsigned Flags,
695 LLVMRustMetadataRef Elements,
696 unsigned RunTimeLang,
697 const char* UniqueId)
698 {
699 return wrap(Builder->createUnionType(
700 unwrapDI<DIDescriptor>(Scope),
701 Name,
702 unwrapDI<DIFile>(File),
703 LineNumber,
704 SizeInBits,
705 AlignInBits,
706 Flags,
707 DINodeArray(unwrapDI<MDTuple>(Elements)),
708 RunTimeLang,
709 UniqueId
710 ));
711 }
712
713 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
714 LLVMRustDIBuilderRef Builder,
715 LLVMRustMetadataRef Scope,
716 const char* Name,
717 LLVMRustMetadataRef Ty,
718 LLVMRustMetadataRef File,
719 unsigned LineNo,
720 unsigned ColumnNo)
721 {
722 return wrap(Builder->createTemplateTypeParameter(
723 unwrapDI<DIDescriptor>(Scope),
724 Name,
725 unwrapDI<DIType>(Ty)
726 ));
727 }
728
729 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateNameSpace(
730 LLVMRustDIBuilderRef Builder,
731 LLVMRustMetadataRef Scope,
732 const char* Name,
733 LLVMRustMetadataRef File,
734 unsigned LineNo)
735 {
736 return wrap(Builder->createNameSpace(
737 unwrapDI<DIDescriptor>(Scope),
738 Name,
739 unwrapDI<DIFile>(File),
740 LineNo));
741 }
742
743 extern "C" void LLVMRustDICompositeTypeSetTypeArray(
744 LLVMRustDIBuilderRef Builder,
745 LLVMRustMetadataRef CompositeType,
746 LLVMRustMetadataRef TypeArray)
747 {
748 DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType);
749 Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray)));
750 }
751
752 extern "C" LLVMValueRef LLVMRustDIBuilderCreateDebugLocation(
753 LLVMContextRef Context,
754 unsigned Line,
755 unsigned Column,
756 LLVMRustMetadataRef Scope,
757 LLVMRustMetadataRef InlinedAt)
758 {
759 LLVMContext& context = *unwrap(Context);
760
761 DebugLoc debug_loc = DebugLoc::get(Line,
762 Column,
763 unwrapDIptr<MDNode>(Scope),
764 unwrapDIptr<MDNode>(InlinedAt));
765
766 return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode()));
767 }
768
769 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref()
770 {
771 return dwarf::DW_OP_deref;
772 }
773
774 extern "C" int64_t LLVMRustDIBuilderCreateOpPlus()
775 {
776 return dwarf::DW_OP_plus;
777 }
778
779 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
780 raw_rust_string_ostream os(str);
781 unwrap<llvm::Type>(Type)->print(os);
782 }
783
784 extern "C" void LLVMRustWriteValueToString(LLVMValueRef Value, RustStringRef str) {
785 raw_rust_string_ostream os(str);
786 os << "(";
787 unwrap<llvm::Value>(Value)->getType()->print(os);
788 os << ":";
789 unwrap<llvm::Value>(Value)->print(os);
790 os << ")";
791 }
792
793 extern "C" bool
794 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
795 Module *Dst = unwrap(dst);
796 std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
797 ErrorOr<std::unique_ptr<Module>> Src =
798 llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
799 if (!Src) {
800 LLVMRustSetLastError(Src.getError().message().c_str());
801 return false;
802 }
803
804 std::string Err;
805
806 raw_string_ostream Stream(Err);
807 DiagnosticPrinterRawOStream DP(Stream);
808 #if LLVM_VERSION_MINOR >= 8
809 if (Linker::linkModules(*Dst, std::move(Src.get()))) {
810 #else
811 if (Linker::LinkModules(Dst, Src->get(), [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
812 #endif
813 LLVMRustSetLastError(Err.c_str());
814 return false;
815 }
816 return true;
817 }
818
819 // Note that the two following functions look quite similar to the
820 // LLVMGetSectionName function. Sadly, it appears that this function only
821 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
822 // function provided by LLVM doesn't return the length, so we've created our own
823 // function which returns the length as well as the data pointer.
824 //
825 // For an example of this not returning a null terminated string, see
826 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
827 // branches explicitly creates a StringRef without a null terminator, and then
828 // that's returned.
829
830 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
831 return reinterpret_cast<section_iterator*>(SI);
832 }
833
834 extern "C" size_t
835 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
836 StringRef ret;
837 if (std::error_code ec = (*unwrap(SI))->getName(ret))
838 report_fatal_error(ec.message());
839 *ptr = ret.data();
840 return ret.size();
841 }
842
843 // LLVMArrayType function does not support 64-bit ElementCount
844 extern "C" LLVMTypeRef
845 LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {
846 return wrap(ArrayType::get(unwrap(ElementType), ElementCount));
847 }
848
849 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
850 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
851
852 extern "C" void
853 LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
854 raw_rust_string_ostream os(str);
855 unwrap(T)->print(os);
856 }
857
858 extern "C" void
859 LLVMRustUnpackOptimizationDiagnostic(
860 LLVMDiagnosticInfoRef di,
861 const char **pass_name_out,
862 LLVMValueRef *function_out,
863 LLVMDebugLocRef *debugloc_out,
864 LLVMTwineRef *message_out)
865 {
866 // Undefined to call this not on an optimization diagnostic!
867 llvm::DiagnosticInfoOptimizationBase *opt
868 = static_cast<llvm::DiagnosticInfoOptimizationBase*>(unwrap(di));
869
870 *pass_name_out = opt->getPassName();
871 *function_out = wrap(&opt->getFunction());
872 *debugloc_out = wrap(&opt->getDebugLoc());
873 *message_out = wrap(&opt->getMsg());
874 }
875
876 extern "C" void
877 LLVMRustUnpackInlineAsmDiagnostic(
878 LLVMDiagnosticInfoRef di,
879 unsigned *cookie_out,
880 LLVMTwineRef *message_out,
881 LLVMValueRef *instruction_out)
882 {
883 // Undefined to call this not on an inline assembly diagnostic!
884 llvm::DiagnosticInfoInlineAsm *ia
885 = static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di));
886
887 *cookie_out = ia->getLocCookie();
888 *message_out = wrap(&ia->getMsgStr());
889 *instruction_out = wrap(ia->getInstruction());
890 }
891
892 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
893 raw_rust_string_ostream os(str);
894 DiagnosticPrinterRawOStream dp(os);
895 unwrap(di)->print(dp);
896 }
897
898 enum class LLVMRustDiagnosticKind {
899 Other,
900 InlineAsm,
901 StackSize,
902 DebugMetadataVersion,
903 SampleProfile,
904 OptimizationRemark,
905 OptimizationRemarkMissed,
906 OptimizationRemarkAnalysis,
907 OptimizationRemarkAnalysisFPCommute,
908 OptimizationRemarkAnalysisAliasing,
909 OptimizationRemarkOther,
910 OptimizationFailure,
911 };
912
913 static LLVMRustDiagnosticKind
914 to_rust(DiagnosticKind kind)
915 {
916 switch (kind) {
917 case DK_InlineAsm:
918 return LLVMRustDiagnosticKind::InlineAsm;
919 case DK_StackSize:
920 return LLVMRustDiagnosticKind::StackSize;
921 case DK_DebugMetadataVersion:
922 return LLVMRustDiagnosticKind::DebugMetadataVersion;
923 case DK_SampleProfile:
924 return LLVMRustDiagnosticKind::SampleProfile;
925 case DK_OptimizationRemark:
926 return LLVMRustDiagnosticKind::OptimizationRemark;
927 case DK_OptimizationRemarkMissed:
928 return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
929 case DK_OptimizationRemarkAnalysis:
930 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
931 #if LLVM_VERSION_MINOR >= 8
932 case DK_OptimizationRemarkAnalysisFPCommute:
933 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
934 case DK_OptimizationRemarkAnalysisAliasing:
935 return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
936 #endif
937 default:
938 #if LLVM_VERSION_MINOR >= 9
939 return (kind >= DK_FirstRemark && kind <= DK_LastRemark) ?
940 LLVMRustDiagnosticKind::OptimizationRemarkOther :
941 LLVMRustDiagnosticKind::Other;
942 #else
943 return LLVMRustDiagnosticKind::Other;
944 #endif
945 }
946 }
947
948 extern "C" LLVMRustDiagnosticKind LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
949 return to_rust((DiagnosticKind) unwrap(di)->getKind());
950 }
951 // This is kept distinct from LLVMGetTypeKind, because when
952 // a new type kind is added, the Rust-side enum must be
953 // updated or UB will result.
954 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
955 switch (unwrap(Ty)->getTypeID()) {
956 case Type::VoidTyID:
957 return LLVMVoidTypeKind;
958 case Type::HalfTyID:
959 return LLVMHalfTypeKind;
960 case Type::FloatTyID:
961 return LLVMFloatTypeKind;
962 case Type::DoubleTyID:
963 return LLVMDoubleTypeKind;
964 case Type::X86_FP80TyID:
965 return LLVMX86_FP80TypeKind;
966 case Type::FP128TyID:
967 return LLVMFP128TypeKind;
968 case Type::PPC_FP128TyID:
969 return LLVMPPC_FP128TypeKind;
970 case Type::LabelTyID:
971 return LLVMLabelTypeKind;
972 case Type::MetadataTyID:
973 return LLVMMetadataTypeKind;
974 case Type::IntegerTyID:
975 return LLVMIntegerTypeKind;
976 case Type::FunctionTyID:
977 return LLVMFunctionTypeKind;
978 case Type::StructTyID:
979 return LLVMStructTypeKind;
980 case Type::ArrayTyID:
981 return LLVMArrayTypeKind;
982 case Type::PointerTyID:
983 return LLVMPointerTypeKind;
984 case Type::VectorTyID:
985 return LLVMVectorTypeKind;
986 case Type::X86_MMXTyID:
987 return LLVMX86_MMXTypeKind;
988 #if LLVM_VERSION_MINOR >= 8
989 case Type::TokenTyID:
990 return LLVMTokenTypeKind;
991 #endif
992 }
993 llvm_unreachable("Unhandled TypeID.");
994 }
995
996 extern "C" void LLVMRustWriteDebugLocToString(
997 LLVMContextRef C,
998 LLVMDebugLocRef dl,
999 RustStringRef str)
1000 {
1001 raw_rust_string_ostream os(str);
1002 unwrap(dl)->print(os);
1003 }
1004
1005 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1006
1007 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1008 LLVMContextRef C,
1009 LLVMContext::InlineAsmDiagHandlerTy H,
1010 void *CX)
1011 {
1012 unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1013 }
1014
1015 extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef d,
1016 RustStringRef str) {
1017 raw_rust_string_ostream os(str);
1018 unwrap(d)->print("", os);
1019 }
1020
1021 extern "C" LLVMValueRef
1022 LLVMRustBuildLandingPad(LLVMBuilderRef Builder,
1023 LLVMTypeRef Ty,
1024 LLVMValueRef PersFn,
1025 unsigned NumClauses,
1026 const char* Name,
1027 LLVMValueRef F) {
1028 return LLVMBuildLandingPad(Builder, Ty, PersFn, NumClauses, Name);
1029 }
1030
1031 extern "C" LLVMValueRef
1032 LLVMRustBuildCleanupPad(LLVMBuilderRef Builder,
1033 LLVMValueRef ParentPad,
1034 unsigned ArgCnt,
1035 LLVMValueRef *LLArgs,
1036 const char *Name) {
1037 #if LLVM_VERSION_MINOR >= 8
1038 Value **Args = unwrap(LLArgs);
1039 if (ParentPad == NULL) {
1040 Type *Ty = Type::getTokenTy(unwrap(Builder)->getContext());
1041 ParentPad = wrap(Constant::getNullValue(Ty));
1042 }
1043 return wrap(unwrap(Builder)->CreateCleanupPad(unwrap(ParentPad),
1044 ArrayRef<Value*>(Args, ArgCnt),
1045 Name));
1046 #else
1047 return NULL;
1048 #endif
1049 }
1050
1051 extern "C" LLVMValueRef
1052 LLVMRustBuildCleanupRet(LLVMBuilderRef Builder,
1053 LLVMValueRef CleanupPad,
1054 LLVMBasicBlockRef UnwindBB) {
1055 #if LLVM_VERSION_MINOR >= 8
1056 CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1057 return wrap(unwrap(Builder)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1058 #else
1059 return NULL;
1060 #endif
1061 }
1062
1063 extern "C" LLVMValueRef
1064 LLVMRustBuildCatchPad(LLVMBuilderRef Builder,
1065 LLVMValueRef ParentPad,
1066 unsigned ArgCnt,
1067 LLVMValueRef *LLArgs,
1068 const char *Name) {
1069 #if LLVM_VERSION_MINOR >= 8
1070 Value **Args = unwrap(LLArgs);
1071 return wrap(unwrap(Builder)->CreateCatchPad(unwrap(ParentPad),
1072 ArrayRef<Value*>(Args, ArgCnt),
1073 Name));
1074 #else
1075 return NULL;
1076 #endif
1077 }
1078
1079 extern "C" LLVMValueRef
1080 LLVMRustBuildCatchRet(LLVMBuilderRef Builder,
1081 LLVMValueRef Pad,
1082 LLVMBasicBlockRef BB) {
1083 #if LLVM_VERSION_MINOR >= 8
1084 return wrap(unwrap(Builder)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1085 unwrap(BB)));
1086 #else
1087 return NULL;
1088 #endif
1089 }
1090
1091 extern "C" LLVMValueRef
1092 LLVMRustBuildCatchSwitch(LLVMBuilderRef Builder,
1093 LLVMValueRef ParentPad,
1094 LLVMBasicBlockRef BB,
1095 unsigned NumHandlers,
1096 const char *Name) {
1097 #if LLVM_VERSION_MINOR >= 8
1098 if (ParentPad == NULL) {
1099 Type *Ty = Type::getTokenTy(unwrap(Builder)->getContext());
1100 ParentPad = wrap(Constant::getNullValue(Ty));
1101 }
1102 return wrap(unwrap(Builder)->CreateCatchSwitch(unwrap(ParentPad),
1103 unwrap(BB),
1104 NumHandlers,
1105 Name));
1106 #else
1107 return NULL;
1108 #endif
1109 }
1110
1111 extern "C" void
1112 LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1113 LLVMBasicBlockRef Handler) {
1114 #if LLVM_VERSION_MINOR >= 8
1115 Value *CatchSwitch = unwrap(CatchSwitchRef);
1116 cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1117 #endif
1118 }
1119
1120 extern "C" void
1121 LLVMRustSetPersonalityFn(LLVMBuilderRef B,
1122 LLVMValueRef Personality) {
1123 #if LLVM_VERSION_MINOR >= 8
1124 unwrap(B)->GetInsertBlock()
1125 ->getParent()
1126 ->setPersonalityFn(cast<Function>(unwrap(Personality)));
1127 #endif
1128 }
1129
1130 #if LLVM_VERSION_MINOR >= 8
1131 extern "C" OperandBundleDef*
1132 LLVMRustBuildOperandBundleDef(const char *Name,
1133 LLVMValueRef *Inputs,
1134 unsigned NumInputs) {
1135 return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1136 }
1137
1138 extern "C" void
1139 LLVMRustFreeOperandBundleDef(OperandBundleDef* Bundle) {
1140 delete Bundle;
1141 }
1142
1143 extern "C" LLVMValueRef
1144 LLVMRustBuildCall(LLVMBuilderRef B,
1145 LLVMValueRef Fn,
1146 LLVMValueRef *Args,
1147 unsigned NumArgs,
1148 OperandBundleDef *Bundle,
1149 const char *Name) {
1150 unsigned len = Bundle ? 1 : 0;
1151 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, len);
1152 return wrap(unwrap(B)->CreateCall(unwrap(Fn),
1153 makeArrayRef(unwrap(Args), NumArgs),
1154 Bundles,
1155 Name));
1156 }
1157
1158 extern "C" LLVMValueRef
1159 LLVMRustBuildInvoke(LLVMBuilderRef B,
1160 LLVMValueRef Fn,
1161 LLVMValueRef *Args,
1162 unsigned NumArgs,
1163 LLVMBasicBlockRef Then,
1164 LLVMBasicBlockRef Catch,
1165 OperandBundleDef *Bundle,
1166 const char *Name) {
1167 unsigned len = Bundle ? 1 : 0;
1168 ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, len);
1169 return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch),
1170 makeArrayRef(unwrap(Args), NumArgs),
1171 Bundles,
1172 Name));
1173 }
1174 #else
1175 extern "C" void*
1176 LLVMRustBuildOperandBundleDef(const char *Name,
1177 LLVMValueRef *Inputs,
1178 unsigned NumInputs) {
1179 return NULL;
1180 }
1181
1182 extern "C" void
1183 LLVMRustFreeOperandBundleDef(void* Bundle) {
1184 }
1185
1186 extern "C" LLVMValueRef
1187 LLVMRustBuildCall(LLVMBuilderRef B,
1188 LLVMValueRef Fn,
1189 LLVMValueRef *Args,
1190 unsigned NumArgs,
1191 void *Bundle,
1192 const char *Name) {
1193 return LLVMBuildCall(B, Fn, Args, NumArgs, Name);
1194 }
1195
1196 extern "C" LLVMValueRef
1197 LLVMRustBuildInvoke(LLVMBuilderRef B,
1198 LLVMValueRef Fn,
1199 LLVMValueRef *Args,
1200 unsigned NumArgs,
1201 LLVMBasicBlockRef Then,
1202 LLVMBasicBlockRef Catch,
1203 void *Bundle,
1204 const char *Name) {
1205 return LLVMBuildInvoke(B, Fn, Args, NumArgs, Then, Catch, Name);
1206 }
1207 #endif
1208
1209 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B, LLVMBasicBlockRef BB) {
1210 auto point = unwrap(BB)->getFirstInsertionPt();
1211 unwrap(B)->SetInsertPoint(unwrap(BB), point);
1212 }
1213
1214 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V, const char *Name) {
1215 Triple TargetTriple(unwrap(M)->getTargetTriple());
1216 GlobalObject *GV = unwrap<GlobalObject>(V);
1217 if (!TargetTriple.isOSBinFormatMachO()) {
1218 GV->setComdat(unwrap(M)->getOrInsertComdat(Name));
1219 }
1220 }
1221
1222 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1223 GlobalObject *GV = unwrap<GlobalObject>(V);
1224 GV->setComdat(nullptr);
1225 }