brintos

brintos / llvm-project-archived public Read only

0
0
Text · 32.4 KiB · 119b329 Raw
1026 lines · python
1#!/usr/bin/env python2 3from __future__ import absolute_import, division, print_function4from pprint import pprint5import random, atexit, time6from random import randrange7import re8 9from Enumeration import *10from TypeGen import *11 12####13 14 15class TypePrinter(object):16    def __init__(17        self,18        output,19        outputHeader=None,20        outputTests=None,21        outputDriver=None,22        headerName=None,23        info=None,24    ):25        self.output = output26        self.outputHeader = outputHeader27        self.outputTests = outputTests28        self.outputDriver = outputDriver29        self.writeBody = outputHeader or outputTests or outputDriver30        self.types = {}31        self.testValues = {}32        self.testReturnValues = {}33        self.layoutTests = []34        self.declarations = set()35 36        if info:37            for f in (38                self.output,39                self.outputHeader,40                self.outputTests,41                self.outputDriver,42            ):43                if f:44                    print(info, file=f)45 46        if self.writeBody:47            print("#include <stdio.h>\n", file=self.output)48            if self.outputTests:49                print("#include <stdio.h>", file=self.outputTests)50                print("#include <string.h>", file=self.outputTests)51                print("#include <assert.h>\n", file=self.outputTests)52 53        if headerName:54            for f in (self.output, self.outputTests, self.outputDriver):55                if f is not None:56                    print('#include "%s"\n' % (headerName,), file=f)57 58        if self.outputDriver:59            print("#include <stdio.h>", file=self.outputDriver)60            print("#include <stdlib.h>\n", file=self.outputDriver)61            print("int main(int argc, char **argv) {", file=self.outputDriver)62            print("  int index = -1;", file=self.outputDriver)63            print("  if (argc > 1) index = atoi(argv[1]);", file=self.outputDriver)64 65    def finish(self):66        if self.layoutTests:67            print("int main(int argc, char **argv) {", file=self.output)68            print("  int index = -1;", file=self.output)69            print("  if (argc > 1) index = atoi(argv[1]);", file=self.output)70            for i, f in self.layoutTests:71                print("  if (index == -1 || index == %d)" % i, file=self.output)72                print("    %s();" % f, file=self.output)73            print("  return 0;", file=self.output)74            print("}", file=self.output)75 76        if self.outputDriver:77            print('  printf("DONE\\n");', file=self.outputDriver)78            print("  return 0;", file=self.outputDriver)79            print("}", file=self.outputDriver)80 81    def addDeclaration(self, decl):82        if decl in self.declarations:83            return False84 85        self.declarations.add(decl)86        if self.outputHeader:87            print(decl, file=self.outputHeader)88        else:89            print(decl, file=self.output)90            if self.outputTests:91                print(decl, file=self.outputTests)92        return True93 94    def getTypeName(self, T):95        name = self.types.get(T)96        if name is None:97            # Reserve slot98            self.types[T] = None99            self.types[T] = name = T.getTypeName(self)100        return name101 102    def writeLayoutTest(self, i, ty):103        tyName = self.getTypeName(ty)104        tyNameClean = tyName.replace(" ", "_").replace("*", "star")105        fnName = "test_%s" % tyNameClean106 107        print("void %s(void) {" % fnName, file=self.output)108        self.printSizeOfType("    %s" % fnName, tyName, ty, self.output)109        self.printAlignOfType("    %s" % fnName, tyName, ty, self.output)110        self.printOffsetsOfType("    %s" % fnName, tyName, ty, self.output)111        print("}", file=self.output)112        print(file=self.output)113 114        self.layoutTests.append((i, fnName))115 116    def writeFunction(self, i, FT):117        args = ", ".join(118            ["%s arg%d" % (self.getTypeName(t), i) for i, t in enumerate(FT.argTypes)]119        )120        if not args:121            args = "void"122 123        if FT.returnType is None:124            retvalName = None125            retvalTypeName = "void"126        else:127            retvalTypeName = self.getTypeName(FT.returnType)128            if self.writeBody or self.outputTests:129                retvalName = self.getTestReturnValue(FT.returnType)130 131        fnName = "fn%d" % (FT.index,)132        if self.outputHeader:133            print("%s %s(%s);" % (retvalTypeName, fnName, args), file=self.outputHeader)134        elif self.outputTests:135            print("%s %s(%s);" % (retvalTypeName, fnName, args), file=self.outputTests)136 137        print("%s %s(%s)" % (retvalTypeName, fnName, args), end=" ", file=self.output)138        if self.writeBody:139            print("{", file=self.output)140 141            for i, t in enumerate(FT.argTypes):142                self.printValueOfType("    %s" % fnName, "arg%d" % i, t)143 144            if retvalName is not None:145                print("  return %s;" % (retvalName,), file=self.output)146            print("}", file=self.output)147        else:148            print("{}", file=self.output)149        print(file=self.output)150 151        if self.outputDriver:152            print("  if (index == -1 || index == %d) {" % i, file=self.outputDriver)153            print("    extern void test_%s(void);" % fnName, file=self.outputDriver)154            print("    test_%s();" % fnName, file=self.outputDriver)155            print("   }", file=self.outputDriver)156 157        if self.outputTests:158            if self.outputHeader:159                print("void test_%s(void);" % (fnName,), file=self.outputHeader)160 161            if retvalName is None:162                retvalTests = None163            else:164                retvalTests = self.getTestValuesArray(FT.returnType)165            tests = [self.getTestValuesArray(ty) for ty in FT.argTypes]166            print("void test_%s(void) {" % (fnName,), file=self.outputTests)167 168            if retvalTests is not None:169                print(170                    '  printf("%s: testing return.\\n");' % (fnName,),171                    file=self.outputTests,172                )173                print(174                    "  for (int i=0; i<%d; ++i) {" % (retvalTests[1],),175                    file=self.outputTests,176                )177                args = ", ".join(["%s[%d]" % (t, randrange(l)) for t, l in tests])178                print("    %s RV;" % (retvalTypeName,), file=self.outputTests)179                print(180                    "    %s = %s[i];" % (retvalName, retvalTests[0]),181                    file=self.outputTests,182                )183                print("    RV = %s(%s);" % (fnName, args), file=self.outputTests)184                self.printValueOfType(185                    "  %s_RV" % fnName,186                    "RV",187                    FT.returnType,188                    output=self.outputTests,189                    indent=4,190                )191                self.checkTypeValues(192                    "RV",193                    "%s[i]" % retvalTests[0],194                    FT.returnType,195                    output=self.outputTests,196                    indent=4,197                )198                print("  }", file=self.outputTests)199 200            if tests:201                print(202                    '  printf("%s: testing arguments.\\n");' % (fnName,),203                    file=self.outputTests,204                )205            for i, (array, length) in enumerate(tests):206                for j in range(length):207                    args = ["%s[%d]" % (t, randrange(l)) for t, l in tests]208                    args[i] = "%s[%d]" % (array, j)209                    print(210                        "  %s(%s);"211                        % (212                            fnName,213                            ", ".join(args),214                        ),215                        file=self.outputTests,216                    )217            print("}", file=self.outputTests)218 219    def getTestReturnValue(self, type):220        typeName = self.getTypeName(type)221        info = self.testReturnValues.get(typeName)222        if info is None:223            name = "%s_retval" % (typeName.replace(" ", "_").replace("*", "star"),)224            print("%s %s;" % (typeName, name), file=self.output)225            if self.outputHeader:226                print("extern %s %s;" % (typeName, name), file=self.outputHeader)227            elif self.outputTests:228                print("extern %s %s;" % (typeName, name), file=self.outputTests)229            info = self.testReturnValues[typeName] = name230        return info231 232    def getTestValuesArray(self, type):233        typeName = self.getTypeName(type)234        info = self.testValues.get(typeName)235        if info is None:236            name = "%s_values" % (typeName.replace(" ", "_").replace("*", "star"),)237            print("static %s %s[] = {" % (typeName, name), file=self.outputTests)238            length = 0239            for item in self.getTestValues(type):240                print("\t%s," % (item,), file=self.outputTests)241                length += 1242            print("};", file=self.outputTests)243            info = self.testValues[typeName] = (name, length)244        return info245 246    def getTestValues(self, t):247        if isinstance(t, BuiltinType):248            if t.name == "float":249                for i in ["0.0", "-1.0", "1.0"]:250                    yield i + "f"251            elif t.name == "double":252                for i in ["0.0", "-1.0", "1.0"]:253                    yield i254            elif t.name in ("void *"):255                yield "(void*) 0"256                yield "(void*) -1"257            else:258                yield "(%s) 0" % (t.name,)259                yield "(%s) -1" % (t.name,)260                yield "(%s) 1" % (t.name,)261        elif isinstance(t, EnumType):262            for i in range(0, len(t.enumerators)):263                yield "enum%dval%d_%d" % (t.index, i, t.unique_id)264        elif isinstance(t, RecordType):265            nonPadding = [f for f in t.fields if not f.isPaddingBitField()]266 267            if not nonPadding:268                yield "{ }"269                return270 271            # FIXME: Use designated initializers to access non-first272            # fields of unions.273            if t.isUnion:274                for v in self.getTestValues(nonPadding[0]):275                    yield "{ %s }" % v276                return277 278            fieldValues = [list(v) for v in map(self.getTestValues, nonPadding)]279            for i, values in enumerate(fieldValues):280                for v in values:281                    elements = [random.choice(fv) for fv in fieldValues]282                    elements[i] = v283                    yield "{ %s }" % (", ".join(elements))284 285        elif isinstance(t, ComplexType):286            for t in self.getTestValues(t.elementType):287                yield "%s + %s * 1i" % (t, t)288        elif isinstance(t, ArrayType):289            values = list(self.getTestValues(t.elementType))290            if not values:291                yield "{ }"292            for i in range(t.numElements):293                for v in values:294                    elements = [random.choice(values) for i in range(t.numElements)]295                    elements[i] = v296                    yield "{ %s }" % (", ".join(elements))297        else:298            raise NotImplementedError('Cannot make tests values of type: "%s"' % (t,))299 300    def printSizeOfType(self, prefix, name, t, output=None, indent=2):301        print(302            '%*sprintf("%s: sizeof(%s) = %%ld\\n", (long)sizeof(%s));'303            % (indent, "", prefix, name, name),304            file=output,305        )306 307    def printAlignOfType(self, prefix, name, t, output=None, indent=2):308        print(309            '%*sprintf("%s: __alignof__(%s) = %%ld\\n", (long)__alignof__(%s));'310            % (indent, "", prefix, name, name),311            file=output,312        )313 314    def printOffsetsOfType(self, prefix, name, t, output=None, indent=2):315        if isinstance(t, RecordType):316            for i, f in enumerate(t.fields):317                if f.isBitField():318                    continue319                fname = "field%d" % i320                print(321                    '%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", (long)__builtin_offsetof(%s, %s));'322                    % (indent, "", prefix, name, fname, name, fname),323                    file=output,324                )325 326    def printValueOfType(self, prefix, name, t, output=None, indent=2):327        if output is None:328            output = self.output329        if isinstance(t, BuiltinType):330            value_expr = name331            if t.name.split(" ")[-1] == "_Bool":332                # Hack to work around PR5579.333                value_expr = "%s ? 2 : 0" % name334 335            if t.name.endswith("long long"):336                code = "lld"337            elif t.name.endswith("long"):338                code = "ld"339            elif t.name.split(" ")[-1] in ("_Bool", "char", "short", "int", "unsigned"):340                code = "d"341            elif t.name in ("float", "double"):342                code = "f"343            elif t.name == "long double":344                code = "Lf"345            else:346                code = "p"347            print(348                '%*sprintf("%s: %s = %%%s\\n", %s);'349                % (indent, "", prefix, name, code, value_expr),350                file=output,351            )352        elif isinstance(t, EnumType):353            print(354                '%*sprintf("%s: %s = %%d\\n", %s);' % (indent, "", prefix, name, name),355                file=output,356            )357        elif isinstance(t, RecordType):358            if not t.fields:359                print(360                    '%*sprintf("%s: %s (empty)\\n");' % (indent, "", prefix, name),361                    file=output,362                )363            for i, f in enumerate(t.fields):364                if f.isPaddingBitField():365                    continue366                fname = "%s.field%d" % (name, i)367                self.printValueOfType(prefix, fname, f, output=output, indent=indent)368        elif isinstance(t, ComplexType):369            self.printValueOfType(370                prefix,371                "(__real %s)" % name,372                t.elementType,373                output=output,374                indent=indent,375            )376            self.printValueOfType(377                prefix,378                "(__imag %s)" % name,379                t.elementType,380                output=output,381                indent=indent,382            )383        elif isinstance(t, ArrayType):384            for i in range(t.numElements):385                # Access in this fashion as a hackish way to portably386                # access vectors.387                if t.isVector:388                    self.printValueOfType(389                        prefix,390                        "((%s*) &%s)[%d]" % (t.elementType, name, i),391                        t.elementType,392                        output=output,393                        indent=indent,394                    )395                else:396                    self.printValueOfType(397                        prefix,398                        "%s[%d]" % (name, i),399                        t.elementType,400                        output=output,401                        indent=indent,402                    )403        else:404            raise NotImplementedError('Cannot print value of type: "%s"' % (t,))405 406    def checkTypeValues(self, nameLHS, nameRHS, t, output=None, indent=2):407        prefix = "foo"408        if output is None:409            output = self.output410        if isinstance(t, BuiltinType):411            print("%*sassert(%s == %s);" % (indent, "", nameLHS, nameRHS), file=output)412        elif isinstance(t, EnumType):413            print("%*sassert(%s == %s);" % (indent, "", nameLHS, nameRHS), file=output)414        elif isinstance(t, RecordType):415            for i, f in enumerate(t.fields):416                if f.isPaddingBitField():417                    continue418                self.checkTypeValues(419                    "%s.field%d" % (nameLHS, i),420                    "%s.field%d" % (nameRHS, i),421                    f,422                    output=output,423                    indent=indent,424                )425                if t.isUnion:426                    break427        elif isinstance(t, ComplexType):428            self.checkTypeValues(429                "(__real %s)" % nameLHS,430                "(__real %s)" % nameRHS,431                t.elementType,432                output=output,433                indent=indent,434            )435            self.checkTypeValues(436                "(__imag %s)" % nameLHS,437                "(__imag %s)" % nameRHS,438                t.elementType,439                output=output,440                indent=indent,441            )442        elif isinstance(t, ArrayType):443            for i in range(t.numElements):444                # Access in this fashion as a hackish way to portably445                # access vectors.446                if t.isVector:447                    self.checkTypeValues(448                        "((%s*) &%s)[%d]" % (t.elementType, nameLHS, i),449                        "((%s*) &%s)[%d]" % (t.elementType, nameRHS, i),450                        t.elementType,451                        output=output,452                        indent=indent,453                    )454                else:455                    self.checkTypeValues(456                        "%s[%d]" % (nameLHS, i),457                        "%s[%d]" % (nameRHS, i),458                        t.elementType,459                        output=output,460                        indent=indent,461                    )462        else:463            raise NotImplementedError('Cannot print value of type: "%s"' % (t,))464 465 466import sys467 468 469def main():470    from optparse import OptionParser, OptionGroup471 472    parser = OptionParser("%prog [options] {indices}")473    parser.add_option(474        "",475        "--mode",476        dest="mode",477        help="autogeneration mode (random or linear) [default %default]",478        type="choice",479        choices=("random", "linear"),480        default="linear",481    )482    parser.add_option(483        "",484        "--count",485        dest="count",486        help="autogenerate COUNT functions according to MODE",487        type=int,488        default=0,489    )490    parser.add_option(491        "",492        "--min",493        dest="minIndex",494        metavar="N",495        help="start autogeneration with the Nth function type  [default %default]",496        type=int,497        default=0,498    )499    parser.add_option(500        "",501        "--max",502        dest="maxIndex",503        metavar="N",504        help="maximum index for random autogeneration  [default %default]",505        type=int,506        default=10000000,507    )508    parser.add_option(509        "",510        "--seed",511        dest="seed",512        help="random number generator seed [default %default]",513        type=int,514        default=1,515    )516    parser.add_option(517        "",518        "--use-random-seed",519        dest="useRandomSeed",520        help="use random value for initial random number generator seed",521        action="store_true",522        default=False,523    )524    parser.add_option(525        "",526        "--skip",527        dest="skipTests",528        help="add a test index to skip",529        type=int,530        action="append",531        default=[],532    )533    parser.add_option(534        "-o",535        "--output",536        dest="output",537        metavar="FILE",538        help="write output to FILE  [default %default]",539        type=str,540        default="-",541    )542    parser.add_option(543        "-O",544        "--output-header",545        dest="outputHeader",546        metavar="FILE",547        help="write header file for output to FILE  [default %default]",548        type=str,549        default=None,550    )551    parser.add_option(552        "-T",553        "--output-tests",554        dest="outputTests",555        metavar="FILE",556        help="write function tests to FILE  [default %default]",557        type=str,558        default=None,559    )560    parser.add_option(561        "-D",562        "--output-driver",563        dest="outputDriver",564        metavar="FILE",565        help="write test driver to FILE  [default %default]",566        type=str,567        default=None,568    )569    parser.add_option(570        "",571        "--test-layout",572        dest="testLayout",573        metavar="FILE",574        help="test structure layout",575        action="store_true",576        default=False,577    )578 579    group = OptionGroup(parser, "Type Enumeration Options")580    # Builtins - Ints581    group.add_option(582        "",583        "--no-char",584        dest="useChar",585        help="do not generate char types",586        action="store_false",587        default=True,588    )589    group.add_option(590        "",591        "--no-short",592        dest="useShort",593        help="do not generate short types",594        action="store_false",595        default=True,596    )597    group.add_option(598        "",599        "--no-int",600        dest="useInt",601        help="do not generate int types",602        action="store_false",603        default=True,604    )605    group.add_option(606        "",607        "--no-long",608        dest="useLong",609        help="do not generate long types",610        action="store_false",611        default=True,612    )613    group.add_option(614        "",615        "--no-long-long",616        dest="useLongLong",617        help="do not generate long long types",618        action="store_false",619        default=True,620    )621    group.add_option(622        "",623        "--no-unsigned",624        dest="useUnsigned",625        help="do not generate unsigned integer types",626        action="store_false",627        default=True,628    )629 630    # Other builtins631    group.add_option(632        "",633        "--no-bool",634        dest="useBool",635        help="do not generate bool types",636        action="store_false",637        default=True,638    )639    group.add_option(640        "",641        "--no-float",642        dest="useFloat",643        help="do not generate float types",644        action="store_false",645        default=True,646    )647    group.add_option(648        "",649        "--no-double",650        dest="useDouble",651        help="do not generate double types",652        action="store_false",653        default=True,654    )655    group.add_option(656        "",657        "--no-long-double",658        dest="useLongDouble",659        help="do not generate long double types",660        action="store_false",661        default=True,662    )663    group.add_option(664        "",665        "--no-void-pointer",666        dest="useVoidPointer",667        help="do not generate void* types",668        action="store_false",669        default=True,670    )671 672    # Enumerations673    group.add_option(674        "",675        "--no-enums",676        dest="useEnum",677        help="do not generate enum types",678        action="store_false",679        default=True,680    )681 682    # Derived types683    group.add_option(684        "",685        "--no-array",686        dest="useArray",687        help="do not generate record types",688        action="store_false",689        default=True,690    )691    group.add_option(692        "",693        "--no-complex",694        dest="useComplex",695        help="do not generate complex types",696        action="store_false",697        default=True,698    )699    group.add_option(700        "",701        "--no-record",702        dest="useRecord",703        help="do not generate record types",704        action="store_false",705        default=True,706    )707    group.add_option(708        "",709        "--no-union",710        dest="recordUseUnion",711        help="do not generate union types",712        action="store_false",713        default=True,714    )715    group.add_option(716        "",717        "--no-vector",718        dest="useVector",719        help="do not generate vector types",720        action="store_false",721        default=True,722    )723    group.add_option(724        "",725        "--no-bit-field",726        dest="useBitField",727        help="do not generate bit-field record members",728        action="store_false",729        default=True,730    )731    group.add_option(732        "",733        "--no-builtins",734        dest="useBuiltins",735        help="do not use any types",736        action="store_false",737        default=True,738    )739 740    # Tuning741    group.add_option(742        "",743        "--no-function-return",744        dest="functionUseReturn",745        help="do not generate return types for functions",746        action="store_false",747        default=True,748    )749    group.add_option(750        "",751        "--vector-types",752        dest="vectorTypes",753        help="comma separated list of vector types (e.g., v2i32) [default %default]",754        action="store",755        type=str,756        default="v2i16, v1i64, v2i32, v4i16, v8i8, v2f32, v2i64, v4i32, v8i16, v16i8, v2f64, v4f32, v16f32",757        metavar="N",758    )759    group.add_option(760        "",761        "--bit-fields",762        dest="bitFields",763        help="comma separated list 'type:width' bit-field specifiers [default %default]",764        action="store",765        type=str,766        default=("char:0,char:4,int:0,unsigned:1,int:1,int:4,int:13,int:24"),767    )768    group.add_option(769        "",770        "--max-args",771        dest="functionMaxArgs",772        help="maximum number of arguments per function [default %default]",773        action="store",774        type=int,775        default=4,776        metavar="N",777    )778    group.add_option(779        "",780        "--max-array",781        dest="arrayMaxSize",782        help="maximum array size [default %default]",783        action="store",784        type=int,785        default=4,786        metavar="N",787    )788    group.add_option(789        "",790        "--max-record",791        dest="recordMaxSize",792        help="maximum number of fields per record [default %default]",793        action="store",794        type=int,795        default=4,796        metavar="N",797    )798    group.add_option(799        "",800        "--max-record-depth",801        dest="recordMaxDepth",802        help="maximum nested structure depth [default %default]",803        action="store",804        type=int,805        default=None,806        metavar="N",807    )808    parser.add_option_group(group)809    (opts, args) = parser.parse_args()810 811    if not opts.useRandomSeed:812        random.seed(opts.seed)813 814    # Construct type generator815    builtins = []816    if opts.useBuiltins:817        ints = []818        if opts.useChar:819            ints.append(("char", 1))820        if opts.useShort:821            ints.append(("short", 2))822        if opts.useInt:823            ints.append(("int", 4))824        # FIXME: Wrong size.825        if opts.useLong:826            ints.append(("long", 4))827        if opts.useLongLong:828            ints.append(("long long", 8))829        if opts.useUnsigned:830            ints = [("unsigned %s" % i, s) for i, s in ints] + [831                ("signed %s" % i, s) for i, s in ints832            ]833        builtins.extend(ints)834 835        if opts.useBool:836            builtins.append(("_Bool", 1))837        if opts.useFloat:838            builtins.append(("float", 4))839        if opts.useDouble:840            builtins.append(("double", 8))841        if opts.useLongDouble:842            builtins.append(("long double", 16))843        # FIXME: Wrong size.844        if opts.useVoidPointer:845            builtins.append(("void*", 4))846 847    btg = FixedTypeGenerator([BuiltinType(n, s) for n, s in builtins])848 849    bitfields = []850    for specifier in opts.bitFields.split(","):851        if not specifier.strip():852            continue853        name, width = specifier.strip().split(":", 1)854        bitfields.append(BuiltinType(name, None, int(width)))855    bftg = FixedTypeGenerator(bitfields)856 857    charType = BuiltinType("char", 1)858    shortType = BuiltinType("short", 2)859    intType = BuiltinType("int", 4)860    longlongType = BuiltinType("long long", 8)861    floatType = BuiltinType("float", 4)862    doubleType = BuiltinType("double", 8)863    sbtg = FixedTypeGenerator([charType, intType, floatType, doubleType])864 865    atg = AnyTypeGenerator()866    artg = AnyTypeGenerator()867 868    def makeGenerator(atg, subgen, subfieldgen, useRecord, useArray, useBitField):869        atg.addGenerator(btg)870        if useBitField and opts.useBitField:871            atg.addGenerator(bftg)872        if useRecord and opts.useRecord:873            assert subgen874            atg.addGenerator(875                RecordTypeGenerator(876                    subfieldgen, opts.recordUseUnion, opts.recordMaxSize877                )878            )879        if opts.useComplex:880            # FIXME: Allow overriding builtins here881            atg.addGenerator(ComplexTypeGenerator(sbtg))882        if useArray and opts.useArray:883            assert subgen884            atg.addGenerator(ArrayTypeGenerator(subgen, opts.arrayMaxSize))885        if opts.useVector:886            vTypes = []887            for i, t in enumerate(opts.vectorTypes.split(",")):888                m = re.match("v([1-9][0-9]*)([if][1-9][0-9]*)", t.strip())889                if not m:890                    parser.error("Invalid vector type: %r" % t)891                count, kind = m.groups()892                count = int(count)893                type = {894                    "i8": charType,895                    "i16": shortType,896                    "i32": intType,897                    "i64": longlongType,898                    "f32": floatType,899                    "f64": doubleType,900                }.get(kind)901                if not type:902                    parser.error("Invalid vector type: %r" % t)903                vTypes.append(ArrayType(i, True, type, count * type.size))904 905            atg.addGenerator(FixedTypeGenerator(vTypes))906        if opts.useEnum:907            atg.addGenerator(EnumTypeGenerator([None, "-1", "1", "1u"], 1, 4))908 909    if opts.recordMaxDepth is None:910        # Fully recursive, just avoid top-level arrays.911        subFTG = AnyTypeGenerator()912        subTG = AnyTypeGenerator()913        atg = AnyTypeGenerator()914        makeGenerator(subFTG, atg, atg, True, True, True)915        makeGenerator(subTG, atg, subFTG, True, True, False)916        makeGenerator(atg, subTG, subFTG, True, False, False)917    else:918        # Make a chain of type generators, each builds smaller919        # structures.920        base = AnyTypeGenerator()921        fbase = AnyTypeGenerator()922        makeGenerator(base, None, None, False, False, False)923        makeGenerator(fbase, None, None, False, False, True)924        for i in range(opts.recordMaxDepth):925            n = AnyTypeGenerator()926            fn = AnyTypeGenerator()927            makeGenerator(n, base, fbase, True, True, False)928            makeGenerator(fn, base, fbase, True, True, True)929            base = n930            fbase = fn931        atg = AnyTypeGenerator()932        makeGenerator(atg, base, fbase, True, False, False)933 934    if opts.testLayout:935        ftg = atg936    else:937        ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs)938 939    # Override max,min,count if finite940    if opts.maxIndex is None:941        if ftg.cardinality is aleph0:942            opts.maxIndex = 10000000943        else:944            opts.maxIndex = ftg.cardinality945    opts.maxIndex = min(opts.maxIndex, ftg.cardinality)946    opts.minIndex = max(0, min(opts.maxIndex - 1, opts.minIndex))947    if not opts.mode == "random":948        opts.count = min(opts.count, opts.maxIndex - opts.minIndex)949 950    if opts.output == "-":951        output = sys.stdout952    else:953        output = open(opts.output, "w")954        atexit.register(lambda: output.close())955 956    outputHeader = None957    if opts.outputHeader:958        outputHeader = open(opts.outputHeader, "w")959        atexit.register(lambda: outputHeader.close())960 961    outputTests = None962    if opts.outputTests:963        outputTests = open(opts.outputTests, "w")964        atexit.register(lambda: outputTests.close())965 966    outputDriver = None967    if opts.outputDriver:968        outputDriver = open(opts.outputDriver, "w")969        atexit.register(lambda: outputDriver.close())970 971    info = ""972    info += "// %s\n" % (" ".join(sys.argv),)973    info += "// Generated: %s\n" % (time.strftime("%Y-%m-%d %H:%M"),)974    info += "// Cardinality of function generator: %s\n" % (ftg.cardinality,)975    info += "// Cardinality of type generator: %s\n" % (atg.cardinality,)976 977    if opts.testLayout:978        info += "\n#include <stdio.h>"979 980    P = TypePrinter(981        output,982        outputHeader=outputHeader,983        outputTests=outputTests,984        outputDriver=outputDriver,985        headerName=opts.outputHeader,986        info=info,987    )988 989    def write(N):990        try:991            FT = ftg.get(N)992        except RuntimeError as e:993            if e.args[0] == "maximum recursion depth exceeded":994                print(995                    "WARNING: Skipped %d, recursion limit exceeded (bad arguments?)"996                    % (N,),997                    file=sys.stderr,998                )999                return1000            raise1001        if opts.testLayout:1002            P.writeLayoutTest(N, FT)1003        else:1004            P.writeFunction(N, FT)1005 1006    if args:1007        [write(int(a)) for a in args]1008 1009    skipTests = set(opts.skipTests)1010    for i in range(opts.count):1011        if opts.mode == "linear":1012            index = opts.minIndex + i1013        else:1014            index = opts.minIndex + int(1015                (opts.maxIndex - opts.minIndex) * random.random()1016            )1017        if index in skipTests:1018            continue1019        write(index)1020 1021    P.finish()1022 1023 1024if __name__ == "__main__":1025    main()1026