• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright (c) 2024 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16"""Adds an analysis build step to invocations of the Clang C/C++ compiler.
17
18Usage: clang_static_analyzer_wrapper.py <compiler> [args...]
19"""
20
21import argparse
22import sys
23import wrapper_utils
24
25# Flags used to enable analysis for Clang invocations.
26analyzer_enable_flags = [
27    '--analyze',
28]
29
30# Flags used to configure the analyzer's behavior.
31analyzer_option_flags = [
32    '-fdiagnostics-show-option',
33    '-analyzer-checker=cplusplus',
34    '-analyzer-opt-analyze-nested-blocks',
35    '-analyzer-eagerly-assume',
36    '-analyzer-output=text',
37    '-analyzer-config',
38    'suppress-c++-stdlib=true',
39
40    # List of checkers to execute.
41    # The full list of checkers can be found at
42    # https://clang-analyzer.llvm.org/available_checks.html.
43    '-analyzer-checker=core',
44    '-analyzer-checker=unix',
45    '-analyzer-checker=deadcode',
46]
47
48
49# Prepends every element of a list |args| with |token|.
50# e.g. ['-analyzer-foo', '-analyzer-bar'] => ['-Xanalyzer', '-analyzer-foo',
51#                                             '-Xanalyzer', '-analyzer-bar']
52def interleave_args(args, token):
53    return list(sum(zip([token] * len(args), args), ()))
54
55
56def main():
57    parser = argparse.ArgumentParser()
58    parser.add_argument('--mode',
59                        choices=['clang', 'cl'],
60                        required=True,
61                        help='Specifies the compiler argument convention '
62                             'to use.')
63    parser.add_argument('args', nargs=argparse.REMAINDER)
64    parsed_args = parser.parse_args()
65
66    prefix = '-Xclang' if parsed_args.mode == 'cl' else '-Xanalyzer'
67    cmd = parsed_args.args + analyzer_enable_flags + interleave_args(
68        analyzer_option_flags, prefix)
69    returncode, stderr = wrapper_utils.capture_command_stderr(
70        wrapper_utils.command_to_run(cmd))
71    sys.stderr.write(stderr)
72
73    return_code, stderr = wrapper_utils.capture_command_stderr(
74        wrapper_utils.command_to_run(parsed_args.args))
75    sys.stderr.write(stderr)
76
77    return return_code
78
79
80if __name__ == '__main__':
81    sys.exit(main())
82