Merge Binding.extern back into Binding.c_visibility.
authorW. Trevor King <wking@drexel.edu>
Tue, 8 Mar 2011 21:42:27 +0000 (16:42 -0500)
committerW. Trevor King <wking@drexel.edu>
Tue, 8 Mar 2011 21:42:32 +0000 (16:42 -0500)
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.

Cython/Compiler/Binding.py
Cython/Compiler/Builtin.py
Cython/Compiler/Code.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/Parsing.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Symtab.py
Cython/Compiler/TypeSlots.py

index faa738e0332f83dfbbd85d32135d09d9ce807d1e..96eb58168f16f6ac5fa0088cf5cf4dd4b42f347d 100644 (file)
@@ -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)
index f8025314279d5179744d5aee3dc164595a2546cb..dd864cd7412dc877dc0b0e01e366589f9ff97be4 100644 (file)
@@ -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
index df25bea22a58daa855469b3b58194121c5f0a043..9bb3927f5fcc50143d690bea8e852c5ca30d45b3 100644 (file)
@@ -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))
index f5ee8126a9bacde09d70a33a28c52c4427e32263..024b74a510edd50584e8bb614129fc28f3b0ea6a 100755 (executable)
@@ -1245,7 +1245,7 @@ class NewExprNode(AtomicExprNode):
             return_type = PyrexTypes.CFuncType(type, [])
             return_type = PyrexTypes.CPtrType(return_type)
             binding = Binding(
-                name = u'<init>', extern = True, c_visibility = 'public')
+                name = u'<init>', c_visibility = 'extern')
             type.scope.declare_cfunction(
                 binding, type = return_type, pos = self.pos)
             constructor = type.scope.lookup(u'<init>')
index 9cef756a5bb9a79fdde1bec78064bb46e1e03523..80312ab2689652d51c676c5bd38ce7d06c06214a 100644 (file)
@@ -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(
index 1184030be808a6e3d7878b2a3abc7ef40c98e996..9178760caa871aa584dad5f78298395673f85903 100644 (file)
@@ -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:
index 03e67709a8cc87eea50c1d1712011cfb1e938737..088cbadcf27c41b60b8977c42c8f7b054aa5bc75 100644 (file)
@@ -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:
index 8c7779007978cb8d4f839a5b99545c2fa865db90..4cafe0e214cdf2080ff5650da1b9c953f42a740e 100644 (file)
@@ -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:%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',
index d7443c7f054e5dec4389e9cfb074ebea25b08fbc..cdf4304e95f9683af9249d42007661eeaef061f1 100755 (executable)
@@ -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)
index cacc234f95d7a79b9bc58da96595e51e2ed21688..5cec8f6b116e6b26202295458ccc3125140869fd 100644 (file)
@@ -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'<init>')
             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
index d6d44a9e9029a1e071bc6e8a490f15bb602877ff..60bb7501683b9ca662fa4b3c9c5e9d67f0320d00 100644 (file)
@@ -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