diff options
Diffstat (limited to 'third_party/libwebrtc/tools_webrtc/clang_tidy.py')
-rwxr-xr-x | third_party/libwebrtc/tools_webrtc/clang_tidy.py | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/third_party/libwebrtc/tools_webrtc/clang_tidy.py b/third_party/libwebrtc/tools_webrtc/clang_tidy.py new file mode 100755 index 0000000000..b3f738eab3 --- /dev/null +++ b/third_party/libwebrtc/tools_webrtc/clang_tidy.py @@ -0,0 +1,97 @@ +#!/usr/bin/env vpython3 + +# Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. +"""Invoke clang-tidy tool. + +Usage: clang_tidy.py file.cc [clang-tidy-args...] + +Just a proof of concept! +We use an embedded clang-tidy whose version doesn't match clang++. +""" + +import argparse +import os +import shutil +import subprocess +import sys +import tempfile +from presubmit_checks_lib.build_helpers import (GetClangTidyPath, + GetCompilationCommand) + +# We enable all checkers by default for investigation purpose. +# This includes clang-analyzer-* checks. +# Individual checkers can be disabled via command line options. +# TODO(bugs.webrtc.com/10258): Select checkers relevant to webrtc guidelines. +CHECKER_OPTION = '-checks=*' + + +def Process(filepath, args): + # Build directory is needed to gather compilation flags. + # Create a temporary one (instead of reusing an existing one) + # to keep the CLI simple and unencumbered. + out_dir = tempfile.mkdtemp('clang_tidy') + + try: + gn_args = [] # Use default build. + command = GetCompilationCommand(filepath, gn_args, out_dir) + + # Remove warning flags. They aren't needed and they cause trouble + # when clang-tidy doesn't match most recent clang. + # Same battle for -f (e.g. -fcomplete-member-pointers). + command = [ + arg for arg in command + if not (arg.startswith('-W') or arg.startswith('-f')) + ] + + # Path from build dir. + rel_path = os.path.relpath(os.path.abspath(filepath), out_dir) + + # Replace clang++ by clang-tidy + command[0:1] = [GetClangTidyPath(), CHECKER_OPTION, rel_path + ] + args + ['--'] # Separator for clang flags. + print("Running: %s" % ' '.join(command)) + # Run from build dir so that relative paths are correct. + p = subprocess.Popen(command, + cwd=out_dir, + stdout=sys.stdout, + stderr=sys.stderr) + p.communicate() + return p.returncode + finally: + shutil.rmtree(out_dir, ignore_errors=True) + + +def ValidateCC(filepath): + """We can only analyze .cc files. Provide explicit message about that.""" + if filepath.endswith('.cc'): + return filepath + msg = ('%s not supported.\n' + 'For now, we can only analyze translation units (.cc files).' % + filepath) + raise argparse.ArgumentTypeError(msg) + + +def Main(): + description = ( + "Run clang-tidy on single cc file.\n" + "Use flags, defines and include paths as in default debug build.\n" + "WARNING, this is a POC version with rough edges.") + parser = argparse.ArgumentParser(description=description) + parser.add_argument('filepath', + help='Specifies the path of the .cc file to analyze.', + type=ValidateCC) + parser.add_argument('args', + nargs=argparse.REMAINDER, + help='Arguments passed to clang-tidy') + parsed_args = parser.parse_args() + return Process(parsed_args.filepath, parsed_args.args) + + +if __name__ == '__main__': + sys.exit(Main()) |