Commit 40f1624b authored by Stefan Behnel's avatar Stefan Behnel

merge

parents 74dffa6f 76e9534b
...@@ -1023,6 +1023,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1023,6 +1023,7 @@ class FuncDefNode(StatNode, BlockNode):
if type.is_cfunction: if type.is_cfunction:
lenv.nogil = type.nogil and not type.with_gil lenv.nogil = type.nogil and not type.with_gil
self.local_scope = lenv self.local_scope = lenv
lenv.directives = env.directives
return lenv return lenv
def generate_function_definitions(self, env, code): def generate_function_definitions(self, env, code):
...@@ -1305,9 +1306,7 @@ class CFuncDefNode(FuncDefNode): ...@@ -1305,9 +1306,7 @@ class CFuncDefNode(FuncDefNode):
return self.entry.name return self.entry.name
def analyse_declarations(self, env): def analyse_declarations(self, env):
if 'locals' in env.directives and env.directives['locals']: directive_locals = self.directive_locals = env.directives['locals']
self.directive_locals = env.directives['locals']
directive_locals = self.directive_locals
base_type = self.base_type.analyse(env) base_type = self.base_type.analyse(env)
# The 2 here is because we need both function and argument names. # The 2 here is because we need both function and argument names.
name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None)) name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
...@@ -1650,11 +1649,7 @@ class DefNode(FuncDefNode): ...@@ -1650,11 +1649,7 @@ class DefNode(FuncDefNode):
directive_locals = getattr(cfunc, 'directive_locals', {})) directive_locals = getattr(cfunc, 'directive_locals', {}))
def analyse_declarations(self, env): def analyse_declarations(self, env):
if 'locals' in env.directives: directive_locals = self.directive_locals = env.directives['locals']
directive_locals = env.directives['locals']
else:
directive_locals = {}
self.directive_locals = directive_locals
for arg in self.args: for arg in self.args:
if hasattr(arg, 'name'): if hasattr(arg, 'name'):
type = arg.type type = arg.type
...@@ -2564,6 +2559,7 @@ class PyClassDefNode(ClassDefNode): ...@@ -2564,6 +2559,7 @@ class PyClassDefNode(ClassDefNode):
def analyse_declarations(self, env): def analyse_declarations(self, env):
self.target.analyse_target_declaration(env) self.target.analyse_target_declaration(env)
cenv = self.create_scope(env) cenv = self.create_scope(env)
cenv.directives = env.directives
cenv.class_obj_cname = self.target.entry.cname cenv.class_obj_cname = self.target.entry.cname
self.body.analyse_declarations(cenv) self.body.analyse_declarations(cenv)
...@@ -2702,6 +2698,8 @@ class CClassDefNode(ClassDefNode): ...@@ -2702,6 +2698,8 @@ class CClassDefNode(ClassDefNode):
if home_scope is not env and self.visibility == 'extern': if home_scope is not env and self.visibility == 'extern':
env.add_imported_entry(self.class_name, self.entry, pos) env.add_imported_entry(self.class_name, self.entry, pos)
scope = self.entry.type.scope scope = self.entry.type.scope
if scope is not None:
scope.directives = env.directives
if self.doc and Options.docstrings: if self.doc and Options.docstrings:
scope.doc = embed_position(self.pos, self.doc) scope.doc = embed_position(self.pos, self.doc)
...@@ -2752,6 +2750,7 @@ class PropertyNode(StatNode): ...@@ -2752,6 +2750,7 @@ class PropertyNode(StatNode):
doc_entry = env.get_string_const( doc_entry = env.get_string_const(
self.doc, identifier = False) self.doc, identifier = False)
entry.doc_cname = doc_entry.cname entry.doc_cname = doc_entry.cname
entry.scope.directives = env.directives
self.body.analyse_declarations(entry.scope) self.body.analyse_declarations(entry.scope)
def analyse_expressions(self, env): def analyse_expressions(self, env):
......
...@@ -659,7 +659,6 @@ class DecoratorTransform(CythonTransform, SkipDeclarations): ...@@ -659,7 +659,6 @@ class DecoratorTransform(CythonTransform, SkipDeclarations):
return [func_node, reassignment] return [func_node, reassignment]
ERR_DEC_AFTER = "cdef variable '%s' declared after it is used"
class AnalyseDeclarationsTransform(CythonTransform): class AnalyseDeclarationsTransform(CythonTransform):
basic_property = TreeFragment(u""" basic_property = TreeFragment(u"""
...@@ -673,22 +672,22 @@ property NAME: ...@@ -673,22 +672,22 @@ property NAME:
def __call__(self, root): def __call__(self, root):
self.env_stack = [root.scope] self.env_stack = [root.scope]
# needed to determine if a cdef var is declared after it's used. # 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) return super(AnalyseDeclarationsTransform, self).__call__(root)
def visit_NameNode(self, node): def visit_NameNode(self, node):
self.local_scope_stack[-1].add(node.name) self.seen_vars_stack[-1].add(node.name)
return node return node
def visit_ModuleNode(self, 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]) node.analyse_declarations(self.env_stack[-1])
self.visitchildren(node) self.visitchildren(node)
self.local_scope_stack.pop() self.seen_vars_stack.pop()
return node return node
def visit_FuncDefNode(self, 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]) lenv = node.create_local_scope(self.env_stack[-1])
node.body.analyse_control_flow(lenv) # this will be totally refactored node.body.analyse_control_flow(lenv) # this will be totally refactored
node.declare_arguments(lenv) node.declare_arguments(lenv)
...@@ -703,7 +702,7 @@ property NAME: ...@@ -703,7 +702,7 @@ property NAME:
self.env_stack.append(lenv) self.env_stack.append(lenv)
self.visitchildren(node) self.visitchildren(node)
self.env_stack.pop() self.env_stack.pop()
self.local_scope_stack.pop() self.seen_vars_stack.pop()
return node return node
# Some nodes are no longer needed after declaration # Some nodes are no longer needed after declaration
...@@ -728,9 +727,10 @@ property NAME: ...@@ -728,9 +727,10 @@ property NAME:
return None return None
def visit_CNameDeclaratorNode(self, node): def visit_CNameDeclaratorNode(self, node):
if node.name in self.local_scope_stack[-1]: if node.name in self.seen_vars_stack[-1]:
# cdef variable declared after it's used. entry = self.env_stack[-1].lookup(node.name)
error(node.pos, ERR_DEC_AFTER % 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) self.visitchildren(node)
return node return node
......
...@@ -211,7 +211,6 @@ class Scope(object): ...@@ -211,7 +211,6 @@ class Scope(object):
scope_prefix = "" scope_prefix = ""
in_cinclude = 0 in_cinclude = 0
nogil = 0 nogil = 0
directives = {}
temp_prefix = Naming.pyrex_prefix temp_prefix = Naming.pyrex_prefix
......
...@@ -147,6 +147,9 @@ class TestBuilder(object): ...@@ -147,6 +147,9 @@ class TestBuilder(object):
languages = self.languages[:1] languages = self.languages[:1]
else: else:
languages = self.languages languages = self.languages
if 'cpp' in module and 'c' in languages:
languages = list(languages)
languages.remove('c')
tests = [ self.build_test(test_class, path, workdir, module, tests = [ self.build_test(test_class, path, workdir, module,
language, expect_errors) language, expect_errors)
for language in languages ] for language in languages ]
......
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