Compare commits
1 Commits
master
...
testing/re
| Author | SHA1 | Date | |
|---|---|---|---|
| 9bc37e23ae |
@ -20,6 +20,9 @@ llvm_map_components_to_libnames(llvm_libs support option core)
|
||||
add_executable(op-finder
|
||||
main.cpp
|
||||
OperationFinder.cpp
|
||||
OperationFinderConsumer.cpp
|
||||
OperationFinderAction.cpp
|
||||
OperationAnalyzer.cpp
|
||||
)
|
||||
|
||||
target_include_directories(op-finder
|
||||
|
||||
135
op-finder/OperationAnalyzer.cpp
Normal file
135
op-finder/OperationAnalyzer.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
//
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
23
op-finder/OperationAnalyzer.hpp
Normal file
23
op-finder/OperationAnalyzer.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by erki on 24.02.21.
|
||||
//
|
||||
|
||||
#ifndef C_ANALYZER_OPERATIONANALYZER_HPP
|
||||
#define C_ANALYZER_OPERATIONANALYZER_HPP
|
||||
|
||||
#include <clang/AST/AST.h>
|
||||
|
||||
class OperationAnalyzer
|
||||
{
|
||||
public:
|
||||
void processAssignment(const clang::BinaryOperator* op, const clang::SourceManager& source_manager);
|
||||
void processBinaryArithmetic(const clang::BinaryOperator* op, const clang::SourceManager& source_manager);
|
||||
void processCompoundAssignment(const clang::CompoundAssignOperator* op, const clang::SourceManager& source_manager);
|
||||
void processUnaryArithmetic(const clang::UnaryOperator* op, const clang::SourceManager& source_manager);
|
||||
|
||||
private:
|
||||
void _processExpressionTypes(const clang::Expr* source, const clang::Expr* lhs, const clang::Expr* rhs);
|
||||
};
|
||||
|
||||
|
||||
#endif //C_ANALYZER_OPERATIONANALYZER_HPP
|
||||
@ -78,21 +78,7 @@ void OperationFinder::_processAssignment(const clang::ast_matchers::MatchFinder:
|
||||
|
||||
assert(op);
|
||||
|
||||
if (!isInMainFile(result, op->getBeginLoc()))
|
||||
return;
|
||||
|
||||
const auto& loc = op->getBeginLoc();
|
||||
const auto& source_manager = *result.SourceManager;
|
||||
|
||||
|
||||
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";
|
||||
_operation_analyzer.processAssignment(op, *result.SourceManager);
|
||||
}
|
||||
|
||||
void OperationFinder::_processArithmetic(const MatchFinder::MatchResult& result)
|
||||
@ -101,20 +87,7 @@ void OperationFinder::_processArithmetic(const MatchFinder::MatchResult& result)
|
||||
|
||||
assert(op);
|
||||
|
||||
if (!isInMainFile(result, op->getBeginLoc()))
|
||||
return;
|
||||
|
||||
const auto& loc = op->getBeginLoc();
|
||||
const auto& source_manager = *result.SourceManager;
|
||||
|
||||
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";
|
||||
_operation_analyzer.processBinaryArithmetic(op, *result.SourceManager);
|
||||
}
|
||||
|
||||
void OperationFinder::_processCompoundStmt(const clang::ast_matchers::MatchFinder::MatchResult& result)
|
||||
@ -128,79 +101,14 @@ void OperationFinder::_processCompoundStmt(const clang::ast_matchers::MatchFinde
|
||||
if (!op || !op->isCompoundAssignmentOp())
|
||||
return;
|
||||
|
||||
if (!isInMainFile(result, op->getBeginLoc()))
|
||||
return;
|
||||
|
||||
const auto& loc = op->getBeginLoc();
|
||||
const auto& source_manager = *result.SourceManager;
|
||||
|
||||
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";
|
||||
_operation_analyzer.processCompoundAssignment(op, *result.SourceManager);
|
||||
}
|
||||
|
||||
void OperationFinder::_processUnaryArithmetic(const MatchFinder::MatchResult &result)
|
||||
{
|
||||
const UnaryOperator* op = result.Nodes.getNodeAs<UnaryOperator>("unary_arithmetic");
|
||||
const Expr* lhs = result.Nodes.getNodeAs<Expr>("lhs");
|
||||
|
||||
assert(op);
|
||||
assert(lhs);
|
||||
|
||||
if (!isInMainFile(result, lhs->getBeginLoc()))
|
||||
return;
|
||||
|
||||
const auto& loc = lhs->getBeginLoc();
|
||||
const auto& source_manager = *result.SourceManager;
|
||||
|
||||
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 OperationFinder::_processExpressionTypes(const Expr* source, const Expr* op1, const Expr* op2)
|
||||
{
|
||||
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 (op1)
|
||||
{
|
||||
llvm::outs() << "\n\tLHS eval type: ";
|
||||
printTypeName(op1->getType());
|
||||
}
|
||||
if (op2)
|
||||
{
|
||||
llvm::outs() << "\n\tRHS eval type: ";
|
||||
printTypeName(op2->getType());
|
||||
}
|
||||
_operation_analyzer.processUnaryArithmetic(op, *result.SourceManager);
|
||||
}
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
#include <clang/ASTMatchers/ASTMatchers.h>
|
||||
#include <clang/ASTMatchers/ASTMatchFinder.h>
|
||||
|
||||
#include "OperationAnalyzer.hpp"
|
||||
|
||||
class OperationFinder : public clang::ast_matchers::MatchFinder::MatchCallback
|
||||
{
|
||||
public:
|
||||
@ -20,7 +22,7 @@ private:
|
||||
void _processCompoundStmt(const clang::ast_matchers::MatchFinder::MatchResult& result);
|
||||
void _processUnaryArithmetic(const clang::ast_matchers::MatchFinder::MatchResult& result);
|
||||
|
||||
void _processExpressionTypes(const clang::Expr* source, const clang::Expr* op1, const clang::Expr* op2);
|
||||
OperationAnalyzer _operation_analyzer;
|
||||
};
|
||||
|
||||
#endif //LLVM_PROTO_OPERATIONFINDER_HPP
|
||||
|
||||
5
op-finder/OperationFinderAction.cpp
Normal file
5
op-finder/OperationFinderAction.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by erki on 24.02.21.
|
||||
//
|
||||
|
||||
#include "OperationFinderAction.hpp"
|
||||
23
op-finder/OperationFinderAction.hpp
Normal file
23
op-finder/OperationFinderAction.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by erki on 24.02.21.
|
||||
//
|
||||
|
||||
#ifndef C_ANALYZER_OPERATIONFINDERACTION_HPP
|
||||
#define C_ANALYZER_OPERATIONFINDERACTION_HPP
|
||||
|
||||
#include <clang/AST/RecursiveASTVisitor.h>
|
||||
|
||||
class OperationFinderAction
|
||||
: public clang::RecursiveASTVisitor<OperationFinderAction>
|
||||
{
|
||||
public:
|
||||
bool VisitBinaryOperation(clang::BinaryOperator* bo);
|
||||
bool VisitUnaryOperation(clang::UnaryOperator* uo);
|
||||
bool VisitCompoundStatement(clang::CompoundStmt* cmp);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //C_ANALYZER_OPERATIONFINDERACTION_HPP
|
||||
25
op-finder/OperationFinderConsumer.cpp
Normal file
25
op-finder/OperationFinderConsumer.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by erki on 24.02.21.
|
||||
//
|
||||
|
||||
#include "OperationFinderConsumer.hpp"
|
||||
|
||||
OperationFinderConsumer::OperationFinderConsumer()
|
||||
{
|
||||
_op_finder.addMatcher(_ast_finder);
|
||||
}
|
||||
|
||||
void OperationFinderConsumer::HandleTranslationUnit(clang::ASTContext& context)
|
||||
{
|
||||
//_ast_finder.matchAST(context);
|
||||
auto consumer = _ast_finder.newASTConsumer();
|
||||
|
||||
consumer->HandleTranslationUnit(context);
|
||||
}
|
||||
|
||||
std::unique_ptr<clang::ASTConsumer> OperationFinderAction::CreateASTConsumer(
|
||||
clang::CompilerInstance& compiler, llvm::StringRef in_file)
|
||||
{
|
||||
return std::unique_ptr<clang::ASTConsumer>(
|
||||
new OperationFinderConsumer());
|
||||
}
|
||||
32
op-finder/OperationFinderConsumer.hpp
Normal file
32
op-finder/OperationFinderConsumer.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by erki on 24.02.21.
|
||||
//
|
||||
|
||||
#ifndef C_ANALYZER_OPERATIONFINDERCONSUMER_HPP
|
||||
#define C_ANALYZER_OPERATIONFINDERCONSUMER_HPP
|
||||
|
||||
#include <clang/AST/ASTConsumer.h>
|
||||
#include <clang/Frontend/FrontendAction.h>
|
||||
|
||||
#include "OperationFinder.hpp"
|
||||
|
||||
class OperationFinderConsumer : public clang::ASTConsumer
|
||||
{
|
||||
public:
|
||||
OperationFinderConsumer();
|
||||
|
||||
void HandleTranslationUnit(clang::ASTContext& context) override;
|
||||
|
||||
private:
|
||||
OperationFinder _op_finder;
|
||||
clang::ast_matchers::MatchFinder _ast_finder;
|
||||
};
|
||||
|
||||
class OperationFinderAction : public clang::ASTFrontendAction
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
|
||||
clang::CompilerInstance& compiler, llvm::StringRef in_file) override;
|
||||
};
|
||||
|
||||
#endif //C_ANALYZER_OPERATIONFINDERCONSUMER_HPP
|
||||
62
op-finder/TestASTConsumer.hpp
Normal file
62
op-finder/TestASTConsumer.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// Created by erki on 24.02.21.
|
||||
//
|
||||
|
||||
#ifndef C_ANALYZER_TESTASTCONSUMER_HPP
|
||||
#define C_ANALYZER_TESTASTCONSUMER_HPP
|
||||
|
||||
#include <clang/Frontend/CompilerInstance.h>
|
||||
#include <clang/Frontend/FrontendActions.h>
|
||||
#include <clang/AST/RecursiveASTVisitor.h>
|
||||
|
||||
class DebuggeringASTVisitor
|
||||
: public clang::RecursiveASTVisitor<DebuggeringASTVisitor>
|
||||
{
|
||||
public:
|
||||
explicit DebuggeringASTVisitor(clang::ASTContext* context)
|
||||
: _context(context)
|
||||
{ }
|
||||
|
||||
bool VisitBinaryOperator(clang::BinaryOperator* bo)
|
||||
{
|
||||
llvm::outs() << "OKAY FUCK YOU\n";
|
||||
bo->dump();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
clang::ASTContext* _context;
|
||||
};
|
||||
|
||||
class DebuggeringASTConsumer : public clang::ASTConsumer
|
||||
{
|
||||
public:
|
||||
explicit DebuggeringASTConsumer(clang::ASTContext* context)
|
||||
: _visitor(context)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void HandleTranslationUnit(clang::ASTContext& context) override
|
||||
{
|
||||
_visitor.TraverseAST(context);
|
||||
}
|
||||
private:
|
||||
DebuggeringASTVisitor _visitor;
|
||||
};
|
||||
|
||||
class DebuggeringASTAction : public clang::ASTFrontendAction
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
|
||||
clang::CompilerInstance &Compiler, llvm::StringRef InFile) override
|
||||
{
|
||||
return std::unique_ptr<clang::ASTConsumer>(
|
||||
new DebuggeringASTConsumer(&Compiler.getASTContext()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //C_ANALYZER_TESTASTCONSUMER_HPP
|
||||
@ -6,6 +6,8 @@
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
#include "OperationFinder.hpp"
|
||||
#include "TestASTConsumer.hpp"
|
||||
#include "OperationFinderConsumer.hpp"
|
||||
|
||||
using namespace clang::tooling;
|
||||
using namespace clang::ast_matchers;
|
||||
@ -42,5 +44,9 @@ int main(int argc, const char** argv)
|
||||
|
||||
op_finder.addMatcher(finder);
|
||||
|
||||
return Tool.run(newFrontendActionFactory(&finder).get());
|
||||
// Tool.run(newFrontendActionFactory<clang::ASTPrintAction>().get());
|
||||
Tool.run(newFrontendActionFactory<DebuggeringASTAction>().get());
|
||||
Tool.run(newFrontendActionFactory<OperationFinderAction>().get());
|
||||
|
||||
// return Tool.run(newFrontendActionFactory(&finder).get());
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user