diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..5489172 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,19 @@ + +0.1, 10-May-2008: + + * Initial release. + + +0.2, ongoing: + + * Independent package, need not be unpacked into llvm/bindings + * Modules can be dumped to a string + * Modules can be verified + * Module.global_variables, Module.functions, Function.args, + Function.basic_blocks and BasicBlock.instructions are + now proper iterators (generators in fact) than plain lists + + * MemoryBuffer is done + * TypeHandle is done + * Unit tester added (but doesn't do much for now) + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..73797e2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2008, Mahadevan R All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of the Mahadevan R, llvm-py nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README b/README new file mode 100644 index 0000000..8bee544 --- /dev/null +++ b/README @@ -0,0 +1,37 @@ + +llvm-py: Python Bindings for LLVM +--------------------------------- + + +Home page: +---------- + http://mdevan.nfshost.com/llvm-py.html + http://code.google.com/p/llvm-py/ + + +Quickstart: +---------- + 1. Get 2.4svn version of LLVM, build it. 2.3 or older will *not* work. + LLVM need not be installed. + + 2. Unpack llvm-py, build and install: + + $ tar jxvf llvm-py-0.2.tar.bz2 + $ cd llvm-py-0.2 + + # if you've installed LLVM, and llvm-config is in the path + $ sudo python setup.py install + + # if you've just built LLVM and not installed it, locate llvm-config, + # usually under ../llvm/Release/bin + $ sudo python setup.py install --llvm-config=/path/to/llvm-config + + 3. See examples under 'test' directory. + + +LICENSE: +-------- + llvm-py is distributed under the new BSD license, which is similar to + the LLVM license itself. See the file called LICENSE for the full license + text. + diff --git a/llvm/__init__.py b/llvm/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/llvm/_core.c b/llvm/_core.c new file mode 100644 index 0000000..aedcd88 --- /dev/null +++ b/llvm/_core.c @@ -0,0 +1,932 @@ + +/* our includes */ +#include "wrap.h" +#include "extra.h" + +/* libc includes */ +#include /* for malloc(), free() */ + + +/*===----------------------------------------------------------------------===*/ +/* Modules */ +/*===----------------------------------------------------------------------===*/ + +static PyObject * +_wLLVMModuleCreateWithName(PyObject *self, PyObject *args) +{ + const char *s; + LLVMModuleRef module; + + if (!PyArg_ParseTuple(args, "s", &s)) + return NULL; + + module = LLVMModuleCreateWithName(s); + return ctor_LLVMModuleRef(module); +} + +_wrap_obj2str(LLVMGetDataLayout, LLVMModuleRef) +_wrap_objstr2none(LLVMSetDataLayout, LLVMModuleRef) +_wrap_obj2str(LLVMGetTarget, LLVMModuleRef) +_wrap_objstr2none(LLVMSetTarget, LLVMModuleRef) +_wrap_objstrobj2obj(LLVMAddTypeName, LLVMModuleRef, LLVMTypeRef, int) +_wrap_objstr2none(LLVMDeleteTypeName, LLVMModuleRef) +_wrap_obj2none(LLVMDumpModule, LLVMModuleRef) +_wrap_obj2none(LLVMDisposeModule, LLVMModuleRef) +_wrap_dumper(LLVMDumpModuleToString, LLVMModuleRef) + +static PyObject * +_wLLVMVerifyModule(PyObject *self, PyObject *args) +{ + PyObject *obj; + char *outmsg = 0; + PyObject *ret; + LLVMModuleRef m; + + if (!PyArg_ParseTuple(args, "O", &obj)) + return NULL; + + m = (LLVMModuleRef) PyCObject_AsVoidPtr(obj); + (void) LLVMVerifyModule(m, LLVMReturnStatusAction, &outmsg); + + if (outmsg) { + ret = PyString_FromString(outmsg); + LLVMDisposeMessage(outmsg); + } else { + ret = PyString_FromString(""); + } + + return ret; +} + + +/*===----------------------------------------------------------------------===*/ +/* Types */ +/*===----------------------------------------------------------------------===*/ + +/*===-- General ----------------------------------------------------------===*/ + +_wrap_obj2obj(LLVMGetTypeKind, LLVMTypeRef, int) +_wrap_dumper(LLVMDumpTypeToString, LLVMTypeRef) + +/*===-- Integer types ----------------------------------------------------===*/ + +_wrap_none2obj(LLVMInt1Type, LLVMTypeRef) +_wrap_none2obj(LLVMInt8Type, LLVMTypeRef) +_wrap_none2obj(LLVMInt16Type, LLVMTypeRef) +_wrap_none2obj(LLVMInt32Type, LLVMTypeRef) +_wrap_none2obj(LLVMInt64Type, LLVMTypeRef) +_wrap_int2obj(LLVMIntType, LLVMTypeRef) +_wrap_obj2obj(LLVMGetIntTypeWidth, LLVMTypeRef, int) + +/*===-- Floating-point types ---------------------------------------------===*/ + +_wrap_none2obj(LLVMFloatType, LLVMTypeRef) +_wrap_none2obj(LLVMDoubleType, LLVMTypeRef) +_wrap_none2obj(LLVMX86FP80Type, LLVMTypeRef) +_wrap_none2obj(LLVMFP128Type, LLVMTypeRef) +_wrap_none2obj(LLVMPPCFP128Type, LLVMTypeRef) + +/*===-- Function types ---------------------------------------------------===*/ + +_wrap_objlistint2obj(LLVMFunctionType, LLVMTypeRef, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMIsFunctionVarArg, LLVMTypeRef, int) +_wrap_obj2obj(LLVMGetReturnType, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMCountParamTypes, LLVMTypeRef, int) + +/* The LLVMGetParamTypes and LLVMGetStructElementTypes functions both + * have the same signatures. The following implementation takes advantage + * of this. + */ + +typedef void (*obj2arr_fn_t)(LLVMTypeRef ty, LLVMTypeRef *outv); +typedef unsigned (*arrcnt_fn_t)(LLVMTypeRef ty); + +static PyObject * +obj2arr(PyObject *self, PyObject *args, arrcnt_fn_t cntfunc, obj2arr_fn_t arrfunc) +{ + LLVMTypeRef type, *param_types; + unsigned param_count; + PyObject *list; + + /* get the function object ptr */ + if (!(type = (LLVMTypeRef)get_object_arg(args))) + return NULL; + + /* get param count */ + param_count = cntfunc(type); + + /* alloc enough space for all of them */ + if (!(param_types = (LLVMTypeRef *)malloc(sizeof(LLVMTypeRef) * param_count))) + return PyErr_NoMemory(); + + /* call LLVM func */ + arrfunc(type, param_types); + + /* create a list from the array */ + list = make_list_from_LLVMTypeRef_array(param_types, param_count); + + /* free temp storage */ + free(param_types); + + return list; +} + +static PyObject * +_wLLVMGetFunctionTypeParams(PyObject *self, PyObject *args) +{ + return obj2arr(self, args, LLVMCountParamTypes, LLVMGetParamTypes); +} + +/*===-- Struct types -----------------------------------------------------===*/ + +_wrap_listint2obj(LLVMStructType, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMCountStructElementTypes, LLVMTypeRef, int) + +static PyObject * +_wLLVMGetStructElementTypes(PyObject *self, PyObject *args) +{ + return obj2arr(self, args, LLVMCountStructElementTypes, LLVMGetStructElementTypes); +} + +_wrap_obj2obj(LLVMIsPackedStruct, LLVMTypeRef, int) + +/*===-- Array types ------------------------------------------------------===*/ + +_wrap_objint2obj(LLVMArrayType, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMGetElementType, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMGetArrayLength, LLVMTypeRef, int) + +/*===-- Pointer types ----------------------------------------------------===*/ + +_wrap_objint2obj(LLVMPointerType, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMGetPointerAddressSpace, LLVMTypeRef, int) + +/*===-- Vector type ------------------------------------------------------===*/ + +_wrap_objint2obj(LLVMVectorType, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMGetVectorSize, LLVMTypeRef, int) + +/*===-- Other types ------------------------------------------------------===*/ + +_wrap_none2obj(LLVMVoidType, LLVMTypeRef) +_wrap_none2obj(LLVMLabelType, LLVMTypeRef) +_wrap_none2obj(LLVMOpaqueType, LLVMTypeRef) + +/*===-- Type handles -----------------------------------------------------===*/ + +_wrap_obj2obj(LLVMCreateTypeHandle, LLVMTypeRef, LLVMTypeHandleRef) +_wrap_objobj2none(LLVMRefineType, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMResolveTypeHandle, LLVMTypeHandleRef, LLVMTypeRef) +_wrap_obj2none(LLVMDisposeTypeHandle, LLVMTypeHandleRef) + + +/*===----------------------------------------------------------------------===*/ +/* Values */ +/*===----------------------------------------------------------------------===*/ + +/* Operations on all values */ + +_wrap_obj2obj(LLVMTypeOf, LLVMValueRef, LLVMTypeRef) +_wrap_obj2str(LLVMGetValueName, LLVMValueRef) +_wrap_objstr2none(LLVMSetValueName, LLVMValueRef) +_wrap_obj2none(LLVMDumpValue, LLVMValueRef) +_wrap_dumper(LLVMDumpValueToString, LLVMValueRef) + +/*===-- Constant Values --------------------------------------------------===*/ + +/* Operations on constants of any type */ + +_wrap_obj2obj(LLVMConstNull, LLVMTypeRef, LLVMValueRef) +_wrap_obj2obj(LLVMConstAllOnes, LLVMTypeRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetUndef, LLVMTypeRef, LLVMValueRef) +_wrap_obj2obj(LLVMIsConstant, LLVMValueRef, int) +_wrap_obj2obj(LLVMIsNull, LLVMValueRef, int) +_wrap_obj2obj(LLVMIsUndef, LLVMValueRef, int) + +/* Operations on scalar constants */ + +static PyObject * +_wLLVMConstInt(PyObject *self, PyObject *args) +{ + PyObject *obj; + unsigned long long n; + int sign_extend; + LLVMTypeRef ty; + LLVMValueRef val; + + if (!PyArg_ParseTuple(args, "OKi", &obj, &n, &sign_extend)) + return NULL; + + ty = (LLVMTypeRef)(PyCObject_AsVoidPtr(obj)); + val = LLVMConstInt(ty, n, sign_extend); + return ctor_LLVMValueRef(val); +} + +static PyObject * +_wLLVMConstReal(PyObject *self, PyObject *args) +{ + PyObject *obj; + double d; + LLVMTypeRef ty; + LLVMValueRef val; + + if (!PyArg_ParseTuple(args, "Od", &obj, &d)) + return NULL; + + ty = (LLVMTypeRef)(PyCObject_AsVoidPtr(obj)); + val = LLVMConstReal(ty, d); + return ctor_LLVMValueRef(val); +} + +_wrap_objstr2obj(LLVMConstRealOfString, LLVMTypeRef, LLVMValueRef) + +/* Operations on composite constants */ + +static PyObject * +_wLLVMConstString(PyObject *self, PyObject *args) +{ + const char *s; + int dont_null_terminate; + LLVMValueRef val; + + if (!PyArg_ParseTuple(args, "si", &s, &dont_null_terminate)) + return NULL; + + val = LLVMConstString(s, strlen(s), dont_null_terminate); + return ctor_LLVMValueRef(val); +} + +_wrap_objlist2obj(LLVMConstArray, LLVMTypeRef, LLVMValueRef, LLVMValueRef) +_wrap_listint2obj(LLVMConstStruct, LLVMValueRef, LLVMValueRef) +_wrap_list2obj(LLVMConstVector, LLVMValueRef, LLVMValueRef) + +/* Constant expressions */ + +_wrap_obj2obj(LLVMSizeOf, LLVMTypeRef, LLVMValueRef) +_wrap_obj2obj(LLVMConstNeg, LLVMValueRef, LLVMValueRef) +_wrap_obj2obj(LLVMConstNot, LLVMValueRef, LLVMValueRef) + +_wrap_objobj2obj(LLVMConstAdd, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstSub, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstMul, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstUDiv, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstSDiv, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFDiv, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstURem, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstSRem, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFRem, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstAnd, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstOr, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstXor, LLVMValueRef, LLVMValueRef, LLVMValueRef) + +_wrap_intobjobj2obj(LLVMConstICmp, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_intobjobj2obj(LLVMConstFCmp, LLVMValueRef, LLVMValueRef, LLVMValueRef) + +_wrap_objobj2obj(LLVMConstShl, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstLShr, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstAShr, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objlist2obj(LLVMConstGEP, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstTrunc, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstSExt, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstZExt, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFPTrunc, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFPExt, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstUIToFP, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstSIToFP, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFPToUI, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFPToSI, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstPtrToInt, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstIntToPtr, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstBitCast, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobj2obj(LLVMConstSelect, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstExtractElement, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobj2obj(LLVMConstInsertElement, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobj2obj(LLVMConstShuffleVector, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) + + +/*===----------------------------------------------------------------------===*/ +/* Globals */ +/*===----------------------------------------------------------------------===*/ + +/*===-- Globals ----------------------------------------------------------===*/ + +_wrap_obj2obj(LLVMGetGlobalParent, LLVMValueRef, LLVMModuleRef) +_wrap_obj2obj(LLVMIsDeclaration, LLVMValueRef, int) +_wrap_obj2obj(LLVMGetLinkage, LLVMValueRef, int) +_wrap_objint2none(LLVMSetLinkage, LLVMValueRef) +_wrap_obj2str(LLVMGetSection, LLVMValueRef) +_wrap_objstr2none(LLVMSetSection, LLVMValueRef) +_wrap_obj2obj(LLVMGetVisibility, LLVMValueRef, int) +_wrap_objint2none(LLVMSetVisibility, LLVMValueRef) +_wrap_obj2obj(LLVMGetAlignment, LLVMValueRef, int) +_wrap_objint2none(LLVMSetAlignment, LLVMValueRef) + +/*===-- Global Variables -------------------------------------------------===*/ + +_wrap_objobjstr2obj(LLVMAddGlobal, LLVMModuleRef, LLVMTypeRef, LLVMValueRef) +_wrap_objstr2obj(LLVMGetNamedGlobal, LLVMModuleRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetFirstGlobal, LLVMModuleRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetNextGlobal, LLVMValueRef, LLVMValueRef) +_wrap_obj2none(LLVMDeleteGlobal, LLVMValueRef) +_wrap_obj2obj(LLVMHasInitializer, LLVMValueRef, int) +_wrap_obj2obj(LLVMGetInitializer, LLVMValueRef, LLVMValueRef) +_wrap_objobj2none(LLVMSetInitializer, LLVMValueRef, LLVMValueRef) +_wrap_objint2none(LLVMSetThreadLocal, LLVMValueRef) +_wrap_objint2none(LLVMSetGlobalConstant, LLVMValueRef) +_wrap_obj2obj(LLVMIsThreadLocal, LLVMValueRef, int) +_wrap_obj2obj(LLVMIsGlobalConstant, LLVMValueRef, int) + +/*===-- Functions --------------------------------------------------------===*/ + +_wrap_objstrobj2obj(LLVMAddFunction, LLVMModuleRef, LLVMTypeRef, LLVMValueRef) +_wrap_objstr2obj(LLVMGetNamedFunction, LLVMModuleRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetFirstFunction, LLVMModuleRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetNextFunction, LLVMValueRef, LLVMValueRef) +_wrap_obj2none(LLVMDeleteFunction, LLVMValueRef) +_wrap_obj2obj(LLVMGetIntrinsicID, LLVMValueRef, int) +_wrap_obj2obj(LLVMGetFunctionCallConv, LLVMValueRef, int) +_wrap_objint2none(LLVMSetFunctionCallConv, LLVMValueRef) +_wrap_obj2str(LLVMGetCollector, LLVMValueRef) +_wrap_objstr2none(LLVMSetCollector, LLVMValueRef) +_wrap_objint2obj(LLVMVerifyFunction, LLVMValueRef, int) + +/*===-- Arguments --------------------------------------------------------===*/ + +_wrap_obj2obj(LLVMCountParams, LLVMValueRef, int) +_wrap_obj2obj(LLVMGetFirstParam, LLVMValueRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetNextParam, LLVMValueRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetParamParent, LLVMValueRef, LLVMValueRef) +_wrap_objint2none(LLVMAddParamAttr, LLVMValueRef) +_wrap_objint2none(LLVMRemoveParamAttr, LLVMValueRef) +_wrap_objint2none(LLVMSetParamAlignment, LLVMValueRef) + +/*===-- Basic Blocks -----------------------------------------------------===*/ + +_wrap_obj2obj(LLVMGetBasicBlockParent, LLVMBasicBlockRef, LLVMValueRef) +_wrap_obj2obj(LLVMCountBasicBlocks, LLVMValueRef, int) +_wrap_obj2obj(LLVMGetFirstBasicBlock, LLVMValueRef, LLVMBasicBlockRef) +_wrap_obj2obj(LLVMGetNextBasicBlock, LLVMBasicBlockRef, LLVMBasicBlockRef) +_wrap_obj2obj(LLVMGetEntryBasicBlock, LLVMValueRef, LLVMBasicBlockRef) +_wrap_objstr2obj(LLVMAppendBasicBlock, LLVMValueRef, LLVMBasicBlockRef) +_wrap_objstr2obj(LLVMInsertBasicBlock, LLVMBasicBlockRef, LLVMBasicBlockRef) +_wrap_obj2none(LLVMDeleteBasicBlock, LLVMBasicBlockRef) + +/*===-- Instructions -----------------------------------------------------===*/ + +_wrap_obj2obj(LLVMGetInstructionParent, LLVMValueRef, LLVMBasicBlockRef) +_wrap_obj2obj(LLVMGetFirstInstruction, LLVMBasicBlockRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetNextInstruction, LLVMValueRef, LLVMValueRef) + +/*===-- Call Sites (Call or Invoke) --------------------------------------===*/ + +_wrap_objint2none(LLVMSetInstructionCallConv, LLVMValueRef) +_wrap_obj2obj(LLVMGetInstructionCallConv, LLVMValueRef, int) +_wrap_objintint2none(LLVMAddInstrParamAttr, LLVMValueRef) +_wrap_objintint2none(LLVMRemoveInstrParamAttr, LLVMValueRef) +_wrap_objintint2none(LLVMSetInstrParamAlignment, LLVMValueRef) + +/*===-- PHI Nodes --------------------------------------------------------===*/ + +static void LLVMAddIncoming1(LLVMValueRef PhiNode, LLVMValueRef IncomingValue, LLVMBasicBlockRef IncomingBlock) +{ + LLVMAddIncoming(PhiNode, &IncomingValue, &IncomingBlock, 1); +} + +_wrap_objobjobj2none(LLVMAddIncoming1, LLVMValueRef, LLVMValueRef, LLVMBasicBlockRef) +_wrap_obj2obj(LLVMCountIncoming, LLVMValueRef, int) +_wrap_objint2obj(LLVMGetIncomingValue, LLVMValueRef, LLVMValueRef) +_wrap_objint2obj(LLVMGetIncomingBlock, LLVMValueRef, LLVMBasicBlockRef) + +/*===-- Instruction builders ----------------------------------------------===*/ + +_wrap_none2obj(LLVMCreateBuilder, LLVMBuilderRef) + +static PyObject * +_wLLVMPositionBuilder(PyObject *self, PyObject *args) +{ + PyObject *obj1, *obj2, *obj3 = 0; + LLVMBuilderRef builder; + LLVMBasicBlockRef block; + LLVMValueRef instr = NULL; + + if (!PyArg_ParseTuple(args, "OO|O", &obj1, &obj2, &obj3)) + return NULL; + + builder = (LLVMBuilderRef) (PyCObject_AsVoidPtr(obj1)); + block = (LLVMBasicBlockRef)(PyCObject_AsVoidPtr(obj2)); + if (obj3) /* optional */ + instr = (LLVMValueRef)(PyCObject_AsVoidPtr(obj3)); + + LLVMPositionBuilder(builder, block, instr); + Py_RETURN_NONE; +} + +_wrap_objobj2none(LLVMPositionBuilderBefore, LLVMBuilderRef, LLVMValueRef) +_wrap_objobj2none(LLVMPositionBuilderAtEnd, LLVMBuilderRef, LLVMBasicBlockRef) +_wrap_obj2obj(LLVMGetInsertBlock, LLVMBuilderRef, LLVMBasicBlockRef) +_wrap_obj2none(LLVMDisposeBuilder, LLVMBuilderRef) + +/* Terminators */ + +_wrap_obj2obj(LLVMBuildRetVoid, LLVMBuilderRef, LLVMValueRef) +_wrap_objobj2obj(LLVMBuildRet, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMBuildBr, LLVMBuilderRef, LLVMBasicBlockRef, LLVMValueRef) +_wrap_objobjobjobj2obj(LLVMBuildCondBr, LLVMBuilderRef, LLVMValueRef, LLVMBasicBlockRef, LLVMBasicBlockRef, LLVMValueRef) +_wrap_objobjobjint2obj(LLVMBuildSwitch, LLVMBuilderRef, LLVMValueRef, LLVMBasicBlockRef, LLVMValueRef) + +static PyObject * +_wLLVMBuildInvoke(PyObject *self, PyObject *args) +{ + PyObject *obj1, *obj2, *obj3, *obj4, *obj5; + const char *name; + LLVMBuilderRef builder; + LLVMValueRef func; + LLVMValueRef *fnargs; + unsigned fnarg_count; + LLVMBasicBlockRef then_blk, catch_blk; + LLVMValueRef inst; + + if (!PyArg_ParseTuple(args, "OOOOOs", &obj1, &obj2, &obj3, &obj4, &obj5, &name)) + return NULL; + + builder = (LLVMBuilderRef)(PyCObject_AsVoidPtr(obj1)); + func = (LLVMValueRef)(PyCObject_AsVoidPtr(obj2)); + fnarg_count = (unsigned) PyList_Size(obj3); + fnargs = (LLVMValueRef *)make_array_from_list(obj3, fnarg_count); + if (!fnargs) + return PyErr_NoMemory(); + then_blk = (LLVMBasicBlockRef)(PyCObject_AsVoidPtr(obj4)); + catch_blk = (LLVMBasicBlockRef)(PyCObject_AsVoidPtr(obj5)); + + inst = LLVMBuildInvoke(builder, func, fnargs, fnarg_count, then_blk, catch_blk, name); + + free(fnargs); + + return ctor_LLVMValueRef(inst); +} + +_wrap_obj2obj(LLVMBuildUnwind, LLVMBuilderRef, LLVMValueRef) +_wrap_obj2obj(LLVMBuildUnreachable, LLVMBuilderRef, LLVMValueRef) + +/* Add a case to the switch instruction */ + +_wrap_objobjobj2none(LLVMAddCase, LLVMValueRef, LLVMValueRef, LLVMBasicBlockRef) + +/* Arithmetic */ + +_wrap_objobjobjstr2obj(LLVMBuildAdd, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildSub, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildMul, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildUDiv, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildSDiv, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFDiv, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildURem, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildSRem, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFRem, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildShl, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildLShr, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildAShr, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildAnd, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildOr, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildXor, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjstr2obj(LLVMBuildNeg, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjstr2obj(LLVMBuildNot, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) + +/* Memory */ + +_wrap_objobjstr2obj(LLVMBuildMalloc, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildArrayMalloc, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjstr2obj(LLVMBuildAlloca, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildArrayAlloca, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMBuildFree, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjstr2obj(LLVMBuildLoad, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobj2obj(LLVMBuildStore, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjliststr2obj(LLVMBuildGEP, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) + +/* Casts */ + +_wrap_objobjobjstr2obj(LLVMBuildTrunc, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildZExt, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildSExt, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFPToUI, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFPToSI, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildUIToFP, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildSIToFP, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFPTrunc, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFPExt, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildPtrToInt, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildIntToPtr, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildBitCast, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) + +/* Comparisons */ + +_wrap_objintobjobjstr2obj(LLVMBuildICmp, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objintobjobjstr2obj(LLVMBuildFCmp, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) + +/* Miscellaneous instructions */ + +_wrap_objobjstr2obj(LLVMBuildPhi, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjliststr2obj(LLVMBuildCall, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjobjstr2obj(LLVMBuildSelect, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildVAArg, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildExtractElement, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjobjstr2obj(LLVMBuildInsertElement, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjobjstr2obj(LLVMBuildShuffleVector, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) + + +/*===----------------------------------------------------------------------===*/ +/* Modules Providers */ +/*===----------------------------------------------------------------------===*/ + +_wrap_obj2obj(LLVMCreateModuleProviderForExistingModule, LLVMModuleRef, LLVMModuleProviderRef) +_wrap_obj2none(LLVMDisposeModuleProvider, LLVMModuleProviderRef) + + +/*===----------------------------------------------------------------------===*/ +/* Memory Buffer */ +/*===----------------------------------------------------------------------===*/ + +static PyObject * +_wLLVMCreateMemoryBufferWithContentsOfFile(PyObject *self, PyObject *args) +{ + const char *path; + LLVMMemoryBufferRef ref; + char *outmsg; + PyObject *ret; + + if (!PyArg_ParseTuple(args, "s", &path)) + return NULL; + + if (!LLVMCreateMemoryBufferWithContentsOfFile(path, &ref, &outmsg)) { + ret = ctor_LLVMMemoryBufferRef(ref); + } else { + ret = PyString_FromString(outmsg); + LLVMDisposeMessage(outmsg); + } + + return ret; +} + +static PyObject * +_wLLVMCreateMemoryBufferWithSTDIN(PyObject *self, PyObject *args) +{ + LLVMMemoryBufferRef ref; + char *outmsg; + PyObject *ret; + + if (!LLVMCreateMemoryBufferWithSTDIN(&ref, &outmsg)) { + ret = ctor_LLVMMemoryBufferRef(ref); + } else { + ret = PyString_FromString(outmsg); + LLVMDisposeMessage(outmsg); + } + + return ret; +} + +_wrap_obj2none(LLVMDisposeMemoryBuffer, LLVMMemoryBufferRef) + + +/*===----------------------------------------------------------------------===*/ +/* Pass Manager */ +/*===----------------------------------------------------------------------===*/ + +_wrap_none2obj(LLVMCreatePassManager, LLVMPassManagerRef) +_wrap_obj2obj(LLVMCreateFunctionPassManager, LLVMModuleProviderRef, LLVMPassManagerRef) +_wrap_objobj2obj(LLVMRunPassManager, LLVMPassManagerRef, LLVMModuleRef, int) +_wrap_obj2obj(LLVMInitializeFunctionPassManager, LLVMPassManagerRef, int) +_wrap_objobj2obj(LLVMRunFunctionPassManager, LLVMPassManagerRef, LLVMValueRef, int) +_wrap_obj2obj(LLVMFinalizeFunctionPassManager, LLVMPassManagerRef, int) +_wrap_obj2none(LLVMDisposePassManager, LLVMPassManagerRef) + + +/*===----------------------------------------------------------------------===*/ +/* Python member method table */ +/*===----------------------------------------------------------------------===*/ + +#define _method( func ) { # func , _w ## func , METH_VARARGS }, + +static PyMethodDef core_methods[] = { + + /* Modules */ + _method( LLVMModuleCreateWithName ) + _method( LLVMGetDataLayout ) + _method( LLVMSetDataLayout ) + _method( LLVMGetTarget ) + _method( LLVMSetTarget ) + _method( LLVMAddTypeName ) + _method( LLVMDeleteTypeName ) + _method( LLVMDumpModule ) + _method( LLVMDisposeModule ) + _method( LLVMDumpModuleToString ) + _method( LLVMVerifyModule ) + + /* Types */ + + /* General */ + _method( LLVMGetTypeKind ) + _method( LLVMDumpTypeToString ) + + /* Integer types */ + _method( LLVMInt1Type ) + _method( LLVMInt8Type ) + _method( LLVMInt16Type ) + _method( LLVMInt32Type ) + _method( LLVMInt64Type ) + _method( LLVMIntType ) + _method( LLVMGetIntTypeWidth ) + + /* Floating-point types */ + _method( LLVMFloatType ) + _method( LLVMDoubleType ) + _method( LLVMX86FP80Type ) + _method( LLVMFP128Type ) + _method( LLVMPPCFP128Type ) + + /* Function types */ + _method( LLVMFunctionType ) + _method( LLVMIsFunctionVarArg ) + _method( LLVMGetReturnType ) + _method( LLVMCountParamTypes ) + _method( LLVMGetFunctionTypeParams ) + + /* Struct types */ + _method( LLVMStructType ) + _method( LLVMCountStructElementTypes ) + _method( LLVMGetStructElementTypes ) + _method( LLVMIsPackedStruct ) + + /* Array types */ + _method( LLVMArrayType ) + _method( LLVMGetElementType ) + _method( LLVMGetArrayLength ) + + /* Pointer types */ + _method( LLVMPointerType ) + _method( LLVMGetPointerAddressSpace ) + + /* Vector type */ + _method( LLVMVectorType ) + _method( LLVMGetVectorSize ) + + /* Other types */ + _method( LLVMVoidType ) + _method( LLVMLabelType ) + _method( LLVMOpaqueType ) + + /* Type handles */ + _method( LLVMCreateTypeHandle ) + _method( LLVMRefineType ) + _method( LLVMResolveTypeHandle ) + _method( LLVMDisposeTypeHandle ) + + /* Values */ + + /* Operations on all values */ + _method( LLVMTypeOf ) + _method( LLVMGetValueName ) + _method( LLVMSetValueName ) + _method( LLVMDumpValue ) + _method( LLVMDumpValueToString ) + + /* Constant Values */ + + /* Operations on constants of any type */ + _method( LLVMConstNull ) + _method( LLVMConstAllOnes ) + _method( LLVMGetUndef ) + _method( LLVMIsConstant ) + _method( LLVMIsNull ) + _method( LLVMIsUndef ) + + /* Operations on scalar constants */ + _method( LLVMConstInt ) + _method( LLVMConstReal ) + _method( LLVMConstRealOfString ) + + /* Operations on composite constants */ + _method( LLVMConstString ) + _method( LLVMConstArray ) + _method( LLVMConstStruct ) + _method( LLVMConstVector ) + + /* Constant expressions */ + _method( LLVMSizeOf ) + _method( LLVMConstNeg ) + _method( LLVMConstNot ) + _method( LLVMConstAdd ) + _method( LLVMConstSub ) + _method( LLVMConstMul ) + _method( LLVMConstUDiv ) + _method( LLVMConstSDiv ) + _method( LLVMConstFDiv ) + _method( LLVMConstURem ) + _method( LLVMConstSRem ) + _method( LLVMConstFRem ) + _method( LLVMConstAnd ) + _method( LLVMConstOr ) + _method( LLVMConstXor ) + _method( LLVMConstICmp ) + _method( LLVMConstFCmp ) + _method( LLVMConstShl ) + _method( LLVMConstLShr ) + _method( LLVMConstAShr ) + _method( LLVMConstGEP ) + _method( LLVMConstTrunc ) + _method( LLVMConstSExt ) + _method( LLVMConstZExt ) + _method( LLVMConstFPTrunc ) + _method( LLVMConstFPExt ) + _method( LLVMConstUIToFP ) + _method( LLVMConstSIToFP ) + _method( LLVMConstFPToUI ) + _method( LLVMConstFPToSI ) + _method( LLVMConstPtrToInt ) + _method( LLVMConstIntToPtr ) + _method( LLVMConstBitCast ) + _method( LLVMConstSelect ) + _method( LLVMConstExtractElement ) + _method( LLVMConstInsertElement ) + _method( LLVMConstShuffleVector ) + + /* Globals */ + + /* Globals (general) */ + _method( LLVMGetGlobalParent ) + _method( LLVMIsDeclaration ) + _method( LLVMGetLinkage ) + _method( LLVMSetLinkage ) + _method( LLVMGetSection ) + _method( LLVMSetSection ) + _method( LLVMGetVisibility ) + _method( LLVMSetVisibility ) + _method( LLVMGetAlignment ) + _method( LLVMSetAlignment ) + + /* Global Variables */ + _method( LLVMAddGlobal ) + _method( LLVMGetNamedGlobal ) + _method( LLVMGetFirstGlobal ) + _method( LLVMGetNextGlobal ) + _method( LLVMDeleteGlobal ) + _method( LLVMHasInitializer ) + _method( LLVMGetInitializer ) + _method( LLVMSetInitializer ) + _method( LLVMSetThreadLocal ) + _method( LLVMSetGlobalConstant ) + _method( LLVMIsThreadLocal ) + _method( LLVMIsGlobalConstant ) + + /* Functions */ + _method( LLVMAddFunction ) + _method( LLVMGetNamedFunction ) + _method( LLVMGetFirstFunction ) + _method( LLVMGetNextFunction ) + _method( LLVMDeleteFunction ) + _method( LLVMGetIntrinsicID ) + _method( LLVMGetFunctionCallConv ) + _method( LLVMSetFunctionCallConv ) + _method( LLVMGetCollector ) + _method( LLVMSetCollector ) + _method( LLVMVerifyFunction ) + + /* Arguments */ + _method( LLVMCountParams ) + _method( LLVMGetFirstParam ) + _method( LLVMGetNextParam ) + _method( LLVMGetParamParent ) + _method( LLVMAddParamAttr ) + _method( LLVMRemoveParamAttr ) + _method( LLVMSetParamAlignment ) + + /* Basic Blocks */ + _method( LLVMGetBasicBlockParent ) + _method( LLVMCountBasicBlocks ) + _method( LLVMGetFirstBasicBlock ) + _method( LLVMGetNextBasicBlock ) + _method( LLVMGetEntryBasicBlock ) + _method( LLVMAppendBasicBlock ) + _method( LLVMInsertBasicBlock ) + _method( LLVMDeleteBasicBlock ) + + /* Instructions */ + _method( LLVMGetInstructionParent ) + _method( LLVMGetFirstInstruction ) + _method( LLVMGetNextInstruction ) + + /* Call Sites (Call or Invoke) */ + _method( LLVMSetInstructionCallConv ) + _method( LLVMGetInstructionCallConv ) + _method( LLVMAddInstrParamAttr ) + _method( LLVMRemoveInstrParamAttr ) + _method( LLVMSetInstrParamAlignment ) + + /* PHI Nodes */ + _method( LLVMAddIncoming1 ) + _method( LLVMCountIncoming ) + _method( LLVMGetIncomingValue ) + _method( LLVMGetIncomingBlock ) + + /* Instruction builders */ + _method( LLVMCreateBuilder ) + _method( LLVMPositionBuilder ) + _method( LLVMPositionBuilderBefore ) + _method( LLVMPositionBuilderAtEnd ) + _method( LLVMGetInsertBlock ) + _method( LLVMDisposeBuilder ) + + /* Terminators */ + _method( LLVMBuildRetVoid ) + _method( LLVMBuildRet ) + _method( LLVMBuildBr ) + _method( LLVMBuildCondBr ) + _method( LLVMBuildSwitch ) + _method( LLVMBuildInvoke ) + _method( LLVMBuildUnwind ) + _method( LLVMBuildUnreachable ) + + /* Add a case to the switch instruction */ + _method( LLVMAddCase ) + + /* Arithmetic */ + _method( LLVMBuildAdd ) + _method( LLVMBuildSub ) + _method( LLVMBuildMul ) + _method( LLVMBuildUDiv ) + _method( LLVMBuildSDiv ) + _method( LLVMBuildFDiv ) + _method( LLVMBuildURem ) + _method( LLVMBuildSRem ) + _method( LLVMBuildFRem ) + _method( LLVMBuildShl ) + _method( LLVMBuildLShr ) + _method( LLVMBuildAShr ) + _method( LLVMBuildAnd ) + _method( LLVMBuildOr ) + _method( LLVMBuildXor ) + _method( LLVMBuildNeg ) + _method( LLVMBuildNot ) + + /* Memory */ + _method( LLVMBuildMalloc ) + _method( LLVMBuildArrayMalloc ) + _method( LLVMBuildAlloca ) + _method( LLVMBuildArrayAlloca ) + _method( LLVMBuildFree ) + _method( LLVMBuildLoad ) + _method( LLVMBuildStore ) + _method( LLVMBuildGEP ) + + /* Casts */ + _method( LLVMBuildTrunc ) + _method( LLVMBuildZExt ) + _method( LLVMBuildSExt ) + _method( LLVMBuildFPToUI ) + _method( LLVMBuildFPToSI ) + _method( LLVMBuildUIToFP ) + _method( LLVMBuildSIToFP ) + _method( LLVMBuildFPTrunc ) + _method( LLVMBuildFPExt ) + _method( LLVMBuildPtrToInt ) + _method( LLVMBuildIntToPtr ) + _method( LLVMBuildBitCast ) + + /* Comparisons */ + _method( LLVMBuildICmp ) + _method( LLVMBuildFCmp ) + + /* Miscellaneous instructions */ + _method( LLVMBuildPhi ) + _method( LLVMBuildCall ) + _method( LLVMBuildSelect ) + _method( LLVMBuildVAArg ) + _method( LLVMBuildExtractElement ) + _method( LLVMBuildInsertElement ) + _method( LLVMBuildShuffleVector ) + + /* Modules Providers */ + _method( LLVMCreateModuleProviderForExistingModule ) + _method( LLVMDisposeModuleProvider ) + + /* Memory Buffer */ + _method( LLVMCreateMemoryBufferWithContentsOfFile ) + _method( LLVMCreateMemoryBufferWithSTDIN ) + _method( LLVMDisposeMemoryBuffer ) + + /* Pass Manager */ + _method( LLVMCreatePassManager ) + _method( LLVMCreateFunctionPassManager ) + _method( LLVMRunPassManager ) + _method( LLVMInitializeFunctionPassManager ) + _method( LLVMRunFunctionPassManager ) + _method( LLVMFinalizeFunctionPassManager ) + _method( LLVMDisposePassManager ) + + { NULL } +}; + +PyMODINIT_FUNC +init_core(void) +{ + Py_InitModule("_core", core_methods); +} diff --git a/llvm/core.py b/llvm/core.py new file mode 100644 index 0000000..149a227 --- /dev/null +++ b/llvm/core.py @@ -0,0 +1,1415 @@ +"""Core classes of LLVM. + +The llvm.core module contains classes and constants required to build the +in-memory intermediate representation (IR) data structures.""" + + +import _core + + +#===----------------------------------------------------------------------=== +# Enumerations +#===----------------------------------------------------------------------=== + + +# type kinds +TYPE_VOID = 0 +TYPE_FLOAT = 1 +TYPE_DOUBLE = 2 +TYPE_X86_FP80 = 3 +TYPE_FP128 = 4 +TYPE_PPC_FP128 = 5 +TYPE_LABEL = 6 +TYPE_INTEGER = 7 +TYPE_FUNCTION = 8 +TYPE_STRUCT = 9 +TYPE_ARRAY = 10 +TYPE_POINTER = 11 +TYPE_OPAQUE = 12 +TYPE_VECTOR = 13 + +# calling conventions +CC_C = 0 +CC_FASTCALL = 8 +CC_COLDCALL = 9 +CC_X86_STDCALL = 64 +CC_X86_FASTCALL = 65 + +# int predicates +IPRED_EQ = 32 +IPRED_NE = 33 +IPRED_UGT = 34 +IPRED_UGE = 35 +IPRED_ULT = 36 +IPRED_ULE = 37 +IPRED_SGT = 38 +IPRED_SGE = 39 +IPRED_SLT = 40 +IPRED_SLE = 41 + +# real predicates +RPRED_FALSE = 0 +RPRED_OEQ = 1 +RPRED_OGT = 2 +RPRED_OGE = 3 +RPRED_OLT = 4 +RPRED_OLE = 5 +RPRED_ONE = 6 +RPRED_ORD = 7 +RPRED_UNO = 8 +RPRED_UEQ = 9 +RPRED_UGT = 10 +RPRED_UGE = 11 +RPRED_ULT = 12 +RPRED_ULE = 13 +RPRED_UNE = 14 +RPRED_TRUE = 15 + +# linkages +LINKAGE_EXTERNAL = 0 +LINKAGE_LINKONCE = 1 +LINKAGE_WEAK = 2 +LINKAGE_APPENDING = 3 +LINKAGE_INTERNAL = 4 +LINKAGE_DLLIMPORT = 5 +LINKAGE_DLLEXPORT = 6 +LINKAGE_EXTERNAL_WEAK = 7 +LINKAGE_GHOST = 8 + +# visibility +VISIBILITY_DEFAULT = 0 +VISIBILITY_HIDDEN = 1 +VISIBILITY_PROTECTED = 2 + +# parameter attributes +ATTR_ZEXT = 1 +ATTR_SEXT = 2 +ATTR_NO_RETURN = 4 +ATTR_IN_REG = 8 +ATTR_STRUCT_RET = 16 +ATTR_NO_UNWIND = 32 +ATTR_NO_ALIAS = 64 +ATTR_BY_VAL = 128 +ATTR_NEST = 256 +ATTR_READ_NONE = 512 +ATTR_READONLY = 1024 + + +#===----------------------------------------------------------------------=== +# Helper functions +#===----------------------------------------------------------------------=== + + +def _check_gen(obj, type, type_str): + if not isinstance(obj, type): + msg = "argument must be an instance of llvm.core.%s (or of a class derived from it)" % type_str + raise TypeError, msg + +def _check_is_type(obj): _check_gen(obj, Type, "Type") +def _check_is_value(obj): _check_gen(obj, Value, "Value") +def _check_is_pointer(obj): _check_gen(obj, Pointer, "Pointer") +def _check_is_constant(obj): _check_gen(obj, Constant, "Constant") +def _check_is_function(obj): _check_gen(obj, Function, "Function") +def _check_is_basic_block(obj): _check_gen(obj, BasicBlock, "BasicBlock") +def _check_is_module_provider(obj): _check_gen(obj, ModuleProvider, "ModuleProvider") + +def _unpack_gen(objlist, check_fn): + for obj in objlist: check_fn(obj) + return [ obj.ptr for obj in objlist ] + +def _unpack_types(objlist): return _unpack_gen(objlist, _check_is_type) +def _unpack_values(objlist): return _unpack_gen(objlist, _check_is_value) +def _unpack_constants(objlist): return _unpack_gen(objlist, _check_is_constant) + +def _wrapiter(first, next, container, wrapper): + ptr = first(container) + while ptr: + yield wrapper(ptr) + ptr = next(ptr) + +class _dummy_owner(object): + + def __init__(self, ownee): + ownee._own(self) + + +#===----------------------------------------------------------------------=== +# Module +#===----------------------------------------------------------------------=== + + +class Module(object): + """A Module instance stores all the information related to an LLVM module. + + Modules are the top level container of all other LLVM Intermediate + Representation (IR) objects. Each module directly contains a list of + globals variables, a list of functions, a list of libraries (or + other modules) this module depends on, a symbol table, and various + data about the target's characteristics. + + Construct a Module only using the static methods defined below, *NOT* + using the constructor. A correct usage is: + + module_obj = Module.new('my_module') + """ + + @staticmethod + def new(id): + """Create a new Module instance. + + Creates an instance of Module, having the id `id'. + """ + return Module(_core.LLVMModuleCreateWithName(id)) + + def __init__(self, ptr): + """DO NOT CALL DIRECTLY. + + Use the static method `Module.new' instead. + """ + self.ptr = ptr + self.owner = None + + def __del__(self): + if not self.owner: + _core.LLVMDisposeModule(self.ptr) + + def __str__(self): + """Text representation of a module. + + Returns the textual representation (`llvm assembly') of the + module. Use it like this: + + ll = str(module_obj) + print module_obj # same as `print ll' + """ + return _core.LLVMDumpModuleToString(self.ptr) + + def __eq__(self, rhs): + if isinstance(rhs, Module): + return str(self) == str(rhs) + else: + return False + + def _own(self, owner): + assert not self.owner + self.owner = owner + + def _get_target(self): + return _core.LLVMGetTarget(self.ptr) + + def _set_target(self, value): + return _core.LLVMSetTarget(self.ptr, value) + + target = property(_get_target, _set_target, + """The target triple string describing the target host.""" + ) + + def _get_data_layout(self): + return _core.LLVMGetDataLayout(self.ptr) + + def _set_data_layout(self, value): + _core.LLVMSetDataLayout(self.ptr, value) + + data_layout = property(_get_data_layout, _set_data_layout, + """The data layout string for the module's target platform. + + The data layout strings is an encoded representation of + the type sizes and alignments expected by this module. + """ + ) + + def add_type_name(self, name, ty): + """Map a string to a type. + + Similar to C's struct/typedef declarations. Returns True + if entry already existed (in which case nothing is changed), + False otherwise. + """ + _check_is_type(ty) + return _core.LLVMAddTypeName(self.ptr, name, ty.ptr) != 0 + + def delete_type_name(self, name): + """Removes a named type. + + Undoes what add_type_name() does. + """ + _core.LLVMDeleteTypeName(self.ptr, name) + + def add_global_variable(self, ty, name): + """Add a global variable of given type with given name.""" + return GlobalVariable.new(self, ty, name) + + def get_global_variable_named(self, name): + """Return a GlobalVariable object for the given name.""" + return GlobalVariable.get(self, name) + + @property + def global_variables(self): + """All global variables in this module. + + This property returns a generator that yields GlobalVariable + objects. Use it like this: + for gv in module_obj.global_variables: + # gv is an instance of GlobalVariable + # do stuff with gv + """ + return _wrapiter(_core.LLVMGetFirstGlobal, _core.LLVMGetNextGlobal, + self.ptr, GlobalVariable) + + def add_function(self, ty, name): + """Add a function of given type with given name.""" + return Function.new(self, ty, name) + + def get_function_named(self, name): + """Return a Function object representing function with given name.""" + return Function.get(self, name) + + @property + def functions(self): + """All functions in this module. + + This property returns a generator that yields Function objects. + Use it like this: + for f in module_obj.functions: + # f is an instance of Function + # do stuff with f + """ + return _wrapiter(_core.LLVMGetFirstFunction, + _core.LLVMGetNextFunction, self.ptr, Function) + + def verify(self): + return _core.LLVMVerifyModule(self.ptr) + + +#===----------------------------------------------------------------------=== +# Types +#===----------------------------------------------------------------------=== + + +class Type(object): + + @staticmethod + def int(bits=32): + if bits == 1: + return _make_type(_core.LLVMInt1Type(), TYPE_INTEGER) + elif bits == 8: + return _make_type(_core.LLVMInt2Type(), TYPE_INTEGER) + elif bits == 16: + return _make_type(_core.LLVMInt16Type(), TYPE_INTEGER) + elif bits == 32: + return _make_type(_core.LLVMInt32Type(), TYPE_INTEGER) + elif bits == 64: + return _make_type(_core.LLVMInt64Type(), TYPE_INTEGER) + else: + return _make_type(_core.LLVMIntType(bits), TYPE_INTEGER) + + @staticmethod + def float(): + return _make_type(_core.LLVMFloatType(), TYPE_FLOAT) + + @staticmethod + def double(): + return _make_type(_core.LLVMDoubleType(), TYPE_DOUBLE) + + @staticmethod + def x86_fp80(): + return _make_type(_core.LLVMX86FP80Type(), TYPE_X86_FP80) + + @staticmethod + def fp128(): + return _make_type(_core.LLVMFP128Type(), TYPE_FP128) + + @staticmethod + def ppc_fp128(): + return _make_type(_core.LLVMPPCFP128Type(), TYPE_PPC_FP128) + + @staticmethod + def function(return_ty, param_tys, var_arg=False): + _check_is_type(return_ty) + var_arg = 1 if var_arg else 0 # convert to int + params = _unpack_types(param_tys) + return _make_type(_core.LLVMFunctionType(return_ty.ptr, params, var_arg), TYPE_FUNCTION) + + @staticmethod + def struct(element_tys): # not packed + elems = _unpack_types(element_tys) + return _make_type(_core.LLVMStructType(elems, 0), TYPE_STRUCT) + + @staticmethod + def struct_packed(element_tys): + elems = _unpack_types(element_tys) + return _make_type(_core.LLVMStructType(elems, 1), TYPE_STRUCT) + + @staticmethod + def array(element_ty, count): + _check_is_type(element_ty) + return _make_type(_core.LLVMArrayType(element_ty.ptr, count), TYPE_ARRAY) + + @staticmethod + def pointer(pointee_ty, addr_space=0): + _check_is_type(pointee_ty) + return _make_type(_core.LLVMPointerType(pointee_ty.ptr, addr_space), TYPE_POINTER) + + @staticmethod + def vector(element_ty, count): + _check_is_type(element_ty) + return _make_type(_core.LLVMVectorType(element_ty.ptr, count), TYPE_VECTOR) + + @staticmethod + def void(): + return _make_type(_core.LLVMVoidType(), TYPE_VOID) + + @staticmethod + def label(): + return _make_type(_core.LLVMLabelType(), TYPE_LABEL) + + @staticmethod + def opaque(): + return _make_type(_core.LLVMOpaqueType(), TYPE_OPAQUE) + + def __init__(self, ptr, kind): + self.ptr = ptr + self.kind = kind + + def __str__(self): + return _core.LLVMDumpTypeToString(self.ptr) + + def __eq__(self, rhs): + if isinstance(rhs, Type): + return str(self) == str(rhs) + else: + return False + + def refine(self, dest): + """Refine the abstract type represented by self to a concrete class. + + This object is no longer valid after refining, so do not hold references + to it after calling.""" + + _check_is_type(dest) + _core.LLVMRefineType(self.ptr, dest.ptr) + self.ptr = None + + +class IntegerType(Type): + + def __init__(self, ptr, kind): + Type.__init__(self, ptr, kind) + + @property + def width(self): + return _core.LLVMGetIntTypeWidth(self.ptr) + + +class FunctionType(Type): + + def __init__(self, ptr, kind): + Type.__init__(self, ptr, kind) + + @property + def return_type(self): + ptr = _core.LLVMGetReturnType(self.ptr) + kind = _core.LLVMGetTypeKind(ptr) + return _make_type(ptr, kind) + + @property + def vararg(self): + return _core.LLVMIsFunctionVarArg(self.ptr) != 0 + + @property + def args(self): + pp = _core.LLVMGetFunctionTypeParams(self.ptr) + return [ _make_type(p, _core.LLVMGetTypeKind(p)) for p in pp ] + + @property + def arg_count(self): + return _core.LLVMCountParamTypes(self.ptr) + + +class StructType(Type): + + def __init__(self, ptr, kind): + Type.__init__(self, ptr, kind) + + @property + def element_count(self): + return _core.LLVMCountStructElementTypes(self.ptr) + + @property + def element_types(self): + pp = _core.LLVMGetStructElementTypes(self.ptr) + return [ _make_type(p, _core.LLVMGetTypeKind(p)) for p in pp ] + + @property + def packed(self): + return _core.LLVMIsPackedStruct(self.ptr) != 0 + + +class ArrayType(Type): + + def __init__(self, ptr, kind): + Type.__init__(self, ptr, kind) + + @property + def element_type(self): + ptr = _core.LLVMGetElementType(self.ptr) + kind = _core.LLVMGetTypeKind(ptr) + return _make_type(ptr, kind) + + @property + def element_count(self): + return _core.LLVMGetArrayLength(self.ptr) + + +class PointerType(Type): + + def __init__(self, ptr, kind): + Type.__init__(self, ptr, kind) + + @property + def address_space(self): + return _core.LLVMGetPointerAddressSpace(self.ptr) + + +class VectorType(Type): + + def __init__(self, ptr, kind): + Type.__init__(self, ptr, kind) + + @property + def element_type(self): + ptr = _core.LLVMGetElementType(self.ptr) + kind = _core.LLVMGetTypeKind(ptr) + return _make_type(ptr, kind) + + @property + def element_count(self): + return _core.LLVMGetVectorSize(self.ptr) + + +def _make_type(ptr, kind): + if kind == TYPE_INTEGER: + return IntegerType(ptr, kind) + elif kind == TYPE_FUNCTION: + return FunctionType(ptr, kind) + elif kind == TYPE_STRUCT: + return StructType(ptr, kind) + elif kind == TYPE_ARRAY: + return ArrayType(ptr, kind) + elif kind == TYPE_POINTER: + return PointerType(ptr, kind) + elif kind == TYPE_VECTOR: + return VectorType(ptr, kind) + else: + return Type(ptr, kind) + + +#===----------------------------------------------------------------------=== +# Type Handle +#===----------------------------------------------------------------------=== + + +class TypeHandle(object): + + @staticmethod + def new(abstract_ty): + _check_is_type(abstract_ty) + return TypeHandle(_core.LLVMCreateTypeHandle(abstract_ty.ptr)) + + def __init__(self, ptr): + self.ptr = ptr + + def __del__(self): + _core.LLVMDisposeTypeHandle(self.ptr) + + @property + def type(self): + ptr = _core.LLVMResolveTypeHandle(self.ptr) + return _make_type(ptr, _core.LLVMGetTypeKind(ptr)) + + +#===----------------------------------------------------------------------=== +# Values +#===----------------------------------------------------------------------=== + + +class Value(object): + + def __init__(self, ptr): + self.ptr = ptr + + def __str__(self): + return _core.LLVMDumpValueToString(self.ptr) + + def __eq__(self, rhs): + if isinstance(rhs, Value): + return str(self) == str(rhs) + else: + return False + + def get_name(self): + return _core.LLVMGetValueName(self.ptr) + + def set_name(self, value): + return _core.LLVMSetValueName(self.ptr, value) + + name = property(get_name, set_name) + + @property + def type(self): + ptr = _core.LLVMTypeOf(self.ptr) + kind = _core.LLVMGetTypeKind(ptr) + return _make_type(ptr, kind) + + +class Constant(Value): + + @staticmethod + def null(ty): + _check_is_type(ty) + return Constant(_core.LLVMConstNull(ty.ptr)); + + @staticmethod + def all_ones(ty): + _check_is_type(ty) + return Constant(_core.LLVMConstAllOnes(ty.ptr)); + + @staticmethod + def undef(ty): + _check_is_type(ty) + return Constant(_core.LLVMGetUndef(ty.ptr)); + + @staticmethod + def int(ty, value): + _check_is_type(ty) + return Constant(_core.LLVMConstInt(ty.ptr, value, 0)) + + @staticmethod + def int_signextend(ty, value): + _check_is_type(ty) + return Constant(_core.LLVMConstInt(ty.ptr, value, 1)) + + @staticmethod + def real(ty, value): + _check_is_type(ty) + if isinstance(value, str): + return Constant(_core.LLVMConstRealOfString(ty.ptr, value)) + else: + return Constant(_core.LLVMConstReal(ty.ptr, value)) + + @staticmethod + def string(strval): # dont_null_terminate=True + return Constant(_core.LLVMConstString(strval, 1)) + + @staticmethod + def stringz(strval): # dont_null_terminate=False + return Constant(_core.LLVMConstString(strval, 0)) + + @staticmethod + def array(ty, consts): + _check_is_type(ty) + const_ptrs = _unpack_constants(consts) + return Constant(_core.LLVMConstArray(ty.ptr, const_ptrs)) + + @staticmethod + def struct(consts): # not packed + const_ptrs = _unpack_constants(consts) + return Constant(_core.LLVMConstStruct(consts, 0)) + + @staticmethod + def struct_packed(consts): + const_ptrs = _unpack_constants(consts) + return Constant(_core.LLVMConstStruct(consts, 1)) + + @staticmethod + def vector(consts): + const_ptrs = _unpack_constants(consts) + return Constant(_core.LLVMConstVector(const_ptrs)) + + @staticmethod + def sizeof(ty): + _check_is_type(ty) + return Constant(_core.LLVMSizeOf(ty.ptr)) + + def __init__(self, ptr): + self.ptr = ptr + + def neg(self): + return Constant(_core.LLVMConstNeg(self.ptr)) + + def not_(self): + return Constant(_core.LLVMConstNot(self.ptr)) + + def add(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstAdd(self.ptr, rhs.ptr)) + + def sub(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstSub(self.ptr, rhs.ptr)) + + def mul(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstMul(self.ptr, rhs.ptr)) + + def udiv(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstUDiv(self.ptr, rhs.ptr)) + + def sdiv(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstSDiv(self.ptr, rhs.ptr)) + + def fdiv(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstFDiv(self.ptr, rhs.ptr)) + + def urem(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstURem(self.ptr, rhs.ptr)) + + def srem(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstSRem(self.ptr, rhs.ptr)) + + def and_(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstAnd(self.ptr, rhs.ptr)) + + def or_(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstOr(self.ptr, rhs.ptr)) + + def xor(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstXor(self.ptr, rhs.ptr)) + + def icmp(self, int_pred, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstICmp(self.ptr, int_pred, rhs.ptr)) + + def fcmp(self, real_pred, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstFCmp(self.ptr, real_pred, rhs.ptr)) + + def shl(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstShl(self.ptr, rhs.ptr)) + + def lshr(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstLShr(self.ptr, rhs.ptr)) + + def ashr(self, rhs): + _check_is_constant(rhs) + return Constant(_core.LLVMConstAShr(self.ptr, rhs.ptr)) + + def gep(self, indices): + index_ptrs = _unpack_constants(indices) + return Constant(_core.LLVMConstGEP(self.ptr, index_ptrs)) + + def trunc(self, ty): + _check_is_type(ty) + return Constant(_core.LLVMConstTrunc(self.ptr, ty.ptr)) + + def sext(self, ty): + _check_is_type(ty) + return Constant(_core.LLVMConstSExt(self.ptr, ty.ptr)) + + def zext(self, ty): + _check_is_type(ty) + return Constant(_core.LLVMConstZExt(self.ptr, ty.ptr)) + + def fptrunc(self, ty): + _check_is_type(ty) + return Constant(_core.LLVMConstFPTrunc(self.ptr, ty.ptr)) + + def fpext(self, ty): + _check_is_type(ty) + return Constant(_core.LLVMConstFPExt(self.ptr, ty.ptr)) + + def uitofp(self, ty): + _check_is_type(ty) + return Constant(_core.LLVMConstUIToFP(self.ptr, ty.ptr)) + + def sitofp(self, ty): + _check_is_type(ty) + return Constant(_core.LLVMConstSIToFP(self.ptr, ty.ptr)) + + def fptoui(self, ty): + _check_is_type(ty) + return Constant(_core.LLVMConstFPToUI(self.ptr, ty.ptr)) + + def fptosi(self, ty): + _check_is_type(ty) + return Constant(_core.LLVMConstFPToSI(self.ptr, ty.ptr)) + + def ptrtoint(self, ty): + _check_is_type(ty) + return Constant(_core.LLVMConstPtrToInt(self.ptr, ty.ptr)) + + def inttoptr(self, ty): + _check_is_type(ty) + return Constant(_core.LLVMConstIntToPtr(self.ptr, ty.ptr)) + + def bitcast(self, ty): + _check_is_type(ty) + return Constant(_core.LLVMConstBitCast(self.ptr, ty.ptr)) + + def select(self, true_const, false_const): + _check_is_constant(true_const) + _check_is_constant(false_const) + return Constant(_core.LLVMConstSelect(self.ptr, true_const.ptr, false_const.ptr)) + + def extract(self, index): # note: self must be a _vector_ constant + _check_is_constant(index) + return Constant(_core.LLVMConstExtractElement(self.ptr, index.ptr)) + + def insert(self, value, index): # note: self must be a _vector_ constant + _check_is_constant(value) + _check_is_constant(index) + return Constant(_core.LLVMConstInsertElement(self.ptr, value.ptr, index.ptr)) + + def shuffle(self, vector_b, mask): # note: self must be a _vector_ constant + _check_is_constant(vector_b) # note: vector_b must be a _vector_ constant + _check_is_constant(mask) + return Constant(_core.LLVMConstShuffleVector(self.ptr, vector_b.ptr, mask.ptr)) + + +class GlobalValue(Value): + + def __init__(self, ptr): + self.ptr = ptr + + def get_linkage(self): return _core.LLVMGetLinkage(self.ptr) + def set_linkage(self, value): _core.LLVMSetLinkage(self.ptr, value) + linkage = property(get_linkage, set_linkage) + + def get_section(self): return _core.LLVMGetSection(self.ptr) + def set_section(self, value): return _core.LLVMSetSection(self.ptr, value) + section = property(get_section, set_section) + + def get_visibility(self): return _core.LLVMGetVisibility(self.ptr) + def set_visibility(self, value): return _core.LLVMSetVisibility(self.ptr, value) + visibility = property(get_visibility, set_visibility) + + def get_alignment(self): return _core.LLVMGetAlignment(self.ptr) + def set_alignment(self, value): return _core.LLVMSetAlignment(self.ptr, value) + alignment = property(get_alignment, set_alignment) + + @property + def is_declaration(self): + return _core.LLVMIsDeclaration(self.ptr) + + @property + def module(self): + mod = Module(_core.LLVMGetGlobalParent(self.ptr)) + owner = _dummy_owner(mod) + return mod + + +class GlobalVariable(GlobalValue): + + @staticmethod + def new(module, ty, name): + _check_is_type(ty) + return GlobalVariable(_core.LLVMAddGlobal(module.ptr, ty.ptr, name)) + + @staticmethod + def get(module, name): + return GlobalVariable(_core.LLVMGetNamedGlobal(module.ptr, name)) + + def __init__(self, ptr): + GlobalValue.__init__(self, ptr) + + def delete(self): + _core.LLVMDeleteGlobal(self.ptr) + self.ptr = None + + def get_initializer(self): + if _core.LLVMHasInitializer(self.ptr): + return Constant(_core.LLVMGetInitializer(self.ptr)) + else: + return None + + def set_initializer(self, const): + _check_is_constant(const) + _core.LLVMSetInitializer(self.ptr, const.ptr) + + initializer = property(get_initializer, set_initializer) + + def get_is_global_constant(self): + return _core.LLVMIsGlobalConstant(self.ptr) + + def set_is_global_constant(self, value): + value = 1 if value else 0 + _core.LLVMSetGlobalConstant(self.ptr, value) + + global_constant = property(get_is_global_constant, set_is_global_constant) + + +class Argument(Value): + + def __init__(self, ptr): + Value.__init__(self, ptr) + + def add_attribute(self, attr): + _core.LLVMAddParamAttr(self.ptr, attr) + + def remove_attribute(self, attr): + _core.LLVMRemoveParamAttr(self.ptr, attr) + + def set_alignment(self, align): + _core.LLVMSetParamAlignment(self.ptr, align) + + @property + def function(self): + return Function(_core.LLVMGetParamParent(self.ptr)) + + +class Function(GlobalValue): + + @staticmethod + def new(module, func_ty, name): + return Function(_core.LLVMAddFunction(module.ptr, name, func_ty.ptr)) + + @staticmethod + def get(module, name): + return Function(_core.LLVMGetNamedFunction(module.ptr, name)) + + def __init__(self, ptr): + GlobalValue.__init__(self, ptr) + + def delete(self): + _core.LLVMDeleteFunction(self.ptr) + self.ptr = None + + @property + def intrinsic_id(self): + return _core.LLVMGetIntrinsicID(self.ptr) + + def get_calling_convention(self): return _core.LLVMGetFunctionCallConv(self.ptr) + def set_calling_convention(self, value): _core.LLVMSetFunctionCallConv(self.ptr, value) + calling_convention = property(get_calling_convention, set_calling_convention) + + def get_collector(self): return _core.LLVMGetCollector(self.ptr) + def set_collector(self, value): _core.LLVMSetCollector(self.ptr, value) + collector = property(get_collector, set_collector) + + @property + def args(self): + return _wrapiter(_core.LLVMGetFirstParam, _core.LLVMGetNextParam, + self.ptr, Argument) + + @property + def basic_block_count(self): + return _core.LLVMCountBasicBlocks(self.ptr) + + def get_entry_basic_block(self): + return BasicBlock(_core.LLVMGetEntryBasicBlock(self.ptr)) + + def append_basic_block(self, name): + return BasicBlock(_core.LLVMAppendBasicBlock(self.ptr, name)) + + @property + def basic_blocks(self): + return _wrapiter(_core.LLVMGetFirstBasicBlock, + _core.LLVMGetNextBasicBlock, self.ptr, BasicBlock) + + def verify(self): + return _core.LLVMVerifyFunction(self.ptr) != 0 + + +#===----------------------------------------------------------------------=== +# Instruction +#===----------------------------------------------------------------------=== + +class Instruction(Value): + + def __init__(self, ptr): + Value.__init__(self, ptr) + + @property + def basic_block(self): + return BasicBlock(_core.LLVMGetInstructionParent(self.ptr)) + + +class CallOrInvokeInstruction(Instruction): + + def __init__(self, ptr): + Instruction.__init__(self, ptr) + + def get_calling_convention(self): return _core.LLVMGetFunctionCallConv(self.ptr) + def set_calling_convention(self, value): _core.LLVMSetFunctionCallConv(self.ptr, value) + calling_convention = property(get_calling_convention, set_calling_convention) + + def add_parameter_attribute(self, idx, attr): + _core.LLVMAddInstrParamAttr(self.ptr, idx, attr) + + def remove_parameter_attribute(self, idx, attr): + _core.LLVMRemoveInstrParamAttr(self.ptr, idx, attr) + + def set_parameter_alignment(self, idx, align): + _core.LLVMSetInstrParamAlignment(self.ptr, idx, align) + + +class PHINode(Instruction): + + def __init__(self, ptr): + Instruction.__init__(self, ptr) + + @property + def incoming_count(self): + return _core.LLVMCountIncoming(self.ptr) + + def add_incoming(self, value, block): + _check_is_value(value) + _check_is_basic_block(block) + _core.LLVMAddIncoming1(self.ptr, value.ptr, block.ptr) + + def get_incoming_value(self, idx): + return Value(_core.LLVMGetIncomingValue(self.ptr, idx)) + + def get_incoming_block(self, idx): + return BasicBlock(_core.LLVMGetIncomingBlock(self.ptr, idx)) + + +class SwitchInstruction(Instruction): + + def __init__(self, ptr): + Instruction.__init__(self, ptr) + + def add_case(self, const, bblk): + _check_is_constant(const) # and has to be an int too + _check_is_basic_block(bblk) + _core.LLVMAddCase(self.ptr, const.ptr, bblk.ptr) + + +#===----------------------------------------------------------------------=== +# Basic block +#===----------------------------------------------------------------------=== + + +class BasicBlock(Value): + + def __init__(self, ptr): + self.ptr = ptr + + def insert_before(self, name): + return BasicBlock(_core.LLVMInsertBasicBlock(self.ptr, name)) + + def delete(self): + _core.LLVMDeleteBasicBlock(self.ptr) + self.ptr = None + + @property + def function(self): + return Function(_core.LLVMGetBasicBlockParent(self.ptr)) + + @property + def instructions(self): + return _wrapiter(_core.LLVMGetFirstInstruction, + _core.LLVMGetNextInstruction, self.ptr, Instruction) + + +#===----------------------------------------------------------------------=== +# Builder +#===----------------------------------------------------------------------=== + + +class Builder(object): + + @staticmethod + def new(): + return Builder(_core.LLVMCreateBuilder()) + + def __init__(self, ptr): + self.ptr = ptr + + def __del__(self): + _core.LLVMDisposeBuilder(self.ptr) + + def position(self, block, instr=None): + if instr: + _core.LLVMPositionBuilder(self.ptr, block.ptr, instr.ptr) + else: + _core.LLVMPositionBuilder(self.ptr, block.ptr) + + def position_before(self, instr): + _core.LLVMPositionBuilderBefore(self.ptr, instr.ptr) + + def position_at_end(self, bblk): + _core.LLVMPositionBuilderAtEnd(self.ptr, bblk.ptr) + + @property + def insert_block(self): + return BasicBlock(_core.LLVMGetInsertBlock(self.ptr)) + + def ret_void(self): + return Instruction(_core.LLVMBuildRetVoid(self.ptr)) + + def ret(self, value): + _check_is_value(value) + return Instruction(_core.LLVMBuildRet(self.ptr, value.ptr)) + + def branch(self, bblk): + _check_is_basic_block(bblk) + return Instruction(_core.LLVMBuildBr(self.ptr, bblk.ptr)) + + def cbranch(self, if_value, then_blk, else_blk): + _check_is_value(if_value) + _check_is_basic_block(then_blk) + _check_is_basic_block(else_blk) + return Instruction(_core.LLVMBuildCondBr(self.ptr, if_value.ptr, then_blk.ptr, else_blk.ptr)) + + def switch(self, value, else_blk, n=10): + _check_is_value(value) + _check_is_basic_block(else_blk) + return SwitchInstruction(_core.LLVMBuildSwitch(self.ptr, value.ptr, else_blk.ptr, n)) + + def invoke(self, func, args, then_blk, catch_blk, name=""): + _check_is_function(func) + _check_is_basic_block(then_blk) + _check_is_basic_block(catch_blk) + args2 = _unpack_values(args) + return CallOrInvokeInstruction(_core.LLVMBuildInvoke(self.ptr, func.ptr, args2, then_blk.ptr, catch_blk.ptr, name)) + + def unwind(self): + return Instruction(_core.LLVMBuildUnwind(self.ptr)) + + def unreachable(self): + return Instruction(_core.LLVMBuildUnreachable(self.ptr)) + + # arithmethic-related + + def add(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildAdd(self.ptr, lhs.ptr, rhs.ptr, name)) + + def sub(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildSub(self.ptr, lhs.ptr, rhs.ptr, name)) + + def mul(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildMul(self.ptr, lhs.ptr, rhs.ptr, name)) + + def udiv(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildUDiv(self.ptr, lhs.ptr, rhs.ptr, name)) + + def sdiv(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildSDiv(self.ptr, lhs.ptr, rhs.ptr, name)) + + def fdiv(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildFDiv(self.ptr, lhs.ptr, rhs.ptr, name)) + + def urem(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildURem(self.ptr, lhs.ptr, rhs.ptr, name)) + + def srem(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildSRem(self.ptr, lhs.ptr, rhs.ptr, name)) + + def frem(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildFRem(self.ptr, lhs.ptr, rhs.ptr, name)) + + def shl(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildShl(self.ptr, lhs.ptr, rhs.ptr, name)) + + def lshr(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildLShr(self.ptr, lhs.ptr, rhs.ptr, name)) + + def ashr(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildAShr(self.ptr, lhs.ptr, rhs.ptr, name)) + + def and_(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildAnd(self.ptr, lhs.ptr, rhs.ptr, name)) + + def or_(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildOr(self.ptr, lhs.ptr, rhs.ptr, name)) + + def xor(self, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildXor(self.ptr, lhs.ptr, rhs.ptr, name)) + + def neg(self, val, name=""): + _check_is_value(val) + return Instruction(_core.LLVMBuildNeg(self.ptr, val.ptr, name)) + + def not_(self, val, name=""): + _check_is_value(val) + return Instruction(_core.LLVMBuildNot(self.ptr, val.ptr, name)) + + # memory + + def malloc(self, ty, name=""): + _check_is_type(ty) + return Instruction(_core.LLVMBuildMalloc(self.ptr, ty.ptr, name)) + + def malloc_array(self, ty, size, name=""): + _check_is_type(ty) + _check_is_value(size) + return Instruction(_core.LLVMBuildArrayMalloc(self.ptr, ty.ptr, size.ptr, name)) + + def alloca(self, ty, name=""): + _check_is_type(ty) + return Instruction(_core.LLVMBuildAlloc(self.ptr, ty.ptr, name)) + + def alloca_array(self, ty, size, name=""): + _check_is_type(ty) + _check_is_value(size) + return Instruction(_core.LLVMBuildArrayAlloca(self.ptr, ty.ptr, size.ptr, name)) + + def free(self, ptr): + _check_is_pointer(ptr) + return Instruction(_core.LLVMBuildFree(self.ptr, ptr.ptr)) + + def load(self, ptr, name=""): + _check_is_pointer(ptr) + return Instruction(_core.LLVMBuildLoad(self.ptr, ptr.ptr, name)) + + def store(self, value, ptr): + _check_is_value(value) + _check_is_pointer(ptr) + return Instruction(_core.LLVMBuildStore(self.ptr, value.ptr, ptr.ptr)) + + def gep(self, ptr, indices, name=""): + _check_is_pointer(ptr) + index_ptrs = _unpack_values(indices) + return Value(_core.LLVMBuildGEP(self.ptr, ptr.ptr, index_ptrs, name)) + + # casts + + def trunc(self, value, dest_ty, name=""): + _check_is_value(value) + _check_is_type(dest_ty) + return Value(_core.LLVMBuildTrunc(self.ptr, value.ptr, dest_ty.ptr, name)) + + def zext(self, value, dest_ty, name=""): + _check_is_value(value) + _check_is_type(dest_ty) + return Value(_core.LLVMBuildZExt(self.ptr, value.ptr, dest_ty.ptr, name)) + + def sext(self, value, dest_ty, name=""): + _check_is_value(value) + _check_is_type(dest_ty) + return Value(_core.LLVMBuildSExt(self.ptr, value.ptr, dest_ty.ptr, name)) + + def fptoui(self, value, dest_ty, name=""): + _check_is_value(value) + _check_is_type(dest_ty) + return Value(_core.LLVMBuildFPToUI(self.ptr, value.ptr, dest_ty.ptr, name)) + + def fptosi(self, value, dest_ty, name=""): + _check_is_value(value) + _check_is_type(dest_ty) + return Value(_core.LLVMBuildFPToSI(self.ptr, value.ptr, dest_ty.ptr, name)) + + def uitofp(self, value, dest_ty, name=""): + _check_is_value(value) + _check_is_type(dest_ty) + return Value(_core.LLVMBuildUIToFP(self.ptr, value.ptr, dest_ty.ptr, name)) + + def sitofp(self, value, dest_ty, name=""): + _check_is_value(value) + _check_is_type(dest_ty) + return Value(_core.LLVMBuildSIToFP(self.ptr, value.ptr, dest_ty.ptr, name)) + + def fptrunc(self, value, dest_ty, name=""): + _check_is_value(value) + _check_is_type(dest_ty) + return Value(_core.LLVMBuildFPTrunc(self.ptr, value.ptr, dest_ty.ptr, name)) + + def fpext(self, value, dest_ty, name=""): + _check_is_value(value) + _check_is_type(dest_ty) + return Value(_core.LLVMBuildFPExt(self.ptr, value.ptr, dest_ty.ptr, name)) + + def ptrtoint(self, value, dest_ty, name=""): + _check_is_value(value) + _check_is_type(dest_ty) + return Value(_core.LLVMBuildPtrToInt(self.ptr, value.ptr, dest_ty.ptr, name)) + + def inttoptr(self, value, dest_ty, name=""): + _check_is_value(value) + _check_is_type(dest_ty) + return Value(_core.LLVMBuildIntToPtr(self.ptr, value.ptr, dest_ty.ptr, name)) + + def bitcast(self, value, dest_ty, name=""): + _check_is_value(value) + _check_is_type(dest_ty) + return Value(_core.LLVMBuildBitCast(self.ptr, value.ptr, dest_ty.ptr, name)) + + # comparisons + + def icmp(self, ipred, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildICmp(self.ptr, ipred, lhs.ptr, rhs.ptr, name)) + + def fcmp(self, rpred, lhs, rhs, name=""): + _check_is_value(lhs) + _check_is_value(rhs) + return Value(_core.LLVMBuildFCmp(self.ptr, rpred, lhs.ptr, rhs.ptr, name)) + + # misc + + def phi(self, ty, name=""): + _check_is_type(ty) + return PHINode(_core.LLVMBuildPhi(self.ptr, ty.ptr, name)) + + def call(self, fn, args, name=""): + _check_is_function(fn) + arg_ptrs = _unpack_values(args) + return CallOrInvokeInstruction(_core.LLVMBuildCall(self.ptr, fn.ptr, arg_ptrs, name)) + + def select(self, if_blk, then_blk, else_blk, name=""): + _check_is_basic_block(if_blk) + _check_is_basic_block(then_blk) + _check_is_basic_block(else_blk) + return Value(_core.LLVMBuildSelect(self.ptr, if_blk.ptr, then_blk.ptr, else_blk.ptr, name)) + + def vaarg(self, list_val, ty, name=""): + _check_is_value(list_val) + _check_is_type(ty) + return Instruction(_core.LLVMBuildVAArg(self.ptr, list_val.ptr, ty.ptr, name)) + + def extract_element(self, vec_val, idx_val, name=""): + _check_is_value(vec_val) + _check_is_value(idx_val) + return Value(_core.LLVMBuildExtractElement(self.ptr, vec_val.ptr, idx_val.ptr, name)) + + def insert_element(self, vec_val, elt_val, idx_val, name=""): + _check_is_value(vec_val) + _check_is_value(elt_val) + _check_is_value(idx_val) + return Value(_core.LLVMBuildInsertElement(self.ptr, vec_val.ptr, elt_val.ptr, idx_val.ptr, name)) + + def shuffle_vector(self, vecA, vecB, mask, name=""): + _check_is_value(vecA) + _check_is_value(vecB) + _check_is_value(mask) + return Value(_core.LLVMBuildShuffleVector(self.ptr, vecA.ptr, vecB.ptr, mask.ptr, name)) + + +#===----------------------------------------------------------------------=== +# Module provider +#===----------------------------------------------------------------------=== + + +class ModuleProvider(object): + + @staticmethod + def new(module): + mp = ModuleProvider(_core.LLVMCreateModuleProviderForExistingModule(module.ptr)) + module._own(mp) + return mp + + def __init__(self, ptr): + self.ptr = ptr + + def __del__(self): + _core.LLVMDisposeModuleProvider(self.ptr) + + +#===----------------------------------------------------------------------=== +# Memory buffer +#===----------------------------------------------------------------------=== + + +class MemoryBuffer(object): + + @staticmethod + def from_file(self, fname): + ret = _core.LLVMCreateMemoryBufferWithContentsOfFile(fname) + if isinstance(ret, str): + return (None, ret) + else: + obj = MemoryBuffer(ret) + return (obj, "") + + @staticmethod + def from_stdin(self): + ret = _core.LLVMCreateMemoryBufferWithSTDIN() + if isinstance(ret, str): + return (None, ret) + else: + obj = MemoryBuffer(ret) + return (obj, "") + + def __init__(self, ptr): + self.ptr = ptr + + def __del__(self): + _core.LLVMDisposeMemoryBuffer(self.ptr) + + +#===----------------------------------------------------------------------=== +# Pass manager +#===----------------------------------------------------------------------=== + +class PassManager(object): + + @staticmethod + def new(): + return PassManager(_core.LLVMCreatePassManager()) + + def __init__(self, ptr): + self.ptr = ptr + + def __del__(self): + _core.LLVMDisposePassManager(self.ptr) + + def run(self, module): + _check_is_module(module) + return _core.LLVMRunPassManager(self.ptr, module.ptr) + + +class FunctionPassManager(PassManager): + + @staticmethod + def new(mp): + _check_is_module_provider(mp) + return FunctionPassManager(_core.LLVMCreateFunctionPassManager(mp.ptr)) + + def __init__(self, ptr): + PassManager.__init__(self, ptr) + + def __del__(self): + PassManager.__del__(self) + + def initialize(self): + _core.LLVMInitializeFunctionPassManager(self.ptr) + + def run(self, fn): + _check_is_function(fn) + return _core.LLVMRunFunctionPassManager(fn.ptr) + + def finalize(self): + _core.LLVMFinalizeFunctionPassManager(self.ptr) + diff --git a/llvm/extra.cpp b/llvm/extra.cpp new file mode 100644 index 0000000..f8a5fa4 --- /dev/null +++ b/llvm/extra.cpp @@ -0,0 +1,43 @@ +/** + * These are some "extra" functions not available in the standard LLVM-C + * bindings, but are required / good-to-have inorder to implement the + * Python bindings. + */ + +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/GlobalVariable.h" +#include "llvm/TypeSymbolTable.h" +#include "llvm/ModuleProvider.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/CallSite.h" +#include +#include +#include +#include + +#include "llvm-c/Core.h" +#include "llvm/Analysis/Verifier.h" +#include "extra.h" + +using namespace llvm; + +char *LLVMDumpModuleToString(LLVMModuleRef M) { + std::ostringstream buf; + unwrap(M)->print(buf); + return strdup(buf.str().c_str()); +} + +char *LLVMDumpTypeToString(LLVMTypeRef Ty) { + std::ostringstream buf; + unwrap(Ty)->print(buf); + return strdup(buf.str().c_str()); +} + +char *LLVMDumpValueToString(LLVMValueRef Val) { + std::ostringstream buf; + unwrap(Val)->print(buf); + return strdup(buf.str().c_str()); +} + diff --git a/llvm/extra.h b/llvm/extra.h new file mode 100644 index 0000000..2b463e0 --- /dev/null +++ b/llvm/extra.h @@ -0,0 +1,31 @@ +/** + * These are some "extra" functions not available in the standard LLVM-C + * bindings, but are required / good-to-have inorder to implement the + * Python bindings. + */ + +#ifndef LLVM_PY_EXTRA_H +#define LLVM_PY_EXTRA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** Dumps module contents to a string. See Module::print. Free the + returned string with LLVMDisposeMessage, after use. */ +char *LLVMDumpModuleToString(LLVMModuleRef M); + +/** Dumps type to a string. See Type::print. Free the returned string with + LLVMDisposeMessage, after use. */ +char *LLVMDumpTypeToString(LLVMTypeRef Ty); + +/** Dumps value to a string. See Value::print. Free the returned string with + LLVMDisposeMessage, after use. */ +char *LLVMDumpValueToString(LLVMValueRef Val); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LLVM_PY_EXTRA_H */ + diff --git a/llvm/wrap.c b/llvm/wrap.c new file mode 100644 index 0000000..d6cf4bb --- /dev/null +++ b/llvm/wrap.c @@ -0,0 +1,124 @@ +#include "wrap.h" + + +/*===----------------------------------------------------------------------===*/ +/* Type ctor/dtor */ +/*===----------------------------------------------------------------------===*/ + +PyObject *ctor_LLVMModuleRef(LLVMModuleRef p) +{ + if (p) + return PyCObject_FromVoidPtr(p, NULL); + Py_RETURN_NONE; /* avoiding the `else' since we don't (want to) know what + the macro Py_RETURN_NONE expands to */ +} + +PyObject *ctor_LLVMTypeRef(LLVMTypeRef p) +{ + if (p) + return PyCObject_FromVoidPtr(p, NULL); + Py_RETURN_NONE; +} + +PyObject *ctor_LLVMValueRef(LLVMValueRef p) +{ + if (p) + return PyCObject_FromVoidPtr(p, NULL); + Py_RETURN_NONE; +} + +PyObject *ctor_LLVMTypeHandleRef(LLVMTypeHandleRef p) +{ + if (p) + return PyCObject_FromVoidPtr(p, NULL); + Py_RETURN_NONE; +} + +PyObject *ctor_LLVMBasicBlockRef(LLVMBasicBlockRef p) +{ + if (p) + return PyCObject_FromVoidPtr(p, NULL); + Py_RETURN_NONE; +} + +PyObject *ctor_LLVMBuilderRef(LLVMBuilderRef p) +{ + if (p) + return PyCObject_FromVoidPtr(p, NULL); + Py_RETURN_NONE; +} + +PyObject *ctor_LLVMModuleProviderRef(LLVMModuleProviderRef p) +{ + if (p) + return PyCObject_FromVoidPtr(p, NULL); + Py_RETURN_NONE; +} + +PyObject *ctor_LLVMMemoryBufferRef(LLVMMemoryBufferRef p) +{ + if (p) + return PyCObject_FromVoidPtr(p, NULL); + Py_RETURN_NONE; +} + +PyObject *ctor_LLVMPassManagerRef(LLVMPassManagerRef p) +{ + if (p) + return PyCObject_FromVoidPtr(p, NULL); + Py_RETURN_NONE; +} + +PyObject *ctor_int(int i) +{ + return PyInt_FromLong(i); +} + + +/*===----------------------------------------------------------------------===*/ +/* Helper functions */ +/*===----------------------------------------------------------------------===*/ + +void *get_object_arg(PyObject *args) +{ + PyObject *o; + + if (!PyArg_ParseTuple(args, "O", &o)) + return NULL; + + return PyCObject_AsVoidPtr(o); +} + +void **make_array_from_list(PyObject *list, int n) +{ + int i; + void **arr; + + arr = (void **)malloc(sizeof(void *) * n); + if (!arr) + return NULL; + + for (i=0; i +#include + +/* llvm includes */ +#include +#include + + +/*===----------------------------------------------------------------------===*/ +/* Type ctor/dtor */ +/*===----------------------------------------------------------------------===*/ + +/* These are functions that can construct a PyCObject (a Python object that + * holds an opaque pointer) from any time. The naming convention is significant, + * this is assumed by the wrapper macros below. These are the equivalent of + * what would in C++ have been specializations of a template function ctor + * for various types. + */ + +/* LLVMModuleRef */ +PyObject *ctor_LLVMModuleRef(LLVMModuleRef p); + +/* LLVMTypeRef */ +PyObject *ctor_LLVMTypeRef(LLVMTypeRef p); + +/* LLVMValueRef */ +PyObject *ctor_LLVMValueRef(LLVMValueRef p); + +/* LLVMTypeHandleRef */ +PyObject *ctor_LLVMTypeHandleRef(LLVMTypeHandleRef p); + +/* LLVMBasicBlockRef */ +PyObject *ctor_LLVMBasicBlockRef(LLVMBasicBlockRef p); + +/* LLVMBuilderRef */ +PyObject *ctor_LLVMBuilderRef(LLVMBuilderRef p); + +/* LLVMModuleProviderRef */ +PyObject *ctor_LLVMModuleProviderRef(LLVMModuleProviderRef p); + +/* LLVMMemoryBufferRef */ +PyObject *ctor_LLVMMemoryBufferRef(LLVMMemoryBufferRef p); + +/* LLVMPassManagerRef */ +PyObject *ctor_LLVMPassManagerRef(LLVMPassManagerRef p); + +/* standard types */ +PyObject *ctor_int(int i); + + +/*===----------------------------------------------------------------------===*/ +/* Helper methods */ +/*===----------------------------------------------------------------------===*/ + +/** + * Accept a single object argument of type PyCObject and return the + * opaque pointer contained in it. + */ +void *get_object_arg(PyObject *args); + +/** + * Given a PyList object (list) having n (= PyList_Size(list)) elements, + * each list object being a PyCObject, return a malloc()-ed array of + * opaque pointers from the PyCObjects. The 'n' is passed explicitly + * since the caller will have to query it once anyway, and we can avoid + * a second call internally. + */ +void **make_array_from_list(PyObject *list, int n); + +/** + * Given an array of LLVMTypeRef's, create a PyList object. Note that + * currently such an action is required only for LLVMTypeRef's, when + * it is required another type, this method has to be generalized. + */ +PyObject *make_list_from_LLVMTypeRef_array(LLVMTypeRef *p, unsigned n); + + +/*===----------------------------------------------------------------------===*/ +/* Wrapper macros */ +/*===----------------------------------------------------------------------===*/ + +/* The following wrapper macros define functions that wrap over LLVM-C APIs + * of various signatures. Though they look hairy, they all follow some + * conventions. + */ + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1) + */ +#define _wrap_obj2obj(func, intype1, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + intype1 arg1; \ + \ + if (!(arg1 = ( intype1 )get_object_arg(args))) \ + return NULL; \ + \ + return ctor_ ## outtype ( func (arg1)); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(int arg1) + */ +#define _wrap_int2obj(func, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + int arg1; \ + \ + if (!PyArg_ParseTuple(args, "i", &arg1)) \ + return NULL; \ + \ + return ctor_ ## outtype ( func (arg1)); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2) + */ +#define _wrap_objobj2obj(func, intype1, intype2, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2; \ + intype1 arg1; \ + intype2 arg2; \ + \ + if (!PyArg_ParseTuple(args, "OO", &obj1, &obj2)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + \ + return ctor_ ## outtype ( func (arg1, arg2)); \ +} + +/** + * Wrap LLVM functions of the type + * void func(intype1 arg1, intype2 arg2) + */ +#define _wrap_objobj2none(func, intype1, intype2) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2; \ + intype1 arg1; \ + intype2 arg2; \ + \ + if (!PyArg_ParseTuple(args, "OO", &obj1, &obj2)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + \ + func (arg1, arg2); \ + Py_RETURN_NONE; \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, arg2) + */ +#define _wrap_objint2obj(func, intype1, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1; \ + intype1 arg1; \ + unsigned int arg2; \ + \ + if (!PyArg_ParseTuple(args, "OI", &obj1, &arg2)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + \ + return ctor_ ## outtype ( func (arg1, arg2)); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2, intype3 arg3) + */ +#define _wrap_objobjobj2obj(func, intype1, intype2, intype3, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2, *obj3; \ + intype1 arg1; \ + intype2 arg2; \ + intype3 arg3; \ + \ + if (!PyArg_ParseTuple(args, "OOO", &obj1, &obj2, &obj3)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + arg3 = ( intype3 ) PyCObject_AsVoidPtr(obj3); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3)); \ +} + +/** + * Wrap LLVM functions of the type + * void func(intype1 arg1, intype2 arg2, intype3 arg3) + */ +#define _wrap_objobjobj2none(func, intype1, intype2, intype3) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2, *obj3; \ + intype1 arg1; \ + intype2 arg2; \ + intype3 arg3; \ + \ + if (!PyArg_ParseTuple(args, "OOO", &obj1, &obj2, &obj3)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + arg3 = ( intype3 ) PyCObject_AsVoidPtr(obj3); \ + \ + func (arg1, arg2, arg3); \ + Py_RETURN_NONE; \ +} + +/** + * Wrap LLVM functions of the type + * outtype func( arg1, intype2 arg2, intype3 arg3) + */ +#define _wrap_intobjobj2obj(func, intype2, intype3, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + unsigned int arg1; \ + PyObject *obj2, *obj3; \ + intype2 arg2; \ + intype3 arg3; \ + \ + if (!PyArg_ParseTuple(args, "IOO", &arg1, &obj2, &obj3)) \ + return NULL; \ + \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + arg3 = ( intype3 ) PyCObject_AsVoidPtr(obj3); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3)); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func() + */ +#define _wrap_none2obj(func, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + if (!PyArg_ParseTuple(args, "")) \ + return NULL; \ + \ + return ctor_ ## outtype ( func ()); \ +} + +/** + * Wrap LLVM functions of the type + * const char *func(intype1 arg1) + */ +#define _wrap_obj2str(func, intype1) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + intype1 arg1; \ + \ + if (!(arg1 = ( intype1 )get_object_arg(args))) \ + return NULL; \ + \ + return PyString_FromString( func (arg1)); \ +} + +/** + * Wrap LLVM functions of the type + * void func(intype1 arg1) + */ +#define _wrap_obj2none(func, intype1) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + intype1 arg1; \ + \ + if (!(arg1 = ( intype1 )get_object_arg(args))) \ + return NULL; \ + \ + func (arg1); \ + Py_RETURN_NONE; \ +} + +/** + * Wrap LLVM functions of the type + * void func(intype1 arg1, const char *arg2) + */ +#define _wrap_objstr2none(func, intype1) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1; \ + const char *arg2; \ + intype1 arg1; \ + \ + if (!PyArg_ParseTuple(args, "Os", &obj1, &arg2)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + \ + func (arg1, arg2); \ + Py_RETURN_NONE; \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, const char *arg2) + */ +#define _wrap_objstr2obj(func, intype1, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1; \ + const char *arg2; \ + intype1 arg1; \ + \ + if (!PyArg_ParseTuple(args, "Os", &obj1, &arg2)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + \ + return ctor_ ## outtype ( func (arg1, arg2)); \ +} + +/** + * Wrap LLVM functions of the type + * void func(intype1 arg1, arg2) + */ +#define _wrap_objint2none(func, intype1) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1; \ + int arg2; \ + intype1 arg1; \ + \ + if (!PyArg_ParseTuple(args, "Oi", &obj1, &arg2)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + \ + func (arg1, arg2); \ + Py_RETURN_NONE; \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2, const char *arg3) + */ +#define _wrap_objobjstr2obj(func, intype1, intype2, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2; \ + intype1 arg1; \ + intype2 arg2; \ + const char *arg3; \ + \ + if (!PyArg_ParseTuple(args, "OOs", &obj1, &obj2, &arg3)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3)) ;\ +} + +/** + * Wrap LLVM functions of the type + * void func(intype1 arg1, arg2, arg3) + */ +#define _wrap_objintint2none(func, intype1) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1; \ + intype1 arg1; \ + int arg2, arg3; \ + \ + if (!PyArg_ParseTuple(args, "Oii", &obj1, &arg2, &arg3)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + \ + func (arg1, arg2, arg3); \ + Py_RETURN_NONE; \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, const char *arg2, intype3 arg3) + */ +#define _wrap_objstrobj2obj(func, intype1, intype3, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj3; \ + intype1 arg1; \ + const char *arg2; \ + intype3 arg3; \ + \ + if (!PyArg_ParseTuple(args, "OsO", &obj1, &arg2, &obj3)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg3 = ( intype3 ) PyCObject_AsVoidPtr(obj3); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3)); \ +} + + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2, intype3 arg3, const char *arg4) + */ +#define _wrap_objobjobjstr2obj(func, intype1, intype2, intype3, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2, *obj3; \ + intype1 arg1; \ + intype2 arg2; \ + intype3 arg3; \ + const char *arg4; \ + \ + if (!PyArg_ParseTuple(args, "OOOs", &obj1, &obj2, &obj3, &arg4)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + arg3 = ( intype3 ) PyCObject_AsVoidPtr(obj3); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3, arg4)); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2, intype3 arg3, arg4) + */ +#define _wrap_objobjobjint2obj(func, intype1, intype2, intype3, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2, *obj3; \ + intype1 arg1; \ + intype2 arg2; \ + intype3 arg3; \ + int arg4; \ + \ + if (!PyArg_ParseTuple(args, "OOOi", &obj1, &obj2, &obj3, &arg4)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + arg3 = ( intype3 ) PyCObject_AsVoidPtr(obj3); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3, arg4)); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2, intype3 arg3, intype arg4) + */ +#define _wrap_objobjobjobj2obj(func, intype1, intype2, intype3, intype4, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2, *obj3, *obj4; \ + intype1 arg1; \ + intype2 arg2; \ + intype3 arg3; \ + intype4 arg4; \ + \ + if (!PyArg_ParseTuple(args, "OOOO", &obj1, &obj2, &obj3, &obj4)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + arg3 = ( intype3 ) PyCObject_AsVoidPtr(obj3); \ + arg4 = ( intype4 ) PyCObject_AsVoidPtr(obj4); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3, arg4)); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2, intype3 arg3, intype arg4, const char *arg5) + */ +#define _wrap_objobjobjobjstr2obj(func, intype1, intype2, intype3, intype4, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2, *obj3, *obj4; \ + intype1 arg1; \ + intype2 arg2; \ + intype3 arg3; \ + intype4 arg4; \ + const char *arg5; \ + \ + if (!PyArg_ParseTuple(args, "OOOOs", &obj1, &obj2, &obj3, &obj4, &arg5)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + arg3 = ( intype3 ) PyCObject_AsVoidPtr(obj3); \ + arg4 = ( intype4 ) PyCObject_AsVoidPtr(obj4); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3, arg4, arg5)); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, int arg2, intype3 arg3, intype4 arg4, const char *arg5) + */ +#define _wrap_objintobjobjstr2obj(func, intype1, intype3, intype4, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj3, *obj4; \ + intype1 arg1; \ + int arg2; \ + intype3 arg3; \ + intype4 arg4; \ + const char *arg5; \ + \ + if (!PyArg_ParseTuple(args, "OiOOs", &obj1, &arg2, &obj3, &obj4, &arg5)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg3 = ( intype3 ) PyCObject_AsVoidPtr(obj3); \ + arg4 = ( intype4 ) PyCObject_AsVoidPtr(obj4); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3, arg4, arg5)); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 *arg2v, unsigned arg2n) + * where arg2v is an array of intype2 elements, arg2n in length. + */ +#define _wrap_objlist2obj(func, intype1, intype2, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2; \ + intype1 arg1; \ + intype2 *arg2v; \ + unsigned arg2n; \ + outtype ret; \ + \ + if (!PyArg_ParseTuple(args, "OO", &obj1, &obj2)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2n = (unsigned) PyList_Size(obj2); \ + if (!(arg2v = ( intype2 *)make_array_from_list(obj2, arg2n))) \ + return PyErr_NoMemory(); \ + \ + ret = func (arg1, arg2v, arg2n); \ + free(arg2v); \ + return ctor_ ## outtype (ret); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 *arg1v, unsigned arg1n, int arg2) + * where arg1v is an array of intype1 elements, arg1n in length. + */ +#define _wrap_listint2obj(func, intype1, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1; \ + int arg2; \ + intype1 *arg1v; \ + unsigned arg1n; \ + outtype ret; \ + \ + if (!PyArg_ParseTuple(args, "Oi", &obj1, &arg2)) \ + return NULL; \ + \ + arg1n = (unsigned) PyList_Size(obj1); \ + if (!(arg1v = ( intype1 *)make_array_from_list(obj1, arg1n))) \ + return PyErr_NoMemory(); \ + \ + ret = func (arg1v, arg1n, arg2); \ + free(arg1v); \ + return ctor_ ## outtype (ret); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 *arg1v, unsigned arg1n) + * where arg1v is an array of intype1 elements, arg1n in length. + */ +#define _wrap_list2obj(func, intype1, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1; \ + intype1 *arg1v; \ + unsigned arg1n; \ + outtype ret; \ + \ + if (!PyArg_ParseTuple(args, "O", &obj1)) \ + return NULL; \ + \ + arg1n = (unsigned) PyList_Size(obj1); \ + if (!(arg1v = ( intype1 *)make_array_from_list(obj1, arg1n))) \ + return PyErr_NoMemory(); \ + \ + ret = func (arg1v, arg1n); \ + free(arg1v); \ + return ctor_ ## outtype (ret); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 *arg2v, unsigned arg2n, int arg3) + * where arg2v is an array of intype2 elements, arg2n in length. + */ +#define _wrap_objlistint2obj(func, intype1, intype2, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2; \ + intype1 arg1; \ + intype2 *arg2v; \ + unsigned arg2n; \ + int arg3; \ + outtype ret; \ + \ + if (!PyArg_ParseTuple(args, "OOi", &obj1, &obj2, &arg3)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2n = (unsigned) PyList_Size(obj2); \ + if (!(arg2v = ( intype2 *)make_array_from_list(obj2, arg2n))) \ + return PyErr_NoMemory(); \ + \ + ret = func (arg1, arg2v, arg2n, arg3); \ + free(arg2v); \ + return ctor_ ## outtype (ret); \ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2, intype3 *arg3v, unsigned arg3n, const char *arg4) + * where arg3v is an array of intype3 elements, arg3n in length. + */ +#define _wrap_objobjliststr2obj(func, intype1, intype2, intype3, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2, *obj3; \ + const char *arg4; \ + intype1 arg1; \ + intype2 arg2; \ + intype3 *arg3v; \ + unsigned arg3n; \ + outtype ret; \ + \ + if (!PyArg_ParseTuple(args, "OOOs", &obj1, &obj2, &obj3, &arg4))\ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + arg3n = ( unsigned ) PyList_Size(obj3); \ + if (!(arg3v = ( intype3 *)make_array_from_list(obj3, arg3n))) \ + return PyErr_NoMemory(); \ + \ + ret = func (arg1, arg2, arg3v, arg3n, arg4); \ + free(arg3v); \ + return ctor_ ## outtype (ret); \ +} + +/** + * Wrap LLVM dump-to-string functions of the type + * char *func(intype1) + * where the return value has to be disposed after use by calling + * LLVMDisposeMessage. + */ +#define _wrap_dumper(func, intype1) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + intype1 arg1; \ + char *val; \ + PyObject *ret; \ + \ + if (!(arg1= ( intype1 ) get_object_arg(args))) \ + return NULL; \ + \ + val = func (arg1); \ + ret = PyString_FromString(val); \ + LLVMDisposeMessage(val); \ + return ret; \ +} + +#endif /* LLVM_PY_WRAP_H */ + diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..2706fdc --- /dev/null +++ b/setup.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python + +import sys, os +from distutils.core import setup, Extension + + +def _run(cmd): + return os.popen(cmd).read().rstrip() + + +def get_libs(llvm_config, components): + return _run(llvm_config + ' --libs ' + ' '.join(components)) + + +def get_llvm_config(): + + # get from command-line, or use default + lc = 'llvm-config' + for i in xrange(0, len(sys.argv)): + arg = sys.argv[i] + if arg.startswith('--llvm-config='): + del sys.argv[i] + lc = arg.split('=')[1] + + # see if it works + version = _run(lc + ' --version') + if version == '': + return (lc, False) # didn't work + + return (lc, True) + + +def call_setup(llvm_config): + + incdir = _run(llvm_config + ' --includedir') + ldflags = _run(llvm_config + ' --ldflags') + libs_core = get_libs(llvm_config, ['core', 'analysis']) + + ext_core = Extension( + 'llvm._core', + ['llvm/_core.c', 'llvm/wrap.c', 'llvm/extra.cpp'], + define_macros = [ + ('__STDC_LIMIT_MACROS', None), + ('_GNU_SOURCE', None)], + include_dirs = [incdir], + extra_link_args = [ldflags + ' ' + libs_core]) + + setup( + name='llvm-py', + version='0.2', + description='Python Bindings for LLVM', + author='Mahadevan R', + author_email='mdevan.foobar@gmail.com', + url='http://code.google.com/p/llvm-py/', + packages=['llvm'], + py_modules = [ 'llvm.core' ], + ext_modules = [ ext_core ],) + + +def main(): + + # get llvm config + llvm_config, is_good = get_llvm_config() + if is_good: + print "Using llvm-config=" + llvm_config + else: + print "Cannot invoke llvm-config (tried '%s')." % llvm_config + print "Try again with --llvm-config=/path/to/llvm-config." + return 1 + + # setup + call_setup(llvm_config) + + # done + return 0 + + +ev = main() +sys.exit(ev) + diff --git a/test/example.py b/test/example.py new file mode 100644 index 0000000..f1e266a --- /dev/null +++ b/test/example.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +from llvm.core import * + +## create a module +module = Module.new("my_module") + +## create a function type taking two doubles and returning a (32-bit) integer +ty_double = Type.double() +ty_int = Type.int() +ty_func = Type.function( ty_int, [ ty_double, ty_double ] ) + +## create a function of this type +func = Function.new( module, ty_func, "foobar" ) + +# name function args +func.args[0].name = "arg1" +func.args[1].name = "arg2" + +## implement the function + +# add a basic block +entry = func.append_basic_block("entry") + +# create an llvm::IRBuilder +builder = Builder.new() +builder.position_at_end(entry) + +# add two args into temp1 +temp1 = builder.add(func.args[0], func.args[1], "temp1") + +# sub `1' from that +one = Constant.real( ty_double, 1.0 ) +temp2 = builder.sub(temp1, one, "temp2") + +# convert to integer +temp3 = builder.fptoui(temp2, ty_int, "temp3") + +# return it +builder.ret(temp3) + +# dump the module to see the bc +module.dump() diff --git a/test/test.py b/test/test.py new file mode 100644 index 0000000..d400b23 --- /dev/null +++ b/test/test.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python + +# watch out for uncollected objects +import gc + +import unittest, sys + +from llvm.core import * + +class TestModule(unittest.TestCase): + + def setUp(self): + pass + + def testmodule_and_moduleprovider(self): + """Ownership issues between Module and ModuleProvider objects.""" + + def temp_mp(m): + mp = ModuleProvider.new(m) + del mp + + def temp_m(): + m = Module.new("temp_m") + return ModuleProvider.new(m) + + m = Module.new("test1.1") + self.assertEqual(m.owner, None) + mp = ModuleProvider.new(m) + self.assertEqual(m.owner, mp) + mp_repr = repr(mp) + mp = None + self.assertNotEqual(m.owner, None) + self.assertEqual(repr(m.owner), mp_repr) + m = None + self.assertEqual(gc.garbage, []) + + m2 = Module.new("test1.2") + temp_mp(m2) + del m2 + self.assertEqual(gc.garbage, []) + + mp3 = temp_m() + mp3 = None + + m4 = Module.new("test1.4") + self.assertEqual(sys.getrefcount(m4), 1+1) + mp4 = ModuleProvider.new(m4) + self.assertEqual(sys.getrefcount(m4), 1+1) + self.assertEqual(sys.getrefcount(mp4), 2+1) + m4 = None + self.assertEqual(sys.getrefcount(mp4), 1+1) + mp4 = None + + own_works = False + m5 = Module.new("test1.5") + mp5 = ModuleProvider.new(m5) + try: + m5._own(None) + except AssertionError: + own_works = True + self.assertEqual(own_works, True) + + + def testdata_layout(self): + """Data layout property.""" + m = Module.new("test2.1") + self.assertEqual(m.data_layout, '') + m.data_layout = 'some_value' + self.assertEqual(m.data_layout, 'some_value') + reqd = '; ModuleID = \'test2.1\'\ntarget datalayout = "some_value"\n' + self.assertEqual(str(m), reqd) + + def testtarget(self): + """Target property.""" + m = Module.new("test3.1") + self.assertEqual(m.target, '') + m.target = 'some_value' + self.assertEqual(m.target, 'some_value') + reqd = '; ModuleID = \'test3.1\'\ntarget triple = "some_value"\n' + self.assertEqual(str(m), reqd) + + def testtype_name(self): + """Type names.""" + m = Module.new("test4.1") + r = m.add_type_name("typename41", Type.int()) + self.assertEqual(r, 0) + r = m.add_type_name("typename41", Type.int()) + self.assertEqual(r, 1) + reqd = "; ModuleID = 'test4.1'\n\t%typename41 = type i32\n" + self.assertEqual(str(m), reqd) + r = m.delete_type_name("typename41") + reqd = "; ModuleID = 'test4.1'\n" + self.assertEqual(str(m), reqd) + r = m.delete_type_name("no such name") # nothing should happen + reqd = "; ModuleID = 'test4.1'\n" + self.assertEqual(str(m), reqd) + + def testglobal_variable(self): + """Global variables.""" + m = Module.new("test5.1") + t = Type.int() + gv = m.add_global_variable(t, "gv") + print m + self.assertNotEqual(gv, None) + self.assertEqual(gv.name, "gv") + self.assertEqual(gv.type, t) + +def main(): + gc.set_debug(gc.DEBUG_LEAK) + + # run tests + unittest.main() + + # done + if gc.garbage: + print "garbage = ", gc.garbage + + +main()