Commit 06ba4584 authored by Xavier Thompson's avatar Xavier Thompson

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

parent e5db8237
......@@ -7703,6 +7703,9 @@ class AttributeNode(ExprNode):
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:
# the entry might have been resolved to an overladed alternative in the meantime
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)
......
......@@ -1042,11 +1042,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
continue
elif attr.type.is_cyp_class:
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:
code.putln("%s;" % attr.type.declaration_code(attr.static_cname))
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
......@@ -1192,14 +1190,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
arg_decls.append(e.type.op_arg_struct.declaration_code(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 "):
header = e.type.return_type.declaration_code(header)
return_code = "" if e.type.return_type.is_void else "return "
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))
if inherited_methods:
......@@ -1220,13 +1220,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
arg_decls.append(func_type.op_arg_struct.declaration_code(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 "):
header = func_type.return_type.declaration_code(header)
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))
......
......@@ -2855,9 +2855,6 @@ class CppClassScope(Scope):
entry.is_cfunction = type.is_cfunction
if type.is_cfunction and self.type:
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)
if name != "this" and (defining or name != "<init>" or self.parent_type.is_cyp_class):
self.var_entries.append(entry)
......@@ -3037,6 +3034,9 @@ class CppClassScope(Scope):
cname=cname, visibility=visibility)
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:
self.reify_method(entry)
#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