diff --git a/newbinding/include/llvm_binding/extra.h b/newbinding/include/llvm_binding/extra.h index 77b399d..fd4eb4e 100644 --- a/newbinding/include/llvm_binding/extra.h +++ b/newbinding/include/llvm_binding/extra.h @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -8,6 +9,10 @@ #include #include #include +#include +#include + +#include "auto_pyobject.h" namespace extra{ using namespace llvm; @@ -496,3 +501,80 @@ PyObject* TargetMachine_addPassesToEmitFile( } } +static +PyObject* Linker_LinkInModule(llvm::Linker* Linker, + llvm::Module* Mod, + PyObject* ErrMsg) +{ + std::string errmsg; + bool failed = Linker->LinkInModule(Mod, &errmsg); + if (not failed) { + Py_RETURN_FALSE; + } else { + if (-1 == PyFile_WriteString(errmsg.c_str(), ErrMsg)) { + return NULL; + } + Py_RETURN_TRUE; + } +} + +static +PyObject* Linker_LinkModules(llvm::Module* Dest, + llvm::Module* Src, + unsigned Mode, + PyObject* ErrMsg) +{ + std::string errmsg; + bool failed = llvm::Linker::LinkModules(Dest, Src, Mode, &errmsg); + if (not failed) { + Py_RETURN_FALSE; + } else { + if (-1 == PyFile_WriteString(errmsg.c_str(), ErrMsg)) { + return NULL; + } + Py_RETURN_TRUE; + } +} + +static +PyObject* StructType_setBody(llvm::StructType* Self, + PyObject* Elems, + bool isPacked=false) +{ + using namespace llvm; + std::vector elements; + Py_ssize_t N = PySequence_Size(Elems); + elements.reserve(N); + for (Py_ssize_t i=0; i < N; ++i) { + auto_pyobject obj = PySequence_GetItem(Elems, i); + auto_pyobject capsule = PyObject_GetAttrString(*obj, "_ptr"); + if (!capsule) { + return NULL; + } + void * ptr = PyCapsule_GetPointer(*capsule, "llvm::Type"); + if (!ptr) { + return NULL; + } + Type* type = static_cast(ptr); + elements.push_back(type); + } + + Self->setBody(elements, isPacked); + + Py_RETURN_NONE; +} + +static +PyObject* Module_list_globals(llvm::Module* Mod) +{ + return iplist_to_pylist(Mod->getGlobalList(), + "llvm::Value", "llvm::GlobalVariable"); +} + +static +PyObject* Module_list_functions(llvm::Module* Mod) +{ + return iplist_to_pylist(Mod->getFunctionList(), + "llvm::Value", "llvm::Function"); +} + diff --git a/newbinding/src/GlobalValue.py b/newbinding/src/GlobalValue.py index 40825a8..d14d48a 100644 --- a/newbinding/src/GlobalValue.py +++ b/newbinding/src/GlobalValue.py @@ -6,3 +6,21 @@ from Value import GlobalValue class GlobalValue: _include_ = 'llvm/GlobalValue.h' + LinkageTypes = Enum(''' + ExternalLinkage, AvailableExternallyLinkage, LinkOnceAnyLinkage, + LinkOnceODRLinkage, LinkOnceODRAutoHideLinkage, WeakAnyLinkage, + WeakODRLinkage, AppendingLinkage, InternalLinkage, PrivateLinkage, + LinkerPrivateLinkage, LinkerPrivateWeakLinkage, DLLImportLinkage, + DLLExportLinkage, ExternalWeakLinkage, CommonLinkage + ''') + + VisibilityTypes = Enum('''DefaultVisibility, + HiddenVisibility, + ProtectedVisibility''') + + setLinkage = Method(Void, LinkageTypes) + getLinkage = Method(LinkageTypes) + + setVisibility = Method(Void, VisibilityTypes) + getVisibility = Method(VisibilityTypes) + diff --git a/newbinding/src/GlobalVariable.py b/newbinding/src/GlobalVariable.py index 548a8d1..70203d5 100644 --- a/newbinding/src/GlobalVariable.py +++ b/newbinding/src/GlobalVariable.py @@ -1,8 +1,48 @@ from binding import * from namespace import llvm + from GlobalValue import GlobalValue +GlobalVariable = llvm.Class(GlobalValue) -@llvm.Class(GlobalValue) +from Constant import Constant +from Module import Module +from Type import Type +from ADT.StringRef import StringRef + +@GlobalVariable class GlobalVariable: - pass + ThreadLocalMode = Enum('''NotThreadLocal, GeneralDynamicTLSModel, + LocalDynamicTLSModel, InitialExecTLSModel, + LocalExecTLSModel + ''') + new = Constructor(ref(Module), + ptr(Type), + cast(bool, Bool), # is constant + GlobalValue.LinkageTypes, + ptr(Constant), # initializer -- can be None + cast(str, StringRef), # name + ptr(GlobalVariable), # insert before + ThreadLocalMode, + cast(int, Unsigned), # address-space + # cast(bool, Bool), # externally initialized + ).require_only(5) + + setThreadLocal = Method(Void, cast(bool, Bool)) + setThreadLocalMode = Method(Void, ThreadLocalMode) + isThreadLocal = Method(cast(Bool, bool)) + + isConstant = Method(cast(Bool, bool)) + setConstant = Method(Void, ptr(Constant)) + + setInitializer = Method(Void, ptr(Constant)) + getInitializer = Method(ptr(Constant)) + hasInitializer = Method(cast(Bool, bool)) + + hasUniqueInitializer = Method(cast(Bool, bool)) + hasDefinitiveInitializer = Method(cast(Bool, bool)) + +# isExternallyInitialized = Method(cast(Bool, bool)) +# setExternallyinitialized = Method(Void, cast(bool, Bool)) + + \ No newline at end of file diff --git a/newbinding/src/Module.py b/newbinding/src/Module.py index 539c486..706fe48 100644 --- a/newbinding/src/Module.py +++ b/newbinding/src/Module.py @@ -1,14 +1,19 @@ from binding import * from namespace import llvm + +Module = llvm.Class() + from LLVMContext import LLVMContext from ADT.StringRef import StringRef from Constant import Constant +from GlobalVariable import GlobalVariable from Function import Function from DerivedTypes import FunctionType from Support.raw_ostream import raw_ostream from Assembly.AssemblyAnnotationWriter import AssemblyAnnotationWriter +from Type import Type, StructType -@llvm.Class() +@Module class Module: _include_ = "llvm/Module.h" # Enumerators @@ -38,6 +43,21 @@ class Module: # Function Accessors getOrInsertFunction = Method(ptr(Constant), cast(str, StringRef), ptr(FunctionType)) + getFunction = Method(ptr(Function), cast(str, StringRef)) + + # Function Iteration + list_functions = CustomMethod('Module_list_functions', PyObjectPtr) + + # GlobalVariabe Accessors + getGlobalVariable = Method(ptr(GlobalVariable), + cast(str, StringRef), + cast(bool, Bool), + ).require_only(1) + getNamedGlobal = Method(ptr(GlobalVariable), cast(str, StringRef)) + getOrInsertGlobal = Method(ptr(Constant), cast(str, StringRef), ptr(Type)) + + # GlobalVariable Iteration + list_globals = CustomMethod('Module_list_globals', PyObjectPtr) # Utilities dump = Method(Void) @@ -52,3 +72,7 @@ class Module: return os.str() dropAllReferences = Method() + + getTypeByName = Method(ptr(StructType), cast(str, StringRef)) + + \ No newline at end of file diff --git a/newbinding/src/Type.py b/newbinding/src/Type.py index 8e6b381..09b8ba9 100644 --- a/newbinding/src/Type.py +++ b/newbinding/src/Type.py @@ -110,6 +110,12 @@ class Type: getIntNPtrTy = StaticMethod(ptr(PointerType), ref(LLVMContext), cast(int, Unsigned)) + @CustomPythonMethod + def __str__(self): + import extra + os = extra.make_raw_ostream_for_printing() + self.print_(os) + return os.str() @IntegerType class IntegerType: @@ -130,4 +136,23 @@ class PointerType: @StructType class StructType: - pass + isPacked = Method(cast(Bool, bool)) + isLiteral = Method(cast(Bool, bool)) + isOpaque = Method(cast(Bool, bool)) + hasName = Method(cast(Bool, bool)) + getName = Method(cast(StringRef, str)) + setName = Method(Void, cast(str, StringRef)) + setBody = CustomMethod('StructType_setBody', + PyObjectPtr, # None + PyObjectPtr, # ArrayRef + cast(bool, Bool), + ).require_only(1) + getNumElements = Method(cast(Unsigned, int)) + getElementType = Method(ptr(Type), cast(int, Unsigned)) + + create = StaticMethod(ptr(StructType), + ref(LLVMContext), + cast(str, StringRef), + ).require_only(1) + isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type)) + diff --git a/newbinding/src/Value.py b/newbinding/src/Value.py index 5841746..5675fa5 100644 --- a/newbinding/src/Value.py +++ b/newbinding/src/Value.py @@ -1,13 +1,8 @@ from binding import * from namespace import llvm -from Support.raw_ostream import raw_ostream -from Assembly.AssemblyAnnotationWriter import AssemblyAnnotationWriter -from Type import Type -from LLVMContext import LLVMContext -from ADT.StringRef import StringRef -Value = llvm.Class() # forward declarations +Value = llvm.Class() Argument = llvm.Class(Value) MDNode = llvm.Class(Value) User = llvm.Class(Value) @@ -16,6 +11,13 @@ Constant = llvm.Class(User) GlobalValue = llvm.Class(Constant) Function = llvm.Class(GlobalValue) +from Support.raw_ostream import raw_ostream +from Assembly.AssemblyAnnotationWriter import AssemblyAnnotationWriter +from Type import Type +from LLVMContext import LLVMContext +from ADT.StringRef import StringRef + + @Value class Value: