Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[clang-tidy] modernize-deprecated-headers check should respect extern…
… "C" blocks The check should not report includes wrapped by `extern "C" { ... }` blocks, such as: ```lang=C++ #ifdef __cplusplus extern "C" { #endif #include "assert.h" #ifdef __cplusplus } #endif ``` This pattern comes up sometimes in header files designed to be consumed by both C and C++ source files. The check now reports false reports when the header file is consumed by a C++ translation unit. In this change, I'm not emitting the reports immediately from the `PPCallback`, rather aggregating them for further processing. After all preprocessing is done, the matcher will be called on the `TranslationUnitDecl`, ensuring that the check callback is called only once. Within that callback, I'm recursively visiting each decls, looking for `LinkageSpecDecls` which represent the `extern "C"` specifier. After this, I'm dropping all the reports coming from inside of it. After the visitation is done, I'm emitting the reports I'm left with. For performance reasons, I'm sorting the `IncludeMarkers` by their corresponding locations. This makes the scan `O(log(N)` when looking up the `IncludeMarkers` affected by the given `extern "C"` block. For this, I'm using `lower_bound()` and `upper_bound()`. Reviewed By: whisperity Differential Revision: https://reviews.llvm.org/D125209
- Loading branch information
Balazs Benics
committed
May 13, 2022
1 parent
a2ac0bb
commit 7e3ea55
Showing
5 changed files
with
192 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
clang-tools-extra/test/clang-tidy/checkers/Inputs/modernize-deprecated-headers/mylib.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
#include "assert.h" |
53 changes: 53 additions & 0 deletions
53
clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-extern-c.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// RUN: %check_clang_tidy -std=c++11-or-later %s modernize-deprecated-headers %t \ | ||
// RUN: -- -header-filter='.*' -system-headers \ | ||
// RUN: -extra-arg-before=-isystem%S/Inputs/modernize-deprecated-headers | ||
|
||
#define EXTERN_C extern "C" | ||
|
||
extern "C++" { | ||
// We should still have the warnings here. | ||
#include <stdbool.h> | ||
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it [modernize-deprecated-headers] | ||
} | ||
|
||
#include <assert.h> | ||
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead [modernize-deprecated-headers] | ||
// CHECK-FIXES: {{^}}#include <cassert>{{$}} | ||
|
||
#include <stdbool.h> | ||
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it [modernize-deprecated-headers] | ||
|
||
#include <mylib.h> | ||
// CHECK-MESSAGES: mylib.h:1:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead [modernize-deprecated-headers] | ||
|
||
namespace wrapping { | ||
extern "C" { | ||
#include <assert.h> // no-warning | ||
#include <mylib.h> // no-warning | ||
#include <stdbool.h> // no-warning | ||
} | ||
} // namespace wrapping | ||
|
||
extern "C" { | ||
namespace wrapped { | ||
#include <assert.h> // no-warning | ||
#include <mylib.h> // no-warning | ||
#include <stdbool.h> // no-warning | ||
} // namespace wrapped | ||
} | ||
|
||
namespace wrapping { | ||
extern "C" { | ||
namespace wrapped { | ||
#include <assert.h> // no-warning | ||
#include <mylib.h> // no-warning | ||
#include <stdbool.h> // no-warning | ||
} // namespace wrapped | ||
} | ||
} // namespace wrapping | ||
|
||
EXTERN_C { | ||
#include <assert.h> // no-warning | ||
#include <mylib.h> // no-warning | ||
#include <stdbool.h> // no-warning | ||
} |