chh updated this revision to Diff 360651.
chh edited the summary of this revision.
chh added a comment.
Add one more skip-headers-2.cpp test, which shows desired check at a top-level
Decl but not at nested Decl. Checking locations of only top-level Decls will
miss the opportunity to skip nested Decls.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D98710/new/
https://reviews.llvm.org/D98710
Files:
clang-tools-extra/clang-tidy/ClangTidy.cpp
clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
clang-tools-extra/clang-tidy/ClangTidyOptions.h
clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-forward-declaration-namespace/a.h
clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-forward-declaration-namespace/b.h
clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/a.h
clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/b.h
clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/my_header1.h
clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/my_header2.h
clang-tools-extra/test/clang-tidy/checkers/abseil-no-internal-dependencies.cpp
clang-tools-extra/test/clang-tidy/checkers/abseil-upgrade-duration-conversions.cpp
clang-tools-extra/test/clang-tidy/checkers/bugprone-forward-declaration-namespace-header.cpp
clang-tools-extra/test/clang-tidy/checkers/bugprone-forward-declaration-namespace.cpp
clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
clang-tools-extra/test/clang-tidy/checkers/bugprone-suspicious-include.cpp
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-interfaces-global-init.cpp
clang-tools-extra/test/clang-tidy/checkers/google-namespaces.cpp
clang-tools-extra/test/clang-tidy/checkers/google-objc-function-naming.m
clang-tools-extra/test/clang-tidy/checkers/llvm-include-order.cpp
clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned.cpp
clang-tools-extra/test/clang-tidy/checkers/llvmlibc-implementation-in-namespace.cpp
clang-tools-extra/test/clang-tidy/checkers/llvmlibc-restrict-system-libc-headers.cpp
clang-tools-extra/test/clang-tidy/checkers/misc-no-recursion.cpp
clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-cxx03.cpp
clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-cxx11.cpp
clang-tools-extra/test/clang-tidy/checkers/modernize-pass-by-value-header.cpp
clang-tools-extra/test/clang-tidy/checkers/portability-restrict-system-includes-allow.cpp
clang-tools-extra/test/clang-tidy/checkers/portability-restrict-system-includes-disallow.cpp
clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-chained-conditional-assignment.cpp
clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-chained-conditional-return.cpp
clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-members.cpp
clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr.cpp
clang-tools-extra/test/clang-tidy/checkers/skip-headers-2.cpp
clang-tools-extra/test/clang-tidy/checkers/skip-headers.cpp
clang-tools-extra/test/clang-tidy/infrastructure/file-filter-symlinks.cpp
clang-tools-extra/test/clang-tidy/infrastructure/file-filter.cpp
clang-tools-extra/test/clang-tidy/infrastructure/line-filter.cpp
clang/include/clang/Frontend/MultiplexConsumer.h
Index: clang/include/clang/Frontend/MultiplexConsumer.h
===================================================================
--- clang/include/clang/Frontend/MultiplexConsumer.h
+++ clang/include/clang/Frontend/MultiplexConsumer.h
@@ -77,8 +77,9 @@
void InitializeSema(Sema &S) override;
void ForgetSema() override;
-private:
+protected:
std::vector<std::unique_ptr<ASTConsumer>> Consumers; // Owns these.
+private:
std::unique_ptr<MultiplexASTMutationListener> MutationListener;
std::unique_ptr<MultiplexASTDeserializationListener> DeserializationListener;
};
Index: clang-tools-extra/test/clang-tidy/infrastructure/line-filter.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/infrastructure/line-filter.cpp
+++ clang-tools-extra/test/clang-tidy/infrastructure/line-filter.cpp
@@ -1,4 +1,4 @@
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -line-filter='[{"name":"line-filter.cpp","lines":[[18,18],[22,22]]},{"name":"header1.h","lines":[[1,2]]},{"name":"header2.h"},{"name":"header3.h"}]' -header-filter='header[12]\.h$' %s -- -I %S/Inputs/line-filter 2>&1 | FileCheck %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -line-filter='[{"name":"line-filter.cpp","lines":[[18,18],[22,22]]},{"name":"header1.h","lines":[[1,2]]},{"name":"header2.h"},{"name":"header3.h"}]' -header-filter='header[12]\.h$' %s -- -I %S/Inputs/line-filter 2>&1 | FileCheck %s
#include "header1.h"
// CHECK-NOT: header1.h:{{.*}} warning
Index: clang-tools-extra/test/clang-tidy/infrastructure/file-filter.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/infrastructure/file-filter.cpp
+++ clang-tools-extra/test/clang-tidy/infrastructure/file-filter.cpp
@@ -1,14 +1,14 @@
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck %s
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK-QUIET %s
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK2 %s
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK2-QUIET %s
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='header2\.h' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK3 %s
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='header2\.h' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK3-QUIET %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK-QUIET %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='.*' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='.*' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK2-QUIET %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='header2\.h' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='header2\.h' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK3-QUIET %s
// FIXME: "-I %S/Inputs/file-filter/system/.." must be redundant.
// On Win32, file-filter/system\system-header1.h precedes
// file-filter\header*.h due to code order between '/' and '\\'.
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4 %s
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers -quiet %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4-QUIET %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers -quiet %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4-QUIET %s
#include "header1.h"
// CHECK-NOT: warning:
Index: clang-tools-extra/test/clang-tidy/infrastructure/file-filter-symlinks.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/infrastructure/file-filter-symlinks.cpp
+++ clang-tools-extra/test/clang-tidy/infrastructure/file-filter-symlinks.cpp
@@ -5,12 +5,12 @@
// RUN: echo 'class A { A(int); };' > %t/dir1/header.h
// RUN: ln -s %t/dir1/header.h %t/dir1/header_alias.h
//
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='dir1/dir2/\.\./header_alias\.h' %s -- -I %t 2>&1 | FileCheck --check-prefix=CHECK_HEADER_ALIAS %s
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='dir1/dir2/\.\./header_alias\.h' -quiet %s -- -I %t 2>&1 | FileCheck --check-prefix=CHECK_HEADER_ALIAS %s
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='header_alias\.h' %s -- -I %t 2>&1 | FileCheck --check-prefix=CHECK_HEADER_ALIAS %s
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='header_alias\.h' -quiet %s -- -I %t 2>&1 | FileCheck --check-prefix=CHECK_HEADER_ALIAS %s
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='header\.h' %s -- -I %t 2>&1 | FileCheck --check-prefix=CHECK_HEADER %s
-// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='header\.h' -quiet %s -- -I %t 2>&1 | FileCheck --check-prefix=CHECK_HEADER %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='dir1/dir2/\.\./header_alias\.h' %s -- -I %t 2>&1 | FileCheck --check-prefix=CHECK_HEADER_ALIAS %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='dir1/dir2/\.\./header_alias\.h' -quiet %s -- -I %t 2>&1 | FileCheck --check-prefix=CHECK_HEADER_ALIAS %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='header_alias\.h' %s -- -I %t 2>&1 | FileCheck --check-prefix=CHECK_HEADER_ALIAS %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='header_alias\.h' -quiet %s -- -I %t 2>&1 | FileCheck --check-prefix=CHECK_HEADER_ALIAS %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='header\.h' %s -- -I %t 2>&1 | FileCheck --check-prefix=CHECK_HEADER %s
+// RUN: clang-tidy --skip-headers=0 -checks='-*,google-explicit-constructor' -header-filter='header\.h' -quiet %s -- -I %t 2>&1 | FileCheck --check-prefix=CHECK_HEADER %s
// Check that `-header-filter` operates on the same file paths as paths in
// diagnostics printed by ClangTidy.
Index: clang-tools-extra/test/clang-tidy/checkers/skip-headers.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/skip-headers.cpp
@@ -0,0 +1,54 @@
+// Test --skip-headers, --show-all-warnings, and --header-filter.
+// TODO(chh): when skip-headers implementation is complete, add back
+// -implicit-check-not="{{warning|error}}:"
+// and use no_hint instead of hint
+//
+// Default shows no warning in .h files, and give HINT to use --header-filter
+// RUN: clang-tidy %s -checks='*' -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,MAIN,HINT
+// later: -implicit-check-not="{{warning|error}}:"
+//
+// --skip-headers skips included files; finds only warnings in the main file.
+// RUN: clang-tidy %s -checks='*' --skip-headers -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,MAIN,HINT
+// later: no_hint -implicit-check-not="{{warning|error}}:"
+//
+// --show-all-warnings reports all warnings, even without --header-filters
+// RUN: clang-tidy %s -checks='*' --show-all-warnings -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,WARN_BOTH,MAIN,NO_HINT
+//
+// --header-filter='.*' is like --show-all-warnings
+// RUN: clang-tidy %s -checks='*' --header-filter='.*' -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,WARN_BOTH,MAIN,NO_HINT
+//
+// --header-filter='header1.h' shows only warnings in header1.h
+// RUN: clang-tidy %s -checks='*' --header-filter='header1.h' -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,WARN1,MAIN,HINT
+// later: -implicit-check-not="{{warning|error}}:"
+//
+// The main purpose of --show-all-warnings is to debug --skip-headers.
+// When used together, no warnings should be reported from header files.
+// RUN: clang-tidy %s -checks='*' --skip-headers --show-all-warnings -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,MAIN,NO_HINT
+// later: -implicit-check-not="{{warning|error}}:"
+//
+// use --skip-headers and --header-filter='header2.h'
+// to skip header1.h but not header2.h
+// RUN: clang-tidy %s -checks='*' --skip-headers --header-filter='header2.h' \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,WARN2,MAIN,HINT
+// later: no_hint
+
+// WARN: {{[0-9]+}} warnings generated.
+#include "Inputs/skip-headers/my_header1.h"
+// WARN1: my_header1.h:1:1: warning: header is missing header guard
+// WARN1-NOT: my_header2.h
+// WARN2: my_header2.h:1:1: warning: header is missing header guard
+// WARN2-NOT: my_header1.h
+// WARN_BOTH: my_header1.h:1:1: warning: header is missing header guard
+// WARN_BOTH: my_header2.h:1:1: warning: header is missing header guard
+
+int xyz = 135;
+// MAIN: skip-headers.cpp:{{[0-9]+}}:{{[0-9]+}}: warning:
+
+// HINT: Use -header-filter={{.*}} to display errors{{.*}}
+// NO_HINT-NOT: Use -header-filter=
Index: clang-tools-extra/test/clang-tidy/checkers/skip-headers-2.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/skip-headers-2.cpp
@@ -0,0 +1,39 @@
+// Test --skip-headers, --show-all-warnings, and --header-filter
+// with nested Decls. Users should be able to select exactly
+// which .h file to check for warnings.
+// Here a.h includes/uses b.h. Maintainers of a.h wants to check/see
+// warnings in a.h but not b.h. So they use --header-filer=a.h --skip-headers.
+//
+// RUN: clang-tidy %s --skip-headers=0 --show-all-warnings \
+// RUN: -checks='-*,readability-convert-member-functions-to-static' -- \
+// RUN: | FileCheck %s -check-prefixes WARNA,WARNB,WARNMAIN
+//
+// RUN: clang-tidy %s --skip-headers=1 --show-all-warnings \
+// RUN: -checks='-*,readability-convert-member-functions-to-static' -- \
+// RUN: | FileCheck %s -check-prefixes WARNMAIN,NOWARNA,NOWARNB
+//
+// RUN: clang-tidy %s --skip-headers=1 --show-all-warnings --header-filter=a.h \
+// RUN: -checks='-*,readability-convert-member-functions-to-static' -- \
+// RUN: | FileCheck %s -check-prefixes WARNMAIN,WARNA,NOWARNB
+//
+// RUN: clang-tidy %s --skip-headers=1 --show-all-warnings --header-filter=.* \
+// RUN: -checks='-*,readability-convert-member-functions-to-static' -- \
+// RUN: | FileCheck %s -check-prefixes WARNMAIN,WARNA,WARNB
+//
+// Current limitation of --skip-haders: b.h is skipped if a.h is skipped.
+// RUN: clang-tidy %s --skip-headers=1 --show-all-warnings --header-filter=b.h \
+// RUN: -checks='-*,readability-convert-member-functions-to-static' -- \
+// RUN: | FileCheck %s -check-prefixes WARNMAIN,NOWARNA,NOWARNB
+
+#include "Inputs/skip-headers/a.h"
+
+// WARNA: warning: method 'fooA' can be made static
+// NOWARNA-NOT: warning: method 'fooA' can be made static
+
+// WARNB: warning: method 'fooB' can be made static
+// NOWARNB-NOT: warning: method 'fooB' can be made static
+
+class C {
+ void foo(int x) { x = 3; };
+// WARNMAIN: warning: method 'foo' can be made static
+};
Index: clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t -- --skip-headers=0
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t -- --skip-headers
bool a1 = false;
Index: clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-members.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-members.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-members.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t -- --skip-headers=0
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t -- --skip-headers
class A {
public:
Index: clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-chained-conditional-return.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-chained-conditional-return.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-chained-conditional-return.cpp
@@ -1,4 +1,7 @@
-// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t -- -config="{CheckOptions: [{key: "readability-simplify-boolean-expr.ChainedConditionalReturn", value: true}]}" --
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t -- --skip-headers=0 \
+// RUN: -config="{CheckOptions: [{key: "readability-simplify-boolean-expr.ChainedConditionalReturn", value: true}]}" --
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t -- --skip-headers \
+// RUN: -config="{CheckOptions: [{key: "readability-simplify-boolean-expr.ChainedConditionalReturn", value: true}]}" --
bool chained_conditional_compound_return(int i) {
if (i < 0) {
Index: clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-chained-conditional-assignment.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-chained-conditional-assignment.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-chained-conditional-assignment.cpp
@@ -1,4 +1,7 @@
-// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t -- -config="{CheckOptions: [{key: "readability-simplify-boolean-expr.ChainedConditionalAssignment", value: true}]}" --
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t -- --skip-headers=0 \
+// RUN: -config="{CheckOptions: [{key: "readability-simplify-boolean-expr.ChainedConditionalAssignment", value: true}]}" --
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t -- --skip-headers \
+// RUN: -config="{CheckOptions: [{key: "readability-simplify-boolean-expr.ChainedConditionalAssignment", value: true}]}" --
void chained_conditional_compound_assignment(int i) {
bool b;
Index: clang-tools-extra/test/clang-tidy/checkers/portability-restrict-system-includes-disallow.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/portability-restrict-system-includes-disallow.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/portability-restrict-system-includes-disallow.cpp
@@ -1,5 +1,9 @@
// RUN: %check_clang_tidy %s portability-restrict-system-includes %t \
-// RUN: -- -config="{CheckOptions: [{key: portability-restrict-system-includes.Includes, value: '-*,stddef.h'}]}" \
+// RUN: -- -config="{CheckOptions: [{key: portability-restrict-system-includes.Includes, value: '-*,stddef.h'}]}" --skip-headers=0 \
+// RUN: -- -isystem %S/Inputs/portability-restrict-system-includes/system
+//
+// RUN: %check_clang_tidy %s portability-restrict-system-includes %t \
+// RUN: -- -config="{CheckOptions: [{key: portability-restrict-system-includes.Includes, value: '-*,stddef.h'}]}" --skip-headers \
// RUN: -- -isystem %S/Inputs/portability-restrict-system-includes/system
// Test allow-list functionality: disallow all but stddef.h.
Index: clang-tools-extra/test/clang-tidy/checkers/portability-restrict-system-includes-allow.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/portability-restrict-system-includes-allow.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/portability-restrict-system-includes-allow.cpp
@@ -1,5 +1,9 @@
// RUN: %check_clang_tidy %s portability-restrict-system-includes %t \
-// RUN: -- -config="{CheckOptions: [{key: portability-restrict-system-includes.Includes, value: '*,-stddef.h'}]}" \
+// RUN: -- -config="{CheckOptions: [{key: portability-restrict-system-includes.Includes, value: '*,-stddef.h'}]}" --skip-headers=0 \
+// RUN: -- -isystem %S/Inputs/portability-restrict-system-includes/system
+//
+// RUN: %check_clang_tidy %s portability-restrict-system-includes %t \
+// RUN: -- -config="{CheckOptions: [{key: portability-restrict-system-includes.Includes, value: '*,-stddef.h'}]}" --skip-headers \
// RUN: -- -isystem %S/Inputs/portability-restrict-system-includes/system
// Test block-list functionality: allow all but stddef.h.
Index: clang-tools-extra/test/clang-tidy/checkers/modernize-pass-by-value-header.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/modernize-pass-by-value-header.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize-pass-by-value-header.cpp
@@ -1,9 +1,37 @@
// RUN: cp %S/Inputs/modernize-pass-by-value/header.h %T/pass-by-value-header.h
-// RUN: clang-tidy %s -checks='-*,modernize-pass-by-value' -header-filter='.*' -fix -- -std=c++11 -I %T | FileCheck %s -check-prefix=CHECK-MESSAGES -implicit-check-not="{{warning|error}}:"
+// RUN: clang-tidy %s -checks='-*,modernize-pass-by-value' -header-filter='.*' -fix -- -std=c++11 -I %T \
+// RUN: | FileCheck %s -check-prefix=CHECK-MESSAGES -implicit-check-not="{{warning|error}}:"
// RUN: FileCheck -input-file=%T/pass-by-value-header.h %s -check-prefix=CHECK-FIXES
+//
+// RUN: cp %S/Inputs/modernize-pass-by-value/header.h %T/pass-by-value-header.h
+// RUN: clang-tidy %s -checks='*' --skip-headers=0 -- -std=c++11 -I %T \
+// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-NOHEADER -allow-empty
+//
+// RUN: cp %S/Inputs/modernize-pass-by-value/header.h %T/pass-by-value-header.h
+// RUN: clang-tidy %s -checks='-*,modernize-pass-by-value' --skip-headers -fix -- -std=c++11 -I %T \
+// RUN: | FileCheck %s -check-prefix=CHECK-SKIP -allow-empty -implicit-check-not="{{warning|error}}:"
+// RUN: FileCheck -input-file=%T/pass-by-value-header.h %s -check-prefix=CHECK-SKIP-FIXES
+//
+// RUN: cp %S/Inputs/modernize-pass-by-value/header.h %T/pass-by-value-header.h
+// RUN: clang-tidy %s -checks='*' --skip-headers -- -std=c++11 -I %T \
+// RUN: | FileCheck %s -check-prefix=CHECK-SKIP -allow-empty -implicit-check-not="{{warning|error}}:"
+//
// FIXME: Make the test work in all language modes.
#include "pass-by-value-header.h"
-// CHECK-MESSAGES: :8:5: warning: pass by value and use std::move [modernize-pass-by-value]
+// header file warnings are not shown, with --skip-headers, or without -header-filter
+// CHECK-MESSAGES: :8:5: warning: pass by value and use std::move [modernize-pass-by-value]
+// CHECK-NOHEADER-NOT: :8:5: warning: pass by value and use std::move [modernize-pass-by-value]
+// CHECK-SKIP-NOT: :8:5: warning: pass by value and use std::move [modernize-pass-by-value]
+//
// CHECK-FIXES: #include <utility>
// CHECK-FIXES: A(ThreadId tid) : threadid(std::move(tid)) {}
+// CHECK-SKIP-FIXES-NOT: #include <utility>
+//
+// header files are checked even without -header-filtler
+// CHECK-NOHEADER: Suppressed {{.*}} warnings
+// CHECK-NOHEADER: Use -header-filter={{.*}} to display errors{{.*}}
+//
+// header files are not checked with --skip-headers
+// CHECK-SKIP-NOT: Suppressed {{.*}} warnings
+// CHECK-SKIP-NOT: Use -header-filter={{.*}} to display errors{{.*}}
Index: clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-cxx11.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-cxx11.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-cxx11.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy -std=c++11-or-later %s modernize-deprecated-headers %t -- -extra-arg-before=-isystem%S/Inputs/modernize-deprecated-headers
+// RUN: %check_clang_tidy -std=c++11-or-later %s modernize-deprecated-headers %t -- --skip-headers=0 -extra-arg-before=-isystem%S/Inputs/modernize-deprecated-headers
+// RUN: %check_clang_tidy -std=c++11-or-later %s modernize-deprecated-headers %t -- --skip-headers -extra-arg-before=-isystem%S/Inputs/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]
Index: clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-cxx03.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-cxx03.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-cxx03.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy -std=c++98 %s modernize-deprecated-headers %t -- -extra-arg-before=-isystem%S/Inputs/modernize-deprecated-headers
+// RUN: %check_clang_tidy -std=c++98 %s modernize-deprecated-headers %t -- --skip-headers=0 -extra-arg-before=-isystem%S/Inputs/modernize-deprecated-headers
+// RUN: %check_clang_tidy -std=c++98 %s modernize-deprecated-headers %t -- --skip-headers -extra-arg-before=-isystem%S/Inputs/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]
Index: clang-tools-extra/test/clang-tidy/checkers/misc-no-recursion.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/misc-no-recursion.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/misc-no-recursion.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s misc-no-recursion %t
+// RUN: %check_clang_tidy %s misc-no-recursion %t -- --skip-headers=0
+// RUN: %check_clang_tidy %s misc-no-recursion %t -- --skip-headers
// We don't have the definition of this function,
// so we can't tell anything about it..
Index: clang-tools-extra/test/clang-tidy/checkers/llvmlibc-restrict-system-libc-headers.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/llvmlibc-restrict-system-libc-headers.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/llvmlibc-restrict-system-libc-headers.cpp
@@ -1,5 +1,9 @@
// RUN: %check_clang_tidy %s llvmlibc-restrict-system-libc-headers %t \
-// RUN: -- -- -isystem %S/Inputs/llvmlibc/system \
+// RUN: -- --skip-headers=0 -- -isystem %S/Inputs/llvmlibc/system \
+// RUN: -resource-dir %S/Inputs/llvmlibc/resource
+//
+// RUN: %check_clang_tidy %s llvmlibc-restrict-system-libc-headers %t \
+// RUN: -- --skip-headers -- -isystem %S/Inputs/llvmlibc/system \
// RUN: -resource-dir %S/Inputs/llvmlibc/resource
#include <stdio.h>
Index: clang-tools-extra/test/clang-tidy/checkers/llvmlibc-implementation-in-namespace.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/llvmlibc-implementation-in-namespace.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/llvmlibc-implementation-in-namespace.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s llvmlibc-implementation-in-namespace %t
+// RUN: %check_clang_tidy %s llvmlibc-implementation-in-namespace %t -- --skip-headers=0
+// RUN: %check_clang_tidy %s llvmlibc-implementation-in-namespace %t -- --skip-headers
#define MACRO_A "defining macros outside namespace is valid"
Index: clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s llvm-prefer-register-over-unsigned %t
+// RUN: %check_clang_tidy %s llvm-prefer-register-over-unsigned %t -- --skip-headers=0
+// RUN: %check_clang_tidy %s llvm-prefer-register-over-unsigned %t -- --skip-headers
namespace llvm {
class Register {
Index: clang-tools-extra/test/clang-tidy/checkers/llvm-include-order.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/llvm-include-order.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/llvm-include-order.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s llvm-include-order %t -- -- -isystem %S/Inputs/Headers
+// RUN: %check_clang_tidy %s llvm-include-order %t -- --skip-headers=0 -- -isystem %S/Inputs/Headers
+// RUN: %check_clang_tidy %s llvm-include-order %t -- --skip-headers -- -isystem %S/Inputs/Headers
// CHECK-MESSAGES: [[@LINE+2]]:1: warning: #includes are not sorted properly
#include "j.h"
Index: clang-tools-extra/test/clang-tidy/checkers/google-objc-function-naming.m
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/google-objc-function-naming.m
+++ clang-tools-extra/test/clang-tidy/checkers/google-objc-function-naming.m
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s google-objc-function-naming %t -- -- -isystem %S/Inputs/Headers
+// RUN: %check_clang_tidy %s google-objc-function-naming %t -- --skip-headers=0 -- -isystem %S/Inputs/Headers
+// RUN: %check_clang_tidy %s google-objc-function-naming %t -- --skip-headers -- -isystem %S/Inputs/Headers
#include <stdio.h>
Index: clang-tools-extra/test/clang-tidy/checkers/google-namespaces.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/google-namespaces.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/google-namespaces.cpp
@@ -1,6 +1,32 @@
-// RUN: clang-tidy %s -checks='-*,google-build-namespaces,google-build-using-namespace' -header-filter='.*' -- | FileCheck %s -implicit-check-not="{{warning|error}}:"
+// RUN: clang-tidy %s --skip-headers=0 -checks='-*,google-build-namespaces,google-build-using-namespace' -header-filter='.*' -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes CHECK,CHECK1 -implicit-check-not="{{warning|error}}:"
+
+// RUN: clang-tidy %s --skip-headers=0 -checks='-*,google-build-namespaces,google-build-using-namespace' -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes CHECK,CHECK0 -implicit-check-not="{{warning|error}}:"
+//
+// RUN: clang-tidy %s --skip-headers -checks='-*,google-build-namespaces,google-build-using-namespace' -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes CHECK,CHECK2 -implicit-check-not="{{warning|error}}:"
+//
+// -header-filter overrides --skip-header
+// RUN: clang-tidy %s --skip-headers -header-filter='.*' -checks='-*,google-build-namespaces,google-build-using-namespace' -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes CHECK,CHECK1 -implicit-check-not="{{warning|error}}:"
+//
+// --show-all-warnings is like -header-filter=.* + -system-headers
+// RUN: clang-tidy %s --skip-headers=0 --show-all-warnings -checks='-*,google-build-namespaces,google-build-using-namespace' -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes CHECK,CHECK1 -implicit-check-not="{{warning|error}}:"
+
+// --skip-header skips 1 warning in the header file.
+// CHECK0: 7 warnings generated
+// CHECK1: 7 warnings generated
+// CHECK2: 6 warnings generated
+
#include "Inputs/google-namespaces.h"
-// CHECK: warning: do not use unnamed namespaces in header files [google-build-namespaces]
+// with -header-filter, warning in .h file is shown
+// CHECK1: warning: do not use unnamed namespaces in header files [google-build-namespaces]
+// without -header-filter, warning in .h files are not shown
+// CHECK0-NOT: warning: do not use unnamed namespaces in header files [google-build-namespaces]
+// with --skip-header, no warning in .h file is detected at all
+// CHECK2-NOT: warning: do not use unnamed namespaces in header files [google-build-namespaces]
using namespace spaaaace;
// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
@@ -50,3 +76,14 @@
using namespace foo_literals;
// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
+
+// If -header-filter= is not used and there is some warning in .h file,
+// give a reminder to use -header-filter.
+// CHECK0: Use -header-filter={{.*}} to display errors{{.*}}
+//
+// If -header-filter= is used, no summary of this message.
+// CHECK1-NOT: Use -header-filter={{.*}} to display errors{{.*}}
+//
+// With --skip-header, no warning in .h file is detected or hidden,
+// no need to give a reminder to use -header-filter.
+// CHECK2-NOT: Use -header-filter={{.*}} to display errors{{.*}}
Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-interfaces-global-init.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-interfaces-global-init.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-interfaces-global-init.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-interfaces-global-init %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-interfaces-global-init %t -- --skip-headers=0
+// RUN: %check_clang_tidy %s cppcoreguidelines-interfaces-global-init %t -- --skip-headers
constexpr int makesInt() { return 3; }
constexpr int takesInt(int i) { return i + 1; }
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-suspicious-include.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-suspicious-include.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-suspicious-include.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s bugprone-suspicious-include %t -- -- -isystem %S/Inputs/Headers -fmodules
+// RUN: %check_clang_tidy %s bugprone-suspicious-include %t -- --skip-headers=0 -- -isystem %S/Inputs/Headers -fmodules
+// RUN: %check_clang_tidy %s bugprone-suspicious-include %t -- --skip-headers -- -isystem %S/Inputs/Headers -fmodules
// clang-format off
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
@@ -1,4 +1,7 @@
-// RUN: %check_clang_tidy %s bugprone-reserved-identifier %t -- -- \
+// RUN: %check_clang_tidy %s bugprone-reserved-identifier %t -- --skip-headers=0 -- \
+// RUN: -I%S/Inputs/bugprone-reserved-identifier \
+// RUN: -isystem %S/Inputs/bugprone-reserved-identifier/system
+// RUN: %check_clang_tidy %s bugprone-reserved-identifier %t -- --skip-headers -- \
// RUN: -I%S/Inputs/bugprone-reserved-identifier \
// RUN: -isystem %S/Inputs/bugprone-reserved-identifier/system
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-forward-declaration-namespace.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-forward-declaration-namespace.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-forward-declaration-namespace.cpp
@@ -1,4 +1,5 @@
-// RUN: %check_clang_tidy %s bugprone-forward-declaration-namespace %t
+// RUN: %check_clang_tidy %s bugprone-forward-declaration-namespace %t -- --skip-headers=0
+// RUN: %check_clang_tidy %s bugprone-forward-declaration-namespace %t -- --skip-headers
namespace {
// This is a declaration in a wrong namespace.
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-forward-declaration-namespace-header.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-forward-declaration-namespace-header.cpp
@@ -0,0 +1,173 @@
+// Same output with skip-headers=0, skip-headers=1, or skip-headers
+// RUN: %check_clang_tidy -check-suffixes=ALL %s bugprone-forward-declaration-namespace %t -- --skip-headers=0 \
+// RUN: -- -I%S/Inputs/bugprone-forward-declaration-namespace
+// RUN: %check_clang_tidy -check-suffixes=ALL %s bugprone-forward-declaration-namespace %t -- --skip-headers=1 \
+// RUN: -- -I%S/Inputs/bugprone-forward-declaration-namespace
+// RUN: %check_clang_tidy -check-suffixes=ALL %s bugprone-forward-declaration-namespace %t -- --skip-headers \
+// RUN: -- -I%S/Inputs/bugprone-forward-declaration-namespace
+//
+// Same output with header-filter=b.h because there is no warning on b.h
+// RUN: %check_clang_tidy -check-suffixes=ALL %s bugprone-forward-declaration-namespace %t -- --skip-headers \
+// RUN: --header-filter=b.h -- -I%S/Inputs/bugprone-forward-declaration-namespace
+//
+// Additional warnings on a.h
+// RUN: %check_clang_tidy -check-suffixes=ALL,A %s bugprone-forward-declaration-namespace %t -- --skip-headers=0 \
+// RUN: --header-filter=.* -- -I%S/Inputs/bugprone-forward-declaration-namespace
+// RUN: %check_clang_tidy -check-suffixes=ALL,A %s bugprone-forward-declaration-namespace %t -- --skip-headers \
+// RUN: --header-filter=.* -- -I%S/Inputs/bugprone-forward-declaration-namespace
+
+#include "a.h"
+
+class T_A;
+
+class T_A {
+ int x;
+};
+
+class NESTED;
+// CHECK-NOTES-ALL: :[[@LINE-1]]:7: warning: no definition found for 'NESTED', but a definition with the same name 'NESTED' found in another namespace '(anonymous namespace)::nq::(anonymous)'
+// CHECK-NOTES-ALL: note: a definition of 'NESTED' is found here
+
+namespace {
+namespace nq {
+namespace {
+class NESTED {};
+}
+}
+}
+
+namespace na {
+class T_B;
+// CHECK-NOTES-ALL: :[[@LINE-1]]:7: warning: declaration 'T_B' is never referenced, but a declaration with the same name found in another namespace 'nb'
+// CHECK-NOTES-ALL: note: a declaration of 'T_B' is found here
+// CHECK-NOTES-ALL: :[[@LINE-3]]:7: warning: no definition found for 'T_B', but a definition with the same name 'T_B' found in another namespace 'nb'
+// CHECK-NOTES-ALL: note: a definition of 'T_B' is found here
+}
+
+#include "b.h"
+
+namespace na {
+class T_B;
+// CHECK-NOTES-ALL: :[[@LINE-1]]:7: warning: declaration 'T_B' is never referenced, but a declaration with the same name found in another namespace 'nb'
+// CHECK-NOTES-ALL: note: a declaration of 'T_B' is found here
+// CHECK-NOTES-ALL: :[[@LINE-3]]:7: warning: no definition found for 'T_B', but a definition with the same name 'T_B' found in another namespace 'nb'
+// CHECK-NOTES-ALL: note: a definition of 'T_B' is found here
+}
+
+// A simple forward declaration. Although it is never used, but no declaration
+// with the same name is found in other namespace.
+class OUTSIDER;
+
+namespace na {
+// This class is referenced declaration, we don't generate warning.
+class OUTSIDER_1;
+}
+
+void f(na::OUTSIDER_1);
+
+namespace nc {
+// This class is referenced as friend in OOP.
+class OUTSIDER_1;
+
+class OOP {
+ friend struct OUTSIDER_1;
+};
+}
+
+namespace nd {
+class OUTSIDER_1;
+void f(OUTSIDER_1 *);
+}
+
+namespace nb {
+class OUTSIDER_1;
+// CHECK-NOTES-ALL: :[[@LINE-1]]:7: warning: declaration 'OUTSIDER_1' is never referenced, but a declaration with the same name found in another namespace 'na'
+// CHECK-NOTES-ALL: note: a declaration of 'OUTSIDER_1' is found here
+}
+
+
+namespace na {
+template<typename T>
+class T_C;
+}
+
+namespace nb {
+// FIXME: this is an error, but we don't consider template class declaration
+// now.
+template<typename T>
+class T_C;
+}
+
+namespace na {
+template<typename T>
+class T_C {
+ int x;
+};
+}
+
+namespace na {
+
+template <typename T>
+class T_TEMP {
+ template <typename _Tp1>
+ struct rebind { typedef T_TEMP<_Tp1> other; };
+};
+
+// We ignore class template specialization.
+template class T_TEMP<char>;
+}
+
+namespace nb {
+
+template <typename T>
+class T_TEMP_1 {
+ template <typename _Tp1>
+ struct rebind { typedef T_TEMP_1<_Tp1> other; };
+};
+
+// We ignore class template specialization.
+extern template class T_TEMP_1<char>;
+}
+
+namespace nd {
+class D;
+// CHECK-NOTES-ALL: :[[@LINE-1]]:7: warning: declaration 'D' is never referenced, but a declaration with the same name found in another namespace 'nd::ne'
+// CHECK-NOTES-ALL: note: a declaration of 'D' is found here
+}
+
+namespace nd {
+namespace ne {
+class D;
+}
+}
+
+int f(nd::ne::D &d);
+
+
+// This should be ignored by the check.
+template <typename... Args>
+class Observer {
+ class Impl;
+};
+
+template <typename... Args>
+class Observer<Args...>::Impl {
+};
+
+// Work around limit of FileCheck, the expected warnings in a.h files are listed here.
+//
+// Bug? Without --header-filter=.*,
+// the "is never referenced" warnings are suppressed
+// but not the "no definiton found" warnings.
+//
+// Warnings on namespace { class T_A; }
+// CHECK-NOTES-A: warning: declaration 'T_A' is never referenced, but a declaration with the same name found in another namespace 'na' [bugprone-forward-declaration-namespace]
+// CHECK-NOTES-A: note: a declaration of 'T_A' is found here
+// CHECK-NOTES-ALL: warning: no definition found for 'T_A', but a definition with the same name 'T_A' found in another namespace '(global)' [bugprone-forward-declaration-namespace]
+// CHECK-NOTES-ALL: note: a definition of 'T_A' is found here
+//
+// Warnings on namespace na { class T_A; }
+// CHECK-NOTES-A: warning: declaration 'T_A' is never referenced, but a declaration with the same name found in another namespace '(anonymous)'
+// CHECK-NOTES-A: note: a declaration of 'T_A' is found here
+// CHECK-NOTES-ALL: warning: no definition found for 'T_A', but a definition with the same name 'T_A' found in another namespace '(global)'
+// CHECK-NOTES-ALL: note: a definition of 'T_A' is found here
Index: clang-tools-extra/test/clang-tidy/checkers/abseil-upgrade-duration-conversions.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/abseil-upgrade-duration-conversions.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/abseil-upgrade-duration-conversions.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy -std=c++11-or-later %s abseil-upgrade-duration-conversions %t -- -- -I%S/Inputs
+// RUN: %check_clang_tidy -std=c++11-or-later %s abseil-upgrade-duration-conversions %t -- --skip-headers=0 -- -I%S/Inputs
using int64_t = long long;
Index: clang-tools-extra/test/clang-tidy/checkers/abseil-no-internal-dependencies.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/abseil-no-internal-dependencies.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/abseil-no-internal-dependencies.cpp
@@ -1,5 +1,5 @@
-// RUN: %check_clang_tidy %s abseil-no-internal-dependencies %t, -- -- -I %S/Inputs
-// RUN: clang-tidy -checks='-*, abseil-no-internal-dependencies' -header-filter='.*' %s -- -I %S/Inputs 2>&1 | FileCheck %s
+// RUN: %check_clang_tidy %s abseil-no-internal-dependencies %t, -- --skip-headers=0 -- -I %S/Inputs
+// RUN: clang-tidy --skip-headers=0 -checks='-*, abseil-no-internal-dependencies' -header-filter='.*' %s -- -I %S/Inputs 2>&1 | FileCheck %s
#include "absl/strings/internal-file.h"
#include "absl/flags/internal-file.h"
Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/my_header2.h
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/my_header2.h
@@ -0,0 +1,6 @@
+// bad header guard
+#ifndef SOME_MACRO
+
+int abc = 123; // bad definition in .h file
+
+#endif
Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/my_header1.h
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/my_header1.h
@@ -0,0 +1,3 @@
+// no header guard
+
+#include "my_header2.h"
Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/b.h
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/b.h
@@ -0,0 +1,4 @@
+class B {
+ // expect a warning on fooB
+ void fooB(int x) { x = 2; };
+};
Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/a.h
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/a.h
@@ -0,0 +1,4 @@
+class A {
+ #include "b.h"
+ void fooA(int x) { x = 1; };
+};
Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-forward-declaration-namespace/b.h
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-forward-declaration-namespace/b.h
@@ -0,0 +1,9 @@
+namespace nb {
+class T_B;
+}
+
+namespace nb {
+class T_B {
+ int x;
+};
+}
Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-forward-declaration-namespace/a.h
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/Inputs/bugprone-forward-declaration-namespace/a.h
@@ -0,0 +1,9 @@
+namespace {
+// This is a declaration in a wrong namespace.
+class T_A;
+}
+
+namespace na {
+// This is a declaration in a wrong namespace.
+class T_A;
+}
Index: clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
===================================================================
--- clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -95,10 +95,23 @@
cl::init(""),
cl::cat(ClangTidyCategory));
+static cl::opt<bool> ShowAllWarnings("show-all-warnings",
+ cl::desc("Display all warning messages."),
+ cl::init(false), cl::Hidden,
+ cl::cat(ClangTidyCategory));
+
+static cl::opt<bool> SkipHeaders("skip-headers", cl::desc(R"(
+Do not check included header files, but
+files matching the --header-filter pattern are still checked.
+System headers are still checked if --system-headers is true.
+)"),
+ cl::init(false), cl::cat(ClangTidyCategory));
+
static cl::opt<bool>
SystemHeaders("system-headers",
cl::desc("Display the errors from system headers."),
cl::init(false), cl::cat(ClangTidyCategory));
+
static cl::opt<std::string> LineFilter("line-filter", cl::desc(R"(
List of files with line ranges to filter the
warnings. Can be used together with
@@ -300,6 +313,8 @@
DefaultOptions.Checks = DefaultChecks;
DefaultOptions.WarningsAsErrors = "";
DefaultOptions.HeaderFilterRegex = HeaderFilter;
+ DefaultOptions.ShowAllWarnings = ShowAllWarnings;
+ DefaultOptions.SkipHeaders = SkipHeaders;
DefaultOptions.SystemHeaders = SystemHeaders;
DefaultOptions.FormatStyle = FormatStyle;
DefaultOptions.User = llvm::sys::Process::GetEnv("USER");
@@ -314,6 +329,10 @@
OverrideOptions.WarningsAsErrors = WarningsAsErrors;
if (HeaderFilter.getNumOccurrences() > 0)
OverrideOptions.HeaderFilterRegex = HeaderFilter;
+ if (ShowAllWarnings.getNumOccurrences() > 0)
+ OverrideOptions.ShowAllWarnings = ShowAllWarnings;
+ if (SkipHeaders.getNumOccurrences() > 0)
+ OverrideOptions.SkipHeaders = SkipHeaders;
if (SystemHeaders.getNumOccurrences() > 0)
OverrideOptions.SystemHeaders = SystemHeaders;
if (FormatStyle.getNumOccurrences() > 0)
Index: clang-tools-extra/clang-tidy/ClangTidyOptions.h
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyOptions.h
+++ clang-tools-extra/clang-tidy/ClangTidyOptions.h
@@ -79,6 +79,15 @@
/// Output warnings from system headers matching \c HeaderFilterRegex.
llvm::Optional<bool> SystemHeaders;
+ /// Show all warnings, including warnings from all header files.
+ /// This overrides HeaderFilterRegex and SystemHeaders.
+ /// This is an option intended for testing/debugging clang-tidy.
+ llvm::Optional<bool> ShowAllWarnings;
+
+ /// Do not check included files, except files matching the --header-filter
+ /// and system files when --system-headers is used.
+ llvm::Optional<bool> SkipHeaders;
+
/// Format code around applied fixes with clang-format using this
/// style.
///
Index: clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
@@ -89,6 +89,9 @@
IO.mapOptional("Checks", Options.Checks);
IO.mapOptional("WarningsAsErrors", Options.WarningsAsErrors);
IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex);
+ // SystemHeaders not mapped?
+ // ShowAllWarnings is hidden debug only option.
+ IO.mapOptional("SkipHeaders", Options.SkipHeaders);
IO.mapOptional("AnalyzeTemporaryDtors", Ignored); // legacy compatibility
IO.mapOptional("FormatStyle", Options.FormatStyle);
IO.mapOptional("User", Options.User);
@@ -111,6 +114,8 @@
Options.Checks = "";
Options.WarningsAsErrors = "";
Options.HeaderFilterRegex = "";
+ Options.ShowAllWarnings = false;
+ Options.SkipHeaders = false;
Options.SystemHeaders = false;
Options.FormatStyle = "none";
Options.User = llvm::None;
@@ -147,6 +152,8 @@
mergeCommaSeparatedLists(Checks, Other.Checks);
mergeCommaSeparatedLists(WarningsAsErrors, Other.WarningsAsErrors);
overrideValue(HeaderFilterRegex, Other.HeaderFilterRegex);
+ overrideValue(ShowAllWarnings, Other.ShowAllWarnings);
+ overrideValue(SkipHeaders, Other.SkipHeaders);
overrideValue(SystemHeaders, Other.SystemHeaders);
overrideValue(FormatStyle, Other.FormatStyle);
overrideValue(User, Other.User);
Index: clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -580,7 +580,7 @@
void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
const SourceManager &Sources) {
// Invalid location may mean a diagnostic in a command line, don't skip these.
- if (!Location.isValid()) {
+ if (!Location.isValid() || *Context.getOptions().ShowAllWarnings) {
LastErrorRelatesToUserCode = true;
LastErrorPassesLineFilter = true;
return;
Index: clang-tools-extra/clang-tidy/ClangTidy.cpp
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidy.cpp
+++ clang-tools-extra/clang-tidy/ClangTidy.cpp
@@ -305,15 +305,83 @@
unsigned WarningsAsErrors;
};
+// Check if a Decl should be skipped by clang-tidy checks.
+struct DeclFilter {
+ DeclFilter(ClangTidyContext &Ctx, SourceManager &SM)
+ : Context(Ctx), Sources(SM) {
+ HeaderFilter =
+ std::make_unique<llvm::Regex>(*Ctx.getOptions().HeaderFilterRegex);
+ LastSkippedFileID = FileID::getSentinel();
+ LastAcceptedFileID = FileID::getSentinel();
+ }
+ bool skipDecl(Decl *);
+ bool skipLocation(SourceLocation);
+
+private:
+ bool skipFileID(SourceLocation, FileID);
+ ClangTidyContext &Context;
+ SourceManager &Sources;
+ std::unique_ptr<llvm::Regex> HeaderFilter;
+ FileID LastSkippedFileID;
+ FileID LastAcceptedFileID;
+};
+
+bool DeclFilter::skipFileID(SourceLocation Location, FileID FID) {
+ // do not skip the main file
+ if (Sources.isInMainFile(Location))
+ return false;
+ // skip system headers unless --system-headers is used
+ if (Sources.isInSystemHeader(Location))
+ return !*Context.getOptions().SystemHeaders;
+ const FileEntry *File = Sources.getFileEntryForID(FID);
+ // without a FileEntry, cannot verify header file path to skip
+ if (!File)
+ return false;
+ StringRef FileName(File->getName());
+ // skip, unless file name matches --header-filter
+ return !HeaderFilter->match(FileName);
+}
+
+bool DeclFilter::skipDecl(Decl *Decl) {
+ return skipLocation(Decl->getLocation());
+}
+
+bool DeclFilter::skipLocation(SourceLocation Location) {
+ // cannot get valid FileID if Location is invalid
+ if (!Location.isValid())
+ return false;
+ // Similar to ClangTidyDiagnosticConsumer::checkFilters,
+ // the decision to skip a check depends on getDecomposedExpansionLoc.
+ auto FID = Sources.getDecomposedExpansionLoc(Location).first;
+ // Quick check against last checked results.
+ if (FID == LastSkippedFileID)
+ return true;
+ if (FID == LastAcceptedFileID)
+ return false;
+ auto ShouldSkip = skipFileID(Location, FID);
+ if (ShouldSkip) {
+ LastSkippedFileID = FID;
+ } else {
+ LastAcceptedFileID = FID;
+ }
+ return ShouldSkip;
+}
+
class ClangTidyASTConsumer : public MultiplexConsumer {
public:
ClangTidyASTConsumer(std::vector<std::unique_ptr<ASTConsumer>> Consumers,
std::unique_ptr<ClangTidyProfiling> Profiling,
std::unique_ptr<ast_matchers::MatchFinder> Finder,
+ ASTConsumer *FinderASTConsumerPtr,
+ std::shared_ptr<DeclFilter> Filter,
std::vector<std::unique_ptr<ClangTidyCheck>> Checks)
: MultiplexConsumer(std::move(Consumers)),
Profiling(std::move(Profiling)), Finder(std::move(Finder)),
- Checks(std::move(Checks)) {}
+ Checks(std::move(Checks)), FinderASTConsumerPtr(FinderASTConsumerPtr),
+ Filter(Filter) {}
+ ~ClangTidyASTConsumer() override;
+ bool HandleTopLevelDecl(DeclGroupRef DG) override;
+ void HandleTranslationUnit(ASTContext &Context) override;
private:
// Destructor order matters! Profiling must be destructed last.
@@ -321,6 +389,16 @@
std::unique_ptr<ClangTidyProfiling> Profiling;
std::unique_ptr<ast_matchers::MatchFinder> Finder;
std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
+ /// Remembered Finder's ASTConsumer, which is also pushed into
+ /// and managed by MultiplexConsumer.
+ ASTConsumer *FinderASTConsumerPtr;
+
+ // When --skip-headers, Filter is not null and handleTopLevelDecl
+ // will collect Decls into TopLevelDecls.
+ /// Check if a Decl should be skipped.
+ std::shared_ptr<DeclFilter> Filter;
+ /// All (filtered) top level decls.
+ std::vector<Decl *> TopLevelDecls;
};
} // namespace
@@ -384,6 +462,62 @@
}
#endif // CLANG_TIDY_ENABLE_STATIC_ANALYZER
+template <class T>
+bool isTemplateSpecializationKind(const NamedDecl *D,
+ TemplateSpecializationKind Kind) {
+ if (const auto *TD = dyn_cast<T>(D))
+ return TD->getTemplateSpecializationKind() == Kind;
+ return false;
+}
+
+bool isTemplateSpecializationKind(const NamedDecl *D,
+ TemplateSpecializationKind Kind) {
+ return isTemplateSpecializationKind<FunctionDecl>(D, Kind) ||
+ isTemplateSpecializationKind<CXXRecordDecl>(D, Kind) ||
+ isTemplateSpecializationKind<VarDecl>(D, Kind);
+}
+
+bool isImplicitTemplateInstantiation(const NamedDecl *D) {
+ return isTemplateSpecializationKind(D, TSK_ImplicitInstantiation);
+}
+
+ClangTidyASTConsumer::~ClangTidyASTConsumer() {}
+
+bool ClangTidyASTConsumer::HandleTopLevelDecl(DeclGroupRef DG) {
+ if (!MultiplexConsumer::HandleTopLevelDecl(DG))
+ return false;
+ if (Filter.get() != nullptr) {
+ for (Decl *D : DG) {
+ if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
+ if (isImplicitTemplateInstantiation(ND))
+ continue;
+
+ // ObjCMethodDecl are not actually top-level decls.
+ if (isa<ObjCMethodDecl>(D))
+ continue;
+
+ if (!Filter->skipDecl(D))
+ TopLevelDecls.push_back(D);
+ }
+ }
+ return true;
+}
+
+void ClangTidyASTConsumer::HandleTranslationUnit(ASTContext &Context) {
+ // If skip-headers is not on, there is no Filter and no skip TopLevelDecls.
+ // If there is no MatchFinder-based checks, FinderASTConsumerPtr is nullptr
+ // and there is no need to change TopLevelDecls.
+ // Only setTraversalScope without restoreing, assuming that this does not
+ // affect the static analyzer checks.
+ if (Filter.get() != nullptr && nullptr != FinderASTConsumerPtr)
+ Context.setTraversalScope(TopLevelDecls);
+ // If any static analyzer check does not work with filtered TopLevelDecls,
+ // the following loop should be changed to set/restore TraversalScope
+ // only when (Consumer.get() == FinderASTConsumerPtr).
+ for (auto &Consumer : Consumers)
+ Consumer->HandleTranslationUnit(Context);
+}
+
std::unique_ptr<clang::ASTConsumer>
ClangTidyASTConsumerFactory::CreateASTConsumer(
clang::CompilerInstance &Compiler, StringRef File) {
@@ -416,6 +550,10 @@
Context.getProfileStorageParams());
FinderOptions.CheckProfiling.emplace(Profiling->Records);
}
+ std::shared_ptr<DeclFilter> SharedDeclFilter;
+ if (*Context.getOptions().SkipHeaders)
+ SharedDeclFilter =
+ std::shared_ptr<DeclFilter>(new DeclFilter(Context, *SM));
std::unique_ptr<ast_matchers::MatchFinder> Finder(
new ast_matchers::MatchFinder(std::move(FinderOptions)));
@@ -436,8 +574,12 @@
}
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
- if (!Checks.empty())
- Consumers.push_back(Finder->newASTConsumer());
+ ASTConsumer *FinderASTConsumerPtr = nullptr;
+ if (!Checks.empty()) {
+ std::unique_ptr<ASTConsumer> FinderASTConsumer(Finder->newASTConsumer());
+ FinderASTConsumerPtr = FinderASTConsumer.get();
+ Consumers.push_back(std::move(FinderASTConsumer));
+ }
#if CLANG_TIDY_ENABLE_STATIC_ANALYZER
AnalyzerOptionsRef AnalyzerOptions = Compiler.getAnalyzerOpts();
@@ -458,7 +600,7 @@
#endif // CLANG_TIDY_ENABLE_STATIC_ANALYZER
return std::make_unique<ClangTidyASTConsumer>(
std::move(Consumers), std::move(Profiling), std::move(Finder),
- std::move(Checks));
+ FinderASTConsumerPtr, std::move(SharedDeclFilter), std::move(Checks));
}
std::vector<std::string> ClangTidyASTConsumerFactory::getCheckNames() {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits