Skip to content

Commit 91d07d7

Browse files
committed
[clang-tidy] Export fixes from check_clang_tidy.py
Makes it possible to export fixes from running llvm-lit on a clang-tidy test. To enable, modify the RUN invocation directly in the test with the new -export flag. llvm-lit will report the test passed and fixes can be found in the file specified to the -export flag.
1 parent 938a734 commit 91d07d7

File tree

2 files changed

+53
-19
lines changed

2 files changed

+53
-19
lines changed

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ Improvements to clang-tidy
100100
- Improved :program:`run-clang-tidy.py` script. Added argument `-source-filter`
101101
to filter source files from the compilation database, via a RegEx. In a
102102
similar fashion to what `-header-filter` does for header files.
103+
- Improved :program:`check_clang_tidy.py` script. Added argument `-export`
104+
to aid in clang-tidy and test development.
103105

104106
New checks
105107
^^^^^^^^^^

clang-tools-extra/test/clang-tidy/check_clang_tidy.py

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,43 @@
88
#
99
# ===------------------------------------------------------------------------===#
1010

11-
r"""
11+
"""
1212
ClangTidy Test Helper
1313
=====================
1414
15-
This script runs clang-tidy in fix mode and verify fixes, messages or both.
15+
This script is used to simplify writing, running, and debugging tests compatible
16+
with llvm-lit. By default it runs clang-tidy in fix mode and uses FileCheck to
17+
verify messages and/or fixes.
18+
19+
For debugging, with --export, the tool simply exports fixes to a provided file
20+
and does not run FileCheck.
21+
22+
Extra arguments, those after the first -- if any, are passed to either
23+
clang-tidy or clang:
24+
* Arguments between the first -- and second -- are clang-tidy arguments.
25+
* May be only whitespace if there are no clang-tidy arguments.
26+
* clang-tidy's --config would go here.
27+
* Arguments after the second -- are clang arguments
1628
17-
Usage:
18-
check_clang_tidy.py [-resource-dir=<resource-dir>] \
19-
[-assume-filename=<file-with-source-extension>] \
20-
[-check-suffix=<comma-separated-file-check-suffixes>] \
21-
[-check-suffixes=<comma-separated-file-check-suffixes>] \
22-
[-std=c++(98|11|14|17|20)[-or-later]] \
23-
<source-file> <check-name> <temp-file> \
24-
-- [optional clang-tidy arguments]
29+
Examples
30+
--------
2531
26-
Example:
2732
// RUN: %check_clang_tidy %s llvm-include-order %t -- -- -isystem %S/Inputs
2833
29-
Notes:
34+
or
35+
36+
// RUN: %check_clang_tidy %s llvm-include-order --export=fixes.yaml %t -std=c++20
37+
38+
Notes
39+
-----
3040
-std=c++(98|11|14|17|20)-or-later:
3141
This flag will cause multiple runs within the same check_clang_tidy
3242
execution. Make sure you don't have shared state across these runs.
3343
"""
3444

3545
import argparse
3646
import os
47+
import pathlib
3748
import re
3849
import subprocess
3950
import sys
@@ -88,6 +99,7 @@ def __init__(self, args, extra_args):
8899
self.has_check_fixes = False
89100
self.has_check_messages = False
90101
self.has_check_notes = False
102+
self.export = args.export
91103
self.fixes = MessagePrefix("CHECK-FIXES")
92104
self.messages = MessagePrefix("CHECK-MESSAGES")
93105
self.notes = MessagePrefix("CHECK-NOTES")
@@ -181,7 +193,9 @@ def run_clang_tidy(self):
181193
[
182194
"clang-tidy",
183195
self.temp_file_name,
184-
"-fix",
196+
]
197+
+ ["-fix" if self.export is None else "--export-fixes=" + self.export]
198+
+ [
185199
"--checks=-*," + self.check_name,
186200
]
187201
+ self.clang_tidy_extra_args
@@ -255,12 +269,14 @@ def check_notes(self, clang_tidy_output):
255269

256270
def run(self):
257271
self.read_input()
258-
self.get_prefixes()
272+
if self.export is None:
273+
self.get_prefixes()
259274
self.prepare_test_inputs()
260275
clang_tidy_output = self.run_clang_tidy()
261-
self.check_fixes()
262-
self.check_messages(clang_tidy_output)
263-
self.check_notes(clang_tidy_output)
276+
if self.export is None:
277+
self.check_fixes()
278+
self.check_messages(clang_tidy_output)
279+
self.check_notes(clang_tidy_output)
264280

265281

266282
def expand_std(std):
@@ -284,7 +300,11 @@ def csv(string):
284300

285301

286302
def parse_arguments():
287-
parser = argparse.ArgumentParser()
303+
parser = argparse.ArgumentParser(
304+
prog=pathlib.Path(__file__).stem,
305+
description=__doc__,
306+
formatter_class=argparse.RawDescriptionHelpFormatter,
307+
)
288308
parser.add_argument("-expect-clang-tidy-error", action="store_true")
289309
parser.add_argument("-resource-dir")
290310
parser.add_argument("-assume-filename")
@@ -298,7 +318,19 @@ def parse_arguments():
298318
type=csv,
299319
help="comma-separated list of FileCheck suffixes",
300320
)
301-
parser.add_argument("-std", type=csv, default=["c++11-or-later"])
321+
parser.add_argument(
322+
"-export",
323+
default=None,
324+
type=str,
325+
metavar="file",
326+
help="A file to export fixes into instead of fixing.",
327+
)
328+
parser.add_argument(
329+
"-std",
330+
type=csv,
331+
default=["c++11-or-later"],
332+
help="Passed to clang. Special -or-later values are expanded.",
333+
)
302334
return parser.parse_known_args()
303335

304336

0 commit comments

Comments
 (0)