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