Mercurial > projects > ldc
comparison tools/binding/llvm/llvm.d @ 1274:4ff9ab0d472c
Check in some old changes to the binding, from before I had commit access.
- Add bindings for InsertValue and ExtractValue
- Updates to use new APIs where they were renamed or removed.
- Add generic error messages if LLVM didn't provide one.
- Enable typesafe variadic arguments for GetGEP.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Mon, 27 Apr 2009 22:34:36 +0200 |
parents | 1ba61de8796b |
children |
comparison
equal
deleted
inserted
replaced
1273:1ba61de8796b | 1274:4ff9ab0d472c |
---|---|
51 /// global registry for 1:1 mapping of ModuleRef's -> Module's | 51 /// global registry for 1:1 mapping of ModuleRef's -> Module's |
52 private static Module[LLVMModuleRef] registry; | 52 private static Module[LLVMModuleRef] registry; |
53 /// | 53 /// |
54 private LLVMModuleRef mod; | 54 private LLVMModuleRef mod; |
55 const char[] name; | 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 | |
56 /// | 63 /// |
57 this(char[] nam) | 64 this(char[] nam) |
58 { | 65 { |
59 name = nam; | 66 name = nam; |
60 mod = LLVMModuleCreateWithName(to_stringz(nam)); | 67 mod = LLVMModuleCreateWithName(to_stringz(nam)); |
84 char* msg; | 91 char* msg; |
85 if (LLVMCreateMemoryBufferWithContentsOfFile(to_stringz(bitcodepath), &bref, &msg)) | 92 if (LLVMCreateMemoryBufferWithContentsOfFile(to_stringz(bitcodepath), &bref, &msg)) |
86 { | 93 { |
87 errmsg = from_stringz(msg).dup; | 94 errmsg = from_stringz(msg).dup; |
88 LLVMDisposeMessage(msg); | 95 LLVMDisposeMessage(msg); |
96 if (errmsg.length == 0) | |
97 errmsg = "Error reading bitcode file"; | |
89 throw new LLVMException(errmsg); | 98 throw new LLVMException(errmsg); |
90 } | 99 } |
91 scope(exit) | 100 scope(exit) |
92 LLVMDisposeMemoryBuffer(bref); | 101 LLVMDisposeMemoryBuffer(bref); |
93 | 102 |
94 if (LLVMParseBitcode(bref, &mref, &msg)) | 103 if (LLVMParseBitcode(bref, &mref, &msg)) |
95 { | 104 { |
96 errmsg = from_stringz(msg).dup; | 105 errmsg = from_stringz(msg).dup; |
97 LLVMDisposeMessage(msg); | 106 LLVMDisposeMessage(msg); |
107 if (errmsg.length == 0) | |
108 errmsg = "Error parsing bitcode"; | |
98 LLVMDisposeMemoryBuffer(bref); | 109 LLVMDisposeMemoryBuffer(bref); |
99 throw new LLVMException(errmsg); | 110 throw new LLVMException(errmsg); |
100 } | 111 } |
101 return new Module(mref); | 112 return new Module(mref); |
102 } | 113 } |
192 /// | 203 /// |
193 Function getOrInsertFunction(Type t, char[] nam) | 204 Function getOrInsertFunction(Type t, char[] nam) |
194 { | 205 { |
195 assert(mod !is null); | 206 assert(mod !is null); |
196 auto c = LLVMGetOrInsertFunction(mod, to_stringz(nam), t.ll); | 207 auto c = LLVMGetOrInsertFunction(mod, to_stringz(nam), t.ll); |
197 assert(c !is null); | 208 auto val = getValueOf(c); |
198 return cast(Function)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; | |
199 } | 213 } |
200 /// Performs the same optimizations as `opt -std-compile-opts ...' would on the module. | 214 /// Performs the same optimizations as `opt -std-compile-opts ...' would on the module. |
201 /// If inline is true, function inlining will be performed. | 215 /// If inline is true, function inlining will be performed. |
202 void optimize(bool inline) | 216 void optimize(bool inline) |
203 { | 217 { |
219 char* msg; | 233 char* msg; |
220 if (LLVMVerifyModule(mod, LLVMVerifierFailureAction.ReturnStatus, &msg)) | 234 if (LLVMVerifyModule(mod, LLVMVerifierFailureAction.ReturnStatus, &msg)) |
221 { | 235 { |
222 auto errmsg = from_stringz(msg).dup; | 236 auto errmsg = from_stringz(msg).dup; |
223 LLVMDisposeMessage(msg); | 237 LLVMDisposeMessage(msg); |
238 if (errmsg.length == 0) | |
239 errmsg = "Module verification failed"; | |
224 throw new LLVMException(errmsg); | 240 throw new LLVMException(errmsg); |
225 } | 241 } |
226 } | 242 } |
227 } | 243 } |
228 | 244 |
254 char* msg; | 270 char* msg; |
255 if (LLVMCreateMemoryBufferWithContentsOfFile(to_stringz(filename), &buf, &msg)) | 271 if (LLVMCreateMemoryBufferWithContentsOfFile(to_stringz(filename), &buf, &msg)) |
256 { | 272 { |
257 auto errmsg = from_stringz(msg).dup; | 273 auto errmsg = from_stringz(msg).dup; |
258 LLVMDisposeMessage(msg); | 274 LLVMDisposeMessage(msg); |
275 if (errmsg.length == 0) | |
276 errmsg = "ModuleProvider: Error reading bitcode file"; | |
259 throw new LLVMException(errmsg); | 277 throw new LLVMException(errmsg); |
260 } | 278 } |
261 | 279 |
262 LLVMModuleProviderRef mp; | 280 LLVMModuleProviderRef mp; |
263 // Takes ownership of buffer ... | 281 // Takes ownership of buffer ... |
266 // ... unless it fails, in which case we need to clean it up ourselves | 284 // ... unless it fails, in which case we need to clean it up ourselves |
267 LLVMDisposeMemoryBuffer(buf); | 285 LLVMDisposeMemoryBuffer(buf); |
268 | 286 |
269 auto errmsg = from_stringz(msg).dup; | 287 auto errmsg = from_stringz(msg).dup; |
270 LLVMDisposeMessage(msg); | 288 LLVMDisposeMessage(msg); |
289 if (errmsg.length == 0) | |
290 errmsg = "Error creating ModuleProvider for bitcode file"; | |
271 throw new LLVMException(errmsg); | 291 throw new LLVMException(errmsg); |
272 } | 292 } |
273 return new ModuleProvider(mp); | 293 return new ModuleProvider(mp); |
274 } | 294 } |
275 /// | 295 /// |
565 /// | 585 /// |
566 mixin(GenericConstCmp!("Int","ICmp")); | 586 mixin(GenericConstCmp!("Int","ICmp")); |
567 /// | 587 /// |
568 mixin(GenericConstCmp!("Real","FCmp")); | 588 mixin(GenericConstCmp!("Real","FCmp")); |
569 /// | 589 /// |
570 Constant GetGEP(Constant ptr, Constant[] idxs) | 590 Constant GetGEP(Constant ptr, Constant[] idxs...) |
571 { | 591 { |
592 static if (size_t.max > uint.max) { | |
593 assert(idxs.length <= uint.max, "Ridiculous number of indexes to GEP"); | |
594 } | |
572 auto ar = new LLVMValueRef[idxs.length]; | 595 auto ar = new LLVMValueRef[idxs.length]; |
573 foreach(i,v; idxs) ar[i] = v.value; | 596 foreach(i,v; idxs) ar[i] = v.value; |
574 auto c = LLVMConstGEP(ptr.value, ar.ptr, ar.length); | 597 auto c = LLVMConstGEP(ptr.value, ar.ptr, ar.length); |
575 return cast(Constant)getValueOf(c); | 598 return cast(Constant)getValueOf(c); |
576 } | 599 } |
577 /// | 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 /// | |
578 Constant GetSizeOf(Type t) | 617 Constant GetSizeOf(Type t) |
579 { | 618 { |
580 return cast(Constant)getValueOf(LLVMSizeOf(t.ll)); | 619 return cast(Constant)getValueOf(LLVMSizeOf(t.ll)); |
581 } | 620 } |
582 } | 621 } |
760 } | 799 } |
761 | 800 |
762 /// | 801 /// |
763 class GlobalVariable : GlobalValue | 802 class GlobalVariable : GlobalValue |
764 { | 803 { |
765 /// TODO: | 804 /// TODO: void DeleteGlobal(ValueRef GlobalVar); |
766 /// void DeleteGlobal(ValueRef GlobalVar); | |
767 | 805 |
768 /// | 806 /// |
769 private this(LLVMValueRef v, Type t) { | 807 private this(LLVMValueRef v, Type t) { |
770 super(v, t); | 808 super(v, t); |
771 } | 809 } |
772 /// | 810 /// |
773 bool hasInitializer() | 811 bool hasInitializer() |
774 { | 812 { |
775 return LLVMHasInitializer(value) != 0; | 813 return isDeclaration() == 0; |
776 } | 814 } |
777 /// | 815 /// |
778 Constant initializer() | 816 Constant initializer() |
779 { | 817 { |
780 auto c = LLVMGetInitializer(value); | 818 auto c = LLVMGetInitializer(value); |
809 } | 847 } |
810 | 848 |
811 /// | 849 /// |
812 class Function : GlobalValue | 850 class Function : GlobalValue |
813 { | 851 { |
814 /// TODO: | 852 /// TODO: void GetParams(ValueRef Fn, ValueRef *Params); |
815 /// void GetParams(ValueRef Fn, ValueRef *Params); | 853 /// TODO: void GetBasicBlocks(ValueRef Fn, BasicBlockRef *BasicBlocks); |
816 /// void GetBasicBlocks(ValueRef Fn, BasicBlockRef *BasicBlocks); | |
817 | 854 |
818 /// | 855 /// |
819 package this(LLVMValueRef v, Type t) { | 856 package this(LLVMValueRef v, Type t) { |
820 super(v, t); | 857 super(v, t); |
821 } | 858 } |
850 void callConv(uint cc) | 887 void callConv(uint cc) |
851 { | 888 { |
852 LLVMSetFunctionCallConv(value, cc); | 889 LLVMSetFunctionCallConv(value, cc); |
853 } | 890 } |
854 /// | 891 /// |
855 char[] collector() | 892 char[] gc() |
856 { | 893 { |
857 return from_stringz(LLVMGetCollector(value)); | 894 return from_stringz(LLVMGetGC(value)); |
858 } | 895 } |
859 /// | 896 /// |
860 void collector(char[] col) | 897 void gc(char[] name) |
861 { | 898 { |
862 LLVMSetCollector(value, to_stringz(col)); | 899 LLVMSetGC(value, to_stringz(name)); |
863 } | 900 } |
864 /// | 901 /// |
865 uint numBasicBlocks() | 902 uint numBasicBlocks() |
866 { | 903 { |
867 return LLVMCountBasicBlocks(value); | 904 return LLVMCountBasicBlocks(value); |