From: daniloaf@daniloaf-PC Date: Tue, 15 Dec 2009 03:08:56 +0000 (-0300) Subject: Overloaded functions with reference X-Git-Tag: 0.13.beta0~353^2~32^2 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=ad263d9be97633ef4361f0e50970c932a00dd22f;p=cython.git Overloaded functions with reference --- diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index e9c14eb2..1ed847a1 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -1,3 +1,4 @@ + # # Pyrex - Parse tree nodes # @@ -485,7 +486,7 @@ class CReferenceDeclaratorNode(CDeclaratorNode): if base_type.is_pyobject: error(self.pos, "Reference base type cannot be a Python object") - ref_type = Pyrextypes.c_ref_type(base_type) + ref_type = PyrexTypes.c_ref_type(base_type) return self.base.analyse(ref_type, env, nonempty = nonempty) class CArrayDeclaratorNode(CDeclaratorNode): diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index d5ee2f27..789429b7 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -1,3 +1,4 @@ + # cython: auto_cpdef=True # # Pyrex Parser @@ -1749,9 +1750,6 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None): if s.sy == 'IDENT' and s.systring in basic_c_type_names: name = s.systring s.next() - if s.sy == '&': - s.next() - #TODO (Danilo) else: name = 'int' if s.sy == 'IDENT' and s.systring == 'complex': @@ -1990,6 +1988,12 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, result = Nodes.CPtrDeclaratorNode(pos, base = Nodes.CPtrDeclaratorNode(pos, base = base)) + elif s.sy == '&' and Options.cplus: + s.next() + base = p_c_declarator(s, ctx, empty = empty, is_type = is_type, + cmethod_flag = cmethod_flag, + assignable = assignable, nonempty = nonempty) + result = Nodes.CReferenceDeclaratorNode(pos, base = base) else: rhs = None if s.sy == 'IDENT': diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index 01d8c6af..514805fe 100755 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -91,6 +91,7 @@ class PyrexType(BaseType): is_array = 0 is_ptr = 0 is_null_ptr = 0 + is_reference = 0 is_cfunction = 0 is_struct_or_union = 0 is_cpp_class = 0 @@ -1031,18 +1032,29 @@ class CReferenceType(CType): return "" % repr(self.base_type) def same_as_resolved_type(self, other_type): - return self.base_type.same_as(other_type.base_type) + return other_type.is_reference and self.base_type.same_as(other_type.base_type) def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): - #print "CPtrType.declaration_code: pointer to", self.base_type ### + #print "CReferenceType.declaration_code: pointer to", self.base_type ### return self.base_type.declaration_code( "&%s" % entity_code, for_display, dll_linkage, pyrex) def assignable_from_resolved_type(self, other_type): - return 0 #TODO (Danilo) implement this - + if other_type is error_type: + return 1 + if other_type.is_ptr: + if other_type.base_type == self.base_type: + return 1 + else: + pass + #should send a warning message: initialization from incompatible pointer type (in C/C++) + if other_type == self.base_type: + return 1 + else: #for now + return 0 + def specialize(self, values): base_type = self.base_type.specialize(values) if base_type == self.base_type: @@ -1797,6 +1809,9 @@ def is_promotion(type, other_type): return False def best_match(args, functions, pos): + '''Finds the best function to be called + Error if no function fits the call or an ambiguity is find (two or more possible functions)''' + #print functions actual_nargs = len(args) possibilities = [] bad_types = 0 @@ -1830,7 +1845,8 @@ def best_match(args, functions, pos): src_type = args[i].type dst_type = func_type.args[i].type if dst_type.assignable_from(src_type): - if src_type == dst_type: + #print src_type, src_type.is_pyobject, dst_type, dst_type.is_pyobject + if src_type == dst_type or (dst_type.is_reference and src_type == dst_type.base_type): pass # score 0 elif is_promotion(src_type, dst_type): score[2] += 1 @@ -1845,6 +1861,7 @@ def best_match(args, functions, pos): break else: possibilities.append((score, func)) # so we can sort it + #print score if len(possibilities): possibilities.sort() if len(possibilities) > 1 and possibilities[0][0] == possibilities[1][0]: diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index f5b29ed7..bc014479 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -1,3 +1,5 @@ + + # # Symbol Table # @@ -311,13 +313,16 @@ class Scope(object): if visibility == 'extern': warning(pos, "'%s' redeclared " % name, 0) elif visibility != 'ignore': - pass - #error(pos, "'%s' redeclared " % name) + #pass + error(pos, "'%s' redeclared " % name) entry = Entry(name, cname, type, pos = pos) entry.in_cinclude = self.in_cinclude if name: entry.qualified_name = self.qualify_name(name) - entries[name] = entry + if name not in entries: + entries[name] = entry + else: + entries[name].overloaded_alternatives.append(entry) entry.scope = self entry.visibility = visibility return entry @@ -464,14 +469,13 @@ class Scope(object): if visibility != 'private' and visibility != entry.visibility: warning(pos, "Function '%s' previously declared as '%s'" % (name, entry.visibility), 1) if not entry.type.same_as(type): - #if visibility == 'extern' and entry.visibility == 'extern': - #warning(pos, "Function signature does not match previous declaration", 1) + if visibility == 'extern' and entry.visibility == 'extern': + warning(pos, "Function signature does not match previous declaration", 1) #entry.type = type - temp = self.add_cfunction(name, type, pos, cname, visibility, modifiers) - entry.overloaded_alternatives.append(temp) - entry = temp - #else: - #error(pos, "Function signature does not match previous declaration") + entry.overloaded_alternatives.append( + self.add_cfunction(name, type, pos, cname, visibility, modifiers)) + else: + error(pos, "Function signature does not match previous declaration") else: entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers) entry.func_cname = cname @@ -485,12 +489,6 @@ class Scope(object): entry.is_implemented = True if modifiers: entry.func_modifiers = modifiers - #try: - # print entry.name, entry.type, entry.overloaded_alternatives - #except: - # pass - #if len(entry.overloaded_alternatives) > 0: - # print entry.name, entry.type, entry.overloaded_alternatives[0].type return entry def add_cfunction(self, name, type, pos, cname, visibility, modifiers):