llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) <details> <summary>Changes</summary> 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 --- Full diff: https://github.com/llvm/llvm-project/pull/126793.diff 2 Files Affected: - (modified) clang/lib/ASTMatchers/ASTMatchFinder.cpp (+21) - (modified) clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp (+17) ``````````diff 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( `````````` </details> https://github.com/llvm/llvm-project/pull/126793 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits