Skip to content

Commit 0c1f7d8

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-fixes 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 0c1f7d8

File tree

2 files changed

+57
-19
lines changed

2 files changed

+57
-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-fixes`
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: 55 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-fixes, the tool simply exports fixes to a provided
20+
file and does not run FileCheck.
1621
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]
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
28+
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=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_fixes = args.export_fixes
91103
self.fixes = MessagePrefix("CHECK-FIXES")
92104
self.messages = MessagePrefix("CHECK-MESSAGES")
93105
self.notes = MessagePrefix("CHECK-NOTES")
@@ -181,7 +193,13 @@ def run_clang_tidy(self):
181193
[
182194
"clang-tidy",
183195
self.temp_file_name,
184-
"-fix",
196+
]
197+
+ [
198+
"-fix"
199+
if self.export_fixes is None
200+
else "--export-fixes=" + self.export_fixes
201+
]
202+
+ [
185203
"--checks=-*," + self.check_name,
186204
]
187205
+ self.clang_tidy_extra_args
@@ -255,12 +273,14 @@ def check_notes(self, clang_tidy_output):
255273

256274
def run(self):
257275
self.read_input()
258-
self.get_prefixes()
276+
if self.export_fixes is None:
277+
self.get_prefixes()
259278
self.prepare_test_inputs()
260279
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)
280+
if self.export_fixes is None:
281+
self.check_fixes()
282+
self.check_messages(clang_tidy_output)
283+
self.check_notes(clang_tidy_output)
264284

265285

266286
def expand_std(std):
@@ -284,7 +304,11 @@ def csv(string):
284304

285305

286306
def parse_arguments():
287-
parser = argparse.ArgumentParser()
307+
parser = argparse.ArgumentParser(
308+
prog=pathlib.Path(__file__).stem,
309+
description=__doc__,
310+
formatter_class=argparse.RawDescriptionHelpFormatter,
311+
)
288312
parser.add_argument("-expect-clang-tidy-error", action="store_true")
289313
parser.add_argument("-resource-dir")
290314
parser.add_argument("-assume-filename")
@@ -298,7 +322,19 @@ def parse_arguments():
298322
type=csv,
299323
help="comma-separated list of FileCheck suffixes",
300324
)
301-
parser.add_argument("-std", type=csv, default=["c++11-or-later"])
325+
parser.add_argument(
326+
"-export-fixes",
327+
default=None,
328+
type=str,
329+
metavar="file",
330+
help="A file to export fixes into instead of fixing.",
331+
)
332+
parser.add_argument(
333+
"-std",
334+
type=csv,
335+
default=["c++11-or-later"],
336+
help="Passed to clang. Special -or-later values are expanded.",
337+
)
302338
return parser.parse_known_args()
303339

304340

0 commit comments

Comments
 (0)