@@ -59,7 +59,9 @@ IncludeCleanerCheck::IncludeCleanerCheck(StringRef Name,
59
59
: ClangTidyCheck(Name, Context),
60
60
IgnoreHeaders (
61
61
utils::options::parseStringList (Options.get(" IgnoreHeaders" , " " ))),
62
- DeduplicateFindings(Options.get(" DeduplicateFindings" , true )) {
62
+ DeduplicateFindings(Options.get(" DeduplicateFindings" , true )),
63
+ UnusedIncludes(Options.get(" UnusedIncludes" , true )),
64
+ MissingIncludes(Options.get(" MissingIncludes" , true )) {
63
65
for (const auto &Header : IgnoreHeaders) {
64
66
if (!llvm::Regex{Header}.isValid ())
65
67
configurationDiag (" Invalid ignore headers regex '%0'" ) << Header;
@@ -74,6 +76,8 @@ void IncludeCleanerCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
74
76
Options.store (Opts, " IgnoreHeaders" ,
75
77
utils::options::serializeStringList (IgnoreHeaders));
76
78
Options.store (Opts, " DeduplicateFindings" , DeduplicateFindings);
79
+ Options.store (Opts, " UnusedIncludes" , UnusedIncludes);
80
+ Options.store (Opts, " MissingIncludes" , MissingIncludes);
77
81
}
78
82
79
83
bool IncludeCleanerCheck::isLanguageVersionSupported (
@@ -200,39 +204,43 @@ void IncludeCleanerCheck::check(const MatchFinder::MatchResult &Result) {
200
204
if (!FileStyle)
201
205
FileStyle = format::getLLVMStyle ();
202
206
203
- for (const auto *Inc : Unused) {
204
- diag (Inc->HashLocation , " included header %0 is not used directly" )
205
- << llvm::sys::path::filename (Inc->Spelled ,
206
- llvm::sys::path::Style::posix)
207
- << FixItHint::CreateRemoval (CharSourceRange::getCharRange (
208
- SM->translateLineCol (SM->getMainFileID (), Inc->Line , 1 ),
209
- SM->translateLineCol (SM->getMainFileID (), Inc->Line + 1 , 1 )));
207
+ if (UnusedIncludes) {
208
+ for (const auto *Inc : Unused) {
209
+ diag (Inc->HashLocation , " included header %0 is not used directly" )
210
+ << llvm::sys::path::filename (Inc->Spelled ,
211
+ llvm::sys::path::Style::posix)
212
+ << FixItHint::CreateRemoval (CharSourceRange::getCharRange (
213
+ SM->translateLineCol (SM->getMainFileID (), Inc->Line , 1 ),
214
+ SM->translateLineCol (SM->getMainFileID (), Inc->Line + 1 , 1 )));
215
+ }
210
216
}
211
217
212
- tooling::HeaderIncludes HeaderIncludes (getCurrentMainFile (), Code,
213
- FileStyle->IncludeStyle );
214
- // Deduplicate insertions when running in bulk fix mode.
215
- llvm::StringSet<> InsertedHeaders{};
216
- for (const auto &Inc : Missing) {
217
- std::string Spelling = include_cleaner::spellHeader (
218
- {Inc.Missing , PP->getHeaderSearchInfo (), MainFile});
219
- bool Angled = llvm::StringRef{Spelling}.starts_with (" <" );
220
- // We might suggest insertion of an existing include in edge cases, e.g.,
221
- // include is present in a PP-disabled region, or spelling of the header
222
- // turns out to be the same as one of the unresolved includes in the
223
- // main file.
224
- if (auto Replacement =
225
- HeaderIncludes.insert (llvm::StringRef{Spelling}.trim (" \" <>" ),
226
- Angled, tooling::IncludeDirective::Include)) {
227
- DiagnosticBuilder DB =
228
- diag (SM->getSpellingLoc (Inc.SymRef .RefLocation ),
229
- " no header providing \" %0\" is directly included" )
230
- << Inc.SymRef .Target .name ();
231
- if (areDiagsSelfContained () ||
232
- InsertedHeaders.insert (Replacement->getReplacementText ()).second ) {
233
- DB << FixItHint::CreateInsertion (
234
- SM->getComposedLoc (SM->getMainFileID (), Replacement->getOffset ()),
235
- Replacement->getReplacementText ());
218
+ if (MissingIncludes) {
219
+ tooling::HeaderIncludes HeaderIncludes (getCurrentMainFile (), Code,
220
+ FileStyle->IncludeStyle );
221
+ // Deduplicate insertions when running in bulk fix mode.
222
+ llvm::StringSet<> InsertedHeaders{};
223
+ for (const auto &Inc : Missing) {
224
+ std::string Spelling = include_cleaner::spellHeader (
225
+ {Inc.Missing , PP->getHeaderSearchInfo (), MainFile});
226
+ bool Angled = llvm::StringRef{Spelling}.starts_with (" <" );
227
+ // We might suggest insertion of an existing include in edge cases, e.g.,
228
+ // include is present in a PP-disabled region, or spelling of the header
229
+ // turns out to be the same as one of the unresolved includes in the
230
+ // main file.
231
+ if (auto Replacement = HeaderIncludes.insert (
232
+ llvm::StringRef{Spelling}.trim (" \" <>" ), Angled,
233
+ tooling::IncludeDirective::Include)) {
234
+ DiagnosticBuilder DB =
235
+ diag (SM->getSpellingLoc (Inc.SymRef .RefLocation ),
236
+ " no header providing \" %0\" is directly included" )
237
+ << Inc.SymRef .Target .name ();
238
+ if (areDiagsSelfContained () ||
239
+ InsertedHeaders.insert (Replacement->getReplacementText ()).second ) {
240
+ DB << FixItHint::CreateInsertion (
241
+ SM->getComposedLoc (SM->getMainFileID (), Replacement->getOffset ()),
242
+ Replacement->getReplacementText ());
243
+ }
236
244
}
237
245
}
238
246
}
0 commit comments