diff --git a/op-finder/ASTHelpers.hpp b/op-finder/ASTHelpers.hpp index 0f6ed9d..e50e740 100644 --- a/op-finder/ASTHelpers.hpp +++ b/op-finder/ASTHelpers.hpp @@ -24,8 +24,20 @@ inline clang::SourceLocation resolveOperationSourceLocation(const clang::SourceM return original; } -template -std::tuple resolveLocations(const TOp* op, +inline std::tuple resolveLocationsWithLoc(const clang::SourceLocation& loc, + const clang::SourceManager& source_manager) +{ + const auto& loc_resolved = resolveOperationSourceLocation(source_manager, loc); + + return { + source_manager.getFilename(loc_resolved).str(), + source_manager.getSpellingLineNumber(loc_resolved), + source_manager.getSpellingColumnNumber(loc_resolved) + }; +} + +template +std::tuple resolveLocations(const TStmt* op, const clang::SourceManager& source_manager) { const auto& loc = resolveOperationSourceLocation(source_manager, op->getBeginLoc()); diff --git a/op-finder/OperationFinder.cpp b/op-finder/OperationFinder.cpp index 04fdab4..94f2cc2 100644 --- a/op-finder/OperationFinder.cpp +++ b/op-finder/OperationFinder.cpp @@ -29,6 +29,7 @@ void OperationFinder::processArithmetic(const clang::BinaryOperator* op, const c OperationLog log; log.line = line_number; log.operation = getOpcode(op).str(); + log.current_for_loops = _for_loop_stack; _processExpressionTypes(log, op, op->getLHS(), op->getRHS()); @@ -54,6 +55,7 @@ void OperationFinder::processUnaryArithmetic(const clang::UnaryOperator* op, con OperationLog log; log.line = line_number; log.operation = getOpcode(op).str(); + log.current_for_loops = _for_loop_stack; _processExpressionTypes(log, op, lhs, nullptr); @@ -62,6 +64,18 @@ void OperationFinder::processUnaryArithmetic(const clang::UnaryOperator* op, con llvm::outs() << "\n"; } +void OperationFinder::forLoopEntered() +{ + _for_loop_stack.push_back(_next_for_loop_id); + + _next_for_loop_id++; +} + +void OperationFinder::forLoopExited() +{ + _for_loop_stack.pop_back(); +} + void OperationFinder::_processExpressionTypes(OperationLog& log, const Expr* source, const Expr* op1, const Expr* op2) { diff --git a/op-finder/OperationFinder.hpp b/op-finder/OperationFinder.hpp index 7e9f554..1ac2ef5 100644 --- a/op-finder/OperationFinder.hpp +++ b/op-finder/OperationFinder.hpp @@ -17,9 +17,14 @@ public: void processArithmetic(const clang::BinaryOperator* op, const clang::SourceManager& source_manager); void processUnaryArithmetic(const clang::UnaryOperator* op, const clang::SourceManager& source_manager); + void forLoopEntered(); + void forLoopExited(); + private: void _processExpressionTypes(OperationLog& log, const clang::Expr* source, const clang::Expr* op1, const clang::Expr* op2); + int _next_for_loop_id = 0; + std::vector _for_loop_stack; IOperationOutput* _storage; }; diff --git a/op-finder/OperationFinderAstVisitor.cpp b/op-finder/OperationFinderAstVisitor.cpp index 7c6ed96..aa0b8e7 100644 --- a/op-finder/OperationFinderAstVisitor.cpp +++ b/op-finder/OperationFinderAstVisitor.cpp @@ -5,6 +5,7 @@ #include "OperationFinderAstVisitor.hpp" #include "OperationFinder.hpp" +#include "ASTHelpers.hpp" OperationFinderAstVisitor::OperationFinderAstVisitor(OperationFinder* op_finder) : _context(nullptr) @@ -28,9 +29,7 @@ bool OperationFinderAstVisitor::VisitBinaryOperator(clang::BinaryOperator* op) assert(_context); if (!op->isCompoundAssignmentOp()) - { _op_finder->processArithmetic(op, _context->getSourceManager()); - } return true; } @@ -48,6 +47,22 @@ 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; } @@ -55,5 +70,34 @@ 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(); + } +} diff --git a/op-finder/OperationFinderAstVisitor.hpp b/op-finder/OperationFinderAstVisitor.hpp index cf57477..cf78f1d 100644 --- a/op-finder/OperationFinderAstVisitor.hpp +++ b/op-finder/OperationFinderAstVisitor.hpp @@ -25,8 +25,12 @@ public: bool dataTraverseStmtPost(clang::Stmt* stmt); private: + void _checkIfForLoopInitDone(clang::Stmt* stmt); + clang::ASTContext* _context; OperationFinder* _op_finder; + + clang::Stmt* _loop_init = nullptr; }; #endif //C_ANALYZER_OPERATIONFINDERASTVISITOR_HPP diff --git a/op-finder/OperationLog.hpp b/op-finder/OperationLog.hpp index 4642ca9..b17e819 100644 --- a/op-finder/OperationLog.hpp +++ b/op-finder/OperationLog.hpp @@ -5,6 +5,8 @@ #ifndef C_ANALYZER_OPERATIONLOG_HPP #define C_ANALYZER_OPERATIONLOG_HPP +#include + struct OperationLog { std::string operation; @@ -12,6 +14,7 @@ struct OperationLog std::string operand_lhs; std::string operand_rhs; std::string operand_result; + std::vector current_for_loops; }; class IOperationOutput @@ -31,7 +34,8 @@ inline void to_json(nlohmann::json& j, const OperationLog& l) {"line", l.line}, {"operand_lhs", l.operand_lhs}, {"operand_rhs", l.operand_rhs}, - {"operand_result", l.operand_result} + {"operand_result", l.operand_result}, + {"current_for_loops", l.current_for_loops} }; } @@ -42,6 +46,7 @@ inline void from_json(const nlohmann::json& j, OperationLog& l) j.at("operand_lhs").get_to(l.operand_lhs); j.at("operand_rhs").get_to(l.operand_rhs); j.at("operand_result").get_to(l.operand_result); + j.at("current_for_loops").get_to(l.current_for_loops); } #endif //C_ANALYZER_OPERATIONLOG_HPP