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

Reply via email to