Author: Amr Hesham Date: 2025-03-05T21:32:24+01:00 New Revision: c017cdf0714afcccca3338529134f3792d9287f6
URL: https://github.com/llvm/llvm-project/commit/c017cdf0714afcccca3338529134f3792d9287f6 DIFF: https://github.com/llvm/llvm-project/commit/c017cdf0714afcccca3338529134f3792d9287f6.diff LOG: [Clang][ASTMatcher] Improve matching isDerivedFrom base in case of multi aliases exists (#126793) Previously in case of multiable aliases exists for the same base we just accept the first one https://github.com/llvm/llvm-project/blob/2cf6663d3c86b065edeb693815e6a4b325045cc2/clang/lib/ASTMatchers/ASTMatchFinder.cpp#L1290-L1297 For example ``` struct AnInterface {}; typedef AnInterface UnusedTypedef; typedef AnInterface Base; class AClass : public Base {}; ``` `cxxRecordDecl(isDerivedFrom(decl().bind("typedef")))` typedef will be bonded to `UnusedTypedef` But if we changed the order now it will point to the right one ``` struct AnInterface {}; typedef AnInterface Base; typedef AnInterface UnusedTypedef; class AClass : public Base {}; ``` `cxxRecordDecl(isDerivedFrom(decl().bind("typedef")))` typedef will be bonded to `Base` This PR improve the matcher to prioritise the alias that has same desugared name as the base, if not then just accept the first one. Fixes: #126498 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/ASTMatchers/ASTMatchFinder.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 35efa2ca4aa93..32db3fe5740ed 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -361,6 +361,8 @@ Fixed Point Support in Clang AST Matchers ------------ +- Ensure ``isDerivedFrom`` matches the correct base in case more than one alias exists. + clang-format ------------ diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp index 3d01a70395a9b..e9ec7eff1e0ab 100644 --- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp +++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp @@ -1287,6 +1287,27 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, auto Aliases = TypeAliases.find(CanonicalType); if (Aliases == TypeAliases.end()) return false; + + if (const auto *ElaboratedTypeNode = + llvm::dyn_cast<ElaboratedType>(TypeNode)) { + if (ElaboratedTypeNode->isSugared() && Aliases->second.size() > 1) { + const auto &DesugaredTypeName = + ElaboratedTypeNode->desugar().getAsString(); + + for (const TypedefNameDecl *Alias : Aliases->second) { + if (Alias->getName() != DesugaredTypeName) { + continue; + } + + BoundNodesTreeBuilder Result(*Builder); + if (Matcher.matches(*Alias, this, &Result)) { + *Builder = std::move(Result); + return true; + } + } + } + } + for (const TypedefNameDecl *Alias : Aliases->second) { BoundNodesTreeBuilder Result(*Builder); if (Matcher.matches(*Alias, this, &Result)) { diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index 5e1c12ba26d87..4e6baedae2be5 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -1167,6 +1167,23 @@ TEST_P(ASTMatchersTest, IsDerivedFrom_EmptyName) { EXPECT_TRUE(notMatches(Code, cxxRecordDecl(isSameOrDerivedFrom("")))); } +TEST_P(ASTMatchersTest, IsDerivedFrom_ElaboratedType) { + if (!GetParam().isCXX()) { + return; + } + + DeclarationMatcher IsDerivenFromBase = + cxxRecordDecl(isDerivedFrom(decl().bind("typedef"))); + + EXPECT_TRUE(matchAndVerifyResultTrue( + "struct AnInterface {};" + "typedef AnInterface UnusedTypedef;" + "typedef AnInterface Base;" + "class AClass : public Base {};", + IsDerivenFromBase, + std::make_unique<VerifyIdIsBoundTo<TypedefDecl>>("typedef", "Base"))); +} + TEST_P(ASTMatchersTest, IsDerivedFrom_ObjC) { DeclarationMatcher IsDerivedFromX = objcInterfaceDecl(isDerivedFrom("X")); EXPECT_TRUE( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits