diff --git a/op-finder/ASTHelpers.hpp b/op-finder/ASTHelpers.hpp new file mode 100644 index 0000000..0f6ed9d --- /dev/null +++ b/op-finder/ASTHelpers.hpp @@ -0,0 +1,40 @@ +// +// Created by erki on 02.03.21. +// + +#ifndef C_ANALYZER_ASTHELPERS_HPP +#define C_ANALYZER_ASTHELPERS_HPP + +#include + +template +clang::StringRef getOpcode(const TOp *op) +{ + return op->getOpcodeStr(op->getOpcode()); +} + +inline clang::SourceLocation resolveOperationSourceLocation(const clang::SourceManager& source_manager, + const clang::SourceLocation& original) +{ + if (source_manager.isMacroBodyExpansion(original)) + { + return source_manager.getExpansionLoc(original); + } + + return original; +} + +template +std::tuple resolveLocations(const TOp* op, + const clang::SourceManager& source_manager) +{ + const auto& loc = resolveOperationSourceLocation(source_manager, op->getBeginLoc()); + + return { + source_manager.getFilename(loc).str(), + source_manager.getSpellingLineNumber(loc), + source_manager.getSpellingColumnNumber(loc) + }; +} + +#endif //C_ANALYZER_ASTHELPERS_HPP diff --git a/op-finder/CMakeLists.txt b/op-finder/CMakeLists.txt index b21bc24..f8cd363 100644 --- a/op-finder/CMakeLists.txt +++ b/op-finder/CMakeLists.txt @@ -21,6 +21,7 @@ add_executable(op-finder main.cpp OperationFinder.cpp OperationStorage.cpp + OperationAstMatcher.cpp ) target_include_directories(op-finder diff --git a/op-finder/OperationAstMatcher.cpp b/op-finder/OperationAstMatcher.cpp new file mode 100644 index 0000000..6f0de6b --- /dev/null +++ b/op-finder/OperationAstMatcher.cpp @@ -0,0 +1,57 @@ +// +// Created by erki on 02.03.21. +// + +#include "OperationAstMatcher.hpp" + +#include "OperationFinder.hpp" + +using namespace clang; +using namespace clang::ast_matchers; + +namespace +{ + +StatementMatcher AssignmentMatcher = + binaryOperation(isAssignmentOperator(), + hasLHS(expr().bind("lhs")), + hasRHS(expr().bind("rhs"))).bind("assignment"); + +StatementMatcher ArithmeticMatcher = + binaryOperation(hasAnyOperatorName("+", "-", "/", "*", "<", ">", + "<=", ">=", "==", "<<", ">>", "%"), + hasLHS(expr().bind("lhs")), + hasRHS(expr().bind("lhs"))).bind("arithmetic"); + +StatementMatcher UnaryArithmeticMatcher = + unaryOperator(hasAnyOperatorName("!", "++", "--"), + hasUnaryOperand(expr().bind("lhs"))).bind("unary_arithmetic"); + +} + +OperationASTMatcher::OperationASTMatcher(OperationFinder* finder) + : _op_finder(finder) +{ } + +void OperationASTMatcher::addToFinder(clang::ast_matchers::MatchFinder& finder) +{ + finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, ArithmeticMatcher), this); + finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, AssignmentMatcher), this); + finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, UnaryArithmeticMatcher), this); +} + +void OperationASTMatcher::run(const clang::ast_matchers::MatchFinder::MatchResult& result) +{ + if (const auto* op = result.Nodes.getNodeAs("assignment")) + { + _op_finder->processAssignment(op, *result.SourceManager); + } + else if (const auto* op = result.Nodes.getNodeAs("arithmetic")) + { + _op_finder->processArithmetic(op, *result.SourceManager); + } + else if (const auto* op = result.Nodes.getNodeAs("unary_arithmetic")) + { + _op_finder->processUnaryArithmetic(op, *result.SourceManager); + } +} diff --git a/op-finder/OperationAstMatcher.hpp b/op-finder/OperationAstMatcher.hpp new file mode 100644 index 0000000..fc00320 --- /dev/null +++ b/op-finder/OperationAstMatcher.hpp @@ -0,0 +1,25 @@ +// +// Created by erki on 02.03.21. +// + +#ifndef C_ANALYZER_OPERATIONASTMATCHER_HPP +#define C_ANALYZER_OPERATIONASTMATCHER_HPP + +#include + +class OperationFinder; + +class OperationASTMatcher : public clang::ast_matchers::MatchFinder::MatchCallback +{ +public: + explicit OperationASTMatcher(OperationFinder* finder); + + void addToFinder(clang::ast_matchers::MatchFinder& finder); + + void run(const clang::ast_matchers::MatchFinder::MatchResult& result) override; +private: + OperationFinder* _op_finder; +}; + + +#endif //C_ANALYZER_OPERATIONASTMATCHER_HPP diff --git a/op-finder/OperationFinder.cpp b/op-finder/OperationFinder.cpp index 8f1c739..6e62a61 100644 --- a/op-finder/OperationFinder.cpp +++ b/op-finder/OperationFinder.cpp @@ -6,99 +6,20 @@ #include +#include "ASTHelpers.hpp" + using namespace clang; using namespace clang::ast_matchers; -namespace -{ - -StatementMatcher AssignmentMatcher = - binaryOperation(isAssignmentOperator(), - hasLHS(expr().bind("lhs")), - hasRHS(expr().bind("rhs"))).bind("assignment"); - -StatementMatcher ArithmeticMatcher = - binaryOperation(hasAnyOperatorName("+", "-", "/", "*", "<", ">", - "<=", ">=", "==", "<<", ">>", "%"), - hasLHS(expr().bind("lhs")), - hasRHS(expr().bind("lhs"))).bind("arithmetic"); - -StatementMatcher UnaryArithmeticMatcher = - unaryOperator(hasAnyOperatorName("!", "++", "--"), - hasUnaryOperand(expr().bind("lhs"))).bind("unary_arithmetic"); - -StatementMatcher CompoundMatcher = - compoundStmt().bind("compound_stmt"); - -//StatementMatcher ForStatementMatcher = -// forStmt(hasInitStatement(expr().bind("init"))).bind("for_stmt"); - -template -StringRef getOpcode(const TOp *op) -{ - return op->getOpcodeStr(op->getOpcode()); -} - -SourceLocation ResolveOperationSourceLocation(const SourceManager& source_manager, const SourceLocation& original) -{ - if (source_manager.isMacroBodyExpansion(original)) - { - return source_manager.getExpansionLoc(original); - } - - return original; -} - -template -std::tuple resolveLocations(const TOp* op, const SourceManager& source_manager) -{ - const auto& loc = ResolveOperationSourceLocation(source_manager, op->getBeginLoc()); - - return { - source_manager.getFilename(loc).str(), - source_manager.getSpellingLineNumber(loc), - source_manager.getSpellingColumnNumber(loc) - }; -} - -} - OperationFinder::OperationFinder(IOperationOutput* storage) : _storage(storage) { assert(storage); } -void OperationFinder::addMatcher(MatchFinder &finder) +void OperationFinder::processAssignment(const clang::BinaryOperator* op, const clang::SourceManager& source_manager) { - finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, ArithmeticMatcher), this); - finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, AssignmentMatcher), this); - finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, UnaryArithmeticMatcher), this); -} - -void OperationFinder::run(const MatchFinder::MatchResult& result) -{ - if (result.Nodes.getNodeAs("assignment")) - { - _processAssignment(result); - } - else if (result.Nodes.getNodeAs("arithmetic")) - { - _processArithmetic(result); - } - else if (result.Nodes.getNodeAs("unary_arithmetic")) - { - _processUnaryArithmetic(result); - } -} - -void OperationFinder::_processAssignment(const clang::ast_matchers::MatchFinder::MatchResult& result) -{ - const BinaryOperator* op = result.Nodes.getNodeAs("assignment"); - - assert(op); - - const auto [file_name, line_number, column_number] = resolveLocations(op, *result.SourceManager); + const auto [file_name, line_number, column_number] = resolveLocations(op, source_manager); llvm::outs() << file_name << ":" << line_number << ":" @@ -116,13 +37,9 @@ void OperationFinder::_processAssignment(const clang::ast_matchers::MatchFinder: llvm::outs() << "\n"; } -void OperationFinder::_processArithmetic(const MatchFinder::MatchResult& result) +void OperationFinder::processArithmetic(const clang::BinaryOperator* op, const clang::SourceManager& source_manager) { - const BinaryOperator* op = result.Nodes.getNodeAs("arithmetic"); - - assert(op); - - const auto [file_name, line_number, column_number] = resolveLocations(op, *result.SourceManager); + const auto [file_name, line_number, column_number] = resolveLocations(op, source_manager); llvm::outs() << file_name << ":" << line_number << ":" @@ -140,15 +57,14 @@ void OperationFinder::_processArithmetic(const MatchFinder::MatchResult& result) llvm::outs() << "\n"; } -void OperationFinder::_processUnaryArithmetic(const MatchFinder::MatchResult &result) +void OperationFinder::processUnaryArithmetic(const clang::UnaryOperator* op, const clang::SourceManager& source_manager) { - const UnaryOperator* op = result.Nodes.getNodeAs("unary_arithmetic"); - const Expr* lhs = result.Nodes.getNodeAs("lhs"); + const Expr* lhs = op->getExprStmt(); assert(op); assert(lhs); - const auto [file_name, line_number, column_number] = resolveLocations(op, *result.SourceManager); + const auto [file_name, line_number, column_number] = resolveLocations(op, source_manager); llvm::outs() << file_name << ":" << line_number << ":" diff --git a/op-finder/OperationFinder.hpp b/op-finder/OperationFinder.hpp index 36a9188..c534e72 100644 --- a/op-finder/OperationFinder.hpp +++ b/op-finder/OperationFinder.hpp @@ -5,24 +5,20 @@ #ifndef LLVM_PROTO_OPERATIONFINDER_HPP #define LLVM_PROTO_OPERATIONFINDER_HPP -#include #include #include "OperationLog.hpp" -class OperationFinder : public clang::ast_matchers::MatchFinder::MatchCallback +class OperationFinder { public: explicit OperationFinder(IOperationOutput* storage); - void addMatcher(clang::ast_matchers::MatchFinder& finder); + 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); - void run(const clang::ast_matchers::MatchFinder::MatchResult& result) override; private: - void _processAssignment(const clang::ast_matchers::MatchFinder::MatchResult& result); - void _processArithmetic(const clang::ast_matchers::MatchFinder::MatchResult& result); - void _processUnaryArithmetic(const clang::ast_matchers::MatchFinder::MatchResult& result); - void _processExpressionTypes(OperationLog& log, const clang::Expr* source, const clang::Expr* op1, const clang::Expr* op2); IOperationOutput* _storage; diff --git a/op-finder/main.cpp b/op-finder/main.cpp index 7bb018d..be312f6 100644 --- a/op-finder/main.cpp +++ b/op-finder/main.cpp @@ -5,6 +5,7 @@ // Declares llvm::cl::extrahelp. #include "llvm/Support/CommandLine.h" +#include "OperationAstMatcher.hpp" #include "OperationFinder.hpp" #include "OperationStorage.hpp" @@ -49,9 +50,12 @@ int main(int argc, const char** argv) OperationStorage storage(OutputFile.getValue()); OperationFinder op_finder(&storage); - MatchFinder finder; + MatchFinder matcher; + OperationASTMatcher finder(&op_finder); - op_finder.addMatcher(finder); + finder.addToFinder(matcher); - return Tool.run(newFrontendActionFactory(&finder).get()); + //Tool.run(newFrontendActionFactory().get()); + + return Tool.run(newFrontendActionFactory(&matcher).get()); } \ No newline at end of file