]> git.cworth.org Git - apitrace/commitdiff
d3d10/d3d11: Complete union support.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Tue, 20 Nov 2012 17:03:43 +0000 (17:03 +0000)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Tue, 20 Nov 2012 17:03:43 +0000 (17:03 +0000)
retrace/retrace.py
specs/d3d10.py
specs/d3d10_1.py
specs/d3d11.py
specs/stdapi.py
wrappers/trace.py

index f1c5bb0ff810b4fd40702b7aa584a30e622561c6..1e39d42a19346d9f3b6be8f226a6c44bc88a8158 100644 (file)
@@ -96,16 +96,14 @@ class ValueAllocator(stdapi.Visitor):
         pass
 
     def visitPolymorphic(self, polymorphic, lvalue, rvalue):
-        if polymorphic.defaultType is None:
-            # FIXME
-            raise UnsupportedType
+        assert polymorphic.defaultType is not None
         self.visit(polymorphic.defaultType, lvalue, rvalue)
 
     def visitOpaque(self, opaque, lvalue, rvalue):
         pass
 
 
-class ValueDeserializer(stdapi.Visitor):
+class ValueDeserializer(stdapi.Visitor, stdapi.ExpanderMixin):
 
     def visitLiteral(self, literal, lvalue, rvalue):
         print '    %s = (%s).to%s();' % (lvalue, rvalue, literal.kind)
@@ -185,14 +183,32 @@ class ValueDeserializer(stdapi.Visitor):
         print '    const trace::Struct *%s = dynamic_cast<const trace::Struct *>(&%s);' % (tmp, rvalue)
         print '    assert(%s);' % (tmp)
         for i in range(len(struct.members)):
-            member_type, member_name = struct.members[i]
-            self.visit(member_type, '%s.%s' % (lvalue, member_name), '*%s->members[%s]' % (tmp, i))
+            member = struct.members[i]
+            self.visitMember(member, lvalue, '*%s->members[%s]' % (tmp, i))
 
     def visitPolymorphic(self, polymorphic, lvalue, rvalue):
         if polymorphic.defaultType is None:
-            # FIXME
-            raise UnsupportedType
-        self.visit(polymorphic.defaultType, lvalue, rvalue)
+            switchExpr = self.expand(polymorphic.switchExpr)
+            print r'    switch (%s) {' % switchExpr
+            for cases, type in polymorphic.iterSwitch():
+                for case in cases:
+                    print r'    %s:' % case
+                caseLvalue = lvalue
+                if type.expr is not None:
+                    caseLvalue = 'static_cast<%s>(%s)' % (type, caseLvalue)
+                print r'        {'
+                try:
+                    self.visit(type, caseLvalue, rvalue)
+                finally:
+                    print r'        }'
+                print r'        break;'
+            if polymorphic.defaultType is None:
+                print r'    default:'
+                print r'        retrace::warning(call) << "unexpected polymorphic case" << %s << "\n";' % (switchExpr,)
+                print r'        break;'
+            print r'    }'
+        else:
+            self.visit(polymorphic.defaultType, lvalue, rvalue)
     
     def visitOpaque(self, opaque, lvalue, rvalue):
         raise UnsupportedType
@@ -208,7 +224,7 @@ class OpaqueValueDeserializer(ValueDeserializer):
         print '    %s = static_cast<%s>(retrace::toPointer(%s));' % (lvalue, opaque, rvalue)
 
 
-class SwizzledValueRegistrator(stdapi.Visitor):
+class SwizzledValueRegistrator(stdapi.Visitor, stdapi.ExpanderMixin):
     '''Type visitor which will register (un)swizzled value pairs, to later be
     swizzled.'''
 
@@ -296,13 +312,11 @@ class SwizzledValueRegistrator(stdapi.Visitor):
         print '    assert(%s);' % (tmp,)
         print '    (void)%s;' % (tmp,)
         for i in range(len(struct.members)):
-            member_type, member_name = struct.members[i]
-            self.visit(member_type, '%s.%s' % (lvalue, member_name), '*%s->members[%s]' % (tmp, i))
+            member = struct.members[i]
+            self.visitMember(member, lvalue, '*%s->members[%s]' % (tmp, i))
     
     def visitPolymorphic(self, polymorphic, lvalue, rvalue):
-        if polymorphic.defaultType is None:
-            # FIXME
-            raise UnsupportedType
+        assert polymorphic.defaultType is not None
         self.visit(polymorphic.defaultType, lvalue, rvalue)
     
     def visitOpaque(self, opaque, lvalue, rvalue):
index 5e11adf8933380da1204e20accff474b8efc87b7..2c1c44c9197710048e9405da8d68c3797c62c56d 100644 (file)
@@ -386,12 +386,14 @@ D3D10_TEX2DMS_ARRAY_DSV = Struct("D3D10_TEX2DMS_ARRAY_DSV", [
 D3D10_DEPTH_STENCIL_VIEW_DESC = Struct("D3D10_DEPTH_STENCIL_VIEW_DESC", [
     (DXGI_FORMAT, "Format"),
     (D3D10_DSV_DIMENSION, "ViewDimension"),
-    (D3D10_TEX1D_DSV, "Texture1D"),
-    (D3D10_TEX1D_ARRAY_DSV, "Texture1DArray"),
-    (D3D10_TEX2D_DSV, "Texture2D"),
-    (D3D10_TEX2D_ARRAY_DSV, "Texture2DArray"),
-    (D3D10_TEX2DMS_DSV, "Texture2DMS"),
-    (D3D10_TEX2DMS_ARRAY_DSV, "Texture2DMSArray"),
+    (Union("{self}.ViewDimension", [
+        ("D3D10_DSV_DIMENSION_TEXTURE1D", D3D10_TEX1D_DSV, "Texture1D"),
+        ("D3D10_DSV_DIMENSION_TEXTURE1DARRAY", D3D10_TEX1D_ARRAY_DSV, "Texture1DArray"),
+        ("D3D10_DSV_DIMENSION_TEXTURE2D", D3D10_TEX2D_DSV, "Texture2D"),
+        ("D3D10_DSV_DIMENSION_TEXTURE2DARRAY", D3D10_TEX2D_ARRAY_DSV, "Texture2DArray"),
+        ("D3D10_DSV_DIMENSION_TEXTURE2DMS", D3D10_TEX2DMS_DSV, "Texture2DMS"),
+        ("D3D10_DSV_DIMENSION_TEXTURE2DMSARRAY", D3D10_TEX2DMS_ARRAY_DSV, "Texture2DMSArray"),
+    ]), None),
 ])
 
 D3D10_RTV_DIMENSION = Enum("D3D10_RTV_DIMENSION", [
@@ -449,14 +451,16 @@ D3D10_TEX3D_RTV = Struct("D3D10_TEX3D_RTV", [
 D3D10_RENDER_TARGET_VIEW_DESC = Struct("D3D10_RENDER_TARGET_VIEW_DESC", [
     (DXGI_FORMAT, "Format"),
     (D3D10_RTV_DIMENSION, "ViewDimension"),
-    (D3D10_BUFFER_RTV, "Buffer"),
-    (D3D10_TEX1D_RTV, "Texture1D"),
-    (D3D10_TEX1D_ARRAY_RTV, "Texture1DArray"),
-    (D3D10_TEX2D_RTV, "Texture2D"),
-    (D3D10_TEX2D_ARRAY_RTV, "Texture2DArray"),
-    (D3D10_TEX2DMS_RTV, "Texture2DMS"),
-    (D3D10_TEX2DMS_ARRAY_RTV, "Texture2DMSArray"),
-    (D3D10_TEX3D_RTV, "Texture3D"),
+    (Union("{self}.ViewDimension", [
+        ("D3D10_RTV_DIMENSION_BUFFER", D3D10_BUFFER_RTV, "Buffer"),
+        ("D3D10_RTV_DIMENSION_TEXTURE1D", D3D10_TEX1D_RTV, "Texture1D"),
+        ("D3D10_RTV_DIMENSION_TEXTURE1DARRAY", D3D10_TEX1D_ARRAY_RTV, "Texture1DArray"),
+        ("D3D10_RTV_DIMENSION_TEXTURE2D", D3D10_TEX2D_RTV, "Texture2D"),
+        ("D3D10_RTV_DIMENSION_TEXTURE2DARRAY", D3D10_TEX2D_ARRAY_RTV, "Texture2DArray"),
+        ("D3D10_RTV_DIMENSION_TEXTURE2DMS", D3D10_TEX2DMS_RTV, "Texture2DMS"),
+        ("D3D10_RTV_DIMENSION_TEXTURE2DMSARRAY", D3D10_TEX2DMS_ARRAY_RTV, "Texture2DMSArray"),
+        ("D3D10_RTV_DIMENSION_TEXTURE3D", D3D10_TEX3D_RTV, "Texture3D"),
+    ]), None),
 ])
 
 D3D10_SRV_DIMENSION = Enum("D3D10_SRV_DIMENSION", [
@@ -523,15 +527,17 @@ D3D10_TEXCUBE_SRV = Struct("D3D10_TEXCUBE_SRV", [
 D3D10_SHADER_RESOURCE_VIEW_DESC = Struct("D3D10_SHADER_RESOURCE_VIEW_DESC", [
     (DXGI_FORMAT, "Format"),
     (D3D10_SRV_DIMENSION, "ViewDimension"),
-    (D3D10_BUFFER_SRV, "Buffer"),
-    (D3D10_TEX1D_SRV, "Texture1D"),
-    (D3D10_TEX1D_ARRAY_SRV, "Texture1DArray"),
-    (D3D10_TEX2D_SRV, "Texture2D"),
-    (D3D10_TEX2D_ARRAY_SRV, "Texture2DArray"),
-    (D3D10_TEX2DMS_SRV, "Texture2DMS"),
-    (D3D10_TEX2DMS_ARRAY_SRV, "Texture2DMSArray"),
-    (D3D10_TEX3D_SRV, "Texture3D"),
-    (D3D10_TEXCUBE_SRV, "TextureCube"),
+    (Union("{self}.ViewDimension", [
+        ("D3D10_SRV_DIMENSION_BUFFER", D3D10_BUFFER_SRV, "Buffer"),
+        ("D3D10_SRV_DIMENSION_TEXTURE1D", D3D10_TEX1D_SRV, "Texture1D"),
+        ("D3D10_SRV_DIMENSION_TEXTURE1DARRAY", D3D10_TEX1D_ARRAY_SRV, "Texture1DArray"),
+        ("D3D10_SRV_DIMENSION_TEXTURE2D", D3D10_TEX2D_SRV, "Texture2D"), 
+        ("D3D10_SRV_DIMENSION_TEXTURE2DARRAY", D3D10_TEX2D_ARRAY_SRV, "Texture2DArray"),
+        ("D3D10_SRV_DIMENSION_TEXTURE2DMS", D3D10_TEX2DMS_SRV, "Texture2DMS"),
+        ("D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY", D3D10_TEX2DMS_ARRAY_SRV, "Texture2DMSArray"),
+        ("D3D10_SRV_DIMENSION_TEXTURE3D", D3D10_TEX3D_SRV, "Texture3D"),
+        ("D3D10_SRV_DIMENSION_TEXTURECUBE", D3D10_TEXCUBE_SRV, "TextureCube"),
+    ]), None),
 ])
 
 D3D10_BOX = Struct("D3D10_BOX", [
index 73d798ec4405cb3e98288035bcbc6952eb2f5611..b107e5645af77964ae6a737cc895e28edf225af3 100644 (file)
@@ -76,16 +76,18 @@ D3D10_TEXCUBE_ARRAY_SRV1 = Struct("D3D10_TEXCUBE_ARRAY_SRV1", [
 D3D10_SHADER_RESOURCE_VIEW_DESC1 = Struct("D3D10_SHADER_RESOURCE_VIEW_DESC1", [
     (DXGI_FORMAT, "Format"),
     (D3D10_SRV_DIMENSION1, "ViewDimension"),
-    (D3D10_BUFFER_SRV, "Buffer"),
-    (D3D10_TEX1D_SRV, "Texture1D"),
-    (D3D10_TEX1D_ARRAY_SRV, "Texture1DArray"),
-    (D3D10_TEX2D_SRV, "Texture2D"),
-    (D3D10_TEX2D_ARRAY_SRV, "Texture2DArray"),
-    (D3D10_TEX2DMS_SRV, "Texture2DMS"),
-    (D3D10_TEX2DMS_ARRAY_SRV, "Texture2DMSArray"),
-    (D3D10_TEX3D_SRV, "Texture3D"),
-    (D3D10_TEXCUBE_SRV, "TextureCube"),
-    (D3D10_TEXCUBE_ARRAY_SRV1, "TextureCubeArray"),
+    (Union("{self}.ViewDimension", [
+        ("D3D10_1_SRV_DIMENSION_BUFFER", D3D10_BUFFER_SRV, "Buffer"),
+        ("D3D10_1_SRV_DIMENSION_TEXTURE1D", D3D10_TEX1D_SRV, "Texture1D"),
+        ("D3D10_1_SRV_DIMENSION_TEXTURE1DARRAY", D3D10_TEX1D_ARRAY_SRV, "Texture1DArray"),
+        ("D3D10_1_SRV_DIMENSION_TEXTURE2D", D3D10_TEX2D_SRV, "Texture2D"), 
+        ("D3D10_1_SRV_DIMENSION_TEXTURE2DARRAY", D3D10_TEX2D_ARRAY_SRV, "Texture2DArray"),
+        ("D3D10_1_SRV_DIMENSION_TEXTURE2DMS", D3D10_TEX2DMS_SRV, "Texture2DMS"),
+        ("D3D10_1_SRV_DIMENSION_TEXTURE2DMSARRAY", D3D10_TEX2DMS_ARRAY_SRV, "Texture2DMSArray"),
+        ("D3D10_1_SRV_DIMENSION_TEXTURE3D", D3D10_TEX3D_SRV, "Texture3D"),
+        ("D3D10_1_SRV_DIMENSION_TEXTURECUBE", D3D10_TEXCUBE_SRV, "TextureCube"),
+        ("D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY", D3D10_TEXCUBE_ARRAY_SRV1, "TextureCubeArray"),
+    ]), None),
 ])
 
 ID3D10ShaderResourceView1 = Interface("ID3D10ShaderResourceView1", ID3D10ShaderResourceView)
@@ -95,7 +97,7 @@ ID3D10ShaderResourceView1.methods += [
 
 ID3D10Device1 = Interface("ID3D10Device1", ID3D10Device)
 ID3D10Device1.methods += [
-    StdMethod(HRESULT, "CreateShaderResourceView1", [(ObjPointer(ID3D10Resource), "pResource"), Out(Pointer(Const(D3D10_SHADER_RESOURCE_VIEW_DESC1)), "pDesc"), Out(Pointer(ObjPointer(ID3D10ShaderResourceView1)), "ppSRView")]),
+    StdMethod(HRESULT, "CreateShaderResourceView1", [(ObjPointer(ID3D10Resource), "pResource"), (Pointer(Const(D3D10_SHADER_RESOURCE_VIEW_DESC1)), "pDesc"), Out(Pointer(ObjPointer(ID3D10ShaderResourceView1)), "ppSRView")]),
     StdMethod(HRESULT, "CreateBlendState1", [(Pointer(Const(D3D10_BLEND_DESC1)), "pBlendStateDesc"), Out(Pointer(ObjPointer(ID3D10BlendState1)), "ppBlendState")]),
     StdMethod(D3D10_FEATURE_LEVEL1, "GetFeatureLevel", [], sideeffects=False),
 ]
index 6592bcbf7d48778662f9dd7f8623994f8877230f..f0e1e274a859b3ea6584eb24b6935dbf1a5223fd 100644 (file)
@@ -615,18 +615,18 @@ D3D11_TEX2DMS_ARRAY_SRV = Struct("D3D11_TEX2DMS_ARRAY_SRV", [
 D3D11_SHADER_RESOURCE_VIEW_DESC = Struct("D3D11_SHADER_RESOURCE_VIEW_DESC", [
     (DXGI_FORMAT, "Format"),
     (D3D11_SRV_DIMENSION, "ViewDimension"),
-    (Union(None, [
-        (D3D11_BUFFER_SRV, "Buffer"),
-        (D3D11_TEX1D_SRV, "Texture1D"),
-        (D3D11_TEX1D_ARRAY_SRV, "Texture1DArray"),
-        (D3D11_TEX2D_SRV, "Texture2D"), 
-        (D3D11_TEX2D_ARRAY_SRV, "Texture2DArray"),
-        (D3D11_TEX2DMS_SRV, "Texture2DMS"),
-        (D3D11_TEX2DMS_ARRAY_SRV, "Texture2DMSArray"),
-        (D3D11_TEX3D_SRV, "Texture3D"),
-        (D3D11_TEXCUBE_SRV, "TextureCube"),
-        (D3D11_TEXCUBE_ARRAY_SRV, "TextureCubeArray"),
-        (D3D11_BUFFEREX_SRV, "BufferEx"),
+    (Union("{self}.ViewDimension", [
+        ("D3D11_SRV_DIMENSION_BUFFER", D3D11_BUFFER_SRV, "Buffer"),
+        ("D3D11_SRV_DIMENSION_TEXTURE1D", D3D11_TEX1D_SRV, "Texture1D"),
+        ("D3D11_SRV_DIMENSION_TEXTURE1DARRAY", D3D11_TEX1D_ARRAY_SRV, "Texture1DArray"),
+        ("D3D11_SRV_DIMENSION_TEXTURE2D", D3D11_TEX2D_SRV, "Texture2D"), 
+        ("D3D11_SRV_DIMENSION_TEXTURE2DARRAY", D3D11_TEX2D_ARRAY_SRV, "Texture2DArray"),
+        ("D3D11_SRV_DIMENSION_TEXTURE2DMS", D3D11_TEX2DMS_SRV, "Texture2DMS"),
+        ("D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY", D3D11_TEX2DMS_ARRAY_SRV, "Texture2DMSArray"),
+        ("D3D11_SRV_DIMENSION_TEXTURE3D", D3D11_TEX3D_SRV, "Texture3D"),
+        ("D3D11_SRV_DIMENSION_TEXTURECUBE", D3D11_TEXCUBE_SRV, "TextureCube"),
+        ("D3D11_SRV_DIMENSION_TEXTURECUBEARRAY", D3D11_TEXCUBE_ARRAY_SRV, "TextureCubeArray"),
+        ("D3D11_SRV_DIMENSION_BUFFEREX", D3D11_BUFFEREX_SRV, "BufferEx"),
     ]), None),
 ])
 
@@ -677,7 +677,7 @@ D3D11_TEX3D_RTV = Struct("D3D11_TEX3D_RTV", [
 D3D11_RENDER_TARGET_VIEW_DESC = Struct("D3D11_RENDER_TARGET_VIEW_DESC", [
     (DXGI_FORMAT, "Format"),
     (D3D11_RTV_DIMENSION, "ViewDimension"),
-    (Union_("{self}.ViewDimension", [
+    (Union("{self}.ViewDimension", [
         ("D3D11_RTV_DIMENSION_BUFFER", D3D11_BUFFER_RTV, "Buffer"),
         ("D3D11_RTV_DIMENSION_TEXTURE1D", D3D11_TEX1D_RTV, "Texture1D"),
         ("D3D11_RTV_DIMENSION_TEXTURE1DARRAY", D3D11_TEX1D_ARRAY_RTV, "Texture1DArray"),
@@ -731,13 +731,13 @@ D3D11_DEPTH_STENCIL_VIEW_DESC = Struct("D3D11_DEPTH_STENCIL_VIEW_DESC", [
     (DXGI_FORMAT, "Format"),
     (D3D11_DSV_DIMENSION, "ViewDimension"),
     (D3D11_DSV_FLAG, "Flags"),
-    (Union(None, [
-        (D3D11_TEX1D_DSV, "Texture1D"),
-        (D3D11_TEX1D_ARRAY_DSV, "Texture1DArray"),
-        (D3D11_TEX2D_DSV, "Texture2D"),
-        (D3D11_TEX2D_ARRAY_DSV, "Texture2DArray"),
-        (D3D11_TEX2DMS_DSV, "Texture2DMS"),
-        (D3D11_TEX2DMS_ARRAY_DSV, "Texture2DMSArray"),
+    (Union("{self}.ViewDimension", [
+        ("D3D11_DSV_DIMENSION_TEXTURE1D", D3D11_TEX1D_DSV, "Texture1D"),
+        ("D3D11_DSV_DIMENSION_TEXTURE1DARRAY", D3D11_TEX1D_ARRAY_DSV, "Texture1DArray"),
+        ("D3D11_DSV_DIMENSION_TEXTURE2D", D3D11_TEX2D_DSV, "Texture2D"),
+        ("D3D11_DSV_DIMENSION_TEXTURE2DARRAY", D3D11_TEX2D_ARRAY_DSV, "Texture2DArray"),
+        ("D3D11_DSV_DIMENSION_TEXTURE2DMS", D3D11_TEX2DMS_DSV, "Texture2DMS"),
+        ("D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY", D3D11_TEX2DMS_ARRAY_DSV, "Texture2DMSArray"),
     ]), None),
 ])
 
@@ -786,13 +786,13 @@ D3D11_TEX3D_UAV = Struct("D3D11_TEX3D_UAV", [
 D3D11_UNORDERED_ACCESS_VIEW_DESC = Struct("D3D11_UNORDERED_ACCESS_VIEW_DESC", [
     (DXGI_FORMAT, "Format"),
     (D3D11_UAV_DIMENSION, "ViewDimension"),
-    (Union(None, [
-        (D3D11_BUFFER_UAV, "Buffer"),
-        (D3D11_TEX1D_UAV, "Texture1D"),
-        (D3D11_TEX1D_ARRAY_UAV, "Texture1DArray"),
-        (D3D11_TEX2D_UAV, "Texture2D"),
-        (D3D11_TEX2D_ARRAY_UAV, "Texture2DArray"),
-        (D3D11_TEX3D_UAV, "Texture3D"),
+    (Union("{self}.ViewDimension", [
+        ("D3D11_UAV_DIMENSION_BUFFER", D3D11_BUFFER_UAV, "Buffer"),
+        ("D3D11_UAV_DIMENSION_TEXTURE1D", D3D11_TEX1D_UAV, "Texture1D"),
+        ("D3D11_UAV_DIMENSION_TEXTURE1DARRAY", D3D11_TEX1D_ARRAY_UAV, "Texture1DArray"),
+        ("D3D11_UAV_DIMENSION_TEXTURE2D", D3D11_TEX2D_UAV, "Texture2D"),
+        ("D3D11_UAV_DIMENSION_TEXTURE2DARRAY", D3D11_TEX2D_ARRAY_UAV, "Texture2DArray"),
+        ("D3D11_UAV_DIMENSION_TEXTURE3D", D3D11_TEX3D_UAV, "Texture3D"),
     ]), None),
 ])
 
index 4b4808e458641173cf0b350a06a91cc715f85881..930bb82b9be8a9eee0088178b9bda22bafb2fa00 100644 (file)
@@ -292,35 +292,13 @@ class Struct(Type):
         Struct.__id += 1
 
         self.name = name
-        self.members = []
-
-        # Eliminate anonymous unions
-        for type, name in members:
-            if name is not None or isinstance(type, Polymorphic):
-                self.members.append((type, name))
-            else:
-                assert isinstance(type, Union)
-                assert type.name is None
-                self.members.extend(type.members)
+        self.members = members
 
     def visit(self, visitor, *args, **kwargs):
         return visitor.visitStruct(self, *args, **kwargs)
 
 
-class Union(Type):
-
-    __id = 0
-
-    def __init__(self, name, members):
-        Type.__init__(self, name)
-
-        self.id = Union.__id
-        Union.__id += 1
-
-        self.name = name
-        self.members = members
-
-def Union_(kindExpr, kindTypes, contextLess=True):
+def Union(kindExpr, kindTypes, contextLess=True):
     switchTypes = []
     for kindCase, kindType, kindMemberName in kindTypes:
         switchType = Struct(None, [(kindType, kindMemberName)])
@@ -855,6 +833,49 @@ class Collector(Traverser):
         self.types.append(type)
 
 
+class ExpanderMixin:
+    '''Mixin class that provides a bunch of methods to expand C expressions
+    from the specifications.'''
+
+    __structs = None
+    __indices = None
+
+    def expand(self, expr):
+        # Expand a C expression, replacing certain variables
+        if not isinstance(expr, basestring):
+            return expr
+        variables = {}
+
+        if self.__structs is not None:
+            variables['self'] = '(%s)' % self.__structs[0]
+        if self.__indices is not None:
+            variables['i'] = self.__indices[0]
+
+        expandedExpr = expr.format(**variables)
+        if expandedExpr != expr and 0:
+            sys.stderr.write("  %r -> %r\n" % (expr, expandedExpr))
+        return expandedExpr
+
+    def visitMember(self, member, structInstance, *args, **kwargs):
+        memberType, memberName = member
+        if memberName is None:
+            # Anonymous structure/union member
+            memberInstance = structInstance
+        else:
+            memberInstance = '(%s).%s' % (structInstance, memberName)
+        self.__structs = (structInstance, self.__structs)
+        try:
+            return self.visit(memberType, memberInstance, *args, **kwargs)
+        finally:
+            _, self.__structs = self.__structs
+
+    def visitElement(self, elementIndex, elementType, *args, **kwargs):
+        self.__indices = (elementIndex, self.__indices)
+        try:
+            return self.visit(elementType, *args, **kwargs)
+        finally:
+            _, self.__indices = self.__indices
+
 
 class Module:
     '''A collection of functions.'''
index 34f4c6930bce7717f60f4ee45aa12f24eafb96ab..506570dca018ed9bc0dde652940cd33babd83fb6 100644 (file)
@@ -40,44 +40,6 @@ def getWrapperInterfaceName(interface):
 
 
 
-class ExpanderMixin:
-    '''Mixin class that provides a bunch of methods to expand C expressions
-    from the specifications.'''
-
-    __structs = None
-    __indices = None
-
-    def expand(self, expr):
-        # Expand a C expression, replacing certain variables
-        if not isinstance(expr, basestring):
-            return expr
-        variables = {}
-
-        if self.__structs is not None:
-            variables['self'] = '(%s)' % self.__structs[0]
-        if self.__indices is not None:
-            variables['i'] = self.__indices[0]
-
-        expandedExpr = expr.format(**variables)
-        if expandedExpr != expr and 0:
-            sys.stderr.write("  %r -> %r\n" % (expr, expandedExpr))
-        return expandedExpr
-
-    def visitMember(self, structInstance, member_type, *args, **kwargs):
-        self.__structs = (structInstance, self.__structs)
-        try:
-            return self.visit(member_type, *args, **kwargs)
-        finally:
-            _, self.__structs = self.__structs
-
-    def visitElement(self, element_index, element_type, *args, **kwargs):
-        self.__indices = (element_index, self.__indices)
-        try:
-            return self.visit(element_type, *args, **kwargs)
-        finally:
-            _, self.__indices = self.__indices
-
-
 class ComplexValueSerializer(stdapi.OnceVisitor):
     '''Type visitors which generates serialization functions for
     complex types.
@@ -188,7 +150,7 @@ class ComplexValueSerializer(stdapi.OnceVisitor):
         print
 
 
-class ValueSerializer(stdapi.Visitor, ExpanderMixin):
+class ValueSerializer(stdapi.Visitor, stdapi.ExpanderMixin):
     '''Visitor which generates code to serialize any type.
     
     Simple types are serialized inline here, whereas the serialization of
@@ -220,13 +182,8 @@ class ValueSerializer(stdapi.Visitor, ExpanderMixin):
 
     def visitStruct(self, struct, instance):
         print '    trace::localWriter.beginStruct(&_struct%s_sig);' % (struct.tag,)
-        for type, name in struct.members:
-            if name is None:
-                # Anonymous structure/union member
-                memberInstance = instance
-            else:
-                memberInstance = '(%s).%s' % (instance, name)
-            self.visitMember(instance, type, memberInstance)
+        for member in struct.members:
+            self.visitMember(member, instance)
         print '    trace::localWriter.endStruct();'
 
     def visitArray(self, array, instance):
@@ -294,7 +251,8 @@ class ValueSerializer(stdapi.Visitor, ExpanderMixin):
         if polymorphic.contextLess:
             print '    _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switchExpr, instance)
         else:
-            print '    switch (%s) {' % self.expand(polymorphic.switchExpr)
+            switchExpr = self.expand(polymorphic.switchExpr)
+            print '    switch (%s) {' % switchExpr
             for cases, type in polymorphic.iterSwitch():
                 for case in cases:
                     print '    %s:' % case
@@ -303,6 +261,11 @@ class ValueSerializer(stdapi.Visitor, ExpanderMixin):
                     caseInstance = 'static_cast<%s>(%s)' % (type, caseInstance)
                 self.visit(type, caseInstance)
                 print '        break;'
+            if polymorphic.defaultType is None:
+                print r'    default:'
+                print r'        os::log("apitrace: warning: %%s: unexpected polymorphic case %%i\n", __FUNCTION__, (int)%s);' % (switchExpr,)
+                print r'        trace::localWriter.writeNull();'
+                print r'        break;'
             print '    }'
 
 
@@ -322,7 +285,7 @@ class WrapDecider(stdapi.Traverser):
         self.needsWrapping = True
 
 
-class ValueWrapper(stdapi.Traverser, ExpanderMixin):
+class ValueWrapper(stdapi.Traverser, stdapi.ExpanderMixin):
     '''Type visitor which will generate the code to wrap an instance.
     
     Wrapping is necessary mostly for interfaces, however interface pointers can
@@ -330,13 +293,8 @@ class ValueWrapper(stdapi.Traverser, ExpanderMixin):
     '''
 
     def visitStruct(self, struct, instance):
-        for type, name in struct.members:
-            if name is None:
-                # Anonymous structure/union member
-                memberInstance = instance
-            else:
-                memberInstance = '(%s).%s' % (instance, name)
-            self.visitMember(instance, type, memberInstance)
+        for member in struct.members:
+            self.visitMember(member, instance)
 
     def visitArray(self, array, instance):
         array_length = self.expand(array.length)