Loop initializations are excluded from eval
This commit is contained in:
parent
be4a71325d
commit
5a2d5ed933
@ -24,8 +24,20 @@ inline clang::SourceLocation resolveOperationSourceLocation(const clang::SourceM
|
||||
return original;
|
||||
}
|
||||
|
||||
template<typename TOp>
|
||||
std::tuple<std::string, unsigned int, unsigned int> resolveLocations(const TOp* op,
|
||||
inline std::tuple<std::string, unsigned int, unsigned int> 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<typename TStmt>
|
||||
std::tuple<std::string, unsigned int, unsigned int> resolveLocations(const TStmt* op,
|
||||
const clang::SourceManager& source_manager)
|
||||
{
|
||||
const auto& loc = resolveOperationSourceLocation(source_manager, op->getBeginLoc());
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
|
||||
@ -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<int> _for_loop_stack;
|
||||
IOperationOutput* _storage;
|
||||
};
|
||||
|
||||
|
||||
@ -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<clang::ForStmt>(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<clang::ForStmt>(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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
#ifndef C_ANALYZER_OPERATIONLOG_HPP
|
||||
#define C_ANALYZER_OPERATIONLOG_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
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<int> 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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user