mirror of https://github.com/ecmwf/eccodes.git
Added funcsig buffer mappings
This commit is contained in:
parent
caaae6360d
commit
9030f1f4ba
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)}]")
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue