// // Created by erki on 02.03.21. // #include "OperationFinderAstVisitor.hpp" #include "OperationFinder.hpp" #include "ASTHelpers.hpp" OperationFinderAstVisitor::OperationFinderAstVisitor(OperationFinder* op_finder) : _context(nullptr) , _op_finder(op_finder) { } void OperationFinderAstVisitor::NewContext(clang::ASTContext* context) { _context = context; } bool OperationFinderAstVisitor::VisitForStmt(clang::ForStmt* stmt) { assert(_context); return true; } bool OperationFinderAstVisitor::VisitBinaryOperator(clang::BinaryOperator* op) { assert(_context); if (!op->isCompoundAssignmentOp()) _op_finder->processArithmetic(op, _context->getSourceManager()); return true; } bool OperationFinderAstVisitor::VisitUnaryOperator(clang::UnaryOperator* op) { assert(_context); _op_finder->processUnaryArithmetic(op, _context->getSourceManager()); return true; } bool OperationFinderAstVisitor::dataTraverseStmtPre(clang::Stmt* stmt) { assert(_context); if (auto* loop = clang::dyn_cast(stmt)) { if (loop->getInit()) { _loop_init = loop->getInit(); } else { _op_finder->forLoopEntered(); } } else { _checkIfForLoopInitDone(stmt); } return true; } bool OperationFinderAstVisitor::dataTraverseStmtPost(clang::Stmt* stmt) { assert(_context); if (clang::dyn_cast(stmt)) _op_finder->forLoopExited(); return true; } void OperationFinderAstVisitor::_checkIfForLoopInitDone(clang::Stmt* stmt) { if (!_loop_init || stmt == _loop_init) return; const auto [file, line, column] = resolveLocationsWithLoc(stmt->getEndLoc(), _context->getSourceManager()); const auto [for_file, for_line, for_column] = resolveLocationsWithLoc(_loop_init->getEndLoc(), _context->getSourceManager()); bool is_done = false; if (line > for_line) { is_done = true; } else if (line == for_line && column > for_column) { is_done = true; } if (is_done) { _loop_init = nullptr; _op_finder->forLoopEntered(); } }