[cfe-commits] r71192 - in /cfe/trunk/utils/ABITest: ABITestGen.py TypeGen.py

Daniel Dunbar daniel at zuster.org
Thu May 7 16:19:56 PDT 2009


Author: ddunbar
Date: Thu May  7 18:19:55 2009
New Revision: 71192

URL: http://llvm.org/viewvc/llvm-project?rev=71192&view=rev
Log:
Add to the house of cards that is ABITestGen.
 - Support generating structures with bit-fields.

Modified:
    cfe/trunk/utils/ABITest/ABITestGen.py
    cfe/trunk/utils/ABITest/TypeGen.py

Modified: cfe/trunk/utils/ABITest/ABITestGen.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/ABITest/ABITestGen.py?rev=71192&r1=71191&r2=71192&view=diff

==============================================================================
--- cfe/trunk/utils/ABITest/ABITestGen.py (original)
+++ cfe/trunk/utils/ABITest/ABITestGen.py Thu May  7 18:19:55 2009
@@ -205,10 +205,20 @@
             # FIXME: Use designated initializers to access non-first
             # fields of unions.
             if t.isUnion:
-                for v in self.getTestValues(t.fields[0]):
-                    yield '{ %s }' % v
+                firstNonPadding = None
+                for t in t.fields:
+                    if not t.isPaddingBitField():
+                        firstNonPadding = t
+                        break
+                if firstNonPadding:
+                    for v in self.getTestValues(firstNonPadding):
+                        yield '{ %s }' % v
+                else:
+                    yield '{ }'
                 return
-            fieldValues = [list(self.getTestValues(f)) for f in t.fields]
+            fieldValues = [list(self.getTestValues(f)) 
+                           for f in t.fields
+                           if not f.isPaddingBitField()]
             for i,values in enumerate(fieldValues):
                 for v in values:
                     elements = map(random.choice,fieldValues)
@@ -236,6 +246,8 @@
     def printOffsetsOfType(self, prefix, name, t, output=None, indent=2):
         if isinstance(t, RecordType):
             for i,f in enumerate(t.fields):
+                if f.isPaddingBitField():
+                    continue
                 fname = 'field%d' % i
                 print >>output, '%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", __builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname) 
                 
@@ -260,6 +272,8 @@
             if not t.fields:
                 print >>output, '%*sprintf("%s: %s (empty)\\n");'%(indent, '', prefix, name) 
             for i,f in enumerate(t.fields):
+                if f.isPaddingBitField():
+                    continue
                 fname = '%s.field%d'%(name,i)
                 self.printValueOfType(prefix, fname, f, output=output, indent=indent)
         elif isinstance(t, ComplexType):
@@ -284,6 +298,8 @@
             print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS)
         elif isinstance(t, RecordType):
             for i,f in enumerate(t.fields):
+                if f.isPaddingBitField():
+                    continue
                 self.checkTypeValues('%s.field%d'%(nameLHS,i), '%s.field%d'%(nameRHS,i), 
                                      f, output=output, indent=indent)
                 if t.isUnion:
@@ -398,6 +414,12 @@
     group.add_option("", "--no-vector", dest="useVector",
                      help="do not generate vector types",
                      action="store_false", default=True)
+    group.add_option("", "--no-bit-field", dest="useBitField",
+                     help="do not generate bit-field record members",
+                     action="store_false", default=True)
+    group.add_option("", "--no-builtins", dest="useBuiltins",
+                     help="do not use any types",
+                     action="store_false", default=True)
 
     # Tuning 
     group.add_option("", "--no-function-return", dest="functionUseReturn",
@@ -406,7 +428,9 @@
     group.add_option("", "--vector-types", dest="vectorTypes",
                      help="comma separated list of vector types (e.g., v2i32) [default %default]",
                      action="store", type=str, default='v2i16, v1i64, v2i32, v4i16, v8i8, v2f32, v2i64, v4i32, v8i16, v16i8, v2f64, v4f32, v16f32', metavar="N")
-
+    group.add_option("", "--bit-fields", dest="bitFields",
+                     help="comma separated list 'type:width' bit-field specifiers [default %default]",
+                     action="store", type=str, default="1,3,-2,-1")
     group.add_option("", "--max-args", dest="functionMaxArgs",
                      help="maximum number of arguments per function [default %default]",
                      action="store", type=int, default=4, metavar="N")
@@ -427,26 +451,36 @@
 
     # Contruct type generator
     builtins = []
-    ints = []
-    if opts.useChar: ints.append(('char',1))
-    if opts.useShort: ints.append(('short',2))
-    if opts.useInt: ints.append(('int',4))
-    # FIXME: Wrong size.
-    if opts.useLong: ints.append(('long',4))
-    if opts.useLongLong: ints.append(('long long',8))
-    if opts.useUnsigned: 
-        ints = ([('unsigned %s'%i,s) for i,s in ints] + 
-                [('signed %s'%i,s) for i,s in ints])
-    builtins.extend(ints)
-
-    if opts.useBool: builtins.append(('_Bool',1))
-    if opts.useFloat: builtins.append(('float',4))
-    if opts.useDouble: builtins.append(('double',8))
-    if opts.useLongDouble: builtins.append(('long double',16))
-    # FIXME: Wrong size.
-    if opts.useVoidPointer:  builtins.append(('void*',4))
+    if opts.useBuiltins:
+        ints = []
+        if opts.useChar: ints.append(('char',1))
+        if opts.useShort: ints.append(('short',2))
+        if opts.useInt: ints.append(('int',4))
+        # FIXME: Wrong size.
+        if opts.useLong: ints.append(('long',4))
+        if opts.useLongLong: ints.append(('long long',8))
+        if opts.useUnsigned: 
+            ints = ([('unsigned %s'%i,s) for i,s in ints] + 
+                    [('signed %s'%i,s) for i,s in ints])
+        builtins.extend(ints)
+
+        if opts.useBool: builtins.append(('_Bool',1))
+        if opts.useFloat: builtins.append(('float',4))
+        if opts.useDouble: builtins.append(('double',8))
+        if opts.useLongDouble: builtins.append(('long double',16))
+        # FIXME: Wrong size.
+        if opts.useVoidPointer:  builtins.append(('void*',4))
 
     btg = FixedTypeGenerator([BuiltinType(n,s) for n,s in builtins])
+
+    bitfields = []
+    for specifier in opts.bitFields.split(','):
+        if not specifier.strip():
+            continue
+        name,width = specifier.strip().split(':', 1)
+        bitfields.append(BuiltinType(name,None,int(width)))
+    bftg = FixedTypeGenerator(bitfields)
+
     charType = BuiltinType('char',1)
     shortType = BuiltinType('short',2)
     intType = BuiltinType('int',4)
@@ -457,11 +491,13 @@
 
     atg = AnyTypeGenerator()
     artg = AnyTypeGenerator()
-    def makeGenerator(atg, subgen, useRecord, useArray):
+    def makeGenerator(atg, subgen, subfieldgen, useRecord, useArray, useBitField):
         atg.addGenerator(btg)
+        if useBitField and opts.useBitField:
+            atg.addGenerator(bftg)
         if useRecord and opts.useRecord:
             assert subgen 
-            atg.addGenerator(RecordTypeGenerator(subgen, opts.recordUseUnion, 
+            atg.addGenerator(RecordTypeGenerator(subfieldgen, opts.recordUseUnion, 
                                                  opts.recordMaxSize))
         if opts.useComplex:
             # FIXME: Allow overriding builtins here
@@ -492,21 +528,28 @@
 
     if opts.recordMaxDepth is None: 
         # Fully recursive, just avoid top-level arrays.
+        subFTG = AnyTypeGenerator()
         subTG = AnyTypeGenerator()
         atg = AnyTypeGenerator()
-        makeGenerator(subTG, atg, True, True)
-        makeGenerator(atg, subTG, True, False)
+        makeGenerator(subFTG, atg, atg, True, True, True)
+        makeGenerator(subTG, atg, subFTG, True, True, False)
+        makeGenerator(atg, subTG, subFTG, True, False, False)
     else:
         # Make a chain of type generators, each builds smaller
         # structures.
         base = AnyTypeGenerator()
-        makeGenerator(base, None, False, False)
+        fbase = AnyTypeGenerator()
+        makeGenerator(base, None, None, False, False, False)
+        makeGenerator(fbase, None, None, False, False, True)
         for i in range(opts.recordMaxDepth):
             n = AnyTypeGenerator()
-            makeGenerator(n, base, True, True)
+            fn = AnyTypeGenerator()
+            makeGenerator(n, base, fbase, True, True, False)
+            makeGenerator(fn, base, fbase, True, True, True)
             base = n
+            fbase = fn
         atg = AnyTypeGenerator()
-        makeGenerator(atg, base, True, False)
+        makeGenerator(atg, base, fbase, True, False, False)
 
     if opts.testLayout:
         ftg = atg

Modified: cfe/trunk/utils/ABITest/TypeGen.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/ABITest/TypeGen.py?rev=71192&r1=71191&r2=71192&view=diff

==============================================================================
--- cfe/trunk/utils/ABITest/TypeGen.py (original)
+++ cfe/trunk/utils/ABITest/TypeGen.py Thu May  7 18:19:55 2009
@@ -4,7 +4,7 @@
 
 # TODO:
 
-#  - struct improvements (bitfields, flexible arrays, packed &
+#  - struct improvements (flexible arrays, packed &
 #    unpacked, alignment)
 #  - objective-c qualified id
 #  - anonymous / transparent unions
@@ -17,10 +17,28 @@
 ###
 # Actual type types
 
-class BuiltinType:
-    def __init__(self, name, size):
+class Type:
+    def isBitField(self):
+        return False
+
+    def isPaddingBitField(self):
+        return False
+
+class BuiltinType(Type):
+    def __init__(self, name, size, bitFieldSize=None):
         self.name = name
         self.size = size
+        self.bitFieldSize = bitFieldSize
+
+    def isBitField(self):
+        return self.bitFieldSize is not None
+
+    def isPaddingBitField(self):
+        return self.bitFieldSize is 0
+
+    def getBitFieldSize(self):
+        assert self.isBitField()
+        return self.bitFieldSize
 
     def sizeof(self):
         return self.size
@@ -28,24 +46,39 @@
     def __str__(self):
         return self.name
 
-class RecordType:
+class RecordType(Type):
     def __init__(self, index, isUnion, fields):
         self.index = index
         self.isUnion = isUnion
         self.fields = fields
         self.name = None
 
-    def __str__(self):        
+    def __str__(self):
+        def getField(t):
+            if t.isBitField():
+                return "%s : %d;" % (t, t.getBitFieldSize())
+            else:
+                return "%s;" % t
+
         return '%s { %s }'%(('struct','union')[self.isUnion],
-                            ' '.join(['%s;'%f for f in self.fields]))
+                            ' '.join(map(getField, self.fields)))
 
     def getTypedefDef(self, name, printer):
-        fields = ['%s field%d;'%(printer.getTypeName(t),i) for i,t in enumerate(self.fields)]
+        def getField((i, t)):
+            if t.isBitField():
+                if t.isPaddingBitField():
+                    return '%s : 0;'%(printer.getTypeName(t),)
+                else:
+                    return '%s field%d : %d;'%(printer.getTypeName(t),i,
+                                               t.getBitFieldSize())
+            else:
+                return '%s field%d;'%(printer.getTypeName(t),i)
+        fields = map(getField, enumerate(self.fields))
         # Name the struct for more readable LLVM IR.
         return 'typedef %s %s { %s } %s;'%(('struct','union')[self.isUnion],
                                            name, ' '.join(fields), name)
                                            
-class ArrayType:
+class ArrayType(Type):
     def __init__(self, index, isVector, elementType, size):
         if isVector:
             # Note that for vectors, this is the size in bytes.
@@ -84,7 +117,7 @@
                 sizeStr = str(self.size)
             return 'typedef %s %s[%s];'%(elementName, name, sizeStr)
 
-class ComplexType:
+class ComplexType(Type):
     def __init__(self, index, elementType):
         self.index = index
         self.elementType = elementType
@@ -95,7 +128,7 @@
     def getTypedefDef(self, name, printer):
         return 'typedef _Complex %s %s;'%(printer.getTypeName(self.elementType), name)
 
-class FunctionType:
+class FunctionType(Type):
     def __init__(self, index, returnType, argTypes):
         self.index = index
         self.returnType = returnType
@@ -317,17 +350,31 @@
         return self.generators[index].get(M)
 
 def test():
+    fbtg = FixedTypeGenerator([BuiltinType('char', 4),
+                               BuiltinType('char', 4, 0),
+                               BuiltinType('int',  4, 5)])
+
+    fields1 = AnyTypeGenerator()
+    fields1.addGenerator( fbtg )
+
+    fields0 = AnyTypeGenerator()
+    fields0.addGenerator( fbtg )
+#    fields0.addGenerator( RecordTypeGenerator(fields1, False, 4) )
+
+    btg = FixedTypeGenerator([BuiltinType('char', 4),
+                              BuiltinType('int',  4)])
+    
     atg = AnyTypeGenerator()
-    btg = FixedTypeGenerator([BuiltinType('int',4),
-                              BuiltinType('float',4)])
     atg.addGenerator( btg )
-    atg.addGenerator( ComplexTypeGenerator(btg) )
-    atg.addGenerator( RecordTypeGenerator(atg, True, 2) )
-    atg.addGenerator( VectorTypeGenerator(btg, (4,8)) )
-    atg.addGenerator( ArrayTypeGenerator(btg, 4) )
-    atg.addGenerator( FunctionTypeGenerator(btg, False, 2) )
+    atg.addGenerator( RecordTypeGenerator(fields0, False, 4) )
     print 'Cardinality:',atg.cardinality
     for i in range(100):
+        if i == atg.cardinality:
+            try:
+                atg.get(i)
+                raise RuntimeError,"Cardinality was wrong"
+            except AssertionError:
+                break
         print '%4d: %s'%(i, atg.get(i))
 
 if __name__ == '__main__':





More information about the cfe-commits mailing list