Commit f3b532d8 authored by Xavier Thompson's avatar Xavier Thompson

Handle dispatching cypclass static methods via virtual methods in a clearer and more robust way

parent 98ae9e0e
...@@ -7703,7 +7703,10 @@ class AttributeNode(ExprNode): ...@@ -7703,7 +7703,10 @@ class AttributeNode(ExprNode):
obj_code = obj.type.cast_code(obj.result(), to_object_struct = True) obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
if obj.type.is_cpp_class and self.entry and self.entry.is_cfunction: if obj.type.is_cpp_class and self.entry and self.entry.is_cfunction:
# the entry might have been resolved to an overladed alternative in the meantime # the entry might have been resolved to an overladed alternative in the meantime
self.member = self.entry.cname if obj.type.is_cyp_class and self.entry.type.is_static_method and self.entry.static_cname is not None:
self.member = self.entry.static_cname
else:
self.member = self.entry.cname
return "%s%s%s" % (obj_code, self.op, self.member) return "%s%s%s" % (obj_code, self.op, self.member)
def generate_result_code(self, code): def generate_result_code(self, code):
......
...@@ -1042,11 +1042,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1042,11 +1042,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
continue continue
elif attr.type.is_cyp_class: elif attr.type.is_cyp_class:
cname = "%s = NULL" % cname cname = "%s = NULL" % cname
code.putln("%s;" % attr.type.declaration_code(cname))
if type.is_cyp_class and attr.type.is_cfunction and attr.type.is_static_method and attr.static_cname is not None: if type.is_cyp_class and attr.type.is_cfunction and attr.type.is_static_method and attr.static_cname is not None:
code.putln("%s;" % attr.type.declaration_code(attr.static_cname))
self.generate_cyp_class_static_method_resolution(attr, code) self.generate_cyp_class_static_method_resolution(attr, code)
else:
code.putln("%s;" % attr.type.declaration_code(cname))
is_implementing = 'init_module' in code.globalstate.parts is_implementing = 'init_module' in code.globalstate.parts
...@@ -1192,14 +1190,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1192,14 +1190,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
arg_decls.append(e.type.op_arg_struct.declaration_code(opt_name)) arg_decls.append(e.type.op_arg_struct.declaration_code(opt_name))
arg_names.append(opt_name) arg_names.append(opt_name)
header = e.type.function_header_code(e.cname, ", ".join(arg_decls)) cname = e.cname if not e.type.is_static_method else e.static_cname
header = e.type.function_header_code(cname, ", ".join(arg_decls))
if not e.name.startswith("operator "): if not e.name.startswith("operator "):
header = e.type.return_type.declaration_code(header) header = e.type.return_type.declaration_code(header)
return_code = "" if e.type.return_type.is_void else "return " return_code = "" if e.type.return_type.is_void else "return "
resolution = e.from_type.empty_declaration_code() resolution = e.from_type.empty_declaration_code()
body = "%s%s::%s(%s);" % (return_code, resolution, e.cname, ", ".join(arg_names)) body = "%s%s::%s(%s);" % (return_code, resolution, cname, ", ".join(arg_names))
code.putln("virtual %s%s {%s}" % (modifiers, header, body)) code.putln("virtual %s%s {%s}" % (modifiers, header, body))
if inherited_methods: if inherited_methods:
...@@ -1220,13 +1220,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1220,13 +1220,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
arg_decls.append(func_type.op_arg_struct.declaration_code(opt_name)) arg_decls.append(func_type.op_arg_struct.declaration_code(opt_name))
arg_names.append(opt_name) arg_names.append(opt_name)
header = func_type.function_header_code(static_method.cname, ", ".join(arg_decls)) header = func_type.function_header_code(static_method.static_cname, ", ".join(arg_decls))
if not static_method.name.startswith("operator "): if not static_method.name.startswith("operator "):
header = func_type.return_type.declaration_code(header) header = func_type.return_type.declaration_code(header)
return_code = "" if func_type.return_type.is_void else "return " return_code = "" if func_type.return_type.is_void else "return "
body = "%s%s(%s);" % (return_code, static_method.static_cname, ", ".join(arg_names)) body = "%s%s(%s);" % (return_code, static_method.cname, ", ".join(arg_names))
code.putln("virtual %s%s {%s}" % (modifiers, header, body)) code.putln("virtual %s%s {%s}" % (modifiers, header, body))
......
...@@ -2855,9 +2855,6 @@ class CppClassScope(Scope): ...@@ -2855,9 +2855,6 @@ class CppClassScope(Scope):
entry.is_cfunction = type.is_cfunction entry.is_cfunction = type.is_cfunction
if type.is_cfunction and self.type: if type.is_cfunction and self.type:
if not self.type.get_fused_types(): if not self.type.get_fused_types():
if (self.parent_type.is_cyp_class and type.is_static_method and name not in ("<alloc>", "__new__")):
cname = "%s__static__%s" % (Naming.func_prefix, cname)
entry.static_cname = cname
entry.func_cname = "%s::%s" % (self.type.empty_declaration_code(), cname) entry.func_cname = "%s::%s" % (self.type.empty_declaration_code(), cname)
if name != "this" and (defining or name != "<init>" or self.parent_type.is_cyp_class): if name != "this" and (defining or name != "<init>" or self.parent_type.is_cyp_class):
self.var_entries.append(entry) self.var_entries.append(entry)
...@@ -3037,6 +3034,9 @@ class CppClassScope(Scope): ...@@ -3037,6 +3034,9 @@ class CppClassScope(Scope):
cname=cname, visibility=visibility) cname=cname, visibility=visibility)
entry.original_name = original_name entry.original_name = original_name
if (self.parent_type.is_cyp_class and type.is_static_method and name not in ("<alloc>", "__new__")):
entry.static_cname = "%s__static__%s" % (Naming.func_prefix, cname)
if reify: if reify:
self.reify_method(entry) self.reify_method(entry)
#if prev_entry and not defining: #if prev_entry and not defining:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment