[analyzer] Support for naive cross translation unit analysis
The aim of this patch is to be minimal to enable incremental development of
the feature on the top of the tree. This patch should be an NFC when the
feature is turned off. It is turned off by default and still considered as
experimental.
Technical details are available in the EuroLLVM Talk:
http://llvm.org/devmtg/2017-03//2017/02/20/accepted-sessions.html#7
Note that the initial prototype was done by A. Sidorin et al.: http://lists.llvm.org/pipermail/cfe-dev/2015-October/045730.html
Contributions to the measurements and the new version of the code: Peter Szecsi, Zoltan Gera, Daniel Krupp, Kareem Khazem.
Differential Revision: https://reviews.llvm.org/D30691
llvm-svn: 326323
diff --git a/clang/tools/scan-build-py/libscanbuild/arguments.py b/clang/tools/scan-build-py/libscanbuild/arguments.py
index 2735123..00679a4 100644
--- a/clang/tools/scan-build-py/libscanbuild/arguments.py
+++ b/clang/tools/scan-build-py/libscanbuild/arguments.py
@@ -18,8 +18,8 @@
import argparse
import logging
import tempfile
-from libscanbuild import reconfigure_logging
-from libscanbuild.clang import get_checkers
+from libscanbuild import reconfigure_logging, CtuConfig
+from libscanbuild.clang import get_checkers, is_ctu_capable
__all__ = ['parse_args_for_intercept_build', 'parse_args_for_analyze_build',
'parse_args_for_scan_build']
@@ -98,6 +98,11 @@
# add cdb parameter invisibly to make report module working.
args.cdb = 'compile_commands.json'
+ # Make ctu_dir an abspath as it is needed inside clang
+ if not from_build_command and hasattr(args, 'ctu_phases') \
+ and hasattr(args.ctu_phases, 'dir'):
+ args.ctu_dir = os.path.abspath(args.ctu_dir)
+
def validate_args_for_analyze(parser, args, from_build_command):
""" Command line parsing is done by the argparse module, but semantic
@@ -122,6 +127,18 @@
elif not from_build_command and not os.path.exists(args.cdb):
parser.error(message='compilation database is missing')
+ # If the user wants CTU mode
+ if not from_build_command and hasattr(args, 'ctu_phases') \
+ and hasattr(args.ctu_phases, 'dir'):
+ # If CTU analyze_only, the input directory should exist
+ if args.ctu_phases.analyze and not args.ctu_phases.collect \
+ and not os.path.exists(args.ctu_dir):
+ parser.error(message='missing CTU directory')
+ # Check CTU capability via checking clang-func-mapping
+ if not is_ctu_capable(args.func_map_cmd):
+ parser.error(message="""This version of clang does not support CTU
+ functionality or clang-func-mapping command not found.""")
+
def create_intercept_parser():
""" Creates a parser for command-line arguments to 'intercept'. """
@@ -218,7 +235,15 @@
default='html',
action='store_const',
help="""Cause the results as a set of .html and .plist files.""")
- # TODO: implement '-view '
+ format_group.add_argument(
+ '--plist-multi-file',
+ '-plist-multi-file',
+ dest='output_format',
+ const='plist-multi-file',
+ default='html',
+ action='store_const',
+ help="""Cause the results as a set of .plist files with extra
+ information on related files.""")
advanced = parser.add_argument_group('advanced options')
advanced.add_argument(
@@ -333,6 +358,51 @@
if from_build_command:
parser.add_argument(
dest='build', nargs=argparse.REMAINDER, help="""Command to run.""")
+ else:
+ ctu = parser.add_argument_group('cross translation unit analysis')
+ ctu_mutex_group = ctu.add_mutually_exclusive_group()
+ ctu_mutex_group.add_argument(
+ '--ctu',
+ action='store_const',
+ const=CtuConfig(collect=True, analyze=True,
+ dir='', func_map_cmd=''),
+ dest='ctu_phases',
+ help="""Perform cross translation unit (ctu) analysis (both collect
+ and analyze phases) using default <ctu-dir> for temporary output.
+ At the end of the analysis, the temporary directory is removed.""")
+ ctu.add_argument(
+ '--ctu-dir',
+ metavar='<ctu-dir>',
+ dest='ctu_dir',
+ default='ctu-dir',
+ help="""Defines the temporary directory used between ctu
+ phases.""")
+ ctu_mutex_group.add_argument(
+ '--ctu-collect-only',
+ action='store_const',
+ const=CtuConfig(collect=True, analyze=False,
+ dir='', func_map_cmd=''),
+ dest='ctu_phases',
+ help="""Perform only the collect phase of ctu.
+ Keep <ctu-dir> for further use.""")
+ ctu_mutex_group.add_argument(
+ '--ctu-analyze-only',
+ action='store_const',
+ const=CtuConfig(collect=False, analyze=True,
+ dir='', func_map_cmd=''),
+ dest='ctu_phases',
+ help="""Perform only the analyze phase of ctu. <ctu-dir> should be
+ present and will not be removed after analysis.""")
+ ctu.add_argument(
+ '--use-func-map-cmd',
+ metavar='<path>',
+ dest='func_map_cmd',
+ default='clang-func-mapping',
+ help="""'%(prog)s' uses the 'clang-func-mapping' executable
+ relative to itself for generating function maps for static
+ analysis. One can override this behavior with this option by using
+ the 'clang-func-mapping' packaged with Xcode (on OS X) or from the
+ PATH.""")
return parser