summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/C++Tests/Clang-Code-Compile/lit.local.cfg26
-rw-r--r--utils/C++Tests/Clang-Code-Syntax/lit.local.cfg25
-rw-r--r--utils/C++Tests/Clang-Syntax/lit.local.cfg24
-rw-r--r--utils/C++Tests/LLVM-Code-Compile/lit.local.cfg48
-rwxr-xr-xutils/C++Tests/LLVM-Code-Symbols/check-symbols54
-rw-r--r--utils/C++Tests/LLVM-Code-Symbols/lit.local.cfg48
-rw-r--r--utils/C++Tests/LLVM-Code-Syntax/lit.local.cfg46
-rw-r--r--utils/C++Tests/LLVM-Syntax/lit.local.cfg24
-rw-r--r--utils/C++Tests/lit.cfg27
-rw-r--r--utils/C++Tests/stdc++-Syntax/lit.local.cfg17
-rw-r--r--utils/ClangDataFormat.py58
-rw-r--r--utils/OptionalTests/Extra/README.txt3
-rw-r--r--utils/OptionalTests/Extra/Runtime/darwin-clang_rt.c338
-rw-r--r--utils/OptionalTests/README.txt4
-rw-r--r--utils/OptionalTests/lit.cfg26
-rwxr-xr-xutils/SummarizeErrors117
-rw-r--r--utils/TableGen/CMakeLists.txt1
-rw-r--r--utils/TableGen/ClangASTNodesEmitter.cpp4
-rw-r--r--utils/TableGen/ClangAttrEmitter.cpp431
-rw-r--r--utils/TableGen/ClangCommentCommandInfoEmitter.cpp54
-rw-r--r--utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp85
-rw-r--r--utils/TableGen/ClangCommentHTMLTagsEmitter.cpp5
-rw-r--r--utils/TableGen/ClangDiagnosticsEmitter.cpp127
-rw-r--r--utils/TableGen/OptParserEmitter.cpp7
-rw-r--r--utils/TableGen/TableGen.cpp30
-rw-r--r--utils/TableGen/TableGenBackends.h4
-rwxr-xr-xutils/analyzer/CmpRuns.py72
-rw-r--r--utils/analyzer/SATestBuild.py8
-rw-r--r--utils/find-unused-diagnostics.sh18
-rw-r--r--utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp7
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
+}
OpenPOWER on IntegriCloud