Fix 158 to ignore extern redeclarations.
authorRobert Bradshaw <robertwb@math.washington.edu>
Thu, 9 Apr 2009 08:51:38 +0000 (01:51 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Thu, 9 Apr 2009 08:51:38 +0000 (01:51 -0700)
Cython/Compiler/ParseTreeTransforms.py

index abf571e6cd383d220c1dc9891a009d12a795afc3..45ed94b40c38d0d552a6577c725d46024f0b8cdd 100644 (file)
@@ -659,7 +659,6 @@ class DecoratorTransform(CythonTransform, SkipDeclarations):
         return [func_node, reassignment]
 
 
-ERR_DEC_AFTER = "cdef variable '%s' declared after it is used"
 class AnalyseDeclarationsTransform(CythonTransform):
 
     basic_property = TreeFragment(u"""
@@ -673,22 +672,22 @@ property NAME:
     def __call__(self, root):
         self.env_stack = [root.scope]
         # needed to determine if a cdef var is declared after it's used.
-        self.local_scope_stack = []
+        self.seen_vars_stack = []
         return super(AnalyseDeclarationsTransform, self).__call__(root)        
     
     def visit_NameNode(self, node):
-        self.local_scope_stack[-1].add(node.name)
+        self.seen_vars_stack[-1].add(node.name)
         return node
 
     def visit_ModuleNode(self, node):
-        self.local_scope_stack.append(set())
+        self.seen_vars_stack.append(set())
         node.analyse_declarations(self.env_stack[-1])
         self.visitchildren(node)
-        self.local_scope_stack.pop()
+        self.seen_vars_stack.pop()
         return node
         
     def visit_FuncDefNode(self, node):
-        self.local_scope_stack.append(set())
+        self.seen_vars_stack.append(set())
         lenv = node.create_local_scope(self.env_stack[-1])
         node.body.analyse_control_flow(lenv) # this will be totally refactored
         node.declare_arguments(lenv)
@@ -703,7 +702,7 @@ property NAME:
         self.env_stack.append(lenv)
         self.visitchildren(node)
         self.env_stack.pop()
-        self.local_scope_stack.pop()
+        self.seen_vars_stack.pop()
         return node
     
     # Some nodes are no longer needed after declaration
@@ -728,9 +727,10 @@ property NAME:
         return None
 
     def visit_CNameDeclaratorNode(self, node):
-        if node.name in self.local_scope_stack[-1]:
-            # cdef variable declared after it's used.
-            error(node.pos, ERR_DEC_AFTER % node.name)
+        if node.name in self.seen_vars_stack[-1]:
+            entry = self.env_stack[-1].lookup(node.name)
+            if entry is None or entry.visibility != 'extern':
+                error(node.pos, "cdef variable '%s' declared after it is used" % node.name)
         self.visitchildren(node)
         return node