xref: /aosp_15_r20/external/webrtc/tools_webrtc/clang_tidy.py (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker#!/usr/bin/env vpython3
2*d9f75844SAndroid Build Coastguard Worker
3*d9f75844SAndroid Build Coastguard Worker# Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
4*d9f75844SAndroid Build Coastguard Worker#
5*d9f75844SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license
6*d9f75844SAndroid Build Coastguard Worker# that can be found in the LICENSE file in the root of the source
7*d9f75844SAndroid Build Coastguard Worker# tree. An additional intellectual property rights grant can be found
8*d9f75844SAndroid Build Coastguard Worker# in the file PATENTS.  All contributing project authors may
9*d9f75844SAndroid Build Coastguard Worker# be found in the AUTHORS file in the root of the source tree.
10*d9f75844SAndroid Build Coastguard Worker"""Invoke clang-tidy tool.
11*d9f75844SAndroid Build Coastguard Worker
12*d9f75844SAndroid Build Coastguard WorkerUsage: clang_tidy.py file.cc [clang-tidy-args...]
13*d9f75844SAndroid Build Coastguard Worker
14*d9f75844SAndroid Build Coastguard WorkerJust a proof of concept!
15*d9f75844SAndroid Build Coastguard WorkerWe use an embedded clang-tidy whose version doesn't match clang++.
16*d9f75844SAndroid Build Coastguard Worker"""
17*d9f75844SAndroid Build Coastguard Worker
18*d9f75844SAndroid Build Coastguard Workerimport argparse
19*d9f75844SAndroid Build Coastguard Workerimport os
20*d9f75844SAndroid Build Coastguard Workerimport shutil
21*d9f75844SAndroid Build Coastguard Workerimport subprocess
22*d9f75844SAndroid Build Coastguard Workerimport sys
23*d9f75844SAndroid Build Coastguard Workerimport tempfile
24*d9f75844SAndroid Build Coastguard Workerfrom presubmit_checks_lib.build_helpers import (GetClangTidyPath,
25*d9f75844SAndroid Build Coastguard Worker                                                GetCompilationCommand)
26*d9f75844SAndroid Build Coastguard Worker
27*d9f75844SAndroid Build Coastguard Worker# We enable all checkers by default for investigation purpose.
28*d9f75844SAndroid Build Coastguard Worker# This includes clang-analyzer-* checks.
29*d9f75844SAndroid Build Coastguard Worker# Individual checkers can be disabled via command line options.
30*d9f75844SAndroid Build Coastguard Worker# TODO(bugs.webrtc.com/10258): Select checkers relevant to webrtc guidelines.
31*d9f75844SAndroid Build Coastguard WorkerCHECKER_OPTION = '-checks=*'
32*d9f75844SAndroid Build Coastguard Worker
33*d9f75844SAndroid Build Coastguard Worker
34*d9f75844SAndroid Build Coastguard Workerdef Process(filepath, args):
35*d9f75844SAndroid Build Coastguard Worker  # Build directory is needed to gather compilation flags.
36*d9f75844SAndroid Build Coastguard Worker  # Create a temporary one (instead of reusing an existing one)
37*d9f75844SAndroid Build Coastguard Worker  # to keep the CLI simple and unencumbered.
38*d9f75844SAndroid Build Coastguard Worker  out_dir = tempfile.mkdtemp('clang_tidy')
39*d9f75844SAndroid Build Coastguard Worker
40*d9f75844SAndroid Build Coastguard Worker  try:
41*d9f75844SAndroid Build Coastguard Worker    gn_args = []  # Use default build.
42*d9f75844SAndroid Build Coastguard Worker    command = GetCompilationCommand(filepath, gn_args, out_dir)
43*d9f75844SAndroid Build Coastguard Worker
44*d9f75844SAndroid Build Coastguard Worker    # Remove warning flags. They aren't needed and they cause trouble
45*d9f75844SAndroid Build Coastguard Worker    # when clang-tidy doesn't match most recent clang.
46*d9f75844SAndroid Build Coastguard Worker    # Same battle for -f (e.g. -fcomplete-member-pointers).
47*d9f75844SAndroid Build Coastguard Worker    command = [
48*d9f75844SAndroid Build Coastguard Worker        arg for arg in command
49*d9f75844SAndroid Build Coastguard Worker        if not (arg.startswith('-W') or arg.startswith('-f'))
50*d9f75844SAndroid Build Coastguard Worker    ]
51*d9f75844SAndroid Build Coastguard Worker
52*d9f75844SAndroid Build Coastguard Worker    # Path from build dir.
53*d9f75844SAndroid Build Coastguard Worker    rel_path = os.path.relpath(os.path.abspath(filepath), out_dir)
54*d9f75844SAndroid Build Coastguard Worker
55*d9f75844SAndroid Build Coastguard Worker    # Replace clang++ by clang-tidy
56*d9f75844SAndroid Build Coastguard Worker    command[0:1] = [GetClangTidyPath(), CHECKER_OPTION, rel_path
57*d9f75844SAndroid Build Coastguard Worker                    ] + args + ['--']  # Separator for clang flags.
58*d9f75844SAndroid Build Coastguard Worker    print("Running: %s" % ' '.join(command))
59*d9f75844SAndroid Build Coastguard Worker    # Run from build dir so that relative paths are correct.
60*d9f75844SAndroid Build Coastguard Worker    p = subprocess.Popen(command,
61*d9f75844SAndroid Build Coastguard Worker                         cwd=out_dir,
62*d9f75844SAndroid Build Coastguard Worker                         stdout=sys.stdout,
63*d9f75844SAndroid Build Coastguard Worker                         stderr=sys.stderr)
64*d9f75844SAndroid Build Coastguard Worker    p.communicate()
65*d9f75844SAndroid Build Coastguard Worker    return p.returncode
66*d9f75844SAndroid Build Coastguard Worker  finally:
67*d9f75844SAndroid Build Coastguard Worker    shutil.rmtree(out_dir, ignore_errors=True)
68*d9f75844SAndroid Build Coastguard Worker
69*d9f75844SAndroid Build Coastguard Worker
70*d9f75844SAndroid Build Coastguard Workerdef ValidateCC(filepath):
71*d9f75844SAndroid Build Coastguard Worker  """We can only analyze .cc files. Provide explicit message about that."""
72*d9f75844SAndroid Build Coastguard Worker  if filepath.endswith('.cc'):
73*d9f75844SAndroid Build Coastguard Worker    return filepath
74*d9f75844SAndroid Build Coastguard Worker  msg = ('%s not supported.\n'
75*d9f75844SAndroid Build Coastguard Worker         'For now, we can only analyze translation units (.cc files).' %
76*d9f75844SAndroid Build Coastguard Worker         filepath)
77*d9f75844SAndroid Build Coastguard Worker  raise argparse.ArgumentTypeError(msg)
78*d9f75844SAndroid Build Coastguard Worker
79*d9f75844SAndroid Build Coastguard Worker
80*d9f75844SAndroid Build Coastguard Workerdef Main():
81*d9f75844SAndroid Build Coastguard Worker  description = (
82*d9f75844SAndroid Build Coastguard Worker      "Run clang-tidy on single cc file.\n"
83*d9f75844SAndroid Build Coastguard Worker      "Use flags, defines and include paths as in default debug build.\n"
84*d9f75844SAndroid Build Coastguard Worker      "WARNING, this is a POC version with rough edges.")
85*d9f75844SAndroid Build Coastguard Worker  parser = argparse.ArgumentParser(description=description)
86*d9f75844SAndroid Build Coastguard Worker  parser.add_argument('filepath',
87*d9f75844SAndroid Build Coastguard Worker                      help='Specifies the path of the .cc file to analyze.',
88*d9f75844SAndroid Build Coastguard Worker                      type=ValidateCC)
89*d9f75844SAndroid Build Coastguard Worker  parser.add_argument('args',
90*d9f75844SAndroid Build Coastguard Worker                      nargs=argparse.REMAINDER,
91*d9f75844SAndroid Build Coastguard Worker                      help='Arguments passed to clang-tidy')
92*d9f75844SAndroid Build Coastguard Worker  parsed_args = parser.parse_args()
93*d9f75844SAndroid Build Coastguard Worker  return Process(parsed_args.filepath, parsed_args.args)
94*d9f75844SAndroid Build Coastguard Worker
95*d9f75844SAndroid Build Coastguard Worker
96*d9f75844SAndroid Build Coastguard Workerif __name__ == '__main__':
97*d9f75844SAndroid Build Coastguard Worker  sys.exit(Main())
98