mirror of https://github.com/ecmwf/eccodes.git
templates converting correctly now
This commit is contained in:
parent
5316b0684b
commit
ea6fa100c6
|
@ -42,6 +42,11 @@ class FuncSig(code_interface.CodeInterface):
|
||||||
@property
|
@property
|
||||||
def template_type_params(self):
|
def template_type_params(self):
|
||||||
return self._template_type_params
|
return self._template_type_params
|
||||||
|
|
||||||
|
@template_type_params.setter
|
||||||
|
def template_type_params(self, new_template_type_params):
|
||||||
|
self._template_type_params = new_template_type_params
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_declaration(self):
|
def is_declaration(self):
|
||||||
|
|
|
@ -38,6 +38,10 @@ class Function(code_interface.CodeInterface):
|
||||||
def body(self, lines):
|
def body(self, lines):
|
||||||
self._body = lines
|
self._body = lines
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_template(self):
|
||||||
|
return len(self._funcsig.template_type_params) > 0
|
||||||
|
|
||||||
# The whole function will be returned: signature and body (in braces)
|
# The whole function will be returned: signature and body (in braces)
|
||||||
def as_lines(self):
|
def as_lines(self):
|
||||||
lines = [self.funcsig_as_definition]
|
lines = [self.funcsig_as_definition]
|
||||||
|
|
|
@ -2,6 +2,7 @@ import utils.debug as debug
|
||||||
import code_object.arg as arg
|
import code_object.arg as arg
|
||||||
import code_object.code_interface as code_interface
|
import code_object.code_interface as code_interface
|
||||||
import code_object.value_declaration_reference as value_declaration_reference
|
import code_object.value_declaration_reference as value_declaration_reference
|
||||||
|
import code_object_converter.conversion_pack.arg_utils as arg_utils
|
||||||
from utils.string_funcs import strip_semicolon
|
from utils.string_funcs import strip_semicolon
|
||||||
from code_object.code_interface import NONE_VALUE
|
from code_object.code_interface import NONE_VALUE
|
||||||
|
|
||||||
|
@ -30,5 +31,7 @@ class FunctionCall(code_interface.CodeInterface):
|
||||||
assert isinstance(arg_entry, code_interface.CodeInterface), f"arg_entry must be a CodeInterface class, supplied=[{arg_entry}]"
|
assert isinstance(arg_entry, code_interface.CodeInterface), f"arg_entry must be a CodeInterface class, supplied=[{arg_entry}]"
|
||||||
self._args.append(arg_entry)
|
self._args.append(arg_entry)
|
||||||
|
|
||||||
|
|
||||||
def as_lines(self):
|
def as_lines(self):
|
||||||
return [f"{self._name}({', '.join([strip_semicolon(a.as_string()) for a in self._args])});"]
|
return [f"{self._name}({', '.join([arg_utils.extract_function_call_name(a) for a in self._args])});"]
|
||||||
|
#return [f"{self._name}({', '.join([strip_semicolon(a.as_string()) for a in self._args])});"]
|
||||||
|
|
|
@ -21,8 +21,13 @@ class MemberFunction(function.Function):
|
||||||
# Overridden to add class_name::
|
# Overridden to add class_name::
|
||||||
@property
|
@property
|
||||||
def funcsig_as_definition(self):
|
def funcsig_as_definition(self):
|
||||||
funcsig_string = re.sub(r"^(.*\s)([^\(]*\()", rf"\1{self._class_name}::\2", self._funcsig.as_string())
|
lines = self.funcsig.as_lines()
|
||||||
return funcsig_string
|
if lines[0].startswith("template"):
|
||||||
|
lines[1] = re.sub(r"^(.*\s)([^\(]*\()", rf"\1{self._class_name}::\2", lines[1])
|
||||||
|
else:
|
||||||
|
lines[0] = re.sub(r"^(.*\s)([^\(]*\()", rf"\1{self._class_name}::\2", lines[0])
|
||||||
|
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_const(self):
|
def is_const(self):
|
||||||
|
|
|
@ -11,6 +11,7 @@ from code_object.value_declaration_reference import ValueDeclarationReference
|
||||||
from code_object.unary_operation import UnaryOperation
|
from code_object.unary_operation import UnaryOperation
|
||||||
from code_object.unary_expression import UnaryExpression
|
from code_object.unary_expression import UnaryExpression
|
||||||
from code_object.paren_expression import ParenExpression
|
from code_object.paren_expression import ParenExpression
|
||||||
|
from utils.string_funcs import strip_semicolon
|
||||||
|
|
||||||
# Try to extract a name value from the object, else return ""
|
# Try to extract a name value from the object, else return ""
|
||||||
def extract_name(cpp_obj):
|
def extract_name(cpp_obj):
|
||||||
|
@ -45,7 +46,12 @@ def extract_name(cpp_obj):
|
||||||
# expression will a paren_expression, so we need to recurse!
|
# expression will a paren_expression, so we need to recurse!
|
||||||
cppname = extract_name(cpp_obj.expression)
|
cppname = extract_name(cpp_obj.expression)
|
||||||
|
|
||||||
|
if not isinstance(cppname, str):
|
||||||
|
debug.line("extract_name", f"** Could not extract string name. cppname type=[{type(cppname)}] value=[{debug.as_debug_string(cppname)}]")
|
||||||
|
cppname = ""
|
||||||
|
|
||||||
debug.line("extract_name", f"[OUT] cpp_obj=[{debug.as_debug_string(cpp_obj)}] -> cppname=[{cppname}]")
|
debug.line("extract_name", f"[OUT] cpp_obj=[{debug.as_debug_string(cpp_obj)}] -> cppname=[{cppname}]")
|
||||||
|
|
||||||
return cppname
|
return cppname
|
||||||
|
|
||||||
# If the code_object has an Arg representation, then this will be returned,
|
# If the code_object has an Arg representation, then this will be returned,
|
||||||
|
@ -65,3 +71,38 @@ def to_cpparg(cpp_obj, conversion_data):
|
||||||
|
|
||||||
debug.line("to_cpparg", f"cpp_obj=[{debug.as_debug_string(cpp_obj)}] -> cpparg=[{debug.as_debug_string(cpparg)}]")
|
debug.line("to_cpparg", f"cpp_obj=[{debug.as_debug_string(cpp_obj)}] -> cpparg=[{debug.as_debug_string(cpparg)}]")
|
||||||
return cpparg
|
return cpparg
|
||||||
|
|
||||||
|
# Return the argument in a form that can be used in a function call
|
||||||
|
def extract_function_call_name(cpp_obj):
|
||||||
|
cppname = None
|
||||||
|
|
||||||
|
if isinstance(cpp_obj, Literal):
|
||||||
|
cppname = cpp_obj.value
|
||||||
|
elif isinstance(cpp_obj, Arg):
|
||||||
|
cppname = cpp_obj.name
|
||||||
|
elif isinstance(cpp_obj, StructArg):
|
||||||
|
cppname = cpp_obj.name
|
||||||
|
elif isinstance(cpp_obj, VariableDeclaration):
|
||||||
|
cppname = cpp_obj.variable
|
||||||
|
'''elif isinstance(cpp_obj, ArrayAccess):
|
||||||
|
cppname = cpp_obj.name
|
||||||
|
elif isinstance(cpp_obj, StructMemberAccess):
|
||||||
|
cppname = cpp_obj.name
|
||||||
|
elif isinstance(cpp_obj, ValueDeclarationReference):
|
||||||
|
cppname = cpp_obj.value
|
||||||
|
elif isinstance(cpp_obj, UnaryOperation):
|
||||||
|
# Operand will a CodeInterface, so we need to recurse!
|
||||||
|
cppname = self.function_call_name(cpp_obj.operand)
|
||||||
|
elif isinstance(cpp_obj, UnaryExpression):
|
||||||
|
# expression will a CodeInterface, so we need to recurse!
|
||||||
|
cppname = self.function_call_name(cpp_obj.expression)
|
||||||
|
elif isinstance(cpp_obj, ParenExpression):
|
||||||
|
# expression will a paren_expression, so we need to recurse!
|
||||||
|
cppname = self.function_call_name(cpp_obj.expression)'''
|
||||||
|
|
||||||
|
if not cppname:
|
||||||
|
cppname = strip_semicolon(cpp_obj.as_string())
|
||||||
|
|
||||||
|
debug.line("function_call_name", f"Converted cpp_obj: [{debug.as_debug_string(cpp_obj)}] -> [{cppname}] cpp_ob type=[{type(cpp_obj)}]")
|
||||||
|
|
||||||
|
return cppname
|
||||||
|
|
|
@ -62,13 +62,13 @@ class ConversionData:
|
||||||
|
|
||||||
# ------------------------------ SET ------------------------------
|
# ------------------------------ SET ------------------------------
|
||||||
|
|
||||||
def add_funcsig_mapping(self, mapping):
|
def add_global_funcsig_mapping(self, mapping):
|
||||||
assert isinstance(mapping, funcsig_mapping.FuncSigMapping), f"Expected FuncSigMapping, got type=[{type(mapping).__name__}]"
|
assert isinstance(mapping, funcsig_mapping.FuncSigMapping), f"Expected FuncSigMapping, got type=[{type(mapping).__name__}]"
|
||||||
for entry in self.active_map.funcsig_mappings:
|
for entry in self._global_mappings.funcsig_mappings:
|
||||||
if entry.cfuncsig.name == mapping.cfuncsig.name:
|
if entry.cfuncsig.name == mapping.cfuncsig.name:
|
||||||
assert False, f"Mapping for [{mapping.cfuncsig.name}] already exists!"
|
assert False, f"Mapping for [{mapping.cfuncsig.name}] already exists!"
|
||||||
|
|
||||||
self.active_map.funcsig_mappings.append(mapping)
|
self._global_mappings.funcsig_mappings.append(mapping)
|
||||||
|
|
||||||
# These need to be global as all functions may access them...
|
# These need to be global as all functions may access them...
|
||||||
def add_global_member_funcsig_mapping(self, mapping):
|
def add_global_member_funcsig_mapping(self, mapping):
|
||||||
|
@ -135,6 +135,14 @@ class ConversionData:
|
||||||
for entry in mapping.all_funcsig_mappings:
|
for entry in mapping.all_funcsig_mappings:
|
||||||
if entry.cfuncsig.name == cfuncname and entry.cppfuncsig:
|
if entry.cfuncsig.name == cfuncname and entry.cppfuncsig:
|
||||||
return entry
|
return entry
|
||||||
|
|
||||||
|
# is this a template?
|
||||||
|
if "<" in cfuncname:
|
||||||
|
template_index = cfuncname.index("<")
|
||||||
|
non_template_name = cfuncname[:template_index]
|
||||||
|
debug.line("funcsig_mapping_for_cfuncname", f"cfuncname=[{cfuncname}] is a template, checking non_template_name=[{non_template_name}]")
|
||||||
|
return self.funcsig_mapping_for_cfuncname(non_template_name)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def funcsig_mapping_for_current_cfuncname(self):
|
def funcsig_mapping_for_current_cfuncname(self):
|
||||||
|
@ -460,6 +468,10 @@ class ConversionData:
|
||||||
if entry.cppfuncsig and entry.cppfuncsig != NONE_VALUE and entry.cppfuncsig.name == function_name:
|
if entry.cppfuncsig and entry.cppfuncsig != NONE_VALUE and entry.cppfuncsig.name == function_name:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
return self.is_virtual_member_function(function_name)
|
||||||
|
|
||||||
|
def is_virtual_member_function(self, function_name):
|
||||||
|
|
||||||
for entry in self._global_mappings.virtual_member_funcsig_mappings:
|
for entry in self._global_mappings.virtual_member_funcsig_mappings:
|
||||||
if entry.cfuncsig.name == function_name:
|
if entry.cfuncsig.name == function_name:
|
||||||
return True
|
return True
|
||||||
|
@ -468,6 +480,7 @@ class ConversionData:
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def is_self_class_pointer_name(self, name):
|
def is_self_class_pointer_name(self, name):
|
||||||
debug.line("is_self_class_pointer_name", f"Testing name=[{debug.as_debug_string(name)}]")
|
debug.line("is_self_class_pointer_name", f"Testing name=[{debug.as_debug_string(name)}]")
|
||||||
for mapping in self.all_mappings():
|
for mapping in self.all_mappings():
|
||||||
|
|
|
@ -26,6 +26,8 @@ class FuncSigConverter(code_interface_converter.CodeInterfaceConverter):
|
||||||
debug.line("", f"cppfuncsig is NONE_VALUE for cfuncsig.name=[{cfuncsig.name}] so won't be converted")
|
debug.line("", f"cppfuncsig is NONE_VALUE for cfuncsig.name=[{cfuncsig.name}] so won't be converted")
|
||||||
return NONE_VALUE
|
return NONE_VALUE
|
||||||
|
|
||||||
|
cppfuncsig.template_type_params = cfuncsig.template_type_params
|
||||||
|
|
||||||
# Add any buffer mappings: {ptr, buffer} -> C++ Container
|
# Add any buffer mappings: {ptr, buffer} -> C++ Container
|
||||||
if mapping.arg_indexes:
|
if mapping.arg_indexes:
|
||||||
cbuffer = cfuncsig.args[mapping.arg_indexes.cbuffer]
|
cbuffer = cfuncsig.args[mapping.arg_indexes.cbuffer]
|
||||||
|
@ -38,23 +40,20 @@ class FuncSigConverter(code_interface_converter.CodeInterfaceConverter):
|
||||||
cppfuncsig = funcsig.FuncSig(cppfunc_arg.decl_spec,
|
cppfuncsig = funcsig.FuncSig(cppfunc_arg.decl_spec,
|
||||||
cppfunc_arg.name,
|
cppfunc_arg.name,
|
||||||
cpp_args,
|
cpp_args,
|
||||||
self._ccode_object.template_type_params)
|
cfuncsig.template_type_params)
|
||||||
|
|
||||||
#cppfuncsig.static = self.is_cpp_static()
|
#cppfuncsig.static = self.is_cpp_static()
|
||||||
|
|
||||||
# Add this to the correct conversion data mappings
|
# Add this to the correct conversion data mappings
|
||||||
mapping = funcsig_mapping.FuncSigMapping(cfuncsig, cppfuncsig)
|
mapping = funcsig_mapping.FuncSigMapping(cfuncsig, cppfuncsig)
|
||||||
|
|
||||||
# Debug info...
|
|
||||||
is_mem_func = conversion_pack.conversion_data.is_member_function(cfuncsig.name)
|
is_mem_func = conversion_pack.conversion_data.is_member_function(cfuncsig.name)
|
||||||
debug.line("create_cpp_code_object", f"Member function test for [{cfuncsig.name}] is_member_function=[{is_mem_func}]")
|
|
||||||
if is_mem_func:
|
if is_mem_func:
|
||||||
stored_cppfuncsig = conversion_pack.conversion_data.cppfuncsig_for_cfuncname(cfuncsig.name)
|
stored_cppfuncsig = conversion_pack.conversion_data.cppfuncsig_for_cfuncname(cfuncsig.name)
|
||||||
if not stored_cppfuncsig:
|
if not stored_cppfuncsig:
|
||||||
debug.line("create_cpp_code_object", f" -> stored_cppfuncsig=[{debug.as_debug_string(stored_cppfuncsig)}], updating member function mapping...")
|
|
||||||
conversion_pack.conversion_data.add_global_member_funcsig_mapping(mapping)
|
conversion_pack.conversion_data.add_global_member_funcsig_mapping(mapping)
|
||||||
else:
|
else:
|
||||||
conversion_pack.conversion_data.add_funcsig_mapping(mapping)
|
conversion_pack.conversion_data.add_global_funcsig_mapping(mapping)
|
||||||
|
|
||||||
# Add all the arg mappings for the rest of the function to use
|
# Add all the arg mappings for the rest of the function to use
|
||||||
# NOTE: We use cfuncsig rather than mapping.cfuncsig as the former may not have variable names included which will
|
# NOTE: We use cfuncsig rather than mapping.cfuncsig as the former may not have variable names included which will
|
||||||
|
|
|
@ -5,6 +5,7 @@ import code_object_converter.code_interface_converter as code_interface_converte
|
||||||
import code_object_converter.conversion_funcs as conversion_funcs
|
import code_object_converter.conversion_funcs as conversion_funcs
|
||||||
import code_object.arg as arg
|
import code_object.arg as arg
|
||||||
from code_object.code_interface import NONE_VALUE
|
from code_object.code_interface import NONE_VALUE
|
||||||
|
import code_object_converter.conversion_pack.arg_utils as arg_utils
|
||||||
|
|
||||||
class FunctionCallConverter(code_interface_converter.CodeInterfaceConverter):
|
class FunctionCallConverter(code_interface_converter.CodeInterfaceConverter):
|
||||||
def __init__(self, ccode_object) -> None:
|
def __init__(self, ccode_object) -> None:
|
||||||
|
@ -30,9 +31,20 @@ class FunctionCallConverter(code_interface_converter.CodeInterfaceConverter):
|
||||||
if arg_entry != NONE_VALUE:
|
if arg_entry != NONE_VALUE:
|
||||||
cpp_arg_entry = conversion_funcs.convert_ccode_object(cfunction_call.args[i], conversion_pack)
|
cpp_arg_entry = conversion_funcs.convert_ccode_object(cfunction_call.args[i], conversion_pack)
|
||||||
assert cpp_arg_entry != NONE_VALUE, f"Expected cpp_arg_entry for carg=[{debug.as_debug_string(cfunction_call.args[i])}], got NoneValue!"
|
assert cpp_arg_entry != NONE_VALUE, f"Expected cpp_arg_entry for carg=[{debug.as_debug_string(cfunction_call.args[i])}], got NoneValue!"
|
||||||
|
|
||||||
|
# Check if we have a container arg
|
||||||
|
cpp_arg_name = arg_utils.extract_name(cpp_arg_entry)
|
||||||
|
if cpp_arg_name:
|
||||||
|
cpp_container_arg = conversion_pack.container_utils.cname_to_cpp_container(cpp_arg_name, conversion_pack.conversion_data)
|
||||||
|
if cpp_container_arg:
|
||||||
|
cpp_arg_entry = cpp_container_arg
|
||||||
|
|
||||||
cpp_args.append(cpp_arg_entry)
|
cpp_args.append(cpp_arg_entry)
|
||||||
|
|
||||||
cppfunction_call = function_call.FunctionCall(mapping.cppfuncsig.name, cpp_args)
|
cppfunction_call = function_call.FunctionCall(mapping.cppfuncsig.name, cpp_args)
|
||||||
|
|
||||||
|
debug.line("create_cpp_code_object", f"cppfunction_call NOW EQUALS [{debug.as_debug_string(cppfunction_call)}]")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
debug.line("create_cpp_code_object", f"FunctionCallConverter [2]")
|
debug.line("create_cpp_code_object", f"FunctionCallConverter [2]")
|
||||||
# 2. Perform a manual conversion
|
# 2. Perform a manual conversion
|
||||||
|
|
|
@ -16,9 +16,13 @@ class GlobalFunctionConverter(function_converter.FunctionConverter):
|
||||||
cpp_body = code_objects.CodeObjects()
|
cpp_body = code_objects.CodeObjects()
|
||||||
|
|
||||||
for entry in self._ccode_object.body.code_objects:
|
for entry in self._ccode_object.body.code_objects:
|
||||||
if isinstance(entry, funcsig.FuncSig) and self._conversion_pack.conversion_data.is_member_function(entry.name):
|
if isinstance(entry, funcsig.FuncSig):
|
||||||
debug.line("create_cpp_code_object", f"Ignoring member function name=[{entry.name}]")
|
if self._conversion_pack.conversion_data.is_member_function(entry.name):
|
||||||
continue
|
debug.line("create_cpp_code_object", f"Ignoring member function name=[{entry.name}]")
|
||||||
|
continue
|
||||||
|
if self._conversion_pack.conversion_data.is_virtual_member_function(entry.name):
|
||||||
|
debug.line("create_cpp_code_object", f"Ignoring virtual member function name=[{entry.name}]")
|
||||||
|
continue
|
||||||
|
|
||||||
cpp_code_obj = conversion_funcs.convert_ccode_object(entry, self._conversion_pack)
|
cpp_code_obj = conversion_funcs.convert_ccode_object(entry, self._conversion_pack)
|
||||||
cpp_body.add_code_object(cpp_code_obj)
|
cpp_body.add_code_object(cpp_code_obj)
|
||||||
|
|
|
@ -59,6 +59,19 @@ class CppCode:
|
||||||
def global_function(self):
|
def global_function(self):
|
||||||
return self._code_elements.global_function
|
return self._code_elements.global_function
|
||||||
|
|
||||||
|
# Returns all functions, in dependency order (as best as possible)
|
||||||
|
# Templates are returned ahead of others in each set
|
||||||
|
@property
|
||||||
|
def all_functions(self):
|
||||||
|
|
||||||
|
sorted_functions = sorted(self.functions, key=lambda instance: instance.is_template, reverse=True)
|
||||||
|
sorted_member_functions = sorted(self.member_functions, key=lambda instance: instance.is_template, reverse=True)
|
||||||
|
sorted_virtual_member_functions = sorted(self.virtual_member_functions, key=lambda instance: instance.is_template, reverse=True)
|
||||||
|
sorted_constructor = [self.constructor] if self.constructor else []
|
||||||
|
sorted_destructor = [self.destructor] if self.destructor else []
|
||||||
|
|
||||||
|
return sorted_functions + sorted_member_functions + sorted_constructor + sorted_virtual_member_functions + sorted_destructor
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def functions(self):
|
def functions(self):
|
||||||
return self._code_elements.functions
|
return self._code_elements.functions
|
||||||
|
|
|
@ -113,7 +113,7 @@ class DefaultCCodeConverter:
|
||||||
self._code_elements.add_data_member(cppmember)
|
self._code_elements.add_data_member(cppmember)
|
||||||
|
|
||||||
# Override to return True if the member function should be marked const
|
# Override to return True if the member function should be marked const
|
||||||
def is_const_member_function(self, function_name):
|
def is_const_member_function(self, function_name, conv_pack):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Helper to ensure the function is converted correctly, including resetting the local conversion data!
|
# Helper to ensure the function is converted correctly, including resetting the local conversion data!
|
||||||
|
@ -126,7 +126,7 @@ class DefaultCCodeConverter:
|
||||||
cpp_func = conversion_funcs.convert_ccode_object(func, conv_pack)
|
cpp_func = conversion_funcs.convert_ccode_object(func, conv_pack)
|
||||||
if isinstance(cpp_func, member_function.MemberFunction):
|
if isinstance(cpp_func, member_function.MemberFunction):
|
||||||
cpp_func.class_name = conv_pack.conversion_data.info.class_name
|
cpp_func.class_name = conv_pack.conversion_data.info.class_name
|
||||||
cpp_func.set_is_const(self.is_const_member_function(func.funcsig.name))
|
cpp_func.set_is_const(self.is_const_member_function(func.funcsig.name, conv_pack))
|
||||||
|
|
||||||
return cpp_func
|
return cpp_func
|
||||||
|
|
||||||
|
|
|
@ -18,30 +18,8 @@ namespace {{ c.nested_namespaces }} {
|
||||||
{{ c.global_function.as_string() }}
|
{{ c.global_function.as_string() }}
|
||||||
// Globals - END
|
// Globals - END
|
||||||
|
|
||||||
{% for func in c.functions %}
|
{% for func in c.all_functions %}
|
||||||
{{ func.as_string() }}
|
{{ func.as_string() }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% if c.class_name %}
|
|
||||||
|
|
||||||
{{ c.constructor.as_string() }}
|
|
||||||
|
|
||||||
{% if c.destructor %}
|
|
||||||
{{ c.destructor.as_string() }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% for func in c.template_member_functions %}
|
|
||||||
{{ func.as_string() }}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% for func in c.virtual_member_functions %}
|
|
||||||
{{ func.as_string() }}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% for func in c.member_functions %}
|
|
||||||
{{ func.as_string() }}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
} // namespace {{ c.nested_namespaces }}
|
} // namespace {{ c.nested_namespaces }}
|
||||||
|
|
|
@ -33,6 +33,26 @@ rename = {
|
||||||
class GribAccessorCCodeConverter(default_ccode_converter.DefaultCCodeConverter):
|
class GribAccessorCCodeConverter(default_ccode_converter.DefaultCCodeConverter):
|
||||||
def __init__(self, ccode_instance) -> None:
|
def __init__(self, ccode_instance) -> None:
|
||||||
super().__init__(ccode_instance)
|
super().__init__(ccode_instance)
|
||||||
|
self.load_conversion_pack_updates_class()
|
||||||
|
|
||||||
|
# See if we have a function-specific updater, otherwise use the main-one
|
||||||
|
def load_conversion_pack_updates_class(self):
|
||||||
|
conversion_pack_updates_path="grib_accessor.grib_accessor_conversion_pack.conversion_pack_updates"
|
||||||
|
cclass_short_name = self._ccode.class_name.replace(prefix, "")
|
||||||
|
accessor_conversion_pack_updates_mod_name = f"{cclass_short_name}_conversion_pack_updates"
|
||||||
|
accessor_conversion_pack_updates_lib_name = f"{conversion_pack_updates_path}.{accessor_conversion_pack_updates_mod_name}"
|
||||||
|
|
||||||
|
try:
|
||||||
|
accessor_conversion_pack_updates_lib = importlib.import_module(accessor_conversion_pack_updates_lib_name)
|
||||||
|
debug.line("function_specific_conversion_pack_updates", f"Loaded accessor_conversion_pack_updates_lib_name=[{accessor_conversion_pack_updates_lib_name}]")
|
||||||
|
accessor_conversion_pack_updates_class_name = standard_transforms.transform_type_name(accessor_conversion_pack_updates_mod_name)
|
||||||
|
accessor_conversion_pack_updates_class = getattr(accessor_conversion_pack_updates_lib, accessor_conversion_pack_updates_class_name)
|
||||||
|
debug.line("function_specific_conversion_pack_updates", f"Loaded accessor_conversion_pack_updates_class_name=[{accessor_conversion_pack_updates_class_name}]")
|
||||||
|
self._conversion_pack_updates = accessor_conversion_pack_updates_class()
|
||||||
|
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
debug.line("function_specific_conversion_pack_updates", f"Could not find accessor_conversion_pack_updates_lib_name=[{accessor_conversion_pack_updates_lib_name}], using base version")
|
||||||
|
self._conversion_pack_updates = base_conversion_pack_updates.BaseConversionPackUpdates()
|
||||||
|
|
||||||
# Convert e.g. grib_accessor_class_proj_string.cc to ProjStringData.cc
|
# Convert e.g. grib_accessor_class_proj_string.cc to ProjStringData.cc
|
||||||
def transform_file_name(self, name):
|
def transform_file_name(self, name):
|
||||||
|
@ -59,27 +79,7 @@ class GribAccessorCCodeConverter(default_ccode_converter.DefaultCCodeConverter):
|
||||||
return info
|
return info
|
||||||
|
|
||||||
def function_specific_conversion_pack_updates(self, cfunction_name, conv_pack):
|
def function_specific_conversion_pack_updates(self, cfunction_name, conv_pack):
|
||||||
# See if we have a function-specific validator,
|
self._conversion_pack_updates.apply_updates_for_cfunction(cfunction_name, conv_pack)
|
||||||
# Otherwise use the main-one
|
|
||||||
conversion_pack_updates_path="grib_accessor.grib_accessor_conversion_pack.conversion_pack_updates"
|
|
||||||
cclass_short_name = self._ccode.class_name.replace(prefix, "")
|
|
||||||
accessor_conversion_pack_updates_mod_name = f"{cclass_short_name}_conversion_pack_updates"
|
|
||||||
accessor_conversion_pack_updates_lib_name = f"{conversion_pack_updates_path}.{accessor_conversion_pack_updates_mod_name}"
|
|
||||||
|
|
||||||
try:
|
|
||||||
accessor_conversion_pack_updates_lib = importlib.import_module(accessor_conversion_pack_updates_lib_name)
|
|
||||||
debug.line("function_specific_conversion_pack_updates", f"Loaded accessor_conversion_pack_updates_lib_name=[{accessor_conversion_pack_updates_lib_name}]")
|
|
||||||
accessor_conversion_pack_updates_class_name = standard_transforms.transform_type_name(accessor_conversion_pack_updates_mod_name)
|
|
||||||
accessor_conversion_pack_updates_class = getattr(accessor_conversion_pack_updates_lib, accessor_conversion_pack_updates_class_name)
|
|
||||||
debug.line("function_specific_conversion_pack_updates", f"Loaded accessor_conversion_pack_updates_class_name=[{accessor_conversion_pack_updates_class_name}]")
|
|
||||||
updates_class_inst = accessor_conversion_pack_updates_class()
|
|
||||||
|
|
||||||
except ModuleNotFoundError:
|
|
||||||
debug.line("function_specific_conversion_pack_updates", f"Could not find accessor_conversion_pack_updates_lib_name=[{accessor_conversion_pack_updates_lib_name}], using base version")
|
|
||||||
updates_class_inst = base_conversion_pack_updates.BaseConversionPackUpdates()
|
|
||||||
|
|
||||||
updates_class_inst.apply_updates_for_cfunction(cfunction_name, conv_pack)
|
|
||||||
|
|
||||||
super().function_specific_conversion_pack_updates(cfunction_name, conv_pack)
|
super().function_specific_conversion_pack_updates(cfunction_name, conv_pack)
|
||||||
|
|
||||||
# See if we have an Accessor-specific validator (e.g. ProjStringValidation),
|
# See if we have an Accessor-specific validator (e.g. ProjStringValidation),
|
||||||
|
@ -121,6 +121,8 @@ class GribAccessorCCodeConverter(default_ccode_converter.DefaultCCodeConverter):
|
||||||
for mapping in grib_accessor_virtual_member_funcsig_mapping:
|
for mapping in grib_accessor_virtual_member_funcsig_mapping:
|
||||||
conv_data.add_global_virtual_member_funcsig_mapping(mapping)
|
conv_data.add_global_virtual_member_funcsig_mapping(mapping)
|
||||||
|
|
||||||
|
self._conversion_pack_updates.add_funcsig_mappings_to_conversion_data(conv_data)
|
||||||
|
|
||||||
all_funcsig_mappings.add_all_funcsig_mappings_to_conversion_data(conv_data)
|
all_funcsig_mappings.add_all_funcsig_mappings_to_conversion_data(conv_data)
|
||||||
|
|
||||||
arg_mappings.add_arg_mappings_to_conversion_data(conv_data)
|
arg_mappings.add_arg_mappings_to_conversion_data(conv_data)
|
||||||
|
@ -161,8 +163,18 @@ class GribAccessorCCodeConverter(default_ccode_converter.DefaultCCodeConverter):
|
||||||
|
|
||||||
return super().add_includes(conv_pack)
|
return super().add_includes(conv_pack)
|
||||||
|
|
||||||
def is_const_member_function(self, function_name):
|
def is_const_member_function(self, function_name, conv_pack):
|
||||||
return function_name in virtual_member_functions.const_virtual_member_function_names
|
|
||||||
|
if function_name in ["init", "destroy"]:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if conv_pack.conversion_data.is_virtual_member_function(function_name):
|
||||||
|
return function_name in virtual_member_functions.const_virtual_member_function_names
|
||||||
|
|
||||||
|
if conv_pack.conversion_data.is_member_function(function_name):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def post_process_function_calls(self):
|
def post_process_function_calls(self):
|
||||||
debug.line("post_process_function_calls", f"Function calls summary:")
|
debug.line("post_process_function_calls", f"Function calls summary:")
|
||||||
|
|
|
@ -7,6 +7,12 @@ from code_object.code_interface import NONE_VALUE
|
||||||
class BaseConversionPackUpdates:
|
class BaseConversionPackUpdates:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self._update_funcs = {}
|
self._update_funcs = {}
|
||||||
|
self._funcsig_mappings = []
|
||||||
|
|
||||||
|
def add_funcsig_mappings_to_conversion_data(self, conversion_data):
|
||||||
|
for mapping in self._funcsig_mappings:
|
||||||
|
debug.line("add_funcsig_mappings_to_conversion_data", f"Adding funcsig mapping: [{mapping.cfuncsig.name}] -> [{mapping.cppfuncsig.name}]")
|
||||||
|
conversion_data.add_global_funcsig_mapping(mapping)
|
||||||
|
|
||||||
# Use this entry point to call the appropriate derived function
|
# Use this entry point to call the appropriate derived function
|
||||||
def apply_updates_for_cfunction(self, cfuncname, conversion_pack):
|
def apply_updates_for_cfunction(self, cfuncname, conversion_pack):
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
import utils.debug as debug
|
import utils.debug as debug
|
||||||
import grib_accessor.grib_accessor_conversion_pack.conversion_pack_updates.base_conversion_pack_updates as base_conversion_pack_updates
|
import grib_accessor.grib_accessor_conversion_pack.conversion_pack_updates.base_conversion_pack_updates as base_conversion_pack_updates
|
||||||
from code_object.arg import Arg
|
from code_object.arg import Arg
|
||||||
|
from code_object_converter.conversion_pack.funcsig_mapping import FuncSigMapping
|
||||||
|
from code_object_converter.conversion_pack.arg_indexes import ArgIndexes
|
||||||
|
from code_object.funcsig import FuncSig
|
||||||
|
from code_object.code_interface import NONE_VALUE
|
||||||
|
|
||||||
class BitConversionPackUpdates(base_conversion_pack_updates.BaseConversionPackUpdates):
|
class BitConversionPackUpdates(base_conversion_pack_updates.BaseConversionPackUpdates):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
import utils.debug as debug
|
||||||
|
import grib_accessor.grib_accessor_conversion_pack.conversion_pack_updates.base_conversion_pack_updates as base_conversion_pack_updates
|
||||||
|
from code_object.arg import Arg
|
||||||
|
from code_object_converter.conversion_pack.funcsig_mapping import FuncSigMapping
|
||||||
|
from code_object_converter.conversion_pack.arg_indexes import ArgIndexes
|
||||||
|
from code_object.funcsig import FuncSig
|
||||||
|
from code_object.code_interface import NONE_VALUE
|
||||||
|
|
||||||
|
class BitmapConversionPackUpdates(base_conversion_pack_updates.BaseConversionPackUpdates):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self._funcsig_mappings.extend([
|
||||||
|
# template<typename T> static int unpack_helper(grib_accessor* a, T* val, size_t* len)
|
||||||
|
FuncSigMapping(FuncSig("int", "unpack_helper", [Arg("grib_accessor*", "a"), Arg("T*", "val"), Arg("size_t*", "len")]),
|
||||||
|
FuncSig("GribStatus", "unpackHelper", [NONE_VALUE, Arg("std::vector<T>&", "vecTValues"), NONE_VALUE]),
|
||||||
|
ArgIndexes(cbuffer=1, clength=2, cpp_container=1)),
|
||||||
|
])
|
|
@ -94,7 +94,7 @@ class GribAccessorConversionValidation(default_conversion_validation.DefaultConv
|
||||||
def validate_function_call_arg(self, calling_arg_value, target_arg):
|
def validate_function_call_arg(self, calling_arg_value, target_arg):
|
||||||
|
|
||||||
if "AccessorName" in target_arg.decl_spec.type:
|
if "AccessorName" in target_arg.decl_spec.type:
|
||||||
return literal.Literal(f"AccessorName({calling_arg_value.as_string()})")
|
return literal.Literal(f"AccessorName({arg_utils.extract_function_call_name(calling_arg_value)})")
|
||||||
|
|
||||||
return super().validate_function_call_arg(calling_arg_value, target_arg)
|
return super().validate_function_call_arg(calling_arg_value, target_arg)
|
||||||
|
|
||||||
|
@ -110,11 +110,11 @@ class GribAccessorConversionValidation(default_conversion_validation.DefaultConv
|
||||||
arg_entry = literal.Literal(f"initData.args[{arg_string}].second")
|
arg_entry = literal.Literal(f"initData.args[{arg_string}].second")
|
||||||
return function_call.FunctionCall(f"std::get<long>", [arg_entry])
|
return function_call.FunctionCall(f"std::get<long>", [arg_entry])
|
||||||
|
|
||||||
# If we're calling grib_XXX which is a member function, and the first argument is "a", then we're actually calling ourself!
|
# If we're calling grib_XXX which is a virtual member function, and the first argument is "a", then we're actually calling ourself!
|
||||||
if cfunction_call.name.startswith("grib_"):
|
if cfunction_call.name.startswith("grib_"):
|
||||||
updated_cfuncname = cfunction_call.name[5:]
|
updated_cfuncname = cfunction_call.name[5:]
|
||||||
if self._conversion_data.is_member_function(updated_cfuncname) and \
|
if self._conversion_data.is_virtual_member_function(updated_cfuncname) and \
|
||||||
len(cppfunction_call.args) > 0 and cppfunction_call.args[0].as_string() == "a":
|
len(cfunction_call.args) > 0 and cfunction_call.args[0].as_string() == "a":
|
||||||
mapping = self._conversion_data.funcsig_mapping_for_cfuncname(updated_cfuncname)
|
mapping = self._conversion_data.funcsig_mapping_for_cfuncname(updated_cfuncname)
|
||||||
if mapping:
|
if mapping:
|
||||||
updated_cppfunction_call = function_call.FunctionCall(mapping.cppfuncsig.name, cppfunction_call.args[1:])
|
updated_cppfunction_call = function_call.FunctionCall(mapping.cppfuncsig.name, cppfunction_call.args[1:])
|
||||||
|
|
|
@ -18,23 +18,7 @@ namespace {{ c.nested_namespaces }} {
|
||||||
{{ c.global_function.as_string() }}
|
{{ c.global_function.as_string() }}
|
||||||
// Globals - END
|
// Globals - END
|
||||||
|
|
||||||
{% for func in c.functions %}
|
{% for func in c.all_functions %}
|
||||||
{{ func.as_string() }}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if c.constructor %}
|
|
||||||
{{ c.constructor.as_string() }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if c.destructor %}
|
|
||||||
{{ c.destructor.as_string() }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% for func in c.virtual_member_functions %}
|
|
||||||
{{ func.as_string() }}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% for func in c.member_functions %}
|
|
||||||
{{ func.as_string() }}
|
{{ func.as_string() }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
|
@ -12,4 +12,4 @@ def add_all_funcsig_mappings_to_conversion_data(conversion_data):
|
||||||
for mapping in all_funcsig_mappings():
|
for mapping in all_funcsig_mappings():
|
||||||
for entry in mapping:
|
for entry in mapping:
|
||||||
debug.line("add_all_funcsig_mappings_to_conversion_data", f"ADDING FUNCIG MAPPING: [{entry.cfuncsig.name}] -> [{entry.cppfuncsig.name}]")
|
debug.line("add_all_funcsig_mappings_to_conversion_data", f"ADDING FUNCIG MAPPING: [{entry.cfuncsig.name}] -> [{entry.cppfuncsig.name}]")
|
||||||
conversion_data.add_funcsig_mapping(entry)
|
conversion_data.add_global_funcsig_mapping(entry)
|
Loading…
Reference in New Issue