Added funcsig buffer mappings

This commit is contained in:
kevstone 2024-01-26 15:26:50 +00:00
parent caaae6360d
commit 9030f1f4ba
6 changed files with 56 additions and 6 deletions

View File

@ -0,0 +1,28 @@
# Represents the mapping from a buffer in C code {ptr, len} to a container class in C++
#
# For example char* v, size_t* len => std::string str
import code_object.arg as arg
class BufferMapping():
def __init__(self, *, cbuffer=None, clength=None, cpp_container=None):
assert isinstance(cbuffer, arg.Arg), f"cbuffer must be Arg instance, not [{type(cbuffer).__name__}]"
assert isinstance(clength, arg.Arg), f"clength must be Arg instance, not [{type(clength).__name__}]"
assert isinstance(cpp_container, arg.Arg), f"cpp_container must be Arg instance, not [{type(cpp_container).__name__}]"
self._cbuffer = cbuffer
self._clength = clength
self._cpp_container = cpp_container
@property
def cbuffer(self):
return self._cbuffer
@property
def clength(self):
return self._clength
@property
def cpp_container(self):
return self._cpp_container

View File

@ -8,6 +8,7 @@ class CodeMappings:
self._funcbody_arg_mappings = {}
self._funcsig_arg_mappings = {}
self._funcsig_type_mappings = {}
self._funcsig_buffer_mappings = [] # Don't expect more than one entry, but just in case!
self._data_member_mappings = {}
self._funcsig_mappings = []
self._funcsig_pointer_mappings = []
@ -32,6 +33,10 @@ class CodeMappings:
def funcsig_type_mappings(self):
return self._funcsig_type_mappings
@property
def funcsig_buffer_mappings(self):
return self._funcsig_buffer_mappings
@property
def data_member_mappings(self):
return self._data_member_mappings

View File

@ -10,6 +10,7 @@ from code_object.declaration_specifier import DeclSpec
from code_object_converter.conversion_pack.conversion_data_helper import *
from code_object_converter.conversion_pack.conversion_validation import ConversionValidation
from code_object.code_interface import NONE_VALUE
import code_object_converter.conversion_pack.buffer_mapping as buffer_mapping
from copy import deepcopy
# Store C to C++ conversion data to be used by the converters
@ -66,7 +67,6 @@ class ConversionData:
self.active_map.funcbody_type_mappings[deepcopy(cdecl_spec)] = deepcopy(cppdecl_spec)
debug.line("add_funcbody_type_mapping", f"Adding decl_spec: [{debug.as_debug_string(cdecl_spec)}] -> [{debug.as_debug_string(cppdecl_spec)}]")
def add_funcsig_type_mapping(self, cdecl_spec, cppdecl_spec):
assert isinstance(cdecl_spec, DeclSpec), f"Expected DeclSpec, got [{cdecl_spec}]"
assert isinstance(cppdecl_spec, DeclSpec) or cppdecl_spec==DeclSpec.NONE, f"Expected DeclSpec, got [{cppdecl_spec}]"
@ -76,6 +76,11 @@ class ConversionData:
self.active_map.funcsig_type_mappings[deepcopy(cdecl_spec)] = deepcopy(cppdecl_spec)
debug.line("add_funcsig_type_mapping", f"Adding decl_spec: [{debug.as_debug_string(cdecl_spec)}] -> [{debug.as_debug_string(cppdecl_spec)}]")
def add_funcsig_buffer_mapping(self, cbuffer, clength, cpp_container):
mapping = buffer_mapping.BufferMapping(cbuffer=cbuffer, clength=clength, cpp_container=cpp_container)
debug.line("add_funcsig_buffer_mapping", f"Adding cbuffer=[{debug.as_debug_string(mapping.cbuffer)}] , clength=[{debug.as_debug_string(mapping.clength)}] -> cpp_container=[{debug.as_debug_string(mapping.cpp_container)}]")
self.active_map.funcsig_buffer_mappings.append(mapping)
def add_funcbody_arg_mapping(self, carg, cpparg):
assert isinstance(carg, Arg), f"Expected Arg, got [{carg}]"
assert isinstance(cpparg, Arg) or cpparg==NONE_VALUE, f"Expected Arg, got [{cpparg}]"
@ -279,6 +284,7 @@ class ConversionData:
return value
return None
#def funcsig_buffer_mapping_for
# Searches both C and C++ member and virtual member maps
def is_member_function(self, function_name):

View File

@ -15,10 +15,19 @@ class FuncSigConverter(code_interface_converter.CodeInterfaceConverter):
def create_cpp_code_object(self, conversion_pack):
self._conversion_pack = conversion_pack
cfuncsig = self._ccode_object
# If we have a mapping already stored, just use that!
cppfuncsig = self._conversion_pack.conversion_data.cppfuncsig_for_cfuncsig(self._ccode_object)
if not cppfuncsig:
mapping = self._conversion_pack.conversion_data.funcsig_mapping_for_cfuncname(cfuncsig.name)
if mapping:
cppfuncsig = mapping.cppfuncsig
# Add any buffer mappings: {ptr, buffer} -> C++ Container
if mapping.arg_indexes:
cbuffer = cfuncsig.args[mapping.arg_indexes.cbuffer]
clength = cfuncsig.args[mapping.arg_indexes.clength]
cpp_container = cfuncsig.args[mapping.arg_indexes.cpp_container]
self._conversion_pack.conversion_data.add_funcsig_buffer_mapping(cbuffer, clength, cpp_container)
else:
cppfunc_arg = self.to_cpp_func_arg()
cpp_args = self.to_cpp_args()
cppfuncsig = funcsig.FuncSig(cppfunc_arg.decl_spec,
@ -29,11 +38,11 @@ class FuncSigConverter(code_interface_converter.CodeInterfaceConverter):
#cppfuncsig.static = self.is_cpp_static()
# Add this to the conversion data mappings
mapping = funcsig_mapping.FuncSigMapping(self._ccode_object, cppfuncsig)
mapping = funcsig_mapping.FuncSigMapping(cfuncsig, cppfuncsig)
self._conversion_pack.conversion_data.add_funcsig_mapping(mapping)
# Update the settings that we don't need (want?) to store in the map
cppfuncsig.is_declaration = self._ccode_object.is_declaration
cppfuncsig.is_declaration = cfuncsig.is_declaration
return cppfuncsig

View File

@ -28,6 +28,9 @@ class ValueDeclarationReferenceConverter(code_interface_converter.CodeInterfaceC
elif cpparg:
return value_declaration_reference.ValueDeclarationReference(cpparg.name)
# 3. Check if it is a mapped buffer (e.g. char *c, int* len => std::string& str)
# 4. Perform a default conversion
cppdecl_ref_expr_value = conversion_funcs.convert_ccode_object(cdecl_ref_expr_value, conversion_pack)
debug.line("create_cpp_code_object", f"ValueDeclarationReferenceConverter [4] cdecl_ref_expr_value=[{debug.as_debug_string(cdecl_ref_expr_value)}] cppdecl_ref_expr_value=[{debug.as_debug_string(cppdecl_ref_expr_value)}]")

View File

@ -92,7 +92,6 @@ class DefaultCCodeConverter:
def convert_functions(self):
for func in self._ccode.functions:
self._conversion_pack.conversion_data.reset_local_state()
cppfunc = self.to_cpp_function(func)
self._code_elements.add_function(cppfunc)
self.dump_function("convert_functions", cppfunc)