[clang-tools-extra] [clang-tidy] Detect project root in llvm-header-guard (PR #205839)
Jeff Bailey via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 25 07:57:20 PDT 2026
https://github.com/kaladron created https://github.com/llvm/llvm-project/pull/205839
The llvm-header-guard check previously relied on hardcoded path components like 'llvm-project' or 'llvm' to identify the repository root. This caused false positives when running in git worktrees with arbitrary directory names.
This change adds a helper to dynamically detect the project root by looking for sibling 'llvm' and 'clang' directories, and canonicalizes the path to '/llvm-project/...' before running the guard calculation.
Assisted-by: Automated tooling, human reviewed.
>From e9883ce38260816d21cd9424ded9f6a035110583 Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Thu, 25 Jun 2026 15:45:14 +0100
Subject: [PATCH] [clang-tidy] Detect project root in llvm-header-guard
The llvm-header-guard check previously relied on hardcoded path
components like 'llvm-project' or 'llvm' to identify the repository
root. This caused false positives when running in git worktrees
with arbitrary directory names.
This change adds a helper to dynamically detect the project root
by looking for sibling 'llvm' and 'clang' directories, and
canonicalizes the path to '/llvm-project/...' before running the
guard calculation.
Assisted-by: Automated tooling, human reviewed.
---
.../clang-tidy/llvm/HeaderGuardCheck.cpp | 40 ++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp b/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp
index ef8b6b1dfb8f7..857e22dda6894 100644
--- a/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp
+++ b/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp
@@ -8,6 +8,7 @@
#include "HeaderGuardCheck.h"
#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
namespace clang::tidy::llvm_check {
@@ -16,9 +17,46 @@ LLVMHeaderGuardCheck::LLVMHeaderGuardCheck(StringRef Name,
ClangTidyContext *Context)
: HeaderGuardCheck(Name, Context) {}
+// Attempt to find the root of the LLVM project monorepo by walking up the
+// directory tree from Filename and looking for a directory containing both
+// 'llvm' and 'clang' subdirectories. This allows us to find the root even
+// when working in git worktrees with arbitrary names.
+static std::string findLLVMProjectRoot(StringRef Filename) {
+ SmallString<256> Path = Filename;
+ while (!Path.empty()) {
+ llvm::sys::path::remove_filename(Path);
+ if (Path.empty()) break;
+
+ SmallString<256> LLVMPath = Path;
+ llvm::sys::path::append(LLVMPath, "llvm");
+ SmallString<256> ClangPath = Path;
+ llvm::sys::path::append(ClangPath, "clang");
+
+ if (llvm::sys::fs::is_directory(LLVMPath) && llvm::sys::fs::is_directory(ClangPath)) {
+ return std::string(Path);
+ }
+ }
+ return "";
+}
+
std::string LLVMHeaderGuardCheck::getHeaderGuard(StringRef Filename,
StringRef OldGuard) {
- std::string Guard = tooling::getAbsolutePath(Filename);
+ std::string AbsolutePath = tooling::getAbsolutePath(Filename);
+ std::string Guard = AbsolutePath;
+
+ // If we can find the LLVM project root, canonicalize the path by replacing
+ // the root path prefix with "/llvm-project/". This ensures the subsequent
+ // legacy logic (which relies on hardcoded "llvm-project" or "llvm" path
+ // components) works correctly regardless of the actual worktree directory name.
+ std::string Root = findLLVMProjectRoot(AbsolutePath);
+ if (!Root.empty()) {
+ StringRef RelativePath = StringRef(AbsolutePath).substr(Root.size());
+ if (RelativePath.starts_with("/")) {
+ Guard = ("/llvm-project" + RelativePath).str();
+ } else {
+ Guard = ("/llvm-project/" + RelativePath).str();
+ }
+ }
// When running under Windows, need to convert the path separators from
// `\` to `/`.
More information about the cfe-commits
mailing list