[clang] Fix hasName matcher assertion with inline namespaces (PR #100975)
Nathan James via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 28 23:22:48 PDT 2024
https://github.com/njames93 created https://github.com/llvm/llvm-project/pull/100975
Fix handling of nodes which can be skipped in the fast path for the hasName matcher
#100973
>From 8d1aeca42a0d544582823ff2bae0a217e14d1c02 Mon Sep 17 00:00:00 2001
From: Nathan James <n.james93 at hotmail.co.uk>
Date: Mon, 29 Jul 2024 07:21:53 +0100
Subject: [PATCH] Fix hasName matcher assertion with inline namespaces
Fix handling of nodes which can be skipped in the fast path for the
hasName matcher
---
clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 21 ++++++++++++-------
.../ASTMatchers/ASTMatchersNarrowingTest.cpp | 4 ++++
2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index bf87b1aa0992a..0556ae7ffae2f 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -537,14 +537,21 @@ class PatternSet {
/// that didn't match.
/// Return true if there are still any patterns left.
bool consumeNameSuffix(StringRef NodeName, bool CanSkip) {
- for (size_t I = 0; I < Patterns.size();) {
- if (::clang::ast_matchers::internal::consumeNameSuffix(Patterns[I].P,
- NodeName) ||
- CanSkip) {
- ++I;
- } else {
- Patterns.erase(Patterns.begin() + I);
+ if (CanSkip) {
+ // If we can skip the node, then we need to handle the case where a
+ // skipped node has the same name as its parent.
+ // namespace a { inline namespace a { class A; } }
+ // cxxRecordDecl(hasName("::a::A"))
+ // To do this, any patterns that match should be duplicated in our set, one of them with the tail removed.
+ for (size_t I = 0, E = Patterns.size(); I != E; ++I) {
+ StringRef Pattern = Patterns[I].P;
+ if (ast_matchers::internal::consumeNameSuffix(Patterns[I].P, NodeName))
+ Patterns.push_back({Pattern, Patterns[I].IsFullyQualified});
}
+ } else {
+ llvm::erase_if(Patterns, [&NodeName](auto &Pattern) {
+ return !::clang::ast_matchers::internal::consumeNameSuffix(Pattern.P, NodeName);
+ });
}
return !Patterns.empty();
}
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index f26140675fd46..611e1f9ba5327 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2552,6 +2552,10 @@ TEST_P(ASTMatchersTest, HasName_MatchesNamespaces) {
recordDecl(hasName("a+b::C"))));
EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
recordDecl(hasName("C"))));
+ EXPECT_TRUE(matches("namespace a { inline namespace a { class C; } }",
+ recordDecl(hasName("::a::C"))));
+ EXPECT_TRUE(matches("namespace a { inline namespace a { class C; } }",
+ recordDecl(hasName("::a::a::C"))));
}
TEST_P(ASTMatchersTest, HasName_MatchesOuterClasses) {
More information about the cfe-commits
mailing list