mirror of https://github.com/ecmwf/eccodes.git
Added additional C to C++ conversions
This commit is contained in:
parent
61ad744fcf
commit
a4af69f1b5
|
@ -459,22 +459,18 @@ class AstParser:
|
|||
def parse_DECL_REF_EXPR(self, node):
|
||||
return value_declaration_reference.ValueDeclarationReference(node.spelling)
|
||||
|
||||
# This is simplified for now, need to come back to...
|
||||
# The top-level node contains the tokens showing the access, e.g. [['self', '->', 'grid_type']]
|
||||
# The child node defines the first parameter ("self" in this case)
|
||||
# However, as we're just storing strings, we'll use the tokens directly!
|
||||
def parse_MEMBER_REF_EXPR(self, node):
|
||||
member_name = node.spelling
|
||||
cstruct_member_access = struct_member_access.StructMemberAccess(None, member_name, None)
|
||||
tokens = [token.spelling for token in node.get_tokens()]
|
||||
debug.line("parse_MEMBER_REF_EXPR", f"[IN] node spelling=[{node.spelling}] type=[{node.type.spelling}] tokens=[{tokens}]")
|
||||
assert len(tokens) == 3, f"Expected exactly 3 tokens for member ref, but got [{len(tokens)}]"
|
||||
|
||||
for child in node.get_children():
|
||||
if child.kind == clang.cindex.CursorKind.UNEXPOSED_EXPR:
|
||||
parent_name = child.spelling
|
||||
cparent_struct_member_access = struct_member_access.StructMemberAccess(None, parent_name, None)
|
||||
cstruct_member_access.access = "->"
|
||||
cparent_struct_member_access.member = cstruct_member_access
|
||||
return cparent_struct_member_access
|
||||
|
||||
debug.line("parse_MEMBER_REF_EXPR", f"*** IGNORING *** child spelling=[{child.spelling}] type=[{child.type.spelling}] kind=[{child.kind}]")
|
||||
cstruct_member_access = struct_member_access.StructMemberAccess(None, tokens[0], None)
|
||||
cstruct_member_access.member = struct_member_access.StructMemberAccess(tokens[1], tokens[2], None)
|
||||
|
||||
return None
|
||||
return cstruct_member_access
|
||||
|
||||
def parse_CALL_EXPR(self, node):
|
||||
tokens = [token.spelling for token in node.get_tokens()]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import utils.debug as debug
|
||||
import code_object.code_interface as code_interface
|
||||
import code_object.operation as operation
|
||||
from utils.string_funcs import strip_semicolon
|
||||
|
||||
# Represent a binary operation of the form LEFT_OPERAND OP RIGHT_OPERAND
|
||||
# Models the BINARY_OPERATOR CursorKind in libclang
|
||||
|
@ -39,6 +40,8 @@ class BinaryOperation(code_interface.CodeInterface):
|
|||
def as_lines(self):
|
||||
lines = []
|
||||
lines.extend(self._left_operand.as_lines())
|
||||
lines[-1] = strip_semicolon(lines[-1])
|
||||
|
||||
lines[-1] += " " + self._binary_op.as_string()
|
||||
|
||||
right_lines = []
|
||||
|
|
|
@ -20,6 +20,10 @@ class ConversionValidation:
|
|||
|
||||
def validate_binary_operation(self, cbinary_operation, cppbinary_operation):
|
||||
return cppbinary_operation
|
||||
|
||||
def validate_if_statement(self, cif_statement, cppif_statement):
|
||||
return cppif_statement
|
||||
|
||||
# ---------- CodeObject Validation : End -----------------------------------------------------
|
||||
|
||||
|
||||
|
|
|
@ -13,4 +13,6 @@ class IfStatementConverter(code_interface_converter.CodeInterfaceConverter):
|
|||
cpp_expression = conversion_funcs.convert_ccode_object(self._ccode_object.expression, conversion_pack)
|
||||
cpp_action = conversion_funcs.convert_ccode_object(self._ccode_object.action, conversion_pack)
|
||||
|
||||
return if_statement.IfStatement(cpp_expression, cpp_action)
|
||||
cpp_if = if_statement.IfStatement(cpp_expression, cpp_action)
|
||||
|
||||
return conversion_pack.conversion_validation.validate_if_statement(self._ccode_object, cpp_if)
|
||||
|
|
|
@ -6,12 +6,13 @@ from code_object.code_interface import NONE_VALUE
|
|||
import code_object.function_call as function_call
|
||||
import code_object.literal as literal
|
||||
import re
|
||||
import code_object.binary_operation as binary_operation
|
||||
|
||||
# Pass this to the conversion_data object to be accessed by the conversion routines
|
||||
class DefaultConversionValidation(conversion_validation.ConversionValidation):
|
||||
|
||||
def validate_function_call(self, cfunction_call, cppfunction_call, callee_funcsig_mapping):
|
||||
if callee_funcsig_mapping:
|
||||
if callee_funcsig_mapping:
|
||||
cpp_args = []
|
||||
for arg_entry in callee_funcsig_mapping.cppfuncsig.args:
|
||||
if arg_entry != NONE_VALUE:
|
||||
|
@ -20,7 +21,10 @@ class DefaultConversionValidation(conversion_validation.ConversionValidation):
|
|||
cpp_args.append(cpp_arg_entry)
|
||||
return function_call.FunctionCall(cppfunction_call.name, cpp_args)
|
||||
|
||||
return cppfunction_call
|
||||
if cfunction_call.name == "strcmp":
|
||||
return binary_operation.BinaryOperation(cppfunction_call.args[0], "==", cppfunction_call.args[1])
|
||||
|
||||
return cppfunction_call
|
||||
|
||||
# Check use of references when calling functions...
|
||||
def validate_function_call_arg(self, calling_arg_value, target_arg):
|
||||
|
@ -45,6 +49,13 @@ class DefaultConversionValidation(conversion_validation.ConversionValidation):
|
|||
if cpparg and self.is_cpp_container_type(cpparg.decl_spec):
|
||||
return literal.Literal(f"{cpparg.name}.size()")
|
||||
|
||||
# If we've updated a strcmp function call, we need to remove the return value comparison
|
||||
if cbinary_operation.left_operand.as_string().startswith("strcmp") and \
|
||||
not cppbinary_operation.left_operand.as_string().startswith("strcmp"):
|
||||
debug.line("validate_binary_operation", f"Removed strcmp return value comparison [{debug.as_debug_string(cppbinary_operation.binary_op)}][{debug.as_debug_string(cppbinary_operation.right_operand)}]")
|
||||
|
||||
return cppbinary_operation.left_operand
|
||||
|
||||
return cppbinary_operation
|
||||
|
||||
# Returns True is the name is a pointer to a class instance
|
||||
|
|
|
@ -3,8 +3,11 @@ import utils.debug as debug
|
|||
import default.default_conversion_pack.default_conversion_validation as default_conversion_validation
|
||||
import code_object.literal as literal
|
||||
import code_object.variable_declaration as variable_declaration
|
||||
import code_object.value_declaration_reference as value_declaration_reference
|
||||
import code_object.binary_operation as binary_operation
|
||||
from grib_accessor.grib_accessor_conversion_pack.grib_accessor_special_function_call_conversion import apply_special_function_call_conversions
|
||||
from code_object.code_interface import NONE_VALUE
|
||||
import code_object.if_statement as if_statement
|
||||
|
||||
# Pass this to the conversion_data object to be accessed by the conversion routines
|
||||
class GribAccessorConversionValidation(default_conversion_validation.DefaultConversionValidation):
|
||||
|
@ -37,9 +40,23 @@ class GribAccessorConversionValidation(default_conversion_validation.DefaultConv
|
|||
if cppbinary_operation.right_operand.as_string().startswith("GribAccessorFlag"):
|
||||
updated_right_operand = literal.Literal(f"toInt({cppbinary_operation.right_operand.as_string()})")
|
||||
return binary_operation.BinaryOperation(cppbinary_operation.left_operand, cppbinary_operation.binary_op, updated_right_operand)
|
||||
|
||||
|
||||
return super().validate_binary_operation(cbinary_operation, cppbinary_operation)
|
||||
|
||||
def validate_if_statement(self, cif_statement, cppif_statement):
|
||||
# Update if(x) statement when type of x is enum GribStatus
|
||||
if isinstance(cppif_statement.expression, value_declaration_reference.ValueDeclarationReference):
|
||||
expression_value = cppif_statement.expression.as_string()
|
||||
cpparg = self._conversion_data.funcbody_cpparg_for_carg_name(expression_value)
|
||||
if cpparg and cpparg != NONE_VALUE and cpparg.decl_spec.type == "GribStatus":
|
||||
updated_expression = literal.Literal(f"isError({cpparg.name})")
|
||||
updated_cppif_statement = if_statement.IfStatement(updated_expression, cppif_statement.action)
|
||||
debug.line("validate_if_statement", f"updated_cppif_statement=[{debug.as_debug_string(updated_cppif_statement)}]")
|
||||
return updated_cppif_statement
|
||||
|
||||
return super().validate_if_statement(cif_statement, cppif_statement)
|
||||
|
||||
|
||||
def is_pointer_to_class_instance(self, arg_name):
|
||||
if arg_name in ["a"]:
|
||||
return True
|
||||
|
|
|
@ -15,5 +15,8 @@ def apply_special_function_call_conversions(cfunction_call, cppfunction_call):
|
|||
|
||||
if cfunction_call.name == "snprintf":
|
||||
return function_call.FunctionCall("fmtString", cppfunction_call.args)
|
||||
|
||||
|
||||
if cfunction_call.name == "strlen":
|
||||
return function_call.FunctionCall("fmtString", cppfunction_call.args)
|
||||
|
||||
return None
|
||||
|
|
Loading…
Reference in New Issue