From 2d7dcc6225e71316d12632c12bb89f40323290d2 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Tue, 29 Apr 2008 22:13:11 -0700 Subject: [PATCH] Fix errors due to ambiguous names in type vs. variable namespace. I didn't realize how unclean the seperation between the two was, hopefully Dag's project will clean this up soon. --- Cython/Compiler/Nodes.py | 28 ++++++++++++++++------------ Cython/Compiler/Parsing.py | 31 ++++++++++++++++++++++++------- Cython/Compiler/Symtab.py | 4 ++-- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 40bf51eb..352ee77e 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -384,7 +384,11 @@ class CNameDeclaratorNode(CDeclaratorNode): child_attrs = [] - def analyse(self, base_type, env): + def analyse(self, base_type, env, nonempty = 0): + if nonempty and self.name == '': + # Must have mistaken the name for the type. + self.name = base_type.name + base_type = py_object_type self.type = base_type return self, base_type @@ -416,12 +420,12 @@ class CPtrDeclaratorNode(CDeclaratorNode): child_attrs = ["base"] - def analyse(self, base_type, env): + def analyse(self, base_type, env, nonempty = 0): if base_type.is_pyobject: error(self.pos, "Pointer base type cannot be a Python object") ptr_type = PyrexTypes.c_ptr_type(base_type) - return self.base.analyse(ptr_type, env) + return self.base.analyse(ptr_type, env, nonempty = nonempty) def analyse_expressions(self, env): self.base.analyse_expressions(env) @@ -435,7 +439,7 @@ class CArrayDeclaratorNode(CDeclaratorNode): child_attrs = ["base", "dimension"] - def analyse(self, base_type, env): + def analyse(self, base_type, env, nonempty = 0): if self.dimension: self.dimension.analyse_const_expression(env) if not self.dimension.type.is_int: @@ -453,7 +457,7 @@ class CArrayDeclaratorNode(CDeclaratorNode): error(self.pos, "Array element cannot be a function") array_type = PyrexTypes.c_array_type(base_type, size) - return self.base.analyse(array_type, env) + return self.base.analyse(array_type, env, nonempty = nonempty) class CFuncDeclaratorNode(CDeclaratorNode): @@ -470,10 +474,10 @@ class CFuncDeclaratorNode(CDeclaratorNode): overridable = 0 optional_arg_count = 0 - def analyse(self, return_type, env): + def analyse(self, return_type, env, nonempty = 0): func_type_args = [] for arg_node in self.args: - name_declarator, type = arg_node.analyse(env) + name_declarator, type = arg_node.analyse(env, nonempty = nonempty) name = name_declarator.name if name_declarator.cname: error(self.pos, @@ -570,10 +574,10 @@ class CArgDeclNode(Node): is_self_arg = 0 is_generic = 1 - def analyse(self, env): + def analyse(self, env, nonempty = 0): #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ### base_type = self.base_type.analyse(env) - return self.declarator.analyse(base_type, env) + return self.declarator.analyse(base_type, env, nonempty = nonempty) def annotate(self, code): if self.default: @@ -718,7 +722,7 @@ class CStructOrUnionDefNode(StatNode): def analyse_declarations(self, env): scope = None if self.attributes is not None: - scope = StructOrUnionScope() + scope = StructOrUnionScope(self.name) self.entry = env.declare_struct_or_union( self.name, self.kind, scope, self.typedef_flag, self.pos, self.cname, visibility = self.visibility) @@ -1039,7 +1043,7 @@ class CFuncDefNode(FuncDefNode): def analyse_declarations(self, env): base_type = self.base_type.analyse(env) - name_declarator, type = self.declarator.analyse(base_type, env) + name_declarator, type = self.declarator.analyse(base_type, env, self.body is not None) if not type.is_cfunction: error(self.pos, "Suite attached to non-function declaration") @@ -1101,7 +1105,7 @@ class CFuncDefNode(FuncDefNode): skip_dispatch = not is_module_scope or Options.lookup_module_cpdef c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1-is_module_scope:]], wrapper_call=skip_dispatch) return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call) - + def declare_arguments(self, env): for arg in self.type.args: if not arg.name: diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index dcb928da..b8ad781b 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -1405,13 +1405,13 @@ def p_suite(s, level = 'other', cdef_flag = 0, else: return body -def p_c_base_type(s, self_flag = 0): +def p_c_base_type(s, self_flag = 0, nonempty = 0): # If self_flag is true, this is the base type for the # self argument of a C method of an extension type. if s.sy == '(': return p_c_complex_base_type(s) else: - return p_c_simple_base_type(s, self_flag) + return p_c_simple_base_type(s, self_flag, nonempty = nonempty) def p_calling_convention(s): if s.sy == 'IDENT' and s.systring in calling_convention_words: @@ -1433,7 +1433,7 @@ def p_c_complex_base_type(s): return Nodes.CComplexBaseTypeNode(pos, base_type = base_type, declarator = declarator) -def p_c_simple_base_type(s, self_flag): +def p_c_simple_base_type(s, self_flag, nonempty): #print "p_c_simple_base_type: self_flag =", self_flag is_basic = 0 signed = 1 @@ -1449,7 +1449,24 @@ def p_c_simple_base_type(s, self_flag): s.next() else: name = 'int' - elif s.looking_at_type_name() or looking_at_dotted_name(s): + elif s.looking_at_type_name(): + name = s.systring + s.next() + if nonempty and s.sy != 'IDENT': + # Make sure this is not a declaration of a variable or + # function with the same name as a type. + if s.sy == '(': + s.next() + if s.sy == '*' or s.sy == '**': + s.put_back('(', '(') + else: + s.put_back('(', '(') + s.put_back('IDENT', name) + name = None + elif s.sy not in ('*', '**', '['): + s.put_back('IDENT', name) + name = None + elif looking_at_dotted_name(s): #print "p_c_simple_base_type: looking_at_type_name at", s.position() name = s.systring s.next() @@ -1683,7 +1700,7 @@ def p_c_arg_decl(s, in_pyfunc, cmethod_flag = 0, nonempty = 0, kw_only = 0): pos = s.position() not_none = 0 default = None - base_type = p_c_base_type(s, cmethod_flag) + base_type = p_c_base_type(s, cmethod_flag, nonempty = nonempty) declarator = p_c_declarator(s, nonempty = nonempty) if s.sy == 'not': s.next() @@ -1875,7 +1892,7 @@ def p_c_func_or_var_declaration(s, level, pos, visibility = 'private', api = 0, overridable = False): cmethod_flag = level in ('c_class', 'c_class_pxd') modifiers = p_c_modifiers(s) - base_type = p_c_base_type(s) + base_type = p_c_base_type(s, nonempty = 1) declarator = p_c_declarator(s, cmethod_flag = cmethod_flag, assignable = 1, nonempty = 1) declarator.overridable = overridable if s.sy == ':': @@ -1926,7 +1943,7 @@ def p_ctypedef_statement(s, level, visibility = 'private', api = 0): return p_c_struct_or_union_definition(s, pos, level, visibility, typedef_flag = 1) else: - base_type = p_c_base_type(s) + base_type = p_c_base_type(s, nonempty = 1) declarator = p_c_declarator(s, is_type = 1, nonempty = 1) s.expect_newline("Syntax error in ctypedef statement") return Nodes.CTypeDefNode(pos, diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 456445ec..b729e432 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -1075,8 +1075,8 @@ class LocalScope(Scope): class StructOrUnionScope(Scope): # Namespace of a C struct or union. - def __init__(self): - Scope.__init__(self, "?", None, None) + def __init__(self, name="?"): + Scope.__init__(self, name, None, None) def declare_var(self, name, type, pos, cname = None, visibility = 'private', is_cdef = 0, allow_pyobject = 0): -- 2.26.2