Skip to content

Commit 8f2858e

Browse files
njames93zmodem
authored andcommitted
[ASTMatchers] HasNameMatcher handles extern "C"
Summary: Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=42193 | hasName AST matcher is confused by extern "C" in namespace. ]] Reviewers: klimek, aaron.ballman, gribozavr2 Reviewed By: aaron.ballman Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D75202 (cherry picked from commit 16cabf2)
1 parent 058a8cd commit 8f2858e

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

clang/lib/ASTMatchers/ASTMatchersInternal.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,13 @@ bool HasNameMatcher::matchesNodeFullFast(const NamedDecl &Node) const {
523523
if (Ctx->isFunctionOrMethod())
524524
return Patterns.foundMatch(/*AllowFullyQualified=*/false);
525525

526-
for (; Ctx && isa<NamedDecl>(Ctx); Ctx = Ctx->getParent()) {
526+
for (; Ctx; Ctx = Ctx->getParent()) {
527+
// Linkage Spec can just be ignored
528+
// FIXME: Any other DeclContext kinds that can be safely disregarded
529+
if (isa<LinkageSpecDecl>(Ctx))
530+
continue;
531+
if (!isa<NamedDecl>(Ctx))
532+
break;
527533
if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
528534
return true;
529535

clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,6 +1520,21 @@ TEST(Matcher, HasNameSupportsFunctionScope) {
15201520
EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));
15211521
}
15221522

1523+
TEST(Matcher, HasNameQualifiedSupportsLinkage) {
1524+
// https://bugs.llvm.org/show_bug.cgi?id=42193
1525+
std::string code = R"cpp(namespace foo { extern "C" void test(); })cpp";
1526+
EXPECT_TRUE(matches(code, functionDecl(hasName("test"))));
1527+
EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test"))));
1528+
EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test"))));
1529+
EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test"))));
1530+
1531+
code = R"cpp(namespace foo { extern "C" { void test(); } })cpp";
1532+
EXPECT_TRUE(matches(code, functionDecl(hasName("test"))));
1533+
EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test"))));
1534+
EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test"))));
1535+
EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test"))));
1536+
}
1537+
15231538
TEST(Matcher, HasAnyName) {
15241539
const std::string Code = "namespace a { namespace b { class C; } }";
15251540

0 commit comments

Comments
 (0)