masters-thesis/op-finder/OperationFinder.cpp

106 lines
2.7 KiB
C++

//
// Created by erki on 16.02.21.
//
#include "OperationFinder.hpp"
#include <iostream>
#include "ASTHelpers.hpp"
using namespace clang;
using namespace clang::ast_matchers;
OperationFinder::OperationFinder(IOperationOutput* storage)
: _storage(storage)
{
assert(storage);
}
void OperationFinder::processArithmetic(const clang::BinaryOperator* op, const clang::SourceManager& source_manager)
{
const auto [file_name, line_number, column_number] = resolveLocations(op, source_manager);
llvm::outs() << file_name << ":"
<< line_number << ":"
<< column_number << ":"
<< "Binary arithmetic: Type: " << getOpcode(op) << " LHS: ";
OperationLog log;
log.line = line_number;
log.operation = getOpcode(op).str();
_processExpressionTypes(log, op, op->getLHS(), op->getRHS());
_storage->pushOperation(file_name, log);
llvm::outs() << "\n";
}
void OperationFinder::processUnaryArithmetic(const clang::UnaryOperator* op, const clang::SourceManager& source_manager)
{
const Expr* lhs = op->getExprStmt();
assert(op);
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.operation = getOpcode(op).str();
_processExpressionTypes(log, op, lhs, nullptr);
_storage->pushOperation(file_name, log);
llvm::outs() << "\n";
}
void OperationFinder::_processExpressionTypes(OperationLog& log, const Expr* source, const Expr* op1, const Expr* op2)
{
auto printTypeName = [](const QualType& t) -> std::string
{
if (t->isTypedefNameType())
{
const TypedefType* tdt = cast<TypedefType>(t);
assert(tdt);
llvm::outs() << "Typedef type: " << t.getAsString()
<< ", underlying: " << tdt->desugar().getAsString()
<< ".";
return tdt->desugar().getAsString();
}
else if (t->isBuiltinType())
{
llvm::outs() << "Builtin type: " << t.getAsString() << ".";
return t.getAsString();
}
else
{
llvm::outs() << "Other type: " << t.getAsString() << ".";
return t.getAsString();
}
};
llvm::outs() << "Expression types:\n\tExpression eval type: ";
log.operand_result = printTypeName(source->getType());
if (op1)
{
llvm::outs() << "\n\tLHS eval type: ";
log.operand_lhs = printTypeName(op1->getType());
}
if (op2)
{
llvm::outs() << "\n\tRHS eval type: ";
log.operand_rhs = printTypeName(op2->getType());
}
}