diff options
| author | Ralf Luther <luther.ralf@gmail.com> | 2019-03-27 20:23:17 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit2@aicp-server-3> | 2019-03-27 20:23:17 +0000 |
| commit | 1ce3a9d272e564b22a1333a1e36a3d3ab7cfab01 (patch) | |
| tree | 391382eadd4fec5bb480f2e8934fa352770221d1 /clang-r353983/bin/clang-tidy | |
| parent | d1d48b140bafaa8a50107292f5fce95562575765 (diff) | |
| parent | 4f56932d3416ac03f646bc1a611b3135fec2fe08 (diff) | |
Merge "Update prebuilt Clang to r353983." into p9.0HEADp9.0-backupp9.0
Diffstat (limited to 'clang-r353983/bin/clang-tidy')
| -rwxr-xr-x | clang-r353983/bin/clang-tidy | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/clang-r353983/bin/clang-tidy b/clang-r353983/bin/clang-tidy new file mode 100755 index 00000000..081cb20a --- /dev/null +++ b/clang-r353983/bin/clang-tidy @@ -0,0 +1,192 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# pylint: disable=not-callable, relative-import + +# Note that adding top-level imports is discouraged unless they're guaranteed to +# be used. Unnecessary imports eat a measurable number of cycles of this +# wrapper. +import os +import sys + +BISECT_STAGE = os.environ.get('BISECT_STAGE') +# We do not need bisect functionality with Goma and clang. +# Goma server does not have bisect_driver, so we only import +# bisect_driver when needed. See http://b/34862041 +# We should be careful when doing imports because of Goma. +if BISECT_STAGE: + import bisect_driver + +DEFAULT_BISECT_DIR = os.path.expanduser('~/ANDROID_BISECT') +BISECT_DIR = os.environ.get('BISECT_DIR') or DEFAULT_BISECT_DIR +STDERR_REDIRECT_KEY = 'ANDROID_LLVM_STDERR_REDIRECT' +PREBUILT_COMPILER_PATH_KEY = 'ANDROID_LLVM_PREBUILT_COMPILER_PATH' +DISABLED_WARNINGS_KEY = 'ANDROID_LLVM_FALLBACK_DISABLED_WARNINGS' + + +def ProcessArgFile(arg_file): + import shlex + + args = [] + # Read in entire file at once and parse as if in shell + with open(arg_file, 'rb') as f: + args.extend(shlex.split(f.read())) + return args + + +def write_log(path, command, log): + import errno + import fcntl + import time + + with open(path, 'a+') as f: + while True: + try: + fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB) + break + except IOError as e: + if e.errno == errno.EAGAIN or e.errno == errno.EACCES: + time.sleep(0.5) + f.write('==================COMMAND:====================\n') + f.write(' '.join(command) + '\n\n') + f.write(log) + f.write('==============================================\n\n') + + +class CompilerWrapper(object): + + def __init__(self, argv): + self.argv0_current = argv[0] + self.args = argv[1:] + self.execargs = [] + self.real_compiler = None + self.argv0 = None + self.append_flags = [] + self.prepend_flags = [] + self.custom_flags = {'--gomacc-path': None} + + def set_real_compiler(self): + """Find the real compiler with the absolute path.""" + compiler_path = os.path.dirname(self.argv0_current) + if os.path.islink(__file__): + compiler = os.path.basename(os.readlink(__file__)) + else: + compiler = os.path.basename(os.path.abspath(__file__)) + self.real_compiler = os.path.join(compiler_path, compiler + '.real') + self.argv0 = self.real_compiler + + def process_gomacc_command(self): + """Return the gomacc command if '--gomacc-path' is set.""" + gomacc = self.custom_flags['--gomacc-path'] + if gomacc and os.path.isfile(gomacc): + self.argv0 = gomacc + self.execargs += [gomacc] + + def parse_custom_flags(self): + i = 0 + args = [] + while i < len(self.args): + if self.args[i] in self.custom_flags: + if i >= len(self.args) - 1: + sys.exit('The value of {} is not set.'.format(self.args[i])) + self.custom_flags[self.args[i]] = self.args[i + 1] + i = i + 2 + else: + args.append(self.args[i]) + i = i + 1 + self.args = args + + def add_flags(self): + self.args = self.prepend_flags + self.args + self.append_flags + + def prepare_compiler_args(self, enable_fallback=False): + self.set_real_compiler() + self.parse_custom_flags() + # Goma should not be enabled for new prebuilt. + if not enable_fallback: + self.process_gomacc_command() + self.add_flags() + self.execargs += [self.real_compiler] + self.args + + def exec_clang_with_fallback(self): + import subprocess + + extra_args_begin = len(self.execargs) + + # We only want to pass extra flags to clang and clang++. + if os.path.basename(__file__) in ['clang', 'clang++']: + # We may introduce some new warnings after rebasing and we need to + # disable them before we fix those warnings. + disabled_warnings_env = os.environ.get(DISABLED_WARNINGS_KEY, '') + disabled_warnings = disabled_warnings_env.split(' ') + self.execargs += ['-fno-color-diagnostics'] + disabled_warnings + + p = subprocess.Popen(self.execargs, stderr=subprocess.PIPE) + (_, err) = p.communicate() + sys.stderr.write(err) + if p.returncode != 0: + redirect_path = os.environ[STDERR_REDIRECT_KEY] + write_log(redirect_path, self.execargs, err) + fallback_arg0 = os.path.join(os.environ[PREBUILT_COMPILER_PATH_KEY], + os.path.basename(__file__)) + + # Delete PREBUILT_COMPILER_PATH_KEY so the fallback doesn't keep + # calling itself in case of an error. + del os.environ[PREBUILT_COMPILER_PATH_KEY] + + # Strip extra args added (from DISABLED_WARNINGS_KEY) for clang and + # clang++ above. They may not be recognized by the fallback clang. + self.execargs = self.execargs[:extra_args_begin] + + os.execv(fallback_arg0, [fallback_arg0] + self.execargs[1:]) + + def invoke_compiler(self): + enable_fallback = PREBUILT_COMPILER_PATH_KEY in os.environ + self.prepare_compiler_args(enable_fallback) + if enable_fallback: + self.exec_clang_with_fallback() + else: + os.execv(self.argv0, self.execargs) + + def bisect(self): + self.prepare_compiler_args() + # Handle @file argument syntax with compiler + idx = 0 + # The length of self.execargs can be changed during the @file argument + # expansion, so we need to use while loop instead of for loop. + while idx < len(self.execargs): + if self.execargs[idx][0] == '@': + args_in_file = ProcessArgFile(self.execargs[idx][1:]) + self.execargs = self.execargs[0:idx] + args_in_file +\ + self.execargs[idx + 1:] + # Skip update of idx, since we want to recursively expand + # response files. + else: + idx = idx + 1 + bisect_driver.bisect_driver(BISECT_STAGE, BISECT_DIR, self.execargs) + + +def main(argv): + cw = CompilerWrapper(argv) + if BISECT_STAGE and BISECT_STAGE in bisect_driver.VALID_MODES\ + and '-o' in argv: + cw.bisect() + else: + cw.invoke_compiler() + + +if __name__ == '__main__': + main(sys.argv) |
