diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-05-07 23:19:55 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-05-07 23:19:55 +0000 |
commit | 5bcbf1ccbd2711947aa67f217e22f697ba12fe4e (patch) | |
tree | 24bfa5af0cf5e275d40528e677d8c642e02010d7 /clang/utils/ABITest | |
parent | 5580bdcaa2d4fd8e12ef3c46b47fad4b85e32e53 (diff) | |
download | bcm5719-llvm-5bcbf1ccbd2711947aa67f217e22f697ba12fe4e.tar.gz bcm5719-llvm-5bcbf1ccbd2711947aa67f217e22f697ba12fe4e.zip |
Add to the house of cards that is ABITestGen.
- Support generating structures with bit-fields.
llvm-svn: 71192
Diffstat (limited to 'clang/utils/ABITest')
-rwxr-xr-x | clang/utils/ABITest/ABITestGen.py | 101 | ||||
-rw-r--r-- | clang/utils/ABITest/TypeGen.py | 81 |
2 files changed, 136 insertions, 46 deletions
diff --git a/clang/utils/ABITest/ABITestGen.py b/clang/utils/ABITest/ABITestGen.py index dbcfdd28557..1bf0cefc537 100755 --- a/clang/utils/ABITest/ABITestGen.py +++ b/clang/utils/ABITest/ABITestGen.py @@ -205,10 +205,20 @@ class TypePrinter: # 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 @@ class TypePrinter: 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 @@ class TypePrinter: 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 @@ class TypePrinter: 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 @@ def main(): 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 @@ def main(): 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 @@ def main(): # 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 @@ def main(): 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 @@ def main(): 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 diff --git a/clang/utils/ABITest/TypeGen.py b/clang/utils/ABITest/TypeGen.py index 3021e607c3a..d5678db6a0e 100644 --- a/clang/utils/ABITest/TypeGen.py +++ b/clang/utils/ABITest/TypeGen.py @@ -4,7 +4,7 @@ from Enumeration import * # 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 @@ from Enumeration import * ### # 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 @@ class BuiltinType: 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 @@ class ArrayType: 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 @@ class ComplexType: 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 @@ class AnyTypeGenerator(TypeGenerator): 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__': |