Skip to content

Commit 4240c91

Browse files
committed
[clang-tidy] Introduce HeaderFileExtensions and ImplementationFileExtensions options
We have a number of checks designed to analyze problems in header files only, for example: bugprone-suspicious-include google-build-namespaces llvm-header-guard misc-definitions-in-header ... All these checks duplicate the same logic and options to determine whether a location is placed in the main source file or in the header. More checks are coming up with similar requirements. Thus, to remove duplication, let's move this option to the top-level configuration of clang-tidy (since it's something all checks should share). Since the checks fetch the option via getLocalOrGlobal, the behavior is unchanged. Add a deprecation notice for all checks that use the local option, prompting to update to the global option. The functionality for parsing the option will need to remain in the checks during the transition period. Once the local options are fully removed, the goal is to store the parsed options in the ClangTidyContext, that checks can easily have access to. Differential Revision: https://reviews.llvm.org/D141000
1 parent c8f5f97 commit 4240c91

File tree

14 files changed

+161
-23
lines changed

14 files changed

+161
-23
lines changed

clang-tools-extra/clang-tidy/ClangTidyOptions.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ template <> struct MappingTraits<ClangTidyOptions> {
122122
bool Ignored = false;
123123
IO.mapOptional("Checks", Options.Checks);
124124
IO.mapOptional("WarningsAsErrors", Options.WarningsAsErrors);
125+
IO.mapOptional("HeaderFileExtensions", Options.HeaderFileExtensions);
126+
IO.mapOptional("ImplementationFileExtensions",
127+
Options.ImplementationFileExtensions);
125128
IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex);
126129
IO.mapOptional("AnalyzeTemporaryDtors", Ignored); // deprecated
127130
IO.mapOptional("FormatStyle", Options.FormatStyle);
@@ -142,6 +145,8 @@ ClangTidyOptions ClangTidyOptions::getDefaults() {
142145
ClangTidyOptions Options;
143146
Options.Checks = "";
144147
Options.WarningsAsErrors = "";
148+
Options.HeaderFileExtensions = {"", "h", "hh", "hpp", "hxx"};
149+
Options.ImplementationFileExtensions = {"c", "cc", "cpp", "cxx"};
145150
Options.HeaderFilterRegex = "";
146151
Options.SystemHeaders = false;
147152
Options.FormatStyle = "none";
@@ -178,6 +183,9 @@ ClangTidyOptions &ClangTidyOptions::mergeWith(const ClangTidyOptions &Other,
178183
unsigned Order) {
179184
mergeCommaSeparatedLists(Checks, Other.Checks);
180185
mergeCommaSeparatedLists(WarningsAsErrors, Other.WarningsAsErrors);
186+
overrideValue(HeaderFileExtensions, Other.HeaderFileExtensions);
187+
overrideValue(ImplementationFileExtensions,
188+
Other.ImplementationFileExtensions);
181189
overrideValue(HeaderFilterRegex, Other.HeaderFilterRegex);
182190
overrideValue(SystemHeaders, Other.SystemHeaders);
183191
overrideValue(FormatStyle, Other.FormatStyle);

clang-tools-extra/clang-tidy/ClangTidyOptions.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ struct ClangTidyOptions {
7272
/// WarningsAsErrors filter.
7373
std::optional<std::string> WarningsAsErrors;
7474

75+
/// File extensions to consider to determine if a given diagnostic is located
76+
/// in a header file.
77+
std::optional<std::vector<std::string>> HeaderFileExtensions;
78+
79+
/// File extensions to consider to determine if a given diagnostic is located
80+
/// is located in an implementation file.
81+
std::optional<std::vector<std::string>> ImplementationFileExtensions;
82+
7583
/// Output warnings from headers matching this filter. Warnings from
7684
/// main files will always be displayed.
7785
std::optional<std::string> HeaderFilterRegex;

clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,14 @@ Configuration files:
4646
4747
$ clang-tidy -dump-config
4848
---
49-
Checks: '-*,some-check'
50-
WarningsAsErrors: ''
51-
HeaderFilterRegex: ''
52-
FormatStyle: none
53-
InheritParentConfig: true
54-
User: user
49+
Checks: '-*,some-check'
50+
WarningsAsErrors: ''
51+
HeaderFileExtensions: ['', 'h','hh','hpp','hxx']
52+
ImplementationFileExtensions: ['c','cc','cpp','cxx']
53+
HeaderFilterRegex: ''
54+
FormatStyle: none
55+
InheritParentConfig: true
56+
User: user
5557
CheckOptions:
5658
some-check.SomeOption: 'some value'
5759
...
@@ -130,10 +132,10 @@ well.
130132
cl::init(false), cl::cat(ClangTidyCategory));
131133

132134
static cl::opt<bool> FixNotes("fix-notes", cl::desc(R"(
133-
If a warning has no fix, but a single fix can
134-
be found through an associated diagnostic note,
135-
apply the fix.
136-
Specifying this flag will implicitly enable the
135+
If a warning has no fix, but a single fix can
136+
be found through an associated diagnostic note,
137+
apply the fix.
138+
Specifying this flag will implicitly enable the
137139
'--fix' flag.
138140
)"),
139141
cl::init(false), cl::cat(ClangTidyCategory));
@@ -458,6 +460,26 @@ static bool verifyChecks(const StringSet<> &AllChecks, StringRef CheckGlob,
458460
return AnyInvalid;
459461
}
460462

463+
static bool verifyFileExtensions(
464+
const std::vector<std::string> &HeaderFileExtensions,
465+
const std::vector<std::string> &ImplementationFileExtensions,
466+
StringRef Source) {
467+
bool AnyInvalid = false;
468+
for (const auto &HeaderExtension : HeaderFileExtensions) {
469+
for (const auto &ImplementationExtension : ImplementationFileExtensions) {
470+
if (HeaderExtension == ImplementationExtension) {
471+
AnyInvalid = true;
472+
auto &Output = llvm::WithColor::warning(llvm::errs(), Source)
473+
<< "HeaderFileExtension '" << HeaderExtension << '\''
474+
<< " is the same as ImplementationFileExtension '"
475+
<< ImplementationExtension << '\'';
476+
Output << VerifyConfigWarningEnd;
477+
}
478+
}
479+
}
480+
return AnyInvalid;
481+
}
482+
461483
int clangTidyMain(int argc, const char **argv) {
462484
llvm::InitLLVM X(argc, argv);
463485

@@ -561,6 +583,11 @@ int clangTidyMain(int argc, const char **argv) {
561583
if (Opts.Checks)
562584
AnyInvalid |= verifyChecks(Valid.Names, *Opts.Checks, Source);
563585

586+
if (Opts.HeaderFileExtensions && Opts.ImplementationFileExtensions)
587+
AnyInvalid |=
588+
verifyFileExtensions(*Opts.HeaderFileExtensions,
589+
*Opts.ImplementationFileExtensions, Source);
590+
564591
for (auto Key : Opts.CheckOptions.keys()) {
565592
if (Valid.Options.contains(Key))
566593
continue;

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ Improvements to clang-tidy
106106
which is no longer in use. The option will be fully removed in
107107
:program:`clang-tidy` version 18.
108108

109+
- New global configuration file options `HeaderFileExtensions` and
110+
`ImplementationFileExtensions`, replacing the check-local options of the
111+
same name.
112+
109113
New checks
110114
^^^^^^^^^^
111115

@@ -157,26 +161,61 @@ Changes in existing checks
157161
<clang-tidy/checks/bugprone/assignment-in-if-condition>` check when there
158162
was an assignement in a lambda found in the condition of an ``if``.
159163

164+
- Deprecated check-local options `HeaderFileExtensions` and `ImplementationFileExtensions`
165+
in :doc:`bugprone-dynamic-static-initializers
166+
<clang-tidy/checks/bugprone/dynamic-static-initializers>` check.
167+
Global options of the same name should be used instead.
168+
160169
- Improved :doc:`bugprone-signal-handler
161170
<clang-tidy/checks/bugprone/signal-handler>` check. Partial
162171
support for C++14 signal handler rules was added. Bug report generation was
163172
improved.
164173

174+
- Deprecated check-local options `HeaderFileExtensions` and `ImplementationFileExtensions`
175+
in :doc:`bugprone-suspicious-include
176+
<clang-tidy/checks/bugprone/suspicious-include>` check.
177+
Global options of the same name should be used instead.
178+
165179
- Fixed a false positive in :doc:`cppcoreguidelines-pro-type-member-init
166180
<clang-tidy/checks/cppcoreguidelines/pro-type-member-init>` when warnings
167181
would be emitted for uninitialized members of an anonymous union despite
168182
there being an initializer for one of the other members.
169183

184+
- Deprecated check-local options `HeaderFileExtensions` and `ImplementationFileExtensions`
185+
in :doc:`google-build-namespaces
186+
<clang-tidy/checks/google/build-namespaces>` check.
187+
Global options of the same name should be used instead.
188+
189+
- Deprecated check-local options `HeaderFileExtensions` and `ImplementationFileExtensions`
190+
in :doc:`google-global-names-in-headers
191+
<clang-tidy/checks/google/global-names-in-headers>` check.
192+
Global options of the same name should be used instead.
193+
170194
- Fixed false positives in :doc:`google-objc-avoid-throwing-exception
171195
<clang-tidy/checks/google/objc-avoid-throwing-exception>` check for exceptions
172196
thrown by code emitted from macros in system headers.
173197

198+
- Deprecated check-local options `HeaderFileExtensions` and `ImplementationFileExtensions`
199+
in :doc:`llvm-header-guard
200+
<clang-tidy/checks/llvm/header-guard>` check.
201+
Global options of the same name should be used instead.
202+
203+
- Deprecated check-local options `HeaderFileExtensions` and `ImplementationFileExtensions`
204+
in :doc:`misc-definitions-in-headers
205+
<clang-tidy/checks/misc/definitions-in-headers>` check.
206+
Global options of the same name should be used instead.
207+
174208
- Improved :doc:`misc-redundant-expression <clang-tidy/checks/misc/redundant-expression>`
175209
check.
176210

177211
The check now skips concept definitions since redundant expressions still make sense
178212
inside them.
179213

214+
- Deprecated check-local options `HeaderFileExtensions` and `ImplementationFileExtensions`
215+
in :doc:`misc-unused-using-decls
216+
<clang-tidy/checks/misc/misc-unused-using-decls>` check.
217+
Global options of the same name should be used instead.
218+
180219
- Improved :doc:`modernize-loop-convert <clang-tidy/checks/modernize/loop-convert>`
181220
to check for container functions ``begin``/``end`` etc on base classes of the container
182221
type, instead of only as direct members of the container type itself.

clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-include.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ Options
1919
-------
2020
.. option:: HeaderFileExtensions
2121

22+
Note: this option is deprecated, it will be removed in :program:`clang-tidy`
23+
version 18. Please use the global configuration option
24+
`HeaderFileExtensions`.
25+
2226
Default value: ``";h;hh;hpp;hxx"``
2327
A semicolon-separated list of filename extensions of header files (the
2428
filename extensions should not contain a "." prefix). For extension-less
@@ -27,6 +31,10 @@ Options
2731

2832
.. option:: ImplementationFileExtensions
2933

34+
Note: this option is deprecated, it will be removed in :program:`clang-tidy`.
35+
version 18. Please use the global configuration option
36+
`ImplementationFileExtensions`.
37+
3038
Default value: ``"c;cc;cpp;cxx"``
3139
Likewise, a semicolon-separated list of filename extensions of
3240
implementation files.

clang-tools-extra/docs/clang-tidy/checks/google/build-namespaces.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ Options
1717

1818
.. option:: HeaderFileExtensions
1919

20+
Note: this option is deprecated, it will be removed in :program:`clang-tidy`
21+
version 18. Please use the global configuration option
22+
`HeaderFileExtensions`.
23+
2024
A comma-separated list of filename extensions of header files (the filename
2125
extensions should not include "." prefix). Default is "h,hh,hpp,hxx".
2226
For header files without an extension, use an empty string (if there are no

clang-tools-extra/docs/clang-tidy/checks/google/global-names-in-headers.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Options
1414

1515
.. option:: HeaderFileExtensions
1616

17+
Note: this option is deprecated, it will be removed in :program:`clang-tidy`
18+
version 18. Please use the global configuration option
19+
`HeaderFileExtensions`.
20+
1721
A comma-separated list of filename extensions of header files (the filename
1822
extensions should not contain "." prefix). Default is "h".
1923
For header files without an extension, use an empty string (if there are no

clang-tools-extra/docs/clang-tidy/checks/llvm/header-guard.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ Options
1010

1111
.. option:: HeaderFileExtensions
1212

13+
Note: this option is deprecated, it will be removed in :program:`clang-tidy`
14+
version 18. Please use the global configuration option
15+
`HeaderFileExtensions`.
16+
1317
A comma-separated list of filename extensions of header files (the filename
1418
extensions should not include "." prefix). Default is "h,hh,hpp,hxx".
1519
For header files without an extension, use an empty string (if there are no

clang-tools-extra/docs/clang-tidy/checks/misc/definitions-in-headers.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ Options
9292

9393
.. option:: HeaderFileExtensions
9494

95+
Note: this option is deprecated, it will be removed in :program:`clang-tidy`
96+
version 18. Please use the global configuration option
97+
`HeaderFileExtensions`.
98+
9599
A comma-separated list of filename extensions of header files (the filename
96100
extensions should not include "." prefix). Default is "h,hh,hpp,hxx".
97101
For header files without an extension, use an empty string (if there are no
@@ -100,5 +104,9 @@ Options
100104

101105
.. option:: UseHeaderFileExtension
102106

107+
Note: this option is deprecated, it will be removed in :program:`clang-tidy`
108+
version 18. The check will unconditionally use the global option
109+
`HeaderFileExtensions`.
110+
103111
When `true`, the check will use the file extension to distinguish header
104112
files. Default is `true`.

clang-tools-extra/docs/clang-tidy/checks/misc/unused-using-decls.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ Options
2222

2323
.. option:: HeaderFileExtensions
2424

25+
Note: this option is deprecated, it will be removed in :program:`clang-tidy`
26+
version 18. Please use the global configuration option
27+
`HeaderFileExtensions`.
28+
2529
A semicolon-separated list of filename extensions of header files (the filename
2630
extensions should not include "." prefix). Default is "h,hh,hpp,hxx".
2731
For extension-less header files, use an empty string or leave an

clang-tools-extra/docs/clang-tidy/checks/misc/use-anonymous-namespace.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ Options
3838

3939
.. option:: HeaderFileExtensions
4040

41+
Note: this option is deprecated, it will be removed in :program:`clang-tidy`
42+
version 18. Please use the global configuration option
43+
`HeaderFileExtensions`.
44+
4145
A semicolon-separated list of filename extensions of header files (the filename
4246
extensions should not include "." prefix). Default is ";h;hh;hpp;hxx".
4347
For extension-less header files, using an empty string or leaving an

clang-tools-extra/docs/clang-tidy/index.rst

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ An overview of all the command-line options:
139139
When the value is empty, clang-tidy will
140140
attempt to find a file named .clang-tidy for
141141
each source file in its parent directories.
142-
--config-file=<string> -
142+
--config-file=<string> -
143143
Specify the path of .clang-tidy or custom config file:
144144
e.g. --config-file=/some/path/myTidyConfigFile
145145
This option internally works exactly the same way as
@@ -237,7 +237,7 @@ An overview of all the command-line options:
237237
format to stderr. When this option is passed,
238238
these per-TU profiles are instead stored as JSON.
239239
--system-headers - Display the errors from system headers.
240-
--use-color -
240+
--use-color -
241241
Use colors in diagnostics. If not set, colors
242242
will be used if the terminal connected to
243243
standard output supports colors.
@@ -287,12 +287,14 @@ An overview of all the command-line options:
287287
288288
$ clang-tidy -dump-config
289289
---
290-
Checks: '-*,some-check'
291-
WarningsAsErrors: ''
292-
HeaderFilterRegex: ''
293-
FormatStyle: none
294-
InheritParentConfig: true
295-
User: user
290+
Checks: '-*,some-check'
291+
WarningsAsErrors: ''
292+
HeaderFileExtensions: ['', 'h','hh','hpp','hxx']
293+
ImplementationFileExtensions: ['c','cc','cpp','cxx']
294+
HeaderFilterRegex: ''
295+
FormatStyle: none
296+
InheritParentConfig: true
297+
User: user
296298
CheckOptions:
297299
some-check.SomeOption: 'some value'
298300
...

clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
// RUN: not clang-tidy -verify-config \
55
// RUN: --checks='-*,bad*glob,llvm*,llvm-includeorder,my-made-up-check' --config='{Checks: "readability-else-after-ret", \
6+
// RUN: HeaderFileExtensions: ["h", "hh", "hpp"], \
7+
// RUN: ImplementationFileExtensions: ["c", "cc", "hpp"], \
68
// RUN: CheckOptions: [{key: "IgnoreMacros", value: "true"}, \
79
// RUN: {key: "StriceMode", value: "true"}, \
810
// RUN: {key: modernize-lop-convert.UseCxx20ReverseRanges, value: true} \
@@ -12,6 +14,7 @@
1214
// CHECK-VERIFY-DAG: command-line option '-config': warning: unknown check 'readability-else-after-ret'; did you mean 'readability-else-after-return' [-verify-config]
1315
// CHECK-VERIFY-DAG: command-line option '-config': warning: unknown check option 'modernize-lop-convert.UseCxx20ReverseRanges'; did you mean 'modernize-loop-convert.UseCxx20ReverseRanges' [-verify-config]
1416
// CHECK-VERIFY-DAG: command-line option '-config': warning: unknown check option 'StriceMode'; did you mean 'StrictMode' [-verify-config]
17+
// CHECK-VERIFY-DAG: command-line option '-config': warning: HeaderFileExtension 'hpp' is the same as ImplementationFileExtension 'hpp' [-verify-config]
1518
// CHECK-VERIFY: command-line option '-checks': warning: check glob 'bad*glob' doesn't match any known check [-verify-config]
1619
// CHECK-VERIFY: command-line option '-checks': warning: unknown check 'llvm-includeorder'; did you mean 'llvm-include-order' [-verify-config]
1720
// CHECK-VERIFY: command-line option '-checks': warning: unknown check 'my-made-up-check' [-verify-config]

0 commit comments

Comments
 (0)