Mercurial > projects > ldc
comparison tools/binding/llvm/llvm.d @ 1651:cb960b882ca3 default tip
bindings were moved to dsource.org/projects/bindings/
author | Moritz Warning <moritzwarning@web.de> |
---|---|
date | Thu, 20 May 2010 20:05:03 +0200 |
parents | 40bd4a0d4870 |
children |
comparison
equal
deleted
inserted
replaced
1650:40bd4a0d4870 | 1651:cb960b882ca3 |
---|---|
1 // Written in the D programming language by Tomas Lindquist Olsen 2008 | |
2 // Binding of llvm.c.Core values for D. | |
3 // | |
4 // This file is distributed under the University of Illinois Open Source | |
5 // License. See LICENSE.TXT for details. | |
6 // | |
7 module llvm.llvm; | |
8 | |
9 import llvm.c.Core; | |
10 import llvm.c.Ext; | |
11 import llvm.c.BitWriter; | |
12 import llvm.c.BitReader; | |
13 import llvm.c.Analysis; | |
14 import llvm.c.Target; | |
15 | |
16 public import llvm.type; | |
17 public import llvm.builder; | |
18 | |
19 import llvm.util; | |
20 | |
21 /// | |
22 class LLVMException : Exception | |
23 { | |
24 this(char[] msg) { | |
25 super(msg); | |
26 } | |
27 } | |
28 | |
29 version(Tango) { | |
30 import tango.stdc.stdlib; | |
31 } | |
32 else { | |
33 import std.c.stdlib; | |
34 } | |
35 /// | |
36 alias LLVMLinkage Linkage; | |
37 /// | |
38 alias LLVMIntPredicate IntPredicate; | |
39 /// | |
40 alias LLVMRealPredicate RealPredicate; | |
41 /// | |
42 alias LLVMCallConv CallConv; | |
43 /// | |
44 alias LLVMVisibility Visibility; | |
45 /// | |
46 alias LLVMValueKind ValueKind; | |
47 | |
48 /// | |
49 class Module | |
50 { | |
51 /// global registry for 1:1 mapping of ModuleRef's -> Module's | |
52 private static Module[LLVMModuleRef] registry; | |
53 /// | |
54 private LLVMModuleRef mod; | |
55 const char[] name; | |
56 | |
57 // Make all methods final to enable linking with just needed libs. | |
58 // To make use of this if compiling with GDC: use -ffunction-sections when | |
59 // compiling and --gc-sections when linking. | |
60 // (Final avoids references in the vtable) | |
61 final: | |
62 | |
63 /// | |
64 this(char[] nam) | |
65 { | |
66 name = nam; | |
67 mod = LLVMModuleCreateWithName(to_stringz(nam)); | |
68 registry[mod] = this; | |
69 } | |
70 /// | |
71 private this(LLVMModuleRef m) | |
72 { | |
73 name = null; | |
74 mod = m; | |
75 registry[m] = this; | |
76 } | |
77 /// | |
78 static package Module GetExisting(LLVMModuleRef m) | |
79 { | |
80 if (auto p = m in registry) | |
81 { | |
82 return *p; | |
83 } | |
84 return new Module(m); | |
85 } | |
86 /// Create a module from bitcode. Returns the Module on success, null on failure. | |
87 static Module GetFromBitcode(char[] bitcodepath, ref char[] errmsg) | |
88 { | |
89 LLVMModuleRef mref; | |
90 LLVMMemoryBufferRef bref; | |
91 char* msg; | |
92 if (LLVMCreateMemoryBufferWithContentsOfFile(to_stringz(bitcodepath), &bref, &msg)) | |
93 { | |
94 errmsg = from_stringz(msg).dup; | |
95 LLVMDisposeMessage(msg); | |
96 if (errmsg.length == 0) | |
97 errmsg = "Error reading bitcode file"; | |
98 throw new LLVMException(errmsg); | |
99 } | |
100 scope(exit) | |
101 LLVMDisposeMemoryBuffer(bref); | |
102 | |
103 if (LLVMParseBitcode(bref, &mref, &msg)) | |
104 { | |
105 errmsg = from_stringz(msg).dup; | |
106 LLVMDisposeMessage(msg); | |
107 if (errmsg.length == 0) | |
108 errmsg = "Error parsing bitcode"; | |
109 LLVMDisposeMemoryBuffer(bref); | |
110 throw new LLVMException(errmsg); | |
111 } | |
112 return new Module(mref); | |
113 } | |
114 /// important to call this when done | |
115 void dispose() | |
116 { | |
117 if (mod) | |
118 { | |
119 registry.remove(mod); | |
120 LLVMDisposeModule(mod); | |
121 mod = null; | |
122 } | |
123 } | |
124 /// | |
125 char[] dataLayout() | |
126 { | |
127 assert(mod !is null); | |
128 return from_stringz(LLVMGetDataLayout(mod)); | |
129 } | |
130 /// | |
131 void dataLayout(char[] dl) | |
132 { | |
133 assert(mod !is null); | |
134 LLVMSetDataLayout(mod, to_stringz(dl)); | |
135 } | |
136 /// | |
137 char[] target() | |
138 { | |
139 assert(mod !is null); | |
140 return from_stringz(LLVMGetTarget(mod)); | |
141 } | |
142 /// | |
143 void target(char[] dl) | |
144 { | |
145 assert(mod !is null); | |
146 LLVMSetTarget(mod, to_stringz(dl)); | |
147 } | |
148 /// | |
149 bool addTypeName(char[] nam, Type t) | |
150 { | |
151 assert(mod !is null); | |
152 return LLVMAddTypeName(mod, to_stringz(nam), t.ll) != 0; | |
153 } | |
154 /// | |
155 Type getTypeByName(char[] name) { | |
156 return getTypeOf(LLVMGetTypeByName(mod, to_stringz(name))); | |
157 } | |
158 /// | |
159 void deleteTypeName(char[] nam) | |
160 { | |
161 assert(mod !is null); | |
162 LLVMDeleteTypeName(mod, to_stringz(nam)); | |
163 } | |
164 /// | |
165 GlobalVariable addGlobal(Type t, char[] nam) | |
166 { | |
167 assert(mod !is null); | |
168 auto c = LLVMAddGlobal(mod, t.ll, to_stringz(nam)); | |
169 assert(c !is null); | |
170 return new GlobalVariable(c, getTypeOf(c)); | |
171 } | |
172 /// Convenience method, type is taken to be that of the initializer | |
173 GlobalVariable addGlobal(Constant initializer, char[] name) | |
174 { | |
175 auto global = addGlobal(initializer.type, name); | |
176 global.initializer = initializer; | |
177 return global; | |
178 } | |
179 /// | |
180 GlobalValue getNamedGlobal(char[] nam) | |
181 { | |
182 assert(mod !is null); | |
183 auto c = LLVMGetNamedGlobal(mod, to_stringz(nam)); | |
184 if (c is null) return null; | |
185 return cast(GlobalValue)getValueOf(c); | |
186 } | |
187 /// | |
188 Function addFunction(Type t, char[] nam) | |
189 { | |
190 assert(mod !is null); | |
191 auto c = LLVMAddFunction(mod, to_stringz(nam), t.ll); | |
192 assert(c !is null); | |
193 return new Function(c, getTypeOf(c)); | |
194 } | |
195 /// | |
196 Function getNamedFunction(char[] nam) | |
197 { | |
198 assert(mod !is null); | |
199 auto c = LLVMGetNamedFunction(mod, to_stringz(nam)); | |
200 if (c is null) return null; | |
201 return cast(Function)getValueOf(c); | |
202 } | |
203 /// | |
204 Function getOrInsertFunction(Type t, char[] nam) | |
205 { | |
206 assert(mod !is null); | |
207 auto c = LLVMGetOrInsertFunction(mod, to_stringz(nam), t.ll); | |
208 auto val = getValueOf(c); | |
209 auto fn = cast(Function) val; | |
210 // Can happen if 'nam' names a function of a different type: | |
211 assert(fn !is null, "Not a function of type " ~ t.toString() ~ ": " ~ val.toString()); | |
212 return fn; | |
213 } | |
214 /// Performs the same optimizations as `opt -std-compile-opts ...' would on the module. | |
215 /// If inline is true, function inlining will be performed. | |
216 void optimize(bool inline) | |
217 { | |
218 LLVMOptimizeModule(mod, inline); | |
219 } | |
220 /// Writes the module to an open file descriptor. Returns true on success. | |
221 bool writeBitcodeToFileHandle(int handle) | |
222 { | |
223 return (LLVMWriteBitcodeToFileHandle(mod, handle) == 0); | |
224 } | |
225 /// Writes the module to the specified path. Returns 0 on success. | |
226 bool writeBitcodeToFile(char[] path) | |
227 { | |
228 return (LLVMWriteBitcodeToFile(mod, to_stringz(path)) == 0); | |
229 } | |
230 /// Throws an exception if the module doesn't pass the LLVM verifier. | |
231 void verify() | |
232 { | |
233 char* msg; | |
234 if (LLVMVerifyModule(mod, LLVMVerifierFailureAction.ReturnStatus, &msg)) | |
235 { | |
236 auto errmsg = from_stringz(msg).dup; | |
237 LLVMDisposeMessage(msg); | |
238 if (errmsg.length == 0) | |
239 errmsg = "Module verification failed"; | |
240 throw new LLVMException(errmsg); | |
241 } | |
242 } | |
243 } | |
244 | |
245 class ModuleProvider | |
246 { | |
247 /// | |
248 private LLVMModuleProviderRef mp; | |
249 /// | |
250 private this(LLVMModuleProviderRef mp) | |
251 { | |
252 this.mp = mp; | |
253 } | |
254 /// Takes ownership of module, returns a ModuleProvider for it. | |
255 static ModuleProvider GetForModule(Module m) | |
256 { | |
257 auto mp = LLVMCreateModuleProviderForExistingModule(m.mod); | |
258 return new ModuleProvider(mp); | |
259 } | |
260 /// Destroys the provided module, unless this MP was passed to an ExecutionEngine. | |
261 void dispose() | |
262 { | |
263 LLVMDisposeModuleProvider(mp); | |
264 mp = null; | |
265 } | |
266 /// Returns a lazily-deserializing ModuleProvider | |
267 static ModuleProvider GetFromBitcode(char[] filename) | |
268 { | |
269 LLVMMemoryBufferRef buf; | |
270 char* msg; | |
271 if (LLVMCreateMemoryBufferWithContentsOfFile(to_stringz(filename), &buf, &msg)) | |
272 { | |
273 auto errmsg = from_stringz(msg).dup; | |
274 LLVMDisposeMessage(msg); | |
275 if (errmsg.length == 0) | |
276 errmsg = "ModuleProvider: Error reading bitcode file"; | |
277 throw new LLVMException(errmsg); | |
278 } | |
279 | |
280 LLVMModuleProviderRef mp; | |
281 // Takes ownership of buffer ... | |
282 if (LLVMGetBitcodeModuleProvider(buf, &mp, &msg)) | |
283 { | |
284 // ... unless it fails, in which case we need to clean it up ourselves | |
285 LLVMDisposeMemoryBuffer(buf); | |
286 | |
287 auto errmsg = from_stringz(msg).dup; | |
288 LLVMDisposeMessage(msg); | |
289 if (errmsg.length == 0) | |
290 errmsg = "Error creating ModuleProvider for bitcode file"; | |
291 throw new LLVMException(errmsg); | |
292 } | |
293 return new ModuleProvider(mp); | |
294 } | |
295 /// | |
296 package LLVMModuleProviderRef ll() | |
297 { | |
298 return mp; | |
299 } | |
300 } | |
301 | |
302 /// | |
303 class Value | |
304 { | |
305 /// | |
306 const LLVMValueRef value; | |
307 /// | |
308 const Type type; | |
309 /// | |
310 this(LLVMValueRef v, Type t=null) { | |
311 value = v; | |
312 if (t is null) t = getTypeOf(v); | |
313 type = t; | |
314 } | |
315 /// | |
316 char[] toString() { | |
317 auto cstr = LLVMValueToString(value); | |
318 auto result = from_stringz(cstr).dup; | |
319 free(cstr); | |
320 return result; | |
321 } | |
322 /// | |
323 ValueKind kind() | |
324 { | |
325 return LLVMGetValueKind(value); | |
326 } | |
327 /// | |
328 char[] name() | |
329 { | |
330 return from_stringz(LLVMGetValueName(value)); | |
331 } | |
332 /// | |
333 void name(char[] s) | |
334 { | |
335 LLVMSetValueName(value, to_stringz(s)); | |
336 } | |
337 /// | |
338 void dump() { | |
339 LLVMDumpValue(value); | |
340 } | |
341 /// | |
342 bool isConstant() | |
343 { | |
344 return LLVMIsConstant(value) != 0; | |
345 } | |
346 /// | |
347 int opEquals(Object o) | |
348 { | |
349 auto v = cast(Value)o; | |
350 if (v is null) return 0; | |
351 if (value is v.value) | |
352 return 1; | |
353 return 0; | |
354 } | |
355 /// invalidates object | |
356 void eraseFromParent() | |
357 { | |
358 LLVMEraseFromParent(value); | |
359 } | |
360 /// ditto | |
361 void replaceAllUsesWith(Value newval) | |
362 { | |
363 LLVMReplaceAllUsesWith(value, newval.value); | |
364 } | |
365 | |
366 /// only for call's | |
367 void callConv(uint CC) | |
368 { | |
369 LLVMSetInstructionCallConv(value, CC); | |
370 } | |
371 /// ditto | |
372 uint callConv() | |
373 { | |
374 return LLVMGetInstructionCallConv(value); | |
375 } | |
376 | |
377 /// only for phi's | |
378 void addIncoming(Value[] inValues, BasicBlock[] inBlocks) | |
379 { | |
380 auto n = inValues.length; | |
381 assert(n == inBlocks.length); | |
382 auto v = new LLVMValueRef[n]; | |
383 auto b = new LLVMBasicBlockRef[n]; | |
384 for (size_t i=0; i<n; i++) { | |
385 v[i] = inValues[i].value; | |
386 b[i] = inBlocks[i].bb; | |
387 } | |
388 LLVMAddIncoming(value, v.ptr, b.ptr, n); | |
389 } | |
390 /// ditto | |
391 uint numIncoming() | |
392 { | |
393 return LLVMCountIncoming(value); | |
394 } | |
395 /// ditto | |
396 Value getIncomingValue(uint index) | |
397 { | |
398 return getValueOf(LLVMGetIncomingValue(value, index)); | |
399 } | |
400 /// ditto | |
401 BasicBlock getIncomingBlock(uint index) | |
402 { | |
403 // TODO bb's should be unique as well | |
404 return new BasicBlock(LLVMGetIncomingBlock(value, index)); | |
405 } | |
406 | |
407 /// only for switch's | |
408 void addCase(Value onval, BasicBlock b) | |
409 { | |
410 LLVMAddCase(value, onval.value, b.bb); | |
411 } | |
412 } | |
413 | |
414 /// | |
415 Value getValueOf(LLVMValueRef v) | |
416 { | |
417 auto kind = LLVMGetValueKind(v); | |
418 switch(kind) | |
419 { | |
420 case ValueKind.Argument: | |
421 case ValueKind.InlineAsm: | |
422 case ValueKind.Instruction: | |
423 return new Value(v); | |
424 | |
425 case ValueKind.Function: | |
426 return new Function(v, getTypeOf(v)); | |
427 | |
428 case ValueKind.GlobalVariable: | |
429 return new GlobalVariable(v, getTypeOf(v)); | |
430 | |
431 case ValueKind.GlobalAlias: | |
432 case ValueKind.UndefValue: | |
433 case ValueKind.ConstantExpr: | |
434 case ValueKind.ConstantAggregateZero: | |
435 case ValueKind.ConstantPointerNull: | |
436 return new Constant(v, getTypeOf(v)); | |
437 | |
438 case ValueKind.ConstantInt: | |
439 return new ConstantInt(v, getTypeOf(v)); | |
440 | |
441 case ValueKind.ConstantFP: | |
442 return new ConstantReal(v, getTypeOf(v)); | |
443 | |
444 case ValueKind.ConstantArray: | |
445 return new ConstantArray(v, getTypeOf(v)); | |
446 | |
447 case ValueKind.ConstantStruct: | |
448 return new ConstantStruct(v, getTypeOf(v)); | |
449 | |
450 case ValueKind.ConstantVector: | |
451 return new ConstantVector(v, getTypeOf(v)); | |
452 | |
453 case ValueKind.BasicBlock: | |
454 default: | |
455 assert(0); | |
456 } | |
457 } | |
458 | |
459 private | |
460 { | |
461 template GenericConstUnaOp(char[] N) | |
462 { | |
463 const GenericConstUnaOp = | |
464 "Constant Get"~N~"(Constant v) { | |
465 auto c = LLVMConst"~N~"(v.value); | |
466 return cast(Constant)getValueOf(c); | |
467 }"; | |
468 } | |
469 | |
470 template GenericConstBinOp(char[] N) | |
471 { | |
472 const GenericConstBinOp = | |
473 "Constant Get"~N~"(Constant l, Constant r) { | |
474 auto c = LLVMConst"~N~"(l.value, r.value); | |
475 return cast(Constant)getValueOf(c); | |
476 }"; | |
477 } | |
478 | |
479 template GenericConstTriOp(char[] N) | |
480 { | |
481 const GenericConstTriOp = | |
482 "Constant Get"~N~"(Constant s, Constant t, Constant u) { | |
483 auto c = LLVMConst"~N~"(s.value, t.value, u.value); | |
484 return cast(Constant)getValueOf(c); | |
485 }"; | |
486 } | |
487 | |
488 template GenericConstCast(char[] N) | |
489 { | |
490 const GenericConstCast = | |
491 "Constant Get"~N~"(Constant v, Type t) { | |
492 auto c = LLVMConst"~N~"(v.value, t.ll); | |
493 return cast(Constant)getValueOf(c); | |
494 }"; | |
495 } | |
496 | |
497 template GenericConstCmp(char[] PRED, char[] N) | |
498 { | |
499 const GenericConstCmp = | |
500 "Constant Get"~N~"("~PRED~"Predicate p, Constant l, Constant r) { | |
501 auto c = LLVMConst"~N~"(p, l.value, r.value); | |
502 return cast(Constant)getValueOf(c); | |
503 }"; | |
504 } | |
505 | |
506 template StringDistribute(alias T, U...) | |
507 { | |
508 static if (!U.length) | |
509 const char[] StringDistribute=""; | |
510 else | |
511 const char[] StringDistribute = T!(U[0]) ~ StringDistribute!(T, U[1..$]); | |
512 } | |
513 } | |
514 | |
515 /// | |
516 class Constant : Value | |
517 { | |
518 /// | |
519 protected this(LLVMValueRef v, Type t) | |
520 { | |
521 super(v,t); | |
522 } | |
523 | |
524 /// | |
525 static Constant GetNull(Type t) | |
526 { | |
527 return cast(Constant)getValueOf(LLVMConstNull(t.ll)); | |
528 } | |
529 /// only for int/vector | |
530 static Constant GetAllOnes(Type t) | |
531 { | |
532 return cast(Constant)getValueOf(LLVMConstAllOnes(t.ll)); | |
533 } | |
534 /// | |
535 static Constant GetUndef(Type t) | |
536 { | |
537 return cast(Constant)getValueOf(LLVMGetUndef(t.ll)); | |
538 } | |
539 /// | |
540 static ConstantInt GetTrue() | |
541 { | |
542 return ConstantInt.GetU(Type.Int1, 1); | |
543 } | |
544 /// | |
545 static ConstantInt GetFalse() | |
546 { | |
547 return ConstantInt.GetU(Type.Int1, 0); | |
548 } | |
549 | |
550 /// | |
551 bool isNull() | |
552 { | |
553 return LLVMIsNull(value) != 0; | |
554 } | |
555 /// | |
556 bool isUndef() | |
557 { | |
558 return LLVMIsUndef(value) != 0; | |
559 } | |
560 | |
561 static | |
562 { | |
563 /// | |
564 mixin(StringDistribute!(GenericConstUnaOp, | |
565 "Neg","Not" | |
566 )); | |
567 /// | |
568 mixin(StringDistribute!(GenericConstBinOp, | |
569 "Add","Sub","Mul","UDiv","SDiv","FDiv","URem","SRem","FRem", | |
570 "And","Or","Xor","Shl","LShr","AShr", | |
571 "ExtractElement" | |
572 )); | |
573 /// | |
574 mixin(StringDistribute!(GenericConstCast, | |
575 "Trunc","SExt","ZExt","FPTrunc","FPExt", | |
576 "UIToFP","SIToFP","FPToUI","FPToSI", | |
577 "PtrToInt","IntToPtr","BitCast" | |
578 )); | |
579 /// | |
580 mixin(StringDistribute!(GenericConstTriOp, | |
581 "Select", | |
582 "InsertElement", | |
583 "ShuffleVector" | |
584 )); | |
585 /// | |
586 mixin(GenericConstCmp!("Int","ICmp")); | |
587 /// | |
588 mixin(GenericConstCmp!("Real","FCmp")); | |
589 /// | |
590 Constant GetGEP(Constant ptr, Constant[] idxs...) | |
591 { | |
592 static if (size_t.max > uint.max) { | |
593 assert(idxs.length <= uint.max, "Ridiculous number of indexes to GEP"); | |
594 } | |
595 auto ar = new LLVMValueRef[idxs.length]; | |
596 foreach(i,v; idxs) ar[i] = v.value; | |
597 auto c = LLVMConstGEP(ptr.value, ar.ptr, ar.length); | |
598 return cast(Constant)getValueOf(c); | |
599 } | |
600 /// | |
601 Constant GetExtractValue(Constant agg, uint[] idxs...) { | |
602 static if (size_t.max > uint.max) { | |
603 assert(idxs.length <= uint.max, "Ridiculous number of indexes to ExtractValue"); | |
604 } | |
605 auto c = LLVMConstExtractValue(agg.value, idxs.ptr, idxs.length); | |
606 return cast(Constant)getValueOf(c); | |
607 } | |
608 /// | |
609 Constant GetInsertValue(Constant agg, Constant elt, uint[] idxs...) { | |
610 static if (size_t.max > uint.max) { | |
611 assert(idxs.length <= uint.max, "Ridiculous number of indexes to InsertValue"); | |
612 } | |
613 auto c = LLVMConstInsertValue(agg.value, elt.value, idxs.ptr, idxs.length); | |
614 return cast(Constant)getValueOf(c); | |
615 } | |
616 /// | |
617 Constant GetSizeOf(Type t) | |
618 { | |
619 return cast(Constant)getValueOf(LLVMSizeOf(t.ll)); | |
620 } | |
621 } | |
622 } | |
623 | |
624 /// | |
625 abstract class ScalarConstant : Constant | |
626 { | |
627 /// | |
628 protected this(LLVMValueRef v, Type t) | |
629 { | |
630 super(v, t); | |
631 } | |
632 } | |
633 | |
634 /// | |
635 class ConstantInt : ScalarConstant | |
636 { | |
637 /// | |
638 private this(LLVMValueRef v, Type t) | |
639 { | |
640 super(v, t); | |
641 } | |
642 /// | |
643 static ConstantInt Get(Type t, ulong N, bool signExt) | |
644 { | |
645 auto c = LLVMConstInt(t.ll, N, signExt); | |
646 return new ConstantInt(c, t); | |
647 } | |
648 /// | |
649 static ConstantInt GetS(Type t, long N) | |
650 { | |
651 return Get(t, cast(ulong)N, true); | |
652 } | |
653 /// | |
654 static ConstantInt GetU(Type t, ulong N) | |
655 { | |
656 return Get(t, N, false); | |
657 } | |
658 } | |
659 | |
660 /// | |
661 class ConstantReal : ScalarConstant | |
662 { | |
663 /// | |
664 private this(LLVMValueRef v, Type t) | |
665 { | |
666 super(v, t); | |
667 } | |
668 /// | |
669 static ConstantReal Get(Type t, real N) | |
670 { | |
671 auto c = LLVMConstReal(t.ll, N); | |
672 return new ConstantReal(c, t); | |
673 } | |
674 } | |
675 | |
676 /// | |
677 abstract class CompositeConstant : Constant | |
678 { | |
679 /// | |
680 protected this(LLVMValueRef v, Type t) | |
681 { | |
682 super(v, t); | |
683 } | |
684 } | |
685 | |
686 /// | |
687 class ConstantArray : CompositeConstant | |
688 { | |
689 /// | |
690 private this(LLVMValueRef v, Type t) | |
691 { | |
692 super(v, t); | |
693 } | |
694 /// | |
695 static ConstantArray Get(Type eltty, Constant[] vals) | |
696 { | |
697 auto p = new LLVMValueRef[vals.length]; | |
698 foreach(i,v; vals) p[i] = v.value; | |
699 auto c = LLVMConstArray(eltty.ll, p.ptr, p.length); | |
700 return new ConstantArray(c, getTypeOf(c)); | |
701 } | |
702 /// | |
703 static ConstantArray GetString(char[] str, bool nullterm) | |
704 { | |
705 auto len = str.length + nullterm; | |
706 auto c = LLVMConstString(str.ptr, str.length, !nullterm); | |
707 return new ConstantArray(c, getTypeOf(c)); | |
708 } | |
709 } | |
710 | |
711 /// | |
712 class ConstantStruct : CompositeConstant | |
713 { | |
714 /// | |
715 private this(LLVMValueRef v, Type t) | |
716 { | |
717 super(v, t); | |
718 } | |
719 /// | |
720 static ConstantStruct Get(Constant[] vals, bool packed=false) | |
721 { | |
722 auto p = new LLVMValueRef[vals.length]; | |
723 foreach(i,v; vals) p[i] = v.value; | |
724 auto c = LLVMConstStruct(p.ptr, p.length, packed); | |
725 return new ConstantStruct(c, getTypeOf(c)); | |
726 } | |
727 } | |
728 | |
729 /// | |
730 class ConstantVector : CompositeConstant | |
731 { | |
732 /// | |
733 private this(LLVMValueRef v, Type t) | |
734 { | |
735 super(v, t); | |
736 } | |
737 /// | |
738 static ConstantVector Get(ScalarConstant[] vals) | |
739 { | |
740 auto p = new LLVMValueRef[vals.length]; | |
741 foreach(i,v; vals) p[i] = v.value; | |
742 auto c = LLVMConstVector(p.ptr, p.length); | |
743 return new ConstantVector(c, getTypeOf(c)); | |
744 } | |
745 } | |
746 | |
747 /// | |
748 abstract class GlobalValue : Constant | |
749 { | |
750 /// | |
751 private this(LLVMValueRef v, Type t) { | |
752 super(v, t); | |
753 } | |
754 /// | |
755 bool isDeclaration() | |
756 { | |
757 return LLVMIsDeclaration(value) != 0; | |
758 } | |
759 /// | |
760 Linkage linkage() | |
761 { | |
762 return LLVMGetLinkage(value); | |
763 } | |
764 /// | |
765 void linkage(Linkage l) | |
766 { | |
767 LLVMSetLinkage(value, l); | |
768 } | |
769 /// | |
770 char[] section() | |
771 { | |
772 return from_stringz(LLVMGetSection(value)); | |
773 } | |
774 /// | |
775 void section(char[] s) | |
776 { | |
777 LLVMSetSection(value, to_stringz(s)); | |
778 } | |
779 /// | |
780 Visibility visibility() | |
781 { | |
782 return LLVMGetVisibility(value); | |
783 } | |
784 /// | |
785 void visibility(Visibility v) | |
786 { | |
787 LLVMSetVisibility(value, v); | |
788 } | |
789 /// | |
790 uint alignment() | |
791 { | |
792 return LLVMGetAlignment(value); | |
793 } | |
794 /// | |
795 void alignment(uint bytes) | |
796 { | |
797 LLVMSetAlignment(value, bytes); | |
798 } | |
799 } | |
800 | |
801 /// | |
802 class GlobalVariable : GlobalValue | |
803 { | |
804 /// TODO: void DeleteGlobal(ValueRef GlobalVar); | |
805 | |
806 /// | |
807 private this(LLVMValueRef v, Type t) { | |
808 super(v, t); | |
809 } | |
810 /// | |
811 bool hasInitializer() | |
812 { | |
813 return isDeclaration() == 0; | |
814 } | |
815 /// | |
816 Constant initializer() | |
817 { | |
818 auto c = LLVMGetInitializer(value); | |
819 if (c is null) return null; | |
820 return cast(Constant)getValueOf(c); | |
821 } | |
822 /// | |
823 void initializer(Constant c) | |
824 { | |
825 LLVMSetInitializer(value, c.value); | |
826 } | |
827 /// | |
828 bool threadLocal() | |
829 { | |
830 return LLVMIsThreadLocal(value) != 0; | |
831 } | |
832 /// | |
833 void threadLocal(bool b) | |
834 { | |
835 LLVMSetThreadLocal(value, b); | |
836 } | |
837 /// | |
838 bool globalConstant() | |
839 { | |
840 return LLVMIsGlobalConstant(value) != 0; | |
841 } | |
842 /// | |
843 void globalConstant(bool b) | |
844 { | |
845 LLVMSetGlobalConstant(value, b); | |
846 } | |
847 } | |
848 | |
849 /// | |
850 class Function : GlobalValue | |
851 { | |
852 /// TODO: void GetParams(ValueRef Fn, ValueRef *Params); | |
853 /// TODO: void GetBasicBlocks(ValueRef Fn, BasicBlockRef *BasicBlocks); | |
854 | |
855 /// | |
856 package this(LLVMValueRef v, Type t) { | |
857 super(v, t); | |
858 } | |
859 /// | |
860 void eraseFromParent() | |
861 { | |
862 LLVMDeleteFunction(value); | |
863 } | |
864 /// | |
865 uint numParams() | |
866 { | |
867 return LLVMCountParams(value); | |
868 } | |
869 /// | |
870 Value getParam(uint idx) | |
871 { | |
872 auto v = LLVMGetParam(value, idx); | |
873 assert(v !is null); | |
874 return getValueOf(v); | |
875 } | |
876 /// | |
877 uint intrinsicID() | |
878 { | |
879 return LLVMGetIntrinsicID(value); | |
880 } | |
881 /// | |
882 uint callConv() | |
883 { | |
884 return LLVMGetFunctionCallConv(value); | |
885 } | |
886 /// | |
887 void callConv(uint cc) | |
888 { | |
889 LLVMSetFunctionCallConv(value, cc); | |
890 } | |
891 /// | |
892 char[] gc() | |
893 { | |
894 return from_stringz(LLVMGetGC(value)); | |
895 } | |
896 /// | |
897 void gc(char[] name) | |
898 { | |
899 LLVMSetGC(value, to_stringz(name)); | |
900 } | |
901 /// | |
902 uint numBasicBlocks() | |
903 { | |
904 return LLVMCountBasicBlocks(value); | |
905 } | |
906 /// | |
907 static BasicBlock InsertBasicBlock(BasicBlock bb, char[] name) | |
908 { | |
909 auto b = LLVMInsertBasicBlock(bb.bb, to_stringz(name)); | |
910 assert(b !is null); | |
911 return new BasicBlock(b); | |
912 } | |
913 /// | |
914 BasicBlock appendBasicBlock(char[] name) | |
915 { | |
916 auto b = LLVMAppendBasicBlock(value, to_stringz(name)); | |
917 assert(b !is null); | |
918 return new BasicBlock(b); | |
919 } | |
920 /// | |
921 BasicBlock getEntryBasicBlock() | |
922 { | |
923 auto b = LLVMGetEntryBasicBlock(value); | |
924 if (b is null) return null; | |
925 return new BasicBlock(b); | |
926 } | |
927 /// Throws an exception if the function doesn't pass the LLVM verifier. | |
928 void verify() | |
929 { | |
930 if (LLVMVerifyFunction(value, LLVMVerifierFailureAction.ReturnStatus)) | |
931 { | |
932 auto exceptionmsg = "Function failed to verify (" ~ name ~ ")"; | |
933 throw new LLVMException(exceptionmsg); | |
934 } | |
935 } | |
936 } | |
937 | |
938 /// | |
939 class BasicBlock | |
940 { | |
941 /// | |
942 LLVMBasicBlockRef bb; | |
943 /// | |
944 this(LLVMBasicBlockRef b) | |
945 { | |
946 assert(b !is null); | |
947 bb = b; | |
948 } | |
949 /// | |
950 this(Value v) | |
951 { | |
952 assert(LLVMValueIsBasicBlock(v.value)); | |
953 bb = LLVMValueAsBasicBlock(v.value); | |
954 } | |
955 /// | |
956 override int opEquals(Object o) { | |
957 auto block = cast(BasicBlock) o; | |
958 if (!block) | |
959 return false; | |
960 return bb == block.bb; | |
961 } | |
962 /// | |
963 void dispose() | |
964 { | |
965 LLVMDeleteBasicBlock(bb); | |
966 bb = null; | |
967 } | |
968 /// | |
969 Function getParent() { | |
970 assert(bb !is null); | |
971 auto func = LLVMGetBasicBlockParent(bb); | |
972 if (!func) return null; | |
973 return new Function(func, getTypeOf(func)); | |
974 } | |
975 /// | |
976 Value asValue() | |
977 { | |
978 assert(bb !is null); | |
979 auto v = LLVMBasicBlockAsValue(bb); | |
980 return new Value(v, Type.Label); | |
981 } | |
982 /// | |
983 bool terminated() | |
984 { | |
985 assert(bb !is null); | |
986 return (LLVMIsTerminated(bb) != 0); | |
987 } | |
988 /// | |
989 bool hasPredecessors() | |
990 { | |
991 assert(bb !is null); | |
992 return (LLVMHasPredecessors(bb) != 0); | |
993 } | |
994 /// | |
995 bool empty() | |
996 { | |
997 assert(bb !is null); | |
998 return (LLVMIsBasicBlockEmpty(bb) != 0); | |
999 } | |
1000 } | |
1001 | |
1002 /// | |
1003 class TargetData | |
1004 { | |
1005 /// | |
1006 private LLVMTargetDataRef target; | |
1007 /// | |
1008 private this(LLVMTargetDataRef td) | |
1009 { | |
1010 target = td; | |
1011 } | |
1012 /// | |
1013 static TargetData Get(char[] str) | |
1014 { | |
1015 return new TargetData(LLVMCreateTargetData(to_stringz(str))); | |
1016 } | |
1017 /// | |
1018 static TargetData Get(Module M) | |
1019 { | |
1020 return new TargetData(LLVMCreateTargetData(to_stringz(M.dataLayout))); | |
1021 } | |
1022 /// invalidates object | |
1023 void dispose() | |
1024 { | |
1025 LLVMDisposeTargetData(target); | |
1026 target = null; | |
1027 } | |
1028 /// | |
1029 size_t getABITypeSize(Type T) | |
1030 { | |
1031 return LLVMABISizeOfType(target, T.ll); | |
1032 } | |
1033 } |