Describe C++ references accurately.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Sun, 1 Apr 2012 20:47:11 +0000 (22:47 +0200)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Sun, 1 Apr 2012 20:47:11 +0000 (22:47 +0200)
retrace.py
specs/stdapi.py
specs/tags.vim [new file with mode: 0644]
specs/winapi.py
trace.py

index d6e8387..4100cf3 100644 (file)
@@ -39,6 +39,15 @@ class ConstRemover(stdapi.Rebuilder):
     def visitConst(self, const):
         return const.type
 
+    def visitAlias(self, alias):
+        type = self.visit(alias.type)
+        if type is alias.type:
+            return alias
+        return type
+
+    def visitReference(self, reference):
+        return reference.type
+
     def visitOpaque(self, opaque):
         return opaque
 
@@ -100,6 +109,9 @@ class ValueDeserializer(stdapi.Visitor):
     def visitLinearPointer(self, pointer, lvalue, rvalue):
         print '    %s = static_cast<%s>(retrace::toPointer(%s));' % (lvalue, pointer, rvalue)
 
+    def visitReference(self, reference, lvalue, rvalue):
+        self.visit(reference.type, lvalue, rvalue);
+
     def visitHandle(self, handle, lvalue, rvalue):
         #OpaqueValueDeserializer().visit(handle.type, lvalue, rvalue);
         self.visit(handle.type, lvalue, rvalue);
@@ -170,6 +182,9 @@ class SwizzledValueRegistrator(stdapi.Visitor):
         if pointer.size is not None:
             print r'    retrace::addRegion((%s).toUIntPtr(), %s, %s);' % (rvalue, lvalue, pointer.size)
 
+    def visitReference(self, reference, lvalue, rvalue):
+        pass
+    
     def visitHandle(self, handle, lvalue, rvalue):
         print '    %s __orig_result;' % handle.type
         OpaqueValueDeserializer().visit(handle.type, '__orig_result', rvalue);
index 30a42df..7aa60a1 100644 (file)
@@ -146,6 +146,17 @@ class LinearPointer(Type):
         return visitor.visitLinearPointer(self, *args, **kwargs)
 
 
+class Reference(Type):
+    '''C++ references.'''
+
+    def __init__(self, type):
+        Type.__init__(self, type.expr + " &", 'R' + type.tag)
+        self.type = type
+
+    def visit(self, visitor, *args, **kwargs):
+        return visitor.visitReference(self, *args, **kwargs)
+
+
 class Handle(Type):
 
     def __init__(self, name, type, range=None, key=None):
@@ -475,6 +486,9 @@ class Visitor:
     def visitLinearPointer(self, pointer, *args, **kwargs):
         raise NotImplementedError
 
+    def visitReference(self, reference, *args, **kwargs):
+        raise NotImplementedError
+
     def visitHandle(self, handle, *args, **kwargs):
         raise NotImplementedError
 
@@ -553,6 +567,10 @@ class Rebuilder(Visitor):
         type = self.visit(pointer.type)
         return LinearPointer(type, pointer.size)
 
+    def visitReference(self, reference):
+        type = self.visit(reference.type)
+        return Reference(type)
+
     def visitHandle(self, handle):
         type = self.visit(handle.type)
         return Handle(handle.name, type, range=handle.range, key=handle.key)
@@ -625,6 +643,9 @@ class Collector(Visitor):
     def visitLinearPointer(self, pointer):
         self.visit(pointer.type)
 
+    def visitReference(self, reference):
+        self.visit(reference.type)
+
     def visitHandle(self, handle):
         self.visit(handle.type)
 
diff --git a/specs/tags.vim b/specs/tags.vim
new file mode 100644 (file)
index 0000000..627aad3
--- /dev/null
@@ -0,0 +1,38 @@
+s/\<__deref_out_bcount\>([^)]*)/[out]/g
+s/\<__deref_out_bcount\>([^)]*)/[out]/g
+s/\<__deref_out_bcount\>([^)]*)/[out]/g
+s/\<__field_ecount\>([^)]*)//g
+s/\<__field_ecount\>([^)]*)//g
+s/\<__field_ecount\>([^)]*)//g
+s/\<__in\>//g
+s/\<__in_bcount\>([^)]*)//g
+s/\<__in_bcount\>([^)]*)//g
+s/\<__in_ecount\>([^)]*)//g
+s/\<__in_ecount\>([^)]*)//g
+s/\<__in_ecount\>([^)]*)//g
+s/\<__in_ecount_opt\>([^)]*)//g
+s/\<__in_ecount_opt\>([^)]*)//g
+s/\<__in_ecount\>([^)]*)//g
+s/\<__in_ecount\>([^)]*)//g
+s/\<__in_opt\>//g
+s/\<__inout\>//g
+s/\<__in_z\>//g
+s/\<__in_z_opt\>//g
+s/\<__maybenull\>//g
+s/\<__notnull\>//g
+s/\<__nullterminated\>//g
+s/\<__out\>/[out]/g
+s/\<__out_bcount\>([^)]*)/[out]/g
+s/\<__out_ecount\>([^)]*)/[out]/g
+s/\<__out_ecount\>([^)]*)/[out]/g
+s/\<__out_ecount\>([^)]*)/[out]/g
+s/\<__out_ecount_opt\>([^)]*)/[out]/g
+s/\<__out_ecount_opt\>([^)]*)/[out]/g
+s/\<__out_ecount_opt\>([^)]*)/[out]/g
+s/\<__out_ecount_opt\>([^)]*)/[out]/g
+s/\<__out_ecount\>([^)]*)/[out]/g
+s/\<__out_ecount_z\>([^)]*)/[out]/g
+s/\<__out_ecount_z\>([^)]*)/[out]/g
+s/\<__out_ecount_z\>([^)]*)/[out]/g
+s/\<__out_opt\>/[out]/g
+s/\<__out_z\>/[out]/g
index 017cf5f..c3acbb6 100644 (file)
@@ -87,16 +87,13 @@ GUID = Struct("GUID", [
 ])
 LPGUID = Pointer(GUID)
 
-#REFGUID = Alias("REFGUID", Pointer(GUID))
-REFGUID = Alias("REFGUID", GUID)
+REFGUID = Alias("REFGUID", Reference(GUID))
 
 IID = Alias("IID", GUID)
-#REFIID = Alias("REFIID", Pointer(IID))
-REFIID = Alias("REFIID", IID)
+REFIID = Alias("REFIID", Reference(IID))
 
 CLSID = Alias("CLSID", GUID)
-#REFCLSID = Alias("REFCLSID", Pointer(CLSID))
-REFCLSID = Alias("REFCLSID", CLSID)
+REFCLSID = Alias("REFCLSID", Reference(CLSID))
 
 LUID = Struct("LUID", [
     (DWORD, "LowPart"),
index 3f385fa..4f39129 100644 (file)
--- a/trace.py
+++ b/trace.py
@@ -114,6 +114,9 @@ class ComplexValueSerializer(stdapi.OnceVisitor):
     def visitHandle(self, handle):
         self.visit(handle.type)
 
+    def visitReference(self, reference):
+        self.visit(reference.type)
+
     def visitAlias(self, alias):
         self.visit(alias.type)
 
@@ -211,6 +214,9 @@ class ValueSerializer(stdapi.Visitor):
     def visitLinearPointer(self, pointer, instance):
         print '    trace::localWriter.writeOpaque((const void *)%s);' % instance
 
+    def visitReference(self, reference, instance):
+        self.visit(reference.type, instance)
+
     def visitHandle(self, handle, instance):
         self.visit(handle.type, instance)
 
@@ -274,6 +280,9 @@ class ValueWrapper(stdapi.Visitor):
     def visitLinearPointer(self, pointer, instance):
         pass
 
+    def visitReference(self, reference, instance):
+        self.visit(reference.type, instance)
+    
     def visitHandle(self, handle, instance):
         self.visit(handle.type, instance)