From: W. Trevor King Date: Tue, 8 Mar 2011 21:42:27 +0000 (-0500) Subject: Merge Binding.extern back into Binding.c_visibility. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=c83625b1e059bd68f12acb880537e51dd12a87bd;p=cython.git Merge Binding.extern back into Binding.c_visibility. Discussions with Robert Bradshaw have convinced me that its not worth keeping separate attributes to control extern, mangling, etc., so I'm bundling these back together again. --- diff --git a/Cython/Compiler/Binding.py b/Cython/Compiler/Binding.py index faa738e0..96eb5816 100644 --- a/Cython/Compiler/Binding.py +++ b/Cython/Compiler/Binding.py @@ -52,12 +52,12 @@ class CBinding(_BindingAttributes): * namespace (string): C++ namespace of the source (`None` for C objects, set if the symbol is external) * cdef_flag (boolean): Symbol (data) has a C definition. - * extern (boolean): Symbol is defined elsewhere (otherwise a local - defition is created). - * visibility ('private'|'public'|'ignore'): + * visibility ('private'|'public'|'extern'|'ignore'): * private: Symbol is not accessible to external C code * public: Symbol is accessible to external C code + * extern: Symbol is defined elsewhere (otherwise a local + definition is created). * ignore: ? something about symbol re-definition? * const (boolean): Symbol data is readonly. @@ -66,7 +66,6 @@ class CBinding(_BindingAttributes): cname = None namespace = None cdef_flag = 0 - extern = 0 c_visibility = 'private' const = 0 api = 0 @@ -96,10 +95,5 @@ class Binding(CBinding, PythonBinding): "Combine all binding attributes in a single, flat namespace." def visibility_string(self): "Summarize binding visibility in a single string" - if self.extern: - extern_string = ' (extern)' - else: - extern_string = '' - return 'C: %s%s, Python: %s' % ( - self.c_visibility, extern_string, self.visibility) - + return 'C: %s, Python: %s' % ( + self.c_visibility, self.visibility) diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py index f8025314..dd864cd7 100644 --- a/Cython/Compiler/Builtin.py +++ b/Cython/Compiler/Builtin.py @@ -348,7 +348,9 @@ class BuiltinFunction(_BuiltinOverride): if sig is None: sig = Signature(self.args, self.ret_type) func_type = sig.function_type() - binding = Binding(name = self.py_name, cname = self.cname, extern = 1) + binding = Binding( + name = self.py_name, cname = self.cname, + c_visibility = 'extern') scope.declare_builtin_cfunction( binding, type = func_type, python_equiv = self.py_equiv, utility_code = self.utility_code) @@ -363,7 +365,9 @@ class BuiltinMethod(_BuiltinOverride): self_arg = PyrexTypes.CFuncTypeArg("", self_type, None) self_arg.not_none = True method_type = sig.function_type(self_arg) - binding = Binding(name = self.py_name, cname = self.cname, extern = 1) + binding = Binding( + name = self.py_name, cname = self.cname, + c_visibility = 'extern') self_type.scope.declare_builtin_cfunction( binding, type = method_type, utility_code = self.utility_code) @@ -558,7 +562,7 @@ def init_builtin_types(): else: objstruct_cname = 'Py%sObject' % name.capitalize() binding = Binding( - name = name, cname = cname, extern = 1, c_visibility = 'public') + name = name, cname = cname, c_visibility = 'extern') the_type = builtin_scope.declare_builtin_type( binding, objstruct_cname = objstruct_cname, utility_code = utility) builtin_types[name] = the_type diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py index df25bea2..9bb3927f 100644 --- a/Cython/Compiler/Code.py +++ b/Cython/Compiler/Code.py @@ -1119,7 +1119,7 @@ class CCodeWriter(object): #print "not used and private, skipping", entry.cname ### return storage_class = "" - if entry.extern: + if entry.c_visibility == 'extern': storage_class = Naming.extern_c_macro elif entry.c_visibility == 'public': if not definition: @@ -1129,7 +1129,7 @@ class CCodeWriter(object): storage_class = "static" if storage_class: self.put("%s " % storage_class) - if (entry.extern or entry.c_visibility != 'public'): + if entry.c_visibility != 'public': dll_linkage = None self.put(entry.type.declaration_code(entry.cname, dll_linkage = dll_linkage)) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index f5ee8126..024b74a5 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -1245,7 +1245,7 @@ class NewExprNode(AtomicExprNode): return_type = PyrexTypes.CFuncType(type, []) return_type = PyrexTypes.CPtrType(return_type) binding = Binding( - name = u'', extern = True, c_visibility = 'public') + name = u'', c_visibility = 'extern') type.scope.declare_cfunction( binding, type = return_type, pos = self.pos) constructor = type.scope.lookup(u'') diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 9cef756a..80312ab2 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -98,8 +98,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): def generate_h_code(self, env, options, result): def h_entries(entries, pxd = 0): return [entry for entry in entries - if (entry.c_visibility == 'public' and - not entry.extern) + if entry.c_visibility == 'public' or pxd and entry.defined_in_pxd] h_types = h_entries(env.type_entries) h_vars = h_entries(env.var_entries) @@ -876,7 +875,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("") name = entry.type.typeobj_cname if name: - if entry.extern and not entry.in_cinclude: + if entry.c_visibility == 'extern' and not entry.in_cinclude: code.putln("%s DL_IMPORT(PyTypeObject) %s;" % ( Naming.extern_c_macro, name)) @@ -964,8 +963,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): def generate_cfunction_predeclarations(self, env, code, definition): for entry in env.cfunc_entries: if entry.inline_func_in_pxd or (not entry.in_cinclude and (definition - or entry.defined_in_pxd or entry.extern)): - if entry.extern or entry.c_visibility == 'public': + or entry.defined_in_pxd or entry.c_visibility == 'extern')): + if entry.c_visibility in ('extern', 'public'): dll_linkage = "DL_EXPORT" else: dll_linkage = None @@ -976,7 +975,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): dll_linkage = dll_linkage) if entry.c_visibility == 'private': storage_class = "static " - elif (entry.c_visibility == 'public' and not entry.extern): + elif entry.c_visibility == 'public': storage_class = "" else: storage_class = "%s " % Naming.extern_c_macro @@ -995,7 +994,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): for entry in env.c_class_entries: #print "generate_typeobj_definitions:", entry.name #print "...c_visibility =", entry.c_visibility - if not entry.extern: + if entry.c_visibility != 'extern': type = entry.type scope = type.scope if scope: # could be None if there was an error @@ -1866,7 +1865,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): rev_entries = list(env.var_entries) rev_entries.reverse() for entry in rev_entries: - if not entry.extern: + if entry.c_visibility != 'extern': if entry.type.is_pyobject and entry.used: code.putln("Py_DECREF(%s); %s = 0;" % ( code.entry_as_pyobject(entry), entry.cname)) @@ -1988,7 +1987,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): # Generate code to initialise global PyObject * # variables to None. for entry in env.var_entries: - if not entry.extern: + if entry.c_visibility != 'extern': if entry.type.is_pyobject and entry.used: code.put_init_var_to_py_none(entry, nanny=False) @@ -2042,7 +2041,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): # Generate type import code for extern extension types # and type ready code for non-extern ones. for entry in env.c_class_entries: - if entry.extern: + if entry.c_visibility == 'extern': self.generate_type_import_code(env, entry.type, entry.pos, code) else: self.generate_base_type_import_code(env, entry, code) @@ -2120,7 +2119,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): typeobj_cname = type.typeobj_cname scope = type.scope if scope: # could be None if there was an error - if not entry.extern: + if entry.c_visibility != 'extern': for slot in TypeSlots.slot_table: slot.generate_dynamic_init_code(scope, code) code.putln( diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 1184030b..9178760c 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -916,7 +916,6 @@ class CComplexBaseTypeNode(CBaseTypeNode): class CVarDefNode(StatNode): # C variable definition or forward/extern function declaration. # - # extern (same as Binding.extern) # c_visibility (same as Binding.c_visibility) # visibility (same as Binding.visibility) # base_type CBaseTypeNode @@ -949,10 +948,10 @@ class CVarDefNode(StatNode): for declarator in self.declarators: name_declarator, type = declarator.analyse(base_type, env) if not type.is_complete(): - if not (self.extern and type.is_array): + if not (self.c_visibility == 'extern' and type.is_array): error(declarator.pos, "Variable type '%s' is incomplete" % type) - if self.extern and type.is_pyobject: + if self.c_visibility == 'extern' and type.is_pyobject: error(declarator.pos, "Python object cannot be declared extern") name = name_declarator.name @@ -971,7 +970,7 @@ class CVarDefNode(StatNode): else: if self.directive_locals: error(self.pos, "Decorators can only be followed by functions") - if self.in_pxd and not self.extern: + if self.in_pxd and self.c_visibility != 'extern': error(self.pos, "Only 'extern' C variable declaration allowed in .pxd file") entry = dest_scope.declare_var( @@ -984,7 +983,6 @@ class CStructOrUnionDefNode(StatNode): # cname (same as Binding.cname) # kind "struct" or "union" # typedef_flag boolean - # extern (same as Binding.extern) # c_visibility (same as Binding.c_visibility) # visibility (same as Binding.visibility) # in_pxd boolean @@ -996,7 +994,7 @@ class CStructOrUnionDefNode(StatNode): def analyse_declarations(self, env): scope = None - if self.extern and self.packed: + if self.c_visibility == 'extern' and self.packed: error(self.pos, "Cannot declare extern struct as 'packed'") if self.attributes is not None: scope = StructOrUnionScope(self.name) @@ -1011,7 +1009,7 @@ class CStructOrUnionDefNode(StatNode): self.entry.defined_in_pxd = 1 for attr in self.attributes: attr.analyse_declarations(env, scope) - if not self.extern: + if self.c_visibility != 'extern': need_typedef_indirection = False for attr in scope.var_entries: type = attr.type @@ -1048,8 +1046,7 @@ class CStructOrUnionDefNode(StatNode): class CppClassNode(CStructOrUnionDefNode): # name (same as Binding.name) # cname (same as Binding.cname) - # extern 1 (same meaning as Binding.extern) - # c_visibility "public" (same as Binding.c_visibility) + # c_visibility 'extern' (same as Binding.c_visibility) # visibility (same as Binding.visibility) # in_pxd boolean # attributes [CVarDefNode] or None @@ -1093,7 +1090,6 @@ class CEnumDefNode(StatNode): # cname (same as Binding.cname) # items [CEnumDefItemNode] # typedef_flag boolean - # extern (same meaning as Binding.extern) # c_visibility (same as Binding.c_visibility) # visibility (same as Binding.visibility) # in_pxd boolean @@ -1631,7 +1627,6 @@ class CFuncDefNode(FuncDefNode): # C function definition. # # modifiers ['inline'] - # extern (same as Binding.extern) # c_visibility (same as Binding.c_visibility) # visibility (same as Binding.visibility) # base_type CBaseTypeNode @@ -1688,7 +1683,7 @@ class CFuncDefNode(FuncDefNode): modifiers = self.modifiers, pos = self.pos) self.entry.inline_func_in_pxd = self.inline_in_pxd self.return_type = type.return_type - if self.return_type.is_array and not self.extern: + if self.return_type.is_array and self.c_visibility != 'extern': error(self.pos, "Function cannot return an array") @@ -1781,14 +1776,13 @@ class CFuncDefNode(FuncDefNode): if cname is None: cname = self.entry.func_cname entity = type.function_header_code(cname, ', '.join(arg_decls)) - if (self.entry.c_visibility == 'public' and - not self.entry.extern): + if self.entry.c_visibility == 'public': dll_linkage = "DL_EXPORT" else: dll_linkage = None header = self.return_type.declaration_code(entity, dll_linkage = dll_linkage) - if self.entry.extern: + if self.entry.c_visibility == 'extern': storage_class = "%s " % Naming.extern_c_macro elif self.entry.c_visibility == 'public': storage_class = "" @@ -2008,7 +2002,6 @@ class DefNode(FuncDefNode): type = cfunc_type, with_gil = cfunc_type.with_gil, nogil = cfunc_type.nogil, - extern = 0, c_visibility = 'private', visibility = 'public', api = False, @@ -2194,7 +2187,7 @@ class DefNode(FuncDefNode): warning(self.pos, "Overriding cdef method with def method.", 5) binding = Binding(name = name) if env.is_c_class_scope: - binding.extern = True + binding.c_visibility = 'extern' entry = env.declare_pyfunction( binding, allow_redefine=not self.is_wrapper, pos = self.pos) self.entry = entry @@ -3106,7 +3099,6 @@ class PyClassDefNode(ClassDefNode): return None return CClassDefNode(self.pos, - extern = 0, c_visibility = 'private', visibility = 'public', module_name = None, @@ -3175,7 +3167,6 @@ class PyClassDefNode(ClassDefNode): class CClassDefNode(ClassDefNode): # An extension type definition. # - # extern (same as Binding.extern) # c_visibility (same as Binding.c_visibility) # visibility (same as Binding.visibility) # typedef_flag boolean @@ -3269,7 +3260,7 @@ class CClassDefNode(ClassDefNode): else: self.base_type = base_class_entry.type has_body = self.body is not None - if self.module_name and not self.extern: + if self.module_name and self.c_visibility != 'extern': module_path = self.module_name.split(".") home_scope = env.find_imported_module(module_path, self.pos) if not home_scope: @@ -3277,7 +3268,7 @@ class CClassDefNode(ClassDefNode): else: home_scope = env - if self.extern: + if self.c_visibility == 'extern': if (self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types and env.qualified_name[:8] != 'cpython.'): # allow overloaded names for cimporting from cpython @@ -3300,7 +3291,7 @@ class CClassDefNode(ClassDefNode): pos = self.pos) if self.shadow: home_scope.lookup(self.class_name).as_variable = self.entry - if home_scope is not env and self.extern: + if home_scope is not env and self.c_visibility == 'extern': env.add_imported_entry(self.entry, self.class_name, pos = self.pos) self.scope = scope = self.entry.type.scope if scope is not None: diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 03e67709..088cbadc 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -1221,7 +1221,7 @@ if VALUE is not None: def visit_CNameDeclaratorNode(self, node): if node.name in self.seen_vars_stack[-1]: entry = self.env_stack[-1].lookup(node.name) - if entry is None or not entry.extern: + if entry is None or entry.c_visibility != 'extern': warning(node.pos, "cdef variable '%s' declared after it is used" % node.name, 2) self.visitchildren(node) return node @@ -1743,8 +1743,6 @@ class DebugTransform(CythonTransform): self.nested_funcdefs.append(node) return node - # node.entry.extern = 1 - # node.entry.c_visibility = 'public' if node.py_func is None: pf_cname = '' else: diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 8c777900..4cafe0e2 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -1820,7 +1820,7 @@ def p_statement(s, ctx, first_statement = 0): s.level = ctx.level if ctx.api: if ctx.cdef_flag: - if ctx.extern: + if ctx.c_visibility == 'extern': error(pos, "Cannot combine 'api' with 'extern'") else: s.error("'api' not allowed with this statement") @@ -1851,7 +1851,7 @@ def p_statement(s, ctx, first_statement = 0): if ctx.level not in ('module', 'function', 'class', 'other'): s.error("class definition not allowed here") return p_class_statement(s, decorators) - elif s.sy == 'from' and ctx.extern: + elif s.sy == 'from' and ctx.c_visibility == 'extern': return p_cdef_extern_block(s, pos, ctx) elif s.sy == 'import' and ctx.cdef_flag: s.next() @@ -1864,7 +1864,7 @@ def p_statement(s, ctx, first_statement = 0): return p_property_decl(s) elif ctx.cdef_flag: if s.sy == 'IDENT' and s.systring == 'cppclass': - if not ctx.extern: + if ctx.c_visibility != 'extern': error(pos, "C++ classes need to be declared extern") return p_cpp_class_definition(s, pos, ctx) elif s.sy == 'IDENT' and s.systring in ("struct", "union", "enum", "packed"): @@ -2323,9 +2323,11 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, error(s.position(), "Empty declarator") name = "" cname = None + if name == 'Rectangle': + pass if cname is None and ctx.namespace is not None and nonempty: cname = ctx.namespace + "::" + name - if name == 'operator' and ctx.extern and nonempty: + if name == 'operator' and ctx.c_visibility == 'extern' and nonempty: op = s.sy if [1 for c in op if c in '+-*/<=>!%&|([^~,']: s.next() @@ -2489,7 +2491,7 @@ def p_cdef_extern_block(s, pos, ctx): include_file = p_string_literal(s, 'u')[2] ctx = ctx() ctx.cdef_flag = 1 - ctx.extern = 1 + ctx.c_visibility = 'extern' if s.systring == "namespace": s.next() ctx.namespace = p_string_literal(s, 'u')[2] @@ -2519,8 +2521,7 @@ def p_c_enum_definition(s, pos, ctx): items = [] # Work around overloading of the 'public' keyword. item_ctx = ctx() - if item_ctx.c_visibility == 'public': - item_ctx.c_visibility = 'public' + if item_ctx.c_visibility in ('public', 'extern'): item_ctx.visibility = 'public' else: item_ctx.c_visibility = 'public' @@ -2535,9 +2536,8 @@ def p_c_enum_definition(s, pos, ctx): s.expect_dedent() return Nodes.CEnumDefNode( pos, name = name, cname = cname, items = items, - typedef_flag = ctx.typedef_flag, extern = ctx.extern, - c_visibility = ctx.c_visibility, visibility = ctx.visibility, - in_pxd = ctx.level == 'module_pxd') + typedef_flag = ctx.typedef_flag, c_visibility = ctx.c_visibility, + visibility = ctx.visibility, in_pxd = ctx.level == 'module_pxd') def p_c_enum_line(s, ctx, items): _LOG.debug('p_c_enum_line(s=)' % (s.sy, s.systring)) @@ -2566,8 +2566,7 @@ def p_c_enum_item(s, ctx, items): value = p_test(s) items.append(Nodes.CEnumDefItemNode(pos, name = name, cname = cname, value = value, - extern = ctx.extern, visibility = ctx.visibility, - c_visibility = ctx.c_visibility, + c_visibility = ctx.c_visibility, visibility = ctx.visibility, in_pxd = ctx.level == 'module_pxd')) @@ -2611,7 +2610,6 @@ def p_c_struct_or_union_definition(s, pos, ctx): typedef_flag = ctx.typedef_flag, cdef_flag = ctx.cdef_flag, overridable = ctx.overridable, - extern = ctx.extern, c_visibility = ctx.c_visibility, visibility = ctx.visibility, in_pxd = ctx.level == 'module_pxd', @@ -2627,8 +2625,7 @@ def p_visibility(s, ctx): #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' + ctx.c_visibility = 'extern' # Need to restore/set default value for Python visibility? elif outer_scope and visibility not in ('readonly',): ctx.c_visibility = visibility @@ -2686,7 +2683,6 @@ def p_c_func_or_var_declaration(s, pos, ctx, decorators=None): result = Nodes.CFuncDefNode(pos, cdef_flag = ctx.cdef_flag, overridable = ctx.overridable, - extern = ctx.extern, c_visibility = ctx.c_visibility, visibility = ctx.visibility, base_type = base_type, @@ -2709,7 +2705,6 @@ def p_c_func_or_var_declaration(s, pos, ctx, decorators=None): declarators.append(declarator) s.expect_newline("Syntax error in C variable declaration") result = Nodes.CVarDefNode(pos, - extern = ctx.extern, c_visibility = ctx.c_visibility, visibility = ctx.visibility, api = ctx.api, @@ -2737,8 +2732,7 @@ def p_ctypedef_statement(s, pos, ctx): s.expect_newline("Syntax error in ctypedef statement") return Nodes.CTypeDefNode( pos, base_type = base_type, declarator = declarator, - extern = ctx.extern, visibility = ctx.visibility, - c_visibility = ctx.c_visibility, + c_visibility = ctx.c_visibility, visibility = ctx.visibility, in_pxd = ctx.level == 'module_pxd') def p_decorators(s): @@ -2847,7 +2841,7 @@ def p_c_class_definition(s, pos, ctx, decorators=None): s.next() module_path.append(class_name) class_name = p_ident(s) - if module_path and not ctx.extern: + if module_path and ctx.c_visibility != 'extern': error(pos, "Qualified class name only allowed for 'extern' C class") if module_path and s.sy == 'IDENT' and s.systring == 'as': s.next() @@ -2870,7 +2864,7 @@ def p_c_class_definition(s, pos, ctx, decorators=None): base_class_module = ".".join(base_class_path[:-1]) base_class_name = base_class_path[-1] if s.sy == '[': - if not (ctx.extern or ctx.c_visibility == 'public'): + if ctx.c_visibility not in ('extern', 'public'): error(s.position(), "Name options only allowed for 'public' or 'extern' C class") objstruct_name, typeobj_name = p_c_class_options(s) if s.sy == ':': @@ -2887,7 +2881,7 @@ def p_c_class_definition(s, pos, ctx, decorators=None): s.expect_newline("Syntax error in C class definition") doc = None body = None - if ctx.extern: + if ctx.c_visibility == 'extern': if not module_path: error(pos, "Module name required for 'extern' C class") if typeobj_name: @@ -2903,7 +2897,6 @@ def p_c_class_definition(s, pos, ctx, decorators=None): else: error(pos, "Invalid class visibility '%s'" % ctx.visibility_string()) return Nodes.CClassDefNode(pos, - extern = ctx.extern, c_visibility = ctx.c_visibility, visibility = ctx.visibility, typedef_flag = ctx.typedef_flag, @@ -3049,9 +3042,9 @@ def p_cpp_class_definition(s, pos, ctx): s.expect_indent() attributes = [] body_ctx = Ctx() - body_ctx.c_visibility = p_visibility(s, ctx) + #body_ctx = p_visibility(s, body_ctx) + body_ctx.c_visibility = ctx.c_visibility body_ctx.visibility = ctx.visibility - body_ctx.extern = ctx.extern body_ctx.templates = templates while s.sy != 'DEDENT': if s.systring == 'cppclass': @@ -3071,7 +3064,6 @@ def p_cpp_class_definition(s, pos, ctx): name = class_name, cname = cname, base_classes = base_classes, - extern = ctx.extern, c_visibility = ctx.c_visibility, visibility = ctx.visibility, in_pxd = ctx.level == 'module_pxd', diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index d7443c7f..cdf4304e 100755 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -683,7 +683,7 @@ class CNumericType(CType): self.scope = scope = Symtab.CClassScope( '', None, - extern=1) + c_visibility='extern') scope.parent_type = self scope.directives = {} binding = Binding(name = 'conjugate', cname = ' ') @@ -1187,7 +1187,7 @@ class CComplexType(CNumericType): self.scope = scope = Symtab.CClassScope( '', None, - extern=1) + c_visibility='extern') scope.parent_type = self scope.directives = {} binding = Binding(name = 'real', cname = 'real') @@ -2019,7 +2019,7 @@ class CStructOrUnionType(CType): self.to_py_function = None self._convert_code = False return False - forward_decl = not self.entry.extern + forward_decl = self.entry.c_visibility != 'extern' self._convert_code = StructUtilityCode(self, forward_decl) env.use_utility_code(self._convert_code) diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index cacc234f..5cec8f6b 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -336,7 +336,7 @@ class Scope(object): warning(pos, "'%s' is a reserved name in C." % binding.cname, -1) entries = self.entries if binding.name and binding.name in entries and not shadow: - if binding.extern: + if binding.c_visibility == 'extern': warning(pos, "'%s' redeclared " % binding.name, 0) elif binding.c_visibility != 'ignore': error(pos, "'%s' redeclared " % binding.name) @@ -393,7 +393,7 @@ class Scope(object): try: type = PyrexTypes.create_typedef_type( binding.name, base_type, binding.cname, - binding.extern) + binding.c_visibility == 'extern') except ValueError, e: error(pos, e.args[0]) type = PyrexTypes.error_type @@ -442,7 +442,7 @@ class Scope(object): def declare_cpp_class( self, binding, pos, scope, base_classes = (), templates = None): - if not binding.extern: + if binding.c_visibility != 'extern': error(pos, "C++ classes may only be extern") if binding.cname is None: binding.cname = binding.name @@ -495,8 +495,6 @@ class Scope(object): # `visibility`. If there is a difference, return a string # representing the conflicting `entry` visibility, otherwise # return an empty string. - if binding.extern != entry.extern: - return 'extern' if binding.c_visibility != entry.c_visibility: return entry.c_visibility if binding.visibility != entry.visibility: @@ -538,7 +536,7 @@ class Scope(object): else: binding.cname = self.mangle( Naming.var_prefix, binding.name) - if type.is_cpp_class and not binding.extern: + if type.is_cpp_class and binding.c_visibility != 'extern': constructor = type.scope.lookup(u'') if constructor is not None and PyrexTypes.best_match([], constructor.all_alternatives()) is None: error(pos, "C++ class must have a default constructor to be stack allocated") @@ -564,15 +562,15 @@ class Scope(object): # Add an entry for a Python function. entry = self.lookup_here(binding.name) if not allow_redefine or Options.disable_function_redefinition: - binding.extern = 1 - binding.c_visibility = binding.visibility = 'public' + binding.c_visibility = 'extern' + binding.visibility = 'public' return self._declare_pyfunction(binding, entry = entry, pos = pos) if entry: if entry.type.is_unspecified: entry.type = py_object_type elif entry.type is not py_object_type: - binding.extern = 1 - binding.c_visibility = binding.visibility = 'public' + binding.c_visibility = 'extern' + binding.visibility = 'public' return self._declare_pyfunction( binding, entry = entry, pos = pos) else: # declare entry stub @@ -617,7 +615,7 @@ class Scope(object): warning(pos, "Function '%s' previously declared as '%s'" % ( binding.name, vis_diff), 1) if not entry.type.same_as(type): - if binding.extern and entry.extern: + if binding.c_visibility == 'extern' and entry.c_visibility == 'extern': can_override = False if self.is_cpp(): can_override = True @@ -642,9 +640,9 @@ class Scope(object): else: entry = self.add_cfunction(binding, pos, type, modifiers) entry.func_cname = binding.cname - if in_pxd and not binding.extern: + if in_pxd and binding.c_visibility != 'extern': entry.defined_in_pxd = 1 - if not defining and not in_pxd and not binding.extern: + if not defining and not in_pxd and binding.c_visibility != 'extern': error(pos, "Non-extern C function '%s' declared but not defined" % binding.name) if defining: @@ -823,7 +821,7 @@ class BuiltinScope(Scope): binding.name, binding.cname, objstruct_cname) # WTK: TODO: visibility checking scope = CClassScope( - binding.name, outer_scope = None, extern = 1) + binding.name, outer_scope = None, c_visibility = 'extern') scope.directives = {} if binding.name == 'bool': scope.directives['final'] = True @@ -1057,7 +1055,7 @@ class ModuleScope(Scope): # global variable. entry = Scope.declare_var( self, binding, type, is_cdef = is_cdef, pos = pos) - if binding.c_visibility not in ('private', 'public'): + if binding.c_visibility not in ('private', 'public', 'extern'): error(pos, "Module-level variable cannot be declared %s" % binding.c_visibility) if not is_cdef: @@ -1092,7 +1090,7 @@ class ModuleScope(Scope): # If this is a non-extern typedef class, expose the typedef, but use # the non-typedef struct internally to avoid needing forward # declarations for anonymous structs. - if typedef_flag and not binding.extern: + if typedef_flag and binding.c_visibility != 'extern': if binding.c_visibility != 'public': warning(pos, "ctypedef only valid for public and extern classes", 2) objtypedef_cname = objstruct_cname @@ -1122,12 +1120,12 @@ class ModuleScope(Scope): if not entry or shadow: type = PyrexTypes.PyExtensionType( binding.name, typedef_flag, base_type, - is_external = binding.extern) + is_external = binding.c_visibility == 'extern') type.pos = pos type.buffer_defaults = buffer_defaults if objtypedef_cname is not None: type.objtypedef_cname = objtypedef_cname - if binding.extern: + if binding.c_visibility == 'extern': type.module_name = module_name else: type.module_name = self.qualified_name @@ -1138,7 +1136,7 @@ class ModuleScope(Scope): entry.is_cclass = True if objstruct_cname: type.objstruct_cname = objstruct_cname - elif binding.extern or binding.c_visibility != 'public': + elif binding.c_visibility != 'public': binding.cname = self.mangle( Naming.objstruct_prefix, binding.name) type.objstruct_cname = binding.cname @@ -1155,7 +1153,7 @@ class ModuleScope(Scope): scope = CClassScope( name = binding.name, outer_scope = self, - extern = binding.extern) + c_visibility = binding.c_visibility) if base_type and base_type.scope: scope.declare_inherited_c_attributes(base_type.scope) type.set_scope(scope) @@ -1251,7 +1249,7 @@ class ModuleScope(Scope): if not type.scope: error(entry.pos, "C class '%s' is declared but not defined" % name) # Generate typeobj_cname - if not entry.extern and not type.typeobj_cname: + if entry.c_visibility != 'extern' and not type.typeobj_cname: type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name) ## Generate typeptr_cname #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name) @@ -1288,9 +1286,7 @@ class ModuleScope(Scope): if debug_check_c_classes: print("...entry %s %s" % (entry.name, entry)) print("......type = ", entry.type) - print("......extern = ", entry.extern) - print("......binding.c_visibility = ", - entry.c_visibility) + print("......binding.c_visibility = ", entry.c_visibility) print("......binding.visibility = ", entry.python.binding.visibility) self.check_c_class(entry) @@ -1302,7 +1298,7 @@ class ModuleScope(Scope): if entry.is_cfunction: if (entry.defined_in_pxd and entry.scope is self - and not entry.extern + and entry.c_visibility != 'extern' and not entry.in_cinclude and not entry.is_implemented): error(entry.pos, "Non-extern C function '%s' declared but not defined" % name) @@ -1566,9 +1562,9 @@ class CClassScope(ClassScope): is_c_class_scope = 1 - def __init__(self, name, outer_scope, extern): + def __init__(self, name, outer_scope, c_visibility): ClassScope.__init__(self, name, outer_scope) - if not extern: + if c_visibility != 'extern': self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name) self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name) self.has_pyobject_attrs = 0 @@ -1600,7 +1596,7 @@ class CClassScope(ClassScope): binding.cname = binding.name if binding.c_visibility == 'private': binding.cname = c_safe_identifier(binding.cname) - if type.is_cpp_class and not binding.extern: + if type.is_cpp_class and binding.c_visibility != 'extern': error(pos, "C++ classes not allowed as members of an extension type, use a pointer or reference instead") entry = self.declare(binding, type, pos = pos) entry.is_variable = 1 @@ -1615,9 +1611,9 @@ class CClassScope(ClassScope): if binding.name == "__weakref__": error(pos, "Special attribute __weakref__ cannot be exposed to Python") if not type.is_pyobject: - #print 'XXX', binding.name, binding.extern, binding.c_visibility, binding.visibility, type.create_to_py_utility_code(self), type.__class__ ####### XXXXX BUG! (cimportfrom_T248) + #print 'XXX', binding.name, binding.c_visibility == 'extern', binding.c_visibility, binding.visibility, type.create_to_py_utility_code(self), type.__class__ ####### XXXXX BUG! (cimportfrom_T248) if not type.create_to_py_utility_code(self): - #print 'XXX', binding.name, binding.extern, binding.c_visibility, binding.visibility ####### XXXXX BUG! (cimportfrom_T248) + #print 'XXX', binding.name, binding.c_visibility == 'extern', binding.c_visibility, binding.visibility ####### XXXXX BUG! (cimportfrom_T248) error(pos, "C attribute of type '%s' cannot be accessed from Python" % type) return entry @@ -1643,7 +1639,7 @@ class CClassScope(ClassScope): if binding.name == "__new__": error(pos, "__new__ method of extension type will change semantics " "in a future version of Pyrex and Cython. Use __cinit__ instead.") - if not binding.extern: + if binding.c_visibility != 'extern': error(pos, "C class pyfunctions may only be extern") entry = self.declare_var(binding, type = py_object_type, pos = pos) special_sig = get_special_method_signature(binding.name) @@ -1685,7 +1681,6 @@ class CClassScope(ClassScope): if type.same_c_signature_as(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil: pass elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil: - binding.extern = 0 binding.c_visibility = 'ignore' binding.visibility = 'public' entry = self.add_cfunction(binding, pos, type, modifiers) @@ -1720,8 +1715,6 @@ class CClassScope(ClassScope): # overridden methods of builtin types still have their Python # equivalent that must be accessible to support bound methods binding.name = EncodedString(binding.name) - #entry = self.declare_cfunction(binding.name, type, None, binding.cname, visibility='extern', - # utility_code = utility_code) entry = self.declare_cfunction( binding, type=type, utility_code = utility_code) var_entry = Entry( @@ -1783,7 +1776,7 @@ class CppClassScope(Scope): def declare_var(self, binding, type, is_cdef = 0, allow_pyobject = 0, pos = None): - if not binding.extern: + if binding.c_visibility != 'extern': error(pos, "c++ variables must be 'extern'") # Add an entry for an attribute. if not binding.cname: @@ -1827,7 +1820,7 @@ class CppClassScope(Scope): def declare_cfunction(self, binding, type, defining = 0, in_pxd = 0, modifiers = (), utility_code = None, pos = None): - if not binding.extern: + if binding.c_visibility != 'extern': error(pos, "c++ cfunctions must be 'extern'") if binding.name == self.name.split('::')[-1] and binding.cname is None: self.check_base_default_constructor(pos) @@ -1855,8 +1848,7 @@ class CppClassScope(Scope): binding = Binding( name = base_entry.name, cname = base_entry.cname, - extern = True, - c_visibility = 'public') + c_visibility = 'extern') entry = self.declare( binding, type = base_entry.type) entry.is_variable = 1 diff --git a/Cython/Compiler/TypeSlots.py b/Cython/Compiler/TypeSlots.py index d6d44a9e..60bb7501 100644 --- a/Cython/Compiler/TypeSlots.py +++ b/Cython/Compiler/TypeSlots.py @@ -287,7 +287,7 @@ class GCDependentSlot(InternalMethodSlot): parent_type_scope = scope.parent_type.base_type.scope if scope.parent_scope is parent_type_scope.parent_scope: entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name) - if not entry.extern: + if entry.c_visibility != 'extern': return self.slot_code(parent_type_scope) return InternalMethodSlot.slot_code(self, scope) @@ -309,7 +309,7 @@ class ConstructorSlot(InternalMethodSlot): parent_type_scope = scope.parent_type.base_type.scope if scope.parent_scope is parent_type_scope.parent_scope: entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name) - if not entry.extern: + if entry.c_visibility != 'extern': return self.slot_code(parent_type_scope) return InternalMethodSlot.slot_code(self, scope) @@ -468,7 +468,7 @@ def get_base_slot_function(scope, slot): parent_slot = slot.slot_code(base_type.scope) if parent_slot != '0': entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name) - if not entry.extern: + if entry.c_visibility != 'extern': return parent_slot return None