run-clang-tidy: forward clang-tidy exit status

Exit with a non-zero value in case any of the underlying clang-tidy
invocations exit with a non-zero value.

This is useful in case WarningsAsErrors is enabled for some of the
checks: if any of those checks find something, the exit status now
reflects that.

Also add the ability to use run-clang-tidy.py via lit, and assert that
the exit code is not 0 when modernize-use-auto is triggered
intentionally.

Reviewers: alexfh, aaron.ballman

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D44366

llvm-svn: 327854
diff --git a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
index 2430312..ce46c0e 100755
--- a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
+++ b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
@@ -153,7 +153,7 @@
   subprocess.call(invocation)
 
 
-def run_tidy(args, tmpdir, build_path, queue):
+def run_tidy(args, tmpdir, build_path, queue, failed_files):
   """Takes filenames out of queue and runs clang-tidy on them."""
   while True:
     name = queue.get()
@@ -162,7 +162,9 @@
                                      args.extra_arg, args.extra_arg_before,
                                      args.quiet, args.config)
     sys.stdout.write(' '.join(invocation) + '\n')
-    subprocess.call(invocation)
+    return_code = subprocess.call(invocation)
+    if return_code != 0:
+      failed_files.append(name)
     queue.task_done()
 
 
@@ -255,12 +257,15 @@
   # Build up a big regexy filter from all command line arguments.
   file_name_re = re.compile('|'.join(args.files))
 
+  return_code = 0
   try:
     # Spin up a bunch of tidy-launching threads.
     task_queue = queue.Queue(max_task)
+    # List of files with a non-zero return code.
+    failed_files = []
     for _ in range(max_task):
       t = threading.Thread(target=run_tidy,
-                           args=(args, tmpdir, build_path, task_queue))
+                           args=(args, tmpdir, build_path, task_queue, failed_files))
       t.daemon = True
       t.start()
 
@@ -271,6 +276,8 @@
 
     # Wait for all threads to be done.
     task_queue.join()
+    if len(failed_files):
+      return_code = 1
 
   except KeyboardInterrupt:
     # This is a sad hack. Unfortunately subprocess goes
@@ -280,7 +287,6 @@
       shutil.rmtree(tmpdir)
     os.kill(0, 9)
 
-  return_code = 0
   if args.export_fixes:
     print('Writing fixes to ' + args.export_fixes + ' ...')
     try: