136 lines
3.6 KiB
C++
136 lines
3.6 KiB
C++
//
|
|
// Created by erki on 24.02.21.
|
|
//
|
|
|
|
#include "OperationAnalyzer.hpp"
|
|
|
|
#include <clang/Basic/SourceManager.h>
|
|
|
|
using namespace clang;
|
|
|
|
namespace
|
|
{
|
|
|
|
bool IsInMainFile(const SourceManager& source_manager, const SourceLocation& loc)
|
|
{
|
|
//return source_manager.isWrittenInMainFile(loc);
|
|
return true;
|
|
}
|
|
|
|
template<typename TOp>
|
|
StringRef getOpcode(const TOp *op)
|
|
{
|
|
return op->getOpcodeStr(op->getOpcode());
|
|
}
|
|
|
|
}
|
|
|
|
void OperationAnalyzer::processAssignment(const BinaryOperator* op, const SourceManager& source_manager)
|
|
{
|
|
if (!IsInMainFile(source_manager, op->getBeginLoc()))
|
|
return;
|
|
|
|
const auto& loc = op->getBeginLoc();
|
|
|
|
|
|
llvm::outs() << source_manager.getFilename(loc) << ":"
|
|
<< source_manager.getSpellingLineNumber(loc) << ":"
|
|
<< source_manager.getSpellingColumnNumber(loc) << ":"
|
|
<< "Assignment: Assigned to: ";
|
|
|
|
_processExpressionTypes(op, op->getLHS(), op->getRHS());
|
|
|
|
llvm::outs() << "\n";
|
|
}
|
|
|
|
void OperationAnalyzer::processBinaryArithmetic(const BinaryOperator* op, const SourceManager& source_manager)
|
|
{
|
|
if (!IsInMainFile(source_manager, op->getBeginLoc()))
|
|
return;
|
|
|
|
const auto& loc = op->getBeginLoc();
|
|
|
|
llvm::outs() << source_manager.getFilename(loc) << ":"
|
|
<< source_manager.getSpellingLineNumber(loc) << ":"
|
|
<< source_manager.getSpellingColumnNumber(loc) << ":"
|
|
<< "Arithmetic: Type: " << getOpcode(op) << " LHS: ";
|
|
|
|
_processExpressionTypes(op, op->getLHS(), op->getRHS());
|
|
|
|
llvm::outs() << "\n";
|
|
}
|
|
|
|
void OperationAnalyzer::processCompoundAssignment(const clang::CompoundAssignOperator* op, const SourceManager& source_manager)
|
|
{
|
|
if (!IsInMainFile(source_manager, op->getBeginLoc()))
|
|
return;
|
|
|
|
const auto& loc = op->getBeginLoc();
|
|
|
|
llvm::outs() << source_manager.getFilename(loc) << ":"
|
|
<< source_manager.getSpellingLineNumber(loc) << ":"
|
|
<< source_manager.getSpellingColumnNumber(loc) << ":"
|
|
<< "Compound assignment: Op code: " << getOpcode(op) << " ";
|
|
|
|
_processExpressionTypes(op, op->getLHS(), op->getRHS());
|
|
|
|
llvm::outs() << "\n";
|
|
}
|
|
|
|
void OperationAnalyzer::processUnaryArithmetic(const UnaryOperator* op, const SourceManager& source_manager)
|
|
{
|
|
const Expr* lhs = op->getExprStmt();
|
|
|
|
if (!IsInMainFile(source_manager, lhs->getBeginLoc()))
|
|
return;
|
|
|
|
const auto& loc = lhs->getBeginLoc();
|
|
|
|
llvm::outs() << source_manager.getFilename(loc) << ":"
|
|
<< source_manager.getSpellingLineNumber(loc) << ":"
|
|
<< source_manager.getSpellingColumnNumber(loc) << ":"
|
|
<< "Unary arithmetic: Type: " << getOpcode(op) << " LHS: ";
|
|
|
|
_processExpressionTypes(op, lhs, nullptr);
|
|
|
|
llvm::outs() << "\n";
|
|
}
|
|
|
|
void OperationAnalyzer::_processExpressionTypes(const Expr* source, const Expr* lhs,
|
|
const Expr* rhs)
|
|
{
|
|
auto printTypeName = [](const QualType& t) -> void
|
|
{
|
|
if (t->isTypedefNameType())
|
|
{
|
|
const TypedefType* tdt = cast<TypedefType>(t);
|
|
assert(tdt);
|
|
llvm::outs() << "Typedef type: " << t.getAsString()
|
|
<< ", underlying: " << tdt->desugar().getAsString()
|
|
<< ".";
|
|
}
|
|
else if (t->isBuiltinType())
|
|
{
|
|
llvm::outs() << "Builtin type: " << t.getAsString() << ".";
|
|
}
|
|
else
|
|
{
|
|
llvm::outs() << "Other type: " << t.getAsString() << ".";
|
|
}
|
|
};
|
|
|
|
llvm::outs() << "Expression types:\n\tExpression eval type: ";
|
|
printTypeName(source->getType());
|
|
|
|
if (lhs)
|
|
{
|
|
llvm::outs() << "\n\tLHS eval type: ";
|
|
printTypeName(lhs->getType());
|
|
}
|
|
if (rhs)
|
|
{
|
|
llvm::outs() << "\n\tRHS eval type: ";
|
|
printTypeName(rhs->getType());
|
|
}
|
|
}
|