I am looking to change the following code, with the help of the clang ast matcher.
foo(NUM << DEV_SHIFT | DEVICE);
to
foo(ADDR(NUM, DEVICE));
with
#define ADDR(a, b) (((a) << NUM_SHIFT) | (b))
I have the following AST-matcher that seems to identify the code pretty well.
Finder->addMatcher(
callExpr(hasArgument(
0, binaryOperator(hasOperatorName("|"),
hasLHS(ignoringParenImpCasts(
binaryOperator(hasOperatorName("<<")))))
.bind("replaceWithMacro"))),
this);
But I have a problem to understand how to write the check and the translation. I am currently stuck with this code:
void FirstCheckCheck::check(const MatchFinder::MatchResult &Result) {
// FIXME: Add callback implementation.
if (const auto MatchedDecl =
Result.Nodes.getNodeAs<CallExpr>("replaceWithMacro")) {
diag(MatchedDecl->getExprLoc(), "CallExp");
} else if (const auto MatchedDecl =
Result.Nodes.getNodeAs<Expr>("replaceWithMacro")) {
diag(MatchedDecl->getExprLoc(), "Expr");
diag(MatchedDecl->getBeginLoc(), "BeginLOC");
diag(MatchedDecl->getEndLoc(), "EndLOC");
}
I don't know how to extract the two variables as strings. I was looking at the documentation for the Expr class (http://clang.llvm.org/doxygen/classclang_1_1Expr.html), but I couldn't find something useful.
If somebody could point me into the right direction it would be appreciated.
Add edit's.