Overloaded functions with reference
authordaniloaf@daniloaf-PC <none@none>
Tue, 15 Dec 2009 03:08:56 +0000 (00:08 -0300)
committerdaniloaf@daniloaf-PC <none@none>
Tue, 15 Dec 2009 03:08:56 +0000 (00:08 -0300)
Cython/Compiler/Nodes.py
Cython/Compiler/Parsing.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Symtab.py

index e9c14eb2bed6d60373e169f09df16e396e223eb7..1ed847a131974f6b3259dad4d7a4752399cbf52e 100644 (file)
@@ -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):
index d5ee2f271b67b43f152a9ba28db8ab5da8f0a283..789429b7017f25051c8c775a3a39ad89d1e6bb84 100644 (file)
@@ -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':
index 01d8c6af6dfb234e76060bbc1afb4f9856c65220..514805fed65faf6f410ed35b0ef5582c034f00d5 100755 (executable)
@@ -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 "<CReferenceType %s>" % 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]:
index f5b29ed76f3706d655c08a9a5474269d0afd5271..bc014479f1b74121da2743fea7509e6c99ca839b 100644 (file)
@@ -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):