blob: 1c54d7267cdb97ef1c10997ee3fc3bfcfdf4911d [file] [log] [blame]
kmarshall520f9512017-01-24 23:25:011#!/usr/bin/env python
kmarshall6694c0e2017-03-10 19:47:212# Copyright 2017 The Chromium Authors. All rights reserved.
kmarshall520f9512017-01-24 23:25:013# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
kmarshall6694c0e2017-03-10 19:47:216"""Adds an analysis build step to invocations of the Clang C/C++ compiler.
7
8Usage: clang_static_analyzer_wrapper.py <compiler> [args...]
kmarshall520f9512017-01-24 23:25:019"""
10
11import argparse
12import fnmatch
kmarshall6694c0e2017-03-10 19:47:2113import itertools
kmarshall520f9512017-01-24 23:25:0114import os
kmarshall520f9512017-01-24 23:25:0115import sys
kmarshall520f9512017-01-24 23:25:0116import wrapper_utils
17
kmarshall6694c0e2017-03-10 19:47:2118# Flags used to enable analysis for Clang invocations.
19analyzer_enable_flags = [
20 '--analyze',
kmarshall6694c0e2017-03-10 19:47:2121]
22
23# Flags used to configure the analyzer's behavior.
24analyzer_option_flags = [
kmarshall5847e4b2017-03-16 21:39:5125 '-fdiagnostics-show-option',
kmarshall6694c0e2017-03-10 19:47:2126 '-analyzer-checker=cplusplus',
27 '-analyzer-opt-analyze-nested-blocks',
28 '-analyzer-eagerly-assume',
29 '-analyzer-output=text',
30 '-analyzer-config',
31 'suppress-c++-stdlib=true',
32
33# List of checkers to execute.
34# The full list of checkers can be found at
35# https://clang-analyzer.llvm.org/available_checks.html.
36 '-analyzer-checker=core',
37 '-analyzer-checker=unix',
38 '-analyzer-checker=deadcode',
39]
40
kmarshall520f9512017-01-24 23:25:0141
kmarshall5847e4b2017-03-16 21:39:5142# Prepends every element of a list |args| with |token|.
43# e.g. ['-analyzer-foo', '-analyzer-bar'] => ['-Xanalyzer', '-analyzer-foo',
44# '-Xanalyzer', '-analyzer-bar']
45def interleave_args(args, token):
46 return list(sum(zip([token] * len(args), args), ()))
47
48
kmarshall520f9512017-01-24 23:25:0149def main():
kmarshall5847e4b2017-03-16 21:39:5150 parser = argparse.ArgumentParser()
51 parser.add_argument('--mode',
52 choices=['clang', 'cl'],
53 required=True,
54 help='Specifies the compiler argument convention to use.')
55 parser.add_argument('args', nargs=argparse.REMAINDER)
56 parsed_args = parser.parse_args()
kmarshall520f9512017-01-24 23:25:0157
kmarshall5847e4b2017-03-16 21:39:5158 prefix = '-Xclang' if parsed_args.mode == 'cl' else '-Xanalyzer'
59 cmd = parsed_args.args + analyzer_enable_flags + \
60 interleave_args(analyzer_option_flags, prefix)
kmarshall6694c0e2017-03-10 19:47:2161 returncode, stderr = wrapper_utils.CaptureCommandStderr(
kmarshall5847e4b2017-03-16 21:39:5162 wrapper_utils.CommandToRun(cmd))
kmarshall6694c0e2017-03-10 19:47:2163 sys.stderr.write(stderr)
kmarshall6694c0e2017-03-10 19:47:2164
kmarshall5847e4b2017-03-16 21:39:5165 returncode, stderr = wrapper_utils.CaptureCommandStderr(
66 wrapper_utils.CommandToRun(parsed_args.args))
67 sys.stderr.write(stderr)
68
69 return returncode
kmarshall6694c0e2017-03-10 19:47:2170
71if __name__ == '__main__':
kmarshall520f9512017-01-24 23:25:0172 sys.exit(main())