diff --git a/llvm/_core.cpp b/llvm/_core.cpp index 2453479..15a58dd 100644 --- a/llvm/_core.cpp +++ b/llvm/_core.cpp @@ -608,6 +608,8 @@ _wrap_obj2none(LLVMDeleteBasicBlock, LLVMBasicBlockRef) _wrap_objlist2obj(LLVMMetaDataGet, LLVMModuleRef, LLVMValueRef, LLVMValueRef) _wrap_objstrobj2none(LLVMAddNamedMetadataOperand, LLVMModuleRef, LLVMValueRef) +_wrap_objint2obj(LLVMMetaDataGetOperand, LLVMValueRef, LLVMValueRef) +_wrap_obj2obj(LLVMMetaDataGetNumOperands, LLVMValueRef, int) static PyObject * _wLLVMGetNamedMetadataOperands(PyObject *self, PyObject *args) @@ -1683,6 +1685,8 @@ static PyMethodDef core_methods[] = { _method( LLVMMetaDataGet ) _method( LLVMGetNamedMetadataOperands ) _method( LLVMAddNamedMetadataOperand ) + _method( LLVMMetaDataGetOperand ) + _method( LLVMMetaDataGetNumOperands ) /* Instructions */ _method( LLVMGetInstructionParent ) diff --git a/llvm/core.py b/llvm/core.py index d5b829b..ed0a9b3 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -1466,6 +1466,18 @@ class MetaData(Value): 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)) + #===----------------------------------------------------------------------=== # Instruction #===----------------------------------------------------------------------=== diff --git a/llvm/extra.cpp b/llvm/extra.cpp index 9925028..ca966bc 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -149,6 +149,16 @@ LLVMValueRef LLVMMetaDataGet(LLVMModuleRef modref, LLVMValueRef * valrefs, return wrap(node); } +LLVMValueRef LLVMMetaDataGetOperand(LLVMValueRef mdref, unsigned index) +{ + return wrap(llvm::unwrap(mdref)->getOperand(index)); +} + +unsigned LLVMMetaDataGetNumOperands(LLVMValueRef mdref) +{ + return llvm::unwrap(mdref)->getNumOperands(); +} + const char *LLVMGetConstExprOpcodeName(LLVMValueRef inst) { return llvm::unwrap(inst)->getOpcodeName(); diff --git a/llvm/extra.h b/llvm/extra.h index dc0a029..1858469 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -65,6 +65,16 @@ void LLVMInstSetMetaData(LLVMValueRef instref, const char* mdkind, LLVMValueRef LLVMMetaDataGet(LLVMModuleRef modref, LLVMValueRef * valrefs, unsigned valct); +/* + * Wraps MDNode::getOperand() + */ +LLVMValueRef LLVMMetaDataGetOperand(LLVMValueRef mdref, unsigned index); + +/* + * Wraps MDNode::getNumOperands() + */ +unsigned LLVMMetaDataGetNumOperands(LLVMValueRef mdref); + /* * Wraps ConstantExpr::getOpcodeName() */ diff --git a/llvm/test_llvmpy.py b/llvm/test_llvmpy.py index 5d0d62b..f03070a 100644 --- a/llvm/test_llvmpy.py +++ b/llvm/test_llvmpy.py @@ -394,10 +394,13 @@ class TestMetaData(unittest.TestCase): # test module metadata def test_metadata(self): m = Module.new('a') - metadata = MetaData.get(m, []) # empty metadata node + t = Type.int() + metadata = MetaData.get(m, [Constant.int(t, 100)]) 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), 1) + self.assertEqual(metadata.operands[0].z_ext_value, 100) tests.append(TestMetaData)