I'm modifying clang-tidy to build a matcher to match multiple (more than 3) else if statements, like such:
if (val < 0) {
result = 0;
}
else if (val < 1) {
result = 1;
}
else if (val < 2) {
result = 2;
}
else if (val < 3) {
result = 3;
}
else {
result = 4;
}
To begin with I try to match the simplest case with 2 nested if:
if (condition_a) {
}
else if (condition_b) {
}
So I have my registerMatchers() and check():
void MultiIfElseCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(ifStmt(hasThen(hasDescendant(ifStmt()))).bind("outer_if"),
this);
}
void MultiIfElseCheck::check(const MatchFinder::MatchResult &Result) {
const auto *OuterIf = Result.Nodes.getNodeAs<IfStmt>("outer_if");
if (OuterIf) {
diag(OuterIf->getIfLoc(), "This IF is followed with too many ELSE-IF\n",
DiagnosticIDs::Note);
}
}
But this matcher matched nothing from the code above. I try futher simplify the matcher to any ifStmt:
Finder->addMatcher(ifStmt().bind("outer_if"), this);
And still matched nothing.
Can someone tell me how do I fix it?
To match an
if-elsechain, use a matcher like:The main issue with your attempt is using
hasThenrather thanhasElse. WithhasThen, it would match things like:I can't explan why the trivial
ifStmt()matcher doesn't match anything. It does for me.Here's a complete example
clang-tidychecker that reports the example in the question:(My
mainfunction is perhaps a bit dodgy, but that's unrelated to this question.)When given the input:
Its output is:
Note: If there are more than three
else ifelements in the chain, then you will get matches for all that have three or more after them. More work would be needed to filter out all but the first one.