Add subscript operation recognition
This commit is contained in:
parent
7a852f8f94
commit
a23e5c66ab
@ -48,19 +48,13 @@ OperationFinder::OperationFinder(IOperationOutput* storage)
|
|||||||
|
|
||||||
void OperationFinder::processArithmetic(const clang::BinaryOperator* op, const clang::SourceManager& source_manager)
|
void OperationFinder::processArithmetic(const clang::BinaryOperator* op, const clang::SourceManager& source_manager)
|
||||||
{
|
{
|
||||||
const auto [file_name, line_number, column_number] = resolveLocations(op, source_manager);
|
auto [file_name, log] = _createBaseOperationLog(op, source_manager);
|
||||||
|
const std::string op_code = getOpcode(op).str();
|
||||||
|
|
||||||
llvm::outs() << file_name << ":"
|
llvm::outs() << "\n\tBinary arithmetic: Type: " << op_code;
|
||||||
<< line_number << ":"
|
|
||||||
<< column_number << ":"
|
|
||||||
<< "Binary arithmetic: Type: " << getOpcode(op) << " LHS: ";
|
|
||||||
|
|
||||||
OperationLog log;
|
|
||||||
log.line = line_number;
|
|
||||||
log.entry_type = OperationLog::BasicOperation::TYPE_NAME;
|
log.entry_type = OperationLog::BasicOperation::TYPE_NAME;
|
||||||
log.entry = _createBasicOperationLogEntry(op, op->getLHS(), op->getRHS());
|
log.entry = _createBasicOperationLogEntry(op_code, op, op->getLHS(), op->getRHS());
|
||||||
log.current_for_loops = _for_loop_stack;
|
|
||||||
log.is_fallthrough = _in_fallthrough;
|
|
||||||
|
|
||||||
_storage->pushOperation(file_name, std::move(log));
|
_storage->pushOperation(file_name, std::move(log));
|
||||||
|
|
||||||
@ -69,24 +63,13 @@ void OperationFinder::processArithmetic(const clang::BinaryOperator* op, const c
|
|||||||
|
|
||||||
void OperationFinder::processUnaryArithmetic(const clang::UnaryOperator* op, const clang::SourceManager& source_manager)
|
void OperationFinder::processUnaryArithmetic(const clang::UnaryOperator* op, const clang::SourceManager& source_manager)
|
||||||
{
|
{
|
||||||
const Expr* lhs = op->getExprStmt();
|
auto [file_name, log] = _createBaseOperationLog(op, source_manager);
|
||||||
|
const std::string op_code = getOpcode(op).str();
|
||||||
|
|
||||||
assert(op);
|
llvm::outs() << "\n\tUnary arithmetic: Type: " << op_code;
|
||||||
assert(lhs);
|
|
||||||
|
|
||||||
const auto [file_name, line_number, column_number] = resolveLocations(op, source_manager);
|
|
||||||
|
|
||||||
llvm::outs() << file_name << ":"
|
|
||||||
<< line_number << ":"
|
|
||||||
<< column_number << ":"
|
|
||||||
<< "Unary arithmetic: Type: " << getOpcode(op) << " LHS: ";
|
|
||||||
|
|
||||||
OperationLog log;
|
|
||||||
log.line = line_number;
|
|
||||||
log.entry_type = OperationLog::BasicOperation::TYPE_NAME;
|
log.entry_type = OperationLog::BasicOperation::TYPE_NAME;
|
||||||
log.entry = _createBasicOperationLogEntry(op, lhs, nullptr);
|
log.entry = _createBasicOperationLogEntry(op_code, op, op->getExprStmt(), nullptr);
|
||||||
log.current_for_loops = _for_loop_stack;
|
|
||||||
log.is_fallthrough = _in_fallthrough;
|
|
||||||
|
|
||||||
_storage->pushOperation(file_name, std::move(log));
|
_storage->pushOperation(file_name, std::move(log));
|
||||||
|
|
||||||
@ -99,29 +82,37 @@ void OperationFinder::processFunctionCall(const clang::CallExpr* call, const Sou
|
|||||||
|
|
||||||
assert(func);
|
assert(func);
|
||||||
|
|
||||||
const auto [file_name, line_number, column_number] = resolveLocations(call, source_manager);
|
auto [file_name, log] = _createBaseOperationLog(call, source_manager);
|
||||||
|
|
||||||
const std::string res_type = ResolveTypeName(func->getType());
|
|
||||||
const std::string func_name = func->getNameAsString();
|
const std::string func_name = func->getNameAsString();
|
||||||
|
|
||||||
llvm::outs() << file_name << ":"
|
llvm::outs() << "\n\tFunction call: func name: " << func_name << "\n\tResult eval type: ";
|
||||||
<< line_number << ":"
|
|
||||||
<< column_number << ":"
|
const std::string res_type = ResolveTypeName(func->getType());
|
||||||
<< "Function call: name: " << func_name << " Restype: "
|
|
||||||
<< res_type << "\n";
|
|
||||||
|
|
||||||
auto func_call = std::make_unique<OperationLog::FunctionCall>();
|
auto func_call = std::make_unique<OperationLog::FunctionCall>();
|
||||||
func_call->function_name = func_name;
|
func_call->function_name = func_name;
|
||||||
func_call->call_result_type = res_type;
|
func_call->call_result_type = res_type;
|
||||||
|
|
||||||
OperationLog log;
|
|
||||||
log.line = line_number;
|
|
||||||
log.entry_type = OperationLog::FunctionCall::TYPE_NAME;
|
log.entry_type = OperationLog::FunctionCall::TYPE_NAME;
|
||||||
log.entry = std::move(func_call);
|
log.entry = std::move(func_call);
|
||||||
log.current_for_loops = _for_loop_stack;
|
|
||||||
log.is_fallthrough = _in_fallthrough;
|
|
||||||
|
|
||||||
_storage->pushOperation(file_name, std::move(log));
|
_storage->pushOperation(file_name, std::move(log));
|
||||||
|
|
||||||
|
llvm::outs() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void OperationFinder::processArraySubscript(const clang::ArraySubscriptExpr* subscript, const clang::SourceManager& source_manager)
|
||||||
|
{
|
||||||
|
auto [file_name, log] = _createBaseOperationLog(subscript, source_manager);
|
||||||
|
|
||||||
|
llvm::outs() << "\n\tSubscript:";
|
||||||
|
|
||||||
|
log.entry_type = OperationLog::BasicOperation::TYPE_NAME;
|
||||||
|
log.entry = _createBasicOperationLogEntry("subscript", subscript, subscript->getBase(), subscript->getIdx());
|
||||||
|
|
||||||
|
_storage->pushOperation(file_name, std::move(log));
|
||||||
|
|
||||||
|
llvm::outs() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void OperationFinder::fallthroughBranchEntered()
|
void OperationFinder::fallthroughBranchEntered()
|
||||||
@ -147,11 +138,13 @@ void OperationFinder::forLoopExited()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<OperationLog::BasicOperation>
|
std::unique_ptr<OperationLog::BasicOperation>
|
||||||
OperationFinder::_createBasicOperationLogEntry(const Expr* source, const Expr* op1, const Expr* op2)
|
OperationFinder::_createBasicOperationLogEntry(const std::string& opcode, const Expr* source, const Expr* op1, const Expr* op2)
|
||||||
{
|
{
|
||||||
auto log = std::make_unique<OperationLog::BasicOperation>();
|
auto log = std::make_unique<OperationLog::BasicOperation>();
|
||||||
|
|
||||||
llvm::outs() << "Expression types:\n\tExpression eval type: ";
|
log->operation_name = opcode;
|
||||||
|
|
||||||
|
llvm::outs() << "\n\tExpression eval type: ";
|
||||||
log->type_result = ResolveTypeName(source->getType());
|
log->type_result = ResolveTypeName(source->getType());
|
||||||
|
|
||||||
if (op1)
|
if (op1)
|
||||||
@ -167,3 +160,19 @@ std::unique_ptr<OperationLog::BasicOperation>
|
|||||||
|
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<std::string, OperationLog> OperationFinder::_createBaseOperationLog(const clang::Stmt* stmt, const clang::SourceManager& source_manager)
|
||||||
|
{
|
||||||
|
const auto [file_name, line_number, column_number] = resolveLocations(stmt, source_manager);
|
||||||
|
|
||||||
|
OperationLog log;
|
||||||
|
log.line = line_number;
|
||||||
|
log.current_for_loops = _for_loop_stack;
|
||||||
|
log.is_fallthrough = _in_fallthrough;
|
||||||
|
|
||||||
|
llvm::outs() << file_name << ":"
|
||||||
|
<< line_number << ":"
|
||||||
|
<< column_number << ":";
|
||||||
|
|
||||||
|
return { file_name, std::move(log) };
|
||||||
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ public:
|
|||||||
void processArithmetic(const clang::BinaryOperator* op, const clang::SourceManager& source_manager);
|
void processArithmetic(const clang::BinaryOperator* op, const clang::SourceManager& source_manager);
|
||||||
void processUnaryArithmetic(const clang::UnaryOperator* op, const clang::SourceManager& source_manager);
|
void processUnaryArithmetic(const clang::UnaryOperator* op, const clang::SourceManager& source_manager);
|
||||||
void processFunctionCall(const clang::CallExpr* call, const clang::SourceManager& source_manager);
|
void processFunctionCall(const clang::CallExpr* call, const clang::SourceManager& source_manager);
|
||||||
|
void processArraySubscript(const clang::ArraySubscriptExpr* subscript, const clang::SourceManager& source_manager);
|
||||||
|
|
||||||
void fallthroughBranchEntered();
|
void fallthroughBranchEntered();
|
||||||
void fallthroughBranchExited();
|
void fallthroughBranchExited();
|
||||||
@ -26,7 +27,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<OperationLog::BasicOperation>
|
std::unique_ptr<OperationLog::BasicOperation>
|
||||||
_createBasicOperationLogEntry(const clang::Expr* source, const clang::Expr* op1, const clang::Expr* op2);
|
_createBasicOperationLogEntry(const std::string& opcode, const clang::Expr* source, const clang::Expr* op1, const clang::Expr* op2);
|
||||||
|
|
||||||
|
std::pair<std::string, OperationLog> _createBaseOperationLog(const clang::Stmt* stmt, const clang::SourceManager& source_manager);
|
||||||
|
|
||||||
int _next_for_loop_id = 0;
|
int _next_for_loop_id = 0;
|
||||||
bool _in_fallthrough = false;
|
bool _in_fallthrough = false;
|
||||||
|
|||||||
@ -52,6 +52,15 @@ bool OperationFinderAstVisitor::VisitCallExpr(clang::CallExpr* call)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OperationFinderAstVisitor::VisitArraySubscriptExpr(clang::ArraySubscriptExpr* subscript)
|
||||||
|
{
|
||||||
|
assert(_context);
|
||||||
|
|
||||||
|
_op_finder->processArraySubscript(subscript, _context->getSourceManager());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool OperationFinderAstVisitor::dataTraverseStmtPre(clang::Stmt* stmt)
|
bool OperationFinderAstVisitor::dataTraverseStmtPre(clang::Stmt* stmt)
|
||||||
{
|
{
|
||||||
assert(_context);
|
assert(_context);
|
||||||
|
|||||||
@ -21,6 +21,7 @@ public:
|
|||||||
bool VisitBinaryOperator(clang::BinaryOperator* op);
|
bool VisitBinaryOperator(clang::BinaryOperator* op);
|
||||||
bool VisitUnaryOperator(clang::UnaryOperator* op);
|
bool VisitUnaryOperator(clang::UnaryOperator* op);
|
||||||
bool VisitCallExpr(clang::CallExpr* call);
|
bool VisitCallExpr(clang::CallExpr* call);
|
||||||
|
bool VisitArraySubscriptExpr(clang::ArraySubscriptExpr* subscript);
|
||||||
|
|
||||||
bool dataTraverseStmtPre(clang::Stmt* stmt);
|
bool dataTraverseStmtPre(clang::Stmt* stmt);
|
||||||
bool dataTraverseStmtPost(clang::Stmt* stmt);
|
bool dataTraverseStmtPost(clang::Stmt* stmt);
|
||||||
|
|||||||
@ -31,6 +31,7 @@ struct OperationLog
|
|||||||
{
|
{
|
||||||
static constexpr char TYPE_NAME[] = "basic_operation";
|
static constexpr char TYPE_NAME[] = "basic_operation";
|
||||||
|
|
||||||
|
std::string operation_name;
|
||||||
std::string type_lhs;
|
std::string type_lhs;
|
||||||
std::string type_rhs;
|
std::string type_rhs;
|
||||||
std::string type_result;
|
std::string type_result;
|
||||||
@ -84,6 +85,7 @@ inline void from_json(const nlohmann::json& j, OperationLog& l)
|
|||||||
inline void to_json(nlohmann::json& j, const OperationLog::BasicOperation& bo)
|
inline void to_json(nlohmann::json& j, const OperationLog::BasicOperation& bo)
|
||||||
{
|
{
|
||||||
j = nlohmann::json{
|
j = nlohmann::json{
|
||||||
|
{"operation_name", bo.operation_name},
|
||||||
{"type_lhs", bo.type_lhs},
|
{"type_lhs", bo.type_lhs},
|
||||||
{"type_rhs", bo.type_rhs},
|
{"type_rhs", bo.type_rhs},
|
||||||
{"type_result", bo.type_result}
|
{"type_result", bo.type_result}
|
||||||
@ -92,6 +94,7 @@ inline void to_json(nlohmann::json& j, const OperationLog::BasicOperation& bo)
|
|||||||
|
|
||||||
inline void from_json(const nlohmann::json& j, OperationLog::BasicOperation& bo)
|
inline void from_json(const nlohmann::json& j, OperationLog::BasicOperation& bo)
|
||||||
{
|
{
|
||||||
|
j.at("operation_name").get_to(bo.operation_name);
|
||||||
j.at("type_lhs").get_to(bo.type_lhs);
|
j.at("type_lhs").get_to(bo.type_lhs);
|
||||||
j.at("type_rhs").get_to(bo.type_rhs);
|
j.at("type_rhs").get_to(bo.type_rhs);
|
||||||
j.at("type_result").get_to(bo.type_result);
|
j.at("type_result").get_to(bo.type_result);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user