From 5ce61575adde60a826576446d2e9e953c54e1e99 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 28 Jan 2009 02:01:23 +0000 Subject: [PATCH] ABITest: Support --test-layout option for generating size/alignment/offsetof based tests of types instead of calling convention tests. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63167 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/ABITest/ABITestGen.py | 59 ++++++++++++++++++++++++++---- utils/ABITest/layout/Makefile | 68 +++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 7 deletions(-) create mode 100644 utils/ABITest/layout/Makefile diff --git a/utils/ABITest/ABITestGen.py b/utils/ABITest/ABITestGen.py index 957ce2bb16..8f922d7e52 100755 --- a/utils/ABITest/ABITestGen.py +++ b/utils/ABITest/ABITestGen.py @@ -21,6 +21,7 @@ class TypePrinter: self.types = {} self.testValues = {} self.testReturnValues = {} + self.layoutTests = [] if info: for f in (self.output,self.outputHeader,self.outputTests,self.outputDriver): @@ -41,9 +42,16 @@ class TypePrinter: print >>self.outputDriver, 'int main(int argc, char **argv) {' def finish(self): + if self.layoutTests: + print >>self.output, 'int main(int argc, char **argv) {' + for f in self.layoutTests: + print >>self.output, ' %s();' % f + print >>self.output, ' return 0;' + print >>self.output, '}' + if self.outputDriver: print >>self.outputDriver, ' return 0;' - print >>self.outputDriver, '}' + print >>self.outputDriver, '}' def getTypeName(self, T): if isinstance(T,BuiltinType): @@ -62,6 +70,20 @@ class TypePrinter: self.types[T] = name return name + def writeLayoutTest(self, i, ty): + tyName = self.getTypeName(ty) + tyNameClean = tyName.replace(' ','_').replace('*','star') + fnName = 'test_%s' % tyNameClean + + print >>self.output,'void %s(void) {' % fnName + self.printSizeOfType(' %s'%fnName, tyName, ty, self.output) + self.printAlignOfType(' %s'%fnName, tyName, ty, self.output) + self.printOffsetsOfType(' %s'%fnName, tyName, ty, self.output) + print >>self.output,'}' + print >>self.output + + self.layoutTests.append(fnName) + def writeFunction(self, i, FT): args = ', '.join(['%s arg%d'%(self.getTypeName(t),i) for i,t in enumerate(FT.argTypes)]) if not args: @@ -194,6 +216,16 @@ class TypePrinter: else: raise NotImplementedError,'Cannot make tests values of type: "%s"'%(t,) + def printSizeOfType(self, prefix, name, t, output=None, indent=2): + print >>output, '%*sprintf("%s: sizeof(%s) = %%ld\\n", sizeof(%s));'%(indent, '', prefix, name, name) + def printAlignOfType(self, prefix, name, t, output=None, indent=2): + print >>output, '%*sprintf("%s: __alignof__(%s) = %%ld\\n", __alignof__(%s));'%(indent, '', prefix, name, name) + def printOffsetsOfType(self, prefix, name, t, output=None, indent=2): + if isinstance(t, RecordType): + for i,f in enumerate(t.fields): + fname = 'field%d' % i + print >>output, '%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", __builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname) + def printValueOfType(self, prefix, name, t, output=None, indent=2): if output is None: output = self.output @@ -263,6 +295,9 @@ def main(): parser.add_option("-D", "--output-driver", dest="outputDriver", metavar="FILE", help="write test driver to FILE [default %default]", type=str, default=None) + parser.add_option("", "--test-layout", dest="testLayout", metavar="FILE", + help="test structure layout", + action='store_true', default=False) group = OptionGroup(parser, "Type Enumeration Options") # Builtins - Ints @@ -325,7 +360,7 @@ def main(): action="store_false", default=True) group.add_option("", "--vector-sizes", dest="vectorSizes", help="comma separated list of sizes for vectors [default %default]", - action="store", type=str, default='4,8', metavar="N") + action="store", type=str, default='8,16', metavar="N") group.add_option("", "--max-args", dest="functionMaxArgs", help="maximum number of arguments per function [default %default]", @@ -369,7 +404,8 @@ def main(): btg = FixedTypeGenerator([BuiltinType(n,s) for n,s in builtins]) sbtg = FixedTypeGenerator([BuiltinType('char',1), BuiltinType('int',4), - BuiltinType('float',4)]) + BuiltinType('float',4), + BuiltinType('double',8)]) atg = AnyTypeGenerator() artg = AnyTypeGenerator() @@ -408,7 +444,10 @@ def main(): atg = AnyTypeGenerator() makeGenerator(atg, base, True, False) - ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs) + if opts.testLayout: + ftg = atg + else: + ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs) # Override max,min,count if finite if opts.maxIndex is None: @@ -447,23 +486,29 @@ def main(): info += '// Generated: %s\n'%(time.strftime('%Y-%m-%d %H:%M'),) info += '// Cardinality of function generator: %s\n'%(ftg.cardinality,) info += '// Cardinality of type generator: %s\n'%(atg.cardinality,) + + if opts.testLayout: + info += '\n#include ' P = TypePrinter(output, outputHeader=outputHeader, outputTests=outputTests, outputDriver=outputDriver, - headerName=opts.outputHeader, + headerName=opts.outputHeader, info=info) def write(N): - try: + try: FT = ftg.get(N) except RuntimeError,e: if e.args[0]=='maximum recursion depth exceeded': print >>sys.stderr,'WARNING: Skipped %d, recursion limit exceeded (bad arguments?)'%(N,) return raise - P.writeFunction(N, FT) + if opts.testLayout: + P.writeLayoutTest(N, FT) + else: + P.writeFunction(N, FT) if args: [write(int(a)) for a in args] diff --git a/utils/ABITest/layout/Makefile b/utils/ABITest/layout/Makefile new file mode 100644 index 0000000000..f93a74e592 --- /dev/null +++ b/utils/ABITest/layout/Makefile @@ -0,0 +1,68 @@ +# Usage: make test.N.report +# +# COUNT can be over-ridden to change the number of tests generated per +# file, and TESTARGS is used to change the type generation. Make sure +# to 'make clean' after changing either of these parameters. + +ABITESTGEN := ../ABITestGen.py +TESTARGS := --max-args 0 --no-complex --no-vector --no-union --test-layout +COUNT := 1000 +TIMEOUT := 5 + +CFLAGS := -std=gnu99 + +X_COMPILER := llvm-gcc +Y_COMPILER := xcc -ccc-clang +CC := gcc + +ifeq (0, 0) +X_CFLAGS := -m32 +Y_CFLAGS := -m32 +CC_CFLAGS := -m32 +else +X_CFLAGS := -m64 +Y_CFLAGS := -m64 +CC_CFLAGS := -m64 +endif + +.PHONY: test.%.report +test.%.report: test.%.x.diff test.%.y.diff + @for t in $^; do \ + if [ -s $$t ]; then \ + echo "TEST $*: $$t failed"; \ + fi; \ + done + +.PHONY: test.%.build +test.%.build: test.%.ref test.%.x test.%.y + @true + +### + +.PRECIOUS: test.%.x.diff +test.%.x.diff: test.%.ref.out test.%.x.out + -diff $^ > $@ +.PRECIOUS: test.%.y.diff +test.%.y.diff: test.%.ref.out test.%.y.out + -diff $^ > $@ + +.PRECIOUS: test.%.out +test.%.out: test.% + -./$< > $@ + +.PRECIOUS: test.%.ref +test.%.ref: test.%.c + $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^ +.PRECIOUS: test.%.x +test.%.x: test.%.c + $(X_COMPILER) $(CFLAGS) $(X_CFLAGS) -o $@ $^ +.PRECIOUS: test.%.y +test.%.y: test.%.c + $(Y_COMPILER) $(CFLAGS) $(Y_CFLAGS) -o $@ $^ + +.PRECIOUS: test.%.c +test.%.c: $(ABITESTGEN) + $(ABITESTGEN) $(TESTARGS) -o $@ --min=$(shell expr $* '*' $(COUNT)) --count=$(COUNT) + +clean: + rm -f test.* *~ -- 2.40.0