15f9996aaSopenharmony_ci#!/usr/bin/env python
25f9996aaSopenharmony_ci# -*- coding: utf-8 -*-
35f9996aaSopenharmony_ci# Copyright 2017 The Chromium Authors. All rights reserved.
45f9996aaSopenharmony_ci# Use of this source code is governed by a BSD-style license that can be
55f9996aaSopenharmony_ci# found in the LICENSE file.
65f9996aaSopenharmony_ci
75f9996aaSopenharmony_ci"""Adds an analysis build step to invocations of the Clang C/C++ compiler.
85f9996aaSopenharmony_ci
95f9996aaSopenharmony_ciUsage: clang_static_analyzer_wrapper.py <compiler> [args...]
105f9996aaSopenharmony_ci"""
115f9996aaSopenharmony_ci
125f9996aaSopenharmony_ciimport argparse
135f9996aaSopenharmony_ciimport sys
145f9996aaSopenharmony_ciimport wrapper_utils
155f9996aaSopenharmony_ci
165f9996aaSopenharmony_ci# Flags used to enable analysis for Clang invocations.
175f9996aaSopenharmony_cianalyzer_enable_flags = [
185f9996aaSopenharmony_ci    '--analyze',
195f9996aaSopenharmony_ci]
205f9996aaSopenharmony_ci
215f9996aaSopenharmony_ci# Flags used to configure the analyzer's behavior.
225f9996aaSopenharmony_cianalyzer_option_flags = [
235f9996aaSopenharmony_ci    '-fdiagnostics-show-option',
245f9996aaSopenharmony_ci    '-analyzer-checker=cplusplus',
255f9996aaSopenharmony_ci    '-analyzer-opt-analyze-nested-blocks',
265f9996aaSopenharmony_ci    '-analyzer-eagerly-assume',
275f9996aaSopenharmony_ci    '-analyzer-output=text',
285f9996aaSopenharmony_ci    '-analyzer-config',
295f9996aaSopenharmony_ci    'suppress-c++-stdlib=true',
305f9996aaSopenharmony_ci
315f9996aaSopenharmony_ci    # List of checkers to execute.
325f9996aaSopenharmony_ci    # The full list of checkers can be found at
335f9996aaSopenharmony_ci    # https://clang-analyzer.llvm.org/available_checks.html.
345f9996aaSopenharmony_ci    '-analyzer-checker=core',
355f9996aaSopenharmony_ci    '-analyzer-checker=unix',
365f9996aaSopenharmony_ci    '-analyzer-checker=deadcode',
375f9996aaSopenharmony_ci]
385f9996aaSopenharmony_ci
395f9996aaSopenharmony_ci
405f9996aaSopenharmony_ci# Prepends every element of a list |args| with |token|.
415f9996aaSopenharmony_ci# e.g. ['-analyzer-foo', '-analyzer-bar'] => ['-Xanalyzer', '-analyzer-foo',
425f9996aaSopenharmony_ci#                                             '-Xanalyzer', '-analyzer-bar']
435f9996aaSopenharmony_cidef interleave_args(args, token):
445f9996aaSopenharmony_ci    return list(sum(zip([token] * len(args), args), ()))
455f9996aaSopenharmony_ci
465f9996aaSopenharmony_ci
475f9996aaSopenharmony_cidef main():
485f9996aaSopenharmony_ci    parser = argparse.ArgumentParser()
495f9996aaSopenharmony_ci    parser.add_argument('--mode',
505f9996aaSopenharmony_ci                        choices=['clang', 'cl'],
515f9996aaSopenharmony_ci                        required=True,
525f9996aaSopenharmony_ci                        help='Specifies the compiler argument convention '
535f9996aaSopenharmony_ci                             'to use.')
545f9996aaSopenharmony_ci    parser.add_argument('args', nargs=argparse.REMAINDER)
555f9996aaSopenharmony_ci    parsed_args = parser.parse_args()
565f9996aaSopenharmony_ci
575f9996aaSopenharmony_ci    prefix = '-Xclang' if parsed_args.mode == 'cl' else '-Xanalyzer'
585f9996aaSopenharmony_ci    cmd = parsed_args.args + analyzer_enable_flags + interleave_args(
595f9996aaSopenharmony_ci        analyzer_option_flags, prefix)
605f9996aaSopenharmony_ci    returncode, stderr = wrapper_utils.capture_command_stderr(
615f9996aaSopenharmony_ci        wrapper_utils.command_to_run(cmd))
625f9996aaSopenharmony_ci    sys.stderr.write(stderr)
635f9996aaSopenharmony_ci
645f9996aaSopenharmony_ci    return_code, stderr = wrapper_utils.capture_command_stderr(
655f9996aaSopenharmony_ci        wrapper_utils.command_to_run(parsed_args.args))
665f9996aaSopenharmony_ci    sys.stderr.write(stderr)
675f9996aaSopenharmony_ci
685f9996aaSopenharmony_ci    return return_code
695f9996aaSopenharmony_ci
705f9996aaSopenharmony_ci
715f9996aaSopenharmony_ciif __name__ == '__main__':
725f9996aaSopenharmony_ci    sys.exit(main())
73