From: W. Trevor King Date: Thu, 3 Mar 2011 17:51:55 +0000 (-0500) Subject: Merge branch 'master' into cdef-enums-stucts-and-unions X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=cbc14c89a1f72aa2f07837730c9d69085943955e;p=cython.git Merge branch 'master' into cdef-enums-stucts-and-unions Conflicts: Cython/Compiler/Nodes.py Cython/Compiler/Symtab.py --- cbc14c89a1f72aa2f07837730c9d69085943955e diff --cc Cython/Compiler/Nodes.py index dbe743b5,609489f1..2615559e --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@@ -1066,11 -1060,11 +1072,13 @@@ class CppClassNode(CStructOrUnionDefNod template_types = None else: template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates] - self.entry = env.declare_cpp_class( - self.name, scope, self.pos, - self.cname, base_class_types, visibility = self.visibility, templates = template_types) + binding = Binding() + binding.pull(self) + self.entry = env.WTK_declare_cpp_class( + binding, scope = scope, base_classes = base_class_types, + templates = template_types, pos = self.pos) + if self.entry is None: + return self.entry.is_cpp_class = 1 if self.attributes is not None: if self.in_pxd and not env.in_cinclude: @@@ -3268,11 -3247,17 +3282,14 @@@ class CClassDefNode(ClassDefNode) defining = has_body and self.in_pxd, implementing = has_body and not self.in_pxd, module_name = self.module_name, - base_type = self.base_type, - objstruct_cname = self.objstruct_name, typeobj_cname = self.typeobj_name, - visibility = self.visibility, typedef_flag = self.typedef_flag, - api = self.api, - buffer_defaults = buffer_defaults, - shadow = self.shadow) + buffer_defaults = buffer_defaults, ++ shadow = self.shadow, + pos = self.pos) + if self.shadow: + home_scope.lookup(self.class_name).as_variable = self.entry - if home_scope is not env and self.visibility == 'extern': + if home_scope is not env and self.extern: env.add_imported_entry(self.class_name, self.entry, self.pos) self.scope = scope = self.entry.type.scope if scope is not None: diff --cc Cython/Compiler/Symtab.py index 6059f3d1,0d0e5760..04f66a42 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@@ -335,84 -329,56 +335,85 @@@ class Scope(object) # Return the module-level scope containing this scope. return self.outer_scope.builtin_scope() - def WTK_declare(self, binding, type, pos): - def declare(self, name, cname, type, pos, visibility, shadow = 0): ++ def WTK_declare(self, binding, type, shadow = 0, pos = None): # Create new entry, and add to dictionary if # name is not None. Reports a warning if already # declared. if type.is_buffer and not isinstance(self, LocalScope): error(pos, ERR_BUF_LOCALONLY) - if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname): + if (not self.in_cinclude and + binding.cname and re.match("^_[_A-Z]+$", binding.cname)): # See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names - warning(pos, "'%s' is a reserved name in C." % cname, -1) + warning(pos, "'%s' is a reserved name in C." % binding.cname, -1) entries = self.entries - if binding.name and binding.name in entries: - if name and name in entries and not shadow: - if visibility == 'extern': - warning(pos, "'%s' redeclared " % name, 0) - elif visibility != 'ignore': - error(pos, "'%s' redeclared " % name) - entry = Entry(name, cname, type, pos = pos) ++ if binding.name and binding.name in entries and not shadow: + if binding.extern: + warning(pos, "'%s' redeclared " % binding.name, 0) + elif binding.c_visibility != 'ignore': + error(pos, "'%s' redeclared " % binding.name) + entry = WTK_Entry(binding, type, pos = pos) entry.in_cinclude = self.in_cinclude - if name: - entry.qualified_name = self.qualify_name(name) -# if name in entries and self.is_cpp(): -# entries[name].overloaded_alternatives.append(entry) + if binding.name: + entry.qualified_name = self.qualify_name(binding.name) +# if binding.name in entries and self.is_cpp(): +# entries[binding.name].overloaded_alternatives.append( +# entry) # else: -# entries[name] = entry +# entries[binding.name] = entry - entries[binding.name] = entry + if not shadow: - entries[name] = entry ++ entries[binding.name] = entry entry.scope = self - entry.visibility = visibility return entry + def _WTK_setup(self, name, cname, visibility): + binding = Binding(name=name, cname=cname) + if visibility == 'extern': + binding.extern = 1 + binding.c_visibility = 'public' + elif self.outer_scope and visibility not in ('readonly',): + binding.c_visibility = visibility + else: + binding.visibility = visibility + if binding.visibility != 'private': + binding.c_visibility = 'public' + return binding + - def declare(self, name, cname, type, pos, visibility): ++ def declare(self, name, cname, type, pos, visibility, shadow = 0): + binding = self._WTK_setup(name, cname, visibility) - return self.WTK_declare(binding, type, pos) ++ return self.WTK_declare(binding, type, shadow = shadow, pos = pos) + def qualify_name(self, name): return EncodedString("%s.%s" % (self.qualified_name, name)) def declare_const(self, name, type, value, pos, cname = None, visibility = 'private'): + binding = self._WTK_setup(name, cname, visibility) - return self.WTK_declare_const(binding, type, value, pos) ++ return self.WTK_declare_const(binding, type, value, pos = pos) + + def WTK_declare_const(self, binding, + type, value, pos): # Add an entry for a named constant. - if not cname: - if self.in_cinclude or visibility == 'public': - cname = name + if not binding.cname: + if self.in_cinclude or binding.c_visibility == 'public': + binding.cname = binding.name else: - cname = self.mangle(Naming.enum_prefix, name) - entry = self.declare(name, cname, type, pos, visibility) + binding.cname = self.mangle( + Naming.enum_prefix, binding.name) - entry = self.WTK_declare(binding, type, pos) ++ entry = self.WTK_declare(binding, type, pos = pos) entry.is_const = 1 entry.value_node = value return entry def declare_type(self, name, type, pos, - cname = None, visibility = 'private', defining = 1): + cname = None, visibility = 'private', defining = 1, shadow = 0): + binding = self._WTK_setup(name, cname, visibility) - return self.WTK_declare_type(binding, type, defining, pos) ++ return self.WTK_declare_type(binding, type, defining, shadow, pos) + + def WTK_declare_type(self, binding, - type, defining = 1, pos = None): ++ type, defining = 1, shadow = 0, pos = None): # Add an entry for a type definition. - if not cname: - cname = name - entry = self.declare(name, cname, type, pos, visibility, shadow) + if not binding.cname: + binding.cname = binding.name - entry = self.WTK_declare(binding, type, pos) ++ entry = self.WTK_declare(binding, type, shadow = shadow, pos = pos) entry.is_type = 1 if defining: self.type_entries.append(entry) @@@ -492,32 -438,22 +493,33 @@@ def declare_cpp_class(self, name, scope, pos, cname = None, base_classes = [], visibility = 'extern', templates = None): - if visibility != 'extern': + binding = self._WTK_setup(name, cname, visibility) + return self.WTK_declare_cpp_class( + binding, pos, scope, base_classes, templates) + + def WTK_declare_cpp_class( + self, binding, + pos, scope, base_classes = (), templates = None): + if not binding.extern: error(pos, "C++ classes may only be extern") - if cname is None: - cname = name - entry = self.lookup_here(name) + if binding.cname is None: + binding.cname = binding.name + entry = self.lookup_here(binding.name) if not entry: type = PyrexTypes.CppClassType( - name, scope, cname, base_classes, templates = templates) - entry = self.declare_type(name, type, pos, cname, - visibility = visibility, defining = scope is not None) + binding.name, scope, binding.cname, base_classes, + templates = templates) + entry = self.WTK_declare_type( + binding, type, + defining = scope is not None, pos = pos) else: if not (entry.is_type and entry.type.is_cpp_class): - warning(pos, "'%s' redeclared " % binding.name, 0) - error(pos, "'%s' redeclared " % name) ++ error(pos, "'%s' redeclared " % binding.name) + return None elif scope and entry.type.scope: - warning(pos, "'%s' already defined (ignoring second definition)" % name, 0) + warning( + pos, "'%s' already defined (ignoring second definition)" % + binding.name, 0) else: if scope: entry.type.scope = scope @@@ -620,10 -512,9 +622,10 @@@ 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") - entry = self.WTK_declare(binding, type, pos) - entry = self.declare(name, cname, type, pos, visibility) ++ entry = self.WTK_declare(binding, type, pos = pos) entry.is_variable = 1 - self.control_flow.set_state((), (name, 'initialized'), False) + self.control_flow.set_state( + (), (binding.name, 'initialized'), False) return entry def declare_builtin(self, name, pos): @@@ -763,13 -617,8 +765,13 @@@ return entry def add_cfunction(self, name, type, pos, cname, visibility, modifiers): + binding = self._WTK_setup(name, cname, visibility) + return self.WTK_add_cfunction(binding, pos, type, modifiers) + + def WTK_add_cfunction(self, binding, pos, type, + modifiers = ()): # Add a C function entry without giving it a func_cname. - entry = self.WTK_declare(binding, type, pos) - entry = self.declare(name, cname, type, pos, visibility) ++ entry = self.WTK_declare(binding, type, pos = pos) entry.is_cfunction = 1 if modifiers: entry.func_modifiers = modifiers @@@ -871,11 -719,7 +873,11 @@@ class PreImportScope(Scope) Scope.__init__(self, Options.pre_import, None, None) def declare_builtin(self, name, pos): - entry = self.declare(name, name, py_object_type, pos, 'private') + binding = self._WTK_setup(name, name, visibility='private') + return self.WTK_declare_builtin(binding, pos) + + def WTK_declare_builtin(self, binding, pos): - entry = self.WTK_declare(binding, py_object_type, pos) ++ entry = self.WTK_declare(binding, py_object_type, pos = pos) entry.is_variable = True entry.is_pyglobal = True return entry @@@ -1233,18 -1030,7 +1235,19 @@@ class ModuleScope(Scope) def declare_c_class(self, name, pos, defining = 0, implementing = 0, module_name = None, base_type = None, objstruct_cname = None, typeobj_cname = None, visibility = 'private', typedef_flag = 0, api = 0, - buffer_defaults = None): + buffer_defaults = None, shadow = 0): + binding = self._WTK_setup(name, objstruct_cname, visibility) + binding.api = api + return self.WTK_declare_c_class( + binding, objstruct_cname, None, base_type, defining, implementing, - module_name, typeobj_cname, typedef_flag, buffer_defaults, pos) ++ module_name, typeobj_cname, typedef_flag, buffer_defaults, shadow, ++ pos) + + def WTK_declare_c_class( + self, binding, objstruct_cname = None, type=None, base_type=None, + defining = 0, implementing = 0, module_name = None, + typeobj_cname = None, typedef_flag = 0, buffer_defaults = None, - pos = None): ++ shadow = 0, pos = None): # 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. @@@ -1258,8 -1044,8 +1261,8 @@@ # # Look for previous declaration as a type # - entry = self.lookup_here(name) + entry = self.lookup_here(binding.name) - if entry: + if entry and not shadow: type = entry.type if not (entry.is_type and type.is_extension_type): entry = None # Will cause redeclaration and produce an error @@@ -1275,9 -1061,8 +1278,10 @@@ # # Make a new entry if needed # - if not entry: + if not entry or shadow: - type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type, visibility == 'extern') + type = PyrexTypes.PyExtensionType( - binding.name, typedef_flag, base_type, binding.extern) ++ binding.name, typedef_flag, base_type, ++ is_external = binding.extern) type.pos = pos type.buffer_defaults = buffer_defaults if objtypedef_cname is not None: @@@ -1286,10 -1071,9 +1290,10 @@@ type.module_name = module_name else: type.module_name = self.qualified_name - type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name) - entry = self.declare_type(name, type, pos, visibility = visibility, - defining = 0, shadow = shadow) + type.typeptr_cname = self.mangle( + Naming.typeptr_prefix, binding.name) + entry = self.WTK_declare_type( - binding, type, defining = 0, pos = pos) ++ binding, type, defining = 0, shadow = shadow, pos = pos) entry.is_cclass = True if objstruct_cname: type.objstruct_cname = objstruct_cname @@@ -1661,20 -1398,14 +1665,20 @@@ class StructOrUnionScope(Scope) def declare_var(self, name, type, pos, cname = None, visibility = 'private', is_cdef = 0, allow_pyobject = 0): + binding = self._WTK_setup(name, cname, visibility) + return self.WTK_declare_var( + binding, type, is_cdef, allow_pyobject, pos = pos) + + def WTK_declare_var(self, binding, type, + is_cdef = 0, allow_pyobject = 0, pos = None): # Add an entry for an attribute. - if not cname: - cname = name - if visibility == 'private': - cname = c_safe_identifier(cname) + if not binding.cname: + binding.cname = binding.name + if binding.c_visibility == 'private': + binding.cname = c_safe_identifier(binding.cname) if type.is_cfunction: type = PyrexTypes.CPtrType(type) - entry = self.WTK_declare(binding, type, pos) - entry = self.declare(name, cname, type, pos, visibility) ++ entry = self.WTK_declare(binding, type, pos = pos) entry.is_variable = 1 self.var_entries.append(entry) if type.is_pyobject and not allow_pyobject: @@@ -1812,17 -1520,17 +1816,17 @@@ class CClassScope(ClassScope) error(pos, "C attributes cannot be added in implementation part of" " extension type defined in a pxd") - if get_special_method_signature(name): + if get_special_method_signature(binding.name): error(pos, "The name '%s' is reserved for a special method." - % name) - if not cname: - cname = name - if visibility == 'private': - cname = c_safe_identifier(cname) - if type.is_cpp_class and visibility != 'extern': + % binding.name) + if not binding.cname: + 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: error(pos, "C++ classes not allowed as members of an extension type, use a pointer or reference instead") - entry = self.WTK_declare(binding, type, pos) - entry = self.declare(name, cname, type, pos, visibility) ++ entry = self.WTK_declare(binding, type, pos = pos) entry.is_variable = 1 self.var_entries.append(entry) if type.is_pyobject: @@@ -2038,18 -1695,12 +2042,18 @@@ class CppClassScope(Scope) def declare_var(self, name, type, pos, cname = None, visibility = 'extern', is_cdef = 0, allow_pyobject = 0): + binding = self._WTK_setup(name, cname, visibility) + return self.WTK_declare_var( + binding, type, is_cdef, allow_pyobject, pos = pos) + + def WTK_declare_var(self, binding, type, + is_cdef = 0, allow_pyobject = 0, pos = None): # Add an entry for an attribute. - if not cname: - cname = name + if not binding.cname: + binding.cname = binding.name if type.is_cfunction: type = PyrexTypes.CPtrType(type) - entry = self.WTK_declare(binding, type, pos) - entry = self.declare(name, cname, type, pos, visibility) ++ entry = self.WTK_declare(binding, type, pos = pos) entry.is_variable = 1 self.var_entries.append(entry) if type.is_pyobject and not allow_pyobject: