diff options
Diffstat (limited to 'utils')
30 files changed, 798 insertions, 940 deletions
diff --git a/utils/C++Tests/Clang-Code-Compile/lit.local.cfg b/utils/C++Tests/Clang-Code-Compile/lit.local.cfg deleted file mode 100644 index 59d3466..0000000 --- a/utils/C++Tests/Clang-Code-Compile/lit.local.cfg +++ /dev/null @@ -1,26 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -cxxflags = ['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-Wno-sign-compare', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root, - '-I%s/tools/clang/include' % root.llvm_src_root, - '-I%s/tools/clang/include' % root.llvm_obj_root] -config.test_format = \ - lit.formats.OneCommandPerFileTest(command=[root.clang, '-emit-llvm', '-c', - '-o', '/dev/null'] + cxxflags, - dir='%s/tools/clang/lib' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.cpp)$') - diff --git a/utils/C++Tests/Clang-Code-Syntax/lit.local.cfg b/utils/C++Tests/Clang-Code-Syntax/lit.local.cfg deleted file mode 100644 index 8f00c8d..0000000 --- a/utils/C++Tests/Clang-Code-Syntax/lit.local.cfg +++ /dev/null @@ -1,25 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -cxxflags = ['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-Wno-sign-compare', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root, - '-I%s/tools/clang/include' % root.llvm_src_root, - '-I%s/tools/clang/include' % root.llvm_obj_root] -config.test_format = \ - lit.formats.OneCommandPerFileTest(command=[root.clang, - '-fsyntax-only'] + cxxflags, - dir='%s/tools/clang/lib' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.cpp)$') diff --git a/utils/C++Tests/Clang-Syntax/lit.local.cfg b/utils/C++Tests/Clang-Syntax/lit.local.cfg deleted file mode 100644 index 89fdd8e..0000000 --- a/utils/C++Tests/Clang-Syntax/lit.local.cfg +++ /dev/null @@ -1,24 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.SyntaxCheckTest(compiler=root.clang, - dir='%s/tools/clang/include/clang' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.h)$', - extra_cxx_args=['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-Wno-sign-compare', - '-Werror', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root, - '-I%s/tools/clang/include' % root.llvm_src_root, - '-I%s/tools/clang/include' % root.llvm_obj_root]) diff --git a/utils/C++Tests/LLVM-Code-Compile/lit.local.cfg b/utils/C++Tests/LLVM-Code-Compile/lit.local.cfg deleted file mode 100644 index c1ac6a9..0000000 --- a/utils/C++Tests/LLVM-Code-Compile/lit.local.cfg +++ /dev/null @@ -1,48 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -target_obj_root = root.llvm_obj_root -cxxflags = ['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-Wno-sign-compare', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root, - '-I%s/lib/Target/ARM' % root.llvm_src_root, - '-I%s/lib/Target/CellSPU' % root.llvm_src_root, - '-I%s/lib/Target/CppBackend' % root.llvm_src_root, - '-I%s/lib/Target/Mips' % root.llvm_src_root, - '-I%s/lib/Target/MSIL' % root.llvm_src_root, - '-I%s/lib/Target/MSP430' % root.llvm_src_root, - '-I%s/lib/Target/PIC16' % root.llvm_src_root, - '-I%s/lib/Target/PowerPC' % root.llvm_src_root, - '-I%s/lib/Target/Sparc' % root.llvm_src_root, - '-I%s/lib/Target/X86' % root.llvm_src_root, - '-I%s/lib/Target/XCore' % root.llvm_src_root, - '-I%s/lib/Target/ARM' % target_obj_root, - '-I%s/lib/Target/CellSPU' % target_obj_root, - '-I%s/lib/Target/CppBackend' % target_obj_root, - '-I%s/lib/Target/Mips' % target_obj_root, - '-I%s/lib/Target/MSIL' % target_obj_root, - '-I%s/lib/Target/MSP430' % target_obj_root, - '-I%s/lib/Target/PIC16' % target_obj_root, - '-I%s/lib/Target/PowerPC' % target_obj_root, - '-I%s/lib/Target/Sparc' % target_obj_root, - '-I%s/lib/Target/X86' % target_obj_root, - '-I%s/lib/Target/XCore' % target_obj_root]; - -config.test_format = \ - lit.formats.OneCommandPerFileTest(command=[root.clang, '-emit-llvm', '-c', - '-o', '/dev/null'] + cxxflags, - dir='%s/lib' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.cpp)$') - diff --git a/utils/C++Tests/LLVM-Code-Symbols/check-symbols b/utils/C++Tests/LLVM-Code-Symbols/check-symbols deleted file mode 100755 index cd54eed..0000000 --- a/utils/C++Tests/LLVM-Code-Symbols/check-symbols +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python - -import subprocess -import difflib - -def capture_2(args0, args1): - import subprocess - p0 = subprocess.Popen(args0, stdin=None, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - p1 = subprocess.Popen(args1, stdin=p0.stdout, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - out,_ = p1.communicate() - return out - -def normalize_nm(data): - lines = data.split('\n') - lines.sort() - - # FIXME: Ignore common symbols for now. - lines = [ln for ln in lines - if not ln.startswith(' C')] - - return lines - -def main(): - import sys - clang = sys.argv[1] - flags = sys.argv[2:] - - # FIXME: Relax to include undefined symbols. - nm_args = ["llvm-nm", "-extern-only", "-defined-only"] - - llvmgcc_args = ["llvm-gcc"] + flags + ["-emit-llvm","-c","-o","-"] - clang_args = [clang] + flags + ["-emit-llvm","-c","-o","-"] - - llvmgcc_nm = capture_2(llvmgcc_args, nm_args) - clang_nm = capture_2(clang_args, nm_args) - - llvmgcc_nm = normalize_nm(llvmgcc_nm) - clang_nm = normalize_nm(clang_nm) - - if llvmgcc_nm == clang_nm: - sys.exit(0) - - print ' '.join(llvmgcc_args), '|', ' '.join(nm_args) - print ' '.join(clang_args), '|', ' '.join(nm_args) - for line in difflib.unified_diff(llvmgcc_nm, clang_nm, - fromfile="llvm-gcc symbols", - tofile="clang symbols"): - print line - sys.exit(1) - -if __name__ == '__main__': - main() diff --git a/utils/C++Tests/LLVM-Code-Symbols/lit.local.cfg b/utils/C++Tests/LLVM-Code-Symbols/lit.local.cfg deleted file mode 100644 index 7882813..0000000 --- a/utils/C++Tests/LLVM-Code-Symbols/lit.local.cfg +++ /dev/null @@ -1,48 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -target_obj_root = root.llvm_obj_root -cxxflags = ['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-Wno-sign-compare', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root, - '-I%s/lib/Target/ARM' % root.llvm_src_root, - '-I%s/lib/Target/CellSPU' % root.llvm_src_root, - '-I%s/lib/Target/CppBackend' % root.llvm_src_root, - '-I%s/lib/Target/Mips' % root.llvm_src_root, - '-I%s/lib/Target/MSIL' % root.llvm_src_root, - '-I%s/lib/Target/MSP430' % root.llvm_src_root, - '-I%s/lib/Target/PIC16' % root.llvm_src_root, - '-I%s/lib/Target/PowerPC' % root.llvm_src_root, - '-I%s/lib/Target/Sparc' % root.llvm_src_root, - '-I%s/lib/Target/X86' % root.llvm_src_root, - '-I%s/lib/Target/XCore' % root.llvm_src_root, - '-I%s/lib/Target/ARM' % target_obj_root, - '-I%s/lib/Target/CellSPU' % target_obj_root, - '-I%s/lib/Target/CppBackend' % target_obj_root, - '-I%s/lib/Target/Mips' % target_obj_root, - '-I%s/lib/Target/MSIL' % target_obj_root, - '-I%s/lib/Target/MSP430' % target_obj_root, - '-I%s/lib/Target/PIC16' % target_obj_root, - '-I%s/lib/Target/PowerPC' % target_obj_root, - '-I%s/lib/Target/Sparc' % target_obj_root, - '-I%s/lib/Target/X86' % target_obj_root, - '-I%s/lib/Target/XCore' % target_obj_root]; - -kScript = os.path.join(os.path.dirname(__file__), "check-symbols") -config.test_format = \ - lit.formats.OneCommandPerFileTest(command=[kScript, root.clang] + cxxflags, - dir='%s/lib' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.cpp)$') - diff --git a/utils/C++Tests/LLVM-Code-Syntax/lit.local.cfg b/utils/C++Tests/LLVM-Code-Syntax/lit.local.cfg deleted file mode 100644 index 42bec2d..0000000 --- a/utils/C++Tests/LLVM-Code-Syntax/lit.local.cfg +++ /dev/null @@ -1,46 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -target_obj_root = root.llvm_obj_root -cxxflags = ['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root, - '-I%s/lib/Target/ARM' % root.llvm_src_root, - '-I%s/lib/Target/CellSPU' % root.llvm_src_root, - '-I%s/lib/Target/CppBackend' % root.llvm_src_root, - '-I%s/lib/Target/Mips' % root.llvm_src_root, - '-I%s/lib/Target/MSIL' % root.llvm_src_root, - '-I%s/lib/Target/MSP430' % root.llvm_src_root, - '-I%s/lib/Target/PIC16' % root.llvm_src_root, - '-I%s/lib/Target/PowerPC' % root.llvm_src_root, - '-I%s/lib/Target/Sparc' % root.llvm_src_root, - '-I%s/lib/Target/X86' % root.llvm_src_root, - '-I%s/lib/Target/XCore' % root.llvm_src_root, - '-I%s/lib/Target/ARM' % target_obj_root, - '-I%s/lib/Target/CellSPU' % target_obj_root, - '-I%s/lib/Target/CppBackend' % target_obj_root, - '-I%s/lib/Target/Mips' % target_obj_root, - '-I%s/lib/Target/MSIL' % target_obj_root, - '-I%s/lib/Target/MSP430' % target_obj_root, - '-I%s/lib/Target/PIC16' % target_obj_root, - '-I%s/lib/Target/PowerPC' % target_obj_root, - '-I%s/lib/Target/Sparc' % target_obj_root, - '-I%s/lib/Target/X86' % target_obj_root, - '-I%s/lib/Target/XCore' % target_obj_root]; - -config.test_format = \ - lit.formats.OneCommandPerFileTest(command=[root.clang, - '-fsyntax-only'] + cxxflags, - dir='%s/lib' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.cpp)$') diff --git a/utils/C++Tests/LLVM-Syntax/lit.local.cfg b/utils/C++Tests/LLVM-Syntax/lit.local.cfg deleted file mode 100644 index cb0e566..0000000 --- a/utils/C++Tests/LLVM-Syntax/lit.local.cfg +++ /dev/null @@ -1,24 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.SyntaxCheckTest(compiler=root.clang, - dir='%s/include/llvm' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.h|[^.]*)$', - extra_cxx_args=['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-Werror', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root]) - -config.excludes = ['AbstractTypeUser.h', 'DAGISelHeader.h', - 'AIXDataTypesFix.h', 'Solaris.h'] diff --git a/utils/C++Tests/lit.cfg b/utils/C++Tests/lit.cfg deleted file mode 100644 index 274ca10..0000000 --- a/utils/C++Tests/lit.cfg +++ /dev/null @@ -1,27 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -# Load the main clang test config so we can leech its clang finding logic. -lit.load_config(config, os.path.join(os.path.dirname(__file__), - '..', '..', 'test', 'lit.cfg')) -assert config.clang, "Failed to set clang!?" - -# name: The name of this test suite. -config.name = 'Clang++' - -# suffixes: A list of file extensions to treat as test files, this is actually -# set by on_clone(). -config.suffixes = [] - -# Reset these from the Clang config. -config.test_source_root = config.test_exec_root = None - -# Don't run Clang and LLVM code checks by default. -config.excludes = [] -if not lit.params.get('run_clang_all'): - config.excludes.append('Clang-Code-Syntax') - config.excludes.append('Clang-Code-Compile') - config.excludes.append('LLVM-Code-Syntax') - config.excludes.append('LLVM-Code-Compile') - config.excludes.append('LLVM-Code-Symbols') diff --git a/utils/C++Tests/stdc++-Syntax/lit.local.cfg b/utils/C++Tests/stdc++-Syntax/lit.local.cfg deleted file mode 100644 index eb04866..0000000 --- a/utils/C++Tests/stdc++-Syntax/lit.local.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.SyntaxCheckTest(compiler=root.clang, - dir='/usr/include/c++/4.2.1', - recursive=False, - pattern='^(.*\\.h|[^.]*)$') - diff --git a/utils/ClangDataFormat.py b/utils/ClangDataFormat.py index ec44d2a..38ef76b 100644 --- a/utils/ClangDataFormat.py +++ b/utils/ClangDataFormat.py @@ -16,38 +16,86 @@ After that, instead of getting this: you'll get: (lldb) p Tok.Loc -(clang::SourceLocation) $4 = "/usr/include/i386/_types.h:37:1" (offset: 123582, file) +(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): - desc = "(offset: %d, %s)" % (self.offset(), "macro" if self.isMacro() else "file") - srcmgr_path = findObjectExpressionPath("clang::SourceManager", lldb.frame) + if self.isInvalid(): + return "<invalid loc>" + srcmgr_path = findObjectExpressionPath("clang::SourceManager", self.frame) if srcmgr_path: - desc = self.getPrint(srcmgr_path) + " " + desc + 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 = {} @@ -105,7 +153,7 @@ def findObject(typename, frame): return found if not found.TypeIsPointerType() else found.Dereference() def getValueFromExpression(val, expr): - return lldb.frame.EvaluateExpression(getExpressionPath(val) + expr) + return val.GetFrame().EvaluateExpression(getExpressionPath(val) + expr) def getExpressionPath(val): stream = lldb.SBStream() diff --git a/utils/OptionalTests/Extra/README.txt b/utils/OptionalTests/Extra/README.txt deleted file mode 100644 index 565241b..0000000 --- a/utils/OptionalTests/Extra/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -This directory is for extra unit style tests following the structure of -clang/tests, but which are not portable or not suitable for inclusion in the -regular test suite. diff --git a/utils/OptionalTests/Extra/Runtime/darwin-clang_rt.c b/utils/OptionalTests/Extra/Runtime/darwin-clang_rt.c deleted file mode 100644 index e527789..0000000 --- a/utils/OptionalTests/Extra/Runtime/darwin-clang_rt.c +++ /dev/null @@ -1,338 +0,0 @@ -/* This file tests that we can successfully call each compiler-rt function. It is - designed to check that the runtime libraries are available for linking and - that they contain the expected contents. It is not designed to test the - correctness of the individual functions in compiler-rt. - - This test is assumed to be run on a 10.6 machine. The two environment - variables below should be set to 10.4 and 10.5 machines which can be directly - ssh/rsync'd to in order to actually test the executables can run on the - desired targets. -*/ - -// RUN: export TENFOUR_X86_MACHINE=localhost -// RUN: export TENFIVE_X86_MACHINE=localhost -// RUN: export ARM_MACHINE=localhost -// RUN: export ARM_SYSROOT=$(xcodebuild -sdk iphoneos -version Path) - -// RUN: echo iPhoneOS, ARM, v6, thumb -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mthumb -c %s -o %t.o -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mthumb -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out -// RUN: ssh $ARM_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo iPhoneOS, ARM, v6, no-thumb -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mno-thumb -c %s -o %t.o -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mno-thumb -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out -// RUN: ssh $ARM_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo iPhoneOS, ARM, v7, thumb -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mthumb -c %s -o %t.o -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mthumb -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out -// RUN: ssh $ARM_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo iPhoneOS, ARM, v7, no-thumb -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mno-thumb -c %s -o %t.o -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mno-thumb -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out -// RUN: ssh $ARM_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo 10.4, i386 -// RUN: %clang -arch i386 -mmacosx-version-min=10.4 -c %s -o %t.o -// RUN: %clang -arch i386 -mmacosx-version-min=10.4 -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: %t -// RUN: echo - -// RUN: rsync -arv %t $TENFOUR_X86_MACHINE:/tmp/a.out -// RUN: ssh $TENFOUR_X86_MACHINE /tmp/a.out -// RUN: echo - -// RUX: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out -// RUX: ssh $TENFIVE_X86_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo 10.5, i386 -// RUN: %clang -arch i386 -mmacosx-version-min=10.5 -c %s -o %t.o -// RUN: %clang -arch i386 -mmacosx-version-min=10.5 -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: %t -// RUN: echo - -// RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out -// RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo 10.6, i386 -// RUN: %clang -arch i386 -mmacosx-version-min=10.6 -c %s -o %t.o -// RUN: %clang -arch i386 -mmacosx-version-min=10.6 -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: %t -// RUN: echo - -// RUN: echo 10.4, x86_64 -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.4 -c %s -o %t.o -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.4 -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: %t -// RUN: echo - -// RUN: rsync -arv %t $TENFOUR_X86_MACHINE:/tmp/a.out -// RUN: ssh $TENFOUR_X86_MACHINE /tmp/a.out -// RUN: echo - -// RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out -// RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo 10.5, x86_64 -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.5 -c %s -o %t.o -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.5 -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: %t -// RUN: echo - -// RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out -// RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo 10.6, x86_64 -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.6 -c %s -o %t.o -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.6 -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: %t -// RUN: echo - -#include <assert.h> -#include <stdio.h> -#include <sys/utsname.h> - -typedef int si_int; -typedef unsigned su_int; - -typedef long long di_int; -typedef unsigned long long du_int; - -// Integral bit manipulation - -di_int __ashldi3(di_int a, si_int b); // a << b -di_int __ashrdi3(di_int a, si_int b); // a >> b arithmetic (sign fill) -di_int __lshrdi3(di_int a, si_int b); // a >> b logical (zero fill) - -si_int __clzsi2(si_int a); // count leading zeros -si_int __clzdi2(di_int a); // count leading zeros -si_int __ctzsi2(si_int a); // count trailing zeros -si_int __ctzdi2(di_int a); // count trailing zeros - -si_int __ffsdi2(di_int a); // find least significant 1 bit - -si_int __paritysi2(si_int a); // bit parity -si_int __paritydi2(di_int a); // bit parity - -si_int __popcountsi2(si_int a); // bit population -si_int __popcountdi2(di_int a); // bit population - -// Integral arithmetic - -di_int __negdi2 (di_int a); // -a -di_int __muldi3 (di_int a, di_int b); // a * b -di_int __divdi3 (di_int a, di_int b); // a / b signed -du_int __udivdi3 (du_int a, du_int b); // a / b unsigned -di_int __moddi3 (di_int a, di_int b); // a % b signed -du_int __umoddi3 (du_int a, du_int b); // a % b unsigned -du_int __udivmoddi4(du_int a, du_int b, du_int* rem); // a / b, *rem = a % b - -// Integral arithmetic with trapping overflow - -si_int __absvsi2(si_int a); // abs(a) -di_int __absvdi2(di_int a); // abs(a) - -si_int __negvsi2(si_int a); // -a -di_int __negvdi2(di_int a); // -a - -si_int __addvsi3(si_int a, si_int b); // a + b -di_int __addvdi3(di_int a, di_int b); // a + b - -si_int __subvsi3(si_int a, si_int b); // a - b -di_int __subvdi3(di_int a, di_int b); // a - b - -si_int __mulvsi3(si_int a, si_int b); // a * b -di_int __mulvdi3(di_int a, di_int b); // a * b - -// Integral comparison: a < b -> 0 -// a == b -> 1 -// a > b -> 2 - -si_int __cmpdi2 (di_int a, di_int b); -si_int __ucmpdi2(du_int a, du_int b); - -// Integral / floating point conversion - -di_int __fixsfdi( float a); -di_int __fixdfdi( double a); -di_int __fixxfdi(long double a); - -su_int __fixunssfsi( float a); -su_int __fixunsdfsi( double a); -su_int __fixunsxfsi(long double a); - -du_int __fixunssfdi( float a); -du_int __fixunsdfdi( double a); -du_int __fixunsxfdi(long double a); - -float __floatdisf(di_int a); -double __floatdidf(di_int a); -long double __floatdixf(di_int a); - -float __floatundisf(du_int a); -double __floatundidf(du_int a); -long double __floatundixf(du_int a); - -// Floating point raised to integer power - -float __powisf2( float a, si_int b); // a ^ b -double __powidf2( double a, si_int b); // a ^ b -long double __powixf2(long double a, si_int b); // a ^ b - -// Complex arithmetic - -// (a + ib) * (c + id) - - float _Complex __mulsc3( float a, float b, float c, float d); - double _Complex __muldc3(double a, double b, double c, double d); -long double _Complex __mulxc3(long double a, long double b, - long double c, long double d); - -// (a + ib) / (c + id) - - float _Complex __divsc3( float a, float b, float c, float d); - double _Complex __divdc3(double a, double b, double c, double d); -long double _Complex __divxc3(long double a, long double b, - long double c, long double d); - -#ifndef __arm -#define HAS_LONG_DOUBLE -#endif - -int main(int argc, char **argv) { - du_int du_tmp; - struct utsname name; -#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ - const char *target_name = "OS X"; - unsigned target_version = __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__; - unsigned target_maj = target_version / 100; - unsigned target_min = (target_version / 10) % 10; - unsigned target_micro = target_version % 10; -#else - const char *target_name = "iPhoneOS"; - unsigned target_version = __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__; - unsigned target_maj = target_version / 10000; - unsigned target_min = (target_version / 100) % 100; - unsigned target_micro = target_version % 100; -#endif - - if (uname(&name)) - return 1; - - fprintf(stderr, "%s: clang_rt test:\n", argv[0]); - fprintf(stderr, " target : %s %d.%d.%d\n\n", target_name, - target_maj, target_min, target_micro); - fprintf(stderr, " sysname : %s\n", name.sysname); - fprintf(stderr, " nodename: %s\n", name.nodename); - fprintf(stderr, " release : %s\n", name.release); - fprintf(stderr, " version : %s\n", name.version); - fprintf(stderr, " machine : %s\n", name.machine); - - assert(__ashldi3(1, 1) == 2); - assert(__ashrdi3(2, 1) == 1); - assert(__lshrdi3(2, 1) == 1); - assert(__clzsi2(1) == 31); - assert(__clzdi2(1) == 63); - assert(__ctzsi2(2) == 1); - assert(__ctzdi2(2) == 1); - assert(__ffsdi2(12) == 3); - assert(__paritysi2(13) == 1); - assert(__paritydi2(13) == 1); - assert(__popcountsi2(13) == 3); - assert(__popcountdi2(13) == 3); - assert(__negdi2(3) == -3); - assert(__muldi3(2,2) == 4); - assert(__divdi3(-4,2) == -2); - assert(__udivdi3(4,2) == 2); - assert(__moddi3(3,2) == 1); - assert(__umoddi3(3,2) == 1); - assert(__udivmoddi4(5,2,&du_tmp) == 2 && du_tmp == 1); - assert(__absvsi2(-2) == 2); - assert(__absvdi2(-2) == 2); - assert(__negvsi2(2) == -2); - assert(__negvdi2(2) == -2); - assert(__addvsi3(2, 3) == 5); - assert(__addvdi3(2, 3) == 5); - assert(__subvsi3(2, 3) == -1); - assert(__subvdi3(2, 3) == -1); - assert(__mulvsi3(2, 3) == 6); - assert(__mulvdi3(2, 3) == 6); - assert(__cmpdi2(3, 2) == 2); - assert(__ucmpdi2(3, 2) == 2); - assert(__fixsfdi(2.0) == 2); - assert(__fixdfdi(2.0) == 2); - assert(__fixunssfsi(2.0) == 2); - assert(__fixunsdfsi(2.0) == 2); - assert(__fixunssfdi(2.0) == 2); - assert(__fixunsdfdi(2.0) == 2); - assert(__floatdisf(2) == 2.0); - assert(__floatdidf(2) == 2.0); - assert(__floatundisf(2) == 2.0); - assert(__floatundidf(2) == 2.0); - assert(__powisf2(2.0, 2) == 4.0); - assert(__powidf2(2.0, 2) == 4.0); - - // FIXME: Clang/LLVM seems to be miscompiling _Complex currently, probably an - // ABI issue. -#ifndef __arm - { - _Complex float a = __mulsc3(1.0, 2.0, 4.0, 8.0); - _Complex float b = (-12.0 + 16.0j); - fprintf(stderr, "a: (%f + %f), b: (%f + %f)\n", - __real a, __imag a, __real b, __imag b); - } - assert(__mulsc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j)); - assert(__muldc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j)); - assert(__divsc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j)); - assert(__divdc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j)); -#endif - -#ifdef HAS_LONG_DOUBLE - assert(__divxc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j)); - assert(__fixunsxfdi(2.0) == 2); - assert(__fixunsxfsi(2.0) == 2); - assert(__fixxfdi(2.0) == 2); - assert(__floatdixf(2) == 2.0); - assert(__floatundixf(2) == 2); - assert(__mulxc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j)); - assert(__powixf2(2.0, 2) == 4.0); -#endif - - // Test some calls which are used on armv6/thumb. The calls/prototypes are - // fake, it would be nice to test correctness, but mostly we just want to - // make sure we resolve symbols correctly. -#if defined(__arm) && defined(__ARM_ARCH_6K__) && defined(__thumb__) - if (argc == 100) { - extern void __restore_vfp_d8_d15_regs(void), __save_vfp_d8_d15_regs(void); - extern void __switch8(void), __switchu8(void), - __switch16(void), __switch32(void); - extern void __addsf3vfp(void); - - __addsf3vfp(); - __restore_vfp_d8_d15_regs(); - __save_vfp_d8_d15_regs(); - __switch8(); - __switchu8(); - __switch16(); - __switch32(); - } -#endif - - fprintf(stderr, " OK!\n"); - - return 0; -} diff --git a/utils/OptionalTests/README.txt b/utils/OptionalTests/README.txt deleted file mode 100644 index 4ffdb3b..0000000 --- a/utils/OptionalTests/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -This is a dumping ground for additional tests which do not fit cleanly into the -clang regression tests. For example, tests which are not portable, require -additional software or configuration, take an excessive time to run, or are -flaky can be kept here. diff --git a/utils/OptionalTests/lit.cfg b/utils/OptionalTests/lit.cfg deleted file mode 100644 index 592c424..0000000 --- a/utils/OptionalTests/lit.cfg +++ /dev/null @@ -1,26 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -# Load the main clang test config so we can leech its clang finding logic. -lit.load_config(config, os.path.join(os.path.dirname(__file__), - '..', '..', 'test', 'lit.cfg')) -assert config.clang, "Failed to set clang!?" - -# name: The name of this test suite. -config.name = 'Clang-Opt-Tests' - -# suffixes: A list of file extensions to treat as test files. -config.suffixes = [] - -# Reset these from the Clang config. - -# test_source_root: The root path where tests are located. -config.test_source_root = os.path.dirname(__file__) - -# test_exec_root: The root path where tests should be run. -clang_obj_root = getattr(config, 'clang_obj_root', None) -if clang_obj_root is not None: - config.test_exec_root = os.path.join(clang_obj_root, 'utils', - 'OptionalTests') - diff --git a/utils/SummarizeErrors b/utils/SummarizeErrors deleted file mode 100755 index b6e9122..0000000 --- a/utils/SummarizeErrors +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env python - -import os, sys, re - -class multidict: - def __init__(self, elts=()): - self.data = {} - for key,value in elts: - self[key] = value - - def __getitem__(self, item): - return self.data[item] - def __setitem__(self, key, value): - if key in self.data: - self.data[key].append(value) - else: - self.data[key] = [value] - def items(self): - return self.data.items() - def values(self): - return self.data.values() - def keys(self): - return self.data.keys() - def __len__(self): - return len(self.data) - -kDiagnosticRE = re.compile(': (error|warning): (.*)') -kAssertionRE = re.compile('Assertion failed: (.*, function .*, file .*, line [0-9]+\\.)') - -def readInfo(path, opts): - lastProgress = [-100,0] - def progress(pos): - pct = (100. * pos) / (size * 2) - if (pct - lastProgress[0]) >= 10: - lastProgress[0] = pct - print '%d/%d = %.2f%%' % (pos, size*2, pct) - - f = open(path) - data = f.read() - f.close() - - if opts.truncate != -1: - data = data[:opts.truncate] - - size = len(data) - warnings = multidict() - errors = multidict() - for m in kDiagnosticRE.finditer(data): - progress(m.end()) - if m.group(1) == 'error': - d = errors - else: - d = warnings - d[m.group(2)] = m - warnings = warnings.items() - errors = errors.items() - assertions = multidict() - for m in kAssertionRE.finditer(data): - print '%d/%d = %.2f%%' % (size + m.end(), size, (float(m.end()) / (size*2)) * 100.) - assertions[m.group(1)] = m - assertions = assertions.items() - - # Manual scan for stack traces - aborts = multidict() - if 0: - prevLine = None - lnIter = iter(data.split('\n')) - for ln in lnIter: - m = kStackDumpLineRE.match(ln) - if m: - stack = [m.group(2)] - for ln in lnIter: - m = kStackDumpLineRE.match(ln) - if not m: - break - stack.append(m.group(2)) - if prevLine is None or not kAssertionRE.match(prevLine): - aborts[tuple(stack)] = stack - prevLine = ln - - sections = [ - (warnings, 'Warnings'), - (errors, 'Errors'), - (assertions, 'Assertions'), - (aborts.items(), 'Aborts'), - ] - - if opts.ascending: - sections.reverse() - - for l,title in sections: - l.sort(key = lambda (a,b): -len(b)) - if l: - print '-- %d %s (%d kinds) --' % (sum([len(b) for a,b in l]), title, len(l)) - for name,elts in l: - print '%5d:' % len(elts), name - -def main(): - global options - from optparse import OptionParser - parser = OptionParser("usage: %prog [options] {inputs}") - parser.add_option("", "--ascending", dest="ascending", - help="Print output in ascending order of severity.", - action="store_true", default=False) - parser.add_option("", "--truncate", dest="truncate", - help="Truncate input file (for testing).", - type=int, action="store", default=-1) - (opts, args) = parser.parse_args() - - if not args: - parser.error('No inputs specified') - - for arg in args: - readInfo(arg, opts) - -if __name__=='__main__': - main() diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt index 534ac9a..a858a21 100644 --- a/utils/TableGen/CMakeLists.txt +++ b/utils/TableGen/CMakeLists.txt @@ -4,6 +4,7 @@ add_tablegen(clang-tblgen CLANG ClangASTNodesEmitter.cpp ClangAttrEmitter.cpp ClangCommentCommandInfoEmitter.cpp + ClangCommentHTMLNamedCharacterReferenceEmitter.cpp ClangCommentHTMLTagsEmitter.cpp ClangDiagnosticsEmitter.cpp ClangSACheckersEmitter.cpp diff --git a/utils/TableGen/ClangASTNodesEmitter.cpp b/utils/TableGen/ClangASTNodesEmitter.cpp index c51ca96..682f9c7 100644 --- a/utils/TableGen/ClangASTNodesEmitter.cpp +++ b/utils/TableGen/ClangASTNodesEmitter.cpp @@ -133,6 +133,8 @@ std::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode( } void ClangASTNodesEmitter::run(raw_ostream &OS) { + emitSourceFileHeader("List of AST nodes of a particular kind", OS); + // Write the preamble OS << "#ifndef ABSTRACT_" << macroName(Root.getName()) << "\n"; OS << "# define ABSTRACT_" << macroName(Root.getName()) << "(Type) Type\n"; @@ -183,6 +185,8 @@ void EmitClangASTNodes(RecordKeeper &RK, raw_ostream &OS, void EmitClangDeclContext(RecordKeeper &Records, raw_ostream &OS) { // FIXME: Find a .td file format to allow for this to be represented better. + emitSourceFileHeader("List of AST Decl nodes", OS); + OS << "#ifndef DECL_CONTEXT\n"; OS << "# define DECL_CONTEXT(DECL)\n"; OS << "#endif\n"; diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index 521f604..7c8603f 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -47,7 +47,7 @@ static std::string ReadPCHRecord(StringRef type) { .EndsWith("Decl *", "GetLocalDeclAs<" + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])") .Case("QualType", "getLocalType(F, Record[Idx++])") - .Case("Expr *", "ReadSubExpr()") + .Case("Expr *", "ReadExpr(F)") .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)") .Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)") .Default("Record[Idx++]"); @@ -125,6 +125,9 @@ namespace { virtual void writePCHReadDecls(raw_ostream &OS) const = 0; virtual void writePCHWrite(raw_ostream &OS) const = 0; virtual void writeValue(raw_ostream &OS) const = 0; + virtual void writeDump(raw_ostream &OS) const = 0; + virtual void writeDumpChildren(raw_ostream &OS) const {} + virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; } }; class SimpleArgument : public Argument { @@ -181,6 +184,28 @@ namespace { OS << "\" << get" << getUpperName() << "() << \""; } } + void writeDump(raw_ostream &OS) const { + if (type == "FunctionDecl *") { + OS << " OS << \" \";\n"; + OS << " dumpBareDeclRef(SA->get" << getUpperName() << "());\n"; + } else if (type == "IdentifierInfo *") { + OS << " OS << \" \" << SA->get" << getUpperName() + << "()->getName();\n"; + } else if (type == "QualType") { + OS << " OS << \" \" << SA->get" << getUpperName() + << "().getAsString();\n"; + } else if (type == "SourceLocation") { + OS << " OS << \" \";\n"; + OS << " SA->get" << getUpperName() << "().print(OS, *SM);\n"; + } else if (type == "bool") { + OS << " if (SA->get" << getUpperName() << "()) OS << \" " + << getUpperName() << "\";\n"; + } else if (type == "int" || type == "unsigned") { + OS << " OS << \" \" << SA->get" << getUpperName() << "();\n"; + } else { + llvm_unreachable("Unknown SimpleArgument type!"); + } + } }; class StringArgument : public Argument { @@ -241,6 +266,10 @@ namespace { void writeValue(raw_ostream &OS) const { OS << "\\\"\" << get" << getUpperName() << "() << \"\\\""; } + void writeDump(raw_ostream &OS) const { + OS << " OS << \" \\\"\" << SA->get" << getUpperName() + << "() << \"\\\"\";\n"; + } }; class AlignedArgument : public Argument { @@ -353,6 +382,19 @@ namespace { << " " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n" << " OS << \""; } + void writeDump(raw_ostream &OS) const { + } + void writeDumpChildren(raw_ostream &OS) const { + OS << " if (SA->is" << getUpperName() << "Expr()) {\n"; + OS << " lastChild();\n"; + OS << " dumpStmt(SA->get" << getUpperName() << "Expr());\n"; + OS << " } else\n"; + OS << " dumpType(SA->get" << getUpperName() + << "Type()->getType());\n"; + } + void writeHasChildren(raw_ostream &OS) const { + OS << "SA->is" << getUpperName() << "Expr()"; + } }; class VariadicArgument : public Argument { @@ -408,7 +450,7 @@ namespace { } void writePCHReadDecls(raw_ostream &OS) const { OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n"; - OS << " llvm::SmallVector<" << type << ", 4> " << getLowerName() + OS << " SmallVector<" << type << ", 4> " << getLowerName() << ";\n"; OS << " " << getLowerName() << ".reserve(" << getLowerName() << "Size);\n"; @@ -439,17 +481,30 @@ namespace { << " }\n"; OS << " OS << \""; } + void writeDump(raw_ostream &OS) const { + OS << " for (" << getAttrName() << "Attr::" << getLowerName() + << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->" + << getLowerName() << "_end(); I != E; ++I)\n"; + OS << " OS << \" \" << *I;\n"; + } }; class EnumArgument : public Argument { std::string type; - std::vector<StringRef> values, enums; + std::vector<StringRef> values, enums, uniques; public: EnumArgument(Record &Arg, StringRef Attr) : Argument(Arg, Attr), type(Arg.getValueAsString("Type")), values(getValueAsListOfStrings(Arg, "Values")), - enums(getValueAsListOfStrings(Arg, "Enums")) - {} + enums(getValueAsListOfStrings(Arg, "Enums")), + uniques(enums) + { + // Calculate the various enum values + std::sort(uniques.begin(), uniques.end()); + uniques.erase(std::unique(uniques.begin(), uniques.end()), uniques.end()); + // FIXME: Emit a proper error + assert(!uniques.empty()); + } void writeAccessors(raw_ostream &OS) const { OS << " " << type << " get" << getUpperName() << "() const {\n"; @@ -469,16 +524,8 @@ namespace { OS << type << " " << getUpperName(); } void writeDeclarations(raw_ostream &OS) const { - // Calculate the various enum values - std::vector<StringRef> uniques(enums); - std::sort(uniques.begin(), uniques.end()); - uniques.erase(std::unique(uniques.begin(), uniques.end()), - uniques.end()); - // FIXME: Emit a proper error - assert(!uniques.empty()); - - std::vector<StringRef>::iterator i = uniques.begin(), - e = uniques.end(); + std::vector<StringRef>::const_iterator i = uniques.begin(), + e = uniques.end(); // The last one needs to not have a comma. --e; @@ -505,6 +552,16 @@ namespace { void writeValue(raw_ostream &OS) const { OS << "\" << get" << getUpperName() << "() << \""; } + void writeDump(raw_ostream &OS) const { + OS << " switch(SA->get" << getUpperName() << "()) {\n"; + for (std::vector<StringRef>::const_iterator I = uniques.begin(), + E = uniques.end(); I != E; ++I) { + OS << " case " << getAttrName() << "Attr::" << *I << ":\n"; + OS << " OS << \" " << *I << "\";\n"; + OS << " break;\n"; + } + OS << " }\n"; + } }; class VersionArgument : public Argument { @@ -552,6 +609,9 @@ namespace { void writeValue(raw_ostream &OS) const { OS << getLowerName() << "=\" << get" << getUpperName() << "() << \""; } + void writeDump(raw_ostream &OS) const { + OS << " OS << \" \" << SA->get" << getUpperName() << "();\n"; + } }; class ExprArgument : public SimpleArgument { @@ -575,6 +635,15 @@ namespace { << "Result.takeAs<Expr>();\n"; OS << " }\n"; } + + void writeDump(raw_ostream &OS) const { + } + + void writeDumpChildren(raw_ostream &OS) const { + OS << " lastChild();\n"; + OS << " dumpStmt(SA->get" << getUpperName() << "());\n"; + } + void writeHasChildren(raw_ostream &OS) const { OS << "true"; } }; class VariadicExprArgument : public VariadicArgument { @@ -607,6 +676,24 @@ namespace { OS << " }\n"; OS << " }\n"; } + + void writeDump(raw_ostream &OS) const { + } + + void writeDumpChildren(raw_ostream &OS) const { + OS << " for (" << getAttrName() << "Attr::" << getLowerName() + << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->" + << getLowerName() << "_end(); I != E; ++I) {\n"; + OS << " if (I + 1 == E)\n"; + OS << " lastChild();\n"; + OS << " dumpStmt(*I);\n"; + OS << " }\n"; + } + + void writeHasChildren(raw_ostream &OS) const { + OS << "SA->" << getLowerName() << "_begin() != " + << "SA->" << getLowerName() << "_end()"; + } }; } @@ -663,11 +750,136 @@ static void writeAvailabilityValue(raw_ostream &OS) { << " OS << \""; } +static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args, + raw_ostream &OS) { + std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings"); + + OS << "void " << R.getName() << "Attr::printPretty(" + << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n"; + + if (Spellings.size() == 0) { + OS << "}\n\n"; + return; + } + + OS << + " switch (SpellingListIndex) {\n" + " default:\n" + " llvm_unreachable(\"Unknown attribute spelling!\");\n" + " break;\n"; + + for (unsigned I = 0; I < Spellings.size(); ++ I) { + llvm::SmallString<16> Prefix; + llvm::SmallString<8> Suffix; + // The actual spelling of the name and namespace (if applicable) + // of an attribute without considering prefix and suffix. + llvm::SmallString<64> Spelling; + std::string Name = Spellings[I]->getValueAsString("Name"); + std::string Variety = Spellings[I]->getValueAsString("Variety"); + + if (Variety == "GNU") { + Prefix = " __attribute__(("; + Suffix = "))"; + } else if (Variety == "CXX11") { + Prefix = " [["; + Suffix = "]]"; + std::string Namespace = Spellings[I]->getValueAsString("Namespace"); + if (Namespace != "") { + Spelling += Namespace; + Spelling += "::"; + } + } else if (Variety == "Declspec") { + Prefix = " __declspec("; + Suffix = ")"; + } else if (Variety == "Keyword") { + Prefix = " "; + Suffix = ""; + } else { + llvm_unreachable("Unknown attribute syntax variety!"); + } + + Spelling += Name; + + OS << + " case " << I << " : {\n" + " OS << \"" + Prefix.str() + Spelling.str(); + + if (Args.size()) OS << "("; + if (Spelling == "availability") { + writeAvailabilityValue(OS); + } else { + for (std::vector<Argument*>::const_iterator I = Args.begin(), + E = Args.end(); I != E; ++ I) { + if (I != Args.begin()) OS << ", "; + (*I)->writeValue(OS); + } + } + + if (Args.size()) OS << ")"; + OS << Suffix.str() + "\";\n"; + + OS << + " break;\n" + " }\n"; + } + + // End of the switch statement. + OS << "}\n"; + // End of the print function. + OS << "}\n\n"; +} + +/// \brief Return the index of a spelling in a spelling list. +static unsigned getSpellingListIndex(const std::vector<Record*> &SpellingList, + const Record &Spelling) { + assert(SpellingList.size() && "Spelling list is empty!"); + + for (unsigned Index = 0; Index < SpellingList.size(); ++Index) { + Record *S = SpellingList[Index]; + if (S->getValueAsString("Variety") != Spelling.getValueAsString("Variety")) + continue; + if (S->getValueAsString("Variety") == "CXX11" && + S->getValueAsString("Namespace") != + Spelling.getValueAsString("Namespace")) + continue; + if (S->getValueAsString("Name") != Spelling.getValueAsString("Name")) + continue; + + return Index; + } + + llvm_unreachable("Unknown spelling!"); +} + +static void writeAttrAccessorDefinition(Record &R, raw_ostream &OS) { + std::vector<Record*> Accessors = R.getValueAsListOfDefs("Accessors"); + for (std::vector<Record*>::const_iterator I = Accessors.begin(), + E = Accessors.end(); I != E; ++I) { + Record *Accessor = *I; + std::string Name = Accessor->getValueAsString("Name"); + std::vector<Record*> Spellings = Accessor->getValueAsListOfDefs( + "Spellings"); + std::vector<Record*> SpellingList = R.getValueAsListOfDefs("Spellings"); + assert(SpellingList.size() && + "Attribute with empty spelling list can't have accessors!"); + + OS << " bool " << Name << "() const { return SpellingListIndex == "; + for (unsigned Index = 0; Index < Spellings.size(); ++Index) { + OS << getSpellingListIndex(SpellingList, *Spellings[Index]); + if (Index != Spellings.size() -1) + OS << " ||\n SpellingListIndex == "; + else + OS << "; }\n"; + } + } +} + namespace clang { // Emits the class definitions for attributes. void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("Attribute classes' definitions", OS); + OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n"; OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n"; @@ -711,9 +923,12 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { (*ai)->writeCtorParameters(OS); OS << "\n"; } - + + OS << " , "; + OS << "unsigned SI = 0\n"; + OS << " )\n"; - OS << " : " << SuperName << "(attr::" << R.getName() << ", R)\n"; + OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n"; for (ai = Args.begin(); ai != ae; ++ai) { OS << " , "; @@ -730,9 +945,11 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { OS << " }\n\n"; OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n"; - OS << " virtual void printPretty(llvm::raw_ostream &OS," + OS << " virtual void printPretty(raw_ostream &OS,\n" << " const PrintingPolicy &Policy) const;\n"; + writeAttrAccessorDefinition(R, OS); + for (ai = Args.begin(); ai != ae; ++ai) { (*ai)->writeAccessors(OS); OS << "\n\n"; @@ -756,7 +973,7 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { // Emits the class method definitions for attributes. void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("Attribute classes' member function definitions", OS); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re; @@ -769,7 +986,6 @@ void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) { continue; std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); - std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings"); std::vector<Argument*> Args; for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri) Args.push_back(createArgument(**ri, R.getName())); @@ -784,26 +1000,9 @@ void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) { OS << ", "; (*ai)->writeCloneArgs(OS); } - OS << ");\n}\n\n"; + OS << ", getSpellingListIndex());\n}\n\n"; - OS << "void " << R.getName() << "Attr::printPretty(" - << "llvm::raw_ostream &OS, const PrintingPolicy &Policy) const {\n"; - if (Spellings.begin() != Spellings.end()) { - std::string Spelling = (*Spellings.begin())->getValueAsString("Name"); - OS << " OS << \" __attribute__((" << Spelling; - if (Args.size()) OS << "("; - if (Spelling == "availability") { - writeAvailabilityValue(OS); - } else { - for (ai = Args.begin(); ai != ae; ++ai) { - if (ai!=Args.begin()) OS <<", "; - (*ai)->writeValue(OS); - } - } - if (Args.size()) OS << ")"; - OS << "))\";\n"; - } - OS << "}\n\n"; + writePrettyPrintFunction(R, Args, OS); } } @@ -830,7 +1029,7 @@ namespace clang { // Emits the enumeration list for attributes. void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("List of all attributes that Clang recognizes", OS); OS << "#ifndef LAST_ATTR\n"; OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n"; @@ -853,10 +1052,20 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { " INHERITABLE_PARAM_ATTR(NAME)\n"; OS << "#endif\n\n"; + OS << "#ifndef MS_INHERITABLE_ATTR\n"; + OS << "#define MS_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n"; + OS << "#endif\n\n"; + + OS << "#ifndef LAST_MS_INHERITABLE_ATTR\n"; + OS << "#define LAST_MS_INHERITABLE_ATTR(NAME)" + " MS_INHERITABLE_ATTR(NAME)\n"; + OS << "#endif\n\n"; + Record *InhClass = Records.getClass("InheritableAttr"); Record *InhParamClass = Records.getClass("InheritableParamAttr"); + Record *MSInheritanceClass = Records.getClass("MSInheritanceAttr"); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), - NonInhAttrs, InhAttrs, InhParamAttrs; + NonInhAttrs, InhAttrs, InhParamAttrs, MSInhAttrs; for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i) { if (!(*i)->getValueAsBit("ASTNode")) @@ -864,6 +1073,8 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { if ((*i)->isSubClassOf(InhParamClass)) InhParamAttrs.push_back(*i); + else if ((*i)->isSubClassOf(MSInheritanceClass)) + MSInhAttrs.push_back(*i); else if ((*i)->isSubClassOf(InhClass)) InhAttrs.push_back(*i); else @@ -871,19 +1082,22 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { } EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs); + EmitAttrList(OS, "MS_INHERITABLE_ATTR", MSInhAttrs); EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs); EmitAttrList(OS, "ATTR", NonInhAttrs); OS << "#undef LAST_ATTR\n"; OS << "#undef INHERITABLE_ATTR\n"; + OS << "#undef MS_INHERITABLE_ATTR\n"; OS << "#undef LAST_INHERITABLE_ATTR\n"; OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n"; + OS << "#undef LAST_MS_INHERITABLE_ATTR\n"; OS << "#undef ATTR\n"; } // Emits the code to read an attribute from a precompiled header. void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("Attribute deserialization code", OS); Record *InhClass = Records.getClass("InheritableAttr"); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), @@ -927,6 +1141,8 @@ void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) { // Emits the code to write an attribute to a precompiled header. void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) { + emitSourceFileHeader("Attribute serialization code", OS); + Record *InhClass = Records.getClass("InheritableAttr"); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args; std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; @@ -956,7 +1172,8 @@ void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) { // Emits the list of spellings for attributes. void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("llvm::StringSwitch code to match all known attributes", + OS); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -972,9 +1189,70 @@ void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) { } +void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) { + emitSourceFileHeader("Code to translate different attribute spellings " + "into internal identifiers", OS); + + OS << + " unsigned Index = 0;\n" + " switch (AttrKind) {\n" + " default:\n" + " llvm_unreachable(\"Unknown attribute kind!\");\n" + " break;\n"; + + std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); + for (std::vector<Record*>::const_iterator I = Attrs.begin(), E = Attrs.end(); + I != E; ++I) { + Record &R = **I; + // We only care about attributes that participate in Sema checking, so + // skip those attributes that are not able to make their way to Sema. + if (!R.getValueAsBit("SemaHandler")) + continue; + + std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings"); + // Each distinct spelling yields an attribute kind. + if (R.getValueAsBit("DistinctSpellings")) { + for (unsigned I = 0; I < Spellings.size(); ++ I) { + OS << + " case AT_" << Spellings[I]->getValueAsString("Name") << ": \n" + " Index = " << I << ";\n" + " break;\n"; + } + } else { + OS << " case AT_" << R.getName() << " : {\n"; + for (unsigned I = 0; I < Spellings.size(); ++ I) { + SmallString<16> Namespace; + if (Spellings[I]->getValueAsString("Variety") == "CXX11") + Namespace = Spellings[I]->getValueAsString("Namespace"); + else + Namespace = ""; + + OS << " if (Name == \"" + << Spellings[I]->getValueAsString("Name") << "\" && " + << "SyntaxUsed == " + << StringSwitch<unsigned>(Spellings[I]->getValueAsString("Variety")) + .Case("GNU", 0) + .Case("CXX11", 1) + .Case("Declspec", 2) + .Case("Keyword", 3) + .Default(0) + << " && Scope == \"" << Namespace << "\")\n" + << " return " << I << ";\n"; + } + + OS << " break;\n"; + OS << " }\n"; + } + } + + OS << " }\n"; + OS << " return Index;\n"; +} + // Emits the LateParsed property for attributes. void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("llvm::StringSwitch code to match late parsed " + "attributes", OS); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -1002,7 +1280,7 @@ void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) { // Emits code to instantiate dependent attributes on templates. void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("Template instantiation code for attributes", OS); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -1075,8 +1353,8 @@ void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) { // Emits the list of parsed attributes. void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; - + emitSourceFileHeader("List of all attributes that Clang recognizes", OS); + OS << "#ifndef PARSED_ATTR\n"; OS << "#define PARSED_ATTR(NAME) NAME\n"; OS << "#endif\n\n"; @@ -1113,9 +1391,8 @@ void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) { // Emits the kind list of parsed attributes void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; - OS << "\n"; - + emitSourceFileHeader("Attribute name matcher", OS); + std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); std::vector<StringMatcher::StringPair> Matches; @@ -1163,4 +1440,56 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { << "}\n"; } +// Emits the code to dump an attribute. +void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) { + emitSourceFileHeader("Attribute dumper", OS); + + OS << + " switch (A->getKind()) {\n" + " default:\n" + " llvm_unreachable(\"Unknown attribute kind!\");\n" + " break;\n"; + std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args; + for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); + I != E; ++I) { + Record &R = **I; + if (!R.getValueAsBit("ASTNode")) + continue; + OS << " case attr::" << R.getName() << ": {\n"; + Args = R.getValueAsListOfDefs("Args"); + if (!Args.empty()) { + OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName() + << "Attr>(A);\n"; + for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end(); + I != E; ++I) + createArgument(**I, R.getName())->writeDump(OS); + + // Code for detecting the last child. + OS << " bool OldMoreChildren = hasMoreChildren();\n"; + OS << " bool MoreChildren = OldMoreChildren;\n"; + + for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end(); + I != E; ++I) { + // More code for detecting the last child. + OS << " MoreChildren = OldMoreChildren"; + for (std::vector<Record*>::iterator Next = I + 1; Next != E; ++Next) { + OS << " || "; + createArgument(**Next, R.getName())->writeHasChildren(OS); + } + OS << ";\n"; + OS << " setMoreChildren(MoreChildren);\n"; + + createArgument(**I, R.getName())->writeDumpChildren(OS); + } + + // Reset the last child. + OS << " setMoreChildren(OldMoreChildren);\n"; + } + OS << + " break;\n" + " }\n"; + } + OS << " }\n"; +} + } // end namespace clang diff --git a/utils/TableGen/ClangCommentCommandInfoEmitter.cpp b/utils/TableGen/ClangCommentCommandInfoEmitter.cpp index 36fbcd4..ebb0427 100644 --- a/utils/TableGen/ClangCommentCommandInfoEmitter.cpp +++ b/utils/TableGen/ClangCommentCommandInfoEmitter.cpp @@ -7,20 +7,22 @@ // //===----------------------------------------------------------------------===// // -// This tablegen backend emits command lists and efficient matchers command +// This tablegen backend emits command lists and efficient matchers for command // names that are used in documentation comments. // //===----------------------------------------------------------------------===// #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringMatcher.h" +#include "llvm/TableGen/TableGenBackend.h" #include <vector> using namespace llvm; namespace clang { void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("A list of commands useable in documentation " + "comments", OS); OS << "namespace {\n" "const CommandInfo Commands[] = {\n"; @@ -39,11 +41,15 @@ void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) { << Tag.getValueAsBit("IsParamCommand") << ", " << Tag.getValueAsBit("IsTParamCommand") << ", " << Tag.getValueAsBit("IsDeprecatedCommand") << ", " + << Tag.getValueAsBit("IsHeaderfileCommand") << ", " << Tag.getValueAsBit("IsEmptyParagraphAllowed") << ", " << Tag.getValueAsBit("IsVerbatimBlockCommand") << ", " << Tag.getValueAsBit("IsVerbatimBlockEndCommand") << ", " << Tag.getValueAsBit("IsVerbatimLineCommand") << ", " << Tag.getValueAsBit("IsDeclarationCommand") << ", " + << Tag.getValueAsBit("IsFunctionDeclarationCommand") << ", " + << Tag.getValueAsBit("IsRecordLikeDetailCommand") << ", " + << Tag.getValueAsBit("IsRecordLikeDeclarationCommand") << ", " << /* IsUnknownCommand = */ "0" << " }"; if (i + 1 != e) @@ -68,5 +74,49 @@ void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) { OS << " return NULL;\n" << "}\n\n"; } + +static std::string MangleName(StringRef Str) { + std::string Mangled; + for (unsigned i = 0, e = Str.size(); i != e; ++i) { + switch (Str[i]) { + default: + Mangled += Str[i]; + break; + case '[': + Mangled += "lsquare"; + break; + case ']': + Mangled += "rsquare"; + break; + case '{': + Mangled += "lbrace"; + break; + case '}': + Mangled += "rbrace"; + break; + case '$': + Mangled += "dollar"; + break; + } + } + return Mangled; +} + +void EmitClangCommentCommandList(RecordKeeper &Records, raw_ostream &OS) { + emitSourceFileHeader("A list of commands useable in documentation " + "comments", OS); + + OS << "#ifndef COMMENT_COMMAND\n" + << "# define COMMENT_COMMAND(NAME)\n" + << "#endif\n"; + + std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Command"); + for (size_t i = 0, e = Tags.size(); i != e; ++i) { + Record &Tag = *Tags[i]; + std::string MangledName = MangleName(Tag.getValueAsString("Name")); + + OS << "COMMENT_COMMAND(" << MangledName << ")\n"; + } +} } // end namespace clang diff --git a/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp b/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp new file mode 100644 index 0000000..bfdb268 --- /dev/null +++ b/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp @@ -0,0 +1,85 @@ +//===--- ClangCommentHTMLNamedCharacterReferenceEmitter.cpp -----------------=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend emits an fficient function to translate HTML named +// character references to UTF-8 sequences. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/ConvertUTF.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringMatcher.h" +#include "llvm/TableGen/TableGenBackend.h" +#include <vector> + +using namespace llvm; + +/// \brief Convert a code point to the corresponding UTF-8 sequence represented +/// as a C string literal. +/// +/// \returns true on success. +static bool translateCodePointToUTF8(unsigned CodePoint, + SmallVectorImpl<char> &CLiteral) { + char Translated[UNI_MAX_UTF8_BYTES_PER_CODE_POINT]; + char *TranslatedPtr = Translated; + if (!ConvertCodePointToUTF8(CodePoint, TranslatedPtr)) + return false; + + StringRef UTF8(Translated, TranslatedPtr - Translated); + + raw_svector_ostream OS(CLiteral); + OS << "\""; + for (size_t i = 0, e = UTF8.size(); i != e; ++i) { + OS << "\\x"; + OS.write_hex(static_cast<unsigned char>(UTF8[i])); + } + OS << "\""; + + return true; +} + +namespace clang { +void EmitClangCommentHTMLNamedCharacterReferences(RecordKeeper &Records, + raw_ostream &OS) { + std::vector<Record *> Tags = Records.getAllDerivedDefinitions("NCR"); + std::vector<StringMatcher::StringPair> NameToUTF8; + SmallString<32> CLiteral; + for (std::vector<Record *>::iterator I = Tags.begin(), E = Tags.end(); + I != E; ++I) { + Record &Tag = **I; + std::string Spelling = Tag.getValueAsString("Spelling"); + uint64_t CodePoint = Tag.getValueAsInt("CodePoint"); + CLiteral.clear(); + CLiteral.append("return "); + if (!translateCodePointToUTF8(CodePoint, CLiteral)) { + SrcMgr.PrintMessage(Tag.getLoc().front(), + SourceMgr::DK_Error, + Twine("invalid code point")); + continue; + } + CLiteral.append(";"); + + StringMatcher::StringPair Match(Spelling, CLiteral.str()); + NameToUTF8.push_back(Match); + } + + emitSourceFileHeader("HTML named character reference to UTF-8 " + "translation", OS); + + OS << "StringRef translateHTMLNamedCharacterReferenceToUTF8(\n" + " StringRef Name) {\n"; + StringMatcher("Name", NameToUTF8, OS).Emit(); + OS << " return StringRef();\n" + << "}\n\n"; +} + +} // end namespace clang + diff --git a/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp b/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp index 0ae23b2..bfcd2cf 100644 --- a/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp +++ b/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp @@ -14,6 +14,7 @@ #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringMatcher.h" +#include "llvm/TableGen/TableGenBackend.h" #include <vector> using namespace llvm; @@ -29,7 +30,7 @@ void EmitClangCommentHTMLTags(RecordKeeper &Records, raw_ostream &OS) { Matches.push_back(StringMatcher::StringPair(Spelling, "return true;")); } - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("HTML tag name matcher", OS); OS << "bool isHTMLTagName(StringRef Name) {\n"; StringMatcher("Name", Matches, OS).Emit(); @@ -53,7 +54,7 @@ void EmitClangCommentHTMLTagsProperties(RecordKeeper &Records, MatchesEndTagForbidden.push_back(Match); } - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("HTML tag properties", OS); OS << "bool isHTMLEndTagOptional(StringRef Name) {\n"; StringMatcher("Name", MatchesEndTagOptional, OS).Emit(); diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp index b1472a8..291eb75 100644 --- a/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -11,11 +11,15 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" -#include "llvm/ADT/Optional.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/TableGen/Error.h" @@ -127,14 +131,41 @@ namespace { std::vector<const Record*> DiagsInGroup; std::vector<std::string> SubGroups; unsigned IDNo; + + const Record *ExplicitDef; + + GroupInfo() : ExplicitDef(0) {} }; } // end anonymous namespace. +static bool beforeThanCompare(const Record *LHS, const Record *RHS) { + assert(!LHS->getLoc().empty() && !RHS->getLoc().empty()); + return + LHS->getLoc().front().getPointer() < RHS->getLoc().front().getPointer(); +} + +static bool beforeThanCompareGroups(const GroupInfo *LHS, const GroupInfo *RHS){ + assert(!LHS->DiagsInGroup.empty() && !RHS->DiagsInGroup.empty()); + return beforeThanCompare(LHS->DiagsInGroup.front(), + RHS->DiagsInGroup.front()); +} + +static SMRange findSuperClassRange(const Record *R, StringRef SuperName) { + ArrayRef<Record *> Supers = R->getSuperClasses(); + + for (size_t i = 0, e = Supers.size(); i < e; ++i) + if (Supers[i]->getName() == SuperName) + return R->getSuperClassRanges()[i]; + + return SMRange(); +} + /// \brief Invert the 1-[0/1] mapping of diags to group into a one to many /// mapping of groups to diags in the group. static void groupDiagnostics(const std::vector<Record*> &Diags, const std::vector<Record*> &DiagGroups, std::map<std::string, GroupInfo> &DiagsInGroup) { + for (unsigned i = 0, e = Diags.size(); i != e; ++i) { const Record *R = Diags[i]; DefInit *DI = dyn_cast<DefInit>(R->getValueInit("Group")); @@ -144,13 +175,25 @@ static void groupDiagnostics(const std::vector<Record*> &Diags, std::string GroupName = DI->getDef()->getValueAsString("GroupName"); DiagsInGroup[GroupName].DiagsInGroup.push_back(R); } - + + typedef SmallPtrSet<GroupInfo *, 16> GroupSetTy; + GroupSetTy ImplicitGroups; + // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty // groups (these are warnings that GCC supports that clang never produces). for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) { Record *Group = DiagGroups[i]; GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")]; - + if (Group->isAnonymous()) { + if (GI.DiagsInGroup.size() > 1) + ImplicitGroups.insert(&GI); + } else { + if (GI.ExplicitDef) + assert(GI.ExplicitDef == Group); + else + GI.ExplicitDef = Group; + } + std::vector<Record*> SubGroups = Group->getValueAsListOfDefs("SubGroups"); for (unsigned j = 0, e = SubGroups.size(); j != e; ++j) GI.SubGroups.push_back(SubGroups[j]->getValueAsString("GroupName")); @@ -161,6 +204,80 @@ static void groupDiagnostics(const std::vector<Record*> &Diags, for (std::map<std::string, GroupInfo>::iterator I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I, ++IDNo) I->second.IDNo = IDNo; + + // Sort the implicit groups, so we can warn about them deterministically. + SmallVector<GroupInfo *, 16> SortedGroups(ImplicitGroups.begin(), + ImplicitGroups.end()); + for (SmallVectorImpl<GroupInfo *>::iterator I = SortedGroups.begin(), + E = SortedGroups.end(); + I != E; ++I) { + MutableArrayRef<const Record *> GroupDiags = (*I)->DiagsInGroup; + std::sort(GroupDiags.begin(), GroupDiags.end(), beforeThanCompare); + } + std::sort(SortedGroups.begin(), SortedGroups.end(), beforeThanCompareGroups); + + // Warn about the same group being used anonymously in multiple places. + for (SmallVectorImpl<GroupInfo *>::const_iterator I = SortedGroups.begin(), + E = SortedGroups.end(); + I != E; ++I) { + ArrayRef<const Record *> GroupDiags = (*I)->DiagsInGroup; + + if ((*I)->ExplicitDef) { + std::string Name = (*I)->ExplicitDef->getValueAsString("GroupName"); + for (ArrayRef<const Record *>::const_iterator DI = GroupDiags.begin(), + DE = GroupDiags.end(); + DI != DE; ++DI) { + const DefInit *GroupInit = cast<DefInit>((*DI)->getValueInit("Group")); + const Record *NextDiagGroup = GroupInit->getDef(); + if (NextDiagGroup == (*I)->ExplicitDef) + continue; + + SMRange InGroupRange = findSuperClassRange(*DI, "InGroup"); + SmallString<64> Replacement; + if (InGroupRange.isValid()) { + Replacement += "InGroup<"; + Replacement += (*I)->ExplicitDef->getName(); + Replacement += ">"; + } + SMFixIt FixIt(InGroupRange, Replacement.str()); + + SrcMgr.PrintMessage(NextDiagGroup->getLoc().front(), + SourceMgr::DK_Error, + Twine("group '") + Name + + "' is referred to anonymously", + ArrayRef<SMRange>(), + InGroupRange.isValid() ? FixIt + : ArrayRef<SMFixIt>()); + SrcMgr.PrintMessage((*I)->ExplicitDef->getLoc().front(), + SourceMgr::DK_Note, "group defined here"); + } + } else { + // If there's no existing named group, we should just warn once and use + // notes to list all the other cases. + ArrayRef<const Record *>::const_iterator DI = GroupDiags.begin(), + DE = GroupDiags.end(); + assert(DI != DE && "We only care about groups with multiple uses!"); + + const DefInit *GroupInit = cast<DefInit>((*DI)->getValueInit("Group")); + const Record *NextDiagGroup = GroupInit->getDef(); + std::string Name = NextDiagGroup->getValueAsString("GroupName"); + + SMRange InGroupRange = findSuperClassRange(*DI, "InGroup"); + SrcMgr.PrintMessage(NextDiagGroup->getLoc().front(), + SourceMgr::DK_Error, + Twine("group '") + Name + + "' is referred to anonymously", + InGroupRange); + + for (++DI; DI != DE; ++DI) { + GroupInit = cast<DefInit>((*DI)->getValueInit("Group")); + InGroupRange = findSuperClassRange(*DI, "InGroup"); + SrcMgr.PrintMessage(GroupInit->getDef()->getLoc().front(), + SourceMgr::DK_Note, "also referenced here", + InGroupRange); + } + } + } } //===----------------------------------------------------------------------===// @@ -174,7 +291,7 @@ typedef llvm::PointerUnion<RecordVec*, RecordSet*> VecOrSet; namespace { class InferPedantic { typedef llvm::DenseMap<const Record*, - std::pair<unsigned, llvm::Optional<unsigned> > > GMap; + std::pair<unsigned, Optional<unsigned> > > GMap; DiagGroupParentMap &DiagGroupParents; const std::vector<Record*> &Diags; diff --git a/utils/TableGen/OptParserEmitter.cpp b/utils/TableGen/OptParserEmitter.cpp index 674c89a..0553b1f 100644 --- a/utils/TableGen/OptParserEmitter.cpp +++ b/utils/TableGen/OptParserEmitter.cpp @@ -7,13 +7,12 @@ // //===----------------------------------------------------------------------===// -#include "llvm/TableGen/Error.h" -#include "llvm/TableGen/Record.h" -#include "llvm/TableGen/TableGenBackend.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" - +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" #include <map> using namespace llvm; diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp index 41471a4..3df8940 100644 --- a/utils/TableGen/TableGen.cpp +++ b/utils/TableGen/TableGen.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "TableGenBackends.h" // Declares all backends. - #include "llvm/Support/CommandLine.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" @@ -30,10 +29,12 @@ enum ActionType { GenClangAttrPCHRead, GenClangAttrPCHWrite, GenClangAttrSpellingList, + GenClangAttrSpellingListIndex, GenClangAttrLateParsedList, GenClangAttrTemplateInstantiate, GenClangAttrParsedAttrList, GenClangAttrParsedAttrKinds, + GenClangAttrDump, GenClangDiagsDefs, GenClangDiagGroups, GenClangDiagsIndexName, @@ -43,7 +44,9 @@ enum ActionType { GenClangSACheckers, GenClangCommentHTMLTags, GenClangCommentHTMLTagsProperties, + GenClangCommentHTMLNamedCharacterReferences, GenClangCommentCommandInfo, + GenClangCommentCommandList, GenOptParserDefs, GenOptParserImpl, GenArmNeon, GenArmNeonSema, @@ -70,6 +73,9 @@ namespace { clEnumValN(GenClangAttrSpellingList, "gen-clang-attr-spelling-list", "Generate a clang attribute spelling list"), + clEnumValN(GenClangAttrSpellingListIndex, + "gen-clang-attr-spelling-index", + "Generate a clang attribute spelling index"), clEnumValN(GenClangAttrLateParsedList, "gen-clang-attr-late-parsed-list", "Generate a clang attribute LateParsed list"), @@ -82,6 +88,8 @@ namespace { clEnumValN(GenClangAttrParsedAttrKinds, "gen-clang-attr-parsed-attr-kinds", "Generate a clang parsed attribute kinds"), + clEnumValN(GenClangAttrDump, "gen-clang-attr-dump", + "Generate clang attribute dumper"), clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs", "Generate Clang diagnostics definitions"), clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups", @@ -105,8 +113,16 @@ namespace { "gen-clang-comment-html-tags-properties", "Generate efficient matchers for HTML tag " "properties"), + clEnumValN(GenClangCommentHTMLNamedCharacterReferences, + "gen-clang-comment-html-named-character-references", + "Generate function to translate named character " + "references to UTF-8 sequences"), clEnumValN(GenClangCommentCommandInfo, "gen-clang-comment-command-info", + "Generate command properties for commands that " + "are used in documentation comments"), + clEnumValN(GenClangCommentCommandList, + "gen-clang-comment-command-list", "Generate list of commands that are used in " "documentation comments"), clEnumValN(GenArmNeon, "gen-arm-neon", @@ -142,6 +158,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenClangAttrSpellingList: EmitClangAttrSpellingList(Records, OS); break; + case GenClangAttrSpellingListIndex: + EmitClangAttrSpellingListIndex(Records, OS); + break; case GenClangAttrLateParsedList: EmitClangAttrLateParsedList(Records, OS); break; @@ -154,6 +173,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenClangAttrParsedAttrKinds: EmitClangAttrParsedAttrKinds(Records, OS); break; + case GenClangAttrDump: + EmitClangAttrDump(Records, OS); + break; case GenClangDiagsDefs: EmitClangDiagsDefs(Records, OS, ClangComponent); break; @@ -182,9 +204,15 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenClangCommentHTMLTagsProperties: EmitClangCommentHTMLTagsProperties(Records, OS); break; + case GenClangCommentHTMLNamedCharacterReferences: + EmitClangCommentHTMLNamedCharacterReferences(Records, OS); + break; case GenClangCommentCommandInfo: EmitClangCommentCommandInfo(Records, OS); break; + case GenClangCommentCommandList: + EmitClangCommentCommandList(Records, OS); + break; case GenOptParserDefs: EmitOptParser(Records, OS, true); break; diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h index 838fc84..03708b6 100644 --- a/utils/TableGen/TableGenBackends.h +++ b/utils/TableGen/TableGenBackends.h @@ -35,10 +35,12 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS); +void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS); +void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS); void EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS, const std::string &Component); @@ -49,8 +51,10 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS); void EmitClangCommentHTMLTags(RecordKeeper &Records, raw_ostream &OS); void EmitClangCommentHTMLTagsProperties(RecordKeeper &Records, raw_ostream &OS); +void EmitClangCommentHTMLNamedCharacterReferences(RecordKeeper &Records, raw_ostream &OS); void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS); +void EmitClangCommentCommandList(RecordKeeper &Records, raw_ostream &OS); void EmitNeon(RecordKeeper &Records, raw_ostream &OS); void EmitNeonSema(RecordKeeper &Records, raw_ostream &OS); diff --git a/utils/analyzer/CmpRuns.py b/utils/analyzer/CmpRuns.py index 3ca9b2b..30157be 100755 --- a/utils/analyzer/CmpRuns.py +++ b/utils/analyzer/CmpRuns.py @@ -120,9 +120,8 @@ class CmpOptions: self.verboseLog = verboseLog class AnalysisReport: - def __init__(self, run, files, clang_vers): + def __init__(self, run, files): self.run = run - self.clang_version = clang_vers self.files = files self.diagnostics = [] @@ -134,32 +133,28 @@ class AnalysisRun: self.reports = [] # Cumulative list of all diagnostics from all the reports. self.diagnostics = [] - - -# Backward compatibility API. -def loadResults(path, opts, root = "", deleteEmpty=True): - return loadResultsFromSingleRun(SingleRunInfo(path, root, opts.verboseLog), - deleteEmpty) - -# 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 -def loadResultsFromSingleRun(info, deleteEmpty=True): - path = info.path - run = AnalysisRun(info) + self.clang_version = None - for f in os.listdir(path): - if (not f.endswith('plist')): - continue + def getClangVersion(self): + return self.clang_version - p = os.path.join(path, f) + def readSingleFile(self, p, deleteEmpty): data = plistlib.readPlist(p) + # 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 == None: + self.clang_version = data.pop('clang_version') + else: + data.pop('clang_version') + # Ignore/delete empty reports. if not data['files']: if deleteEmpty == True: os.remove(p) - continue + return # Extract the HTML reports, if they exists. if 'HTMLDiagnostics_files' in data['diagnostics'][0]: @@ -171,21 +166,40 @@ def loadResultsFromSingleRun(info, deleteEmpty=True): htmlFiles.append(d.pop('HTMLDiagnostics_files')[0]) else: htmlFiles = [None] * len(data['diagnostics']) - - clang_version = '' - if 'clang_version' in data: - clang_version = data.pop('clang_version') - - report = AnalysisReport(run, data.pop('files'), clang_version) + + 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) - run.reports.append(report) - run.diagnostics.extend(diagnostics) + self.reports.append(report) + self.diagnostics.extend(diagnostics) + + +# Backward compatibility API. +def loadResults(path, opts, root = "", deleteEmpty=True): + return loadResultsFromSingleRun(SingleRunInfo(path, root, opts.verboseLog), + deleteEmpty) + +# 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 +def loadResultsFromSingleRun(info, deleteEmpty=True): + 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 diff --git a/utils/analyzer/SATestBuild.py b/utils/analyzer/SATestBuild.py index 9412358..067be16 100644 --- a/utils/analyzer/SATestBuild.py +++ b/utils/analyzer/SATestBuild.py @@ -142,7 +142,7 @@ if not Clang: sys.exit(-1) # Number of jobs. -Jobs = math.ceil(detectCPUs() * 0.75) +Jobs = int(math.ceil(detectCPUs() * 0.75)) # Project map stores info about all the "registered" projects. ProjectMapFile = "projectMap.csv" @@ -206,6 +206,7 @@ def runScanBuild(Dir, SBOutputDir, PBuildLogFile): SBOptions = "--use-analyzer " + Clang + " " SBOptions += "-plist-html -o " + SBOutputDir + " " SBOptions += "-enable-checker " + Checkers + " " + SBOptions += "--keep-empty " try: SBCommandFile = open(BuildScriptPath, "r") SBPrefix = "scan-build " + SBOptions + " " @@ -213,8 +214,9 @@ def runScanBuild(Dir, SBOutputDir, PBuildLogFile): # 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 "): - Command += "-j" + Jobs + if (Command.startswith("make ") or Command == "make") and \ + "-j" not in Command: + Command += " -j%d" % Jobs SBCommand = SBPrefix + Command if Verbose == 1: print " Executing: %s" % (SBCommand,) diff --git a/utils/find-unused-diagnostics.sh b/utils/find-unused-diagnostics.sh index 89b7f7a..c7fa01a 100644 --- a/utils/find-unused-diagnostics.sh +++ b/utils/find-unused-diagnostics.sh @@ -4,16 +4,12 @@ # in Diagnostic*.td files but not used in sources. # -ALL_DIAGS=$(mktemp) -ALL_SOURCES=$(mktemp) +# 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) -grep -E --only-matching --no-filename '(err_|warn_|ext_|note_)[a-z_]+ ' ./include/clang/Basic/Diagnostic*.td > $ALL_DIAGS -find lib include tools -name \*.cpp -or -name \*.h > $ALL_SOURCES -for DIAG in $(cat $ALL_DIAGS); do - if ! grep -r $DIAG $(cat $ALL_SOURCES) > /dev/null; then - echo $DIAG - fi; -done - -rm $ALL_DIAGS $ALL_SOURCES +# Now look for all potential identifiers in the source files. +ALL_SOURCES=$(find lib include tools -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/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp b/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp index a86be6c..b8ba7f3 100644 --- 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 @@ -21,3 +21,10 @@ ... 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 +} |