Commit 2108d1aa authored by Robert Bradshaw's avatar Robert Bradshaw

Completely re-do out-of-order class declarations.

parent d929ac08
...@@ -379,38 +379,7 @@ class StatListNode(Node): ...@@ -379,38 +379,7 @@ class StatListNode(Node):
def analyse_declarations(self, env): def analyse_declarations(self, env):
#print "StatListNode.analyse_declarations" ### #print "StatListNode.analyse_declarations" ###
base_classes = {} for stat in self.stats:
def flatten(stats):
# Common case is trivial flatten.
if not [stat for stat in stats if isinstance(stat, StatListNode)]:
return stats
else:
all = []
for stat in stats:
if isinstance(stat, StatListNode):
all.extend(flatten(stat.stats))
else:
all.append(stat)
return all
flattened = flatten(self.stats)
for stat in flattened:
if isinstance(stat, CClassDefNode) and not stat.base_class_module:
base_classes[stat.class_name] = stat.base_class_name
@cached_function
def depth(class_name):
base_class = base_classes.get(class_name)
if class_name is None:
return 0
else:
return depth(base_class) + 1
keyed_stats = []
for ix, stat in enumerate(flattened):
if isinstance(stat, CClassDefNode):
key = 20, depth(stat.class_name), ix
else:
key = 10, ix
keyed_stats.append((key, stat))
for key, stat in sorted(keyed_stats):
stat.analyse_declarations(env) stat.analyse_declarations(env)
def analyse_expressions(self, env): def analyse_expressions(self, env):
...@@ -4337,6 +4306,12 @@ class CClassDefNode(ClassDefNode): ...@@ -4337,6 +4306,12 @@ class CClassDefNode(ClassDefNode):
warning(self.pos, "freelists cannot be used on subtypes, only the base class can manage them", 1) warning(self.pos, "freelists cannot be used on subtypes, only the base class can manage them", 1)
has_body = self.body is not None has_body = self.body is not None
if has_body and self.base_type and not self.base_type.scope:
# To properly initialize inherited attributes, the base type must
# be analysed before this type.
self.base_type.defered_declarations.append(lambda : self.analyse_declarations(env))
return
if self.module_name and self.visibility != 'extern': if self.module_name and self.visibility != 'extern':
module_path = self.module_name.split(".") module_path = self.module_name.split(".")
home_scope = env.find_imported_module(module_path, self.pos) home_scope = env.find_imported_module(module_path, self.pos)
...@@ -4385,6 +4360,9 @@ class CClassDefNode(ClassDefNode): ...@@ -4385,6 +4360,9 @@ class CClassDefNode(ClassDefNode):
scope.implemented = 1 scope.implemented = 1
env.allocate_vtable_names(self.entry) env.allocate_vtable_names(self.entry)
for thunk in self.entry.type.defered_declarations:
thunk()
def analyse_expressions(self, env): def analyse_expressions(self, env):
if self.body: if self.body:
scope = self.entry.type.scope scope = self.entry.type.scope
......
...@@ -1070,6 +1070,7 @@ class PyExtensionType(PyObjectType): ...@@ -1070,6 +1070,7 @@ class PyExtensionType(PyObjectType):
# vtabstruct_cname string Name of C method table struct # vtabstruct_cname string Name of C method table struct
# vtabptr_cname string Name of pointer to C method table # vtabptr_cname string Name of pointer to C method table
# vtable_cname string Name of C method table definition # vtable_cname string Name of C method table definition
# defered_declarations [thunk] Used to declare class hierarchies in order
is_extension_type = 1 is_extension_type = 1
has_attributes = 1 has_attributes = 1
...@@ -1092,6 +1093,7 @@ class PyExtensionType(PyObjectType): ...@@ -1092,6 +1093,7 @@ class PyExtensionType(PyObjectType):
self.vtabptr_cname = None self.vtabptr_cname = None
self.vtable_cname = None self.vtable_cname = None
self.is_external = is_external self.is_external = is_external
self.defered_declarations = []
def set_scope(self, scope): def set_scope(self, scope):
self.scope = scope self.scope = scope
......
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