]>
Commit | Line | Data |
---|---|---|
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 |
30 | using namespace llvm; |
31 | using namespace llvm::sys; | |
1a4d82fc | 32 | using namespace llvm::object; |
223e47cc | 33 | |
1a4d82fc | 34 | static char *LastError; |
970d7e83 | 35 | |
1a4d82fc | 36 | #if LLVM_VERSION_MINOR >= 5 |
223e47cc LB |
37 | extern "C" LLVMMemoryBufferRef |
38 | LLVMRustCreateMemoryBufferWithContentsOfFile(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 |
49 | extern "C" LLVMMemoryBufferRef | |
50 | LLVMRustCreateMemoryBufferWithContentsOfFile(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 |
61 | extern "C" char *LLVMRustGetLastError(void) { |
62 | char *ret = LastError; | |
63 | LastError = NULL; | |
64 | return ret; | |
223e47cc LB |
65 | } |
66 | ||
1a4d82fc JJ |
67 | void LLVMRustSetLastError(const char *err) { |
68 | free((void*) LastError); | |
69 | LastError = strdup(err); | |
223e47cc LB |
70 | } |
71 | ||
1a4d82fc JJ |
72 | extern "C" void |
73 | LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) { | |
74 | unwrap(M)->setTargetTriple(Triple::normalize(triple)); | |
223e47cc LB |
75 | } |
76 | ||
77 | extern "C" LLVMValueRef LLVMRustConstSmallInt(LLVMTypeRef IntTy, unsigned N, | |
78 | LLVMBool SignExtend) { | |
79 | return LLVMConstInt(IntTy, (unsigned long long)N, SignExtend); | |
80 | } | |
81 | ||
970d7e83 LB |
82 | extern "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 |
92 | extern "C" void LLVMRustPrintPassTimings() { |
93 | raw_fd_ostream OS (2, false); // stderr. | |
94 | TimerGroup::printAll(OS); | |
95 | } | |
96 | ||
97 | extern "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 | ||
104 | extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) { | |
105 | return wrap(Type::getMetadataTy(*unwrap(C))); | |
106 | } | |
970d7e83 | 107 | |
1a4d82fc JJ |
108 | extern "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 | |
120 | extern "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 | |
130 | extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef, unsigned, uint64_t) {} | |
131 | #endif | |
132 | ||
133 | extern "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 | |
141 | extern "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 | |
148 | extern "C" void LLVMAddDereferenceableAttr(LLVMValueRef, unsigned, uint64_t) {} | |
149 | #endif | |
150 | ||
151 | extern "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 | ||
158 | extern "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 |
171 | extern "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 | ||
183 | extern "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 | ||
195 | extern "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 |
208 | extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B, AtomicOrdering order) { |
209 | return wrap(unwrap(B)->CreateFence(order)); | |
223e47cc LB |
210 | } |
211 | ||
212 | extern "C" void LLVMSetDebug(int Enabled) { | |
213 | #ifndef NDEBUG | |
214 | DebugFlag = Enabled; | |
215 | #endif | |
216 | } | |
217 | ||
218 | extern "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 |
229 | typedef DIBuilder* DIBuilderRef; |
230 | ||
231 | template<typename DIT> | |
1a4d82fc JJ |
232 | DIT unwrapDI(LLVMValueRef ref) { |
233 | return DIT(ref ? unwrap<MDNode>(ref) : NULL); | |
234 | } | |
235 | ||
236 | #if LLVM_VERSION_MINOR >= 5 | |
237 | extern "C" const uint32_t LLVMRustDebugMetadataVersion = DEBUG_METADATA_VERSION; | |
238 | #else | |
239 | extern "C" const uint32_t LLVMRustDebugMetadataVersion = 1; | |
240 | #endif | |
241 | ||
242 | extern "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 | ||
248 | extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) { | |
249 | return new DIBuilder(*unwrap(M)); | |
250 | } | |
251 | ||
252 | extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) { | |
253 | delete Builder; | |
254 | } | |
255 | ||
256 | extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) { | |
257 | Builder->finalize(); | |
258 | } | |
259 | ||
1a4d82fc | 260 | extern "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 | ||
280 | extern "C" LLVMValueRef LLVMDIBuilderCreateFile( | |
281 | DIBuilderRef Builder, | |
282 | const char* Filename, | |
283 | const char* Directory) { | |
284 | return wrap(Builder->createFile(Filename, Directory)); | |
285 | } | |
286 | ||
287 | extern "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 | ||
300 | extern "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 | ||
326 | extern "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 |
337 | extern "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 | ||
347 | extern "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 | ||
379 | extern "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 |
397 | extern "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 | ||
412 | extern "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 |
438 | extern "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 | ||
456 | extern "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 | ||
467 | extern "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 | ||
478 | extern "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 | ||
485 | extern "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 | ||
493 | extern "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 | ||
504 | extern "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 | |
515 | extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerator( | |
516 | DIBuilderRef Builder, | |
517 | const char* Name, | |
518 | uint64_t Val) | |
519 | { | |
520 | return wrap(Builder->createEnumerator(Name, Val)); | |
521 | } | |
522 | ||
523 | extern "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 | ||
545 | extern "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 | |
575 | extern "C" void LLVMSetUnnamedAddr(LLVMValueRef Value, LLVMBool Unnamed) { | |
576 | unwrap<GlobalValue>(Value)->setUnnamedAddr(Unnamed); | |
577 | } | |
578 | #endif | |
579 | ||
580 | extern "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 | ||
598 | extern "C" LLVMValueRef LLVMDIBuilderCreateOpDeref(LLVMTypeRef IntTy) | |
599 | { | |
600 | return LLVMConstInt(IntTy, DIBuilder::OpDeref, true); | |
601 | } | |
602 | ||
603 | extern "C" LLVMValueRef LLVMDIBuilderCreateOpPlus(LLVMTypeRef IntTy) | |
604 | { | |
605 | return LLVMConstInt(IntTy, DIBuilder::OpPlus, true); | |
606 | } | |
607 | ||
608 | extern "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 | ||
634 | extern "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 | ||
648 | extern "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 | ||
659 | extern "C" void LLVMWriteTypeToString(LLVMTypeRef Type, RustStringRef str) { | |
660 | raw_rust_string_ostream os(str); | |
661 | unwrap<llvm::Type>(Type)->print(os); | |
662 | } | |
663 | ||
664 | extern "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 | |
674 | extern "C" bool | |
675 | LLVMRustLinkInExternalBitcode(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 | |
700 | extern "C" bool | |
701 | LLVMRustLinkInExternalBitcode(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 | |
721 | extern "C" void* | |
722 | LLVMRustOpenArchive(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 | |
754 | extern "C" void* | |
755 | LLVMRustOpenArchive(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 | ||
771 | extern "C" const char* | |
772 | #if LLVM_VERSION_MINOR >= 6 | |
773 | LLVMRustArchiveReadSection(OwningBinary<Archive> *ob, char *name, size_t *size) { | |
774 | ||
775 | std::unique_ptr<Archive> &ar = ob->getBinary(); | |
776 | #else | |
777 | LLVMRustArchiveReadSection(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 | ||
804 | extern "C" void | |
805 | #if LLVM_VERSION_MINOR >= 6 | |
806 | LLVMRustDestroyArchive(OwningBinary<Archive> *ar) { | |
807 | #else | |
808 | LLVMRustDestroyArchive(Archive *ar) { | |
809 | #endif | |
810 | delete ar; | |
811 | } | |
812 | ||
813 | #if LLVM_VERSION_MINOR >= 5 | |
814 | extern "C" void | |
815 | LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) { | |
816 | GlobalValue *V = unwrap<GlobalValue>(Value); | |
817 | V->setDLLStorageClass(GlobalValue::DLLExportStorageClass); | |
818 | } | |
819 | #else | |
820 | extern "C" void | |
821 | LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) { | |
822 | LLVMSetLinkage(Value, LLVMDLLExportLinkage); | |
823 | } | |
824 | #endif | |
825 | ||
826 | extern "C" int | |
827 | LLVMVersionMinor() { | |
828 | return LLVM_VERSION_MINOR; | |
829 | } | |
830 | ||
831 | extern "C" int | |
832 | LLVMVersionMajor() { | |
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 | ||
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 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 | |
865 | extern "C" LLVMTypeRef | |
866 | LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) { | |
867 | return wrap(ArrayType::get(unwrap(ElementType), ElementCount)); | |
868 | } | |
869 | ||
870 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef) | |
871 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef) | |
872 | ||
873 | extern "C" void | |
874 | LLVMWriteTwineToString(LLVMTwineRef T, RustStringRef str) { | |
875 | raw_rust_string_ostream os(str); | |
876 | unwrap(T)->print(os); | |
877 | } | |
878 | ||
879 | extern "C" void | |
880 | LLVMUnpackOptimizationDiagnostic( | |
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 | ||
897 | extern "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 | ||
903 | extern "C" int LLVMGetDiagInfoKind(LLVMDiagnosticInfoRef di) { | |
904 | return unwrap(di)->getKind(); | |
905 | } | |
906 | ||
907 | extern "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 | ||
916 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef) | |
917 | ||
918 | extern "C" void LLVMSetInlineAsmDiagnosticHandler( | |
919 | LLVMContextRef C, | |
920 | LLVMContext::InlineAsmDiagHandlerTy H, | |
921 | void *CX) | |
922 | { | |
923 | unwrap(C)->setInlineAsmDiagnosticHandler(H, CX); | |
924 | } | |
925 | ||
926 | extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, RustStringRef str) { | |
927 | raw_rust_string_ostream os(str); | |
928 | unwrap(d)->print("", os); | |
929 | } |