Start with references
authorDanilo Freitas <dsurviver@gmail.com>
Sat, 17 Oct 2009 20:58:51 +0000 (17:58 -0300)
committerDanilo Freitas <dsurviver@gmail.com>
Sat, 17 Oct 2009 20:58:51 +0000 (17:58 -0300)
Cython/Compiler/Nodes.py
Cython/Compiler/Parsing.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Symtab.py

index 8b2d8afab766ac5209aac9209079719044bcf68b..e9c14eb2bed6d60373e169f09df16e396e223eb7 100644 (file)
@@ -475,7 +475,19 @@ class CPtrDeclaratorNode(CDeclaratorNode):
                 "Pointer base type cannot be a Python object")
         ptr_type = PyrexTypes.c_ptr_type(base_type)
         return self.base.analyse(ptr_type, env, nonempty = nonempty)
-        
+
+class CReferenceDeclaratorNode(CDeclaratorNode):
+    # base     CDeclaratorNode
+
+    child_attrs = ["base"]
+
+    def analyse(self, base_type, env, nonempty = 0):
+        if base_type.is_pyobject:
+            error(self.pos,
+                  "Reference base type cannot be a Python object")
+        ref_type = Pyrextypes.c_ref_type(base_type)
+        return self.base.analyse(ref_type, env, nonempty = nonempty)
+
 class CArrayDeclaratorNode(CDeclaratorNode):
     # base        CDeclaratorNode
     # dimension   ExprNode
index 6e7044f584017b37fbc0918b30e1b594a1d1c2c5..d5ee2f271b67b43f152a9ba28db8ab5da8f0a283 100644 (file)
@@ -1749,6 +1749,9 @@ 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':
@@ -1778,7 +1781,7 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
             elif s.sy not in ('*', '**', '['):
                 s.put_back('IDENT', name)
                 name = None
-    
+
     type_node = Nodes.CSimpleBaseTypeNode(pos, 
         name = name, module_path = module_path,
         is_basic_c_type = is_basic, signed = signed,
index 04eaee098ab1805499418ecc12cd8b5824051ce3..e01053807dbe90b28a3af3b9464c5048f8a010f6 100755 (executable)
@@ -39,6 +39,7 @@ class PyrexType(BaseType):
     #  is_array              boolean     Is a C array type
     #  is_ptr                boolean     Is a C pointer type
     #  is_null_ptr           boolean     Is the type of NULL
+    #  is_reference          boolean     Is a C reference type
     #  is_cfunction          boolean     Is a C function type
     #  is_struct_or_union    boolean     Is a C struct or union type
     #  is_struct             boolean     Is a C struct type
@@ -1018,6 +1019,37 @@ class CNullPtrType(CPtrType):
     is_null_ptr = 1
     
 
+
+class CReferenceType(CType):
+
+    is_reference = 1
+
+    def __init__(self, base_type):
+        self.base_type = base_type
+
+    def __repr__(self):
+        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)
+    
+    def declaration_code(self, entity_code, 
+            for_display = 0, dll_linkage = None, pyrex = 0):
+        #print "CPtrType.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
+    
+    def specialize(self, values):
+        base_type = self.base_type.specialize(values)
+        if base_type == self.base_type:
+            return self
+        else:
+            return CReferenceType(base_type)
+
 class CFuncType(CType):
     #  return_type      CType
     #  args             [CFuncTypeArg]
@@ -1890,6 +1922,15 @@ def c_ptr_type(base_type):
         return error_type
     else:
         return CPtrType(base_type)
+
+def c_ref_type(base_type):
+    # Construct a C reference type
+    if base_type is c_char_type:
+        return None #TODO (Danilo) create c_char_ref_type
+    elif base_type is error_type:
+        return error_type
+    else:
+        return CReferenceType(base_type)
         
 def Node_to_type(node, env):
     from ExprNodes import NameNode, AttributeNode, StringNode, error
index ec207487db74374d1fede0e423165ac18dfe9578..f5b29ed76f3706d655c08a9a5474269d0afd5271 100644 (file)
@@ -311,7 +311,8 @@ class Scope(object):
             if visibility == 'extern':
                 warning(pos, "'%s' redeclared " % name, 0)
             elif visibility != 'ignore':
-                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:
@@ -463,13 +464,14 @@ 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
-                    entry.overloaded_alternatives.append(
-                        self.add_cfunction(name, type, pos, cname, visibility, modifiers))
-                else:
-                    error(pos, "Function signature does not match previous declaration")
+                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")
         else:
             entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
             entry.func_cname = cname