From 16f4c85f6d6121f18c73424f5481f13c725e3d1a Mon Sep 17 00:00:00 2001 From: Erki Date: Wed, 3 Mar 2021 00:34:06 +0200 Subject: [PATCH] AST Visitor based implementation of the operation finder --- op-finder/CMakeLists.txt | 3 ++ op-finder/OperationAstMatcher.cpp | 2 +- op-finder/OperationFinder.cpp | 20 -------- op-finder/OperationFinder.hpp | 1 - op-finder/OperationFinderAstAction.cpp | 17 +++++++ op-finder/OperationFinderAstAction.hpp | 24 ++++++++++ op-finder/OperationFinderAstConsumer.cpp | 19 ++++++++ op-finder/OperationFinderAstConsumer.hpp | 27 +++++++++++ op-finder/OperationFinderAstVisitor.cpp | 59 ++++++++++++++++++++++++ op-finder/OperationFinderAstVisitor.hpp | 32 +++++++++++++ op-finder/main.cpp | 10 +++- 11 files changed, 191 insertions(+), 23 deletions(-) create mode 100644 op-finder/OperationFinderAstAction.cpp create mode 100644 op-finder/OperationFinderAstAction.hpp create mode 100644 op-finder/OperationFinderAstConsumer.cpp create mode 100644 op-finder/OperationFinderAstConsumer.hpp create mode 100644 op-finder/OperationFinderAstVisitor.cpp create mode 100644 op-finder/OperationFinderAstVisitor.hpp diff --git a/op-finder/CMakeLists.txt b/op-finder/CMakeLists.txt index f8cd363..9e2285e 100644 --- a/op-finder/CMakeLists.txt +++ b/op-finder/CMakeLists.txt @@ -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 diff --git a/op-finder/OperationAstMatcher.cpp b/op-finder/OperationAstMatcher.cpp index 6f0de6b..b3579e5 100644 --- a/op-finder/OperationAstMatcher.cpp +++ b/op-finder/OperationAstMatcher.cpp @@ -44,7 +44,7 @@ void OperationASTMatcher::run(const clang::ast_matchers::MatchFinder::MatchResul { if (const auto* op = result.Nodes.getNodeAs("assignment")) { - _op_finder->processAssignment(op, *result.SourceManager); + _op_finder->processArithmetic(op, *result.SourceManager); } else if (const auto* op = result.Nodes.getNodeAs("arithmetic")) { diff --git a/op-finder/OperationFinder.cpp b/op-finder/OperationFinder.cpp index 6e62a61..04fdab4 100644 --- a/op-finder/OperationFinder.cpp +++ b/op-finder/OperationFinder.cpp @@ -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); diff --git a/op-finder/OperationFinder.hpp b/op-finder/OperationFinder.hpp index c534e72..7e9f554 100644 --- a/op-finder/OperationFinder.hpp +++ b/op-finder/OperationFinder.hpp @@ -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); diff --git a/op-finder/OperationFinderAstAction.cpp b/op-finder/OperationFinderAstAction.cpp new file mode 100644 index 0000000..e268931 --- /dev/null +++ b/op-finder/OperationFinderAstAction.cpp @@ -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 OperationFinderAstAction::newASTConsumer() +{ + return std::unique_ptr( + new OperationFinderAstConsumer(_op_finder)); +} diff --git a/op-finder/OperationFinderAstAction.hpp b/op-finder/OperationFinderAstAction.hpp new file mode 100644 index 0000000..133c181 --- /dev/null +++ b/op-finder/OperationFinderAstAction.hpp @@ -0,0 +1,24 @@ +// +// Created by erki on 02.03.21. +// + +#ifndef C_ANALYZER_OPERATIONFINDERASTACTION_HPP +#define C_ANALYZER_OPERATIONFINDERASTACTION_HPP + +#include +#include + +class OperationFinder; + +class OperationFinderAstAction +{ +public: + explicit OperationFinderAstAction(OperationFinder* op_finder); + + std::unique_ptr newASTConsumer(); +private: + OperationFinder* _op_finder; +}; + + +#endif //C_ANALYZER_OPERATIONFINDERASTACTION_HPP diff --git a/op-finder/OperationFinderAstConsumer.cpp b/op-finder/OperationFinderAstConsumer.cpp new file mode 100644 index 0000000..8fbe92c --- /dev/null +++ b/op-finder/OperationFinderAstConsumer.cpp @@ -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); +} diff --git a/op-finder/OperationFinderAstConsumer.hpp b/op-finder/OperationFinderAstConsumer.hpp new file mode 100644 index 0000000..9152945 --- /dev/null +++ b/op-finder/OperationFinderAstConsumer.hpp @@ -0,0 +1,27 @@ +// +// Created by erki on 02.03.21. +// + +#ifndef C_ANALYZER_OPERATIONFINDERASTCONSUMER_HPP +#define C_ANALYZER_OPERATIONFINDERASTCONSUMER_HPP + +#include + +#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 diff --git a/op-finder/OperationFinderAstVisitor.cpp b/op-finder/OperationFinderAstVisitor.cpp new file mode 100644 index 0000000..7c6ed96 --- /dev/null +++ b/op-finder/OperationFinderAstVisitor.cpp @@ -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; +} diff --git a/op-finder/OperationFinderAstVisitor.hpp b/op-finder/OperationFinderAstVisitor.hpp new file mode 100644 index 0000000..cf57477 --- /dev/null +++ b/op-finder/OperationFinderAstVisitor.hpp @@ -0,0 +1,32 @@ +// +// Created by erki on 02.03.21. +// + +#ifndef C_ANALYZER_OPERATIONFINDERASTVISITOR_HPP +#define C_ANALYZER_OPERATIONFINDERASTVISITOR_HPP + +#include + +class OperationFinder; + +class OperationFinderAstVisitor +: public clang::RecursiveASTVisitor +{ +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 diff --git a/op-finder/main.cpp b/op-finder/main.cpp index be312f6..1a58772 100644 --- a/op-finder/main.cpp +++ b/op-finder/main.cpp @@ -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().get()); - return Tool.run(newFrontendActionFactory(&matcher).get()); + return Tool.run(newFrontendActionFactory(&finder).get()); +#endif + + OperationFinderAstAction action(&op_finder); + + return Tool.run(newFrontendActionFactory(&action).get()); } \ No newline at end of file