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 }