[clang] Fix main header matching for headers with special characters. (PR #211934)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 24 14:53:30 PDT 2026
https://github.com/dmaclach created https://github.com/llvm/llvm-project/pull/211934
In Clang Tooling, escape HeaderStem before constructing MainIncludeRegex to prevent special characters (such as '+') from being interpreted as regex operators. Useful for Objective-C where "Foo+Bar.h" headers are very common for categories.
>From 826a4c5f0e7b9d1bd06e5734128ea0a9ea789aaf Mon Sep 17 00:00:00 2001
From: Dave MacLachlan <dmaclach at gmail.com>
Date: Fri, 24 Jul 2026 14:51:11 -0700
Subject: [PATCH] Fix main header matching for headers with special characters.
In Clang Tooling, escape HeaderStem before constructing MainIncludeRegex to prevent special characters (such as '+') from being interpreted as regex operators.
Useful for Objective-C where "Foo+Bar.h" headers are very common for categories.
---
clang/lib/Tooling/Inclusions/HeaderIncludes.cpp | 3 ++-
clang/unittests/Tooling/HeaderIncludesTest.cpp | 14 ++++++++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp b/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp
index 1212af52e1490..34f21faa8e342 100644
--- a/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp
+++ b/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp
@@ -340,7 +340,8 @@ bool IncludeCategoryManager::isMainHeader(StringRef IncludeName) const {
else if (FileStem.equals_insensitive(HeaderStem))
Matching = FileStem; // example 3)
if (!Matching.empty()) {
- llvm::Regex MainIncludeRegex(HeaderStem.str() + Style.IncludeIsMainRegex,
+ llvm::Regex MainIncludeRegex(llvm::Regex::escape(HeaderStem) +
+ Style.IncludeIsMainRegex,
llvm::Regex::IgnoreCase);
if (MainIncludeRegex.match(Matching))
return true;
diff --git a/clang/unittests/Tooling/HeaderIncludesTest.cpp b/clang/unittests/Tooling/HeaderIncludesTest.cpp
index 95fb05885a0b9..bc2ac3a97e97d 100644
--- a/clang/unittests/Tooling/HeaderIncludesTest.cpp
+++ b/clang/unittests/Tooling/HeaderIncludesTest.cpp
@@ -144,6 +144,20 @@ TEST_F(HeaderIncludesTest, InsertAfterMainHeader) {
EXPECT_NE(Expected, insert(Code, "<a>")) << "Not main header";
}
+TEST_F(HeaderIncludesTest, InsertAfterMainHeaderWithSpecialChars) {
+ std::string Code = "#include \"fix+bar.h\"\n"
+ "\n"
+ "int main() {}";
+ std::string Expected = "#include \"fix+bar.h\"\n"
+ "#include <a>\n"
+ "\n"
+ "int main() {}";
+ Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
+ .IncludeStyle;
+ FileName = "fix+bar.cpp";
+ EXPECT_EQ(Expected, insert(Code, "<a>"));
+}
+
TEST_F(HeaderIncludesTest, InsertMainHeader) {
Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
.IncludeStyle;
More information about the cfe-commits
mailing list