Skip to content

Commit bf17eb2

Browse files
committed
[Clang][ASTMatcher] Improve matching isDerivedFrom base in case of multi alias exists
1 parent 7639242 commit bf17eb2

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

clang/lib/ASTMatchers/ASTMatchFinder.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,27 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
12871287
auto Aliases = TypeAliases.find(CanonicalType);
12881288
if (Aliases == TypeAliases.end())
12891289
return false;
1290+
1291+
if (const auto *ElaboratedTypeNode =
1292+
llvm::dyn_cast<ElaboratedType>(TypeNode)) {
1293+
if (ElaboratedTypeNode->isSugared() && Aliases->second.size() > 1) {
1294+
const auto &DesugaredTypeName =
1295+
ElaboratedTypeNode->desugar().getAsString();
1296+
1297+
for (const TypedefNameDecl *Alias : Aliases->second) {
1298+
if (Alias->getName() != DesugaredTypeName) {
1299+
continue;
1300+
}
1301+
1302+
BoundNodesTreeBuilder Result(*Builder);
1303+
if (Matcher.matches(*Alias, this, &Result)) {
1304+
*Builder = std::move(Result);
1305+
return true;
1306+
}
1307+
}
1308+
}
1309+
}
1310+
12901311
for (const TypedefNameDecl *Alias : Aliases->second) {
12911312
BoundNodesTreeBuilder Result(*Builder);
12921313
if (Matcher.matches(*Alias, this, &Result)) {

clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,23 @@ TEST_P(ASTMatchersTest, IsDerivedFrom_EmptyName) {
11671167
EXPECT_TRUE(notMatches(Code, cxxRecordDecl(isSameOrDerivedFrom(""))));
11681168
}
11691169

1170+
TEST_P(ASTMatchersTest, IsDerivedFrom_ElaboratedType) {
1171+
if (!GetParam().isCXX()) {
1172+
return;
1173+
}
1174+
1175+
DeclarationMatcher IsDerivenFromBase =
1176+
cxxRecordDecl(isDerivedFrom(decl().bind("typedef")));
1177+
1178+
EXPECT_TRUE(matchAndVerifyResultTrue(
1179+
"struct AnInterface {};"
1180+
"typedef AnInterface UnusedTypedef;"
1181+
"typedef AnInterface Base;"
1182+
"class AClass : public Base {};",
1183+
IsDerivenFromBase,
1184+
std::make_unique<VerifyIdIsBoundTo<TypedefDecl>>("typedef", "Base")));
1185+
}
1186+
11701187
TEST_P(ASTMatchersTest, IsDerivedFrom_ObjC) {
11711188
DeclarationMatcher IsDerivedFromX = objcInterfaceDecl(isDerivedFrom("X"));
11721189
EXPECT_TRUE(

0 commit comments

Comments
 (0)