zinovy.nis updated this revision to Diff 193023.
zinovy.nis added a comment.
Herald added a subscriber: jdoerfert.
Added a test.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D59449/new/
https://reviews.llvm.org/D59449
Files:
clang-tidy/tool/run-clang-tidy.py
test/clang-tidy/run-clang-tidy-diff.cpp
Index: test/clang-tidy/run-clang-tidy-diff.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/run-clang-tidy-diff.cpp
@@ -0,0 +1,27 @@
+// REQUIRES: shell
+// RUN: mkdir -p "%t"
+// RUN: cd "%t"
+// RUN: sed 's/placeholder_for_f/f/' %s > diff_to.cpp
+// RUN: echo '[{"directory": "%t", "command": "clang++ -o test.o -std=c++11 diff_to.cpp", "file": "diff_to.cpp"}]' > compile_commands.json
+// RUN: clang-tidy -checks=-*,modernize-use-override diff_to.cpp -- -std=c++11 | FileCheck -check-prefix=CHECK-SANITY %s
+// RUN: not diff -U0 %s diff_to.cpp | %run_clang_tidy --diff=0 -checks=-*,modernize-use-override 2>&1 | FileCheck %s
+// RUN: not diff -U0 %s diff_to.cpp | %run_clang_tidy --diff=0 -checks=-*,modernize-use-override -quiet 2>&1 | FileCheck -check-prefix=CHECK-QUIET %s
+// RUN: not diff -U0 %s diff_to.cpp | %run_clang_tidy --diff=0 -checks=-*,modernize-use-override 2>&1 | FileCheck -check-prefix=CHECK %s
+struct A {
+ virtual void f() {}
+ virtual void g() {}
+};
+// CHECK-NOT: warning:
+// CHECK-QUIET-NOT: warning:
+struct B : public A {
+ void placeholder_for_f() {}
+// CHECK-SANITY: [[@LINE-1]]:8: warning: annotate this
+// CHECK: [[@LINE-2]]:8: warning: annotate this
+// CHECK-QUIET: [[@LINE-3]]:8: warning: annotate this
+ void g() {}
+// CHECK-SANITY: [[@LINE-1]]:8: warning: annotate this
+// CHECK-NOT: warning:
+// CHECK-QUIET-NOT: warning:
+};
+// CHECK-SANITY-NOT: Suppressed
+// CHECK-QUIET-NOT: Suppressed
Index: clang-tidy/tool/run-clang-tidy.py
===================================================================
--- clang-tidy/tool/run-clang-tidy.py
+++ clang-tidy/tool/run-clang-tidy.py
@@ -7,7 +7,6 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
#===------------------------------------------------------------------------===#
-# FIXME: Integrate with clang-tidy-diff.py
"""
Parallel clang-tidy runner
@@ -60,6 +59,7 @@
else:
import queue as queue
+
def find_compilation_database(path):
"""Adjusts the directory until a compilation database is found."""
result = './'
@@ -77,7 +77,7 @@
return os.path.normpath(os.path.join(directory, f))
-def get_tidy_invocation(f, clang_tidy_binary, checks, tmpdir, build_path,
+def get_tidy_invocation(f, lines, clang_tidy_binary, checks, tmpdir, build_path,
header_filter, extra_arg, extra_arg_before, quiet,
config):
"""Gets a command line for clang-tidy."""
@@ -87,6 +87,12 @@
else:
# Show warnings in all in-project headers by default.
start.append('-header-filter=^' + build_path + '/.*')
+
+ if lines is not None:
+ line_json = json.dumps([{"name": f, "lines": lines}], separators=(',', ':'))
+ # Run clang-tidy on files containing changes.
+ start.append('-line-filter=' + line_json)
+
if checks:
start.append('-checks=' + checks)
if tmpdir is not None:
@@ -159,8 +165,9 @@
def run_tidy(args, tmpdir, build_path, queue, lock, failed_files):
"""Takes filenames out of queue and runs clang-tidy on them."""
while True:
- name = queue.get()
- invocation = get_tidy_invocation(name, args.clang_tidy_binary, args.checks,
+ (name, lines) = queue.get()
+ invocation = get_tidy_invocation(name, lines,
+ args.clang_tidy_binary, args.checks,
tmpdir, build_path, args.header_filter,
args.extra_arg, args.extra_arg_before,
args.quiet, args.config)
@@ -176,11 +183,42 @@
queue.task_done()
+def get_changed_lines(prefix_len):
+ iregex = '^%s$' % r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc)'
+ lines_by_file = {}
+ filename = None
+ for line in sys.stdin:
+ match = re.search('^\+\+\+\ \"?(.*?/){%s}([^ \t\n\"]*)' % prefix_len, line)
+ if match:
+ filename = match.group(2)
+ if filename is None:
+ continue
+
+ if not re.match(iregex, filename, re.IGNORECASE):
+ continue
+
+ match = re.search('^@@.*\+(\d+)(,(\d+))?', line)
+ if match:
+ start_line = int(match.group(1))
+ line_count = 1
+ if match.group(3):
+ line_count = int(match.group(3))
+ if line_count == 0:
+ continue
+ end_line = start_line + line_count - 1
+ lines_by_file.setdefault(filename, []).append([start_line, end_line])
+
+ return lines_by_file
+
+
def main():
parser = argparse.ArgumentParser(description='Runs clang-tidy over all files '
'in a compilation database. Requires '
'clang-tidy and clang-apply-replacements in '
'$PATH.')
+ parser.add_argument('--diff', default=None, const=2, nargs='?', type=int,
+ help='check only the diff read from stdin.'
+ ' Strip the smallest prefix containing DIFF[=2] slashes')
parser.add_argument('-clang-tidy-binary', metavar='PATH',
default='clang-tidy',
help='path to clang-tidy binary')
@@ -249,11 +287,6 @@
print("Unable to run clang-tidy.", file=sys.stderr)
sys.exit(1)
- # Load the database and extract all files.
- database = json.load(open(os.path.join(build_path, db_path)))
- files = [make_absolute(entry['file'], entry['directory'])
- for entry in database]
-
max_task = args.j
if max_task == 0:
max_task = multiprocessing.cpu_count()
@@ -265,6 +298,16 @@
# Build up a big regexy filter from all command line arguments.
file_name_re = re.compile('|'.join(args.files))
+ files = None
+ changed_lines = None
+ if args.diff is not None:
+ changed_lines = get_changed_lines(args.diff)
+ files = [(k, v) for k,v in changed_lines.items() if file_name_re.search(k)]
+ else:
+ # Load the database and extract affected files.
+ database = json.load(open(os.path.join(build_path, db_path)))
+ all_files = (make_absolute(entry['file'], entry['directory']) for entry in database)
+ files = [(x, None) for x in all_files if file_name_re.search(x)]
return_code = 0
try:
@@ -281,8 +324,7 @@
# Fill the queue with files.
for name in files:
- if file_name_re.search(name):
- task_queue.put(name)
+ task_queue.put(name)
# Wait for all threads to be done.
task_queue.join()
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits