Merge pull request #20 from laanwj/2012_09_module_named_metadata

Add support for module named metadata
This commit is contained in:
Ilan Schnell 2012-09-12 12:27:55 -07:00
commit 28c659ec90
5 changed files with 113 additions and 1 deletions

View file

@ -607,6 +607,30 @@ _wrap_obj2none(LLVMDeleteBasicBlock, LLVMBasicBlockRef)
/*===-- MetaData -----------------------------------------------------===*/ /*===-- MetaData -----------------------------------------------------===*/
_wrap_objlist2obj(LLVMMetaDataGet, LLVMModuleRef, LLVMValueRef, LLVMValueRef) _wrap_objlist2obj(LLVMMetaDataGet, LLVMModuleRef, LLVMValueRef, LLVMValueRef)
_wrap_objstrobj2none(LLVMAddNamedMetadataOperand, LLVMModuleRef, LLVMValueRef)
_wrap_objint2obj(LLVMMetaDataGetOperand, LLVMValueRef, LLVMValueRef)
_wrap_obj2obj(LLVMMetaDataGetNumOperands, LLVMValueRef, int)
_wrap_objstr2obj(LLVMMetaDataStringGet, LLVMModuleRef, LLVMValueRef)
static PyObject *
_wLLVMGetNamedMetadataOperands(PyObject *self, PyObject *args)
{
PyObject *obj_module;
const char *name;
if (!PyArg_ParseTuple(args, "Os", &obj_module, &name))
return NULL;
LLVMModuleRef module = (LLVMModuleRef)PyCapsule_GetPointer(obj_module, NULL);
unsigned num_operands = LLVMGetNamedMetadataNumOperands(module, name);
LLVMValueRef *operands = (LLVMValueRef*)malloc(sizeof(LLVMValueRef)*num_operands);
LLVMGetNamedMetadataOperands(module, name, operands);
PyObject *list = make_list_from_LLVMValueRef_array(operands, num_operands);
free(operands);
return list;
}
/*===-- Instructions -----------------------------------------------------===*/ /*===-- Instructions -----------------------------------------------------===*/
@ -1660,6 +1684,11 @@ static PyMethodDef core_methods[] = {
/* MetaData */ /* MetaData */
_method( LLVMMetaDataGet ) _method( LLVMMetaDataGet )
_method( LLVMGetNamedMetadataOperands )
_method( LLVMAddNamedMetadataOperand )
_method( LLVMMetaDataGetOperand )
_method( LLVMMetaDataGetNumOperands )
_method( LLVMMetaDataStringGet )
/* Instructions */ /* Instructions */
_method( LLVMGetInstructionParent ) _method( LLVMGetInstructionParent )

View file

@ -1457,6 +1457,38 @@ class MetaData(Value):
ptr = _core.LLVMMetaDataGet(module.ptr, vs) ptr = _core.LLVMMetaDataGet(module.ptr, vs)
return MetaData(ptr) return MetaData(ptr)
@staticmethod
def get_named_operands(module, name):
lst = _core.LLVMGetNamedMetadataOperands(module.ptr, name)
return [MetaData(ptr) for ptr in lst]
@staticmethod
def add_named_operand(module, name, operand):
_core.LLVMAddNamedMetadataOperand(module.ptr, name, operand.ptr)
@property
def operand_count(self):
return _core.LLVMMetaDataGetNumOperands(self.ptr)
@property
def operands(self):
"""Yields operands of this metadata."""
return [self._get_operand(i) for i in range(self.operand_count)]
def _get_operand(self, i):
return _make_value(_core.LLVMMetaDataGetOperand(self.ptr, i))
class MetaDataString(Value):
@staticmethod
def get(module, s):
ptr = _core.LLVMMetaDataStringGet(module.ptr, s)
return MetaDataString(ptr)
@property
def string(self):
'''Same as MDString::getString'''
return self.name
#===----------------------------------------------------------------------=== #===----------------------------------------------------------------------===
# Instruction # Instruction
#===----------------------------------------------------------------------=== #===----------------------------------------------------------------------===
@ -1627,6 +1659,8 @@ __class_for_valueid = {
VALUE_CONSTANT_STRUCT : ConstantStruct, VALUE_CONSTANT_STRUCT : ConstantStruct,
VALUE_CONSTANT_VECTOR : ConstantVector, VALUE_CONSTANT_VECTOR : ConstantVector,
VALUE_CONSTANT_POINTER_NULL : ConstantPointerNull, VALUE_CONSTANT_POINTER_NULL : ConstantPointerNull,
VALUE_MD_NODE : MetaData,
VALUE_MD_STRING : MetaDataString,
VALUE_INSTRUCTION + OPCODE_PHI : PHINode, VALUE_INSTRUCTION + OPCODE_PHI : PHINode,
VALUE_INSTRUCTION + OPCODE_CALL : CallOrInvokeInstruction, VALUE_INSTRUCTION + OPCODE_CALL : CallOrInvokeInstruction,
VALUE_INSTRUCTION + OPCODE_INVOKE : CallOrInvokeInstruction, VALUE_INSTRUCTION + OPCODE_INVOKE : CallOrInvokeInstruction,

View file

@ -149,6 +149,23 @@ LLVMValueRef LLVMMetaDataGet(LLVMModuleRef modref, LLVMValueRef * valrefs,
return wrap(node); return wrap(node);
} }
LLVMValueRef LLVMMetaDataGetOperand(LLVMValueRef mdref, unsigned index)
{
return wrap(llvm::unwrap<llvm::MDNode>(mdref)->getOperand(index));
}
unsigned LLVMMetaDataGetNumOperands(LLVMValueRef mdref)
{
return llvm::unwrap<llvm::MDNode>(mdref)->getNumOperands();
}
LLVMValueRef LLVMMetaDataStringGet(LLVMModuleRef modref, const char *s)
{
LLVMContext & context = unwrap(modref)->getContext();
MDString * const mdstring = MDString::get(context, s);
return wrap(mdstring);
}
const char *LLVMGetConstExprOpcodeName(LLVMValueRef inst) const char *LLVMGetConstExprOpcodeName(LLVMValueRef inst)
{ {
return llvm::unwrap<llvm::ConstantExpr>(inst)->getOpcodeName(); return llvm::unwrap<llvm::ConstantExpr>(inst)->getOpcodeName();

View file

@ -65,6 +65,21 @@ void LLVMInstSetMetaData(LLVMValueRef instref, const char* mdkind,
LLVMValueRef LLVMMetaDataGet(LLVMModuleRef modref, LLVMValueRef * valrefs, LLVMValueRef LLVMMetaDataGet(LLVMModuleRef modref, LLVMValueRef * valrefs,
unsigned valct); unsigned valct);
/*
* Wraps MDNode::getOperand()
*/
LLVMValueRef LLVMMetaDataGetOperand(LLVMValueRef mdref, unsigned index);
/*
* Wraps MDNode::getNumOperands()
*/
unsigned LLVMMetaDataGetNumOperands(LLVMValueRef mdref);
/*
* Wraps MDString::get()
*/
LLVMValueRef LLVMMetaDataStringGet(LLVMModuleRef modref, const char *s);
/* /*
* Wraps ConstantExpr::getOpcodeName() * Wraps ConstantExpr::getOpcodeName()
*/ */

View file

@ -16,7 +16,7 @@ else:
from llvm import __version__ from llvm import __version__
from llvm.core import (Module, Type, GlobalVariable, Function, Builder, from llvm.core import (Module, Type, GlobalVariable, Function, Builder,
Constant) Constant, MetaData, MetaDataString)
import llvm.passes as lp import llvm.passes as lp
import llvm.ee as le import llvm.ee as le
@ -390,6 +390,23 @@ tests.append(TestUses)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
class TestMetaData(unittest.TestCase):
# test module metadata
def test_metadata(self):
m = Module.new('a')
t = Type.int()
metadata = MetaData.get(m, [Constant.int(t, 100), MetaDataString.get(m, 'abcdef')])
MetaData.add_named_operand(m, 'foo', metadata)
self.assertEqual(MetaData.get_named_operands(m, 'foo'), [metadata])
self.assertEqual(MetaData.get_named_operands(m, 'bar'), [])
self.assertEqual(len(metadata.operands), 2)
self.assertEqual(metadata.operands[0].z_ext_value, 100)
self.assertEqual(metadata.operands[1].string, 'abcdef')
tests.append(TestMetaData)
# ---------------------------------------------------------------------------
def run(verbosity=1): def run(verbosity=1):
print('llvmpy is installed in: ' + os.path.dirname(__file__)) print('llvmpy is installed in: ' + os.path.dirname(__file__))
print('llvmpy version: ' + __version__) print('llvmpy version: ' + __version__)