AST Visitor based implementation of the operation finder

This commit is contained in:
Erki 2021-03-03 00:34:06 +02:00
parent aff90d5a9d
commit 16f4c85f6d
11 changed files with 191 additions and 23 deletions

View File

@ -22,6 +22,9 @@ add_executable(op-finder
OperationFinder.cpp
OperationStorage.cpp
OperationAstMatcher.cpp
OperationFinderAstVisitor.cpp
OperationFinderAstConsumer.cpp
OperationFinderAstAction.cpp
)
target_include_directories(op-finder

View File

@ -44,7 +44,7 @@ void OperationASTMatcher::run(const clang::ast_matchers::MatchFinder::MatchResul
{
if (const auto* op = result.Nodes.getNodeAs<clang::BinaryOperator>("assignment"))
{
_op_finder->processAssignment(op, *result.SourceManager);
_op_finder->processArithmetic(op, *result.SourceManager);
}
else if (const auto* op = result.Nodes.getNodeAs<clang::BinaryOperator>("arithmetic"))
{

View File

@ -17,26 +17,6 @@ OperationFinder::OperationFinder(IOperationOutput* storage)
assert(storage);
}
void OperationFinder::processAssignment(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 << ":"
<< "Assignment: Assigned to: ";
OperationLog log;
log.line = line_number;
log.operation = "=";
_processExpressionTypes(log, op, op->getLHS(), op->getRHS());
_storage->pushOperation(file_name, log);
llvm::outs() << "\n";
}
void OperationFinder::processArithmetic(const clang::BinaryOperator* op, const clang::SourceManager& source_manager)
{
const auto [file_name, line_number, column_number] = resolveLocations(op, source_manager);

View File

@ -14,7 +14,6 @@ class OperationFinder
public:
explicit OperationFinder(IOperationOutput* storage);
void processAssignment(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);

View File

@ -0,0 +1,17 @@
//
// Created by erki on 02.03.21.
//
#include "OperationFinderAstAction.hpp"
#include "OperationFinderAstConsumer.hpp"
OperationFinderAstAction::OperationFinderAstAction(OperationFinder* op_finder)
: _op_finder(op_finder)
{ }
std::unique_ptr<clang::ASTConsumer> OperationFinderAstAction::newASTConsumer()
{
return std::unique_ptr<clang::ASTConsumer>(
new OperationFinderAstConsumer(_op_finder));
}

View File

@ -0,0 +1,24 @@
//
// Created by erki on 02.03.21.
//
#ifndef C_ANALYZER_OPERATIONFINDERASTACTION_HPP
#define C_ANALYZER_OPERATIONFINDERASTACTION_HPP
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/FrontendActions.h>
class OperationFinder;
class OperationFinderAstAction
{
public:
explicit OperationFinderAstAction(OperationFinder* op_finder);
std::unique_ptr<clang::ASTConsumer> newASTConsumer();
private:
OperationFinder* _op_finder;
};
#endif //C_ANALYZER_OPERATIONFINDERASTACTION_HPP

View File

@ -0,0 +1,19 @@
//
// Created by erki on 02.03.21.
//
#include "OperationFinderAstConsumer.hpp"
OperationFinderAstConsumer::OperationFinderAstConsumer(OperationFinder* op_finder)
: _visitor(op_finder)
{ }
void OperationFinderAstConsumer::Initialize(clang::ASTContext& context)
{
_visitor.NewContext(&context);
}
void OperationFinderAstConsumer::HandleTranslationUnit(clang::ASTContext& context)
{
_visitor.TraverseAST(context);
}

View File

@ -0,0 +1,27 @@
//
// Created by erki on 02.03.21.
//
#ifndef C_ANALYZER_OPERATIONFINDERASTCONSUMER_HPP
#define C_ANALYZER_OPERATIONFINDERASTCONSUMER_HPP
#include <clang/AST/ASTConsumer.h>
#include "OperationFinderAstVisitor.hpp"
class OperationFinder;
class OperationFinderAstConsumer : public clang::ASTConsumer
{
public:
explicit OperationFinderAstConsumer(OperationFinder* op_finder);
void Initialize(clang::ASTContext& context) override;
void HandleTranslationUnit(clang::ASTContext& context) override;
private:
OperationFinderAstVisitor _visitor;
};
#endif //C_ANALYZER_OPERATIONFINDERASTCONSUMER_HPP

View File

@ -0,0 +1,59 @@
//
// Created by erki on 02.03.21.
//
#include "OperationFinderAstVisitor.hpp"
#include "OperationFinder.hpp"
OperationFinderAstVisitor::OperationFinderAstVisitor(OperationFinder* op_finder)
: _context(nullptr)
, _op_finder(op_finder)
{ }
void OperationFinderAstVisitor::NewContext(clang::ASTContext* context)
{
_context = context;
}
bool OperationFinderAstVisitor::VisitForStmt(clang::ForStmt* stmt)
{
assert(_context);
return true;
}
bool OperationFinderAstVisitor::VisitBinaryOperator(clang::BinaryOperator* op)
{
assert(_context);
if (!op->isCompoundAssignmentOp())
{
_op_finder->processArithmetic(op, _context->getSourceManager());
}
return true;
}
bool OperationFinderAstVisitor::VisitUnaryOperator(clang::UnaryOperator* op)
{
assert(_context);
_op_finder->processUnaryArithmetic(op, _context->getSourceManager());
return true;
}
bool OperationFinderAstVisitor::dataTraverseStmtPre(clang::Stmt* stmt)
{
assert(_context);
return true;
}
bool OperationFinderAstVisitor::dataTraverseStmtPost(clang::Stmt* stmt)
{
assert(_context);
return true;
}

View File

@ -0,0 +1,32 @@
//
// Created by erki on 02.03.21.
//
#ifndef C_ANALYZER_OPERATIONFINDERASTVISITOR_HPP
#define C_ANALYZER_OPERATIONFINDERASTVISITOR_HPP
#include <clang/AST/RecursiveASTVisitor.h>
class OperationFinder;
class OperationFinderAstVisitor
: public clang::RecursiveASTVisitor<OperationFinderAstVisitor>
{
public:
explicit OperationFinderAstVisitor(OperationFinder* op_finder);
void NewContext(clang::ASTContext* context);
bool VisitForStmt(clang::ForStmt* stmt);
bool VisitBinaryOperator(clang::BinaryOperator* op);
bool VisitUnaryOperator(clang::UnaryOperator* op);
bool dataTraverseStmtPre(clang::Stmt* stmt);
bool dataTraverseStmtPost(clang::Stmt* stmt);
private:
clang::ASTContext* _context;
OperationFinder* _op_finder;
};
#endif //C_ANALYZER_OPERATIONFINDERASTVISITOR_HPP

View File

@ -8,6 +8,7 @@
#include "OperationAstMatcher.hpp"
#include "OperationFinder.hpp"
#include "OperationStorage.hpp"
#include "OperationFinderAstAction.hpp"
using namespace clang::tooling;
using namespace clang::ast_matchers;
@ -50,6 +51,8 @@ int main(int argc, const char** argv)
OperationStorage storage(OutputFile.getValue());
OperationFinder op_finder(&storage);
#if 0
MatchFinder matcher;
OperationASTMatcher finder(&op_finder);
@ -57,5 +60,10 @@ int main(int argc, const char** argv)
//Tool.run(newFrontendActionFactory<DebuggeringASTAction>().get());
return Tool.run(newFrontendActionFactory(&matcher).get());
return Tool.run(newFrontendActionFactory(&finder).get());
#endif
OperationFinderAstAction action(&op_finder);
return Tool.run(newFrontendActionFactory(&action).get());
}