From 48af70f34c193ae7f6029b5d368fa5840d7cd20c Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 2 Mar 2011 11:19:17 -0500 Subject: [PATCH] Convert CVarDefNode to use explicit visibilities. This required some cleanups in Parsing.p_visibility, and the explicit return to private visibility (for both C and Python) when parsing C-backed class bodies. --- Cython/Compiler/Nodes.py | 29 ++++++++++++++------------ Cython/Compiler/Parsing.py | 42 ++++++++++++++++++++------------------ 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 087e474b..23ca71ef 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -15,6 +15,7 @@ cython.declare(sys=object, os=object, time=object, copy=object, import sys, os, time, copy import Builtin +from Binding import Binding from Errors import error, warning, InternalError import Naming import PyrexTypes @@ -907,11 +908,13 @@ class CComplexBaseTypeNode(CBaseTypeNode): class CVarDefNode(StatNode): # C variable definition or forward/extern function declaration. # - # visibility 'private' or 'public' or 'extern' + # extern (same as Binding.extern) + # c_visibility (same as Binding.c_visibility) + # visibility (same as Binding.visibility) # base_type CBaseTypeNode # declarators [CDeclaratorNode] # in_pxd boolean - # api boolean + # api (same as Binding.api) # decorators [cython.locals(...)] or None # directive_locals { string : NameNode } locals defined by cython.locals(...) @@ -930,20 +933,18 @@ class CVarDefNode(StatNode): # If the field is an external typedef, we cannot be sure about the type, # so do conversion ourself rather than rely on the CPython mechanism (through # a property; made in AnalyseDeclarationsTransform). - if (dest_scope.is_c_class_scope - and self.visibility in ('public', 'readonly')): + if dest_scope.is_c_class_scope and self.c_visibility == 'public': need_property = True else: need_property = False - visibility = self.visibility for declarator in self.declarators: name_declarator, type = declarator.analyse(base_type, env) if not type.is_complete(): - if not (self.visibility == 'extern' and type.is_array): + if not (self.extern and type.is_array): error(declarator.pos, "Variable type '%s' is incomplete" % type) - if self.visibility == 'extern' and type.is_pyobject: + if self.extern and type.is_pyobject: error(declarator.pos, "Python object cannot be declared extern") name = name_declarator.name @@ -951,20 +952,22 @@ class CVarDefNode(StatNode): if name == '': error(declarator.pos, "Missing name in declaration.") return + binding = Binding(name=name, cname=cname) + binding.pull(self) if type.is_cfunction: - entry = dest_scope.declare_cfunction(name, type, declarator.pos, - cname = cname, visibility = self.visibility, in_pxd = self.in_pxd, - api = self.api) + entry = dest_scope.WTK_declare_cfunction( + binding, type = type, pos = declarator.pos, + in_pxd = self.in_pxd) if entry is not None: entry.directive_locals = self.directive_locals else: if self.directive_locals: error(self.pos, "Decorators can only be followed by functions") - if self.in_pxd and self.visibility != 'extern': + if self.in_pxd and not self.extern: error(self.pos, "Only 'extern' C variable declaration allowed in .pxd file") - entry = dest_scope.declare_var(name, type, declarator.pos, - cname = cname, visibility = visibility, is_cdef = 1) + entry = dest_scope.WTK_declare_var( + binding, type = type, is_cdef = 1, pos = declarator.pos) entry.needs_property = need_property diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 2a2eff3b..e3fe4c74 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -2659,22 +2659,23 @@ def p_visibility(s, ctx): _LOG.debug('p_visibility(s=)' % (s.sy, s.systring)) pos = s.position() - prev_visibility = 'private' - if ctx.extern: - prev_visibility = 'extern' - elif ctx.c_visibility != 'private': - prev_visibility = ctx.c_visibility - visibility = prev_visibility if s.sy == 'IDENT' and s.systring in ('extern', 'public', 'readonly'): visibility = s.systring - if prev_visibility != 'private' and visibility != prev_visibility: - s.error("Conflicting visibility options '%s' and '%s'" - % (prev_visibility, visibility)) + outer_scope = ctx.level in ('module', 'module_pxd') + if visibility == 'extern': + #if prev_visibility != 'private' and visibility != prev_visibility: + # s.error("Conflicting visibility options '%s' and '%s'" + # % (prev_visibility, visibility)) + ctx.extern = 1 + ctx.c_visibility = 'public' + # Need to restore/set default value for Python visibility? + elif outer_scope and visibility not in ('readonly',): + ctx.c_visibility = visibility + else: + ctx.visibility = visibility + if ctx.visibility != 'private': + ctx.c_visibility = 'public' s.next() - if visibility == 'extern': - ctx.extern = 1 - else: - ctx.c_visibility = visibility return ctx def p_c_modifiers(s): @@ -2752,13 +2753,10 @@ def p_c_func_or_var_declaration(s, pos, ctx, decorators=None): assignable = 1, nonempty = 1) declarators.append(declarator) s.expect_newline("Syntax error in C variable declaration") - visibility = 'private' - if ctx.extern: - visibility = 'extern' - elif ctx.c_visibility != 'private': - visibility = ctx.c_visibility result = Nodes.CVarDefNode(pos, - visibility = visibility, + extern = ctx.extern, + c_visibility = ctx.c_visibility, + visibility = ctx.visibility, api = ctx.api, overridable = ctx.overridable, base_type = base_type, @@ -2935,7 +2933,11 @@ def p_c_class_definition(s, pos, ctx, decorators=None): body_level = 'c_class_pxd' else: body_level = 'c_class' - doc, body = p_suite(s, Ctx(level = body_level), with_doc = 1) + body_ctx = Ctx( + level = body_level, + visibility = 'private', + c_visibility = 'private') + doc, body = p_suite(s, body_ctx, with_doc = 1) else: s.expect_newline("Syntax error in C class definition") doc = None -- 2.26.2