llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-tidy @llvm/pr-subscribers-clang-tools-extra Author: Thorsten Klein (thorsten-klein) <details> <summary>Changes</summary> new option `HeaderDirs` for `llvm-header-guard` is added. Defaults to `include`. When checking header guards, the header file path is searched for the first matching directory in this `HeaderDirs` list. All parent path components preceding that directory are discarded, so the generated header guard starts at the matched include directory. Ref: #<!-- -->71732 --- Full diff: https://github.com/llvm/llvm-project/pull/176940.diff 11 Files Affected: - (modified) clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp (+18-5) - (modified) clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.h (+4) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+8) - (modified) clang-tools-extra/docs/clang-tidy/checks/llvm/header-guard.rst (+8) - (added) clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard.cpp (+104) - (added) clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/include/correct.hpp (+6) - (added) clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/include/missing.hpp () - (added) clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/include/wrong.hpp (+6) - (added) clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/other/correct.hpp (+11) - (added) clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/other/missing.hpp () - (added) clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/other/wrong.hpp (+6) ``````````diff diff --git a/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp b/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp index ef8b6b1dfb8f7..36e837e203a89 100644 --- a/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "HeaderGuardCheck.h" +#include "../utils/OptionsUtils.h" #include "clang/Tooling/Tooling.h" #include "llvm/Support/Path.h" @@ -14,7 +15,9 @@ namespace clang::tidy::llvm_check { LLVMHeaderGuardCheck::LLVMHeaderGuardCheck(StringRef Name, ClangTidyContext *Context) - : HeaderGuardCheck(Name, Context) {} + : HeaderGuardCheck(Name, Context), + HeaderDirs(utils::options::parseStringList( + Options.get("HeaderDirs", "include"))) {} std::string LLVMHeaderGuardCheck::getHeaderGuard(StringRef Filename, StringRef OldGuard) { @@ -27,10 +30,15 @@ std::string LLVMHeaderGuardCheck::getHeaderGuard(StringRef Filename, // Sanitize the path. There are some rules for compatibility with the historic // style in include/llvm and include/clang which we want to preserve. - // We don't want _INCLUDE_ in our guards. - const size_t PosInclude = Guard.rfind("include/"); - if (PosInclude != StringRef::npos) - Guard = Guard.substr(PosInclude + std::strlen("include/")); + // consider all directories from HeaderDirs option. Stop at first found. + for (StringRef HeaderDir : HeaderDirs) { + size_t PosHeaderDir = Guard.rfind(HeaderDir.str() + "/"); + if (PosHeaderDir != StringRef::npos) { + // We don't want the header dir in our guards, i.e. _INCLUDE_ + Guard = Guard.substr(PosHeaderDir + HeaderDir.size() + 1); + break; // stop at first found + } + } // For clang we drop the _TOOLS_. const size_t PosToolsClang = Guard.rfind("tools/clang/"); @@ -64,4 +72,9 @@ std::string LLVMHeaderGuardCheck::getHeaderGuard(StringRef Filename, return StringRef(Guard).upper(); } +void LLVMHeaderGuardCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "HeaderDirs", + utils::options::serializeStringList(HeaderDirs)); +} + } // namespace clang::tidy::llvm_check diff --git a/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.h b/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.h index cfc920bb85e23..a7447a5c8863d 100644 --- a/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.h +++ b/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.h @@ -21,7 +21,11 @@ class LLVMHeaderGuardCheck : public utils::HeaderGuardCheck { LLVMHeaderGuardCheck(StringRef Name, ClangTidyContext *Context); bool shouldSuggestEndifComment(StringRef Filename) override { return false; } + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; std::string getHeaderGuard(StringRef Filename, StringRef OldGuard) override; + +private: + const std::vector<StringRef> HeaderDirs; }; } // namespace clang::tidy::llvm_check diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 94a11b1acb73a..61889d8b90210 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -113,6 +113,14 @@ Changes in existing checks <clang-tidy/checks/performance/move-const-arg>` check by avoiding false positives on trivially copyable types with a non-public copy constructor. +- Improved :doc:`llvm-header-guard + <clang-tidy/checks/llvm/header-guard>` check by adding the option + `HeaderDirs` which is a list of one or more include directory names. + Defaults to `include`. When checking header guards, the header file path is + searched for the first matching directory in this list. All parent path + components preceding that directory are discarded, so the generated header + guard starts at the matched include directory. + Removed checks ^^^^^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/llvm/header-guard.rst b/clang-tools-extra/docs/clang-tidy/checks/llvm/header-guard.rst index 74eb10ba6fcf9..f65bea01421f0 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/llvm/header-guard.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/llvm/header-guard.rst @@ -4,3 +4,11 @@ llvm-header-guard ================= Finds and fixes header guards that do not adhere to LLVM style. + +Options +------- + +.. option:: HeaderDirs + + A list of directories where the include guard string will start. + defaults to `include`. diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard.cpp new file mode 100644 index 0000000000000..8cc3ea8f26581 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard.cpp @@ -0,0 +1,104 @@ +#include "header-guard/include/correct.hpp" +#include "header-guard/include/missing.hpp" +#include "header-guard/include/wrong.hpp" + +#include "header-guard/other/correct.hpp" +#include "header-guard/other/missing.hpp" +#include "header-guard/other/wrong.hpp" + +// --------------------------------------- +// TEST 1: Use no config options (default) +// --------------------------------------- +// RUN: %check_clang_tidy %s llvm-header-guard %t -export-fixes=%t.1.yaml --header-filter=.* -- -I%S > %t.1.msg 2>&1 +// RUN: FileCheck -input-file=%t.1.msg -check-prefix=CHECK-MESSAGES1 %s +// RUN: FileCheck -input-file=%t.1.yaml -check-prefix=CHECK-YAML1 %s + +// CHECK-MESSAGES1: header-guard/include/missing.hpp:1:1: warning: header is missing header guard [llvm-header-guard] +// CHECK-MESSAGES1: header-guard/other/missing.hpp:1:1: warning: header is missing header guard [llvm-header-guard] +// CHECK-MESSAGES1: header-guard/include/wrong.hpp:1:9: warning: header guard does not follow preferred style [llvm-header-guard] +// CHECK-MESSAGES1: header-guard/other/wrong.hpp:1:9: warning: header guard does not follow preferred style [llvm-header-guard] + +// CHECK-YAML1: Message: header is missing header guard +// CHECK-YAML1: FilePath: '{{.*}}/header-guard/include/missing.hpp' +// CHECK-YAML1: ReplacementText: "#ifndef MISSING_HPP\n#define MISSING_HPP\n\n\n#endif\n" +// CHECK-YAML1: Message: header guard does not follow preferred style +// CHECK-YAML1: FilePath: '{{.*}}/header-guard/include/wrong.hpp' +// CHECK-YAML1: ReplacementText: WRONG_HPP + +// CHECK-YAML1: Message: header is missing header guard +// CHECK-YAML1: FilePath: '{{.*}}/header-guard/other/missing.hpp' +// CHECK-YAML1: ReplacementText: "#ifndef LLVM_HEADER_GUARD_OTHER_MISSING_HPP\n#define LLVM_HEADER_GUARD_OTHER_MISSING_HPP\n\n\n#endif\n" +// CHECK-YAML1: Message: header guard does not follow preferred style +// CHECK-YAML1: FilePath: '{{.*}}/header-guard/other/wrong.hpp' +// CHECK-YAML1: ReplacementText: LLVM_HEADER_GUARD_OTHER_WRONG_HPP + +// --------------------------------------- +// TEST 2: Set option HeaderDirs=other +// --------------------------------------- +// RUN: %check_clang_tidy %s llvm-header-guard %t -export-fixes=%t.2.yaml --header-filter=.* \ +// RUN: --config='{CheckOptions: { \ +// RUN: llvm-header-guard.HeaderDirs: other, \ +// RUN: }}' -- -I%S > %t.2.msg 2>&1 +// RUN: FileCheck -input-file=%t.2.msg -check-prefix=CHECK-MESSAGES2 %s +// RUN: FileCheck -input-file=%t.2.yaml -check-prefix=CHECK-YAML2 %s + +// CHECK-MESSAGES2: header-guard/include/missing.hpp:1:1: warning: header is missing header guard [llvm-header-guard] +// CHECK-MESSAGES2: header-guard/other/missing.hpp:1:1: warning: header is missing header guard [llvm-header-guard] +// CHECK-MESSAGES2: header-guard/include/wrong.hpp:1:9: warning: header guard does not follow preferred style [llvm-header-guard] +// CHECK-MESSAGES2: header-guard/other/wrong.hpp:1:9: warning: header guard does not follow preferred style [llvm-header-guard] + +// CHECK-YAML2: Message: header guard does not follow preferred style +// CHECK-YAML2: FilePath: '{{.*}}/header-guard/include/correct.hpp' +// CHECK-YAML2: ReplacementText: LLVM_HEADER_GUARD_INCLUDE_CORRECT_HPP +// CHECK-YAML2: Message: header is missing header guard +// CHECK-YAML2: FilePath: '{{.*}}/header-guard/include/missing.hpp' +// CHECK-YAML2: ReplacementText: "#ifndef LLVM_HEADER_GUARD_INCLUDE_MISSING_HPP\n#define LLVM_HEADER_GUARD_INCLUDE_MISSING_HPP\n\n\n#endif\n" +// CHECK-YAML2: Message: header guard does not follow preferred style +// CHECK-YAML2: FilePath: '{{.*}}/header-guard/include/wrong.hpp' +// CHECK-YAML2: ReplacementText: LLVM_HEADER_GUARD_INCLUDE_WRONG_HPP + +// CHECK-YAML2: Message: header guard does not follow preferred style +// CHECK-YAML2: FilePath: '{{.*}}/header-guard/other/correct.hpp' +// CHECK-YAML2: ReplacementText: CORRECT_HPP +// CHECK-YAML2: Message: header is missing header guard +// CHECK-YAML2: FilePath: '{{.*}}/header-guard/other/missing.hpp' +// CHECK-YAML2: ReplacementText: "#ifndef MISSING_HPP\n#define MISSING_HPP\n\n\n#endif\n" +// CHECK-YAML2: Message: header guard does not follow preferred style +// CHECK-YAML2: FilePath: '{{.*}}/header-guard/other/wrong.hpp' +// CHECK-YAML2: ReplacementText: WRONG_HPP + + +// --------------------------------------- +// TEST 3: Set option HeaderDirs=include;other +// --------------------------------------- +// RUN: %check_clang_tidy %s llvm-header-guard %t -export-fixes=%t.3.yaml --header-filter=.* \ +// RUN: --config='{CheckOptions: { \ +// RUN: llvm-header-guard.HeaderDirs: include;other, \ +// RUN: }}' -- -I%S > %t.3.msg 2>&1 +// RUN: FileCheck -input-file=%t.3.msg -check-prefix=CHECK-MESSAGES3 %s +// RUN: FileCheck -input-file=%t.3.yaml -check-prefix=CHECK-YAML3 %s + +// CHECK-MESSAGES3: header-guard/include/missing.hpp:1:1: warning: header is missing header guard [llvm-header-guard] +// CHECK-MESSAGES3: header-guard/other/missing.hpp:1:1: warning: header is missing header guard [llvm-header-guard] +// CHECK-MESSAGES3: header-guard/include/wrong.hpp:1:9: warning: header guard does not follow preferred style [llvm-header-guard] +// CHECK-MESSAGES3: header-guard/other/wrong.hpp:1:9: warning: header guard does not follow preferred style [llvm-header-guard] + +// CHECK-YAML3: Message: header is missing header guard +// CHECK-YAML3: FilePath: '{{.*}}/header-guard/include/missing.hpp' +// CHECK-YAML3: ReplacementText: "#ifndef MISSING_HPP\n#define MISSING_HPP\n\n\n#endif\n" +// CHECK-YAML3: Message: header guard does not follow preferred style +// CHECK-YAML3: FilePath: '{{.*}}/header-guard/include/wrong.hpp' +// CHECK-YAML3: ReplacementText: WRONG_HPP + +// CHECK-YAML3: Message: header guard does not follow preferred style +// CHECK-YAML3: FilePath: '{{.*}}/header-guard/other/correct.hpp' +// CHECK-YAML3: ReplacementText: CORRECT_HPP +// CHECK-YAML3: Message: header is missing header guard +// CHECK-YAML3: FilePath: '{{.*}}/header-guard/other/missing.hpp' +// CHECK-YAML3: ReplacementText: "#ifndef MISSING_HPP\n#define MISSING_HPP\n\n\n#endif\n" +// CHECK-YAML3: Message: header guard does not follow preferred style +// CHECK-YAML3: FilePath: '{{.*}}/header-guard/other/wrong.hpp' +// CHECK-YAML3: ReplacementText: WRONG_HPP + + + diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/include/correct.hpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/include/correct.hpp new file mode 100644 index 0000000000000..19f3347459a7a --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/include/correct.hpp @@ -0,0 +1,6 @@ +#ifndef CORRECT_HPP +#define CORRECT_HPP + +// do anything + +#endif diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/include/missing.hpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/include/missing.hpp new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/include/wrong.hpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/include/wrong.hpp new file mode 100644 index 0000000000000..bc58b550aca09 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/include/wrong.hpp @@ -0,0 +1,6 @@ +#ifndef HERE_IS_SOMETHING_WRONG_HPP +#define HERE_IS_SOMETHING_WRONG_HPP + +// do anything + +#endif diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/other/correct.hpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/other/correct.hpp new file mode 100644 index 0000000000000..f3da7919d5853 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/other/correct.hpp @@ -0,0 +1,11 @@ +#ifndef LLVM_HEADER_GUARD_OTHER_CORRECT_HPP +#define LLVM_HEADER_GUARD_OTHER_CORRECT_HPP + +#ifndef CORRECT_HPP +#define CORRECT_HPP + +// do anything + +#endif + +#endif diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/other/missing.hpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/other/missing.hpp new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/other/wrong.hpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/other/wrong.hpp new file mode 100644 index 0000000000000..7b8abb25cf951 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/header-guard/other/wrong.hpp @@ -0,0 +1,6 @@ +#ifndef SOME_WRONG_HEADER_GUARD_HPP +#define SOME_WRONG_HEADER_GUARD_HPP + +// do anything + +#endif `````````` </details> https://github.com/llvm/llvm-project/pull/176940 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
