diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 17:59:23 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 17:59:23 +0000 |
commit | 9a83721404652cea39e9f02ae3e3b5c964602a5c (patch) | |
tree | 23e9541ce27049a103f6ed046be61592123e02c9 /utils | |
parent | 676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (diff) |
Notes
Diffstat (limited to 'utils')
58 files changed, 0 insertions, 8812 deletions
diff --git a/utils/ABITest/ABITestGen.py b/utils/ABITest/ABITestGen.py deleted file mode 100755 index 93a6de93068d..000000000000 --- a/utils/ABITest/ABITestGen.py +++ /dev/null @@ -1,673 +0,0 @@ -#!/usr/bin/env python - -from __future__ import absolute_import, division, print_function -from pprint import pprint -import random, atexit, time -from random import randrange -import re - -from Enumeration import * -from TypeGen import * - -#### - -class TypePrinter(object): - def __init__(self, output, outputHeader=None, - outputTests=None, outputDriver=None, - headerName=None, info=None): - self.output = output - self.outputHeader = outputHeader - self.outputTests = outputTests - self.outputDriver = outputDriver - self.writeBody = outputHeader or outputTests or outputDriver - self.types = {} - self.testValues = {} - self.testReturnValues = {} - self.layoutTests = [] - self.declarations = set() - - if info: - for f in (self.output,self.outputHeader,self.outputTests,self.outputDriver): - if f: - print(info, file=f) - - if self.writeBody: - print('#include <stdio.h>\n', file=self.output) - if self.outputTests: - print('#include <stdio.h>', file=self.outputTests) - print('#include <string.h>', file=self.outputTests) - print('#include <assert.h>\n', file=self.outputTests) - - if headerName: - for f in (self.output,self.outputTests,self.outputDriver): - if f is not None: - print('#include "%s"\n'%(headerName,), file=f) - - if self.outputDriver: - print('#include <stdio.h>', file=self.outputDriver) - print('#include <stdlib.h>\n', file=self.outputDriver) - print('int main(int argc, char **argv) {', file=self.outputDriver) - print(' int index = -1;', file=self.outputDriver) - print(' if (argc > 1) index = atoi(argv[1]);', file=self.outputDriver) - - def finish(self): - if self.layoutTests: - print('int main(int argc, char **argv) {', file=self.output) - print(' int index = -1;', file=self.output) - print(' if (argc > 1) index = atoi(argv[1]);', file=self.output) - for i,f in self.layoutTests: - print(' if (index == -1 || index == %d)' % i, file=self.output) - print(' %s();' % f, file=self.output) - print(' return 0;', file=self.output) - print('}', file=self.output) - - if self.outputDriver: - print(' printf("DONE\\n");', file=self.outputDriver) - print(' return 0;', file=self.outputDriver) - print('}', file=self.outputDriver) - - def addDeclaration(self, decl): - if decl in self.declarations: - return False - - self.declarations.add(decl) - if self.outputHeader: - print(decl, file=self.outputHeader) - else: - print(decl, file=self.output) - if self.outputTests: - print(decl, file=self.outputTests) - return True - - def getTypeName(self, T): - name = self.types.get(T) - if name is None: - # Reserve slot - self.types[T] = None - self.types[T] = name = T.getTypeName(self) - return name - - def writeLayoutTest(self, i, ty): - tyName = self.getTypeName(ty) - tyNameClean = tyName.replace(' ','_').replace('*','star') - fnName = 'test_%s' % tyNameClean - - print('void %s(void) {' % fnName, file=self.output) - 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('}', file=self.output) - print(file=self.output) - - self.layoutTests.append((i,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: - args = 'void' - - if FT.returnType is None: - retvalName = None - retvalTypeName = 'void' - else: - retvalTypeName = self.getTypeName(FT.returnType) - if self.writeBody or self.outputTests: - retvalName = self.getTestReturnValue(FT.returnType) - - fnName = 'fn%d'%(FT.index,) - if self.outputHeader: - print('%s %s(%s);'%(retvalTypeName, fnName, args), file=self.outputHeader) - elif self.outputTests: - print('%s %s(%s);'%(retvalTypeName, fnName, args), file=self.outputTests) - - print('%s %s(%s)'%(retvalTypeName, fnName, args), end=' ', file=self.output) - if self.writeBody: - print('{', file=self.output) - - for i,t in enumerate(FT.argTypes): - self.printValueOfType(' %s'%fnName, 'arg%d'%i, t) - - if retvalName is not None: - print(' return %s;'%(retvalName,), file=self.output) - print('}', file=self.output) - else: - print('{}', file=self.output) - print(file=self.output) - - if self.outputDriver: - print(' if (index == -1 || index == %d) {' % i, file=self.outputDriver) - print(' extern void test_%s(void);' % fnName, file=self.outputDriver) - print(' test_%s();' % fnName, file=self.outputDriver) - print(' }', file=self.outputDriver) - - if self.outputTests: - if self.outputHeader: - print('void test_%s(void);'%(fnName,), file=self.outputHeader) - - if retvalName is None: - retvalTests = None - else: - retvalTests = self.getTestValuesArray(FT.returnType) - tests = [self.getTestValuesArray(ty) for ty in FT.argTypes] - print('void test_%s(void) {'%(fnName,), file=self.outputTests) - - if retvalTests is not None: - print(' printf("%s: testing return.\\n");'%(fnName,), file=self.outputTests) - print(' for (int i=0; i<%d; ++i) {'%(retvalTests[1],), file=self.outputTests) - args = ', '.join(['%s[%d]'%(t,randrange(l)) for t,l in tests]) - print(' %s RV;'%(retvalTypeName,), file=self.outputTests) - print(' %s = %s[i];'%(retvalName, retvalTests[0]), file=self.outputTests) - print(' RV = %s(%s);'%(fnName, args), file=self.outputTests) - self.printValueOfType(' %s_RV'%fnName, 'RV', FT.returnType, output=self.outputTests, indent=4) - self.checkTypeValues('RV', '%s[i]' % retvalTests[0], FT.returnType, output=self.outputTests, indent=4) - print(' }', file=self.outputTests) - - if tests: - print(' printf("%s: testing arguments.\\n");'%(fnName,), file=self.outputTests) - for i,(array,length) in enumerate(tests): - for j in range(length): - args = ['%s[%d]'%(t,randrange(l)) for t,l in tests] - args[i] = '%s[%d]'%(array,j) - print(' %s(%s);'%(fnName, ', '.join(args),), file=self.outputTests) - print('}', file=self.outputTests) - - def getTestReturnValue(self, type): - typeName = self.getTypeName(type) - info = self.testReturnValues.get(typeName) - if info is None: - name = '%s_retval'%(typeName.replace(' ','_').replace('*','star'),) - print('%s %s;'%(typeName,name), file=self.output) - if self.outputHeader: - print('extern %s %s;'%(typeName,name), file=self.outputHeader) - elif self.outputTests: - print('extern %s %s;'%(typeName,name), file=self.outputTests) - info = self.testReturnValues[typeName] = name - return info - - def getTestValuesArray(self, type): - typeName = self.getTypeName(type) - info = self.testValues.get(typeName) - if info is None: - name = '%s_values'%(typeName.replace(' ','_').replace('*','star'),) - print('static %s %s[] = {'%(typeName,name), file=self.outputTests) - length = 0 - for item in self.getTestValues(type): - print('\t%s,'%(item,), file=self.outputTests) - length += 1 - print('};', file=self.outputTests) - info = self.testValues[typeName] = (name,length) - return info - - def getTestValues(self, t): - if isinstance(t, BuiltinType): - if t.name=='float': - for i in ['0.0','-1.0','1.0']: - yield i+'f' - elif t.name=='double': - for i in ['0.0','-1.0','1.0']: - yield i - elif t.name in ('void *'): - yield '(void*) 0' - yield '(void*) -1' - else: - yield '(%s) 0'%(t.name,) - yield '(%s) -1'%(t.name,) - yield '(%s) 1'%(t.name,) - elif isinstance(t, EnumType): - for i in range(0, len(t.enumerators)): - yield 'enum%dval%d_%d' % (t.index, i, t.unique_id) - elif isinstance(t, RecordType): - nonPadding = [f for f in t.fields - if not f.isPaddingBitField()] - - if not nonPadding: - yield '{ }' - return - - # FIXME: Use designated initializers to access non-first - # fields of unions. - if t.isUnion: - for v in self.getTestValues(nonPadding[0]): - yield '{ %s }' % v - return - - fieldValues = [list(v) for v in map(self.getTestValues, nonPadding)] - for i,values in enumerate(fieldValues): - for v in values: - elements = [random.choice(fv) for fv in fieldValues] - elements[i] = v - yield '{ %s }'%(', '.join(elements)) - - elif isinstance(t, ComplexType): - for t in self.getTestValues(t.elementType): - yield '%s + %s * 1i'%(t,t) - elif isinstance(t, ArrayType): - values = list(self.getTestValues(t.elementType)) - if not values: - yield '{ }' - for i in range(t.numElements): - for v in values: - elements = [random.choice(values) for i in range(t.numElements)] - elements[i] = v - yield '{ %s }'%(', '.join(elements)) - else: - raise NotImplementedError('Cannot make tests values of type: "%s"'%(t,)) - - def printSizeOfType(self, prefix, name, t, output=None, indent=2): - print('%*sprintf("%s: sizeof(%s) = %%ld\\n", (long)sizeof(%s));'%(indent, '', prefix, name, name), file=output) - def printAlignOfType(self, prefix, name, t, output=None, indent=2): - print('%*sprintf("%s: __alignof__(%s) = %%ld\\n", (long)__alignof__(%s));'%(indent, '', prefix, name, name), file=output) - def printOffsetsOfType(self, prefix, name, t, output=None, indent=2): - if isinstance(t, RecordType): - for i,f in enumerate(t.fields): - if f.isBitField(): - continue - fname = 'field%d' % i - print('%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", (long)__builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname), file=output) - - def printValueOfType(self, prefix, name, t, output=None, indent=2): - if output is None: - output = self.output - if isinstance(t, BuiltinType): - value_expr = name - if t.name.split(' ')[-1] == '_Bool': - # Hack to work around PR5579. - value_expr = "%s ? 2 : 0" % name - - if t.name.endswith('long long'): - code = 'lld' - elif t.name.endswith('long'): - code = 'ld' - elif t.name.split(' ')[-1] in ('_Bool','char','short', - 'int','unsigned'): - code = 'd' - elif t.name in ('float','double'): - code = 'f' - elif t.name == 'long double': - code = 'Lf' - else: - code = 'p' - print('%*sprintf("%s: %s = %%%s\\n", %s);'%( - indent, '', prefix, name, code, value_expr), file=output) - elif isinstance(t, EnumType): - print('%*sprintf("%s: %s = %%d\\n", %s);'%(indent, '', prefix, name, name), file=output) - elif isinstance(t, RecordType): - if not t.fields: - print('%*sprintf("%s: %s (empty)\\n");'%(indent, '', prefix, name), file=output) - 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): - self.printValueOfType(prefix, '(__real %s)'%name, t.elementType, output=output,indent=indent) - self.printValueOfType(prefix, '(__imag %s)'%name, t.elementType, output=output,indent=indent) - elif isinstance(t, ArrayType): - for i in range(t.numElements): - # Access in this fashion as a hackish way to portably - # access vectors. - if t.isVector: - self.printValueOfType(prefix, '((%s*) &%s)[%d]'%(t.elementType,name,i), t.elementType, output=output,indent=indent) - else: - self.printValueOfType(prefix, '%s[%d]'%(name,i), t.elementType, output=output,indent=indent) - else: - raise NotImplementedError('Cannot print value of type: "%s"'%(t,)) - - def checkTypeValues(self, nameLHS, nameRHS, t, output=None, indent=2): - prefix = 'foo' - if output is None: - output = self.output - if isinstance(t, BuiltinType): - print('%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS), file=output) - elif isinstance(t, EnumType): - print('%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS), file=output) - 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: - break - elif isinstance(t, ComplexType): - self.checkTypeValues('(__real %s)'%nameLHS, '(__real %s)'%nameRHS, t.elementType, output=output,indent=indent) - self.checkTypeValues('(__imag %s)'%nameLHS, '(__imag %s)'%nameRHS, t.elementType, output=output,indent=indent) - elif isinstance(t, ArrayType): - for i in range(t.numElements): - # Access in this fashion as a hackish way to portably - # access vectors. - if t.isVector: - self.checkTypeValues('((%s*) &%s)[%d]'%(t.elementType,nameLHS,i), - '((%s*) &%s)[%d]'%(t.elementType,nameRHS,i), - t.elementType, output=output,indent=indent) - else: - self.checkTypeValues('%s[%d]'%(nameLHS,i), '%s[%d]'%(nameRHS,i), - t.elementType, output=output,indent=indent) - else: - raise NotImplementedError('Cannot print value of type: "%s"'%(t,)) - -import sys - -def main(): - from optparse import OptionParser, OptionGroup - parser = OptionParser("%prog [options] {indices}") - parser.add_option("", "--mode", dest="mode", - help="autogeneration mode (random or linear) [default %default]", - type='choice', choices=('random','linear'), default='linear') - parser.add_option("", "--count", dest="count", - help="autogenerate COUNT functions according to MODE", - type=int, default=0) - parser.add_option("", "--min", dest="minIndex", metavar="N", - help="start autogeneration with the Nth function type [default %default]", - type=int, default=0) - parser.add_option("", "--max", dest="maxIndex", metavar="N", - help="maximum index for random autogeneration [default %default]", - type=int, default=10000000) - parser.add_option("", "--seed", dest="seed", - help="random number generator seed [default %default]", - type=int, default=1) - parser.add_option("", "--use-random-seed", dest="useRandomSeed", - help="use random value for initial random number generator seed", - action='store_true', default=False) - parser.add_option("", "--skip", dest="skipTests", - help="add a test index to skip", - type=int, action='append', default=[]) - parser.add_option("-o", "--output", dest="output", metavar="FILE", - help="write output to FILE [default %default]", - type=str, default='-') - parser.add_option("-O", "--output-header", dest="outputHeader", metavar="FILE", - help="write header file for output to FILE [default %default]", - type=str, default=None) - parser.add_option("-T", "--output-tests", dest="outputTests", metavar="FILE", - help="write function tests to FILE [default %default]", - type=str, default=None) - 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 - group.add_option("", "--no-char", dest="useChar", - help="do not generate char types", - action="store_false", default=True) - group.add_option("", "--no-short", dest="useShort", - help="do not generate short types", - action="store_false", default=True) - group.add_option("", "--no-int", dest="useInt", - help="do not generate int types", - action="store_false", default=True) - group.add_option("", "--no-long", dest="useLong", - help="do not generate long types", - action="store_false", default=True) - group.add_option("", "--no-long-long", dest="useLongLong", - help="do not generate long long types", - action="store_false", default=True) - group.add_option("", "--no-unsigned", dest="useUnsigned", - help="do not generate unsigned integer types", - action="store_false", default=True) - - # Other builtins - group.add_option("", "--no-bool", dest="useBool", - help="do not generate bool types", - action="store_false", default=True) - group.add_option("", "--no-float", dest="useFloat", - help="do not generate float types", - action="store_false", default=True) - group.add_option("", "--no-double", dest="useDouble", - help="do not generate double types", - action="store_false", default=True) - group.add_option("", "--no-long-double", dest="useLongDouble", - help="do not generate long double types", - action="store_false", default=True) - group.add_option("", "--no-void-pointer", dest="useVoidPointer", - help="do not generate void* types", - action="store_false", default=True) - - # Enumerations - group.add_option("", "--no-enums", dest="useEnum", - help="do not generate enum types", - action="store_false", default=True) - - # Derived types - group.add_option("", "--no-array", dest="useArray", - help="do not generate record types", - action="store_false", default=True) - group.add_option("", "--no-complex", dest="useComplex", - help="do not generate complex types", - action="store_false", default=True) - group.add_option("", "--no-record", dest="useRecord", - help="do not generate record types", - action="store_false", default=True) - group.add_option("", "--no-union", dest="recordUseUnion", - help="do not generate union types", - action="store_false", default=True) - 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", - help="do not generate return types for functions", - action="store_false", default=True) - 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=( - "char:0,char:4,int:0,unsigned:1,int:1,int:4,int:13,int:24")) - group.add_option("", "--max-args", dest="functionMaxArgs", - help="maximum number of arguments per function [default %default]", - action="store", type=int, default=4, metavar="N") - group.add_option("", "--max-array", dest="arrayMaxSize", - help="maximum array size [default %default]", - action="store", type=int, default=4, metavar="N") - group.add_option("", "--max-record", dest="recordMaxSize", - help="maximum number of fields per record [default %default]", - action="store", type=int, default=4, metavar="N") - group.add_option("", "--max-record-depth", dest="recordMaxDepth", - help="maximum nested structure depth [default %default]", - action="store", type=int, default=None, metavar="N") - parser.add_option_group(group) - (opts, args) = parser.parse_args() - - if not opts.useRandomSeed: - random.seed(opts.seed) - - # Construct type generator - builtins = [] - 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) - longlongType = BuiltinType('long long',8) - floatType = BuiltinType('float',4) - doubleType = BuiltinType('double',8) - sbtg = FixedTypeGenerator([charType, intType, floatType, doubleType]) - - atg = AnyTypeGenerator() - artg = AnyTypeGenerator() - 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(subfieldgen, opts.recordUseUnion, - opts.recordMaxSize)) - if opts.useComplex: - # FIXME: Allow overriding builtins here - atg.addGenerator(ComplexTypeGenerator(sbtg)) - if useArray and opts.useArray: - assert subgen - atg.addGenerator(ArrayTypeGenerator(subgen, opts.arrayMaxSize)) - if opts.useVector: - vTypes = [] - for i,t in enumerate(opts.vectorTypes.split(',')): - m = re.match('v([1-9][0-9]*)([if][1-9][0-9]*)', t.strip()) - if not m: - parser.error('Invalid vector type: %r' % t) - count,kind = m.groups() - count = int(count) - type = { 'i8' : charType, - 'i16' : shortType, - 'i32' : intType, - 'i64' : longlongType, - 'f32' : floatType, - 'f64' : doubleType, - }.get(kind) - if not type: - parser.error('Invalid vector type: %r' % t) - vTypes.append(ArrayType(i, True, type, count * type.size)) - - atg.addGenerator(FixedTypeGenerator(vTypes)) - if opts.useEnum: - atg.addGenerator(EnumTypeGenerator([None, '-1', '1', '1u'], 1, 4)) - - if opts.recordMaxDepth is None: - # Fully recursive, just avoid top-level arrays. - subFTG = AnyTypeGenerator() - subTG = AnyTypeGenerator() - atg = AnyTypeGenerator() - 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() - fbase = AnyTypeGenerator() - makeGenerator(base, None, None, False, False, False) - makeGenerator(fbase, None, None, False, False, True) - for i in range(opts.recordMaxDepth): - n = AnyTypeGenerator() - 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, fbase, True, False, False) - - if opts.testLayout: - ftg = atg - else: - ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs) - - # Override max,min,count if finite - if opts.maxIndex is None: - if ftg.cardinality is aleph0: - opts.maxIndex = 10000000 - else: - opts.maxIndex = ftg.cardinality - opts.maxIndex = min(opts.maxIndex, ftg.cardinality) - opts.minIndex = max(0,min(opts.maxIndex-1, opts.minIndex)) - if not opts.mode=='random': - opts.count = min(opts.count, opts.maxIndex-opts.minIndex) - - if opts.output=='-': - output = sys.stdout - else: - output = open(opts.output,'w') - atexit.register(lambda: output.close()) - - outputHeader = None - if opts.outputHeader: - outputHeader = open(opts.outputHeader,'w') - atexit.register(lambda: outputHeader.close()) - - outputTests = None - if opts.outputTests: - outputTests = open(opts.outputTests,'w') - atexit.register(lambda: outputTests.close()) - - outputDriver = None - if opts.outputDriver: - outputDriver = open(opts.outputDriver,'w') - atexit.register(lambda: outputDriver.close()) - - info = '' - info += '// %s\n'%(' '.join(sys.argv),) - 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 <stdio.h>' - - P = TypePrinter(output, - outputHeader=outputHeader, - outputTests=outputTests, - outputDriver=outputDriver, - headerName=opts.outputHeader, - info=info) - - def write(N): - try: - FT = ftg.get(N) - except RuntimeError as e: - if e.args[0]=='maximum recursion depth exceeded': - print('WARNING: Skipped %d, recursion limit exceeded (bad arguments?)'%(N,), file=sys.stderr) - return - raise - if opts.testLayout: - P.writeLayoutTest(N, FT) - else: - P.writeFunction(N, FT) - - if args: - [write(int(a)) for a in args] - - skipTests = set(opts.skipTests) - for i in range(opts.count): - if opts.mode=='linear': - index = opts.minIndex + i - else: - index = opts.minIndex + int((opts.maxIndex-opts.minIndex) * random.random()) - if index in skipTests: - continue - write(index) - - P.finish() - -if __name__=='__main__': - main() - diff --git a/utils/ABITest/Enumeration.py b/utils/ABITest/Enumeration.py deleted file mode 100644 index 24f5b5fba24c..000000000000 --- a/utils/ABITest/Enumeration.py +++ /dev/null @@ -1,278 +0,0 @@ -"""Utilities for enumeration of finite and countably infinite sets. -""" -from __future__ import absolute_import, division, print_function -### -# Countable iteration - -# Simplifies some calculations -class Aleph0(int): - _singleton = None - def __new__(type): - if type._singleton is None: - type._singleton = int.__new__(type) - return type._singleton - def __repr__(self): return '<aleph0>' - def __str__(self): return 'inf' - - def __cmp__(self, b): - return 1 - - def __sub__(self, b): - raise ValueError("Cannot subtract aleph0") - __rsub__ = __sub__ - - def __add__(self, b): - return self - __radd__ = __add__ - - def __mul__(self, b): - if b == 0: return b - return self - __rmul__ = __mul__ - - def __floordiv__(self, b): - if b == 0: raise ZeroDivisionError - return self - __rfloordiv__ = __floordiv__ - __truediv__ = __floordiv__ - __rtuediv__ = __floordiv__ - __div__ = __floordiv__ - __rdiv__ = __floordiv__ - - def __pow__(self, b): - if b == 0: return 1 - return self -aleph0 = Aleph0() - -def base(line): - return line*(line+1)//2 - -def pairToN(pair): - x,y = pair - line,index = x+y,y - return base(line)+index - -def getNthPairInfo(N): - # Avoid various singularities - if N==0: - return (0,0) - - # Gallop to find bounds for line - line = 1 - next = 2 - while base(next)<=N: - line = next - next = line << 1 - - # Binary search for starting line - lo = line - hi = line<<1 - while lo + 1 != hi: - #assert base(lo) <= N < base(hi) - mid = (lo + hi)>>1 - if base(mid)<=N: - lo = mid - else: - hi = mid - - line = lo - return line, N - base(line) - -def getNthPair(N): - line,index = getNthPairInfo(N) - return (line - index, index) - -def getNthPairBounded(N,W=aleph0,H=aleph0,useDivmod=False): - """getNthPairBounded(N, W, H) -> (x, y) - - Return the N-th pair such that 0 <= x < W and 0 <= y < H.""" - - if W <= 0 or H <= 0: - raise ValueError("Invalid bounds") - elif N >= W*H: - raise ValueError("Invalid input (out of bounds)") - - # Simple case... - if W is aleph0 and H is aleph0: - return getNthPair(N) - - # Otherwise simplify by assuming W < H - if H < W: - x,y = getNthPairBounded(N,H,W,useDivmod=useDivmod) - return y,x - - if useDivmod: - return N%W,N//W - else: - # Conceptually we want to slide a diagonal line across a - # rectangle. This gives more interesting results for large - # bounds than using divmod. - - # If in lower left, just return as usual - cornerSize = base(W) - if N < cornerSize: - return getNthPair(N) - - # Otherwise if in upper right, subtract from corner - if H is not aleph0: - M = W*H - N - 1 - if M < cornerSize: - x,y = getNthPair(M) - return (W-1-x,H-1-y) - - # Otherwise, compile line and index from number of times we - # wrap. - N = N - cornerSize - index,offset = N%W,N//W - # p = (W-1, 1+offset) + (-1,1)*index - return (W-1-index, 1+offset+index) -def getNthPairBoundedChecked(N,W=aleph0,H=aleph0,useDivmod=False,GNP=getNthPairBounded): - x,y = GNP(N,W,H,useDivmod) - assert 0 <= x < W and 0 <= y < H - return x,y - -def getNthNTuple(N, W, H=aleph0, useLeftToRight=False): - """getNthNTuple(N, W, H) -> (x_0, x_1, ..., x_W) - - Return the N-th W-tuple, where for 0 <= x_i < H.""" - - if useLeftToRight: - elts = [None]*W - for i in range(W): - elts[i],N = getNthPairBounded(N, H) - return tuple(elts) - else: - if W==0: - return () - elif W==1: - return (N,) - elif W==2: - return getNthPairBounded(N, H, H) - else: - LW,RW = W//2, W - (W//2) - L,R = getNthPairBounded(N, H**LW, H**RW) - return (getNthNTuple(L,LW,H=H,useLeftToRight=useLeftToRight) + - getNthNTuple(R,RW,H=H,useLeftToRight=useLeftToRight)) -def getNthNTupleChecked(N, W, H=aleph0, useLeftToRight=False, GNT=getNthNTuple): - t = GNT(N,W,H,useLeftToRight) - assert len(t) == W - for i in t: - assert i < H - return t - -def getNthTuple(N, maxSize=aleph0, maxElement=aleph0, useDivmod=False, useLeftToRight=False): - """getNthTuple(N, maxSize, maxElement) -> x - - Return the N-th tuple where len(x) < maxSize and for y in x, 0 <= - y < maxElement.""" - - # All zero sized tuples are isomorphic, don't ya know. - if N == 0: - return () - N -= 1 - if maxElement is not aleph0: - if maxSize is aleph0: - raise NotImplementedError('Max element size without max size unhandled') - bounds = [maxElement**i for i in range(1, maxSize+1)] - S,M = getNthPairVariableBounds(N, bounds) - else: - S,M = getNthPairBounded(N, maxSize, useDivmod=useDivmod) - return getNthNTuple(M, S+1, maxElement, useLeftToRight=useLeftToRight) -def getNthTupleChecked(N, maxSize=aleph0, maxElement=aleph0, - useDivmod=False, useLeftToRight=False, GNT=getNthTuple): - # FIXME: maxsize is inclusive - t = GNT(N,maxSize,maxElement,useDivmod,useLeftToRight) - assert len(t) <= maxSize - for i in t: - assert i < maxElement - return t - -def getNthPairVariableBounds(N, bounds): - """getNthPairVariableBounds(N, bounds) -> (x, y) - - Given a finite list of bounds (which may be finite or aleph0), - return the N-th pair such that 0 <= x < len(bounds) and 0 <= y < - bounds[x].""" - - if not bounds: - raise ValueError("Invalid bounds") - if not (0 <= N < sum(bounds)): - raise ValueError("Invalid input (out of bounds)") - - level = 0 - active = list(range(len(bounds))) - active.sort(key=lambda i: bounds[i]) - prevLevel = 0 - for i,index in enumerate(active): - level = bounds[index] - W = len(active) - i - if level is aleph0: - H = aleph0 - else: - H = level - prevLevel - levelSize = W*H - if N<levelSize: # Found the level - idelta,delta = getNthPairBounded(N, W, H) - return active[i+idelta],prevLevel+delta - else: - N -= levelSize - prevLevel = level - else: - raise RuntimError("Unexpected loop completion") - -def getNthPairVariableBoundsChecked(N, bounds, GNVP=getNthPairVariableBounds): - x,y = GNVP(N,bounds) - assert 0 <= x < len(bounds) and 0 <= y < bounds[x] - return (x,y) - -### - -def testPairs(): - W = 3 - H = 6 - a = [[' ' for x in range(10)] for y in range(10)] - b = [[' ' for x in range(10)] for y in range(10)] - for i in range(min(W*H,40)): - x,y = getNthPairBounded(i,W,H) - x2,y2 = getNthPairBounded(i,W,H,useDivmod=True) - print(i,(x,y),(x2,y2)) - a[y][x] = '%2d'%i - b[y2][x2] = '%2d'%i - - print('-- a --') - for ln in a[::-1]: - if ''.join(ln).strip(): - print(' '.join(ln)) - print('-- b --') - for ln in b[::-1]: - if ''.join(ln).strip(): - print(' '.join(ln)) - -def testPairsVB(): - bounds = [2,2,4,aleph0,5,aleph0] - a = [[' ' for x in range(15)] for y in range(15)] - b = [[' ' for x in range(15)] for y in range(15)] - for i in range(min(sum(bounds),40)): - x,y = getNthPairVariableBounds(i, bounds) - print(i,(x,y)) - a[y][x] = '%2d'%i - - print('-- a --') - for ln in a[::-1]: - if ''.join(ln).strip(): - print(' '.join(ln)) - -### - -# Toggle to use checked versions of enumeration routines. -if False: - getNthPairVariableBounds = getNthPairVariableBoundsChecked - getNthPairBounded = getNthPairBoundedChecked - getNthNTuple = getNthNTupleChecked - getNthTuple = getNthTupleChecked - -if __name__ == '__main__': - testPairs() - - testPairsVB() - diff --git a/utils/ABITest/Makefile.test.common b/utils/ABITest/Makefile.test.common deleted file mode 100644 index 3c208adf0c54..000000000000 --- a/utils/ABITest/Makefile.test.common +++ /dev/null @@ -1,170 +0,0 @@ -# -*- Makefile -*- - -# 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. - -TESTARGS := --no-unsigned --no-vector --no-complex --no-bool - -COUNT := 1 -TIMEOUT := 5 - -CFLAGS := -std=gnu99 - -X_COMPILER := gcc -X_LL_CFLAGS := -emit-llvm -S -Y_COMPILER := clang -Y_LL_CFLAGS := -emit-llvm -S -CC := gcc - -### - -ABITESTGEN := ../ABITestGen.py - -ifndef VERBOSE - Verb := @ -endif - -.PHONY: test.%.report -test.%.report: temps/test.%.xx.diff temps/test.%.xy.diff temps/test.%.yx.diff temps/test.%.yy.diff - @ok=1;\ - for t in $^; do \ - if [ -s $$t ]; then \ - echo "TEST $*: $$t failed"; \ - ok=0;\ - fi; \ - done; \ - if [ $$ok -eq 1 ]; then \ - true; \ - else \ - false; \ - fi - - -.PHONY: test.%.defs-report -test.%.defs-report: temps/test.%.defs.diff - @for t in $^; do \ - if [ -s $$t ]; then \ - echo "TEST $*: $$t failed"; \ - cat $$t; \ - fi; \ - done - -.PHONY: test.%.build -test.%.build: temps/test.%.ref temps/test.%.xx temps/test.%.xy temps/test.%.yx temps/test.%.yy temps/test.%.x.defs temps/test.%.y.defs - @true - -### - -# Diffs and output - -.PRECIOUS: temps/.dir - -.PRECIOUS: temps/test.%.xx.diff -temps/test.%.xx.diff: temps/test.%.ref.out temps/test.%.xx.out - $(Verb) diff $^ > $@ || true -.PRECIOUS: temps/test.%.xy.diff -temps/test.%.xy.diff: temps/test.%.ref.out temps/test.%.xy.out - $(Verb) diff $^ > $@ || true -.PRECIOUS: temps/test.%.yx.diff -temps/test.%.yx.diff: temps/test.%.ref.out temps/test.%.yx.out - $(Verb) diff $^ > $@ || true -.PRECIOUS: temps/test.%.yy.diff -temps/test.%.yy.diff: temps/test.%.ref.out temps/test.%.yy.out - $(Verb) diff $^ > $@ || true -.PRECIOUS: temps/test.%.defs.diff -temps/test.%.defs.diff: temps/test.%.x.defs temps/test.%.y.defs - $(Verb) zipdifflines \ - --replace "%struct.T[0-9]+" "%struct.s" \ - --replace "%union.T[0-9]+" "%struct.s" \ - --replace "byval align [0-9]+" "byval" \ - $^ > $@ - -.PRECIOUS: temps/test.%.out -temps/test.%.out: temps/test.% - -$(Verb) ./$< > $@ - -# Executables - -.PRECIOUS: temps/test.%.ref -temps/test.%.ref: temps/test.%.driver.ref.o temps/test.%.a.ref.o temps/test.%.b.ref.o - $(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3 -o $@ $^ -.PRECIOUS: temps/test.%.xx -temps/test.%.xx: temps/test.%.driver.ref.o temps/test.%.a.x.o temps/test.%.b.x.o - $(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3 -o $@ $^ -.PRECIOUS: temps/test.%.xy -temps/test.%.xy: temps/test.%.driver.ref.o temps/test.%.a.x.o temps/test.%.b.y.o - $(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3 -o $@ $^ -.PRECIOUS: temps/test.%.yx -temps/test.%.yx: temps/test.%.driver.ref.o temps/test.%.a.y.o temps/test.%.b.x.o - $(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3 -o $@ $^ -.PRECIOUS: temps/test.%.yy -temps/test.%.yy: temps/test.%.driver.ref.o temps/test.%.a.y.o temps/test.%.b.y.o - $(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3 -o $@ $^ - -# Object files - -.PRECIOUS: temps/test.%.ref.o -temps/test.%.ref.o: inputs/test.%.c temps/.dir - $(Verb) $(CC) -c $(CFLAGS) $(CC_CFLAGS) -o $@ $< -.PRECIOUS: temps/test.%.x.o -temps/test.%.x.o: inputs/test.%.c temps/.dir - $(Verb) $(X_COMPILER) -c $(CFLAGS) $(X_CFLAGS) -o $@ $< -.PRECIOUS: temps/test.%.y.o -temps/test.%.y.o: inputs/test.%.c temps/.dir - $(Verb) $(Y_COMPILER) -c $(CFLAGS) $(Y_CFLAGS) -o $@ $< - -.PRECIOUS: temps/test.%.x.defs -temps/test.%.x.defs: temps/test.%.a.x.ll temps/.dir - -$(Verb) -grep '^define ' $< > $@ -.PRECIOUS: temps/test.%.y.defs -temps/test.%.y.defs: temps/test.%.a.y.ll temps/.dir - -$(Verb) -grep '^define ' $< > $@ - -.PRECIOUS: temps/test.%.a.x.ll -temps/test.%.a.x.ll: inputs/test.%.a.c temps/.dir - $(Verb) $(X_COMPILER) $(CFLAGS) $(X_LL_CFLAGS) $(X_CFLAGS) -o $@ $< -.PRECIOUS: temps/test.%.b.x.ll -temps/test.%.b.x.ll: inputs/test.%.b.c temps/.dir - $(Verb) $(X_COMPILER) $(CFLAGS) $(X_LL_CFLAGS) $(X_CFLAGS) -o $@ $< -.PRECIOUS: temps/test.%.a.y.ll -temps/test.%.a.y.ll: inputs/test.%.a.c temps/.dir - $(Verb) $(Y_COMPILER) $(CFLAGS) $(Y_LL_CFLAGS) $(Y_CFLAGS) -o $@ $< -.PRECIOUS: temps/test.%.b.y.ll -temps/test.%.b.y.ll: inputs/test.%.b.c temps/.dir - $(Verb) $(Y_COMPILER) $(CFLAGS) $(Y_LL_CFLAGS) $(Y_CFLAGS) -o $@ $< - -# Input generation - -.PHONY: test.%.top -test.%.top: inputs/test.%.a.c inputs/test.%.b.c inputs/test.%.driver.c - @true - -.PRECIOUS: inputs/test.%.a.c inputs/test.%.b.c inputs/test.%.driver.c -inputs/test.%.a.c: test.%.generate - @true -inputs/test.%.b.c: test.%.generate - @true -inputs/test.%.driver.c: test.%.generate - @true - -.PHONY: test.%.generate -.PRECIOUS: inputs/.dir -test.%.generate: $(ABITESTGEN) inputs/.dir - $(Verb) $(ABITESTGEN) $(TESTARGS) -o inputs/test.$*.a.c -T inputs/test.$*.b.c -D inputs/test.$*.driver.c --min=$(shell expr $* '*' $(COUNT)) --count=$(COUNT) - -# Cleaning - -clean-temps: - $(Verb) rm -rf temps - -clean: - $(Verb) rm -rf temps inputs - -# Etc. - -%/.dir: - $(Verb) mkdir -p $* > /dev/null - $(Verb) $(DATE) > $@ diff --git a/utils/ABITest/TypeGen.py b/utils/ABITest/TypeGen.py deleted file mode 100644 index 8561baea617b..000000000000 --- a/utils/ABITest/TypeGen.py +++ /dev/null @@ -1,477 +0,0 @@ -"""Flexible enumeration of C types.""" -from __future__ import division, print_function - -from Enumeration import * - -# TODO: - -# - struct improvements (flexible arrays, packed & -# unpacked, alignment) -# - objective-c qualified id -# - anonymous / transparent unions -# - VLAs -# - block types -# - K&R functions -# - pass arguments of different types (test extension, transparent union) -# - varargs - -### -# Actual type types - -class Type(object): - def isBitField(self): - return False - - def isPaddingBitField(self): - return False - - def getTypeName(self, printer): - name = 'T%d' % len(printer.types) - typedef = self.getTypedefDef(name, printer) - printer.addDeclaration(typedef) - return name - -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 getTypeName(self, printer): - return self.name - - def sizeof(self): - return self.size - - def __str__(self): - return self.name - -class EnumType(Type): - unique_id = 0 - - def __init__(self, index, enumerators): - self.index = index - self.enumerators = enumerators - self.unique_id = self.__class__.unique_id - self.__class__.unique_id += 1 - - def getEnumerators(self): - result = '' - for i, init in enumerate(self.enumerators): - if i > 0: - result = result + ', ' - result = result + 'enum%dval%d_%d' % (self.index, i, self.unique_id) - if init: - result = result + ' = %s' % (init) - - return result - - def __str__(self): - return 'enum { %s }' % (self.getEnumerators()) - - def getTypedefDef(self, name, printer): - return 'typedef enum %s { %s } %s;'%(name, self.getEnumerators(), name) - -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 getField(t): - if t.isBitField(): - return "%s : %d;" % (t, t.getBitFieldSize()) - else: - return "%s;" % t - - return '%s { %s }'%(('struct','union')[self.isUnion], - ' '.join(map(getField, self.fields))) - - def getTypedefDef(self, name, printer): - def getField(it): - i, t = it - 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 = [getField(f) for f in 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(Type): - def __init__(self, index, isVector, elementType, size): - if isVector: - # Note that for vectors, this is the size in bytes. - assert size > 0 - else: - assert size is None or size >= 0 - self.index = index - self.isVector = isVector - self.elementType = elementType - self.size = size - if isVector: - eltSize = self.elementType.sizeof() - assert not (self.size % eltSize) - self.numElements = self.size // eltSize - else: - self.numElements = self.size - - def __str__(self): - if self.isVector: - return 'vector (%s)[%d]'%(self.elementType,self.size) - elif self.size is not None: - return '(%s)[%d]'%(self.elementType,self.size) - else: - return '(%s)[]'%(self.elementType,) - - def getTypedefDef(self, name, printer): - elementName = printer.getTypeName(self.elementType) - if self.isVector: - return 'typedef %s %s __attribute__ ((vector_size (%d)));'%(elementName, - name, - self.size) - else: - if self.size is None: - sizeStr = '' - else: - sizeStr = str(self.size) - return 'typedef %s %s[%s];'%(elementName, name, sizeStr) - -class ComplexType(Type): - def __init__(self, index, elementType): - self.index = index - self.elementType = elementType - - def __str__(self): - return '_Complex (%s)'%(self.elementType) - - def getTypedefDef(self, name, printer): - return 'typedef _Complex %s %s;'%(printer.getTypeName(self.elementType), name) - -class FunctionType(Type): - def __init__(self, index, returnType, argTypes): - self.index = index - self.returnType = returnType - self.argTypes = argTypes - - def __str__(self): - if self.returnType is None: - rt = 'void' - else: - rt = str(self.returnType) - if not self.argTypes: - at = 'void' - else: - at = ', '.join(map(str, self.argTypes)) - return '%s (*)(%s)'%(rt, at) - - def getTypedefDef(self, name, printer): - if self.returnType is None: - rt = 'void' - else: - rt = str(self.returnType) - if not self.argTypes: - at = 'void' - else: - at = ', '.join(map(str, self.argTypes)) - return 'typedef %s (*%s)(%s);'%(rt, name, at) - -### -# Type enumerators - -class TypeGenerator(object): - def __init__(self): - self.cache = {} - - def setCardinality(self): - abstract - - def get(self, N): - T = self.cache.get(N) - if T is None: - assert 0 <= N < self.cardinality - T = self.cache[N] = self.generateType(N) - return T - - def generateType(self, N): - abstract - -class FixedTypeGenerator(TypeGenerator): - def __init__(self, types): - TypeGenerator.__init__(self) - self.types = types - self.setCardinality() - - def setCardinality(self): - self.cardinality = len(self.types) - - def generateType(self, N): - return self.types[N] - -# Factorial -def fact(n): - result = 1 - while n > 0: - result = result * n - n = n - 1 - return result - -# Compute the number of combinations (n choose k) -def num_combinations(n, k): - return fact(n) // (fact(k) * fact(n - k)) - -# Enumerate the combinations choosing k elements from the list of values -def combinations(values, k): - # From ActiveState Recipe 190465: Generator for permutations, - # combinations, selections of a sequence - if k==0: yield [] - else: - for i in range(len(values)-k+1): - for cc in combinations(values[i+1:],k-1): - yield [values[i]]+cc - -class EnumTypeGenerator(TypeGenerator): - def __init__(self, values, minEnumerators, maxEnumerators): - TypeGenerator.__init__(self) - self.values = values - self.minEnumerators = minEnumerators - self.maxEnumerators = maxEnumerators - self.setCardinality() - - def setCardinality(self): - self.cardinality = 0 - for num in range(self.minEnumerators, self.maxEnumerators + 1): - self.cardinality += num_combinations(len(self.values), num) - - def generateType(self, n): - # Figure out the number of enumerators in this type - numEnumerators = self.minEnumerators - valuesCovered = 0 - while numEnumerators < self.maxEnumerators: - comb = num_combinations(len(self.values), numEnumerators) - if valuesCovered + comb > n: - break - numEnumerators = numEnumerators + 1 - valuesCovered += comb - - # Find the requested combination of enumerators and build a - # type from it. - i = 0 - for enumerators in combinations(self.values, numEnumerators): - if i == n - valuesCovered: - return EnumType(n, enumerators) - - i = i + 1 - - assert False - -class ComplexTypeGenerator(TypeGenerator): - def __init__(self, typeGen): - TypeGenerator.__init__(self) - self.typeGen = typeGen - self.setCardinality() - - def setCardinality(self): - self.cardinality = self.typeGen.cardinality - - def generateType(self, N): - return ComplexType(N, self.typeGen.get(N)) - -class VectorTypeGenerator(TypeGenerator): - def __init__(self, typeGen, sizes): - TypeGenerator.__init__(self) - self.typeGen = typeGen - self.sizes = tuple(map(int,sizes)) - self.setCardinality() - - def setCardinality(self): - self.cardinality = len(self.sizes)*self.typeGen.cardinality - - def generateType(self, N): - S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality) - return ArrayType(N, True, self.typeGen.get(T), self.sizes[S]) - -class FixedArrayTypeGenerator(TypeGenerator): - def __init__(self, typeGen, sizes): - TypeGenerator.__init__(self) - self.typeGen = typeGen - self.sizes = tuple(size) - self.setCardinality() - - def setCardinality(self): - self.cardinality = len(self.sizes)*self.typeGen.cardinality - - def generateType(self, N): - S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality) - return ArrayType(N, false, self.typeGen.get(T), self.sizes[S]) - -class ArrayTypeGenerator(TypeGenerator): - def __init__(self, typeGen, maxSize, useIncomplete=False, useZero=False): - TypeGenerator.__init__(self) - self.typeGen = typeGen - self.useIncomplete = useIncomplete - self.useZero = useZero - self.maxSize = int(maxSize) - self.W = useIncomplete + useZero + self.maxSize - self.setCardinality() - - def setCardinality(self): - self.cardinality = self.W * self.typeGen.cardinality - - def generateType(self, N): - S,T = getNthPairBounded(N, self.W, self.typeGen.cardinality) - if self.useIncomplete: - if S==0: - size = None - S = None - else: - S = S - 1 - if S is not None: - if self.useZero: - size = S - else: - size = S + 1 - return ArrayType(N, False, self.typeGen.get(T), size) - -class RecordTypeGenerator(TypeGenerator): - def __init__(self, typeGen, useUnion, maxSize): - TypeGenerator.__init__(self) - self.typeGen = typeGen - self.useUnion = bool(useUnion) - self.maxSize = int(maxSize) - self.setCardinality() - - def setCardinality(self): - M = 1 + self.useUnion - if self.maxSize is aleph0: - S = aleph0 * self.typeGen.cardinality - else: - S = 0 - for i in range(self.maxSize+1): - S += M * (self.typeGen.cardinality ** i) - self.cardinality = S - - def generateType(self, N): - isUnion,I = False,N - if self.useUnion: - isUnion,I = (I&1),I>>1 - fields = [self.typeGen.get(f) for f in getNthTuple(I,self.maxSize,self.typeGen.cardinality)] - return RecordType(N, isUnion, fields) - -class FunctionTypeGenerator(TypeGenerator): - def __init__(self, typeGen, useReturn, maxSize): - TypeGenerator.__init__(self) - self.typeGen = typeGen - self.useReturn = useReturn - self.maxSize = maxSize - self.setCardinality() - - def setCardinality(self): - if self.maxSize is aleph0: - S = aleph0 * self.typeGen.cardinality() - elif self.useReturn: - S = 0 - for i in range(1,self.maxSize+1+1): - S += self.typeGen.cardinality ** i - else: - S = 0 - for i in range(self.maxSize+1): - S += self.typeGen.cardinality ** i - self.cardinality = S - - def generateType(self, N): - if self.useReturn: - # Skip the empty tuple - argIndices = getNthTuple(N+1, self.maxSize+1, self.typeGen.cardinality) - retIndex,argIndices = argIndices[0],argIndices[1:] - retTy = self.typeGen.get(retIndex) - else: - retTy = None - argIndices = getNthTuple(N, self.maxSize, self.typeGen.cardinality) - args = [self.typeGen.get(i) for i in argIndices] - return FunctionType(N, retTy, args) - -class AnyTypeGenerator(TypeGenerator): - def __init__(self): - TypeGenerator.__init__(self) - self.generators = [] - self.bounds = [] - self.setCardinality() - self._cardinality = None - - def getCardinality(self): - if self._cardinality is None: - return aleph0 - else: - return self._cardinality - def setCardinality(self): - self.bounds = [g.cardinality for g in self.generators] - self._cardinality = sum(self.bounds) - cardinality = property(getCardinality, None) - - def addGenerator(self, g): - self.generators.append(g) - for i in range(100): - prev = self._cardinality - self._cardinality = None - for g in self.generators: - g.setCardinality() - self.setCardinality() - if (self._cardinality is aleph0) or prev==self._cardinality: - break - else: - raise RuntimeError("Infinite loop in setting cardinality") - - def generateType(self, N): - index,M = getNthPairVariableBounds(N, self.bounds) - 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)]) - etg = EnumTypeGenerator([None, '-1', '1', '1u'], 0, 3) - - atg = AnyTypeGenerator() - atg.addGenerator( btg ) - atg.addGenerator( RecordTypeGenerator(fields0, False, 4) ) - atg.addGenerator( etg ) - 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__': - test() diff --git a/utils/ABITest/build-and-summarize-all.sh b/utils/ABITest/build-and-summarize-all.sh deleted file mode 100755 index 23e34a4669b6..000000000000 --- a/utils/ABITest/build-and-summarize-all.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -set -eu - -if [ $# != 1 ]; then - echo "usage: $0 <num-tests>" - exit 1 -fi - -for bits in 32 64; do - for kind in return-types single-args; do - echo "-- $kind-$bits --" - (cd $kind-$bits && ../build-and-summarize.sh $1) - done -done diff --git a/utils/ABITest/build-and-summarize.sh b/utils/ABITest/build-and-summarize.sh deleted file mode 100755 index 602728b79f91..000000000000 --- a/utils/ABITest/build-and-summarize.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -set -eu - -if [ $# != 1 ]; then - echo "usage: $0 <num-tests>" - exit 1 -fi - -dir=$(dirname $0) -$dir/build.sh $1 &> /dev/null || true -../summarize.sh $1 &> fails-x.txt -cat fails-x.txt -wc -l fails-x.txt diff --git a/utils/ABITest/build.sh b/utils/ABITest/build.sh deleted file mode 100755 index a50d14ab8d06..000000000000 --- a/utils/ABITest/build.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -set -eu - -if [ $# != 1 ]; then - echo "usage: $0 <num-tests>" - exit 1 -fi - -CPUS=2 -make -j $CPUS \ - $(for i in $(seq 0 $1); do echo test.$i.report; done) -k diff --git a/utils/ABITest/layout/Makefile b/utils/ABITest/layout/Makefile deleted file mode 100644 index 0520625fcf29..000000000000 --- a/utils/ABITest/layout/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# 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 --test-layout -COUNT := 1000 -TIMEOUT := 5 - -CFLAGS := -std=gnu99 - -X_COMPILER := llvm-gcc -Y_COMPILER := 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.* *~ diff --git a/utils/ABITest/return-types-32/Makefile b/utils/ABITest/return-types-32/Makefile deleted file mode 100644 index df1c53f1a166..000000000000 --- a/utils/ABITest/return-types-32/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -X_CFLAGS := -m32 -Y_CFLAGS := -m32 -CC_CFLAGS := -m32 - -include ../Makefile.test.common - -TESTARGS += --max-args 0 diff --git a/utils/ABITest/return-types-64/Makefile b/utils/ABITest/return-types-64/Makefile deleted file mode 100644 index 9616e45cba94..000000000000 --- a/utils/ABITest/return-types-64/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -X_CFLAGS := -m64 -Y_CFLAGS := -m64 -CC_CFLAGS := -m64 - -include ../Makefile.test.common - -TESTARGS += --max-args 0 diff --git a/utils/ABITest/single-args-32/Makefile b/utils/ABITest/single-args-32/Makefile deleted file mode 100644 index 9ff417fc29e5..000000000000 --- a/utils/ABITest/single-args-32/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -X_CFLAGS := -m32 -Y_CFLAGS := -m32 -CC_CFLAGS := -m32 - -include ../Makefile.test.common - -TESTARGS += --no-function-return --max-args 1 diff --git a/utils/ABITest/single-args-64/Makefile b/utils/ABITest/single-args-64/Makefile deleted file mode 100644 index b8acb70c1354..000000000000 --- a/utils/ABITest/single-args-64/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# 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. - -X_CFLAGS := -m64 -Y_CFLAGS := -m64 -CC_CFLAGS := -m64 - -include ../Makefile.test.common - -TESTARGS += --no-function-return --max-args 1 diff --git a/utils/ABITest/summarize.sh b/utils/ABITest/summarize.sh deleted file mode 100755 index 3efb52bf7227..000000000000 --- a/utils/ABITest/summarize.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -set -eu - -if [ $# != 1 ]; then - echo "usage: $0 <num-tests>" - exit 1 -fi - -for i in $(seq 0 $1); do - if (! make test.$i.report &> /dev/null); then - echo "FAIL: $i"; - fi; -done - diff --git a/utils/CIndex/completion_logger_server.py b/utils/CIndex/completion_logger_server.py deleted file mode 100755 index 201667117fc2..000000000000 --- a/utils/CIndex/completion_logger_server.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python -from __future__ import absolute_import, division, print_function -import sys -from socket import * -from time import strftime -import datetime - -def main(): - if len(sys.argv) < 4: - print("completion_logger_server.py <listen address> <listen port> <log file>") - exit(1) - - host = sys.argv[1] - port = int(sys.argv[2]) - buf = 1024 * 8 - addr = (host,port) - - # Create socket and bind to address - UDPSock = socket(AF_INET,SOCK_DGRAM) - UDPSock.bind(addr) - - print("Listing on {0}:{1} and logging to '{2}'".format(host, port, sys.argv[3])) - - # Open the logging file. - f = open(sys.argv[3], "a") - - # Receive messages - while 1: - data,addr = UDPSock.recvfrom(buf) - if not data: - break - else: - f.write("{ "); - f.write("\"time\": \"{0}\"".format(datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S'))) - f.write(", \"sender\": \"{0}\" ".format(addr[0])) - f.write(", \"data\": ") - f.write(data) - f.write(" }\n") - f.flush() - - # Close socket - UDPSock.close() - -if __name__ == '__main__': - main() diff --git a/utils/CaptureCmd b/utils/CaptureCmd deleted file mode 100755 index 705585c3bb04..000000000000 --- a/utils/CaptureCmd +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -"""CaptureCmd - A generic tool for capturing information about the -invocations of another program. - -Usage --- -1. Move the original tool to a safe known location. - -2. Link CaptureCmd to the original tool's location. - -3. Define CAPTURE_CMD_PROGRAM to the known location of the original -tool; this must be an absolute path. - -4. Define CAPTURE_CMD_DIR to a directory to write invocation -information to. -""" - -import hashlib -import os -import sys -import time - -def saveCaptureData(prefix, dir, object): - string = repr(object) + '\n' - key = hashlib.sha1(string).hexdigest() - path = os.path.join(dir, - prefix + key) - if not os.path.exists(path): - f = open(path, 'wb') - f.write(string) - f.close() - return prefix + key - -def main(): - program = os.getenv('CAPTURE_CMD_PROGRAM') - dir = os.getenv('CAPTURE_CMD_DIR') - fallback = os.getenv('CAPTURE_CMD_FALLBACK') - if not program: - raise ValueError('CAPTURE_CMD_PROGRAM is not defined!') - if not dir: - raise ValueError('CAPTURE_CMD_DIR is not defined!') - - # Make the output directory if it doesn't already exist. - if not os.path.exists(dir): - os.mkdir(dir, 0700) - - # Get keys for various data. - env = os.environ.items() - env.sort() - envKey = saveCaptureData('env-', dir, env) - cwdKey = saveCaptureData('cwd-', dir, os.getcwd()) - argvKey = saveCaptureData('argv-', dir, sys.argv) - entry = (time.time(), envKey, cwdKey, argvKey) - saveCaptureData('cmd-', dir, entry) - - if fallback: - pid = os.fork() - if not pid: - os.execv(program, sys.argv) - os._exit(1) - else: - res = os.waitpid(pid, 0) - if not res: - os.execv(fallback, sys.argv) - os._exit(1) - os._exit(res) - else: - os.execv(program, sys.argv) - os._exit(1) - -if __name__ == '__main__': - main() diff --git a/utils/ClangDataFormat.py b/utils/ClangDataFormat.py deleted file mode 100644 index 38ef76b32535..000000000000 --- a/utils/ClangDataFormat.py +++ /dev/null @@ -1,161 +0,0 @@ -"""lldb data formatters for clang classes. - -Usage --- -import this file in your ~/.lldbinit by adding this line: - -command script import /path/to/ClangDataFormat.py - -After that, instead of getting this: - -(lldb) p Tok.Loc -(clang::SourceLocation) $0 = { - (unsigned int) ID = 123582 -} - -you'll get: - -(lldb) p Tok.Loc -(clang::SourceLocation) $4 = "/usr/include/i386/_types.h:37:1" (offset: 123582, file, local) -""" - -import lldb - -def __lldb_init_module(debugger, internal_dict): - debugger.HandleCommand("type summary add -F ClangDataFormat.SourceLocation_summary clang::SourceLocation") - debugger.HandleCommand("type summary add -F ClangDataFormat.QualType_summary clang::QualType") - debugger.HandleCommand("type summary add -F ClangDataFormat.StringRef_summary llvm::StringRef") - -def SourceLocation_summary(srcloc, internal_dict): - return SourceLocation(srcloc).summary() - -def QualType_summary(qualty, internal_dict): - return QualType(qualty).summary() - -def StringRef_summary(strref, internal_dict): - return StringRef(strref).summary() - -class SourceLocation(object): - def __init__(self, srcloc): - self.srcloc = srcloc - self.ID = srcloc.GetChildAtIndex(0).GetValueAsUnsigned() - self.frame = srcloc.GetFrame() - - def offset(self): - return getValueFromExpression(self.srcloc, ".getOffset()").GetValueAsUnsigned() - - def isInvalid(self): - return self.ID == 0 - - def isMacro(self): - return getValueFromExpression(self.srcloc, ".isMacroID()").GetValueAsUnsigned() - - def isLocal(self, srcmgr_path): - return self.frame.EvaluateExpression("(%s).isLocalSourceLocation(%s)" % (srcmgr_path, getExpressionPath(self.srcloc))).GetValueAsUnsigned() - - def getPrint(self, srcmgr_path): - print_str = getValueFromExpression(self.srcloc, ".printToString(%s)" % srcmgr_path) - return print_str.GetSummary() - - def summary(self): - if self.isInvalid(): - return "<invalid loc>" - srcmgr_path = findObjectExpressionPath("clang::SourceManager", self.frame) - if srcmgr_path: - return "%s (offset: %d, %s, %s)" % (self.getPrint(srcmgr_path), self.offset(), "macro" if self.isMacro() else "file", "local" if self.isLocal(srcmgr_path) else "loaded") - return "(offset: %d, %s)" % (self.offset(), "macro" if self.isMacro() else "file") - -class QualType(object): - def __init__(self, qualty): - self.qualty = qualty - - def getAsString(self): - std_str = getValueFromExpression(self.qualty, ".getAsString()") - return std_str.GetSummary() - - def summary(self): - desc = self.getAsString() - if desc == '"NULL TYPE"': - return "<NULL TYPE>" - return desc - -class StringRef(object): - def __init__(self, strref): - self.strref = strref - self.Data_value = strref.GetChildAtIndex(0) - self.Length = strref.GetChildAtIndex(1).GetValueAsUnsigned() - - def summary(self): - if self.Length == 0: - return '""' - data = self.Data_value.GetPointeeData(0, self.Length) - error = lldb.SBError() - string = data.ReadRawData(error, 0, data.GetByteSize()) - if error.Fail(): - return None - return '"%s"' % string - - -# Key is a (function address, type name) tuple, value is the expression path for -# an object with such a type name from inside that function. -FramePathMapCache = {} - -def findObjectExpressionPath(typename, frame): - func_addr = frame.GetFunction().GetStartAddress().GetFileAddress() - key = (func_addr, typename) - try: - return FramePathMapCache[key] - except KeyError: - #print "CACHE MISS" - path = None - obj = findObject(typename, frame) - if obj: - path = getExpressionPath(obj) - FramePathMapCache[key] = path - return path - -def findObject(typename, frame): - def getTypename(value): - # FIXME: lldb should provide something like getBaseType - ty = value.GetType() - if ty.IsPointerType() or ty.IsReferenceType(): - return ty.GetPointeeType().GetName() - return ty.GetName() - - def searchForType(value, searched): - tyname = getTypename(value) - #print "SEARCH:", getExpressionPath(value), value.GetType().GetName() - if tyname == typename: - return value - ty = value.GetType() - if not (ty.IsPointerType() or - ty.IsReferenceType() or - # FIXME: lldb should provide something like getCanonicalType - tyname.startswith("llvm::IntrusiveRefCntPtr<") or - tyname.startswith("llvm::OwningPtr<")): - return None - # FIXME: Hashing for SBTypes does not seem to work correctly, uses the typename instead, - # and not the canonical one unfortunately. - if tyname in searched: - return None - searched.add(tyname) - for i in range(value.GetNumChildren()): - child = value.GetChildAtIndex(i, 0, False) - found = searchForType(child, searched) - if found: - return found - - searched = set() - value_list = frame.GetVariables(True, True, True, True) - for val in value_list: - found = searchForType(val, searched) - if found: - return found if not found.TypeIsPointerType() else found.Dereference() - -def getValueFromExpression(val, expr): - return val.GetFrame().EvaluateExpression(getExpressionPath(val) + expr) - -def getExpressionPath(val): - stream = lldb.SBStream() - val.GetExpressionPath(stream) - return stream.GetData() diff --git a/utils/ClangVisualizers/CMakeLists.txt b/utils/ClangVisualizers/CMakeLists.txt deleted file mode 100644 index 16d118a421ba..000000000000 --- a/utils/ClangVisualizers/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Do this by hand instead of using add_llvm_utilities(), which -# tries to create a corresponding executable, which we don't want. -if (LLVM_ADD_NATIVE_VISUALIZERS_TO_SOLUTION) - set(CLANG_VISUALIZERS clang.natvis) - add_custom_target(ClangVisualizers SOURCES ${CLANG_VISUALIZERS}) - set_target_properties(ClangVisualizers PROPERTIES FOLDER "Utils") -endif() diff --git a/utils/ClangVisualizers/clang.natvis b/utils/ClangVisualizers/clang.natvis deleted file mode 100644 index 17556f9cabb1..000000000000 --- a/utils/ClangVisualizers/clang.natvis +++ /dev/null @@ -1,627 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!--
-Visual Studio Native Debugging Visualizers for LLVM
-
-For Visual Studio 2013 only, put this file into
-"%USERPROFILE%\Documents\Visual Studio 2013\Visualizers" or create a symbolic link so it updates automatically.
-
-For later versions of Visual Studio, no setup is required-->
-<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
-
- <Type Name="clang::Type">
- <!-- To visualize clang::Types, we need to look at TypeBits.TC to determine the actual
- type subclass and manually dispatch accordingly (Visual Studio can't identify the real type
- because clang::Type has no virtual members hence no RTTI).
-
- Views:
- "cmn": Visualization that is common to all clang::Type subclasses
- "poly": Visualization that is specific to the actual clang::Type subclass. The subtype-specific
- <DisplayString> is typically as C++-like as possible (like in dump()) with <Expand>
- containing all the gory details.
- "cpp": Only occasionally used when we need to distinguish between an ordinary view and a C++-like view.
- -->
- <DisplayString IncludeView="cmn" Condition="TypeBits.TC==clang::LocInfoType::LocInfo">LocInfoType</DisplayString>
- <DisplayString IncludeView="cmn">{(clang::Type::TypeClass)TypeBits.TC, en}Type</DisplayString>
- <!-- Dispatch to visualizers for the actual Type subclass -->
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::Builtin" IncludeView="poly">{*(clang::BuiltinType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::Pointer" IncludeView="poly">{*(clang::PointerType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::LValueReference" IncludeView="poly">{*(clang::LValueReferenceType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::RValueReference" IncludeView="poly">{*(clang::RValueReferenceType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::Attributed" IncludeView="poly">{*(clang::AttributedType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::TemplateTypeParm" IncludeView="poly">{*(clang::TemplateTypeParmType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::SubstTemplateTypeParm" IncludeView="poly">{*(clang::SubstTemplateTypeParmType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::Record" IncludeView="poly">{*(clang::RecordType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::Record" IncludeView="cpp">{*(clang::RecordType *)this,view(cpp)}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::FunctionProto" IncludeView="poly">{*(clang::FunctionProtoType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::TemplateSpecialization" IncludeView="poly">{*(clang::TemplateSpecializationType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::DeducedTemplateSpecialization" IncludeView="poly">{*(clang::DeducedTemplateSpecializationType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::InjectedClassName" IncludeView="poly">{*(clang::InjectedClassNameType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::PackExpansion" IncludeView="poly">{*(clang::PackExpansionType *)this}</DisplayString>
- <DisplayString Condition="TypeBits.TC==clang::LocInfoType::LocInfo" IncludeView="poly">{*(clang::LocInfoType *)this}</DisplayString>
- <DisplayString IncludeView="cpp">{*this,view(poly)}</DisplayString>
- <DisplayString IncludeView="poly">No visualizer yet for {(clang::Type::TypeClass)TypeBits.TC,en}Type</DisplayString> <!-- Not yet implemented Type subclass -->
- <DisplayString IncludeView="Dependent" Condition="TypeBits.Dependent">Dependent{" ",sb}</DisplayString>
- <DisplayString IncludeView="Dependent"></DisplayString>
- <DisplayString IncludeView="InstantiationDependent" Condition="TypeBits.InstantiationDependent">InstantiationDependent{" ",sb}</DisplayString>
- <DisplayString IncludeView="InstantiationDependent"></DisplayString>
- <DisplayString IncludeView="VariablyModified" Condition="TypeBits.VariablyModified">VariablyModified{" ",sb}</DisplayString>
- <DisplayString IncludeView="VariablyModified"></DisplayString>
- <DisplayString IncludeView="ContainsUnexpandedParameterPack" Condition="TypeBits.ContainsUnexpandedParameterPack">ContainsUnexpandedParameterPack{" ",sb}</DisplayString>
- <DisplayString IncludeView="ContainsUnexpandedParameterPack"></DisplayString>
- <DisplayString IncludeView="Cache" Condition="TypeBits.CacheValid && TypeBits.CachedLocalOrUnnamed">CachedLinkage: {(clang::Linkage)TypeBits.CachedLinkage,en} CachedLocalOrUnnamed</DisplayString>
- <DisplayString IncludeView="Cache" Condition="TypeBits.CacheValid && !TypeBits.CachedLocalOrUnnamed">CachedLinkage: {(clang::Linkage)TypeBits.CachedLinkage,en}{" ",sb}</DisplayString>
- <DisplayString IncludeView="Cache"></DisplayString>
- <DisplayString IncludeView="FromAST" Condition="TypeBits.FromAST">FromAST</DisplayString>
- <DisplayString IncludeView="FromAST"></DisplayString>
- <DisplayString IncludeView="flags" Condition="!TypeBits.Dependent && !TypeBits.InstantiationDependent && !TypeBits.VariablyModified && !TypeBits.ContainsUnexpandedParameterPack && !TypeBits.CacheValid && !TypeBits.FromAST">
- No TypeBits set beyond TypeClass
- </DisplayString>
- <DisplayString IncludeView="flags">
-{*this, view(Dependent)}{*this, view(InstantiationDependent)}{*this, view(VariablyModified)}
-{*this, view(ContainsUnexpandedParameterPack)}{*this, view(Cache)}{*this, view(FromAST)}</DisplayString>
- <DisplayString>{*this,view(cmn)} {{{*this,view(poly)}}}</DisplayString>
- <Expand>
- <Item Name="TypeClass" IncludeView="cmn">(clang::Type::TypeClass)TypeBits.TC</Item>
- <Item Name="Flags" IncludeView="cmn">*this,view(flags)</Item>
- <Item Name="Canonical" IncludeView="cmn">CanonicalType</Item>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::Builtin">*(clang::BuiltinType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::Pointer">*(clang::PointerType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::LValueReference">*(clang::LValueReferenceType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::RValueReference">*(clang::RValueReferenceType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::Attributed">*(clang::AttributedType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::TemplateTypeParm">(clang::TemplateTypeParmType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::SubstTemplateTypeParm">(clang::SubstTemplateTypeParmType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::Record">(clang::RecordType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::FunctionProto">(clang::FunctionProtoType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::TemplateSpecialization">(clang::TemplateSpecializationType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::DeducedTemplateSpecialization">(clang::DeducedTemplateSpecializationType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::InjectedClassName">(clang::InjectedClassNameType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::PackExpansion">(clang::PackExpansionType *)this</ExpandedItem>
- <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::LocInfoType::LocInfo">(clang::LocInfoType *)this</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::PointerType">
- <DisplayString>{PointeeType, view(poly)} *</DisplayString>
- <Expand>
- <Item Name="PointeeType">PointeeType</Item>
- <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
- </Expand>
- </Type>
- <!-- We visualize all inner types for clang reference types. So a rvalue reference to an lvalue reference
- to an int would visual as int & && This is a little different than GetPointeeType(),
- but more clearly displays the data structure and seems natural -->
- <Type Name="clang::LValueReferenceType">
- <DisplayString>{((clang::ReferenceType *)this)->PointeeType,view(cpp)} &</DisplayString>
- <Expand>
- <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
- <Item Name="PointeeType">PointeeType</Item>
- </Expand>
- </Type>
- <Type Name="clang::RValueReferenceType">
- <DisplayString>{((clang::ReferenceType *)this)->PointeeType,view(cpp)} &&</DisplayString>
- <Expand>
- <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
- <Item Name="PointeeType">PointeeType</Item>
- </Expand>
- </Type>
- <Type Name="clang::AttributedType">
- <DisplayString>{ModifiedType} Attribute={(clang::AttributedType::Kind)AttributedTypeBits.AttrKind}</DisplayString>
- </Type>
-
- <!-- Unfortunately, Visual Studio has trouble seeing the PointerBitMask member PointerIntUnion, so I hardwire it to 2 bits-->
- <Type Name="clang::DeclContext">
- <DisplayString>{(clang::Decl::Kind)DeclKind,en}Decl</DisplayString>
- <Expand>
- <Item Name="DeclKind">(clang::Decl::Kind)DeclKind,en</Item>
- <Synthetic Name="Members">
- <DisplayString></DisplayString>
- <Expand>
- <LinkedListItems>
- <HeadPointer>FirstDecl</HeadPointer>
- <NextPointer>(clang::Decl *)(NextInContextAndBits.Value & ~3)</NextPointer>
- <ValueNode>*this</ValueNode>
- </LinkedListItems>
- </Expand>
- </Synthetic>
- </Expand>
- </Type>
- <Type Name="clang::FieldDecl">
- <DisplayString>Field {{{*(clang::DeclaratorDecl *)this,view(cpp)nd}}}</DisplayString>
- </Type>
- <Type Name="clang::CXXMethodDecl">
- <DisplayString IncludeView="cpp">{*(clang::FunctionDecl *)this,nd}</DisplayString>
- <DisplayString>Method {{{*this,view(cpp)}}}</DisplayString>
- </Type>
- <Type Name="clang::CXXConstructorDecl">
- <DisplayString>Constructor {{{Name,view(cpp)}({*(clang::FunctionDecl *)this,view(parm0)nd})}}</DisplayString>
- </Type>
- <Type Name="clang::CXXDestructorDecl">
- <DisplayString>Destructor {{~{Name,view(cpp)}()}}</DisplayString>
- </Type>
- <Type Name="clang::TemplateTypeParmDecl">
- <DisplayString IncludeView="TorC" Condition="Typename">typename</DisplayString>
- <DisplayString IncludeView="TorC" Condition="!Typename">class</DisplayString>
- <DisplayString IncludeView="MaybeEllipses" Condition="TypeForDecl == nullptr">(not yet known if parameter pack) </DisplayString>
- <DisplayString IncludeView="MaybeEllipses" Condition="((TemplateTypeParmType *)(((clang::ExtQualsTypeCommonBase *)(((uintptr_t)TypeForDecl->CanonicalType.Value.Value) & ~(uintptr_t)((1 << 4) - 1)))->BaseType))->CanTTPTInfo.ParameterPack">...</DisplayString>
- <DisplayString IncludeView="MaybeEllipses" Condition="!((TemplateTypeParmType *)(((clang::ExtQualsTypeCommonBase *)(((uintptr_t)TypeForDecl->CanonicalType.Value.Value) & ~(uintptr_t)((1 << 4) - 1)))->BaseType))->CanTTPTInfo.ParameterPack"></DisplayString>
- <DisplayString>{*this,view(TorC)} {*this,view(MaybeEllipses)}{Name,view(cpp)}</DisplayString>
- </Type>
- <Type Name="clang::TemplateDecl">
- <DisplayString>template{TemplateParams,view(deref)} {*TemplatedDecl};</DisplayString>
- </Type>
- <Type Name="clang::TemplateName">
- <DisplayString>{Storage,view(deref)}</DisplayString>
- <Expand>
- <ExpandedItem>Storage</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::NamedDecl" >
- <DisplayString IncludeView="cpp">{Name,view(cpp)}</DisplayString>
- <DisplayString>{Name}</DisplayString>
- </Type>
- <Type Name="clang::TagDecl">
- <DisplayString IncludeView="implicit" Condition="Implicit">implicit{" ",sb}</DisplayString>
- <DisplayString IncludeView="implicit"></DisplayString>
- <DisplayString IncludeView="modifiers">{*this,view(implicit)nd}</DisplayString>
- <DisplayString IncludeView="cpp">{*this,view(modifiers)}{Name,view(cpp)}</DisplayString>
- <DisplayString Condition="TagDeclBits.TagDeclKind==clang::TagTypeKind::TTK_Struct">{*this,view(modifiers)nd}struct {Name,view(cpp)}</DisplayString>
- <DisplayString Condition="TagDeclBits.TagDeclKind==clang::TagTypeKind::TTK_Interface">{*this,view(modifiers)nd}interface {Name,view(cpp)}</DisplayString>
- <DisplayString Condition="TagDeclBits.TagDeclKind==clang::TagTypeKind::TTK_Union">{*this,view(modifiers)nd}union {Name,view(cpp)}</DisplayString>
- <DisplayString Condition="TagDeclBits.TagDeclKind==clang::TagTypeKind::TTK_Class">{*this,view(modifiers)nd}class {Name,view(cpp)}</DisplayString>
- <DisplayString Condition="TagDeclBits.TagDeclKind==clang::TagTypeKind::TTK_Enum">{*this,view(modifiers)nd}enum {Name,view(cpp)}</DisplayString>
- <Expand>
- <ExpandedItem>(clang::DeclContext *)this</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::TagType">
- <DisplayString IncludeView="cpp">{*decl,view(cpp)}</DisplayString>
- <DisplayString>{*decl}</DisplayString>
- <Expand>
- <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
- <Item Name="decl">decl</Item>
- </Expand>
- </Type>
- <Type Name="clang::RecordType">
- <DisplayString IncludeView="cpp">{*(clang::TagType *)this,view(cpp)}</DisplayString>
- <DisplayString>{*(clang::TagType *)this}</DisplayString>
- <Expand>
- <Item Name="TagType">*(clang::TagType *)this</Item>
- </Expand>
- </Type>
- <Type Name="clang::SubstTemplateTypeParmType">
- <DisplayString>{*Replaced,view(cpp)} <= {CanonicalType,view(cpp)}</DisplayString>
- <Expand>
- <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
- <Item Name="Replaced">*Replaced</Item>
- </Expand>
- </Type>
- <!-- We only show the first 5 parameter types in the display string (can't figure out how to loop in DisplayString)
- but the expansion has all parameters -->
- <Type Name="clang::FunctionProtoType">
- <DisplayString IncludeView="retType">{ResultType,view(cpp)}</DisplayString>
- <DisplayString IncludeView="parm0" Condition="FunctionTypeBits.NumParams==0"></DisplayString>
- <DisplayString IncludeView="parm0">{*(clang::QualType *)(this+1),view(cpp)}{*this,view(parm1)}</DisplayString>
- <DisplayString IncludeView="parm1" Condition="FunctionTypeBits.NumParams==1"></DisplayString>
- <DisplayString IncludeView="parm1">, {*((clang::QualType *)(this+1)+1),view(cpp)}{*this,view(parm2)}</DisplayString>
- <DisplayString IncludeView="parm2" Condition="FunctionTypeBits.NumParams==2"></DisplayString>
- <DisplayString IncludeView="parm2">, {*((clang::QualType *)(this+1)+2),view(cpp)}{*this,view(parm3)}</DisplayString>
- <DisplayString IncludeView="parm3" Condition="FunctionTypeBits.NumParams==3"></DisplayString>
- <DisplayString IncludeView="parm3">, {*((clang::QualType *)(this+1)+3),view(cpp)}{*this,view(parm4)}</DisplayString>
- <DisplayString IncludeView="parm4" Condition="FunctionTypeBits.NumParams==4"></DisplayString>
- <DisplayString IncludeView="parm4">, {*((clang::QualType *)(this+1)+4),view(cpp)}{*this,view(parm5)}</DisplayString>
- <DisplayString IncludeView="parm5" Condition="FunctionTypeBits.NumParams==5"></DisplayString>
- <DisplayString IncludeView="parm5">, /* expand for more params */</DisplayString>
- <DisplayString>{*this,view(retType)}({*this,view(parm0)})</DisplayString>
- <Expand>
- <Item Name="ReturnType">ResultType</Item>
- <Synthetic Name="Parameter Types">
- <DisplayString>{*this,view(parm0)}</DisplayString>
- <Expand>
- <ArrayItems>
- <Size>FunctionTypeBits.NumParams</Size>
- <ValuePointer>(clang::QualType *)(this+1)</ValuePointer>
- </ArrayItems>
- </Expand>
- </Synthetic>
- <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::TemplateTypeParmType">
- <DisplayString IncludeView="cpp" Condition="CanonicalType.Value.Value != this">{*TTPDecl}</DisplayString>
- <DisplayString Condition="CanonicalType.Value.Value != this">Non-canonical: {*TTPDecl}</DisplayString>
- <DisplayString>Canonical: {CanTTPTInfo}</DisplayString>
- <Expand>
- </Expand>
- </Type>
- <Type Name="clang::InjectedClassNameType">
- <DisplayString>{*Decl,view(cpp)}</DisplayString>
- <Expand>
- <Item Name="Decl">Decl</Item>
- <Item Name="InjectedType">InjectedType</Item>
- <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::PackExpansionType">
- <DisplayString>{Pattern}</DisplayString>
- <Expand>
- <Item Name="Pattern">Pattern</Item>
- <Item Name="NumExpansions">NumExpansions</Item>
- <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::QualType">
- <!-- When VS2013 support is deprecated, change 4 to clang::TypeAlignmentInBits (not properly recognized by VS2013) -->
- <DisplayString IncludeView="poly">{*((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) & ~(uintptr_t)((1 << 4) - 1)))->BaseType,view(poly)}{*this,view(fastQuals)}</DisplayString>
- <DisplayString IncludeView="cpp">{*((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) & ~(uintptr_t)((1 << 4) - 1)))->BaseType,view(cpp)}{*this,view(fastQuals)}</DisplayString>
- <!-- For the Fast Qualifiers, it is simpler (and probably more efficient) just to list all 8 cases than create
- views for each qualifier. TODO: Non-fast qualifiers -->
- <DisplayString IncludeView="fastQuals" Condition="(Value.Value & 15)==0"></DisplayString>
- <DisplayString IncludeView="fastQuals" Condition="(Value.Value & 15)==1">{" ",sb}const</DisplayString>
- <DisplayString IncludeView="fastQuals" Condition="(Value.Value & 15)==2">{" ",sb}restrict</DisplayString>
- <DisplayString IncludeView="fastQuals" Condition="(Value.Value & 15)==3">{" ",sb}const restrict</DisplayString>
- <DisplayString IncludeView="fastQuals" Condition="(Value.Value & 15)==4">{" ",sb}volatile</DisplayString>
- <DisplayString IncludeView="fastQuals" Condition="(Value.Value & 15)==5">{" ",sb}const volatile</DisplayString>
- <DisplayString IncludeView="fastQuals" Condition="(Value.Value & 15)==6">{" ",sb}volatile restrict</DisplayString>
- <DisplayString IncludeView="fastQuals" Condition="(Value.Value & 15)==7">{" ",sb}const volatile restrict</DisplayString>
- <DisplayString IncludeView="fastQuals">Cannot visualize non-fast qualifiers</DisplayString>
- <DisplayString Condition="(uintptr_t)Value.Value == 0">Null</DisplayString>
- <DisplayString>{*((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) & ~(uintptr_t)((1 << 4) - 1)))->BaseType}{*this,view(fastQuals)}</DisplayString>
- <Expand>
- <Item Name="Fast Quals">*this,view(fastQuals)</Item>
- <ExpandedItem>*((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) & ~(uintptr_t)((1 << 4) - 1)))->BaseType</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::LocInfoType">
- <DisplayString>{*DeclInfo}</DisplayString>
- <Expand>
- <Item Name="DeclInfo">DeclInfo</Item>
- <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::TypeSourceInfo">
- <DisplayString>{Ty}</DisplayString>
- </Type>
- <Type Name="clang::TemplateArgumentLoc">
- <DisplayString>{Argument}</DisplayString>
- <Expand>
- <ExpandedItem>Argument</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::TemplateArgument">
- <DisplayString IncludeView="cpp" Condition="Integer.Kind == clang::TemplateArgument::ArgKind::Type">{*(clang::QualType *)&TypeOrValue.V,view(cpp)}</DisplayString>
- <DisplayString Condition="Integer.Kind == clang::TemplateArgument::ArgKind::Type">{(clang::TemplateArgument::ArgKind)TypeOrValue.Kind,en} template argument: {*(clang::QualType *)&TypeOrValue.V}</DisplayString>
- <DisplayString IncludeView="arg0" Condition="Args.NumArgs==0"></DisplayString>
- <DisplayString IncludeView="arg0">{Args.Args[0]}{*this,view(arg1)}</DisplayString>
- <DisplayString IncludeView="arg1" Condition="Args.NumArgs==1"></DisplayString>
- <DisplayString IncludeView="arg1">, {Args.Args[1]}{*this,view(arg2)}</DisplayString>
- <DisplayString IncludeView="arg2" Condition="Args.NumArgs==2"></DisplayString>
- <DisplayString IncludeView="arg2">, {Args.Args[2]}, ...</DisplayString>
- <DisplayString IncludeView="arg0cpp" Condition="Args.NumArgs==0"></DisplayString>
- <DisplayString IncludeView="arg0cpp">{Args.Args[0],view(cpp)}{*this,view(arg1cpp)}</DisplayString>
- <DisplayString IncludeView="arg1cpp" Condition="Args.NumArgs==1"></DisplayString>
- <DisplayString IncludeView="arg1cpp">, {Args.Args[1],view(cpp)}{*this,view(arg2cpp)}</DisplayString>
- <DisplayString IncludeView="arg2cpp" Condition="Args.NumArgs==2"></DisplayString>
- <DisplayString IncludeView="arg2cpp">, {Args.Args[2],view(cpp)}, ...</DisplayString>
- <DisplayString IncludeView="cpp" Condition="Integer.Kind == clang::TemplateArgument::ArgKind::Pack">{*this,view(arg0cpp)}</DisplayString>
- <DisplayString Condition="Integer.Kind == clang::TemplateArgument::ArgKind::Pack">{*this,view(arg0)}</DisplayString>
- <DisplayString>{(clang::TemplateArgument::ArgKind)TypeOrValue.Kind,en}</DisplayString>
- <Expand>
- <Item Name="QualType" Condition="Integer.Kind == clang::TemplateArgument::ArgKind::Type">*(clang::QualType *)&TypeOrValue.V</Item>
- <ArrayItems Condition="Integer.Kind == clang::TemplateArgument::ArgKind::Pack">
- <Size>Args.NumArgs</Size>
- <ValuePointer>Args.Args</ValuePointer>
- </ArrayItems>
- <!-- TODO: Other kinds-->
- </Expand>
- </Type>
- <Type Name="clang::TemplateArgumentList">
- <DisplayString IncludeView="arg0" Condition="NumArguments==0"></DisplayString>
- <DisplayString IncludeView="arg0">{Arguments[0],view(cpp)}{*this,view(arg1)}</DisplayString>
- <DisplayString IncludeView="arg1" Condition="NumArguments==1"></DisplayString>
- <DisplayString IncludeView="arg1">, {Arguments[1],view(cpp)}{*this,view(arg2)}</DisplayString>
- <DisplayString IncludeView="arg2" Condition="NumArguments==2"></DisplayString>
- <DisplayString IncludeView="arg2">, {Arguments[1],view(cpp)}, ...</DisplayString>
- <DisplayString><{*this,view(arg0)}></DisplayString>
- <Expand>
- <Item Name="NumArguments">NumArguments</Item>
- <ArrayItems>
- <Size>NumArguments</Size>
- <ValuePointer>Arguments</ValuePointer>
- </ArrayItems>
- </Expand>
- </Type>
- <Type Name="llvm::ArrayRef<clang::TemplateArgument>">
- <DisplayString IncludeView="arg0" Condition="Length==0"></DisplayString>
- <DisplayString IncludeView="arg0">{Data[0],view(cpp)}{*this,view(arg1)}</DisplayString>
- <DisplayString IncludeView="arg1" Condition="Length==1"></DisplayString>
- <DisplayString IncludeView="arg1">, {Data[1],view(cpp)}{*this,view(arg2)}</DisplayString>
- <DisplayString IncludeView="arg2" Condition="Length==2"></DisplayString>
- <DisplayString IncludeView="arg2">, {Data[2],view(cpp)}, ...</DisplayString>
- <DisplayString><{*this,view(arg0)}></DisplayString>
- </Type>
- <Type Name="clang::MultiLevelTemplateArgumentList">
- <DisplayString IncludeView="level0" Condition="(llvm::ArrayRef<clang::TemplateArgument> *)TemplateArgumentLists.EndX - (llvm::ArrayRef<clang::TemplateArgument> *)TemplateArgumentLists.BeginX==0"></DisplayString>
- <DisplayString IncludeView="level0">{((llvm::ArrayRef<clang::TemplateArgument> *)TemplateArgumentLists.BeginX)[0],view(cpp)}{*this,view(level1)}</DisplayString>
- <DisplayString IncludeView="level1" Condition="(llvm::ArrayRef<clang::TemplateArgument> *)TemplateArgumentLists.EndX - (llvm::ArrayRef<clang::TemplateArgument> *)TemplateArgumentLists.BeginX==1"></DisplayString>
- <DisplayString IncludeView="level1">::{((llvm::ArrayRef<clang::TemplateArgument> *)TemplateArgumentLists.BeginX)[1],view(cpp)}{*this,view(level2)}</DisplayString>
- <DisplayString IncludeView="level2" Condition="(llvm::ArrayRef<clang::TemplateArgument> *)TemplateArgumentLists.EndX - (llvm::ArrayRef<clang::TemplateArgument> *)TemplateArgumentLists.BeginX==2"></DisplayString>
- <DisplayString IncludeView="level2">::{((llvm::ArrayRef<clang::TemplateArgument> *)TemplateArgumentLists.BeginX)[2],view(cpp)}, ...</DisplayString>
- <DisplayString>{*this,view(level0)}</DisplayString>
- <Expand>
- <Item Name="TemplateList">TemplateArgumentLists</Item>
- </Expand>
- </Type>
- <Type Name="clang::ParsedTemplateArgument">
- <DisplayString Condition="Kind==clang::ParsedTemplateArgument::Type">Type template argument: {*(clang::QualType *)Arg}</DisplayString>
- <DisplayString Condition="Kind==clang::ParsedTemplateArgument::NonType">Non-type template argument: {*(clang::Expr *)Arg}</DisplayString>
- <DisplayString Condition="Kind==clang::ParsedTemplateArgument::Template">Template template argument: {*(clang::TemplateName *)Arg</DisplayString>
- <Expand>
- <Item Name="Kind">Kind,en</Item>
- <Item Name="Arg" Condition="Kind==clang::ParsedTemplateArgument::Type">(clang::QualType *)Arg</Item>
- <Item Name="Arg" Condition="Kind==clang::ParsedTemplateArgument::NonType">(clang::Expr *)Arg</Item>
- <Item Name="Arg" Condition="Kind==clang::ParsedTemplateArgument::Template">(clang::TemplateName *)Arg</Item>
- </Expand>
- </Type>
- <!-- Builtin types that have C++ keywords are manually displayed as that keyword. Otherwise, just use the enum name -->
- <Type Name="clang::BuiltinType">
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Void">void</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Bool">bool</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Char_U">char</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::UChar">unsigned char</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::WChar_U">wchar_t</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Char16">char16_t</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Char32">char32_t</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::UShort">unsigned short</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::UInt">unsigned int</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::ULong">unsigned long</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::ULongLong">unsigned long long</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::UInt128">__uint128_t</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Char_S">char</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::SChar">signed char</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::WChar_S">wchar_t</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Short">short</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Int">int</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Long">long</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::LongLong">long long</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Int128">__int128_t</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Half">__fp16</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Float">float</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Double">double</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::LongDouble">long double</DisplayString>
- <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::NullPtr">nullptr_t</DisplayString>
- <DisplayString>{(clang::BuiltinType::Kind)BuiltinTypeBits.Kind, en}</DisplayString>
- <Expand>
- <Item Name="Kind">(clang::BuiltinType::Kind)BuiltinTypeBits.Kind</Item>
- </Expand>
- </Type>
-
- <Type Name="clang::TemplateSpecializationType">
- <DisplayString IncludeView="arg0" Condition="NumArgs==0"></DisplayString>
- <DisplayString IncludeView="arg0">{((clang::TemplateArgument *)(this+1))[0],view(cpp)}{*this,view(arg1)}</DisplayString>
- <DisplayString IncludeView="arg1" Condition="NumArgs==1"></DisplayString>
- <DisplayString IncludeView="arg1">, {((clang::TemplateArgument *)(this+1))[1],view(cpp)}{*this,view(arg2)}</DisplayString>
- <DisplayString IncludeView="arg2" Condition="NumArgs==2"></DisplayString>
- <DisplayString IncludeView="arg2">, {((clang::TemplateArgument *)(this+1))[2],view(cpp)}{*this,view(arg3)}</DisplayString>
- <DisplayString Condition="(Template.Storage.Val.Val.Value & 3) == 0">
- {*((clang::TemplateDecl *)((Template.Storage.Val.Val.Value >> 2) << 2))->TemplatedDecl,view(cpp)}<{*this,view(arg0)}>
- </DisplayString>
- <Expand>
- <Item Name="Template">Template.Storage</Item>
- <ArrayItems>
- <Size>NumArgs</Size>
- <ValuePointer>(clang::TemplateArgument *)(this+1)</ValuePointer>
- </ArrayItems>
- </Expand>
- </Type>
- <Type Name="clang::DeducedType">
- <Expand>
- <Item Name="isDeduced">(CanonicalType.Value.Value != this) || TypeBits.Dependent</Item>
- <ExpandedItem>*(clang::Type *)this,view(cmn)</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::DeducedTemplateSpecializationType">
- <DisplayString Condition="(CanonicalType.Value.Value != this) || TypeBits.Dependent">{CanonicalType,view(cpp)}</DisplayString>
- <DisplayString>{Template}</DisplayString>
- <Expand>
- <Item Name="Template">Template</Item>
- <Item Name="Deduced As" Condition="(CanonicalType.Value.Value != this) || TypeBits.Dependent">CanonicalType,view(cpp)</Item>
- <ExpandedItem>*(clang::DeducedType *)this</ExpandedItem>
- <Item Name="Template">Template</Item>
- </Expand>
- </Type>
- <Type Name="clang::ClassTemplateSpecializationDecl">
- <DisplayString>{*(CXXRecordDecl *)this,nd}{*TemplateArgs}</DisplayString>
- <Expand>
- <ExpandedItem>(CXXRecordDecl *)this,nd</ExpandedItem>
- <Item Name="TemplateArgs">TemplateArgs</Item>
- </Expand>
- </Type>
- <Type Name="clang::IdentifierInfo">
- <DisplayString Condition="Entry != 0">{((llvm::StringMapEntry<clang::IdentifierInfo *>*)Entry)+1,sb}</DisplayString>
- <Expand>
- <Item Condition="Entry != 0" Name="[Identifier]">((llvm::StringMapEntry<clang::IdentifierInfo *>*)Entry)+1,s</Item>
- <Item Name="Token Kind">(clang::tok::TokenKind)TokenID</Item>
- </Expand>
- </Type>
- <Type Name="clang::DeclarationName">
- <DisplayString Condition="Ptr == 0" IncludeView="cpp"></DisplayString>
- <DisplayString Condition="Ptr == 0">Empty</DisplayString>
- <DisplayString Condition="(Ptr & PtrMask) == StoredIdentifier" IncludeView="cpp">{*(clang::IdentifierInfo *)(Ptr & ~PtrMask)}</DisplayString>
- <DisplayString Condition="(Ptr & PtrMask) == StoredIdentifier">{{Identifier ({*(clang::IdentifierInfo *)(Ptr & ~PtrMask)})}}</DisplayString>
- <DisplayString Condition="(Ptr & PtrMask) == StoredObjCZeroArgSelector">{{ObjC Zero Arg Selector (*{(clang::IdentifierInfo *)(Ptr & ~PtrMask)})}}</DisplayString>
- <DisplayString Condition="(Ptr & PtrMask) == StoredObjCOneArgSelector">{{ObjC One Arg Selector (*{(clang::IdentifierInfo *)(Ptr & ~PtrMask)})}}</DisplayString>
- <DisplayString Condition="(Ptr & PtrMask) == StoredCXXConstructorName">C++ Constructor {{*(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask)}}</DisplayString>
- <DisplayString Condition="(Ptr & PtrMask) == StoredCXXDestructorName">C++ Destructor {{*(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask)}}</DisplayString>
- <DisplayString Condition="(Ptr & PtrMask) == StoredCXXConversionFunctionName">C++ Conversion function {{*(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask)}}</DisplayString>
- <DisplayString Condition="(Ptr & PtrMask) == StoredCXXOperatorName">C++ Operator {{*(clang::detail::CXXOperatorIdName *)(Ptr & ~PtrMask)}}</DisplayString>
- <DisplayString Condition="(Ptr & PtrMask) == StoredDeclarationNameExtra"
- IncludeView="cpp">{*(clang::detail::DeclarationNameExtra *)(Ptr & ~PtrMask),view(cpp)}</DisplayString>
- <DisplayString Condition="(Ptr & PtrMask) == StoredDeclarationNameExtra">{{Extra ({*(clang::detail::DeclarationNameExtra *)(Ptr & ~PtrMask)})}}</DisplayString>
- <Expand>
- <Item Condition="(Ptr & PtrMask) == StoredIdentifier" Name="[Identifier]">*(clang::IdentifierInfo *)(Ptr & ~PtrMask)</Item>
- <Item Condition="(Ptr & PtrMask) == StoredObjCZeroArgSelector" Name="[ObjC Zero Arg Selector]">*(clang::IdentifierInfo *)(Ptr & ~PtrMask)</Item>
- <Item Condition="(Ptr & PtrMask) == StoredObjCOneArgSelector" Name="[ObjC One Arg Selector]">*(clang::IdentifierInfo *)(Ptr & ~PtrMask)</Item>
- <Item Condition="(Ptr & PtrMask) == StoredCXXConstructorName" Name="[C++ Constructor]">*(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask)</Item>
- <Item Condition="(Ptr & PtrMask) == StoredCXXDestructorName" Name="[C++ Destructor]">*(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask)</Item>
- <Item Condition="(Ptr & PtrMask) == StoredCXXConversionFunctionName" Name="[C++ Conversion function]">*(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask)</Item>
- <Item Condition="(Ptr & PtrMask) == StoredCXXOperatorName" Name="[C++ Operator]">*(clang::detail::CXXOperatorIdName *)(Ptr & ~PtrMask)</Item>
- <Item Condition="(Ptr & PtrMask) == StoredDeclarationNameExtra" Name="[Extra]">(clang::detail::DeclarationNameExtra *)(Ptr & ~PtrMask)</Item>
- </Expand>
- </Type>
- <Type Name="clang::detail::DeclarationNameExtra">
- <DisplayString Condition="ExtraKindOrNumArgs == CXXDeductionGuideName">C++ Deduction guide</DisplayString>
- <DisplayString Condition="ExtraKindOrNumArgs == CXXLiteralOperatorName">C++ Literal operator</DisplayString>
- <DisplayString Condition="ExtraKindOrNumArgs == CXXUsingDirective">C++ Using directive</DisplayString>
- <DisplayString>{(clang::detail::DeclarationNameExtra::ExtraKind)ExtraKindOrNumArgs,en}{" ",sb}{*this,view(cpp)}</DisplayString>
- </Type>
- <Type Name="clang::Token">
- <DisplayString Condition="Kind != clang::tok::identifier">{(clang::tok::TokenKind)Kind,en}</DisplayString>
- <DisplayString Condition="Kind == clang::tok::identifier">{{Identifier ({*(clang::IdentifierInfo *)(PtrData)})}}</DisplayString>
- </Type>
- <Type Name="clang::DeclSpec">
- <DisplayString>[{(clang::DeclSpec::SCS)StorageClassSpec}], [{(clang::TypeSpecifierType)TypeSpecType}]</DisplayString>
- </Type>
- <Type Name="clang::PragmaHandler">
- <DisplayString>{Name,s}</DisplayString>
- </Type>
- <Type Name="clang::FileEntry">
- <DisplayString>{Name,s}</DisplayString>
- </Type>
- <Type Name="clang::DirectoryEntry">
- <DisplayString>{Name,s}</DisplayString>
- </Type>
- <Type Name="clang::VarDecl::VarDeclBitfields">
- <Expand>
- <Item Name="StorageClass">(clang::StorageClass)SClass</Item>
- <Item Name="ThreadStorageClass">(clang::ThreadStorageClassSpecifier)TSCSpec</Item>
- <Item Name="InitStyle">(clang::VarDecl::InitializationStyle)InitStyle</Item>
- </Expand>
- </Type>
- <Type Name="clang::DeclaratorDecl">
- <DisplayString>{DeclType,view(cpp)} {Name,view(cpp)}</DisplayString>
- <Expand>
- <Item Name="Name">Name</Item>
- <Item Name="DeclType">DeclType</Item>
- </Expand>
- </Type>
- <Type Name="clang::VarDecl">
- <DisplayString>{*(DeclaratorDecl*)this,nd}</DisplayString>
- <Expand>
- <ExpandedItem>*(DeclaratorDecl*)this,nd</ExpandedItem>
- <Item Name="VarDeclBits">VarDeclBits</Item>
- </Expand>
- </Type>
- <Type Name="clang::ParmVarDecl">
- <DisplayString>{*(VarDecl*)this,nd}</DisplayString>
- <Expand>
- <Item Name="ParmVarDeclBits">ParmVarDeclBits</Item>
- <ExpandedItem>*(VarDecl*)this,nd</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::FunctionDecl">
- <DisplayString IncludeView="retType">{*(clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) & ~15))->BaseType,view(retType)}</DisplayString>
- <DisplayString IncludeView="parm0" Condition="0 == ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) & ~15))->BaseType)->FunctionTypeBits.NumParams"></DisplayString>
- <DisplayString IncludeView="parm0">{*ParamInfo[0]}{*this,view(parm1)nd}</DisplayString>
- <DisplayString IncludeView="parm1" Condition="1 == ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) & ~15))->BaseType)->FunctionTypeBits.NumParams"></DisplayString>
- <DisplayString IncludeView="parm1">, {*ParamInfo[1]}{*this,view(parm2)nd}</DisplayString>
- <DisplayString IncludeView="parm2" Condition="2 == ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) & ~15))->BaseType)->FunctionTypeBits.NumParams"></DisplayString>
- <DisplayString IncludeView="parm2">, {*ParamInfo[2]}{*this,view(parm3)nd}</DisplayString>
- <DisplayString IncludeView="parm3" Condition="3 == ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) & ~15))->BaseType)->FunctionTypeBits.NumParams"></DisplayString>
- <DisplayString IncludeView="parm3">, {*ParamInfo[3]}{*this,view(parm4)nd}</DisplayString>
- <DisplayString IncludeView="parm4" Condition="4 == ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) & ~15))->BaseType)->FunctionTypeBits.NumParams"></DisplayString>
- <DisplayString IncludeView="parm4">, {*ParamInfo[4]}{*this,view(parm5)nd}</DisplayString>
- <DisplayString IncludeView="parm5" Condition="5 == ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) & ~15))->BaseType)->FunctionTypeBits.NumParams"></DisplayString>
- <DisplayString IncludeView="parm5">, /* expand for more params */</DisplayString>
- <DisplayString>{*this,view(retType)nd} {Name,view(cpp)nd}({*this,view(parm0)nd})</DisplayString>
- <Expand>
- <Item Name="ReturnType">*this,view(retType)nd</Item>
- <Synthetic Name="Parameter Types">
- <DisplayString>{*this,view(parm0)nd}</DisplayString>
- <Expand>
- <ArrayItems>
- <Size>((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) & ~15))->BaseType)->FunctionTypeBits.NumParams</Size>
- <ValuePointer>ParamInfo</ValuePointer>
- </ArrayItems>
- </Expand>
- </Synthetic>
- </Expand>
- </Type>
- <Type Name="clang::OpaquePtr<*>">
- <DisplayString>{($T1 *)Ptr}</DisplayString>
- <Expand>
- <ExpandedItem>($T1 *)Ptr</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::UnionOpaquePtr<*>">
- <DisplayString>{($T1 *)Ptr}</DisplayString>
- <Expand>
- <ExpandedItem>($T1 *)Ptr</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::TemplateParameterList">
- <DisplayString IncludeView="parm0" Condition="NumParams==0"></DisplayString>
- <DisplayString IncludeView="parm0">{*((NamedDecl **)(this+1))[0],view(cpp)}{*this,view(parm1)}</DisplayString>
- <DisplayString IncludeView="parm1" Condition="NumParams==1"></DisplayString>
- <DisplayString IncludeView="parm1">, {*((NamedDecl **)(this+1))[1],view(cpp)}{*this,view(parm2)}</DisplayString>
- <DisplayString IncludeView="parm2" Condition="NumParams==2"></DisplayString>
- <DisplayString IncludeView="parm2">, {*((NamedDecl **)(this+1))[2],view(cpp)}{*this,view(parm3)}</DisplayString>
- <DisplayString IncludeView="parm3" Condition="NumParams==3"></DisplayString>
- <DisplayString IncludeView="parm3">, {*((NamedDecl **)(this+1))[3],view(cpp)}{*this,view(parm4)}</DisplayString>
- <DisplayString IncludeView="parm4" Condition="NumParams==4"></DisplayString>
- <DisplayString IncludeView="parm4">, {*((NamedDecl **)(this+1))[4],view(cpp)}{*this,view(parm5)}</DisplayString>
- <DisplayString IncludeView="parm5" Condition="NumParams==5"></DisplayString>
- <DisplayString IncludeView="parm5">, /* Expand for more params */</DisplayString>
- <DisplayString><{*this,view(parm0)}></DisplayString>
- <Expand>
- <ArrayItems>
- <Size>NumParams</Size>
- <ValuePointer>(NamedDecl **)(this+1)</ValuePointer>
- </ArrayItems>
- </Expand>
- </Type>
- <Type Name="clang::Stmt">
- <DisplayString>{(clang::Stmt::StmtClass)StmtBits.sClass,en}</DisplayString>
- <Expand>
- <Item Name="Class">(clang::Stmt::StmtClass)StmtBits.sClass,en</Item>
- </Expand>
- </Type>
- <Type Name="clang::Expr">
- <DisplayString>Expression of class {(clang::Stmt::StmtClass)StmtBits.sClass,en} and type {TR,view(cpp)}</DisplayString>
- </Type>
- <Type Name="clang::DeclAccessPair">
- <DisplayString IncludeView="access" Condition="(Ptr&Mask) == clang::AS_public">public</DisplayString>
- <DisplayString IncludeView="access" Condition="(Ptr&Mask) == clang::AS_protected">protected</DisplayString>
- <DisplayString IncludeView="access" Condition="(Ptr&Mask) == clang::AS_private">private</DisplayString>
- <DisplayString IncludeView="access" Condition="(Ptr&Mask) == clang::AS_none">b</DisplayString>
- <DisplayString IncludeView="decl">{*(clang::NamedDecl *)(Ptr&~Mask)}</DisplayString>
- <DisplayString>{*this,view(access)} {*this,view(decl)}</DisplayString>
- <Expand>
- <Item Name="access">(clang::AccessSpecifier)(Ptr&Mask),en</Item>
- <Item Name="decl">*(clang::NamedDecl *)(Ptr&~Mask)</Item>
- </Expand>
- </Type>
- <Type Name="clang::UnresolvedSet<*>">
- <DisplayString>{Decls}</DisplayString>
- <Expand>
- <ExpandedItem>Decls</ExpandedItem>
- </Expand>
- </Type>
- <Type Name="clang::LookupResult">
- <DisplayString Condition="ResultKind == clang::LookupResult::Ambiguous">{Ambiguity,en}: {Decls}</DisplayString>
- <DisplayString>{ResultKind,en}: {Decls}</DisplayString>
- </Type>
- <Type Name="clang::ActionResult<*, 0>">
- <DisplayString Condition="Invalid">Invalid</DisplayString>
- <DisplayString Condition="!*(void **)&Val">Unset</DisplayString>
- <DisplayString>{Val}</DisplayString>
- </Type>
- <Type Name="clang::ActionResult<*, 1>">
- <DisplayString Condition="PtrWithInvalid&1">Invalid</DisplayString>
- <DisplayString Condition="!PtrWithInvalid">Unset</DisplayString>
- <DisplayString>{($T1)(PtrWithInvalid&~1)}</DisplayString>
- <Expand>
- <Item Name="Invalid">(bool)(PtrWithInvalid&1)</Item>
- <Item Name="Val">($T1)(PtrWithInvalid&~1)</Item>
- </Expand>
- </Type>
-</AutoVisualizer>
diff --git a/utils/CmpDriver b/utils/CmpDriver deleted file mode 100755 index 12ce7a3250f6..000000000000 --- a/utils/CmpDriver +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env python - -""" -A simple utility that compares tool invocations and exit codes issued by -compiler drivers that support -### (e.g. gcc and clang). -""" - -import subprocess - -def splitArgs(s): - it = iter(s) - current = '' - inQuote = False - for c in it: - if c == '"': - if inQuote: - inQuote = False - yield current + '"' - else: - inQuote = True - current = '"' - elif inQuote: - if c == '\\': - current += c - current += it.next() - else: - current += c - elif not c.isspace(): - yield c - -def insertMinimumPadding(a, b, dist): - """insertMinimumPadding(a,b) -> (a',b') - - Return two lists of equal length, where some number of Nones have - been inserted into the shorter list such that sum(map(dist, a', - b')) is minimized. - - Assumes dist(X, Y) -> int and non-negative. - """ - - def cost(a, b): - return sum(map(dist, a + [None] * (len(b) - len(a)), b)) - - # Normalize so a is shortest. - if len(b) < len(a): - b, a = insertMinimumPadding(b, a, dist) - return a,b - - # For each None we have to insert... - for i in range(len(b) - len(a)): - # For each position we could insert it... - current = cost(a, b) - best = None - for j in range(len(a) + 1): - a_0 = a[:j] + [None] + a[j:] - candidate = cost(a_0, b) - if best is None or candidate < best[0]: - best = (candidate, a_0, j) - a = best[1] - return a,b - -class ZipperDiff(object): - """ZipperDiff - Simple (slow) diff only accommodating inserts.""" - - def __init__(self, a, b): - self.a = a - self.b = b - - def dist(self, a, b): - return a != b - - def getDiffs(self): - a,b = insertMinimumPadding(self.a, self.b, self.dist) - for aElt,bElt in zip(a,b): - if self.dist(aElt, bElt): - yield aElt,bElt - -class DriverZipperDiff(ZipperDiff): - def isTempFile(self, filename): - if filename[0] != '"' or filename[-1] != '"': - return False - return (filename.startswith('/tmp/', 1) or - filename.startswith('/var/', 1)) - - def dist(self, a, b): - if a and b and self.isTempFile(a) and self.isTempFile(b): - return 0 - return super(DriverZipperDiff, self).dist(a,b) - -class CompileInfo: - def __init__(self, out, err, res): - self.commands = [] - - # Standard out isn't used for much. - self.stdout = out - self.stderr = '' - - # FIXME: Compare error messages as well. - for ln in err.split('\n'): - if (ln == 'Using built-in specs.' or - ln.startswith('Target: ') or - ln.startswith('Configured with: ') or - ln.startswith('Thread model: ') or - ln.startswith('gcc version') or - ln.startswith('clang version')): - pass - elif ln.strip().startswith('"'): - self.commands.append(list(splitArgs(ln))) - else: - self.stderr += ln + '\n' - - self.stderr = self.stderr.strip() - self.exitCode = res - -def captureDriverInfo(cmd, args): - p = subprocess.Popen([cmd,'-###'] + args, - stdin=None, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - out,err = p.communicate() - res = p.wait() - return CompileInfo(out,err,res) - -def main(): - import os, sys - - args = sys.argv[1:] - driverA = os.getenv('DRIVER_A') or 'gcc' - driverB = os.getenv('DRIVER_B') or 'clang' - - infoA = captureDriverInfo(driverA, args) - infoB = captureDriverInfo(driverB, args) - - differ = False - - # Compare stdout. - if infoA.stdout != infoB.stdout: - print '-- STDOUT DIFFERS -' - print 'A OUTPUT: ',infoA.stdout - print 'B OUTPUT: ',infoB.stdout - print - - diff = ZipperDiff(infoA.stdout.split('\n'), - infoB.stdout.split('\n')) - for i,(aElt,bElt) in enumerate(diff.getDiffs()): - if aElt is None: - print 'A missing: %s' % bElt - elif bElt is None: - print 'B missing: %s' % aElt - else: - print 'mismatch: A: %s' % aElt - print ' B: %s' % bElt - - differ = True - - # Compare stderr. - if infoA.stderr != infoB.stderr: - print '-- STDERR DIFFERS -' - print 'A STDERR: ',infoA.stderr - print 'B STDERR: ',infoB.stderr - print - - diff = ZipperDiff(infoA.stderr.split('\n'), - infoB.stderr.split('\n')) - for i,(aElt,bElt) in enumerate(diff.getDiffs()): - if aElt is None: - print 'A missing: %s' % bElt - elif bElt is None: - print 'B missing: %s' % aElt - else: - print 'mismatch: A: %s' % aElt - print ' B: %s' % bElt - - differ = True - - # Compare commands. - for i,(a,b) in enumerate(map(None, infoA.commands, infoB.commands)): - if a is None: - print 'A MISSING:',' '.join(b) - differ = True - continue - elif b is None: - print 'B MISSING:',' '.join(a) - differ = True - continue - - diff = DriverZipperDiff(a,b) - diffs = list(diff.getDiffs()) - if diffs: - print '-- COMMAND %d DIFFERS -' % i - print 'A COMMAND:',' '.join(a) - print 'B COMMAND:',' '.join(b) - print - for i,(aElt,bElt) in enumerate(diffs): - if aElt is None: - print 'A missing: %s' % bElt - elif bElt is None: - print 'B missing: %s' % aElt - else: - print 'mismatch: A: %s' % aElt - print ' B: %s' % bElt - differ = True - - # Compare result codes. - if infoA.exitCode != infoB.exitCode: - print '-- EXIT CODES DIFFER -' - print 'A: ',infoA.exitCode - print 'B: ',infoB.exitCode - differ = True - - if differ: - sys.exit(1) - -if __name__ == '__main__': - main() diff --git a/utils/FindSpecRefs b/utils/FindSpecRefs deleted file mode 100755 index 9097f93f28d6..000000000000 --- a/utils/FindSpecRefs +++ /dev/null @@ -1,910 +0,0 @@ -#!/usr/bin/env python - -import os -import re -import time -from pprint import pprint - -### - -c99URL = 'http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf' -c99TOC = [('Foreword', 'xi'), -('Introduction', 'xiv'), -('1. Scope', '1'), -('2. Normative references', '2'), -('3. Terms, definitions, and symbols', '3'), -('4. Conformance', '7'), -('5. Environment', '9'), -('5.1 Conceptual models', '9'), -('5.1.1 Translation environment', '9'), -('5.1.2 Execution environments', '11'), -('5.2 Environmental considerations', '17'), -('5.2.1 Character sets', '17'), -('5.2.2 Character display semantics', '19'), -('5.2.3 Signals and interrupts', '20'), -('5.2.4 Environmental limits', '20'), -('6. Language', '29'), -('6.1 Notation', '29'), -('6.2 Concepts', '29'), -('6.2.1 Scopes of identifiers', '29'), -('6.2.2 Linkages of identifiers', '30'), -('6.2.3 Name spaces of identifiers', '31'), -('6.2.4 Storage durations of objects', '32'), -('6.2.5 Types', '33'), -('6.2.6 Representations of types', '37'), -('6.2.7 Compatible type and composite type', '40'), -('6.3 Conversions', '42'), -('6.3.1 Arithmetic operands', '42'), -('6.3.2 Other operands', '46'), -('6.4 Lexical elements', '49'), -('6.4.1 Keywords', '50'), -('6.4.2 Identifiers', '51'), -('6.4.3 Universal character names', '53'), -('6.4.4 Constants', '54'), -('6.4.5 String literals', '62'), -('6.4.6 Punctuators', '63'), -('6.4.7 Header names', '64'), -('6.4.8 Preprocessing numbers', '65'), -('6.4.9 Comments', '66'), -('6.5 Expressions', '67'), -('6.5.1 Primary expressions', '69'), -('6.5.2 Postfix operators', '69'), -('6.5.3 Unary operators', '78'), -('6.5.4 Cast operators', '81'), -('6.5.5 Multiplicative operators', '82'), -('6.5.6 Additive operators', '82'), -('6.5.7 Bitwise shift operators', '84'), -('6.5.8 Relational operators', '85'), -('6.5.9 Equality operators', '86'), -('6.5.10 Bitwise AND operator', '87'), -('6.5.11 Bitwise exclusive OR operator', '88'), -('6.5.12 Bitwise inclusive OR operator', '88'), -('6.5.13 Logical AND operator', '89'), -('6.5.14 Logical OR operator', '89'), -('6.5.15 Conditional operator', '90'), -('6.5.16 Assignment operators', '91'), -('6.5.17 Comma operator', '94'), -('6.6 Constant expressions', '95'), -('6.7 Declarations', '97'), -('6.7.1 Storage-class specifiers', '98'), -('6.7.2 Type specifiers', '99'), -('6.7.3 Type qualifiers', '108'), -('6.7.4 Function specifiers', '112'), -('6.7.5 Declarators', '114'), -('6.7.6 Type names', '122'), -('6.7.7 Type definitions', '123'), -('6.7.8 Initialization', '125'), -('6.8 Statements and blocks', '131'), -('6.8.1 Labeled statements', '131'), -('6.8.2 Compound statement', '132'), -('6.8.3 Expression and null statements', '132'), -('6.8.4 Selection statements', '133'), -('6.8.5 Iteration statements', '135'), -('6.8.6 Jump statements', '136'), -('6.9 External definitions', '140'), -('6.9.1 Function definitions', '141'), -('6.9.2 External object definitions', '143'), -('6.10 Preprocessing directives', '145'), -('6.10.1 Conditional inclusion', '147'), -('6.10.2 Source file inclusion', '149'), -('6.10.3 Macro replacement', '151'), -('6.10.4 Line control', '158'), -('6.10.5 Error directive', '159'), -('6.10.6 Pragma directive', '159'), -('6.10.7 Null directive', '160'), -('6.10.8 Predefined macro names', '160'), -('6.10.9 Pragma operator', '161'), -('6.11 Future language directions', '163'), -('6.11.1 Floating types', '163'), -('6.11.2 Linkages of identifiers', '163'), -('6.11.3 External names', '163'), -('6.11.4 Character escape sequences', '163'), -('6.11.5 Storage-class specifiers', '163'), -('6.11.6 Function declarators', '163'), -('6.11.7 Function definitions', '163'), -('6.11.8 Pragma directives', '163'), -('6.11.9 Predefined macro names', '163'), -('7. Library', '164'), -('7.1 Introduction', '164'), -('7.1.1 Definitions of terms', '164'), -('7.1.2 Standard headers', '165'), -('7.1.3 Reserved identifiers', '166'), -('7.1.4 Use of library functions', '166'), -('7.2 Diagnostics <assert.h>', '169'), -('7.2.1 Program diagnostics', '169'), -('7.3 Complex arithmetic <complex.h>', '170'), -('7.3.1 Introduction', '170'), -('7.3.2 Conventions', '170'), -('7.3.3 Branch cuts', '171'), -('7.3.4 The CX_LIMITED_RANGE pragma', '171'), -('7.3.5 Trigonometric functions', '172'), -('7.3.6 Hyperbolic functions', '174'), -('7.3.7 Exponential and logarithmic functions', '176'), -('7.3.8 Power and absolute-value functions', '177'), -('7.3.9 Manipulation functions', '178'), -('7.4 Character handling <ctype.h>', '181'), -('7.4.1 Character classification functions', '181'), -('7.4.2 Character case mapping functions', '184'), -('7.5 Errors <errno.h>', '186'), -('7.6 Floating-point environment <fenv.h>', '187'), -('7.6.1 The FENV_ACCESS pragma', '189'), -('7.6.2 Floating-point exceptions', '190'), -('7.6.3 Rounding', '193'), -('7.6.4 Environment', '194'), -('7.7 Characteristics of floating types <float.h>', '197'), -('7.8 Format conversion of integer types <inttypes.h>', '198'), -('7.8.1 Macros for format specifiers', '198'), -('7.8.2 Functions for greatest-width integer types', '199'), -('7.9 Alternative spellings <iso646.h>', '202'), -('7.10 Sizes of integer types <limits.h>', '203'), -('7.11 Localization <locale.h>', '204'), -('7.11.1 Locale control', '205'), -('7.11.2 Numeric formatting convention inquiry', '206'), -('7.12 Mathematics <math.h>', '212'), -('7.12.1 Treatment of error conditions', '214'), -('7.12.2 The FP_CONTRACT pragma', '215'), -('7.12.3 Classification macros', '216'), -('7.12.4 Trigonometric functions', '218'), -('7.12.5 Hyperbolic functions', '221'), -('7.12.6 Exponential and logarithmic functions', '223'), -('7.12.7 Power and absolute-value functions', '228'), -('7.12.8 Error and gamma functions', '230'), -('7.12.9 Nearest integer functions', '231'), -('7.12.10 Remainder functions', '235'), -('7.12.11 Manipulation functions', '236'), -('7.12.12 Maximum, minimum, and positive difference functions', '238'), -('7.12.13 Floating multiply-add', '239'), -('7.12.14 Comparison macros', '240'), -('7.13 Nonlocal jumps <setjmp.h>', '243'), -('7.13.1 Save calling environment', '243'), -('7.13.2 Restore calling environment', '244'), -('7.14 Signal handling <signal.h>', '246'), -('7.14.1 Specify signal handling', '247'), -('7.14.2 Send signal', '248'), -('7.15 Variable arguments <stdarg.h>', '249'), -('7.15.1 Variable argument list access macros', '249'), -('7.16 Boolean type and values <stdbool.h>', '253'), -('7.17 Common definitions <stddef.h>', '254'), -('7.18 Integer types <stdint.h>', '255'), -('7.18.1 Integer types', '255'), -('7.18.2 Limits of specified-width integer types', '257'), -('7.18.3 Limits of other integer types', '259'), -('7.18.4 Macros for integer constants', '260'), -('7.19 Input/output <stdio.h>', '262'), -('7.19.1 Introduction', '262'), -('7.19.2 Streams', '264'), -('7.19.3 Files', '266'), -('7.19.4 Operations on files', '268'), -('7.19.5 File access functions', '270'), -('7.19.6 Formatted input/output functions', '274'), -('7.19.7 Character input/output functions', '296'), -('7.19.8 Direct input/output functions', '301'), -('7.19.9 File positioning functions', '302'), -('7.19.10 Error-handling functions', '304'), -('7.20 General utilities <stdlib.h>', '306'), -('7.20.1 Numeric conversion functions', '307'), -('7.20.2 Pseudo-random sequence generation functions', '312'), -('7.20.3 Memory management functions', '313'), -('7.20.4 Communication with the environment', '315'), -('7.20.5 Searching and sorting utilities', '318'), -('7.20.6 Integer arithmetic functions', '320'), -('7.20.7 Multibyte/wide character conversion functions', '321'), -('7.20.8 Multibyte/wide string conversion functions', '323'), -('7.21 String handling <string.h>', '325'), -('7.21.1 String function conventions', '325'), -('7.21.2 Copying functions', '325'), -('7.21.3 Concatenation functions', '327'), -('7.21.4 Comparison functions', '328'), -('7.21.5 Search functions', '330'), -('7.21.6 Miscellaneous functions', '333'), -('7.22 Type-generic math <tgmath.h>', '335'), -('7.23 Date and time <time.h>', '338'), -('7.23.1 Components of time', '338'), -('7.23.2 Time manipulation functions', '339'), -('7.23.3 Time conversion functions', '341'), -('7.24 Extended multibyte and wide character utilities <wchar.h>', '348'), -('7.24.1 Introduction', '348'), -('7.24.2 Formatted wide character input/output functions', '349'), -('7.24.3 Wide character input/output functions', '367'), -('7.24.4 General wide string utilities', '371'), -('7.24.5 Wide character time conversion functions', '385'), -('7.24.6 Extended multibyte/wide character conversion utilities', '386'), -('7.25 Wide character classification and mapping utilities <wctype.h>', - '393'), -('7.25.1 Introduction', '393'), -('7.25.2 Wide character classification utilities', '394'), -('7.25.3 Wide character case mapping utilities', '399'), -('7.26 Future library directions', '401'), -('7.26.1 Complex arithmetic <complex.h>', '401'), -('7.26.2 Character handling <ctype.h>', '401'), -('7.26.3 Errors <errno.h>', '401'), -('7.26.4 Format conversion of integer types <inttypes.h>', '401'), -('7.26.5 Localization <locale.h>', '401'), -('7.26.6 Signal handling <signal.h>', '401'), -('7.26.7 Boolean type and values <stdbool.h>', '401'), -('7.26.8 Integer types <stdint.h>', '401'), -('7.26.9 Input/output <stdio.h>', '402'), -('7.26.10 General utilities <stdlib.h>', '402'), -('7.26.11 String handling <string.h>', '402'), -('<wchar.h>', '402'), -('<wctype.h>', '402'), -('Annex A (informative) Language syntax summary', '403'), -('A.1 Lexical grammar', '403'), -('A.2 Phrase structure grammar', '409'), -('A.3 Preprocessing directives', '416'), -('Annex B (informative) Library summary', '418'), -('B.1 Diagnostics <assert.h>', '418'), -('B.2 Complex <complex.h>', '418'), -('B.3 Character handling <ctype.h>', '420'), -('B.4 Errors <errno.h>', '420'), -('B.5 Floating-point environment <fenv.h>', '420'), -('B.6 Characteristics of floating types <float.h>', '421'), -('B.7 Format conversion of integer types <inttypes.h>', '421'), -('B.8 Alternative spellings <iso646.h>', '422'), -('B.9 Sizes of integer types <limits.h>', '422'), -('B.10 Localization <locale.h>', '422'), -('B.11 Mathematics <math.h>', '422'), -('B.12 Nonlocal jumps <setjmp.h>', '427'), -('B.13 Signal handling <signal.h>', '427'), -('B.14 Variable arguments <stdarg.h>', '427'), -('B.15 Boolean type and values <stdbool.h>', '427'), -('B.16 Common definitions <stddef.h>', '428'), -('B.17 Integer types <stdint.h>', '428'), -('B.18 Input/output <stdio.h>', '428'), -('B.19 General utilities <stdlib.h>', '430'), -('B.20 String handling <string.h>', '432'), -('B.21 Type-generic math <tgmath.h>', '433'), -('B.22 Date and time <time.h>', '433'), -('B.23 Extended multibyte/wide character utilities <wchar.h>', '434'), -('B.24 Wide character classification and mapping utilities <wctype.h>', - '436'), -('Annex C (informative) Sequence points', '438'), -('Annex D (normative) Universal character names for identifiers', '439'), -('Annex E (informative) Implementation limits', '441'), -('Annex F (normative) IEC 60559 floating-point arithmetic', '443'), -('F.1 Introduction', '443'), -('F.2 Types', '443'), -('F.3 Operators and functions', '444'), -('F.4 Floating to integer conversion', '446'), -('F.5 Binary-decimal conversion', '446'), -('F.6 Contracted expressions', '447'), -('F.7 Floating-point environment', '447'), -('F.8 Optimization', '450'), -('F.9 Mathematics <math.h>', '453'), -('Annex G (informative) IEC 60559-compatible complex arithmetic', '466'), -('G.1 Introduction', '466'), -('G.2 Types', '466'), -('G.3 Conventions', '466'), -('G.4 Conversions', '467'), -('G.5 Binary operators', '467'), -('G.6 Complex arithmetic <complex.h>', '471'), -('G.7 Type-generic math <tgmath.h>', '479'), -('Annex H (informative) Language independent arithmetic', '480'), -('H.1 Introduction', '480'), -('H.2 Types', '480'), -('H.3 Notification', '484'), -('Annex I (informative) Common warnings', '486'), -('Annex J (informative) Portability issues', '488'), -('J.1 Unspecified behavior', '488'), -('J.2 Undefined behavior', '491'), -('J.3 Implementation-defined behavior', '504'), -('J.4 Locale-specific behavior', '511'), -('J.5 Common extensions', '512'), -('Bibliography', '515'), -('Index', '517')] - -cXXURL = 'http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf' -cXXTOC = [('Contents', 'ii'), -('List of Tables', 'ix'), -('1 General', '1'), -('1.1 Scope', '1'), -('1.2 Normative references', '1'), -('1.3 Definitions', '2'), -('1.4 Implementation compliance', '4'), -('1.5 Structure of this International Standard', '5'), -('1.6 Syntax notation', '5'), -('1.7 The C++ memory model', '6'), -('1.8 The C++ object model', '6'), -('1.9 Program execution', '7'), -('1.10 Multi-threaded executions and data races', '10'), -('1.11 Acknowledgments', '13'), -('2 Lexical conventions', '15'), -('2.1 Phases of translation', '15'), -('2.2 Character sets', '16'), -('2.3 Trigraph sequences', '17'), -('2.4 Preprocessing tokens', '17'), -('2.5 Alternative tokens', '18'), -('2.6 Tokens', '19'), -('2.7 Comments', '19'), -('2.8 Header names', '19'), -('2.9 Preprocessing numbers', '20'), -('2.10 Identifiers', '20'), -('2.11 Keywords', '20'), -('2.12 Operators and punctuators', '21'), -('2.13 Literals', '21'), -('3 Basic concepts', '29'), -('3.1 Declarations and definitions', '29'), -('3.2 One definition rule', '31'), -('3.3 Declarative regions and scopes', '33'), -('3.4 Name lookup', '38'), -('3.5 Program and linkage', '51'), -('3.6 Start and termination', '54'), -('3.7 Storage duration', '58'), -('3.8 Object Lifetime', '62'), -('3.9 Types', '65'), -('3.10 Lvalues and rvalues', '70'), -('3.11 Alignment', '72'), -('4 Standard conversions', '73'), -('4.1 Lvalue-to-rvalue conversion', '74'), -('4.2 Array-to-pointer conversion', '74'), -('4.3 Function-to-pointer conversion', '74'), -('4.4 Qualification conversions', '74'), -('4.5 Integral promotions', '75'), -('4.6 Floating point promotion', '76'), -('4.7 Integral conversions', '76'), -('4.8 Floating point conversions', '76'), -('4.9 Floating-integral conversions', '77'), -('4.10 Pointer conversions', '77'), -('4.11 Pointer to member conversions', '77'), -('4.12 Boolean conversions', '78'), -('4.13 Integer conversion rank', '78'), -('5 Expressions', '79'), -('5.1 Primary expressions', '80'), -('5.2 Postfix expressions', '85'), -('5.3 Unary expressions', '96'), -('5.4 Explicit type conversion (cast notation)', '104'), -('5.5 Pointer-to-member operators', '105'), -('5.6 Multiplicative operators', '106'), -('5.7 Additive operators', '106'), -('5.8 Shift operators', '107'), -('5.9 Relational operators', '108'), -('5.10 Equality operators', '109'), -('5.11 Bitwise AND operator', '110'), -('5.12 Bitwise exclusive OR operator', '110'), -('5.13 Bitwise inclusive OR operator', '110'), -('5.14 Logical AND operator', '110'), -('5.15 Logical OR operator', '110'), -('5.16 Conditional operator', '111'), -('5.17 Assignment and compound assignment operators', '112'), -('5.18 Comma operator', '113'), -('5.19 Constant expressions', '113'), -('6 Statements', '116'), -('6.1 Labeled statement', '116'), -('6.2 Expression statement', '116'), -('6.3 Compound statement or block', '116'), -('6.4 Selection statements', '117'), -('6.5 Iteration statements', '118'), -('6.6 Jump statements', '121'), -('6.7 Declaration statement', '122'), -('6.8 Ambiguity resolution', '123'), -('7 Declarations', '125'), -('7.1 Specifiers', '126'), -('7.2 Enumeration declarations', '140'), -('7.3 Namespaces', '143'), -('7.4 The asm declaration', '156'), -('7.5 Linkage specifications', '156'), -('8 Declarators', '160'), -('8.1 Type names', '161'), -('8.2 Ambiguity resolution', '161'), -('8.3 Meaning of declarators', '163'), -('8.4 Function definitions', '175'), -('8.5 Initializers', '177'), -('9 Classes', '191'), -('9.1 Class names', '193'), -('9.2 Class members', '194'), -('9.3 Member functions', '197'), -('9.4 Static members', '200'), -('9.5 Unions', '202'), -('9.6 Bit-fields', '203'), -('9.7 Nested class declarations', '204'), -('9.8 Local class declarations', '205'), -('9.9 Nested type names', '206'), -('10 Derived classes', '207'), -('10.1 Multiple base classes', '208'), -('10.2 Member name lookup', '210'), -('10.3 Virtual functions', '213'), -('10.4 Abstract classes', '217'), -('11 Member access control', '219'), -('11.1 Access specifiers', '221'), -('11.2 Accessibility of base classes and base class members', '222'), -('11.3 Access declarations', '224'), -('11.4 Friends', '225'), -('11.5 Protected member access', '228'), -('11.6 Access to virtual functions', '229'), -('11.7 Multiple access', '230'), -('11.8 Nested classes', '230'), -('12 Special member functions', '231'), -('12.1 Constructors', '231'), -('12.2 Temporary objects', '233'), -('12.3 Conversions', '235'), -('12.4 Destructors', '238'), -('12.5 Free store', '240'), -('12.6 Initialization', '242'), -('12.7 Construction and destruction', '247'), -('12.8 Copying class objects', '250'), -('12.9 Inheriting Constructors', '255'), -('13 Overloading', '259'), -('13.1 Overloadable declarations', '259'), -('13.2 Declaration matching', '261'), -('13.3 Overload resolution', '262'), -('13.4 Address of overloaded function', '281'), -('13.5 Overloaded operators', '282'), -('13.6 Built-in operators', '286'), -('14 Templates', '290'), -('14.1 Template parameters', '291'), -('14.2 Names of template specializations', '294'), -('14.3 Template arguments', '296'), -('14.4 Type equivalence', '302'), -('14.5 Template declarations', '303'), -('14.6 Name resolution', '318'), -('14.7 Template instantiation and specialization', '331'), -('14.8 Function template specializations', '343'), -('15 Exception handling', '363'), -('15.1 Throwing an exception', '364'), -('15.2 Constructors and destructors', '366'), -('15.3 Handling an exception', '366'), -('15.4 Exception specifications', '368'), -('15.5 Special functions', '371'), -('15.6 Exceptions and access', '372'), -('16 Preprocessing directives', '373'), -('16.1 Conditional inclusion', '375'), -('16.2 Source file inclusion', '376'), -('16.3 Macro replacement', '377'), -('16.4 Line control', '382'), -('16.5 Error directive', '383'), -('16.6 Pragma directive', '383'), -('16.7 Null directive', '383'), -('16.8 Predefined macro names', '383'), -('16.9 Pragma operator', '384'), -('17 Library introduction', '386'), -('17.1 General', '386'), -('17.2 Overview', '386'), -('17.3 Definitions', '386'), -('17.4 Additional definitions', '390'), -('17.5 Method of description (Informative)', '390'), -('17.6 Library-wide requirements', '396'), -('18 Language support library', '407'), -('18.1 Types', '407'), -('18.2 Implementation properties', '408'), -('18.3 Integer types', '417'), -('18.4 Start and termination', '418'), -('18.5 Dynamic memory management', '420'), -('18.6 Type identification', '424'), -('18.7 Exception handling', '427'), -('18.8 Initializer lists', '432'), -('18.9 Other runtime support', '434'), -('19 Diagnostics library', '435'), -('19.1 Exception classes', '435'), -('19.2 Assertions', '439'), -('19.3 Error numbers', '440'), -('19.4 System error support', '440'), -('20 General utilities library', '452'), -('20.1 Requirements', '452'), -('20.2 Utility components', '457'), -('20.3 Compile-time rational arithmetic', '463'), -('20.4 Tuples', '465'), -('20.5 Metaprogramming and type traits', '473'), -('20.6 Function objects', '486'), -('20.7 Memory', '509'), -('20.8 Time utilities', '548'), -('20.9 Date and time functions', '562'), -('21 Strings library', '563'), -('21.1 Character traits', '563'), -('21.2 String classes', '569'), -('21.3 Class template basic_string', '572'), -('21.4 Numeric Conversions', '599'), -('21.5 Null-terminated sequence utilities', '600'), -('22 Localization library', '604'), -('22.1 Locales', '604'), -('22.2 Standard locale categories', '617'), -('22.3 Standard code conversion facets', '657'), -('22.4 C Library Locales', '659'), -('23 Containers library', '660'), -('23.1 Container requirements', '660'), -('23.2 Sequence containers', '681'), -('23.3 Associative containers', '719'), -('23.4 Unordered associative containers', '744'), -('24 Iterators library', '759'), -('24.1 Iterator requirements', '759'), -('24.2 Header <iterator> synopsis', '764'), -('24.3 Iterator primitives', '767'), -('24.4 Predefined iterators', '770'), -('24.5 Stream iterators', '784'), -('25 Algorithms library', '792'), -('25.1 Non-modifying sequence operations', '802'), -('25.2 Mutating sequence operations', '806'), -('25.3 Sorting and related operations', '815'), -('25.4 C library algorithms', '829'), -('26 Numerics library', '831'), -('26.1 Numeric type requirements', '831'), -('26.2 The floating-point environment', '832'), -('26.3 Complex numbers', '833'), -('26.4 Random number generation', '842'), -('26.5 Numeric arrays', '884'), -('26.6 Generalized numeric operations', '904'), -('26.7 C Library', '907'), -('27 Input/output library', '912'), -('27.1 Iostreams requirements', '912'), -('27.2 Forward declarations', '912'), -('27.3 Standard iostream objects', '915'), -('27.4 Iostreams base classes', '916'), -('27.5 Stream buffers', '934'), -('27.6 Formatting and manipulators', '944'), -('27.7 String-based streams', '972'), -('27.8 File-based streams', '984'), -('28 Regular expressions library', '1000'), -('28.1 Definitions', '1000'), -('28.2 Requirements', '1000'), -('28.3 Regular expressions summary', '1002'), -('28.4 Header <regex> synopsis', '1003'), -('28.5 Namespace std::regex_constants', '1009'), -('28.6 Class regex_error', '1012'), -('28.7 Class template regex_traits', '1012'), -('28.8 Class template basic_regex', '1015'), -('28.9 Class template sub_match', '1020'), -('28.10Class template match_results', '1025'), -('28.11Regular expression algorithms', '1029'), -('28.12Regular expression Iterators', '1033'), -('28.13Modified ECMAScript regular expression grammar', '1039'), -('29 Atomic operations library', '1042'), -('29.1 Order and Consistency', '1044'), -('29.2 Lock-free Property', '1046'), -('29.3 Atomic Types', '1046'), -('29.4 Operations on Atomic Types', '1051'), -('29.5 Flag Type and Operations', '1054'), -('30 Thread support library', '1057'), -('30.1 Requirements', '1057'), -('30.2 Threads', '1058'), -('30.3 Mutual exclusion', '1063'), -('30.4 Condition variables', '1077'), -('A Grammar summary', '1085'), -('A.1 Keywords', '1085'), -('A.2 Lexical conventions', '1085'), -('A.3 Basic concepts', '1089'), -('A.4 Expressions', '1090'), -('A.5 Statements', '1093'), -('A.6 Declarations', '1094'), -('A.7 Declarators', '1097'), -('A.8 Classes', '1098'), -('A.9 Derived classes', '1099'), -('A.10 Special member functions', '1099'), -('A.11 Overloading', '1100'), -('A.12 Templates', '1100'), -('A.13 Exception handling', '1101'), -('A.14 Preprocessing directives', '1101'), -('B Implementation quantities', '1103'), -('C Compatibility', '1105'), -('C.1 C++ and ISO C', '1105'), -('C.2 Standard C library', '1114'), -('D Compatibility features', '1119'), -('D.1 Increment operator with bool operand', '1119'), -('D.2 static keyword', '1119'), -('D.3 Access declarations', '1119'), -('D.4 Implicit conversion from const strings', '1119'), -('D.5 C standard library headers', '1119'), -('D.6 Old iostreams members', '1120'), -('D.7 char* streams', '1121'), -('D.8 Binders', '1130'), -('D.9 auto_ptr', '1132'), -('E Universal-character-names', '1135'), -('F Cross references', '1137'), -('Index', '1153')] - -kDocuments = { - 'C99' : (c99URL, c99TOC, 12), - 'C++' : (cXXURL, cXXTOC, 12), -} - -def findClosestTOCEntry(data, target): - # FIXME: Fix for named spec references - if isinstance(target[0],str): - return ('.'.join(target),'<named>',1) - - offset = data[2] - best = None - for (name,page) in data[1]: - if ' ' in name: - section,name = name.split(' ',1) - if section == 'Annex': - section,name = name.split(' ',1) - section = 'Annex '+section - else: - section = None - try: - page = int(page) + offset - except: - page = 1 - try: - spec = SpecIndex.fromstring(section) - except: - spec = None - - # Meh, could be better... - if spec is not None: - dist = spec - target - if best is None or dist < best[0]: - best = (dist, (section, name, page)) - return best[1] - -# What a hack. Slow to boot. -doxyLineRefRE = re.compile(r"<a name=\"l([0-9]+)\"></a>") -def findClosestLineReference(clangRoot, doxyName, target): - try: - f = open(os.path.join(clangRoot, 'docs', 'doxygen', 'html', doxyName)) - except: - return None - - best = None - for m in doxyLineRefRE.finditer(f.read()): - line = int(m.group(1), 10) - dist = abs(line - target) - if best is None or dist < best[0]: - best = (dist,'l'+m.group(1)) - f.close() - if best is not None: - return best[1] - return None - -### - -nameAndSpecRefRE = re.compile(r"(C99|C90|C\+\+|H\&S) ((([0-9]+)(\.[0-9]+)*|\[[^]]+\])(p[0-9]+)?)") -loneSpecRefRE = re.compile(r" (([0-9]+)(\.[0-9]+){2,100}(p[0-9]+)?)") -def scanFile(path, filename): - try: - f = open(path) - except IOError: - print >>sys.stderr,'WARNING: Unable to open:',path - return - - for i,ln in enumerate(f): - ignore = set() - for m in nameAndSpecRefRE.finditer(ln): - section = m.group(2) - name = m.group(1) - if section.endswith('.'): - section = section[:-1] - yield RefItem(name, section, filename, path, i+1) - ignore.add(section) - for m in loneSpecRefRE.finditer(ln): - section = m.group(1) - if section.endswith('.'): - section = section[:-1] - if section not in ignore: - yield RefItem(None, section, filename, path, i+1) - -### - -class SpecIndex: - @staticmethod - def fromstring(str): - # Check for named sections - if str[0] == '[': - assert ']' in str - secs = str[1:str.index(']')].split('.') - tail = str[str.index(']')+1:] - if tail: - assert tail[0] == 'p' - paragraph = int(tail[1:]) - else: - paragraph = None - indices = secs - else: - secs = str.split('.') - paragraph = None - if 'p' in secs[-1]: - secs[-1],p = secs[-1].split('p',1) - paragraph = int(p) - indices = map(int, secs) - return SpecIndex(indices, paragraph) - - def __init__(self, indices, paragraph=None): - assert len(indices)>0 - self.indices = tuple(indices) - self.paragraph = paragraph - - def __str__(self): - s = '.'.join(map(str,self.indices)) - if self.paragraph is not None: - s += '.p%d'%(self.paragraph,) - return s - - def __repr__(self): - return 'SpecIndex(%s, %s)'%(self.indices, self.paragraph) - - def __cmp__(self, b): - return cmp((self.indices,self.paragraph), - (b.indices,b.paragraph)) - - def __hash__(self): - return hash((self.indices,self.paragraph)) - - def __sub__(self, indices): - def sub(a,b): - a = a or 0 - b = b or 0 - return abs(a-b) - return map(sub,self.indices,indices) - -class RefItem: - def __init__(self, name, section, filename, path, line): - self.name = name - self.section = SpecIndex.fromstring(section) - self.filename = filename - self.path = path - self.line = line - - def __str__(self): - if self.name is not None: - return '%s %s'%(self.name, self.section) - else: - return '--- %s'%(self.section,) - - def __repr__(self): - return 'RefItem(%s, %r, "%s", "%s", %d)'%(self.name, - self.section, - self.filename, - self.path, - self.line) - - def __cmp__(self, b): - return cmp((self.name,self.section,self.filename,self.path,self.line), - (b.name,b.section,self.filename,self.path,self.line)) - - def __hash__(self): - return hash((self.name,self.section,self.filename,self.path,self.line)) - -### - -def sorted(l): - l = list(l) - l.sort() - return l - -def getRevision(path): - import subprocess - p = subprocess.Popen(['svn', 'info', path], - stdin=open('/dev/null','r'), - stdout=subprocess.PIPE) - for ln in p.stdout.read(1024).split('\n'): - if ln.startswith('Revision:'): - return ln.split(':',1)[1].strip() - return None - -def buildRefTree(references): - root = (None, {}, []) - - def getNode(keys): - if not keys: - return root - key,parent = keys[-1],getNode(keys[:-1]) - node = parent[1].get(key) - if node is None: - parent[1][key] = node = (key, {}, []) - return node - - for ref in references: - n = getNode((ref.name,) + ref.section.indices) - n[2].append(ref) - - def flatten((key, children, data)): - children = sorted(map(flatten,children.values())) - return (key, children, sorted(data)) - - return flatten(root) - -def preorder(node,parents=(),first=True): - (key,children,data) = node - if first: - yield parents+(node,) - for c in children: - for item in preorder(c, parents+(node,)): - yield item - -def main(): - global options - from optparse import OptionParser - parser = OptionParser("usage: %prog [options] CLANG_ROOT <output-dir>") - parser.add_option("", "--debug", dest="debug", - help="Print extra debugging output", - action="store_true", - default=False) - (opts, args) = parser.parse_args() - - if len(args) != 2: - parser.error("incorrect number of arguments") - - references = [] - root,outputDir = args - if os.path.isdir(root): - for (dirpath, dirnames, filenames) in os.walk(root): - for filename in filenames: - name,ext = os.path.splitext(filename) - if ext in ('.c', '.cpp', '.h', '.def'): - fullpath = os.path.join(dirpath, filename) - references.extend(list(scanFile(fullpath, filename))) - else: - references.extend(list(scanFile(root, root))) - - refTree = buildRefTree(references) - - specs = {} - for ref in references: - spec = specs[ref.name] = specs.get(ref.name,{}) - items = spec[ref.section] = spec.get(ref.section,[]) - items.append(ref) - - print 'Found %d references.'%(len(references),) - - if opts.debug: - pprint(refTree) - - referencesPath = os.path.join(outputDir,'references.html') - print 'Writing: %s'%(referencesPath,) - f = open(referencesPath,'w') - print >>f, '<html><head><title>clang: Specification References</title></head>' - print >>f, '<body>' - print >>f, '\t<h2>Specification References</h2>' - for i,node in enumerate(refTree[1]): - specName = node[0] or 'Unknown' - print >>f, '<a href="#spec%d">%s</a><br>'%(i,specName) - for i,node in enumerate(refTree[1]): - specName = node[0] or 'Unknown' - print >>f, '<hr>' - print >>f, '<a name="spec%d">'%(i,) - print >>f, '<h3>Document: %s</h3>'%(specName or 'Unknown',) - print >>f, '<table border="1" cellspacing="2" width="80%">' - print >>f, '<tr><th width="20%">Name</th><th>References</th></tr>' - docData = kDocuments.get(specName) - for path in preorder(node,first=False): - if not path[-1][2]: - continue - components = '.'.join([str(p[0]) for p in path[1:]]) - print >>f, '\t<tr>' - tocEntry = None - if docData is not None: - tocEntry = findClosestTOCEntry(docData, [p[0] for p in path[1:]]) - if tocEntry is not None: - section,name,page = tocEntry - # If section is exact print the TOC name - if page is not None: - linkStr = '<a href="%s#page=%d">%s</a> (pg.%d)'%(docData[0],page,components,page) - else: - linkStr = components - if section == components: - print >>f, '\t\t<td valign=top>%s<br>%s</td>'%(linkStr,name) - else: - print >>f, '\t\t<td valign=top>%s</td>'%(linkStr,) - else: - print >>f, '\t\t<td valign=top>%s</td>'%(components,) - print >>f, '\t\t<td valign=top>' - for item in path[-1][2]: - # XXX total hack - relativePath = item.path[len(root):] - if relativePath.startswith('/'): - relativePath = relativePath[1:] - # XXX this is broken, how does doxygen mangle w/ multiple - # refs? Can we just read its map? - filename = os.path.basename(relativePath) - doxyName = '%s-source.html'%(filename.replace('.','_8'),) - # Grrr, why can't doxygen write line number references. - lineReference = findClosestLineReference(root,doxyName,item.line) - if lineReference is not None: - linkStr = 'http://clang.llvm.org/doxygen/%s#%s'%(doxyName,lineReference) - else: - linkStr = 'http://clang.llvm.org/doxygen/%s'%(doxyName,) - if item.section.paragraph is not None: - paraText = ' (p%d)'%(item.section.paragraph,) - else: - paraText = '' - print >>f,'<a href="%s">%s:%d</a>%s<br>'%(linkStr,relativePath,item.line,paraText) - print >>f, '\t\t</td>' - print >>f, '\t</tr>' - print >>f, '</table>' - print >>f, '<hr>' - print >>f, 'Generated: %s<br>'%(time.strftime('%Y-%m-%d %H:%M'),) - print >>f, 'SVN Revision: %s'%(getRevision(root),) - print >>f, '</body>' - f.close() - -if __name__=='__main__': - main() diff --git a/utils/FuzzTest b/utils/FuzzTest deleted file mode 100755 index 0e043df7cf08..000000000000 --- a/utils/FuzzTest +++ /dev/null @@ -1,350 +0,0 @@ -#!/usr/bin/env python - -""" -This is a generic fuzz testing tool, see --help for more information. -""" - -import os -import sys -import random -import subprocess -import itertools - -class TestGenerator: - def __init__(self, inputs, delete, insert, replace, - insert_strings, pick_input): - self.inputs = [(s, open(s).read()) for s in inputs] - - self.delete = bool(delete) - self.insert = bool(insert) - self.replace = bool(replace) - self.pick_input = bool(pick_input) - self.insert_strings = list(insert_strings) - - self.num_positions = sum([len(d) for _,d in self.inputs]) - self.num_insert_strings = len(insert_strings) - self.num_tests = ((delete + (insert + replace)*self.num_insert_strings) - * self.num_positions) - self.num_tests += 1 - - if self.pick_input: - self.num_tests *= self.num_positions - - def position_to_source_index(self, position): - for i,(s,d) in enumerate(self.inputs): - n = len(d) - if position < n: - return (i,position) - position -= n - raise ValueError,'Invalid position.' - - def get_test(self, index): - assert 0 <= index < self.num_tests - - picked_position = None - if self.pick_input: - index,picked_position = divmod(index, self.num_positions) - picked_position = self.position_to_source_index(picked_position) - - if index == 0: - return ('nothing', None, None, picked_position) - - index -= 1 - index,position = divmod(index, self.num_positions) - position = self.position_to_source_index(position) - if self.delete: - if index == 0: - return ('delete', position, None, picked_position) - index -= 1 - - index,insert_index = divmod(index, self.num_insert_strings) - insert_str = self.insert_strings[insert_index] - if self.insert: - if index == 0: - return ('insert', position, insert_str, picked_position) - index -= 1 - - assert self.replace - assert index == 0 - return ('replace', position, insert_str, picked_position) - -class TestApplication: - def __init__(self, tg, test): - self.tg = tg - self.test = test - - def apply(self): - if self.test[0] == 'nothing': - pass - else: - i,j = self.test[1] - name,data = self.tg.inputs[i] - if self.test[0] == 'delete': - data = data[:j] + data[j+1:] - elif self.test[0] == 'insert': - data = data[:j] + self.test[2] + data[j:] - elif self.test[0] == 'replace': - data = data[:j] + self.test[2] + data[j+1:] - else: - raise ValueError,'Invalid test %r' % self.test - open(name,'wb').write(data) - - def revert(self): - if self.test[0] != 'nothing': - i,j = self.test[1] - name,data = self.tg.inputs[i] - open(name,'wb').write(data) - -def quote(str): - return '"' + str + '"' - -def run_one_test(test_application, index, input_files, args): - test = test_application.test - - # Interpolate arguments. - options = { 'index' : index, - 'inputs' : ' '.join(quote(f) for f in input_files) } - - # Add picked input interpolation arguments, if used. - if test[3] is not None: - pos = test[3][1] - options['picked_input'] = input_files[test[3][0]] - options['picked_input_pos'] = pos - # Compute the line and column. - file_data = test_application.tg.inputs[test[3][0]][1] - line = column = 1 - for i in range(pos): - c = file_data[i] - if c == '\n': - line += 1 - column = 1 - else: - column += 1 - options['picked_input_line'] = line - options['picked_input_col'] = column - - test_args = [a % options for a in args] - if opts.verbose: - print '%s: note: executing %r' % (sys.argv[0], test_args) - - stdout = None - stderr = None - if opts.log_dir: - stdout_log_path = os.path.join(opts.log_dir, '%s.out' % index) - stderr_log_path = os.path.join(opts.log_dir, '%s.err' % index) - stdout = open(stdout_log_path, 'wb') - stderr = open(stderr_log_path, 'wb') - else: - sys.stdout.flush() - p = subprocess.Popen(test_args, stdout=stdout, stderr=stderr) - p.communicate() - exit_code = p.wait() - - test_result = (exit_code == opts.expected_exit_code or - exit_code in opts.extra_exit_codes) - - if stdout is not None: - stdout.close() - stderr.close() - - # Remove the logs for passes, unless logging all results. - if not opts.log_all and test_result: - os.remove(stdout_log_path) - os.remove(stderr_log_path) - - if not test_result: - print 'FAIL: %d' % index - elif not opts.succinct: - print 'PASS: %d' % index - return test_result - -def main(): - global opts - from optparse import OptionParser, OptionGroup - parser = OptionParser("""%prog [options] ... test command args ... - -%prog is a tool for fuzzing inputs and testing them. - -The most basic usage is something like: - - $ %prog --file foo.txt ./test.sh - -which will run a default list of fuzzing strategies on the input. For each -fuzzed input, it will overwrite the input files (in place), run the test script, -then restore the files back to their original contents. - -NOTE: You should make sure you have a backup copy of your inputs, in case -something goes wrong!!! - -You can cause the fuzzing to not restore the original files with -'--no-revert'. Generally this is used with '--test <index>' to run one failing -test and then leave the fuzzed inputs in place to examine the failure. - -For each fuzzed input, %prog will run the test command given on the command -line. Each argument in the command is subject to string interpolation before -being executed. The syntax is "%(VARIABLE)FORMAT" where FORMAT is a standard -printf format, and VARIABLE is one of: - - 'index' - the test index being run - 'inputs' - the full list of test inputs - 'picked_input' - (with --pick-input) the selected input file - 'picked_input_pos' - (with --pick-input) the selected input position - 'picked_input_line' - (with --pick-input) the selected input line - 'picked_input_col' - (with --pick-input) the selected input column - -By default, the script will run forever continually picking new tests to -run. You can limit the number of tests that are run with '--max-tests <number>', -and you can run a particular test with '--test <index>'. - -You can specify '--stop-on-fail' to stop the script on the first failure -without reverting the changes. - -""") - parser.add_option("-v", "--verbose", help="Show more output", - action='store_true', dest="verbose", default=False) - parser.add_option("-s", "--succinct", help="Reduce amount of output", - action="store_true", dest="succinct", default=False) - - group = OptionGroup(parser, "Test Execution") - group.add_option("", "--expected-exit-code", help="Set expected exit code", - type=int, dest="expected_exit_code", - default=0) - group.add_option("", "--extra-exit-code", - help="Set additional expected exit code", - type=int, action="append", dest="extra_exit_codes", - default=[]) - group.add_option("", "--log-dir", - help="Capture test logs to an output directory", - type=str, dest="log_dir", - default=None) - group.add_option("", "--log-all", - help="Log all outputs (not just failures)", - action="store_true", dest="log_all", default=False) - parser.add_option_group(group) - - group = OptionGroup(parser, "Input Files") - group.add_option("", "--file", metavar="PATH", - help="Add an input file to fuzz", - type=str, action="append", dest="input_files", default=[]) - group.add_option("", "--filelist", metavar="LIST", - help="Add a list of inputs files to fuzz (one per line)", - type=str, action="append", dest="filelists", default=[]) - parser.add_option_group(group) - - group = OptionGroup(parser, "Fuzz Options") - group.add_option("", "--replacement-chars", dest="replacement_chars", - help="Characters to insert/replace", - default="0{}[]<>\;@#$^%& ") - group.add_option("", "--replacement-string", dest="replacement_strings", - action="append", help="Add a replacement string to use", - default=[]) - group.add_option("", "--replacement-list", dest="replacement_lists", - help="Add a list of replacement strings (one per line)", - action="append", default=[]) - group.add_option("", "--no-delete", help="Don't delete characters", - action='store_false', dest="enable_delete", default=True) - group.add_option("", "--no-insert", help="Don't insert strings", - action='store_false', dest="enable_insert", default=True) - group.add_option("", "--no-replace", help="Don't replace strings", - action='store_false', dest="enable_replace", default=True) - group.add_option("", "--no-revert", help="Don't revert changes", - action='store_false', dest="revert", default=True) - group.add_option("", "--stop-on-fail", help="Stop on first failure", - action='store_true', dest="stop_on_fail", default=False) - parser.add_option_group(group) - - group = OptionGroup(parser, "Test Selection") - group.add_option("", "--test", help="Run a particular test", - type=int, dest="test", default=None, metavar="INDEX") - group.add_option("", "--max-tests", help="Maximum number of tests", - type=int, dest="max_tests", default=None, metavar="COUNT") - group.add_option("", "--pick-input", - help="Randomly select an input byte as well as fuzzing", - action='store_true', dest="pick_input", default=False) - parser.add_option_group(group) - - parser.disable_interspersed_args() - - (opts, args) = parser.parse_args() - - if not args: - parser.error("Invalid number of arguments") - - # Collect the list of inputs. - input_files = list(opts.input_files) - for filelist in opts.filelists: - f = open(filelist) - try: - for ln in f: - ln = ln.strip() - if ln: - input_files.append(ln) - finally: - f.close() - input_files.sort() - - if not input_files: - parser.error("No input files!") - - print '%s: note: fuzzing %d files.' % (sys.argv[0], len(input_files)) - - # Make sure the log directory exists if used. - if opts.log_dir: - if not os.path.exists(opts.log_dir): - try: - os.mkdir(opts.log_dir) - except OSError: - print "%s: error: log directory couldn't be created!" % ( - sys.argv[0],) - raise SystemExit,1 - - # Get the list if insert/replacement strings. - replacements = list(opts.replacement_chars) - replacements.extend(opts.replacement_strings) - for replacement_list in opts.replacement_lists: - f = open(replacement_list) - try: - for ln in f: - ln = ln[:-1] - if ln: - replacements.append(ln) - finally: - f.close() - - # Unique and order the replacement list. - replacements = list(set(replacements)) - replacements.sort() - - # Create the test generator. - tg = TestGenerator(input_files, opts.enable_delete, opts.enable_insert, - opts.enable_replace, replacements, opts.pick_input) - - print '%s: note: %d input bytes.' % (sys.argv[0], tg.num_positions) - print '%s: note: %d total tests.' % (sys.argv[0], tg.num_tests) - if opts.test is not None: - it = [opts.test] - elif opts.max_tests is not None: - it = itertools.imap(random.randrange, - itertools.repeat(tg.num_tests, opts.max_tests)) - else: - it = itertools.imap(random.randrange, itertools.repeat(tg.num_tests)) - for test in it: - t = tg.get_test(test) - - if opts.verbose: - print '%s: note: running test %d: %r' % (sys.argv[0], test, t) - ta = TestApplication(tg, t) - try: - ta.apply() - test_result = run_one_test(ta, test, input_files, args) - if not test_result and opts.stop_on_fail: - opts.revert = False - sys.exit(1) - finally: - if opts.revert: - ta.revert() - - sys.stdout.flush() - -if __name__ == '__main__': - main() diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt deleted file mode 100644 index dba0c94ac0e4..000000000000 --- a/utils/TableGen/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -set(LLVM_LINK_COMPONENTS Support) - -add_tablegen(clang-tblgen CLANG - ClangASTNodesEmitter.cpp - ClangAttrEmitter.cpp - ClangCommentCommandInfoEmitter.cpp - ClangCommentHTMLNamedCharacterReferenceEmitter.cpp - ClangCommentHTMLTagsEmitter.cpp - ClangDataCollectorsEmitter.cpp - ClangDiagnosticsEmitter.cpp - ClangOptionDocEmitter.cpp - ClangSACheckersEmitter.cpp - NeonEmitter.cpp - TableGen.cpp - ) -set_target_properties(clang-tblgen PROPERTIES FOLDER "Clang tablegenning") diff --git a/utils/TestUtils/deep-stack.py b/utils/TestUtils/deep-stack.py deleted file mode 100755 index 10bf47acb1f7..000000000000 --- a/utils/TestUtils/deep-stack.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python - -from __future__ import absolute_import, division, print_function -def pcall(f, N): - if N == 0: - print(' f(0)', file=f) - return - - print(' f(', file=f) - pcall(f, N - 1) - print(' )', file=f) - -def main(): - f = open('t.c','w') - print('int f(int n) { return n; }', file=f) - print('int t() {', file=f) - print(' return', file=f) - pcall(f, 10000) - print(' ;', file=f) - print('}', file=f) - -if __name__ == "__main__": - import sys - sys.setrecursionlimit(100000) - main() diff --git a/utils/TestUtils/pch-test.pl b/utils/TestUtils/pch-test.pl deleted file mode 100755 index e4311e965bb7..000000000000 --- a/utils/TestUtils/pch-test.pl +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/perl -w - -# This tiny little script, which should be run from the clang -# directory (with clang in your patch), tries to take each -# compilable Clang test and build a PCH file from that test, then read -# and dump the contents of the PCH file just created. -use POSIX; - -$exitcode = 0; -sub testfiles($$) { - my $suffix = shift; - my $language = shift; - my $passed = 0; - my $failed = 0; - my $skipped = 0; - - @files = `ls test/*/*.$suffix`; - foreach $file (@files) { - chomp($file); - my $code = system("clang -fsyntax-only -x $language $file > /dev/null 2>&1"); - if ($code == 0) { - print("."); - $code = system("clang -cc1 -emit-pch -x $language -o $file.pch $file > /dev/null 2>&1"); - if ($code == 0) { - $code = system("clang -cc1 -include-pch $file.pch -x $language -ast-dump /dev/null > /dev/null 2>&1"); - if ($code == 0) { - $passed++; - } elsif (($code & 0xFF) == SIGINT) { - exit($exitcode); - } else { - print("\n---Failed to dump AST file for \"$file\"---\n"); - $exitcode = 1; - $failed++; - } - unlink "$file.pch"; - } elsif (($code & 0xFF) == SIGINT) { - exit($exitcode); - } else { - print("\n---Failed to build PCH file for \"$file\"---\n"); - $exitcode = 1; - $failed++; - } - } elsif (($code & 0xFF) == SIGINT) { - exit($exitcode); - } else { - print("x"); - $skipped++; - } - } - - print("\n\n$passed tests passed\n"); - print("$failed tests failed\n"); - print("$skipped tests skipped ('x')\n") -} - -printf("-----Testing precompiled headers for C-----\n"); -testfiles("c", "c"); -printf("\n-----Testing precompiled headers for Objective-C-----\n"); -testfiles("m", "objective-c"); -print("\n"); -exit($exitcode); diff --git a/utils/VtableTest/check-zti b/utils/VtableTest/check-zti deleted file mode 100755 index bf5b045d81d2..000000000000 --- a/utils/VtableTest/check-zti +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -N_STRUCTS=300 - -# Utility routine to "hand" check type infos. - -let i=1; -while [ $i != $N_STRUCTS ]; do - sed -n "/^__ZTI.*s$i:/,/\.[sg][el]/p" test-clang.s | - grep -v '\.[sg][el]' | sed 's/(\([0-9][0-9]*\))/\1/' >test-clang-zti - sed -n "/^__ZTI.*s$i:/,/\.[sg][el]/p" test-gcc.s | - grep -v '\.[sg][el]' | sed 's/(\([0-9][0-9]*\))/\1/' >test-gcc-zti - diff -U3 test-gcc-zti test-clang-zti - if [ $? != 0 ]; then - echo "FAIL: s$i type info" - else - echo "PASS: s$i type info" - fi - let i=i+1 -done diff --git a/utils/VtableTest/check-ztt b/utils/VtableTest/check-ztt deleted file mode 100755 index 4a83c55796a4..000000000000 --- a/utils/VtableTest/check-ztt +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -N_STRUCTS=300 - -# Utility routine to "hand" check VTTs. - -let i=1; -while [ $i != $N_STRUCTS ]; do - sed -n "/^__ZTT.*s$i:/,/\.[sgm][elo]/p" test-clang.s | - grep -v '\.[sgm][elo]' | sed -e 's/[()]//g' -e '/^$/d' >test-clang-ztt - sed -n "/^__ZTT.*s$i:/,/\.[sgm][elo]/p" test-gcc.s | - grep -v '\.[sgm][elo]' | sed -e 's/[()]//g' -e 's/ + /+/' >test-gcc-ztt - diff -U3 test-gcc-ztt test-clang-ztt - if [ $? != 0 ]; then - echo "FAIL: s$i VTT" - else - echo "PASS: s$i VTT" - fi - let i=i+1 -done diff --git a/utils/VtableTest/check-zvt b/utils/VtableTest/check-zvt deleted file mode 100755 index d8b93bd01fa1..000000000000 --- a/utils/VtableTest/check-zvt +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -N_STRUCTS=300 - -# Utility routine to "hand" check vtables. - -let i=1; -while [ $i != $N_STRUCTS ]; do - sed -n "/^__ZTV.*s$i:/,/\.[sg][el]/p" test-clang.s | grep -v '\.[sg][el]' >test-clang-ztv - sed -n "/^__ZTV.*s$i:/,/\.[sg][el]/p" test-gcc.s | grep -v '\.[sg][el]' >test-gcc-ztv - diff -U3 test-gcc-ztv test-clang-ztv - if [ $? != 0 ]; then - echo "FAIL: s$i vtable" - else - echo "PASS: s$i vtable" - fi - let i=i+1 -done diff --git a/utils/VtableTest/gen.cc b/utils/VtableTest/gen.cc deleted file mode 100644 index 8396f8d138b3..000000000000 --- a/utils/VtableTest/gen.cc +++ /dev/null @@ -1,350 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -#define N_FIELDS 7 -#define N_FUNCS 128 -#define FUNCSPACING 20 -#define N_STRUCTS 180 /* 1280 */ -#define N_BASES 6 -#define COVARIANT 0 - -const char *simple_types[] = { "bool", "char", "short", "int", "float", - "double", "long double", "wchar_t", "void *", - "char *" -}; - -void gl(const char *c) { - printf("%s\n", c); -} - -void g(const char *c) { - printf("%s", c); -} - -void g(int i) { - printf("%d", i); -} - -int uuid = 0; -char base_present[N_STRUCTS][N_STRUCTS]; - -// The return type for each function when doing covariant testcase generation. -short ret_types[N_STRUCTS][N_FUNCS*FUNCSPACING]; - -bool is_ambiguous(int s, int base) { - for (int i = 0; i < N_STRUCTS; ++i) { - if ((base_present[base][i] & base_present[s][i]) == 1) - return true; - } - return false; -} - -void add_bases(int s, int base) { - for (int i = 0; i < N_STRUCTS; ++i) - base_present[s][i] |= base_present[base][i]; - if (!COVARIANT) - return; - for (int i = 0; i < N_FUNCS*FUNCSPACING; ++i) { - if (!ret_types[base][i]) - continue; - if (!ret_types[s][i]) { - ret_types[s][i] = ret_types[base][i]; - continue; - } - if (base_present[ret_types[base][i]][ret_types[s][i]]) - // If the return type of the function from this base dominates - ret_types[s][i] = ret_types[base][i]; - if (base_present[ret_types[s][i]][ret_types[base][i]]) - // If a previous base dominates - continue; - // If neither dominates, we'll use this class. - ret_types[s][i] = s; - } -} - -// This contains the class that has the final override for -// each class, for each function. -short final_override[N_STRUCTS][N_FUNCS*FUNCSPACING]; - -void gs(int s) { - bool polymorphic = false; - - static int bases[N_BASES]; - int i_bases = random() % (N_BASES*2); - if (i_bases >= N_BASES) - // PARAM: 1/2 of all clases should have no bases - i_bases = 0; - int n_bases = 0; - bool first_base = true; - - // PARAM: 3/4 of all should be class, the rest are structs - if (random() % 4 == 0) - g("struct s"); - else - g("class s"); - g(s); - int old_base = -1; - if (s == 0 || s == 1) - i_bases = 0; - while (i_bases) { - --i_bases; - int base = random() % (s-1) + 1; - if (!base_present[s][base]) { - if (is_ambiguous(s, base)) - continue; - if (first_base) { - first_base = false; - g(": "); - } else - g(", "); - int base_type = 1; - if (random()%8 == 0) { - // PARAM: 1/8th the bases are virtual - g("virtual "); - // We have a vtable and rtti, but technically we're not polymorphic - // polymorphic = true; - base_type = 3; - } - // PARAM: 1/4 are public, 1/8 are privare, 1/8 are protected, the reset, default - int base_protection = 0; - if (!COVARIANT) - base_protection = random()%8; - switch (base_protection) { - case 0: - case 1: - g("public "); break; - case 2: - case 3: - case 4: - case 5: - break; - case 6: - g("private "); break; - case 7: - g("protected "); break; - } - g("s"); - add_bases(s, base); - bases[n_bases] = base; - base_present[s][base] = base_type; - ++n_bases; - g(base); - old_base = base; - } - } - gl(" {"); - - /* Fields */ - int n_fields = N_FIELDS == 0 ? 0 : random() % (N_FIELDS*4); - // PARAM: 3/4 of all structs should have no members - if (n_fields >= N_FIELDS) - n_fields = 0; - for (int i = 0; i < n_fields; ++i) { - int t = random() % (sizeof(simple_types) / sizeof(simple_types[0])); - g(" "); g(simple_types[t]); g(" field"); g(i); gl(";"); - } - - /* Virtual functions */ - static int funcs[N_FUNCS*FUNCSPACING]; - // PARAM: 1/2 of all structs should have no virtual functions - int n_funcs = random() % (N_FUNCS*2); - if (n_funcs > N_FUNCS) - n_funcs = 0; - int old_func = -1; - for (int i = 0; i < n_funcs; ++i) { - int fn = old_func + random() % FUNCSPACING + 1; - funcs[i] = fn; - int ret_type = 0; - if (COVARIANT) { - ret_type = random() % s + 1; - if (!base_present[s][ret_type] - || !base_present[ret_type][ret_types[s][fn]]) - if (ret_types[s][fn]) { - printf(" // Found one for s%d for s%d* fun%d.\n", s, - ret_types[s][fn], fn); - ret_type = ret_types[s][fn]; - } else - ret_type = s; - else - printf(" // Wow found one for s%d for fun%d.\n", s, fn); - ret_types[s][fn] = ret_type; - } - if (ret_type) { - g(" virtual s"); g(ret_type); g("* fun"); - } else - g(" virtual void fun"); - g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid); - if (ret_type) - gl("); return 0; }"); - else - gl("); }"); - final_override[s][fn] = s; - old_func = fn; - } - - // Add required overriders for correctness - for (int i = 0; i < n_bases; ++i) { - // For each base - int base = bases[i]; - for (int fn = 0; fn < N_FUNCS*FUNCSPACING; ++fn) { - // For each possible function - int new_base = final_override[base][fn]; - if (new_base == 0) - // If the base didn't have a final overrider, skip - continue; - - int prev_base = final_override[s][fn]; - if (prev_base == s) - // Skip functions defined in this class - continue; - - // If we don't want to change the info, skip - if (prev_base == new_base) - continue; - - if (prev_base == 0) { - // record the final override - final_override[s][fn] = new_base; - continue; - } - - if (base_present[prev_base][new_base]) { - // The previous base dominates the new base, no update necessary - printf(" // No override for fun%d in s%d as s%d dominates s%d.\n", - fn, s, prev_base, new_base); - continue; - } - - if (base_present[new_base][prev_base]) { - // The new base dominates the old base, no override necessary - printf(" // No override for fun%d in s%d as s%d dominates s%d.\n", - fn, s, new_base, prev_base); - // record the final override - final_override[s][fn] = new_base; - continue; - } - - printf(" // Found we needed override for fun%d in s%d.\n", fn, s); - - // record the final override - funcs[n_funcs++] = fn; - if (n_funcs == (N_FUNCS*FUNCSPACING-1)) - abort(); - int ret_type = 0; - if (COVARIANT) { - if (!ret_types[s][fn]) { - ret_types[s][fn] = ret_type = s; - } else { - ret_type = ret_types[s][fn]; - if (ret_type != s) - printf(" // Calculated return type in s%d as s%d* fun%d.\n", - s, ret_type, fn); - } - } - if (ret_type) { - g(" virtual s"); g(ret_type); g("* fun"); - } else - g(" virtual void fun"); - g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid); - if (ret_type) - gl("); return 0; }"); - else - gl("); }"); - final_override[s][fn] = s; - } - } - - gl("public:"); - gl(" void calc(char *t) {"); - - // mix in the type number - g(" mix(\"type num\", "); g(s); gl(");"); - // mix in the size - g(" mix(\"type size\", sizeof (s"); g(s); gl("));"); - // mix in the this offset - gl(" mix(\"subobject offset\", (char *)this - t);"); - if (n_funcs) - polymorphic = true; - if (polymorphic) { - // mix in offset to the complete object under construction - gl(" mix(\"real top v current top\", t - (char *)dynamic_cast<void*>(this));"); - } - - /* check base layout and overrides */ - for (int i = 0; i < n_bases; ++i) { - g(" calc_s"); g(bases[i]); gl("(t);"); - } - - if (polymorphic) { - /* check dynamic_cast to each direct base */ - for (int i = 0; i < n_bases; ++i) { - g(" if ((char *)dynamic_cast<s"); g(bases[i]); gl("*>(this))"); - g(" mix(\"base dyn cast\", t - (char *)dynamic_cast<s"); g(bases[i]); gl("*>(this));"); - g(" else mix(\"no dyncast\", "); g(++uuid); gl(");"); - } - } - - /* check field layout */ - for (int i = 0; i < n_fields; ++i) { - g(" mix(\"field offset\", (char *)&field"); g(i); gl(" - (char *)this);"); - } - if (n_fields == 0) { - g(" mix(\"no fields\", "); g(++uuid); gl(");"); - } - - /* check functions */ - for (int i = 0; i < n_funcs; ++i) { - g(" fun"); g(funcs[i]); gl("(t);"); - } - if (n_funcs == 0) { - g(" mix(\"no funcs\", "); g(++uuid); gl(");"); - } - - gl(" }"); - - // default ctor - g(" s"); g(s); g("() "); - first_base = true; - for (int i = 0; i < n_bases; ++i) { - if (first_base) { - g(": "); - first_base = false; - } else - g(", "); - g("s"); g(bases[i]); g("((char *)this)"); - } - gl(" { calc((char *)this); }"); - g(" ~s"); g(s); gl("() { calc((char *)this); }"); - - // ctor with this to the complete object - g(" s"); g(s); gl("(char *t) { calc(t); }"); - g(" void calc_s"); g(s); gl("(char *t) { calc(t); }"); - g("} a"); g(s); gl(";"); -} - -main(int argc, char **argv) { - unsigned seed = 0; - char state[16]; - if (argc > 1) - seed = atol(argv[1]); - - initstate(seed, state, sizeof(state)); - gl("extern \"C\" int printf(const char *...);"); - gl(""); - gl("long long sum;"); - gl("void mix(const char *desc, long long i) {"); - // If this ever becomes too slow, we can remove this after we improve the - // mixing function - gl(" printf(\"%s: %lld\\n\", desc, i);"); - gl(" sum += ((sum ^ i) << 3) + (sum<<1) - i;"); - gl("}"); - gl(""); - // PARAM: Randomly size testcases or large testcases? - int n_structs = /* random() % */ N_STRUCTS; - for (int i = 1; i < n_structs; ++i) - gs(i); - gl("int main() {"); - gl(" printf(\"%llx\\n\", sum);"); - gl("}"); - return 0; -} diff --git a/utils/analyzer/CmpRuns.py b/utils/analyzer/CmpRuns.py deleted file mode 100755 index be503499622d..000000000000 --- a/utils/analyzer/CmpRuns.py +++ /dev/null @@ -1,435 +0,0 @@ -#!/usr/bin/env python - -""" -CmpRuns - A simple tool for comparing two static analyzer runs to determine -which reports have been added, removed, or changed. - -This is designed to support automated testing using the static analyzer, from -two perspectives: - 1. To monitor changes in the static analyzer's reports on real code bases, - for regression testing. - - 2. For use by end users who want to integrate regular static analyzer testing - into a buildbot like environment. - -Usage: - - # Load the results of both runs, to obtain lists of the corresponding - # AnalysisDiagnostic objects. - # - resultsA = loadResultsFromSingleRun(singleRunInfoA, deleteEmpty) - resultsB = loadResultsFromSingleRun(singleRunInfoB, deleteEmpty) - - # Generate a relation from diagnostics in run A to diagnostics in run B - # to obtain a list of triples (a, b, confidence). - diff = compareResults(resultsA, resultsB) - -""" -from __future__ import division, print_function - -from collections import defaultdict - -from math import log -from optparse import OptionParser -import json -import os -import plistlib -import re -import sys - -STATS_REGEXP = re.compile(r"Statistics: (\{.+\})", re.MULTILINE | re.DOTALL) - -class Colors(object): - """ - Color for terminal highlight. - """ - RED = '\x1b[2;30;41m' - GREEN = '\x1b[6;30;42m' - CLEAR = '\x1b[0m' - -# Information about analysis run: -# path - the analysis output directory -# root - the name of the root directory, which will be disregarded when -# determining the source file name -class SingleRunInfo(object): - def __init__(self, path, root="", verboseLog=None): - self.path = path - self.root = root.rstrip("/\\") - self.verboseLog = verboseLog - - -class AnalysisDiagnostic(object): - def __init__(self, data, report, htmlReport): - self._data = data - self._loc = self._data['location'] - self._report = report - self._htmlReport = htmlReport - self._reportSize = len(self._data['path']) - - def getFileName(self): - root = self._report.run.root - fileName = self._report.files[self._loc['file']] - if fileName.startswith(root) and len(root) > 0: - return fileName[len(root) + 1:] - return fileName - - def getLine(self): - return self._loc['line'] - - def getColumn(self): - return self._loc['col'] - - def getPathLength(self): - return self._reportSize - - def getCategory(self): - return self._data['category'] - - def getDescription(self): - return self._data['description'] - - def getIssueIdentifier(self): - id = self.getFileName() + "+" - if 'issue_context' in self._data: - id += self._data['issue_context'] + "+" - if 'issue_hash_content_of_line_in_context' in self._data: - id += str(self._data['issue_hash_content_of_line_in_context']) - return id - - def getReport(self): - if self._htmlReport is None: - return " " - return os.path.join(self._report.run.path, self._htmlReport) - - def getReadableName(self): - if 'issue_context' in self._data: - funcnamePostfix = "#" + self._data['issue_context'] - else: - funcnamePostfix = "" - return '%s%s:%d:%d, %s: %s' % (self.getFileName(), - funcnamePostfix, - self.getLine(), - self.getColumn(), self.getCategory(), - self.getDescription()) - - # Note, the data format is not an API and may change from one analyzer - # version to another. - def getRawData(self): - return self._data - - -class AnalysisReport(object): - def __init__(self, run, files): - self.run = run - self.files = files - self.diagnostics = [] - - -class AnalysisRun(object): - def __init__(self, info): - self.path = info.path - self.root = info.root - self.info = info - self.reports = [] - # Cumulative list of all diagnostics from all the reports. - self.diagnostics = [] - self.clang_version = None - self.stats = [] - - def getClangVersion(self): - return self.clang_version - - def readSingleFile(self, p, deleteEmpty): - data = plistlib.readPlist(p) - if 'statistics' in data: - self.stats.append(json.loads(data['statistics'])) - data.pop('statistics') - - # We want to retrieve the clang version even if there are no - # reports. Assume that all reports were created using the same - # clang version (this is always true and is more efficient). - if 'clang_version' in data: - if self.clang_version is None: - self.clang_version = data.pop('clang_version') - else: - data.pop('clang_version') - - # Ignore/delete empty reports. - if not data['files']: - if deleteEmpty: - os.remove(p) - return - - # Extract the HTML reports, if they exists. - if 'HTMLDiagnostics_files' in data['diagnostics'][0]: - htmlFiles = [] - for d in data['diagnostics']: - # FIXME: Why is this named files, when does it have multiple - # files? - assert len(d['HTMLDiagnostics_files']) == 1 - htmlFiles.append(d.pop('HTMLDiagnostics_files')[0]) - else: - htmlFiles = [None] * len(data['diagnostics']) - - report = AnalysisReport(self, data.pop('files')) - diagnostics = [AnalysisDiagnostic(d, report, h) - for d, h in zip(data.pop('diagnostics'), htmlFiles)] - - assert not data - - report.diagnostics.extend(diagnostics) - self.reports.append(report) - self.diagnostics.extend(diagnostics) - - -def loadResults(path, opts, root="", deleteEmpty=True): - """ - Backwards compatibility API. - """ - return loadResultsFromSingleRun(SingleRunInfo(path, root, opts.verboseLog), - deleteEmpty) - - -def loadResultsFromSingleRun(info, deleteEmpty=True): - """ - # Load results of the analyzes from a given output folder. - # - info is the SingleRunInfo object - # - deleteEmpty specifies if the empty plist files should be deleted - - """ - path = info.path - run = AnalysisRun(info) - - if os.path.isfile(path): - run.readSingleFile(path, deleteEmpty) - else: - for (dirpath, dirnames, filenames) in os.walk(path): - for f in filenames: - if (not f.endswith('plist')): - continue - p = os.path.join(dirpath, f) - run.readSingleFile(p, deleteEmpty) - - return run - - -def cmpAnalysisDiagnostic(d): - return d.getIssueIdentifier() - - -def compareResults(A, B, opts): - """ - compareResults - Generate a relation from diagnostics in run A to - diagnostics in run B. - - The result is the relation as a list of triples (a, b) where - each element {a,b} is None or a matching element from the respective run - """ - - res = [] - - # Map size_before -> size_after - path_difference_data = [] - - # Quickly eliminate equal elements. - neqA = [] - neqB = [] - eltsA = list(A.diagnostics) - eltsB = list(B.diagnostics) - eltsA.sort(key=cmpAnalysisDiagnostic) - eltsB.sort(key=cmpAnalysisDiagnostic) - while eltsA and eltsB: - a = eltsA.pop() - b = eltsB.pop() - if (a.getIssueIdentifier() == b.getIssueIdentifier()): - if a.getPathLength() != b.getPathLength(): - if opts.relative_path_histogram: - path_difference_data.append( - float(a.getPathLength()) / b.getPathLength()) - elif opts.relative_log_path_histogram: - path_difference_data.append( - log(float(a.getPathLength()) / b.getPathLength())) - elif opts.absolute_path_histogram: - path_difference_data.append( - a.getPathLength() - b.getPathLength()) - - res.append((a, b)) - elif a.getIssueIdentifier() > b.getIssueIdentifier(): - eltsB.append(b) - neqA.append(a) - else: - eltsA.append(a) - neqB.append(b) - neqA.extend(eltsA) - neqB.extend(eltsB) - - # FIXME: Add fuzzy matching. One simple and possible effective idea would - # be to bin the diagnostics, print them in a normalized form (based solely - # on the structure of the diagnostic), compute the diff, then use that as - # the basis for matching. This has the nice property that we don't depend - # in any way on the diagnostic format. - - for a in neqA: - res.append((a, None)) - for b in neqB: - res.append((None, b)) - - if opts.relative_log_path_histogram or opts.relative_path_histogram or \ - opts.absolute_path_histogram: - from matplotlib import pyplot - pyplot.hist(path_difference_data, bins=100) - pyplot.show() - - return res - -def computePercentile(l, percentile): - """ - Return computed percentile. - """ - return sorted(l)[int(round(percentile * len(l) + 0.5)) - 1] - -def deriveStats(results): - # Assume all keys are the same in each statistics bucket. - combined_data = defaultdict(list) - - # Collect data on paths length. - for report in results.reports: - for diagnostic in report.diagnostics: - combined_data['PathsLength'].append(diagnostic.getPathLength()) - - for stat in results.stats: - for key, value in stat.items(): - combined_data[key].append(value) - combined_stats = {} - for key, values in combined_data.items(): - combined_stats[str(key)] = { - "max": max(values), - "min": min(values), - "mean": sum(values) / len(values), - "90th %tile": computePercentile(values, 0.9), - "95th %tile": computePercentile(values, 0.95), - "median": sorted(values)[len(values) // 2], - "total": sum(values) - } - return combined_stats - - -def compareStats(resultsA, resultsB): - statsA = deriveStats(resultsA) - statsB = deriveStats(resultsB) - keys = sorted(statsA.keys()) - for key in keys: - print(key) - for kkey in statsA[key]: - valA = float(statsA[key][kkey]) - valB = float(statsB[key][kkey]) - report = "%.3f -> %.3f" % (valA, valB) - # Only apply highlighting when writing to TTY and it's not Windows - if sys.stdout.isatty() and os.name != 'nt': - if valB != 0: - ratio = (valB - valA) / valB - if ratio < -0.2: - report = Colors.GREEN + report + Colors.CLEAR - elif ratio > 0.2: - report = Colors.RED + report + Colors.CLEAR - print("\t %s %s" % (kkey, report)) - -def dumpScanBuildResultsDiff(dirA, dirB, opts, deleteEmpty=True, - Stdout=sys.stdout): - # Load the run results. - resultsA = loadResults(dirA, opts, opts.rootA, deleteEmpty) - resultsB = loadResults(dirB, opts, opts.rootB, deleteEmpty) - if opts.show_stats: - compareStats(resultsA, resultsB) - if opts.stats_only: - return - - # Open the verbose log, if given. - if opts.verboseLog: - auxLog = open(opts.verboseLog, "wb") - else: - auxLog = None - - diff = compareResults(resultsA, resultsB, opts) - foundDiffs = 0 - totalAdded = 0 - totalRemoved = 0 - for res in diff: - a, b = res - if a is None: - Stdout.write("ADDED: %r\n" % b.getReadableName()) - foundDiffs += 1 - totalAdded += 1 - if auxLog: - auxLog.write("('ADDED', %r, %r)\n" % (b.getReadableName(), - b.getReport())) - elif b is None: - Stdout.write("REMOVED: %r\n" % a.getReadableName()) - foundDiffs += 1 - totalRemoved += 1 - if auxLog: - auxLog.write("('REMOVED', %r, %r)\n" % (a.getReadableName(), - a.getReport())) - else: - pass - - TotalReports = len(resultsB.diagnostics) - Stdout.write("TOTAL REPORTS: %r\n" % TotalReports) - Stdout.write("TOTAL ADDED: %r\n" % totalAdded) - Stdout.write("TOTAL REMOVED: %r\n" % totalRemoved) - if auxLog: - auxLog.write("('TOTAL NEW REPORTS', %r)\n" % TotalReports) - auxLog.write("('TOTAL DIFFERENCES', %r)\n" % foundDiffs) - auxLog.close() - - return foundDiffs, len(resultsA.diagnostics), len(resultsB.diagnostics) - -def generate_option_parser(): - parser = OptionParser("usage: %prog [options] [dir A] [dir B]") - parser.add_option("", "--rootA", dest="rootA", - help="Prefix to ignore on source files for directory A", - action="store", type=str, default="") - parser.add_option("", "--rootB", dest="rootB", - help="Prefix to ignore on source files for directory B", - action="store", type=str, default="") - parser.add_option("", "--verbose-log", dest="verboseLog", - help="Write additional information to LOG \ - [default=None]", - action="store", type=str, default=None, - metavar="LOG") - parser.add_option("--relative-path-differences-histogram", - action="store_true", dest="relative_path_histogram", - default=False, - help="Show histogram of relative paths differences. \ - Requires matplotlib") - parser.add_option("--relative-log-path-differences-histogram", - action="store_true", dest="relative_log_path_histogram", - default=False, - help="Show histogram of log relative paths differences. \ - Requires matplotlib") - parser.add_option("--absolute-path-differences-histogram", - action="store_true", dest="absolute_path_histogram", - default=False, - help="Show histogram of absolute paths differences. \ - Requires matplotlib") - parser.add_option("--stats-only", action="store_true", dest="stats_only", - default=False, help="Only show statistics on reports") - parser.add_option("--show-stats", action="store_true", dest="show_stats", - default=False, help="Show change in statistics") - return parser - - -def main(): - parser = generate_option_parser() - (opts, args) = parser.parse_args() - - if len(args) != 2: - parser.error("invalid number of arguments") - - dirA, dirB = args - - dumpScanBuildResultsDiff(dirA, dirB, opts) - - -if __name__ == '__main__': - main() diff --git a/utils/analyzer/SATestAdd.py b/utils/analyzer/SATestAdd.py deleted file mode 100644 index 52089f4e0660..000000000000 --- a/utils/analyzer/SATestAdd.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python - -""" -Static Analyzer qualification infrastructure: adding a new project to -the Repository Directory. - - Add a new project for testing: build it and add to the Project Map file. - Assumes it's being run from the Repository Directory. - The project directory should be added inside the Repository Directory and - have the same name as the project ID - - The project should use the following files for set up: - - cleanup_run_static_analyzer.sh - prepare the build environment. - Ex: make clean can be a part of it. - - run_static_analyzer.cmd - a list of commands to run through scan-build. - Each command should be on a separate line. - Choose from: configure, make, xcodebuild - - download_project.sh - download the project into the CachedSource/ - directory. For example, download a zip of - the project source from GitHub, unzip it, - and rename the unzipped directory to - 'CachedSource'. This script is not called - when 'CachedSource' is already present, - so an alternative is to check the - 'CachedSource' directory into the - repository directly. - - CachedSource/ - An optional directory containing the source of the - project being analyzed. If present, - download_project.sh will not be called. - - changes_for_analyzer.patch - An optional patch file for any local - changes - (e.g., to adapt to newer version of clang) - that should be applied to CachedSource - before analysis. To construct this patch, - run the download script to download - the project to CachedSource, copy the - CachedSource to another directory (for - example, PatchedSource) and make any - needed modifications to the copied - source. - Then run: - diff -ur CachedSource PatchedSource \ - > changes_for_analyzer.patch -""" -from __future__ import absolute_import, division, print_function -import SATestBuild - -import os -import csv -import sys - - -def isExistingProject(PMapFile, projectID): - PMapReader = csv.reader(PMapFile) - for I in PMapReader: - if projectID == I[0]: - return True - return False - - -def addNewProject(ID, BuildMode): - """ - Add a new project for testing: build it and add to the Project Map file. - :param ID: is a short string used to identify a project. - """ - - CurDir = os.path.abspath(os.curdir) - Dir = SATestBuild.getProjectDir(ID) - if not os.path.exists(Dir): - print("Error: Project directory is missing: %s" % Dir) - sys.exit(-1) - - # Build the project. - SATestBuild.testProject(ID, BuildMode, IsReferenceBuild=True) - - # Add the project ID to the project map. - ProjectMapPath = os.path.join(CurDir, SATestBuild.ProjectMapFile) - - if os.path.exists(ProjectMapPath): - FileMode = "r+b" - else: - print("Warning: Creating the Project Map file!!") - FileMode = "w+b" - - with open(ProjectMapPath, FileMode) as PMapFile: - if (isExistingProject(PMapFile, ID)): - print('Warning: Project with ID \'', ID, \ - '\' already exists.', file=sys.stdout) - print("Reference output has been regenerated.", file=sys.stdout) - else: - PMapWriter = csv.writer(PMapFile) - PMapWriter.writerow((ID, int(BuildMode))) - print("The project map is updated: ", ProjectMapPath) - - -# TODO: Add an option not to build. -# TODO: Set the path to the Repository directory. -if __name__ == '__main__': - if len(sys.argv) < 2 or sys.argv[1] in ('-h', '--help'): - print('Add a new project for testing to the analyzer'\ - '\nUsage: ', sys.argv[0],\ - 'project_ID <mode>\n' \ - 'mode: 0 for single file project, ' \ - '1 for scan_build, ' \ - '2 for single file c++11 project', file=sys.stderr) - sys.exit(-1) - - BuildMode = 1 - if (len(sys.argv) >= 3): - BuildMode = int(sys.argv[2]) - assert((BuildMode == 0) | (BuildMode == 1) | (BuildMode == 2)) - - addNewProject(sys.argv[1], BuildMode) diff --git a/utils/analyzer/SATestBuild.py b/utils/analyzer/SATestBuild.py deleted file mode 100644 index 1c96cd883818..000000000000 --- a/utils/analyzer/SATestBuild.py +++ /dev/null @@ -1,809 +0,0 @@ -#!/usr/bin/env python - -""" -Static Analyzer qualification infrastructure. - -The goal is to test the analyzer against different projects, -check for failures, compare results, and measure performance. - -Repository Directory will contain sources of the projects as well as the -information on how to build them and the expected output. -Repository Directory structure: - - ProjectMap file - - Historical Performance Data - - Project Dir1 - - ReferenceOutput - - Project Dir2 - - ReferenceOutput - .. -Note that the build tree must be inside the project dir. - -To test the build of the analyzer one would: - - Copy over a copy of the Repository Directory. (TODO: Prefer to ensure that - the build directory does not pollute the repository to min network - traffic). - - Build all projects, until error. Produce logs to report errors. - - Compare results. - -The files which should be kept around for failure investigations: - RepositoryCopy/Project DirI/ScanBuildResults - RepositoryCopy/Project DirI/run_static_analyzer.log - -Assumptions (TODO: shouldn't need to assume these.): - The script is being run from the Repository Directory. - The compiler for scan-build and scan-build are in the PATH. - export PATH=/Users/zaks/workspace/c2llvm/build/Release+Asserts/bin:$PATH - -For more logging, set the env variables: - zaks:TI zaks$ export CCC_ANALYZER_LOG=1 - zaks:TI zaks$ export CCC_ANALYZER_VERBOSE=1 - -The list of checkers tested are hardcoded in the Checkers variable. -For testing additional checkers, use the SA_ADDITIONAL_CHECKERS environment -variable. It should contain a comma separated list. -""" -import CmpRuns -import SATestUtils - -from subprocess import CalledProcessError, check_call -import argparse -import csv -import glob -import logging -import math -import multiprocessing -import os -import plistlib -import shutil -import sys -import threading -import time -try: - import queue -except ImportError: - import Queue as queue - -############################################################################### -# Helper functions. -############################################################################### - -Local = threading.local() -Local.stdout = sys.stdout -Local.stderr = sys.stderr -logging.basicConfig( - level=logging.DEBUG, - format='%(asctime)s:%(levelname)s:%(name)s: %(message)s') - -class StreamToLogger(object): - def __init__(self, logger, log_level=logging.INFO): - self.logger = logger - self.log_level = log_level - - def write(self, buf): - # Rstrip in order not to write an extra newline. - self.logger.log(self.log_level, buf.rstrip()) - - def flush(self): - pass - - def fileno(self): - return 0 - - -def getProjectMapPath(): - ProjectMapPath = os.path.join(os.path.abspath(os.curdir), - ProjectMapFile) - if not os.path.exists(ProjectMapPath): - Local.stdout.write("Error: Cannot find the Project Map file " + - ProjectMapPath + - "\nRunning script for the wrong directory?\n") - sys.exit(1) - return ProjectMapPath - - -def getProjectDir(ID): - return os.path.join(os.path.abspath(os.curdir), ID) - - -def getSBOutputDirName(IsReferenceBuild): - if IsReferenceBuild: - return SBOutputDirReferencePrefix + SBOutputDirName - else: - return SBOutputDirName - -############################################################################### -# Configuration setup. -############################################################################### - - -# Find Clang for static analysis. -if 'CC' in os.environ: - Clang = os.environ['CC'] -else: - Clang = SATestUtils.which("clang", os.environ['PATH']) -if not Clang: - print("Error: cannot find 'clang' in PATH") - sys.exit(1) - -# Number of jobs. -MaxJobs = int(math.ceil(multiprocessing.cpu_count() * 0.75)) - -# Project map stores info about all the "registered" projects. -ProjectMapFile = "projectMap.csv" - -# Names of the project specific scripts. -# The script that downloads the project. -DownloadScript = "download_project.sh" -# The script that needs to be executed before the build can start. -CleanupScript = "cleanup_run_static_analyzer.sh" -# This is a file containing commands for scan-build. -BuildScript = "run_static_analyzer.cmd" - -# A comment in a build script which disables wrapping. -NoPrefixCmd = "#NOPREFIX" - -# The log file name. -LogFolderName = "Logs" -BuildLogName = "run_static_analyzer.log" -# Summary file - contains the summary of the failures. Ex: This info can be be -# displayed when buildbot detects a build failure. -NumOfFailuresInSummary = 10 -FailuresSummaryFileName = "failures.txt" - -# The scan-build result directory. -SBOutputDirName = "ScanBuildResults" -SBOutputDirReferencePrefix = "Ref" - -# The name of the directory storing the cached project source. If this -# directory does not exist, the download script will be executed. -# That script should create the "CachedSource" directory and download the -# project source into it. -CachedSourceDirName = "CachedSource" - -# The name of the directory containing the source code that will be analyzed. -# Each time a project is analyzed, a fresh copy of its CachedSource directory -# will be copied to the PatchedSource directory and then the local patches -# in PatchfileName will be applied (if PatchfileName exists). -PatchedSourceDirName = "PatchedSource" - -# The name of the patchfile specifying any changes that should be applied -# to the CachedSource before analyzing. -PatchfileName = "changes_for_analyzer.patch" - -# The list of checkers used during analyzes. -# Currently, consists of all the non-experimental checkers, plus a few alpha -# checkers we don't want to regress on. -Checkers = ",".join([ - "alpha.unix.SimpleStream", - "alpha.security.taint", - "cplusplus.NewDeleteLeaks", - "core", - "cplusplus", - "deadcode", - "security", - "unix", - "osx", - "nullability" -]) - -Verbose = 0 - -############################################################################### -# Test harness logic. -############################################################################### - - -def runCleanupScript(Dir, PBuildLogFile): - """ - Run pre-processing script if any. - """ - Cwd = os.path.join(Dir, PatchedSourceDirName) - ScriptPath = os.path.join(Dir, CleanupScript) - SATestUtils.runScript(ScriptPath, PBuildLogFile, Cwd, - Stdout=Local.stdout, Stderr=Local.stderr) - - -def runDownloadScript(Dir, PBuildLogFile): - """ - Run the script to download the project, if it exists. - """ - ScriptPath = os.path.join(Dir, DownloadScript) - SATestUtils.runScript(ScriptPath, PBuildLogFile, Dir, - Stdout=Local.stdout, Stderr=Local.stderr) - - -def downloadAndPatch(Dir, PBuildLogFile): - """ - Download the project and apply the local patchfile if it exists. - """ - CachedSourceDirPath = os.path.join(Dir, CachedSourceDirName) - - # If the we don't already have the cached source, run the project's - # download script to download it. - if not os.path.exists(CachedSourceDirPath): - runDownloadScript(Dir, PBuildLogFile) - if not os.path.exists(CachedSourceDirPath): - Local.stderr.write("Error: '%s' not found after download.\n" % ( - CachedSourceDirPath)) - exit(1) - - PatchedSourceDirPath = os.path.join(Dir, PatchedSourceDirName) - - # Remove potentially stale patched source. - if os.path.exists(PatchedSourceDirPath): - shutil.rmtree(PatchedSourceDirPath) - - # Copy the cached source and apply any patches to the copy. - shutil.copytree(CachedSourceDirPath, PatchedSourceDirPath, symlinks=True) - applyPatch(Dir, PBuildLogFile) - - -def applyPatch(Dir, PBuildLogFile): - PatchfilePath = os.path.join(Dir, PatchfileName) - PatchedSourceDirPath = os.path.join(Dir, PatchedSourceDirName) - if not os.path.exists(PatchfilePath): - Local.stdout.write(" No local patches.\n") - return - - Local.stdout.write(" Applying patch.\n") - try: - check_call("patch -p1 < '%s'" % (PatchfilePath), - cwd=PatchedSourceDirPath, - stderr=PBuildLogFile, - stdout=PBuildLogFile, - shell=True) - except: - Local.stderr.write("Error: Patch failed. See %s for details.\n" % ( - PBuildLogFile.name)) - sys.exit(1) - - -def generateAnalyzerConfig(Args): - Out = "serialize-stats=true,stable-report-filename=true" - if Args.extra_analyzer_config: - Out += "," + Args.extra_analyzer_config - return Out - - -def runScanBuild(Args, Dir, SBOutputDir, PBuildLogFile): - """ - Build the project with scan-build by reading in the commands and - prefixing them with the scan-build options. - """ - BuildScriptPath = os.path.join(Dir, BuildScript) - if not os.path.exists(BuildScriptPath): - Local.stderr.write( - "Error: build script is not defined: %s\n" % BuildScriptPath) - sys.exit(1) - - AllCheckers = Checkers - if 'SA_ADDITIONAL_CHECKERS' in os.environ: - AllCheckers = AllCheckers + ',' + os.environ['SA_ADDITIONAL_CHECKERS'] - - # Run scan-build from within the patched source directory. - SBCwd = os.path.join(Dir, PatchedSourceDirName) - - SBOptions = "--use-analyzer '%s' " % Clang - SBOptions += "-plist-html -o '%s' " % SBOutputDir - SBOptions += "-enable-checker " + AllCheckers + " " - SBOptions += "--keep-empty " - SBOptions += "-analyzer-config '%s' " % generateAnalyzerConfig(Args) - - # Always use ccc-analyze to ensure that we can locate the failures - # directory. - SBOptions += "--override-compiler " - ExtraEnv = {} - try: - SBCommandFile = open(BuildScriptPath, "r") - SBPrefix = "scan-build " + SBOptions + " " - for Command in SBCommandFile: - Command = Command.strip() - if len(Command) == 0: - continue - - # Custom analyzer invocation specified by project. - # Communicate required information using environment variables - # instead. - if Command == NoPrefixCmd: - SBPrefix = "" - ExtraEnv['OUTPUT'] = SBOutputDir - ExtraEnv['CC'] = Clang - ExtraEnv['ANALYZER_CONFIG'] = generateAnalyzerConfig(Args) - continue - - # If using 'make', auto imply a -jX argument - # to speed up analysis. xcodebuild will - # automatically use the maximum number of cores. - if (Command.startswith("make ") or Command == "make") and \ - "-j" not in Command: - Command += " -j%d" % MaxJobs - SBCommand = SBPrefix + Command - - if Verbose == 1: - Local.stdout.write(" Executing: %s\n" % (SBCommand,)) - check_call(SBCommand, cwd=SBCwd, - stderr=PBuildLogFile, - stdout=PBuildLogFile, - env=dict(os.environ, **ExtraEnv), - shell=True) - except CalledProcessError: - Local.stderr.write("Error: scan-build failed. Its output was: \n") - PBuildLogFile.seek(0) - shutil.copyfileobj(PBuildLogFile, Local.stderr) - sys.exit(1) - - -def runAnalyzePreprocessed(Args, Dir, SBOutputDir, Mode): - """ - Run analysis on a set of preprocessed files. - """ - if os.path.exists(os.path.join(Dir, BuildScript)): - Local.stderr.write( - "Error: The preprocessed files project should not contain %s\n" % ( - BuildScript)) - raise Exception() - - CmdPrefix = Clang + " -cc1 " - - # For now, we assume the preprocessed files should be analyzed - # with the OS X SDK. - SDKPath = SATestUtils.getSDKPath("macosx") - if SDKPath is not None: - CmdPrefix += "-isysroot " + SDKPath + " " - - CmdPrefix += "-analyze -analyzer-output=plist -w " - CmdPrefix += "-analyzer-checker=" + Checkers - CmdPrefix += " -fcxx-exceptions -fblocks " - CmdPrefix += " -analyzer-config %s " % generateAnalyzerConfig(Args) - - if (Mode == 2): - CmdPrefix += "-std=c++11 " - - PlistPath = os.path.join(Dir, SBOutputDir, "date") - FailPath = os.path.join(PlistPath, "failures") - os.makedirs(FailPath) - - for FullFileName in glob.glob(Dir + "/*"): - FileName = os.path.basename(FullFileName) - Failed = False - - # Only run the analyzes on supported files. - if SATestUtils.hasNoExtension(FileName): - continue - if not SATestUtils.isValidSingleInputFile(FileName): - Local.stderr.write( - "Error: Invalid single input file %s.\n" % (FullFileName,)) - raise Exception() - - # Build and call the analyzer command. - OutputOption = "-o '%s.plist' " % os.path.join(PlistPath, FileName) - Command = CmdPrefix + OutputOption + ("'%s'" % FileName) - LogFile = open(os.path.join(FailPath, FileName + ".stderr.txt"), "w+b") - try: - if Verbose == 1: - Local.stdout.write(" Executing: %s\n" % (Command,)) - check_call(Command, cwd=Dir, stderr=LogFile, - stdout=LogFile, - shell=True) - except CalledProcessError as e: - Local.stderr.write("Error: Analyzes of %s failed. " - "See %s for details." - "Error code %d.\n" % ( - FullFileName, LogFile.name, e.returncode)) - Failed = True - finally: - LogFile.close() - - # If command did not fail, erase the log file. - if not Failed: - os.remove(LogFile.name) - - -def getBuildLogPath(SBOutputDir): - return os.path.join(SBOutputDir, LogFolderName, BuildLogName) - - -def removeLogFile(SBOutputDir): - BuildLogPath = getBuildLogPath(SBOutputDir) - # Clean up the log file. - if (os.path.exists(BuildLogPath)): - RmCommand = "rm '%s'" % BuildLogPath - if Verbose == 1: - Local.stdout.write(" Executing: %s\n" % (RmCommand,)) - check_call(RmCommand, shell=True) - - -def buildProject(Args, Dir, SBOutputDir, ProjectBuildMode, IsReferenceBuild): - TBegin = time.time() - - BuildLogPath = getBuildLogPath(SBOutputDir) - Local.stdout.write("Log file: %s\n" % (BuildLogPath,)) - Local.stdout.write("Output directory: %s\n" % (SBOutputDir, )) - - removeLogFile(SBOutputDir) - - # Clean up scan build results. - if (os.path.exists(SBOutputDir)): - RmCommand = "rm -r '%s'" % SBOutputDir - if Verbose == 1: - Local.stdout.write(" Executing: %s\n" % (RmCommand,)) - check_call(RmCommand, shell=True, stdout=Local.stdout, - stderr=Local.stderr) - assert(not os.path.exists(SBOutputDir)) - os.makedirs(os.path.join(SBOutputDir, LogFolderName)) - - # Build and analyze the project. - with open(BuildLogPath, "wb+") as PBuildLogFile: - if (ProjectBuildMode == 1): - downloadAndPatch(Dir, PBuildLogFile) - runCleanupScript(Dir, PBuildLogFile) - runScanBuild(Args, Dir, SBOutputDir, PBuildLogFile) - else: - runAnalyzePreprocessed(Args, Dir, SBOutputDir, ProjectBuildMode) - - if IsReferenceBuild: - runCleanupScript(Dir, PBuildLogFile) - normalizeReferenceResults(Dir, SBOutputDir, ProjectBuildMode) - - Local.stdout.write("Build complete (time: %.2f). " - "See the log for more details: %s\n" % ( - (time.time() - TBegin), BuildLogPath)) - - -def normalizeReferenceResults(Dir, SBOutputDir, ProjectBuildMode): - """ - Make the absolute paths relative in the reference results. - """ - for (DirPath, Dirnames, Filenames) in os.walk(SBOutputDir): - for F in Filenames: - if (not F.endswith('plist')): - continue - Plist = os.path.join(DirPath, F) - Data = plistlib.readPlist(Plist) - PathPrefix = Dir - if (ProjectBuildMode == 1): - PathPrefix = os.path.join(Dir, PatchedSourceDirName) - Paths = [SourceFile[len(PathPrefix) + 1:] - if SourceFile.startswith(PathPrefix) - else SourceFile for SourceFile in Data['files']] - Data['files'] = Paths - - # Remove transient fields which change from run to run. - for Diag in Data['diagnostics']: - if 'HTMLDiagnostics_files' in Diag: - Diag.pop('HTMLDiagnostics_files') - if 'clang_version' in Data: - Data.pop('clang_version') - - plistlib.writePlist(Data, Plist) - - -def CleanUpEmptyPlists(SBOutputDir): - """ - A plist file is created for each call to the analyzer(each source file). - We are only interested on the once that have bug reports, - so delete the rest. - """ - for F in glob.glob(SBOutputDir + "/*/*.plist"): - P = os.path.join(SBOutputDir, F) - - Data = plistlib.readPlist(P) - # Delete empty reports. - if not Data['files']: - os.remove(P) - continue - - -def CleanUpEmptyFolders(SBOutputDir): - """ - Remove empty folders from results, as git would not store them. - """ - Subfolders = glob.glob(SBOutputDir + "/*") - for Folder in Subfolders: - if not os.listdir(Folder): - os.removedirs(Folder) - - -def checkBuild(SBOutputDir): - """ - Given the scan-build output directory, checks if the build failed - (by searching for the failures directories). If there are failures, it - creates a summary file in the output directory. - - """ - # Check if there are failures. - Failures = glob.glob(SBOutputDir + "/*/failures/*.stderr.txt") - TotalFailed = len(Failures) - if TotalFailed == 0: - CleanUpEmptyPlists(SBOutputDir) - CleanUpEmptyFolders(SBOutputDir) - Plists = glob.glob(SBOutputDir + "/*/*.plist") - Local.stdout.write( - "Number of bug reports (non-empty plist files) produced: %d\n" % - len(Plists)) - return - - Local.stderr.write("Error: analysis failed.\n") - Local.stderr.write("Total of %d failures discovered.\n" % TotalFailed) - if TotalFailed > NumOfFailuresInSummary: - Local.stderr.write( - "See the first %d below.\n" % NumOfFailuresInSummary) - # TODO: Add a line "See the results folder for more." - - Idx = 0 - for FailLogPathI in Failures: - if Idx >= NumOfFailuresInSummary: - break - Idx += 1 - Local.stderr.write("\n-- Error #%d -----------\n" % Idx) - with open(FailLogPathI, "r") as FailLogI: - shutil.copyfileobj(FailLogI, Local.stdout) - - sys.exit(1) - - -def runCmpResults(Dir, Strictness=0): - """ - Compare the warnings produced by scan-build. - Strictness defines the success criteria for the test: - 0 - success if there are no crashes or analyzer failure. - 1 - success if there are no difference in the number of reported bugs. - 2 - success if all the bug reports are identical. - - :return success: Whether tests pass according to the Strictness - criteria. - """ - TestsPassed = True - TBegin = time.time() - - RefDir = os.path.join(Dir, SBOutputDirReferencePrefix + SBOutputDirName) - NewDir = os.path.join(Dir, SBOutputDirName) - - # We have to go one level down the directory tree. - RefList = glob.glob(RefDir + "/*") - NewList = glob.glob(NewDir + "/*") - - # Log folders are also located in the results dir, so ignore them. - RefLogDir = os.path.join(RefDir, LogFolderName) - if RefLogDir in RefList: - RefList.remove(RefLogDir) - NewList.remove(os.path.join(NewDir, LogFolderName)) - - if len(RefList) != len(NewList): - print("Mismatch in number of results folders: %s vs %s" % ( - RefList, NewList)) - sys.exit(1) - - # There might be more then one folder underneath - one per each scan-build - # command (Ex: one for configure and one for make). - if (len(RefList) > 1): - # Assume that the corresponding folders have the same names. - RefList.sort() - NewList.sort() - - # Iterate and find the differences. - NumDiffs = 0 - for P in zip(RefList, NewList): - RefDir = P[0] - NewDir = P[1] - - assert(RefDir != NewDir) - if Verbose == 1: - Local.stdout.write(" Comparing Results: %s %s\n" % ( - RefDir, NewDir)) - - PatchedSourceDirPath = os.path.join(Dir, PatchedSourceDirName) - Opts, Args = CmpRuns.generate_option_parser().parse_args( - ["--rootA", "", "--rootB", PatchedSourceDirPath]) - # Scan the results, delete empty plist files. - NumDiffs, ReportsInRef, ReportsInNew = \ - CmpRuns.dumpScanBuildResultsDiff(RefDir, NewDir, Opts, - deleteEmpty=False, - Stdout=Local.stdout) - if (NumDiffs > 0): - Local.stdout.write("Warning: %s differences in diagnostics.\n" - % NumDiffs) - if Strictness >= 2 and NumDiffs > 0: - Local.stdout.write("Error: Diffs found in strict mode (2).\n") - TestsPassed = False - elif Strictness >= 1 and ReportsInRef != ReportsInNew: - Local.stdout.write("Error: The number of results are different " + - " strict mode (1).\n") - TestsPassed = False - - Local.stdout.write("Diagnostic comparison complete (time: %.2f).\n" % ( - time.time() - TBegin)) - return TestsPassed - - -def cleanupReferenceResults(SBOutputDir): - """ - Delete html, css, and js files from reference results. These can - include multiple copies of the benchmark source and so get very large. - """ - Extensions = ["html", "css", "js"] - for E in Extensions: - for F in glob.glob("%s/*/*.%s" % (SBOutputDir, E)): - P = os.path.join(SBOutputDir, F) - RmCommand = "rm '%s'" % P - check_call(RmCommand, shell=True) - - # Remove the log file. It leaks absolute path names. - removeLogFile(SBOutputDir) - - -class TestProjectThread(threading.Thread): - def __init__(self, Args, TasksQueue, ResultsDiffer, FailureFlag): - """ - :param ResultsDiffer: Used to signify that results differ from - the canonical ones. - :param FailureFlag: Used to signify a failure during the run. - """ - self.Args = Args - self.TasksQueue = TasksQueue - self.ResultsDiffer = ResultsDiffer - self.FailureFlag = FailureFlag - super(TestProjectThread, self).__init__() - - # Needed to gracefully handle interrupts with Ctrl-C - self.daemon = True - - def run(self): - while not self.TasksQueue.empty(): - try: - ProjArgs = self.TasksQueue.get() - Logger = logging.getLogger(ProjArgs[0]) - Local.stdout = StreamToLogger(Logger, logging.INFO) - Local.stderr = StreamToLogger(Logger, logging.ERROR) - if not testProject(Args, *ProjArgs): - self.ResultsDiffer.set() - self.TasksQueue.task_done() - except: - self.FailureFlag.set() - raise - - -def testProject(Args, ID, ProjectBuildMode, IsReferenceBuild=False, Strictness=0): - """ - Test a given project. - :return TestsPassed: Whether tests have passed according - to the :param Strictness: criteria. - """ - Local.stdout.write(" \n\n--- Building project %s\n" % (ID,)) - - TBegin = time.time() - - Dir = getProjectDir(ID) - if Verbose == 1: - Local.stdout.write(" Build directory: %s.\n" % (Dir,)) - - # Set the build results directory. - RelOutputDir = getSBOutputDirName(IsReferenceBuild) - SBOutputDir = os.path.join(Dir, RelOutputDir) - - buildProject(Args, Dir, SBOutputDir, ProjectBuildMode, IsReferenceBuild) - - checkBuild(SBOutputDir) - - if IsReferenceBuild: - cleanupReferenceResults(SBOutputDir) - TestsPassed = True - else: - TestsPassed = runCmpResults(Dir, Strictness) - - Local.stdout.write("Completed tests for project %s (time: %.2f).\n" % ( - ID, (time.time() - TBegin))) - return TestsPassed - - -def projectFileHandler(): - return open(getProjectMapPath(), "rb") - - -def iterateOverProjects(PMapFile): - """ - Iterate over all projects defined in the project file handler `PMapFile` - from the start. - """ - PMapFile.seek(0) - for I in csv.reader(PMapFile): - if (SATestUtils.isCommentCSVLine(I)): - continue - yield I - - -def validateProjectFile(PMapFile): - """ - Validate project file. - """ - for I in iterateOverProjects(PMapFile): - if len(I) != 2: - print("Error: Rows in the ProjectMapFile should have 2 entries.") - raise Exception() - if I[1] not in ('0', '1', '2'): - print("Error: Second entry in the ProjectMapFile should be 0" \ - " (single file), 1 (project), or 2(single file c++11).") - raise Exception() - -def singleThreadedTestAll(Args, ProjectsToTest): - """ - Run all projects. - :return: whether tests have passed. - """ - Success = True - for ProjArgs in ProjectsToTest: - Success &= testProject(Args, *ProjArgs) - return Success - -def multiThreadedTestAll(Args, ProjectsToTest, Jobs): - """ - Run each project in a separate thread. - - This is OK despite GIL, as testing is blocked - on launching external processes. - - :return: whether tests have passed. - """ - TasksQueue = queue.Queue() - - for ProjArgs in ProjectsToTest: - TasksQueue.put(ProjArgs) - - ResultsDiffer = threading.Event() - FailureFlag = threading.Event() - - for i in range(Jobs): - T = TestProjectThread(Args, TasksQueue, ResultsDiffer, FailureFlag) - T.start() - - # Required to handle Ctrl-C gracefully. - while TasksQueue.unfinished_tasks: - time.sleep(0.1) # Seconds. - if FailureFlag.is_set(): - Local.stderr.write("Test runner crashed\n") - sys.exit(1) - return not ResultsDiffer.is_set() - - -def testAll(Args): - ProjectsToTest = [] - - with projectFileHandler() as PMapFile: - validateProjectFile(PMapFile) - - # Test the projects. - for (ProjName, ProjBuildMode) in iterateOverProjects(PMapFile): - ProjectsToTest.append((ProjName, - int(ProjBuildMode), - Args.regenerate, - Args.strictness)) - if Args.jobs <= 1: - return singleThreadedTestAll(Args, ProjectsToTest) - else: - return multiThreadedTestAll(Args, ProjectsToTest, Args.jobs) - - -if __name__ == '__main__': - # Parse command line arguments. - Parser = argparse.ArgumentParser( - description='Test the Clang Static Analyzer.') - Parser.add_argument('--strictness', dest='strictness', type=int, default=0, - help='0 to fail on runtime errors, 1 to fail when the \ - number of found bugs are different from the \ - reference, 2 to fail on any difference from the \ - reference. Default is 0.') - Parser.add_argument('-r', dest='regenerate', action='store_true', - default=False, help='Regenerate reference output.') - Parser.add_argument('-j', '--jobs', dest='jobs', type=int, - default=0, - help='Number of projects to test concurrently') - Parser.add_argument('--extra-analyzer-config', dest='extra_analyzer_config', - type=str, - default="", - help="Arguments passed to to -analyzer-config") - Args = Parser.parse_args() - - TestsPassed = testAll(Args) - if not TestsPassed: - print("ERROR: Tests failed.") - sys.exit(42) diff --git a/utils/analyzer/SATestUpdateDiffs.py b/utils/analyzer/SATestUpdateDiffs.py deleted file mode 100755 index ea3c08cc210c..000000000000 --- a/utils/analyzer/SATestUpdateDiffs.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python - -""" -Update reference results for static analyzer. -""" -from __future__ import absolute_import, division, print_function - -import SATestBuild - -from subprocess import check_call -import os -import sys - -Verbose = 0 - - -def runCmd(Command, **kwargs): - if Verbose: - print("Executing %s" % Command) - check_call(Command, shell=True, **kwargs) - - -def updateReferenceResults(ProjName, ProjBuildMode): - ProjDir = SATestBuild.getProjectDir(ProjName) - - RefResultsPath = os.path.join( - ProjDir, - SATestBuild.getSBOutputDirName(IsReferenceBuild=True)) - CreatedResultsPath = os.path.join( - ProjDir, - SATestBuild.getSBOutputDirName(IsReferenceBuild=False)) - - if not os.path.exists(CreatedResultsPath): - print("New results not found, was SATestBuild.py "\ - "previously run?", file=sys.stderr) - sys.exit(1) - - BuildLogPath = SATestBuild.getBuildLogPath(RefResultsPath) - Dirname = os.path.dirname(os.path.abspath(BuildLogPath)) - runCmd("mkdir -p '%s'" % Dirname) - with open(BuildLogPath, "wb+") as PBuildLogFile: - # Remove reference results: in git, and then again for a good measure - # with rm, as git might not remove things fully if there are empty - # directories involved. - runCmd('git rm -r -q "%s"' % (RefResultsPath,), stdout=PBuildLogFile) - runCmd('rm -rf "%s"' % (RefResultsPath,), stdout=PBuildLogFile) - - # Replace reference results with a freshly computed once. - runCmd('cp -r "%s" "%s"' % (CreatedResultsPath, RefResultsPath,), - stdout=PBuildLogFile) - - # Run cleanup script. - SATestBuild.runCleanupScript(ProjDir, PBuildLogFile) - - SATestBuild.normalizeReferenceResults( - ProjDir, RefResultsPath, ProjBuildMode) - - # Clean up the generated difference results. - SATestBuild.cleanupReferenceResults(RefResultsPath) - - runCmd('git add "%s"' % (RefResultsPath,), stdout=PBuildLogFile) - - -def main(argv): - if len(argv) == 2 and argv[1] in ('-h', '--help'): - print("Update static analyzer reference results based "\ - "\non the previous run of SATestBuild.py.\n"\ - "\nN.B.: Assumes that SATestBuild.py was just run", file=sys.stderr) - sys.exit(1) - - with SATestBuild.projectFileHandler() as f: - for (ProjName, ProjBuildMode) in SATestBuild.iterateOverProjects(f): - updateReferenceResults(ProjName, int(ProjBuildMode)) - - -if __name__ == '__main__': - main(sys.argv) diff --git a/utils/analyzer/SATestUtils.py b/utils/analyzer/SATestUtils.py deleted file mode 100644 index 2320652619ed..000000000000 --- a/utils/analyzer/SATestUtils.py +++ /dev/null @@ -1,89 +0,0 @@ -import os -from subprocess import check_output, check_call -import sys - - -Verbose = 1 - -def which(command, paths=None): - """which(command, [paths]) - Look up the given command in the paths string - (or the PATH environment variable, if unspecified).""" - - if paths is None: - paths = os.environ.get('PATH', '') - - # Check for absolute match first. - if os.path.exists(command): - return command - - # Would be nice if Python had a lib function for this. - if not paths: - paths = os.defpath - - # Get suffixes to search. - # On Cygwin, 'PATHEXT' may exist but it should not be used. - if os.pathsep == ';': - pathext = os.environ.get('PATHEXT', '').split(';') - else: - pathext = [''] - - # Search the paths... - for path in paths.split(os.pathsep): - for ext in pathext: - p = os.path.join(path, command + ext) - if os.path.exists(p): - return p - - return None - - -def hasNoExtension(FileName): - (Root, Ext) = os.path.splitext(FileName) - return (Ext == "") - - -def isValidSingleInputFile(FileName): - (Root, Ext) = os.path.splitext(FileName) - return Ext in (".i", ".ii", ".c", ".cpp", ".m", "") - - -def getSDKPath(SDKName): - """ - Get the path to the SDK for the given SDK name. Returns None if - the path cannot be determined. - """ - if which("xcrun") is None: - return None - - Cmd = "xcrun --sdk " + SDKName + " --show-sdk-path" - return check_output(Cmd, shell=True).rstrip() - - -def runScript(ScriptPath, PBuildLogFile, Cwd, Stdout=sys.stdout, - Stderr=sys.stderr): - """ - Run the provided script if it exists. - """ - if os.path.exists(ScriptPath): - try: - if Verbose == 1: - Stdout.write(" Executing: %s\n" % (ScriptPath,)) - check_call("chmod +x '%s'" % ScriptPath, cwd=Cwd, - stderr=PBuildLogFile, - stdout=PBuildLogFile, - shell=True) - check_call("'%s'" % ScriptPath, cwd=Cwd, - stderr=PBuildLogFile, - stdout=PBuildLogFile, - shell=True) - except: - Stderr.write("Error: Running %s failed. See %s for details.\n" % ( - ScriptPath, PBuildLogFile.name)) - sys.exit(-1) - - -def isCommentCSVLine(Entries): - """ - Treat CSV lines starting with a '#' as a comment. - """ - return len(Entries) > 0 and Entries[0].startswith("#") diff --git a/utils/analyzer/SumTimerInfo.py b/utils/analyzer/SumTimerInfo.py deleted file mode 100644 index 36e519adbf71..000000000000 --- a/utils/analyzer/SumTimerInfo.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python - -""" -Script to Summarize statistics in the scan-build output. - -Statistics are enabled by passing '-internal-stats' option to scan-build -(or '-analyzer-stats' to the analyzer). -""" -from __future__ import absolute_import, division, print_function - -import sys - -if __name__ == '__main__': - if len(sys.argv) < 2: - print('Usage: ', sys.argv[0],\ - 'scan_build_output_file', file=sys.stderr) - sys.exit(-1) - - f = open(sys.argv[1], 'r') - Time = 0.0 - TotalTime = 0.0 - MaxTime = 0.0 - Warnings = 0 - Count = 0 - FunctionsAnalyzed = 0 - ReachableBlocks = 0 - ReachedMaxSteps = 0 - NumSteps = 0 - NumInlinedCallSites = 0 - NumBifurcatedCallSites = 0 - MaxCFGSize = 0 - for line in f: - if ("Analyzer Total Time" in line): - s = line.split() - Time = Time + float(s[6]) - Count = Count + 1 - if (float(s[6]) > MaxTime): - MaxTime = float(s[6]) - if ("warning generated." in line) or ("warnings generated" in line): - s = line.split() - Warnings = Warnings + int(s[0]) - if "The # of functions analysed (as top level)" in line: - s = line.split() - FunctionsAnalyzed = FunctionsAnalyzed + int(s[0]) - if "The % of reachable basic blocks" in line: - s = line.split() - ReachableBlocks = ReachableBlocks + int(s[0]) - if "The # of times we reached the max number of steps" in line: - s = line.split() - ReachedMaxSteps = ReachedMaxSteps + int(s[0]) - if "The maximum number of basic blocks in a function" in line: - s = line.split() - if MaxCFGSize < int(s[0]): - MaxCFGSize = int(s[0]) - if "The # of steps executed" in line: - s = line.split() - NumSteps = NumSteps + int(s[0]) - if "The # of times we inlined a call" in line: - s = line.split() - NumInlinedCallSites = NumInlinedCallSites + int(s[0]) - if "The # of times we split the path due \ - to imprecise dynamic dispatch info" in line: - s = line.split() - NumBifurcatedCallSites = NumBifurcatedCallSites + int(s[0]) - if ") Total" in line: - s = line.split() - TotalTime = TotalTime + float(s[6]) - - print("TU Count %d" % (Count)) - print("Time %f" % (Time)) - print("Warnings %d" % (Warnings)) - print("Functions Analyzed %d" % (FunctionsAnalyzed)) - print("Reachable Blocks %d" % (ReachableBlocks)) - print("Reached Max Steps %d" % (ReachedMaxSteps)) - print("Number of Steps %d" % (NumSteps)) - print("Number of Inlined calls %d (bifurcated %d)" % ( - NumInlinedCallSites, NumBifurcatedCallSites)) - print("MaxTime %f" % (MaxTime)) - print("TotalTime %f" % (TotalTime)) - print("Max CFG Size %d" % (MaxCFGSize)) diff --git a/utils/analyzer/reducer.pl b/utils/analyzer/reducer.pl deleted file mode 100755 index 872f61b33a77..000000000000 --- a/utils/analyzer/reducer.pl +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/perl -w -use strict; -use File::Temp qw/ tempdir /; -my $prog = "reducer"; - -die "$prog <code file> <error string> [optional command]\n" if ($#ARGV < 0); -my $file = shift @ARGV; -die "$prog: [error] cannot read file $file\n" if (! -r $file); - -my $magic = shift @ARGV; -die "$prog: [error] no error string specified\n" if (! defined $magic); - -# Create a backup of the file. -my $dir = tempdir( CLEANUP => 1 ); -print "$prog: created temporary directory '$dir'\n"; -my $srcFile = "$dir/$file"; -`cp $file $srcFile`; - -# Create the script. -my $scriptFile = "$dir/script"; -open(OUT, ">$scriptFile") or die "$prog: cannot create '$scriptFile'\n"; -my $reduceOut = "$dir/reduceOut"; - -my $command; -if (scalar(@ARGV) > 0) { $command = \@ARGV; } -else { - my $compiler = "clang"; - $command = [$compiler, "-fsyntax-only", "-Wfatal-errors", "-Wno-deprecated-declarations", "-Wimplicit-function-declaration"]; -} -push @$command, $srcFile; -my $commandStr = "@$command"; - -print OUT <<ENDTEXT; -#!/usr/bin/perl -w -use strict; -my \$BAD = 1; -my \$GOOD = 0; -`rm -f $reduceOut`; -my \$command = "$commandStr > $reduceOut 2>&1"; -system(\$command); -open(IN, "$reduceOut") or exit(\$BAD); -my \$found = 0; -while(<IN>) { - if (/$magic/) { exit \$GOOD; } -} -exit \$BAD; -ENDTEXT -close(OUT); -`chmod +x $scriptFile`; - -print "$prog: starting reduction\n"; -sub multidelta($) { - my ($level) = @_; - system("multidelta -level=$level $scriptFile $srcFile"); -} - -for (my $i = 1 ; $i <= 5; $i++) { - foreach my $level (0,0,1,1,2,2,10) { - multidelta($level); - } -} - -# Copy the final file. -`cp $srcFile $file.reduced`; -print "$prog: generated '$file.reduced"; diff --git a/utils/analyzer/update_plist_test.pl b/utils/analyzer/update_plist_test.pl deleted file mode 100755 index abb74a57c3c1..000000000000 --- a/utils/analyzer/update_plist_test.pl +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/perl -w -use strict; -require File::Temp; -use File::Temp (); - -die "update_plist_test <test file> <plist file>\n" if ($#ARGV < 1); -my $testFile = shift @ARGV; -die "error: cannot read file $testFile\n" if (! -r $testFile); -my $plistFile = shift @ARGV; -die "error: cannot read file $plistFile\n" if (! -r $plistFile); - -# Create a temp file for the new test. -my $fh = File::Temp->new(); -my $filename = $fh->filename; -$fh->unlink_on_destroy(1); - -# Copy the existing temp file, skipping the FileCheck comments. -open (IN, $testFile) or die "cannot open $testFile\n"; -while (<IN>) { - next if (/^\/\/ CHECK/); - print $fh $_; -} -close(IN); - -# Copy the plist data, and specially format it. -open (IN, $plistFile) or die "cannot open $plistFile\n"; -my $firstArray = 1; -my $first = 1; -while (<IN>) { - # Skip everything not indented. - next if (/^[^\s]/); - # Skip the first array entry, which is for files. - if ($firstArray) { - if (/<\/array>/) { $firstArray = 0; } - next; - } - # Format the CHECK lines. - if ($first) { - print $fh "// CHECK: "; - $first = 0; - } - else { - print $fh "// CHECK-NEXT: "; - } - print $fh $_; -} -close (IN); -close ($fh); - -`cp $filename $testFile`; -print "updated $testFile\n"; diff --git a/utils/bash-autocomplete.sh b/utils/bash-autocomplete.sh deleted file mode 100755 index bcda789b1c07..000000000000 --- a/utils/bash-autocomplete.sh +++ /dev/null @@ -1,65 +0,0 @@ -# Please add "source /path/to/bash-autocomplete.sh" to your .bashrc to use this. - -_clang_filedir() -{ - # _filedir function provided by recent versions of bash-completion package is - # better than "compgen -f" because the former honors spaces in pathnames while - # the latter doesn't. So we use compgen only when _filedir is not provided. - _filedir 2> /dev/null || COMPREPLY=( $( compgen -f ) ) -} - -_clang() -{ - local cur prev words cword arg flags w1 w2 - # If latest bash-completion is not supported just initialize COMPREPLY and - # initialize variables by setting manually. - _init_completion -n 2> /dev/null - if [[ "$?" != 0 ]]; then - COMPREPLY=() - cword=$COMP_CWORD - cur="${COMP_WORDS[$cword]}" - fi - - w1="${COMP_WORDS[$cword - 1]}" - if [[ $cword > 1 ]]; then - w2="${COMP_WORDS[$cword - 2]}" - fi - - # Pass all the current command-line flags to clang, so that clang can handle - # these internally. - # '=' is separated differently by bash, so we have to concat them without ',' - for i in `seq 1 $cword`; do - if [[ $i == $cword || "${COMP_WORDS[$(($i+1))]}" == '=' ]]; then - arg="$arg${COMP_WORDS[$i]}" - else - arg="$arg${COMP_WORDS[$i]}," - fi - done - - # expand ~ to $HOME - eval local path=${COMP_WORDS[0]} - # Use $'\t' so that bash expands the \t for older versions of sed. - flags=$( "$path" --autocomplete="$arg" 2>/dev/null | sed -e $'s/\t.*//' ) - # If clang is old that it does not support --autocomplete, - # fall back to the filename completion. - if [[ "$?" != 0 ]]; then - _clang_filedir - return - fi - - # When clang does not emit any possible autocompletion, or user pushed tab after " ", - # just autocomplete files. - if [[ "$flags" == "$(echo -e '\n')" ]]; then - # If -foo=<tab> and there was no possible values, autocomplete files. - [[ "$cur" == '=' || "$cur" == -*= ]] && cur="" - _clang_filedir - elif [[ "$cur" == '=' ]]; then - COMPREPLY=( $( compgen -W "$flags" -- "") ) - else - # Bash automatically appends a space after '=' by default. - # Disable it so that it works nicely for options in the form of -foo=bar. - [[ "${flags: -1}" == '=' ]] && compopt -o nospace 2> /dev/null - COMPREPLY=( $( compgen -W "$flags" -- "$cur" ) ) - fi -} -complete -F _clang clang diff --git a/utils/builtin-defines.c b/utils/builtin-defines.c deleted file mode 100644 index 9bbe5be25026..000000000000 --- a/utils/builtin-defines.c +++ /dev/null @@ -1,85 +0,0 @@ -/* -This is a clang style test case for checking that preprocessor -defines match gcc. -*/ - -/* -RUN: for arch in -m32 -m64; do \ -RUN: for lang in -std=gnu89 -ansi -std=c99 -std=gnu99; do \ -RUN: for input in c objective-c; do \ -RUN: for opts in "-O0" "-O1 -dynamic" "-O2 -static" "-Os"; do \ -RUN: echo "-- $arch, $lang, $input, $opts --"; \ -RUN: for cc in 0 1; do \ -RUN: if [ "$cc" == 0 ]; then \ -RUN: cc_prog=clang; \ -RUN: output=%t0; \ -RUN: else \ -RUN: cc_prog=gcc; \ -RUN: output=%t1; \ -RUN: fi; \ -RUN: $cc_prog $arch $lang $opts -march=core2 -dM -E -x $input %s | sort > $output; \ -RUN: done; \ -RUN: if (! diff %t0 %t1); then exit 1; fi; \ -RUN: done; \ -RUN: done; \ -RUN: done; \ -RUN: done; -*/ - -/* We don't care about this difference */ -#ifdef __PIC__ -#if __PIC__ == 1 -#undef __PIC__ -#undef __pic__ -#define __PIC__ 2 -#define __pic__ 2 -#endif -#endif - -/* Undefine things we don't expect to match. */ -#undef __core2 -#undef __core2__ -#undef __SSSE3__ - -/* Undefine things we don't expect to match. */ -#undef __DEC_EVAL_METHOD__ -#undef __INT16_TYPE__ -#undef __INT32_TYPE__ -#undef __INT64_TYPE__ -#undef __INT8_TYPE__ -#undef __SSP__ -#undef __APPLE_CC__ -#undef __VERSION__ -#undef __clang__ -#undef __llvm__ -#undef __nocona -#undef __nocona__ -#undef __k8 -#undef __k8__ -#undef __tune_nocona__ -#undef __tune_core2__ -#undef __POINTER_WIDTH__ -#undef __INTPTR_TYPE__ -#undef __NO_MATH_INLINES - -#undef __DEC128_DEN__ -#undef __DEC128_EPSILON__ -#undef __DEC128_MANT_DIG__ -#undef __DEC128_MAX_EXP__ -#undef __DEC128_MAX__ -#undef __DEC128_MIN_EXP__ -#undef __DEC128_MIN__ -#undef __DEC32_DEN__ -#undef __DEC32_EPSILON__ -#undef __DEC32_MANT_DIG__ -#undef __DEC32_MAX_EXP__ -#undef __DEC32_MAX__ -#undef __DEC32_MIN_EXP__ -#undef __DEC32_MIN__ -#undef __DEC64_DEN__ -#undef __DEC64_EPSILON__ -#undef __DEC64_MANT_DIG__ -#undef __DEC64_MAX_EXP__ -#undef __DEC64_MAX__ -#undef __DEC64_MIN_EXP__ -#undef __DEC64_MIN__ diff --git a/utils/check_cfc/check_cfc.cfg b/utils/check_cfc/check_cfc.cfg deleted file mode 100644 index 967623e71339..000000000000 --- a/utils/check_cfc/check_cfc.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[Checks] -dash_g_no_change = true -dash_s_no_change = true diff --git a/utils/check_cfc/check_cfc.py b/utils/check_cfc/check_cfc.py deleted file mode 100755 index 311f502f800b..000000000000 --- a/utils/check_cfc/check_cfc.py +++ /dev/null @@ -1,405 +0,0 @@ -#!/usr/bin/env python - -"""Check CFC - Check Compile Flow Consistency - -This is a compiler wrapper for testing that code generation is consistent with -different compilation processes. It checks that code is not unduly affected by -compiler options or other changes which should not have side effects. - -To use: --Ensure that the compiler under test (i.e. clang, clang++) is on the PATH --On Linux copy this script to the name of the compiler - e.g. cp check_cfc.py clang && cp check_cfc.py clang++ --On Windows use setup.py to generate check_cfc.exe and copy that to clang.exe - and clang++.exe --Enable the desired checks in check_cfc.cfg (in the same directory as the - wrapper) - e.g. -[Checks] -dash_g_no_change = true -dash_s_no_change = false - --The wrapper can be run using its absolute path or added to PATH before the - compiler under test - e.g. export PATH=<path to check_cfc>:$PATH --Compile as normal. The wrapper intercepts normal -c compiles and will return - non-zero if the check fails. - e.g. -$ clang -c test.cpp -Code difference detected with -g ---- /tmp/tmp5nv893.o -+++ /tmp/tmp6Vwjnc.o -@@ -1 +1 @@ -- 0: 48 8b 05 51 0b 20 00 mov 0x200b51(%rip),%rax -+ 0: 48 39 3d 51 0b 20 00 cmp %rdi,0x200b51(%rip) - --To run LNT with Check CFC specify the absolute path to the wrapper to the --cc - and --cxx options - e.g. - lnt runtest nt --cc <path to check_cfc>/clang \\ - --cxx <path to check_cfc>/clang++ ... - -To add a new check: --Create a new subclass of WrapperCheck --Implement the perform_check() method. This should perform the alternate compile - and do the comparison. --Add the new check to check_cfc.cfg. The check has the same name as the - subclass. -""" - -from __future__ import absolute_import, division, print_function - -import imp -import os -import platform -import shutil -import subprocess -import sys -import tempfile -try: - import configparser -except ImportError: - import ConfigParser as configparser -import io - -import obj_diff - -def is_windows(): - """Returns True if running on Windows.""" - return platform.system() == 'Windows' - -class WrapperStepException(Exception): - """Exception type to be used when a step other than the original compile - fails.""" - def __init__(self, msg, stdout, stderr): - self.msg = msg - self.stdout = stdout - self.stderr = stderr - -class WrapperCheckException(Exception): - """Exception type to be used when a comparison check fails.""" - def __init__(self, msg): - self.msg = msg - -def main_is_frozen(): - """Returns True when running as a py2exe executable.""" - return (hasattr(sys, "frozen") or # new py2exe - hasattr(sys, "importers") or # old py2exe - imp.is_frozen("__main__")) # tools/freeze - -def get_main_dir(): - """Get the directory that the script or executable is located in.""" - if main_is_frozen(): - return os.path.dirname(sys.executable) - return os.path.dirname(sys.argv[0]) - -def remove_dir_from_path(path_var, directory): - """Remove the specified directory from path_var, a string representing - PATH""" - pathlist = path_var.split(os.pathsep) - norm_directory = os.path.normpath(os.path.normcase(directory)) - pathlist = [x for x in pathlist if os.path.normpath( - os.path.normcase(x)) != norm_directory] - return os.pathsep.join(pathlist) - -def path_without_wrapper(): - """Returns the PATH variable modified to remove the path to this program.""" - scriptdir = get_main_dir() - path = os.environ['PATH'] - return remove_dir_from_path(path, scriptdir) - -def flip_dash_g(args): - """Search for -g in args. If it exists then return args without. If not then - add it.""" - if '-g' in args: - # Return args without any -g - return [x for x in args if x != '-g'] - else: - # No -g, add one - return args + ['-g'] - -def derive_output_file(args): - """Derive output file from the input file (if just one) or None - otherwise.""" - infile = get_input_file(args) - if infile is None: - return None - else: - return '{}.o'.format(os.path.splitext(infile)[0]) - -def get_output_file(args): - """Return the output file specified by this command or None if not - specified.""" - grabnext = False - for arg in args: - if grabnext: - return arg - if arg == '-o': - # Specified as a separate arg - grabnext = True - elif arg.startswith('-o'): - # Specified conjoined with -o - return arg[2:] - assert grabnext == False - - return None - -def is_output_specified(args): - """Return true is output file is specified in args.""" - return get_output_file(args) is not None - -def replace_output_file(args, new_name): - """Replaces the specified name of an output file with the specified name. - Assumes that the output file name is specified in the command line args.""" - replaceidx = None - attached = False - for idx, val in enumerate(args): - if val == '-o': - replaceidx = idx + 1 - attached = False - elif val.startswith('-o'): - replaceidx = idx - attached = True - - if replaceidx is None: - raise Exception - replacement = new_name - if attached == True: - replacement = '-o' + new_name - args[replaceidx] = replacement - return args - -def add_output_file(args, output_file): - """Append an output file to args, presuming not already specified.""" - return args + ['-o', output_file] - -def set_output_file(args, output_file): - """Set the output file within the arguments. Appends or replaces as - appropriate.""" - if is_output_specified(args): - args = replace_output_file(args, output_file) - else: - args = add_output_file(args, output_file) - return args - -gSrcFileSuffixes = ('.c', '.cpp', '.cxx', '.c++', '.cp', '.cc') - -def get_input_file(args): - """Return the input file string if it can be found (and there is only - one).""" - inputFiles = list() - for arg in args: - testarg = arg - quotes = ('"', "'") - while testarg.endswith(quotes): - testarg = testarg[:-1] - testarg = os.path.normcase(testarg) - - # Test if it is a source file - if testarg.endswith(gSrcFileSuffixes): - inputFiles.append(arg) - if len(inputFiles) == 1: - return inputFiles[0] - else: - return None - -def set_input_file(args, input_file): - """Replaces the input file with that specified.""" - infile = get_input_file(args) - if infile: - infile_idx = args.index(infile) - args[infile_idx] = input_file - return args - else: - # Could not find input file - assert False - -def is_normal_compile(args): - """Check if this is a normal compile which will output an object file rather - than a preprocess or link. args is a list of command line arguments.""" - compile_step = '-c' in args - # Bitcode cannot be disassembled in the same way - bitcode = '-flto' in args or '-emit-llvm' in args - # Version and help are queries of the compiler and override -c if specified - query = '--version' in args or '--help' in args - # Options to output dependency files for make - dependency = '-M' in args or '-MM' in args - # Check if the input is recognised as a source file (this may be too - # strong a restriction) - input_is_valid = bool(get_input_file(args)) - return compile_step and not bitcode and not query and not dependency and input_is_valid - -def run_step(command, my_env, error_on_failure): - """Runs a step of the compilation. Reports failure as exception.""" - # Need to use shell=True on Windows as Popen won't use PATH otherwise. - p = subprocess.Popen(command, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, env=my_env, shell=is_windows()) - (stdout, stderr) = p.communicate() - if p.returncode != 0: - raise WrapperStepException(error_on_failure, stdout, stderr) - -def get_temp_file_name(suffix): - """Get a temporary file name with a particular suffix. Let the caller be - responsible for deleting it.""" - tf = tempfile.NamedTemporaryFile(suffix=suffix, delete=False) - tf.close() - return tf.name - -class WrapperCheck(object): - """Base class for a check. Subclass this to add a check.""" - def __init__(self, output_file_a): - """Record the base output file that will be compared against.""" - self._output_file_a = output_file_a - - def perform_check(self, arguments, my_env): - """Override this to perform the modified compilation and required - checks.""" - raise NotImplementedError("Please Implement this method") - -class dash_g_no_change(WrapperCheck): - def perform_check(self, arguments, my_env): - """Check if different code is generated with/without the -g flag.""" - output_file_b = get_temp_file_name('.o') - - alternate_command = list(arguments) - alternate_command = flip_dash_g(alternate_command) - alternate_command = set_output_file(alternate_command, output_file_b) - run_step(alternate_command, my_env, "Error compiling with -g") - - # Compare disassembly (returns first diff if differs) - difference = obj_diff.compare_object_files(self._output_file_a, - output_file_b) - if difference: - raise WrapperCheckException( - "Code difference detected with -g\n{}".format(difference)) - - # Clean up temp file if comparison okay - os.remove(output_file_b) - -class dash_s_no_change(WrapperCheck): - def perform_check(self, arguments, my_env): - """Check if compiling to asm then assembling in separate steps results - in different code than compiling to object directly.""" - output_file_b = get_temp_file_name('.o') - - alternate_command = arguments + ['-via-file-asm'] - alternate_command = set_output_file(alternate_command, output_file_b) - run_step(alternate_command, my_env, - "Error compiling with -via-file-asm") - - # Compare if object files are exactly the same - exactly_equal = obj_diff.compare_exact(self._output_file_a, output_file_b) - if not exactly_equal: - # Compare disassembly (returns first diff if differs) - difference = obj_diff.compare_object_files(self._output_file_a, - output_file_b) - if difference: - raise WrapperCheckException( - "Code difference detected with -S\n{}".format(difference)) - - # Code is identical, compare debug info - dbgdifference = obj_diff.compare_debug_info(self._output_file_a, - output_file_b) - if dbgdifference: - raise WrapperCheckException( - "Debug info difference detected with -S\n{}".format(dbgdifference)) - - raise WrapperCheckException("Object files not identical with -S\n") - - # Clean up temp file if comparison okay - os.remove(output_file_b) - -if __name__ == '__main__': - # Create configuration defaults from list of checks - default_config = """ -[Checks] -""" - - # Find all subclasses of WrapperCheck - checks = [cls.__name__ for cls in vars()['WrapperCheck'].__subclasses__()] - - for c in checks: - default_config += "{} = false\n".format(c) - - config = configparser.RawConfigParser() - config.readfp(io.BytesIO(default_config)) - scriptdir = get_main_dir() - config_path = os.path.join(scriptdir, 'check_cfc.cfg') - try: - config.read(os.path.join(config_path)) - except: - print("Could not read config from {}, " - "using defaults.".format(config_path)) - - my_env = os.environ.copy() - my_env['PATH'] = path_without_wrapper() - - arguments_a = list(sys.argv) - - # Prevent infinite loop if called with absolute path. - arguments_a[0] = os.path.basename(arguments_a[0]) - - # Sanity check - enabled_checks = [check_name - for check_name in checks - if config.getboolean('Checks', check_name)] - checks_comma_separated = ', '.join(enabled_checks) - print("Check CFC, checking: {}".format(checks_comma_separated)) - - # A - original compilation - output_file_orig = get_output_file(arguments_a) - if output_file_orig is None: - output_file_orig = derive_output_file(arguments_a) - - p = subprocess.Popen(arguments_a, env=my_env, shell=is_windows()) - p.communicate() - if p.returncode != 0: - sys.exit(p.returncode) - - if not is_normal_compile(arguments_a) or output_file_orig is None: - # Bail out here if we can't apply checks in this case. - # Does not indicate an error. - # Maybe not straight compilation (e.g. -S or --version or -flto) - # or maybe > 1 input files. - sys.exit(0) - - # Sometimes we generate files which have very long names which can't be - # read/disassembled. This will exit early if we can't find the file we - # expected to be output. - if not os.path.isfile(output_file_orig): - sys.exit(0) - - # Copy output file to a temp file - temp_output_file_orig = get_temp_file_name('.o') - shutil.copyfile(output_file_orig, temp_output_file_orig) - - # Run checks, if they are enabled in config and if they are appropriate for - # this command line. - current_module = sys.modules[__name__] - for check_name in checks: - if config.getboolean('Checks', check_name): - class_ = getattr(current_module, check_name) - checker = class_(temp_output_file_orig) - try: - checker.perform_check(arguments_a, my_env) - except WrapperCheckException as e: - # Check failure - print("{} {}".format(get_input_file(arguments_a), e.msg), file=sys.stderr) - - # Remove file to comply with build system expectations (no - # output file if failed) - os.remove(output_file_orig) - sys.exit(1) - - except WrapperStepException as e: - # Compile step failure - print(e.msg, file=sys.stderr) - print("*** stdout ***", file=sys.stderr) - print(e.stdout, file=sys.stderr) - print("*** stderr ***", file=sys.stderr) - print(e.stderr, file=sys.stderr) - - # Remove file to comply with build system expectations (no - # output file if failed) - os.remove(output_file_orig) - sys.exit(1) diff --git a/utils/check_cfc/obj_diff.py b/utils/check_cfc/obj_diff.py deleted file mode 100755 index a0951c5bcdee..000000000000 --- a/utils/check_cfc/obj_diff.py +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env python - -from __future__ import absolute_import, division, print_function - -import argparse -import difflib -import filecmp -import os -import subprocess -import sys - -disassembler = 'objdump' - -def keep_line(line): - """Returns true for lines that should be compared in the disassembly - output.""" - return "file format" not in line - -def disassemble(objfile): - """Disassemble object to a file.""" - p = subprocess.Popen([disassembler, '-d', objfile], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - (out, err) = p.communicate() - if p.returncode or err: - print("Disassemble failed: {}".format(objfile)) - sys.exit(1) - return [line for line in out.split(os.linesep) if keep_line(line)] - -def dump_debug(objfile): - """Dump all of the debug info from a file.""" - p = subprocess.Popen([disassembler, '-WliaprmfsoRt', objfile], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - (out, err) = p.communicate() - if p.returncode or err: - print("Dump debug failed: {}".format(objfile)) - sys.exit(1) - return [line for line in out.split(os.linesep) if keep_line(line)] - -def first_diff(a, b, fromfile, tofile): - """Returns the first few lines of a difference, if there is one. Python - diff can be very slow with large objects and the most interesting changes - are the first ones. Truncate data before sending to difflib. Returns None - is there is no difference.""" - - # Find first diff - first_diff_idx = None - for idx, val in enumerate(a): - if val != b[idx]: - first_diff_idx = idx - break - - if first_diff_idx == None: - # No difference - return None - - # Diff to first line of diff plus some lines - context = 3 - diff = difflib.unified_diff(a[:first_diff_idx+context], - b[:first_diff_idx+context], - fromfile, - tofile) - difference = "\n".join(diff) - if first_diff_idx + context < len(a): - difference += "\n*** Diff truncated ***" - return difference - -def compare_object_files(objfilea, objfileb): - """Compare disassembly of two different files. - Allowing unavoidable differences, such as filenames. - Return the first difference if the disassembly differs, or None. - """ - disa = disassemble(objfilea) - disb = disassemble(objfileb) - return first_diff(disa, disb, objfilea, objfileb) - -def compare_debug_info(objfilea, objfileb): - """Compare debug info of two different files. - Allowing unavoidable differences, such as filenames. - Return the first difference if the debug info differs, or None. - If there are differences in the code, there will almost certainly be differences in the debug info too. - """ - dbga = dump_debug(objfilea) - dbgb = dump_debug(objfileb) - return first_diff(dbga, dbgb, objfilea, objfileb) - -def compare_exact(objfilea, objfileb): - """Byte for byte comparison between object files. - Returns True if equal, False otherwise. - """ - return filecmp.cmp(objfilea, objfileb) - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('objfilea', nargs=1) - parser.add_argument('objfileb', nargs=1) - parser.add_argument('-v', '--verbose', action='store_true') - args = parser.parse_args() - diff = compare_object_files(args.objfilea[0], args.objfileb[0]) - if diff: - print("Difference detected") - if args.verbose: - print(diff) - sys.exit(1) - else: - print("The same") diff --git a/utils/check_cfc/setup.py b/utils/check_cfc/setup.py deleted file mode 100644 index 64f07d5dcc52..000000000000 --- a/utils/check_cfc/setup.py +++ /dev/null @@ -1,22 +0,0 @@ -"""For use on Windows. Run with: - python.exe setup.py py2exe - """ -from __future__ import absolute_import, division, print_function -from distutils.core import setup -try: - import py2exe -except ImportError: - import platform - import sys - if platform.system() == 'Windows': - print("Could not find py2exe. Please install then run setup.py py2exe.") - raise - else: - print("setup.py only required on Windows.") - sys.exit(1) - -setup( - console=['check_cfc.py'], - name="Check CFC", - description='Check Compile Flow Consistency' - ) diff --git a/utils/check_cfc/test_check_cfc.py b/utils/check_cfc/test_check_cfc.py deleted file mode 100755 index 0808252a2c60..000000000000 --- a/utils/check_cfc/test_check_cfc.py +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env python - -"""Test internal functions within check_cfc.py.""" - -import check_cfc -import os -import platform -import unittest - - -class TestCheckCFC(unittest.TestCase): - - def test_flip_dash_g(self): - self.assertIn('-g', check_cfc.flip_dash_g(['clang', '-c'])) - self.assertNotIn('-g', check_cfc.flip_dash_g(['clang', '-c', '-g'])) - self.assertNotIn( - '-g', check_cfc.flip_dash_g(['clang', '-g', '-c', '-g'])) - - def test_remove_dir_from_path(self): - bin_path = r'/usr/bin' - space_path = r'/home/user/space in path' - superstring_path = r'/usr/bin/local' - - # Test removing last thing in path - self.assertNotIn( - bin_path, check_cfc.remove_dir_from_path(bin_path, bin_path)) - - # Test removing one entry and leaving others - # Also tests removing repeated path - path_var = os.pathsep.join( - [superstring_path, bin_path, space_path, bin_path]) - stripped_path_var = check_cfc.remove_dir_from_path(path_var, bin_path) - self.assertIn(superstring_path, stripped_path_var) - self.assertNotIn(bin_path, stripped_path_var.split(os.pathsep)) - self.assertIn(space_path, stripped_path_var) - - # Test removing non-canonical path - self.assertNotIn(r'/usr//bin', - check_cfc.remove_dir_from_path(r'/usr//bin', bin_path)) - - if platform == 'Windows': - # Windows is case insensitive so should remove a different case - # path - self.assertNotIn( - bin_path, check_cfc.remove_dir_from_path(path_var, r'/USR/BIN')) - else: - # Case sensitive so will not remove different case path - self.assertIn( - bin_path, check_cfc.remove_dir_from_path(path_var, r'/USR/BIN')) - - def test_is_output_specified(self): - self.assertTrue( - check_cfc.is_output_specified(['clang', '-o', 'test.o'])) - self.assertTrue(check_cfc.is_output_specified(['clang', '-otest.o'])) - self.assertFalse( - check_cfc.is_output_specified(['clang', '-gline-tables-only'])) - # Not specified for implied output file name - self.assertFalse(check_cfc.is_output_specified(['clang', 'test.c'])) - - def test_get_output_file(self): - self.assertEqual( - check_cfc.get_output_file(['clang', '-o', 'test.o']), 'test.o') - self.assertEqual( - check_cfc.get_output_file(['clang', '-otest.o']), 'test.o') - self.assertIsNone( - check_cfc.get_output_file(['clang', '-gline-tables-only'])) - # Can't get output file if more than one input file - self.assertIsNone( - check_cfc.get_output_file(['clang', '-c', 'test.cpp', 'test2.cpp'])) - # No output file specified - self.assertIsNone(check_cfc.get_output_file(['clang', '-c', 'test.c'])) - - def test_derive_output_file(self): - # Test getting implicit output file - self.assertEqual( - check_cfc.derive_output_file(['clang', '-c', 'test.c']), 'test.o') - self.assertEqual( - check_cfc.derive_output_file(['clang', '-c', 'test.cpp']), 'test.o') - self.assertIsNone(check_cfc.derive_output_file(['clang', '--version'])) - - def test_is_normal_compile(self): - self.assertTrue(check_cfc.is_normal_compile( - ['clang', '-c', 'test.cpp', '-o', 'test2.o'])) - self.assertTrue( - check_cfc.is_normal_compile(['clang', '-c', 'test.cpp'])) - # Outputting bitcode is not a normal compile - self.assertFalse( - check_cfc.is_normal_compile(['clang', '-c', 'test.cpp', '-flto'])) - self.assertFalse( - check_cfc.is_normal_compile(['clang', '-c', 'test.cpp', '-emit-llvm'])) - # Outputting preprocessed output or assembly is not a normal compile - self.assertFalse( - check_cfc.is_normal_compile(['clang', '-E', 'test.cpp', '-o', 'test.ii'])) - self.assertFalse( - check_cfc.is_normal_compile(['clang', '-S', 'test.cpp', '-o', 'test.s'])) - # Input of preprocessed or assembly is not a "normal compile" - self.assertFalse( - check_cfc.is_normal_compile(['clang', '-c', 'test.s', '-o', 'test.o'])) - self.assertFalse( - check_cfc.is_normal_compile(['clang', '-c', 'test.ii', '-o', 'test.o'])) - # Specifying --version and -c is not a normal compile - self.assertFalse( - check_cfc.is_normal_compile(['clang', '-c', 'test.cpp', '--version'])) - self.assertFalse( - check_cfc.is_normal_compile(['clang', '-c', 'test.cpp', '--help'])) - # Outputting dependency files is not a normal compile - self.assertFalse( - check_cfc.is_normal_compile(['clang', '-c', '-M', 'test.cpp'])) - self.assertFalse( - check_cfc.is_normal_compile(['clang', '-c', '-MM', 'test.cpp'])) - # Creating a dependency file as a side effect still outputs an object file - self.assertTrue( - check_cfc.is_normal_compile(['clang', '-c', '-MD', 'test.cpp'])) - self.assertTrue( - check_cfc.is_normal_compile(['clang', '-c', '-MMD', 'test.cpp'])) - - def test_replace_output_file(self): - self.assertEqual(check_cfc.replace_output_file( - ['clang', '-o', 'test.o'], 'testg.o'), ['clang', '-o', 'testg.o']) - self.assertEqual(check_cfc.replace_output_file( - ['clang', '-otest.o'], 'testg.o'), ['clang', '-otestg.o']) - with self.assertRaises(Exception): - check_cfc.replace_output_file(['clang'], 'testg.o') - - def test_add_output_file(self): - self.assertEqual(check_cfc.add_output_file( - ['clang'], 'testg.o'), ['clang', '-o', 'testg.o']) - - def test_set_output_file(self): - # Test output not specified - self.assertEqual( - check_cfc.set_output_file(['clang'], 'test.o'), ['clang', '-o', 'test.o']) - # Test output is specified - self.assertEqual(check_cfc.set_output_file( - ['clang', '-o', 'test.o'], 'testb.o'), ['clang', '-o', 'testb.o']) - - def test_get_input_file(self): - # No input file - self.assertIsNone(check_cfc.get_input_file(['clang'])) - # Input C file - self.assertEqual( - check_cfc.get_input_file(['clang', 'test.c']), 'test.c') - # Input C++ file - self.assertEqual( - check_cfc.get_input_file(['clang', 'test.cpp']), 'test.cpp') - # Multiple input files - self.assertIsNone( - check_cfc.get_input_file(['clang', 'test.c', 'test2.cpp'])) - self.assertIsNone( - check_cfc.get_input_file(['clang', 'test.c', 'test2.c'])) - # Don't handle preprocessed files - self.assertIsNone(check_cfc.get_input_file(['clang', 'test.i'])) - self.assertIsNone(check_cfc.get_input_file(['clang', 'test.ii'])) - # Test identifying input file with quotes - self.assertEqual( - check_cfc.get_input_file(['clang', '"test.c"']), '"test.c"') - self.assertEqual( - check_cfc.get_input_file(['clang', "'test.c'"]), "'test.c'") - # Test multiple quotes - self.assertEqual( - check_cfc.get_input_file(['clang', "\"'test.c'\""]), "\"'test.c'\"") - - def test_set_input_file(self): - self.assertEqual(check_cfc.set_input_file( - ['clang', 'test.c'], 'test.s'), ['clang', 'test.s']) - -if __name__ == '__main__': - unittest.main() diff --git a/utils/clangdiag.py b/utils/clangdiag.py deleted file mode 100755 index 6baf65a8761c..000000000000 --- a/utils/clangdiag.py +++ /dev/null @@ -1,192 +0,0 @@ -#!/usr/bin/python - -#---------------------------------------------------------------------- -# Be sure to add the python path that points to the LLDB shared library. -# -# # To use this in the embedded python interpreter using "lldb" just -# import it with the full path using the "command script import" -# command -# (lldb) command script import /path/to/clandiag.py -#---------------------------------------------------------------------- - -from __future__ import absolute_import, division, print_function -import lldb -import argparse -import shlex -import os -import re -import subprocess - -class MyParser(argparse.ArgumentParser): - def format_help(self): - return ''' Commands for managing clang diagnostic breakpoints - -Syntax: clangdiag enable [<warning>|<diag-name>] - clangdiag disable - clangdiag diagtool [<path>|reset] - -The following subcommands are supported: - - enable -- Enable clang diagnostic breakpoints. - disable -- Disable all clang diagnostic breakpoints. - diagtool -- Return, set, or reset diagtool path. - -This command sets breakpoints in clang, and clang based tools, that -emit diagnostics. When a diagnostic is emitted, and clangdiag is -enabled, it will use the appropriate diagtool application to determine -the name of the DiagID, and set breakpoints in all locations that -'diag::name' appears in the source. Since the new breakpoints are set -after they are encountered, users will need to launch the executable a -second time in order to hit the new breakpoints. - -For in-tree builds, the diagtool application, used to map DiagID's to -names, is found automatically in the same directory as the target -executable. However, out-or-tree builds must use the 'diagtool' -subcommand to set the appropriate path for diagtool in the clang debug -bin directory. Since this mapping is created at build-time, it's -important for users to use the same version that was generated when -clang was compiled, or else the id's won't match. - -Notes: -- Substrings can be passed for both <warning> and <diag-name>. -- If <warning> is passed, only enable the DiagID(s) for that warning. -- If <diag-name> is passed, only enable that DiagID. -- Rerunning enable clears existing breakpoints. -- diagtool is used in breakpoint callbacks, so it can be changed - without the need to rerun enable. -- Adding this to your ~.lldbinit file makes clangdiag available at startup: - "command script import /path/to/clangdiag.py" - -''' - -def create_diag_options(): - parser = MyParser(prog='clangdiag') - subparsers = parser.add_subparsers( - title='subcommands', - dest='subcommands', - metavar='') - disable_parser = subparsers.add_parser('disable') - enable_parser = subparsers.add_parser('enable') - enable_parser.add_argument('id', nargs='?') - diagtool_parser = subparsers.add_parser('diagtool') - diagtool_parser.add_argument('path', nargs='?') - return parser - -def getDiagtool(target, diagtool = None): - id = target.GetProcess().GetProcessID() - if 'diagtool' not in getDiagtool.__dict__: - getDiagtool.diagtool = {} - if diagtool: - if diagtool == 'reset': - getDiagtool.diagtool[id] = None - elif os.path.exists(diagtool): - getDiagtool.diagtool[id] = diagtool - else: - print('clangdiag: %s not found.' % diagtool) - if not id in getDiagtool.diagtool or not getDiagtool.diagtool[id]: - getDiagtool.diagtool[id] = None - exe = target.GetExecutable() - if not exe.Exists(): - print('clangdiag: Target (%s) not set.' % exe.GetFilename()) - else: - diagtool = os.path.join(exe.GetDirectory(), 'diagtool') - if os.path.exists(diagtool): - getDiagtool.diagtool[id] = diagtool - else: - print('clangdiag: diagtool not found along side %s' % exe) - - return getDiagtool.diagtool[id] - -def setDiagBreakpoint(frame, bp_loc, dict): - id = frame.FindVariable("DiagID").GetValue() - if id is None: - print('clangdiag: id is None') - return False - - # Don't need to test this time, since we did that in enable. - target = frame.GetThread().GetProcess().GetTarget() - diagtool = getDiagtool(target) - name = subprocess.check_output([diagtool, "find-diagnostic-id", id]).rstrip(); - # Make sure we only consider errors, warnings, and extensions. - # FIXME: Make this configurable? - prefixes = ['err_', 'warn_', 'exp_'] - if len([prefix for prefix in prefixes+[''] if name.startswith(prefix)][0]): - bp = target.BreakpointCreateBySourceRegex(name, lldb.SBFileSpec()) - bp.AddName("clang::Diagnostic") - - return False - -def enable(exe_ctx, args): - # Always disable existing breakpoints - disable(exe_ctx) - - target = exe_ctx.GetTarget() - numOfBreakpoints = target.GetNumBreakpoints() - - if args.id: - # Make sure we only consider errors, warnings, and extensions. - # FIXME: Make this configurable? - prefixes = ['err_', 'warn_', 'exp_'] - if len([prefix for prefix in prefixes+[''] if args.id.startswith(prefix)][0]): - bp = target.BreakpointCreateBySourceRegex(args.id, lldb.SBFileSpec()) - bp.AddName("clang::Diagnostic") - else: - diagtool = getDiagtool(target) - list = subprocess.check_output([diagtool, "list-warnings"]).rstrip(); - for line in list.splitlines(True): - m = re.search(r' *(.*) .*\[\-W' + re.escape(args.id) + r'.*].*', line) - # Make sure we only consider warnings. - if m and m.group(1).startswith('warn_'): - bp = target.BreakpointCreateBySourceRegex(m.group(1), lldb.SBFileSpec()) - bp.AddName("clang::Diagnostic") - else: - print('Adding callbacks.') - bp = target.BreakpointCreateByName('DiagnosticsEngine::Report') - bp.SetScriptCallbackFunction('clangdiag.setDiagBreakpoint') - bp.AddName("clang::Diagnostic") - - count = target.GetNumBreakpoints() - numOfBreakpoints - print('%i breakpoint%s added.' % (count, "s"[count==1:])) - - return - -def disable(exe_ctx): - target = exe_ctx.GetTarget() - # Remove all diag breakpoints. - bkpts = lldb.SBBreakpointList(target) - target.FindBreakpointsByName("clang::Diagnostic", bkpts) - for i in range(bkpts.GetSize()): - target.BreakpointDelete(bkpts.GetBreakpointAtIndex(i).GetID()) - - return - -def the_diag_command(debugger, command, exe_ctx, result, dict): - # Use the Shell Lexer to properly parse up command options just like a - # shell would - command_args = shlex.split(command) - parser = create_diag_options() - try: - args = parser.parse_args(command_args) - except: - return - - if args.subcommands == 'enable': - enable(exe_ctx, args) - elif args.subcommands == 'disable': - disable(exe_ctx) - else: - diagtool = getDiagtool(exe_ctx.GetTarget(), args.path) - print('diagtool = %s' % diagtool) - - return - -def __lldb_init_module(debugger, dict): - # This initializer is being run from LLDB in the embedded command interpreter - # Make the options so we can generate the help text for the new LLDB - # command line command prior to registering it with LLDB below - parser = create_diag_options() - the_diag_command.__doc__ = parser.format_help() - # Add any commands contained in this module to LLDB - debugger.HandleCommand( - 'command script add -f clangdiag.the_diag_command clangdiag') - print('The "clangdiag" command has been installed, type "help clangdiag" or "clangdiag --help" for detailed help.') diff --git a/utils/find-unused-diagnostics.sh b/utils/find-unused-diagnostics.sh deleted file mode 100644 index 783f58ba1d30..000000000000 --- a/utils/find-unused-diagnostics.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -# -# This script produces a list of all diagnostics that are defined -# in Diagnostic*.td files but not used in sources. -# - -# Gather all diagnostic identifiers from the .td files. -ALL_DIAGS=$(grep -E --only-matching --no-filename '(err_|warn_|ext_|note_)[a-z_]+' ./include/clang/Basic/Diagnostic*.td) - -# Now look for all potential identifiers in the source files. -ALL_SOURCES=$(find lib include tools utils -name \*.cpp -or -name \*.h) -DIAGS_IN_SOURCES=$(grep -E --only-matching --no-filename '(err_|warn_|ext_|note_)[a-z_]+' $ALL_SOURCES) - -# Print all diags that occur in the .td files but not in the source. -comm -23 <(sort -u <<< "$ALL_DIAGS") <(sort -u <<< "$DIAGS_IN_SOURCES") diff --git a/utils/hmaptool/CMakeLists.txt b/utils/hmaptool/CMakeLists.txt deleted file mode 100644 index 5573009d343a..000000000000 --- a/utils/hmaptool/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -set(CLANG_HMAPTOOL hmaptool) - -add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin/${CLANG_HMAPTOOL} - COMMAND ${CMAKE_COMMAND} -E make_directory - ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/${CLANG_HMAPTOOL} - ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin/ - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${CLANG_HMAPTOOL}) - -list(APPEND Depends ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin/${CLANG_HMAPTOOL}) -install(PROGRAMS ${CLANG_HMAPTOOL} DESTINATION bin) - -add_custom_target(hmaptool ALL DEPENDS ${Depends}) -set_target_properties(hmaptool PROPERTIES FOLDER "Utils") - diff --git a/utils/hmaptool/hmaptool b/utils/hmaptool/hmaptool deleted file mode 100755 index 58baab2f7746..000000000000 --- a/utils/hmaptool/hmaptool +++ /dev/null @@ -1,296 +0,0 @@ -#!/usr/bin/env python -from __future__ import absolute_import, division, print_function - -import json -import optparse -import os -import struct -import sys - -### - -k_header_magic_LE = 'pamh' -k_header_magic_BE = 'hmap' - -def hmap_hash(str): - """hash(str) -> int - - Apply the "well-known" headermap hash function. - """ - - return sum((ord(c.lower()) * 13 - for c in str), 0) - -class HeaderMap(object): - @staticmethod - def frompath(path): - with open(path, 'rb') as f: - magic = f.read(4) - if magic == k_header_magic_LE: - endian_code = '<' - elif magic == k_header_magic_BE: - endian_code = '>' - else: - raise SystemExit("error: %s: not a headermap" % ( - path,)) - - # Read the header information. - header_fmt = endian_code + 'HHIIII' - header_size = struct.calcsize(header_fmt) - data = f.read(header_size) - if len(data) != header_size: - raise SystemExit("error: %s: truncated headermap header" % ( - path,)) - - (version, reserved, strtable_offset, num_entries, - num_buckets, max_value_len) = struct.unpack(header_fmt, data) - - if version != 1: - raise SystemExit("error: %s: unknown headermap version: %r" % ( - path, version)) - if reserved != 0: - raise SystemExit("error: %s: invalid reserved value in header" % ( - path,)) - - # The number of buckets must be a power of two. - if num_buckets == 0 or (num_buckets & num_buckets - 1) != 0: - raise SystemExit("error: %s: invalid number of buckets" % ( - path,)) - - # Read all of the buckets. - bucket_fmt = endian_code + 'III' - bucket_size = struct.calcsize(bucket_fmt) - buckets_data = f.read(num_buckets * bucket_size) - if len(buckets_data) != num_buckets * bucket_size: - raise SystemExit("error: %s: truncated headermap buckets" % ( - path,)) - buckets = [struct.unpack(bucket_fmt, - buckets_data[i*bucket_size:(i+1)*bucket_size]) - for i in range(num_buckets)] - - # Read the string table; the format doesn't explicitly communicate the - # size of the string table (which is dumb), so assume it is the rest of - # the file. - f.seek(0, 2) - strtable_size = f.tell() - strtable_offset - f.seek(strtable_offset) - - if strtable_size == 0: - raise SystemExit("error: %s: unable to read zero-sized string table"%( - path,)) - strtable = f.read(strtable_size) - - if len(strtable) != strtable_size: - raise SystemExit("error: %s: unable to read complete string table"%( - path,)) - if strtable[-1] != '\0': - raise SystemExit("error: %s: invalid string table in headermap" % ( - path,)) - - return HeaderMap(num_entries, buckets, strtable) - - def __init__(self, num_entries, buckets, strtable): - self.num_entries = num_entries - self.buckets = buckets - self.strtable = strtable - - def get_string(self, idx): - if idx >= len(self.strtable): - raise SystemExit("error: %s: invalid string index" % ( - path,)) - end_idx = self.strtable.index('\0', idx) - return self.strtable[idx:end_idx] - - @property - def mappings(self): - for key_idx,prefix_idx,suffix_idx in self.buckets: - if key_idx == 0: - continue - yield (self.get_string(key_idx), - self.get_string(prefix_idx) + self.get_string(suffix_idx)) - -### - -def action_dump(name, args): - "dump a headermap file" - - parser = optparse.OptionParser("%%prog %s [options] <headermap path>" % ( - name,)) - parser.add_option("-v", "--verbose", dest="verbose", - help="show more verbose output [%default]", - action="store_true", default=False) - (opts, args) = parser.parse_args(args) - - if len(args) != 1: - parser.error("invalid number of arguments") - - path, = args - - hmap = HeaderMap.frompath(path) - - # Dump all of the buckets. - print ('Header Map: %s' % (path,)) - if opts.verbose: - print ('headermap: %r' % (path,)) - print (' num entries: %d' % (hmap.num_entries,)) - print (' num buckets: %d' % (len(hmap.buckets),)) - print (' string table size: %d' % (len(hmap.strtable),)) - for i,bucket in enumerate(hmap.buckets): - key_idx,prefix_idx,suffix_idx = bucket - - if key_idx == 0: - continue - - # Get the strings. - key = hmap.get_string(key_idx) - prefix = hmap.get_string(prefix_idx) - suffix = hmap.get_string(suffix_idx) - - print (" bucket[%d]: %r -> (%r, %r) -- %d" % ( - i, key, prefix, suffix, (hmap_hash(key) & (num_buckets - 1)))) - else: - mappings = sorted(hmap.mappings) - for key,value in mappings: - print ("%s -> %s" % (key, value)) - print () - -def next_power_of_two(value): - if value < 0: - raise ArgumentError - return 1 if value == 0 else 2**(value - 1).bit_length() - -def action_write(name, args): - "write a headermap file from a JSON definition" - - parser = optparse.OptionParser("%%prog %s [options] <input path> <output path>" % ( - name,)) - (opts, args) = parser.parse_args(args) - - if len(args) != 2: - parser.error("invalid number of arguments") - - input_path,output_path = args - - with open(input_path, "r") as f: - input_data = json.load(f) - - # Compute the headermap contents, we make a table that is 1/3 full. - mappings = input_data['mappings'] - num_buckets = next_power_of_two(len(mappings) * 3) - - table = [(0, 0, 0) - for i in range(num_buckets)] - max_value_len = 0 - strtable = "\0" - for key,value in mappings.items(): - if not isinstance(key, str): - key = key.decode('utf-8') - if not isinstance(value, str): - value = value.decode('utf-8') - max_value_len = max(max_value_len, len(value)) - - key_idx = len(strtable) - strtable += key + '\0' - prefix = os.path.dirname(value) + '/' - suffix = os.path.basename(value) - prefix_idx = len(strtable) - strtable += prefix + '\0' - suffix_idx = len(strtable) - strtable += suffix + '\0' - - hash = hmap_hash(key) - for i in range(num_buckets): - idx = (hash + i) % num_buckets - if table[idx][0] == 0: - table[idx] = (key_idx, prefix_idx, suffix_idx) - break - else: - raise RuntimeError - - endian_code = '<' - magic = k_header_magic_LE - magic_size = 4 - header_fmt = endian_code + 'HHIIII' - header_size = struct.calcsize(header_fmt) - bucket_fmt = endian_code + 'III' - bucket_size = struct.calcsize(bucket_fmt) - strtable_offset = magic_size + header_size + num_buckets * bucket_size - header = (1, 0, strtable_offset, len(mappings), - num_buckets, max_value_len) - - # Write out the headermap. - with open(output_path, 'wb') as f: - f.write(magic.encode()) - f.write(struct.pack(header_fmt, *header)) - for bucket in table: - f.write(struct.pack(bucket_fmt, *bucket)) - f.write(strtable.encode()) - -def action_tovfs(name, args): - "convert a headermap to a VFS layout" - - parser = optparse.OptionParser("%%prog %s [options] <headermap path>" % ( - name,)) - parser.add_option("", "--build-path", dest="build_path", - help="build path prefix", - action="store", type=str) - (opts, args) = parser.parse_args(args) - - if len(args) != 2: - parser.error("invalid number of arguments") - if opts.build_path is None: - parser.error("--build-path is required") - - input_path,output_path = args - - hmap = HeaderMap.frompath(input_path) - - # Create the table for all the objects. - vfs = {} - vfs['version'] = 0 - build_dir_contents = [] - vfs['roots'] = [{ - 'name' : opts.build_path, - 'type' : 'directory', - 'contents' : build_dir_contents }] - - # We assume we are mapping framework paths, so a key of "Foo/Bar.h" maps to - # "<build path>/Foo.framework/Headers/Bar.h". - for key,value in hmap.mappings: - # If this isn't a framework style mapping, ignore it. - components = key.split('/') - if len(components) != 2: - continue - framework_name,header_name = components - build_dir_contents.append({ - 'name' : '%s.framework/Headers/%s' % (framework_name, - header_name), - 'type' : 'file', - 'external-contents' : value }) - - with open(output_path, 'w') as f: - json.dump(vfs, f, indent=2) - -commands = dict((name[7:].replace("_","-"), f) - for name,f in locals().items() - if name.startswith('action_')) - -def usage(): - print ("Usage: %s command [options]" % ( - os.path.basename(sys.argv[0])), file=sys.stderr) - print (file=sys.stderr) - print ("Available commands:", file=sys.stderr) - cmds_width = max(map(len, commands)) - for name,func in sorted(commands.items()): - print (" %-*s - %s" % (cmds_width, name, func.__doc__), file=sys.stderr) - sys.exit(1) - -def main(): - if len(sys.argv) < 2 or sys.argv[1] not in commands: - usage() - - cmd = sys.argv[1] - commands[cmd](cmd, sys.argv[2:]) - -if __name__ == '__main__': - main() diff --git a/utils/modfuzz.py b/utils/modfuzz.py deleted file mode 100644 index 61ca3272aca5..000000000000 --- a/utils/modfuzz.py +++ /dev/null @@ -1,167 +0,0 @@ -#! /usr/bin/env python - -# To use: -# 1) Update the 'decls' list below with your fuzzing configuration. -# 2) Run with the clang binary as the command-line argument. - -from __future__ import absolute_import, division, print_function -import random -import subprocess -import sys -import os - -clang = sys.argv[1] -none_opts = 0.3 - -class Decl(object): - def __init__(self, text, depends=[], provides=[], conflicts=[]): - self.text = text - self.depends = depends - self.provides = provides - self.conflicts = conflicts - - def valid(self, model): - for i in self.depends: - if i not in model.decls: - return False - for i in self.conflicts: - if i in model.decls: - return False - return True - - def apply(self, model, name): - for i in self.provides: - model.decls[i] = True - model.source += self.text % {'name': name} - -decls = [ - Decl('struct X { int n; };\n', provides=['X'], conflicts=['X']), - Decl('static_assert(X{.n=1}.n == 1, "");\n', depends=['X']), - Decl('X %(name)s;\n', depends=['X']), -] - -class FS(object): - def __init__(self): - self.fs = {} - self.prevfs = {} - - def write(self, path, contents): - self.fs[path] = contents - - def done(self): - for f, s in self.fs.items(): - if self.prevfs.get(f) != s: - f = file(f, 'w') - f.write(s) - f.close() - - for f in self.prevfs: - if f not in self.fs: - os.remove(f) - - self.prevfs, self.fs = self.fs, {} - -fs = FS() - -class CodeModel(object): - def __init__(self): - self.source = '' - self.modules = {} - self.decls = {} - self.i = 0 - - def make_name(self): - self.i += 1 - return 'n' + str(self.i) - - def fails(self): - fs.write('module.modulemap', - ''.join('module %s { header "%s.h" export * }\n' % (m, m) - for m in self.modules.keys())) - - for m, (s, _) in self.modules.items(): - fs.write('%s.h' % m, s) - - fs.write('main.cc', self.source) - fs.done() - - return subprocess.call([clang, '-std=c++11', '-c', '-fmodules', 'main.cc', '-o', '/dev/null']) != 0 - -def generate(): - model = CodeModel() - m = [] - - try: - for d in mutations(model): - d(model) - m.append(d) - if not model.fails(): - return - except KeyboardInterrupt: - print() - return True - - sys.stdout.write('\nReducing:\n') - sys.stdout.flush() - - try: - while True: - assert m, 'got a failure with no steps; broken clang binary?' - i = random.choice(list(range(len(m)))) - x = m[0:i] + m[i+1:] - m2 = CodeModel() - for d in x: - d(m2) - if m2.fails(): - m = x - model = m2 - else: - sys.stdout.write('.') - sys.stdout.flush() - except KeyboardInterrupt: - # FIXME: Clean out output directory first. - model.fails() - return model - -def choose(options): - while True: - i = int(random.uniform(0, len(options) + none_opts)) - if i >= len(options): - break - yield options[i] - -def mutations(model): - options = [create_module, add_top_level_decl] - for opt in choose(options): - yield opt(model, options) - -def create_module(model, options): - n = model.make_name() - def go(model): - model.modules[n] = (model.source, model.decls) - (model.source, model.decls) = ('', {}) - options += [lambda model, options: add_import(model, options, n)] - return go - -def add_top_level_decl(model, options): - n = model.make_name() - d = random.choice([decl for decl in decls if decl.valid(model)]) - def go(model): - if not d.valid(model): - return - d.apply(model, n) - return go - -def add_import(model, options, module_name): - def go(model): - if module_name in model.modules: - model.source += '#include "%s.h"\n' % module_name - model.decls.update(model.modules[module_name][1]) - return go - -sys.stdout.write('Finding bug: ') -while True: - if generate(): - break - sys.stdout.write('.') - sys.stdout.flush() diff --git a/utils/perf-training/CMakeLists.txt b/utils/perf-training/CMakeLists.txt deleted file mode 100644 index 39f9a4ca3c13..000000000000 --- a/utils/perf-training/CMakeLists.txt +++ /dev/null @@ -1,67 +0,0 @@ - -# All test suites added here should be excuded from check-all -set(EXCLUDE_FROM_ALL On) - -if (CMAKE_CFG_INTDIR STREQUAL ".") - set(LLVM_BUILD_MODE ".") -else () - set(LLVM_BUILD_MODE "%(build_mode)s") -endif () - -string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} CLANG_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR}) - -if(LLVM_BUILD_INSTRUMENTED) - configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/pgo-data/lit.site.cfg - ) - - add_lit_testsuite(generate-profraw "Generating clang PGO data" - ${CMAKE_CURRENT_BINARY_DIR}/pgo-data/ - DEPENDS clang clear-profraw - ) - - add_custom_target(clear-profraw - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py clean ${CMAKE_CURRENT_BINARY_DIR} profraw - COMMENT "Clearing old profraw data") - - if(NOT LLVM_PROFDATA) - find_program(LLVM_PROFDATA llvm-profdata) - endif() - - if(NOT LLVM_PROFDATA) - message(STATUS "To enable merging PGO data LLVM_PROFDATA has to point to llvm-profdata") - else() - add_custom_target(generate-profdata - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Merging profdata" - DEPENDS generate-profraw) - endif() -endif() - -find_program(DTRACE dtrace) -if(APPLE AND DTRACE) - configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/order-files.lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/order-files/lit.site.cfg - ) - - add_lit_testsuite(generate-dtrace-logs "Generating clang dtrace data" - ${CMAKE_CURRENT_BINARY_DIR}/order-files/ - ARGS -j 1 - DEPENDS clang clear-dtrace-logs - ) - - add_custom_target(clear-dtrace-logs - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py clean ${CMAKE_CURRENT_BINARY_DIR} dtrace - COMMENT "Clearing old dtrace data") - - if(NOT CLANG_ORDER_FILE) - message(FATAL_ERROR "Output clang order file is not set") - endif() - - add_custom_target(generate-order-file - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py gen-order-file --binary $<TARGET_FILE:clang> --output ${CLANG_ORDER_FILE} ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Generating order file" - DEPENDS generate-dtrace-logs) -endif() diff --git a/utils/perf-training/README.txt b/utils/perf-training/README.txt deleted file mode 100644 index cfbce40ca3ef..000000000000 --- a/utils/perf-training/README.txt +++ /dev/null @@ -1,6 +0,0 @@ -========================== - Performance Training Data -========================== - -This directory contains simple source files for use as training data for -generating PGO data and linker order files for clang. diff --git a/utils/perf-training/cxx/hello_world.cpp b/utils/perf-training/cxx/hello_world.cpp deleted file mode 100644 index fc9f6892eb74..000000000000 --- a/utils/perf-training/cxx/hello_world.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %clang_cpp -c %s -// RUN: %clang_cpp_skip_driver -Wall -pedantic -c %s -#include <iostream> - -int main(int, char**) { - std::cout << "Hello, World!"; - return 0; -} diff --git a/utils/perf-training/lit.cfg b/utils/perf-training/lit.cfg deleted file mode 100644 index 671d44f83b94..000000000000 --- a/utils/perf-training/lit.cfg +++ /dev/null @@ -1,41 +0,0 @@ -# -*- Python -*- - -from lit import Test -import lit.formats -import lit.util -import subprocess - -def getSysrootFlagsOnDarwin(config, lit_config): - # On Darwin, support relocatable SDKs by providing Clang with a - # default system root path. - if 'darwin' in config.target_triple: - try: - out = subprocess.check_output(['xcrun', '--show-sdk-path']).strip() - res = 0 - except OSError: - res = -1 - if res == 0 and out: - sdk_path = out - lit_config.note('using SDKROOT: %r' % sdk_path) - return '-isysroot %s' % sdk_path - return '' - -sysroot_flags = getSysrootFlagsOnDarwin(config, lit_config) - -config.clang = lit.util.which('clang', config.clang_tools_dir).replace('\\', '/') - -config.name = 'Clang Perf Training' -config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s', '.S', '.modulemap'] - -cc1_wrapper = '%s %s/perf-helper.py cc1' % (config.python_exe, config.test_source_root) - -use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") -config.test_format = lit.formats.ShTest(use_lit_shell == "0") -config.substitutions.append( ('%clang_cpp_skip_driver', ' %s %s %s ' % (cc1_wrapper, config.clang, sysroot_flags))) -config.substitutions.append( ('%clang_cpp', ' %s --driver-mode=g++ %s ' % (config.clang, sysroot_flags))) -config.substitutions.append( ('%clang_skip_driver', ' %s %s %s ' % (cc1_wrapper, config.clang, sysroot_flags))) -config.substitutions.append( ('%clang', ' %s %s ' % (config.clang, sysroot_flags) ) ) -config.substitutions.append( ('%test_root', config.test_exec_root ) ) - -config.environment['LLVM_PROFILE_FILE'] = 'perf-training-%p.profraw' - diff --git a/utils/perf-training/lit.site.cfg.in b/utils/perf-training/lit.site.cfg.in deleted file mode 100644 index 66683bcd5286..000000000000 --- a/utils/perf-training/lit.site.cfg.in +++ /dev/null @@ -1,21 +0,0 @@ -@LIT_SITE_CFG_IN_HEADER@ - -import sys - -config.clang_tools_dir = "@CLANG_TOOLS_DIR@" -config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@" -config.test_source_root = "@CMAKE_CURRENT_SOURCE_DIR@" -config.target_triple = "@TARGET_TRIPLE@" -config.python_exe = "@PYTHON_EXECUTABLE@" - -# Support substitution of the tools and libs dirs with user parameters. This is -# used when we can't determine the tool dir at configuration time. -try: - config.clang_tools_dir = config.clang_tools_dir % lit_config.params -except KeyError: - e = sys.exc_info()[1] - key, = e.args - lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) - -# Let the main config do the real work. -lit_config.load_config(config, "@CLANG_SOURCE_DIR@/utils/perf-training/lit.cfg") diff --git a/utils/perf-training/order-files.lit.cfg b/utils/perf-training/order-files.lit.cfg deleted file mode 100644 index 93904ec84a41..000000000000 --- a/utils/perf-training/order-files.lit.cfg +++ /dev/null @@ -1,46 +0,0 @@ -# -*- Python -*- - -from lit import Test -import lit.formats -import lit.util -import os -import subprocess - -def getSysrootFlagsOnDarwin(config, lit_config): - # On Darwin, support relocatable SDKs by providing Clang with a - # default system root path. - if 'darwin' in config.target_triple: - try: - out = subprocess.check_output(['xcrun', '--show-sdk-path']).strip() - res = 0 - except OSError: - res = -1 - if res == 0 and out: - sdk_path = out - lit_config.note('using SDKROOT: %r' % sdk_path) - return '-isysroot %s' % sdk_path - return '' - -sysroot_flags = getSysrootFlagsOnDarwin(config, lit_config) - -config.clang = os.path.realpath(lit.util.which('clang', config.clang_tools_dir)).replace('\\', '/') - -config.name = 'Clang Perf Training' -config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s', '.S', '.modulemap'] - -dtrace_wrapper = '%s %s/perf-helper.py dtrace' % (config.python_exe, config.test_source_root) -dtrace_wrapper_cc1 = '%s %s/perf-helper.py dtrace --cc1' % (config.python_exe, config.test_source_root) - -if 'darwin' in config.target_triple: - lit_config.note('using DTrace oneshot probe') - dtrace_wrapper = '%s --use-oneshot' % dtrace_wrapper - dtrace_wrapper_cc1 = '%s --use-oneshot' % dtrace_wrapper_cc1 - -use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") -config.test_format = lit.formats.ShTest(use_lit_shell == "0") -config.substitutions.append( ('%clang_cpp_skip_driver', ' %s %s --driver-mode=g++ %s ' % (dtrace_wrapper_cc1, config.clang, sysroot_flags))) -config.substitutions.append( ('%clang_cpp', ' %s %s --driver-mode=g++ %s ' % (dtrace_wrapper, config.clang, sysroot_flags))) -config.substitutions.append( ('%clang_skip_driver', ' %s %s %s ' % (dtrace_wrapper_cc1, config.clang, sysroot_flags))) -config.substitutions.append( ('%clang', ' %s %s %s ' % (dtrace_wrapper, config.clang, sysroot_flags) ) ) -config.substitutions.append( ('%test_root', config.test_exec_root ) ) - diff --git a/utils/perf-training/order-files.lit.site.cfg.in b/utils/perf-training/order-files.lit.site.cfg.in deleted file mode 100644 index 0490a217ad04..000000000000 --- a/utils/perf-training/order-files.lit.site.cfg.in +++ /dev/null @@ -1,21 +0,0 @@ -@LIT_SITE_CFG_IN_HEADER@ - -import sys - -config.clang_tools_dir = "@CLANG_TOOLS_DIR@" -config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@" -config.test_source_root = "@CMAKE_CURRENT_SOURCE_DIR@" -config.target_triple = "@TARGET_TRIPLE@" -config.python_exe = "@PYTHON_EXECUTABLE@" - -# Support substitution of the tools and libs dirs with user parameters. This is -# used when we can't determine the tool dir at configuration time. -try: - config.clang_tools_dir = config.clang_tools_dir % lit_config.params -except KeyError: - e = sys.exc_info()[1] - key, = e.args - lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) - -# Let the main config do the real work. -lit_config.load_config(config, "@CLANG_SOURCE_DIR@/utils/perf-training/order-files.lit.cfg") diff --git a/utils/perf-training/perf-helper.py b/utils/perf-training/perf-helper.py deleted file mode 100644 index 65afbb6ed572..000000000000 --- a/utils/perf-training/perf-helper.py +++ /dev/null @@ -1,408 +0,0 @@ -#===- perf-helper.py - Clang Python Bindings -----------------*- python -*--===# -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -#===------------------------------------------------------------------------===# - -from __future__ import absolute_import, division, print_function - -import sys -import os -import subprocess -import argparse -import time -import bisect -import shlex -import tempfile - -test_env = { 'PATH' : os.environ['PATH'] } - -def findFilesWithExtension(path, extension): - filenames = [] - for root, dirs, files in os.walk(path): - for filename in files: - if filename.endswith(extension): - filenames.append(os.path.join(root, filename)) - return filenames - -def clean(args): - if len(args) != 2: - print('Usage: %s clean <path> <extension>\n' % __file__ + - '\tRemoves all files with extension from <path>.') - return 1 - for filename in findFilesWithExtension(args[0], args[1]): - os.remove(filename) - return 0 - -def merge(args): - if len(args) != 3: - print('Usage: %s clean <llvm-profdata> <output> <path>\n' % __file__ + - '\tMerges all profraw files from path into output.') - return 1 - cmd = [args[0], 'merge', '-o', args[1]] - cmd.extend(findFilesWithExtension(args[2], "profraw")) - subprocess.check_call(cmd) - return 0 - -def dtrace(args): - parser = argparse.ArgumentParser(prog='perf-helper dtrace', - description='dtrace wrapper for order file generation') - parser.add_argument('--buffer-size', metavar='size', type=int, required=False, - default=1, help='dtrace buffer size in MB (default 1)') - parser.add_argument('--use-oneshot', required=False, action='store_true', - help='Use dtrace\'s oneshot probes') - parser.add_argument('--use-ustack', required=False, action='store_true', - help='Use dtrace\'s ustack to print function names') - parser.add_argument('--cc1', required=False, action='store_true', - help='Execute cc1 directly (don\'t profile the driver)') - parser.add_argument('cmd', nargs='*', help='') - - # Use python's arg parser to handle all leading option arguments, but pass - # everything else through to dtrace - first_cmd = next(arg for arg in args if not arg.startswith("--")) - last_arg_idx = args.index(first_cmd) - - opts = parser.parse_args(args[:last_arg_idx]) - cmd = args[last_arg_idx:] - - if opts.cc1: - cmd = get_cc1_command_for_args(cmd, test_env) - - if opts.use_oneshot: - target = "oneshot$target:::entry" - else: - target = "pid$target:::entry" - predicate = '%s/probemod=="%s"/' % (target, os.path.basename(cmd[0])) - log_timestamp = 'printf("dtrace-TS: %d\\n", timestamp)' - if opts.use_ustack: - action = 'ustack(1);' - else: - action = 'printf("dtrace-Symbol: %s\\n", probefunc);' - dtrace_script = "%s { %s; %s }" % (predicate, log_timestamp, action) - - dtrace_args = [] - if not os.geteuid() == 0: - print( - 'Script must be run as root, or you must add the following to your sudoers:' - + '%%admin ALL=(ALL) NOPASSWD: /usr/sbin/dtrace') - dtrace_args.append("sudo") - - dtrace_args.extend(( - 'dtrace', '-xevaltime=exec', - '-xbufsize=%dm' % (opts.buffer_size), - '-q', '-n', dtrace_script, - '-c', ' '.join(cmd))) - - if sys.platform == "darwin": - dtrace_args.append('-xmangled') - - start_time = time.time() - - with open("%d.dtrace" % os.getpid(), "w") as f: - f.write("### Command: %s" % dtrace_args) - subprocess.check_call(dtrace_args, stdout=f, stderr=subprocess.PIPE) - - elapsed = time.time() - start_time - print("... data collection took %.4fs" % elapsed) - - return 0 - -def get_cc1_command_for_args(cmd, env): - # Find the cc1 command used by the compiler. To do this we execute the - # compiler with '-###' to figure out what it wants to do. - cmd = cmd + ['-###'] - cc_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, env=env, universal_newlines=True).strip() - cc_commands = [] - for ln in cc_output.split('\n'): - # Filter out known garbage. - if (ln == 'Using built-in specs.' or - ln.startswith('Configured with:') or - ln.startswith('Target:') or - ln.startswith('Thread model:') or - ln.startswith('InstalledDir:') or - ln.startswith('LLVM Profile Note') or - ' version ' in ln): - continue - cc_commands.append(ln) - - if len(cc_commands) != 1: - print('Fatal error: unable to determine cc1 command: %r' % cc_output) - exit(1) - - cc1_cmd = shlex.split(cc_commands[0]) - if not cc1_cmd: - print('Fatal error: unable to determine cc1 command: %r' % cc_output) - exit(1) - - return cc1_cmd - -def cc1(args): - parser = argparse.ArgumentParser(prog='perf-helper cc1', - description='cc1 wrapper for order file generation') - parser.add_argument('cmd', nargs='*', help='') - - # Use python's arg parser to handle all leading option arguments, but pass - # everything else through to dtrace - first_cmd = next(arg for arg in args if not arg.startswith("--")) - last_arg_idx = args.index(first_cmd) - - opts = parser.parse_args(args[:last_arg_idx]) - cmd = args[last_arg_idx:] - - # clear the profile file env, so that we don't generate profdata - # when capturing the cc1 command - cc1_env = test_env - cc1_env["LLVM_PROFILE_FILE"] = os.devnull - cc1_cmd = get_cc1_command_for_args(cmd, cc1_env) - - subprocess.check_call(cc1_cmd) - return 0 - -def parse_dtrace_symbol_file(path, all_symbols, all_symbols_set, - missing_symbols, opts): - def fix_mangling(symbol): - if sys.platform == "darwin": - if symbol[0] != '_' and symbol != 'start': - symbol = '_' + symbol - return symbol - - def get_symbols_with_prefix(symbol): - start_index = bisect.bisect_left(all_symbols, symbol) - for s in all_symbols[start_index:]: - if not s.startswith(symbol): - break - yield s - - # Extract the list of symbols from the given file, which is assumed to be - # the output of a dtrace run logging either probefunc or ustack(1) and - # nothing else. The dtrace -xdemangle option needs to be used. - # - # This is particular to OS X at the moment, because of the '_' handling. - with open(path) as f: - current_timestamp = None - for ln in f: - # Drop leading and trailing whitespace. - ln = ln.strip() - if not ln.startswith("dtrace-"): - continue - - # If this is a timestamp specifier, extract it. - if ln.startswith("dtrace-TS: "): - _,data = ln.split(': ', 1) - if not data.isdigit(): - print("warning: unrecognized timestamp line %r, ignoring" % ln, - file=sys.stderr) - continue - current_timestamp = int(data) - continue - elif ln.startswith("dtrace-Symbol: "): - - _,ln = ln.split(': ', 1) - if not ln: - continue - - # If there is a '`' in the line, assume it is a ustack(1) entry in - # the form of <modulename>`<modulefunc>, where <modulefunc> is never - # truncated (but does need the mangling patched). - if '`' in ln: - yield (current_timestamp, fix_mangling(ln.split('`',1)[1])) - continue - - # Otherwise, assume this is a probefunc printout. DTrace on OS X - # seems to have a bug where it prints the mangled version of symbols - # which aren't C++ mangled. We just add a '_' to anything but start - # which doesn't already have a '_'. - symbol = fix_mangling(ln) - - # If we don't know all the symbols, or the symbol is one of them, - # just return it. - if not all_symbols_set or symbol in all_symbols_set: - yield (current_timestamp, symbol) - continue - - # Otherwise, we have a symbol name which isn't present in the - # binary. We assume it is truncated, and try to extend it. - - # Get all the symbols with this prefix. - possible_symbols = list(get_symbols_with_prefix(symbol)) - if not possible_symbols: - continue - - # If we found too many possible symbols, ignore this as a prefix. - if len(possible_symbols) > 100: - print( "warning: ignoring symbol %r " % symbol + - "(no match and too many possible suffixes)", file=sys.stderr) - continue - - # Report that we resolved a missing symbol. - if opts.show_missing_symbols and symbol not in missing_symbols: - print("warning: resolved missing symbol %r" % symbol, file=sys.stderr) - missing_symbols.add(symbol) - - # Otherwise, treat all the possible matches as having occurred. This - # is an over-approximation, but it should be ok in practice. - for s in possible_symbols: - yield (current_timestamp, s) - -def uniq(list): - seen = set() - for item in list: - if item not in seen: - yield item - seen.add(item) - -def form_by_call_order(symbol_lists): - # Simply strategy, just return symbols in order of occurrence, even across - # multiple runs. - return uniq(s for symbols in symbol_lists for s in symbols) - -def form_by_call_order_fair(symbol_lists): - # More complicated strategy that tries to respect the call order across all - # of the test cases, instead of giving a huge preference to the first test - # case. - - # First, uniq all the lists. - uniq_lists = [list(uniq(symbols)) for symbols in symbol_lists] - - # Compute the successors for each list. - succs = {} - for symbols in uniq_lists: - for a,b in zip(symbols[:-1], symbols[1:]): - succs[a] = items = succs.get(a, []) - if b not in items: - items.append(b) - - # Emit all the symbols, but make sure to always emit all successors from any - # call list whenever we see a symbol. - # - # There isn't much science here, but this sometimes works better than the - # more naive strategy. Then again, sometimes it doesn't so more research is - # probably needed. - return uniq(s - for symbols in symbol_lists - for node in symbols - for s in ([node] + succs.get(node,[]))) - -def form_by_frequency(symbol_lists): - # Form the order file by just putting the most commonly occurring symbols - # first. This assumes the data files didn't use the oneshot dtrace method. - - counts = {} - for symbols in symbol_lists: - for a in symbols: - counts[a] = counts.get(a,0) + 1 - - by_count = list(counts.items()) - by_count.sort(key = lambda __n: -__n[1]) - return [s for s,n in by_count] - -def form_by_random(symbol_lists): - # Randomize the symbols. - merged_symbols = uniq(s for symbols in symbol_lists - for s in symbols) - random.shuffle(merged_symbols) - return merged_symbols - -def form_by_alphabetical(symbol_lists): - # Alphabetize the symbols. - merged_symbols = list(set(s for symbols in symbol_lists for s in symbols)) - merged_symbols.sort() - return merged_symbols - -methods = dict((name[len("form_by_"):],value) - for name,value in locals().items() if name.startswith("form_by_")) - -def genOrderFile(args): - parser = argparse.ArgumentParser( - "%prog [options] <dtrace data file directories>]") - parser.add_argument('input', nargs='+', help='') - parser.add_argument("--binary", metavar="PATH", type=str, dest="binary_path", - help="Path to the binary being ordered (for getting all symbols)", - default=None) - parser.add_argument("--output", dest="output_path", - help="path to output order file to write", default=None, required=True, - metavar="PATH") - parser.add_argument("--show-missing-symbols", dest="show_missing_symbols", - help="show symbols which are 'fixed up' to a valid name (requires --binary)", - action="store_true", default=None) - parser.add_argument("--output-unordered-symbols", - dest="output_unordered_symbols_path", - help="write a list of the unordered symbols to PATH (requires --binary)", - default=None, metavar="PATH") - parser.add_argument("--method", dest="method", - help="order file generation method to use", choices=list(methods.keys()), - default='call_order') - opts = parser.parse_args(args) - - # If the user gave us a binary, get all the symbols in the binary by - # snarfing 'nm' output. - if opts.binary_path is not None: - output = subprocess.check_output(['nm', '-P', opts.binary_path], universal_newlines=True) - lines = output.split("\n") - all_symbols = [ln.split(' ',1)[0] - for ln in lines - if ln.strip()] - print("found %d symbols in binary" % len(all_symbols)) - all_symbols.sort() - else: - all_symbols = [] - all_symbols_set = set(all_symbols) - - # Compute the list of input files. - input_files = [] - for dirname in opts.input: - input_files.extend(findFilesWithExtension(dirname, "dtrace")) - - # Load all of the input files. - print("loading from %d data files" % len(input_files)) - missing_symbols = set() - timestamped_symbol_lists = [ - list(parse_dtrace_symbol_file(path, all_symbols, all_symbols_set, - missing_symbols, opts)) - for path in input_files] - - # Reorder each symbol list. - symbol_lists = [] - for timestamped_symbols_list in timestamped_symbol_lists: - timestamped_symbols_list.sort() - symbol_lists.append([symbol for _,symbol in timestamped_symbols_list]) - - # Execute the desire order file generation method. - method = methods.get(opts.method) - result = list(method(symbol_lists)) - - # Report to the user on what percentage of symbols are present in the order - # file. - num_ordered_symbols = len(result) - if all_symbols: - print("note: order file contains %d/%d symbols (%.2f%%)" % ( - num_ordered_symbols, len(all_symbols), - 100.*num_ordered_symbols/len(all_symbols)), file=sys.stderr) - - if opts.output_unordered_symbols_path: - ordered_symbols_set = set(result) - with open(opts.output_unordered_symbols_path, 'w') as f: - f.write("\n".join(s for s in all_symbols if s not in ordered_symbols_set)) - - # Write the order file. - with open(opts.output_path, 'w') as f: - f.write("\n".join(result)) - f.write("\n") - - return 0 - -commands = {'clean' : clean, - 'merge' : merge, - 'dtrace' : dtrace, - 'cc1' : cc1, - 'gen-order-file' : genOrderFile} - -def main(): - f = commands[sys.argv[1]] - sys.exit(f(sys.argv[2:])) - -if __name__ == '__main__': - main() diff --git a/utils/token-delta.py b/utils/token-delta.py deleted file mode 100755 index 62b4eb3c776c..000000000000 --- a/utils/token-delta.py +++ /dev/null @@ -1,252 +0,0 @@ -#!/usr/bin/env python - -from __future__ import absolute_import, division, print_function -import os -import re -import subprocess -import sys -import tempfile - -### - -class DeltaAlgorithm(object): - def __init__(self): - self.cache = set() - - def test(self, changes): - abstract - - ### - - def getTestResult(self, changes): - # There is no reason to cache successful tests because we will - # always reduce the changeset when we see one. - - changeset = frozenset(changes) - if changeset in self.cache: - return False - elif not self.test(changes): - self.cache.add(changeset) - return False - else: - return True - - def run(self, changes, force=False): - # Make sure the initial test passes, if not then (a) either - # the user doesn't expect monotonicity, and we may end up - # doing O(N^2) tests, or (b) the test is wrong. Avoid the - # O(N^2) case unless user requests it. - if not force: - if not self.getTestResult(changes): - raise ValueError('Initial test passed to delta fails.') - - # Check empty set first to quickly find poor test functions. - if self.getTestResult(set()): - return set() - else: - return self.delta(changes, self.split(changes)) - - def split(self, S): - """split(set) -> [sets] - - Partition a set into one or two pieces. - """ - - # There are many ways to split, we could do a better job with more - # context information (but then the API becomes grosser). - L = list(S) - mid = len(L)//2 - if mid==0: - return L, - else: - return L[:mid],L[mid:] - - def delta(self, c, sets): - # assert(reduce(set.union, sets, set()) == c) - - # If there is nothing left we can remove, we are done. - if len(sets) <= 1: - return c - - # Look for a passing subset. - res = self.search(c, sets) - if res is not None: - return res - - # Otherwise, partition sets if possible; if not we are done. - refined = sum(map(list, map(self.split, sets)), []) - if len(refined) == len(sets): - return c - - return self.delta(c, refined) - - def search(self, c, sets): - for i,S in enumerate(sets): - # If test passes on this subset alone, recurse. - if self.getTestResult(S): - return self.delta(S, self.split(S)) - - # Otherwise if we have more than two sets, see if test - # pases without this subset. - if len(sets) > 2: - complement = sum(sets[:i] + sets[i+1:],[]) - if self.getTestResult(complement): - return self.delta(complement, sets[:i] + sets[i+1:]) - -### - -class Token(object): - def __init__(self, type, data, flags, file, line, column): - self.type = type - self.data = data - self.flags = flags - self.file = file - self.line = line - self.column = column - -kTokenRE = re.compile(r"""([a-z_]+) '(.*)'\t(.*)\tLoc=<(.*):(.*):(.*)>""", - re.DOTALL | re.MULTILINE) - -def getTokens(path): - p = subprocess.Popen(['clang','-dump-raw-tokens',path], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - out,err = p.communicate() - - tokens = [] - collect = None - for ln in err.split('\n'): - # Silly programmers refuse to print in simple machine readable - # formats. Whatever. - if collect is None: - collect = ln - else: - collect = collect + '\n' + ln - if 'Loc=<' in ln and ln.endswith('>'): - ln,collect = collect,None - tokens.append(Token(*kTokenRE.match(ln).groups())) - - return tokens - -### - -class TMBDDelta(DeltaAlgorithm): - def __init__(self, testProgram, tokenLists, log): - def patchName(name, suffix): - base,ext = os.path.splitext(name) - return base + '.' + suffix + ext - super(TMBDDelta, self).__init__() - self.testProgram = testProgram - self.tokenLists = tokenLists - self.tempFiles = [patchName(f,'tmp') - for f,_ in self.tokenLists] - self.targetFiles = [patchName(f,'ok') - for f,_ in self.tokenLists] - self.log = log - self.numTests = 0 - - def writeFiles(self, changes, fileNames): - assert len(fileNames) == len(self.tokenLists) - byFile = [[] for i in self.tokenLists] - for i,j in changes: - byFile[i].append(j) - - for i,(file,tokens) in enumerate(self.tokenLists): - f = open(fileNames[i],'w') - for j in byFile[i]: - f.write(tokens[j]) - f.close() - - return byFile - - def test(self, changes): - self.numTests += 1 - - byFile = self.writeFiles(changes, self.tempFiles) - - if self.log: - print('TEST - ', end=' ', file=sys.stderr) - if self.log > 1: - for i,(file,_) in enumerate(self.tokenLists): - indices = byFile[i] - if i: - sys.stderr.write('\n ') - sys.stderr.write('%s:%d tokens: [' % (file,len(byFile[i]))) - prev = None - for j in byFile[i]: - if prev is None or j != prev + 1: - if prev: - sys.stderr.write('%d][' % prev) - sys.stderr.write(str(j)) - sys.stderr.write(':') - prev = j - if byFile[i]: - sys.stderr.write(str(byFile[i][-1])) - sys.stderr.write('] ') - else: - print(', '.join(['%s:%d tokens' % (file, len(byFile[i])) - for i,(file,_) in enumerate(self.tokenLists)]), end=' ', file=sys.stderr) - - p = subprocess.Popen([self.testProgram] + self.tempFiles) - res = p.wait() == 0 - - if res: - self.writeFiles(changes, self.targetFiles) - - if self.log: - print('=> %s' % res, file=sys.stderr) - else: - if res: - print('\nSUCCESS (%d tokens)' % len(changes)) - else: - sys.stderr.write('.') - - return res - - def run(self): - res = super(TMBDDelta, self).run([(i,j) - for i,(file,tokens) in enumerate(self.tokenLists) - for j in range(len(tokens))]) - self.writeFiles(res, self.targetFiles) - if not self.log: - print(file=sys.stderr) - return res - -def tokenBasedMultiDelta(program, files, log): - # Read in the lists of tokens. - tokenLists = [(file, [t.data for t in getTokens(file)]) - for file in files] - - numTokens = sum([len(tokens) for _,tokens in tokenLists]) - print("Delta on %s with %d tokens." % (', '.join(files), numTokens)) - - tbmd = TMBDDelta(program, tokenLists, log) - - res = tbmd.run() - - print("Finished %s with %d tokens (in %d tests)." % (', '.join(tbmd.targetFiles), - len(res), - tbmd.numTests)) - -def main(): - from optparse import OptionParser, OptionGroup - parser = OptionParser("%prog <test program> {files+}") - parser.add_option("", "--debug", dest="debugLevel", - help="set debug level [default %default]", - action="store", type=int, default=0) - (opts, args) = parser.parse_args() - - if len(args) <= 1: - parser.error('Invalid number of arguments.') - - program,files = args[0],args[1:] - - md = tokenBasedMultiDelta(program, files, log=opts.debugLevel) - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - print('Interrupted.', file=sys.stderr) - os._exit(1) # Avoid freeing our giant cache. diff --git a/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp b/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp deleted file mode 100644 index b8ba7f329eb9..000000000000 --- a/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp +++ /dev/null @@ -1,30 +0,0 @@ -{ - libstdcxx_overlapped_memcpy_in_stable_sort_1 - Memcheck:Overlap - fun:memcpy - ... - fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm5ValueEjESt6vectorIS7_SaIS7_EEEEN12_GLOBAL__N_116CstSortPredicateEEvT_SF_T0_ -} - -{ - libstdcxx_overlapped_memcpy_in_stable_sort_2 - Memcheck:Overlap - fun:memcpy - ... - fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm5ValueEjESt6vectorIS7_SaIS7_EEEEN12_GLOBAL__N_116CstSortPredicateEEvT_SF_T0_ -} - -{ - libstdcxx_overlapped_memcpy_in_stable_sort_3 - Memcheck:Overlap - fun:memcpy - ... - fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm4TypeEjESt6vectorIS7_SaIS7_EEEEPFbRKS7_SE_EEvT_SH_T0_ -} - -# Remove this if clang-vg didn't use "check-all" -{ - We don't care of cmp - Memcheck:Cond - obj:/usr/bin/cmp -} |