// // Created by erki on 02.03.21. // #include "OperationAstMatcher.hpp" #include "OperationFinder.hpp" using namespace clang; using namespace clang::ast_matchers; namespace { StatementMatcher AssignmentMatcher = binaryOperation(isAssignmentOperator(), hasLHS(expr().bind("lhs")), hasRHS(expr().bind("rhs"))).bind("assignment"); StatementMatcher ArithmeticMatcher = binaryOperation(hasAnyOperatorName("+", "-", "/", "*", "<", ">", "<=", ">=", "==", "<<", ">>", "%"), hasLHS(expr().bind("lhs")), hasRHS(expr().bind("lhs"))).bind("arithmetic"); StatementMatcher UnaryArithmeticMatcher = unaryOperator(hasAnyOperatorName("!", "++", "--"), hasUnaryOperand(expr().bind("lhs"))).bind("unary_arithmetic"); } OperationASTMatcher::OperationASTMatcher(OperationFinder* finder) : _op_finder(finder) { } void OperationASTMatcher::addToFinder(clang::ast_matchers::MatchFinder& finder) { finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, ArithmeticMatcher), this); finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, AssignmentMatcher), this); finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, UnaryArithmeticMatcher), this); } void OperationASTMatcher::run(const clang::ast_matchers::MatchFinder::MatchResult& result) { if (const auto* op = result.Nodes.getNodeAs("assignment")) { _op_finder->processArithmetic(op, *result.SourceManager); } else if (const auto* op = result.Nodes.getNodeAs("arithmetic")) { _op_finder->processArithmetic(op, *result.SourceManager); } else if (const auto* op = result.Nodes.getNodeAs("unary_arithmetic")) { _op_finder->processUnaryArithmetic(op, *result.SourceManager); } }