Compare commits
3 Commits
6f3dce5972
...
b609c48bfe
| Author | SHA1 | Date | |
|---|---|---|---|
| b609c48bfe | |||
| cff605642f | |||
| 375e3f9af6 |
66
.clang-format
Normal file
66
.clang-format
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# Generated from CLion C/C++ Code Style settings
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignOperands: true
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Always
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Always
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortLoopsOnASingleLine: true
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: Always
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
|
AfterUnion: true
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakInheritanceList: BeforeComma
|
||||||
|
ColumnLimit: 0
|
||||||
|
CompactNamespaces: false
|
||||||
|
ContinuationIndentWidth: 8
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentWidth: 2
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MaxEmptyLinesToKeep: 2
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PointerAlignment: Left
|
||||||
|
ReflowComments: false
|
||||||
|
SpaceAfterCStyleCast: true
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 0
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
TabWidth: 2
|
||||||
|
UseTab: Never
|
||||||
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
1
.idea/.name
generated
Normal file
1
.idea/.name
generated
Normal file
@ -0,0 +1 @@
|
|||||||
|
C Analyzer
|
||||||
2
.idea/analyzer.git.iml
generated
Normal file
2
.idea/analyzer.git.iml
generated
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||||
54
.idea/codeStyles/Project.xml
generated
Normal file
54
.idea/codeStyles/Project.xml
generated
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<Objective-C>
|
||||||
|
<option name="INDENT_NAMESPACE_MEMBERS" value="0" />
|
||||||
|
<option name="INDENT_C_STRUCT_MEMBERS" value="2" />
|
||||||
|
<option name="INDENT_CLASS_MEMBERS" value="2" />
|
||||||
|
<option name="INDENT_INSIDE_CODE_BLOCK" value="2" />
|
||||||
|
<option name="NAMESPACE_BRACE_PLACEMENT" value="2" />
|
||||||
|
<option name="FUNCTION_BRACE_PLACEMENT" value="2" />
|
||||||
|
<option name="BLOCK_BRACE_PLACEMENT" value="2" />
|
||||||
|
<option name="SUPERCLASS_LIST_COMMA_ON_NEXT_LINE" value="true" />
|
||||||
|
<option name="SPACE_WITHIN_EMPTY_BRACES" value="true" />
|
||||||
|
<option name="SPACE_BEFORE_POINTER_IN_DECLARATION" value="false" />
|
||||||
|
<option name="SPACE_AFTER_POINTER_IN_DECLARATION" value="true" />
|
||||||
|
<option name="SPACE_BEFORE_REFERENCE_IN_DECLARATION" value="false" />
|
||||||
|
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
||||||
|
</Objective-C>
|
||||||
|
<Objective-C-extensions>
|
||||||
|
<extensions>
|
||||||
|
<pair source="cpp" header="hpp" fileNamingConvention="PASCAL_CASE" />
|
||||||
|
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||||
|
<pair source="cu" header="cuh" fileNamingConvention="NONE" />
|
||||||
|
</extensions>
|
||||||
|
<rules>
|
||||||
|
<rule entity="NAMESPACE" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="MACRO" visibility="ANY" specifier="ANY" prefix="" style="SCREAMING_SNAKE_CASE" suffix="" />
|
||||||
|
<rule entity="CLASS" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="STRUCT" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="ENUM" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="UNION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="CLASS_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="STRUCT_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="CLASS_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
|
||||||
|
<rule entity="STRUCT_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
|
||||||
|
<rule entity="GLOBAL_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
|
||||||
|
<rule entity="PARAMETER" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
|
||||||
|
<rule entity="LOCAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
|
||||||
|
<rule entity="CLASS_MEMBER_FIELD,STRUCT_MEMBER_FIELD" visibility="PROTECTED,PRIVATE" specifier="ANY" prefix="_" style="SNAKE_CASE" suffix="" />
|
||||||
|
<rule entity="CLASS_MEMBER_FUNCTION,STRUCT_MEMBER_FUNCTION" visibility="PROTECTED,PRIVATE" specifier="ANY" prefix="_" style="PASCAL_CASE" suffix="" />
|
||||||
|
</rules>
|
||||||
|
</Objective-C-extensions>
|
||||||
|
<codeStyleSettings language="ObjectiveC">
|
||||||
|
<option name="BRACE_STYLE" value="2" />
|
||||||
|
<option name="CLASS_BRACE_STYLE" value="2" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
<option name="TAB_SIZE" value="2" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
||||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
||||||
4
.idea/misc.xml
generated
Normal file
4
.idea/misc.xml
generated
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/analyzer.git.iml" filepath="$PROJECT_DIR$/.idea/analyzer.git.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
25447
dependencies/nlohmann/json.hpp
vendored
Normal file
25447
dependencies/nlohmann/json.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -20,10 +20,13 @@ llvm_map_components_to_libnames(llvm_libs support option core)
|
|||||||
add_executable(op-finder
|
add_executable(op-finder
|
||||||
main.cpp
|
main.cpp
|
||||||
OperationFinder.cpp
|
OperationFinder.cpp
|
||||||
|
OperationStorage.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(op-finder
|
target_include_directories(op-finder
|
||||||
PRIVATE ${LLVM_INCLUDE_DIRS}
|
PRIVATE
|
||||||
|
${LLVM_INCLUDE_DIRS}
|
||||||
|
${PROJECT_SOURCE_DIR}/dependencies
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(op-finder
|
target_compile_definitions(op-finder
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
#include "OperationFinder.hpp"
|
#include "OperationFinder.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
using namespace clang::ast_matchers;
|
using namespace clang::ast_matchers;
|
||||||
@ -50,13 +49,28 @@ SourceLocation ResolveOperationSourceLocation(const SourceManager& source_manage
|
|||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename TOp>
|
||||||
|
std::tuple<std::string, unsigned int, unsigned int> 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(const std::string& output_dir)
|
||||||
|
: _storage(output_dir)
|
||||||
|
{ }
|
||||||
|
|
||||||
void OperationFinder::addMatcher(MatchFinder &finder)
|
void OperationFinder::addMatcher(MatchFinder &finder)
|
||||||
{
|
{
|
||||||
finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, ArithmeticMatcher), this);
|
finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, ArithmeticMatcher), this);
|
||||||
finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, AssignmentMatcher), this);
|
finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, AssignmentMatcher), this);
|
||||||
//finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, CompoundMatcher), this);
|
|
||||||
finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, UnaryArithmeticMatcher), this);
|
finder.addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, UnaryArithmeticMatcher), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,10 +84,6 @@ void OperationFinder::run(const MatchFinder::MatchResult &result)
|
|||||||
{
|
{
|
||||||
_processArithmetic(result);
|
_processArithmetic(result);
|
||||||
}
|
}
|
||||||
else if (result.Nodes.getNodeAs<clang::CompoundStmt>("compound_stmt"))
|
|
||||||
{
|
|
||||||
_processCompoundStmt(result);
|
|
||||||
}
|
|
||||||
else if (result.Nodes.getNodeAs<clang::UnaryOperator>("unary_arithmetic"))
|
else if (result.Nodes.getNodeAs<clang::UnaryOperator>("unary_arithmetic"))
|
||||||
{
|
{
|
||||||
_processUnaryArithmetic(result);
|
_processUnaryArithmetic(result);
|
||||||
@ -86,15 +96,20 @@ void OperationFinder::_processAssignment(const clang::ast_matchers::MatchFinder:
|
|||||||
|
|
||||||
assert(op);
|
assert(op);
|
||||||
|
|
||||||
const auto& source_manager = *result.SourceManager;
|
const auto [file_name, line_number, column_number] = resolveLocations(op, *result.SourceManager);
|
||||||
const auto& loc = ResolveOperationSourceLocation(source_manager, op->getBeginLoc());
|
|
||||||
|
|
||||||
llvm::outs() << source_manager.getFilename(loc) << ":"
|
llvm::outs() << file_name << ":"
|
||||||
<< source_manager.getSpellingLineNumber(loc) << ":"
|
<< line_number << ":"
|
||||||
<< source_manager.getSpellingColumnNumber(loc) << ":"
|
<< column_number << ":"
|
||||||
<< "Assignment: Assigned to: ";
|
<< "Assignment: Assigned to: ";
|
||||||
|
|
||||||
_processExpressionTypes(op, op->getLHS(), op->getRHS());
|
OperationStorage::Log log;
|
||||||
|
log.line = line_number;
|
||||||
|
log.operation = "=";
|
||||||
|
|
||||||
|
_processExpressionTypes(log, op, op->getLHS(), op->getRHS());
|
||||||
|
|
||||||
|
_storage.pushOperation(file_name, log);
|
||||||
|
|
||||||
llvm::outs() << "\n";
|
llvm::outs() << "\n";
|
||||||
}
|
}
|
||||||
@ -105,39 +120,20 @@ void OperationFinder::_processArithmetic(const MatchFinder::MatchResult& result)
|
|||||||
|
|
||||||
assert(op);
|
assert(op);
|
||||||
|
|
||||||
const auto& source_manager = *result.SourceManager;
|
const auto [file_name, line_number, column_number] = resolveLocations(op, *result.SourceManager);
|
||||||
const auto& loc = ResolveOperationSourceLocation(source_manager, op->getBeginLoc());
|
|
||||||
|
|
||||||
llvm::outs() << source_manager.getFilename(loc) << ":"
|
llvm::outs() << file_name << ":"
|
||||||
<< source_manager.getSpellingLineNumber(loc) << ":"
|
<< line_number << ":"
|
||||||
<< source_manager.getSpellingColumnNumber(loc) << ":"
|
<< column_number << ":"
|
||||||
<< "Arithmetic: Type: " << getOpcode(op) << " LHS: ";
|
<< "Binary arithmetic: Type: " << getOpcode(op) << " LHS: ";
|
||||||
|
|
||||||
_processExpressionTypes(op, op->getLHS(), op->getRHS());
|
OperationStorage::Log log;
|
||||||
|
log.line = line_number;
|
||||||
|
log.operation = getOpcode(op).str();
|
||||||
|
|
||||||
llvm::outs() << "\n";
|
_processExpressionTypes(log, op, op->getLHS(), op->getRHS());
|
||||||
}
|
|
||||||
|
|
||||||
void OperationFinder::_processCompoundStmt(const clang::ast_matchers::MatchFinder::MatchResult& result)
|
_storage.pushOperation(file_name, log);
|
||||||
{
|
|
||||||
const CompoundStmt* stmt = result.Nodes.getNodeAs<CompoundStmt>("compound_stmt");
|
|
||||||
|
|
||||||
assert(stmt);
|
|
||||||
|
|
||||||
const CompoundAssignOperator* op = dyn_cast<CompoundAssignOperator>(stmt->getStmtExprResult());
|
|
||||||
|
|
||||||
if (!op || !op->isCompoundAssignmentOp())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto& source_manager = *result.SourceManager;
|
|
||||||
const auto& loc = ResolveOperationSourceLocation(source_manager, 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";
|
llvm::outs() << "\n";
|
||||||
}
|
}
|
||||||
@ -150,22 +146,28 @@ void OperationFinder::_processUnaryArithmetic(const MatchFinder::MatchResult &re
|
|||||||
assert(op);
|
assert(op);
|
||||||
assert(lhs);
|
assert(lhs);
|
||||||
|
|
||||||
const auto& source_manager = *result.SourceManager;
|
const auto [file_name, line_number, column_number] = resolveLocations(op, *result.SourceManager);
|
||||||
const auto& loc = ResolveOperationSourceLocation(source_manager, op->getBeginLoc());
|
|
||||||
|
|
||||||
llvm::outs() << source_manager.getFilename(loc) << ":"
|
llvm::outs() << file_name << ":"
|
||||||
<< source_manager.getSpellingLineNumber(loc) << ":"
|
<< line_number << ":"
|
||||||
<< source_manager.getSpellingColumnNumber(loc) << ":"
|
<< column_number << ":"
|
||||||
<< "Unary arithmetic: Type: " << getOpcode(op) << " LHS: ";
|
<< "Unary arithmetic: Type: " << getOpcode(op) << " LHS: ";
|
||||||
|
|
||||||
_processExpressionTypes(op, lhs, nullptr);
|
OperationStorage::Log log;
|
||||||
|
log.line = line_number;
|
||||||
|
log.operation = getOpcode(op).str();
|
||||||
|
|
||||||
|
_processExpressionTypes(log, op, lhs, nullptr);
|
||||||
|
|
||||||
|
_storage.pushOperation(file_name, log);
|
||||||
|
|
||||||
llvm::outs() << "\n";
|
llvm::outs() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void OperationFinder::_processExpressionTypes(const Expr* source, const Expr* op1, const Expr* op2)
|
void OperationFinder::_processExpressionTypes(OperationStorage::Log& log, const Expr* source, const Expr* op1, const Expr* op2)
|
||||||
{
|
{
|
||||||
auto printTypeName = [](const QualType& t) -> void
|
|
||||||
|
auto printTypeName = [](const QualType& t) -> std::string
|
||||||
{
|
{
|
||||||
if (t->isTypedefNameType())
|
if (t->isTypedefNameType())
|
||||||
{
|
{
|
||||||
@ -174,28 +176,32 @@ void OperationFinder::_processExpressionTypes(const Expr* source, const Expr* op
|
|||||||
llvm::outs() << "Typedef type: " << t.getAsString()
|
llvm::outs() << "Typedef type: " << t.getAsString()
|
||||||
<< ", underlying: " << tdt->desugar().getAsString()
|
<< ", underlying: " << tdt->desugar().getAsString()
|
||||||
<< ".";
|
<< ".";
|
||||||
|
|
||||||
|
return tdt->desugar().getAsString();
|
||||||
}
|
}
|
||||||
else if (t->isBuiltinType())
|
else if (t->isBuiltinType())
|
||||||
{
|
{
|
||||||
llvm::outs() << "Builtin type: " << t.getAsString() << ".";
|
llvm::outs() << "Builtin type: " << t.getAsString() << ".";
|
||||||
|
return t.getAsString();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
llvm::outs() << "Other type: " << t.getAsString() << ".";
|
llvm::outs() << "Other type: " << t.getAsString() << ".";
|
||||||
|
return t.getAsString();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
llvm::outs() << "Expression types:\n\tExpression eval type: ";
|
llvm::outs() << "Expression types:\n\tExpression eval type: ";
|
||||||
printTypeName(source->getType());
|
log.operand_result = printTypeName(source->getType());
|
||||||
|
|
||||||
if (op1)
|
if (op1)
|
||||||
{
|
{
|
||||||
llvm::outs() << "\n\tLHS eval type: ";
|
llvm::outs() << "\n\tLHS eval type: ";
|
||||||
printTypeName(op1->getType());
|
log.operand_lhs = printTypeName(op1->getType());
|
||||||
}
|
}
|
||||||
if (op2)
|
if (op2)
|
||||||
{
|
{
|
||||||
llvm::outs() << "\n\tRHS eval type: ";
|
llvm::outs() << "\n\tRHS eval type: ";
|
||||||
printTypeName(op2->getType());
|
log.operand_rhs = printTypeName(op2->getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,19 +8,24 @@
|
|||||||
#include <clang/ASTMatchers/ASTMatchers.h>
|
#include <clang/ASTMatchers/ASTMatchers.h>
|
||||||
#include <clang/ASTMatchers/ASTMatchFinder.h>
|
#include <clang/ASTMatchers/ASTMatchFinder.h>
|
||||||
|
|
||||||
|
#include "OperationStorage.hpp"
|
||||||
|
|
||||||
class OperationFinder : public clang::ast_matchers::MatchFinder::MatchCallback
|
class OperationFinder : public clang::ast_matchers::MatchFinder::MatchCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
OperationFinder(const std::string& output_dir);
|
||||||
|
|
||||||
void addMatcher(clang::ast_matchers::MatchFinder& finder);
|
void addMatcher(clang::ast_matchers::MatchFinder& finder);
|
||||||
|
|
||||||
virtual void run(const clang::ast_matchers::MatchFinder::MatchResult& result) override;
|
void run(const clang::ast_matchers::MatchFinder::MatchResult& result) override;
|
||||||
private:
|
private:
|
||||||
void _processAssignment(const clang::ast_matchers::MatchFinder::MatchResult& result);
|
void _processAssignment(const clang::ast_matchers::MatchFinder::MatchResult& result);
|
||||||
void _processArithmetic(const clang::ast_matchers::MatchFinder::MatchResult& result);
|
void _processArithmetic(const clang::ast_matchers::MatchFinder::MatchResult& result);
|
||||||
void _processCompoundStmt(const clang::ast_matchers::MatchFinder::MatchResult& result);
|
|
||||||
void _processUnaryArithmetic(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);
|
void _processExpressionTypes(OperationStorage::Log& log, const clang::Expr* source, const clang::Expr* op1, const clang::Expr* op2);
|
||||||
|
|
||||||
|
OperationStorage _storage;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //LLVM_PROTO_OPERATIONFINDER_HPP
|
#endif //LLVM_PROTO_OPERATIONFINDER_HPP
|
||||||
|
|||||||
64
op-finder/OperationStorage.cpp
Normal file
64
op-finder/OperationStorage.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// Created by erki on 28.02.21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "OperationStorage.hpp"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include <llvm/Support/CommandLine.h>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
void to_json(nlohmann::json& j, const OperationStorage::Log& l)
|
||||||
|
{
|
||||||
|
j = nlohmann::json{
|
||||||
|
{"operation", l.operation},
|
||||||
|
{"line", l.line},
|
||||||
|
{"operand_lhs", l.operand_lhs},
|
||||||
|
{"operand_rhs", l.operand_rhs},
|
||||||
|
{"operand_result", l.operand_result}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void from_json(const nlohmann::json& j, OperationStorage::Log& l)
|
||||||
|
{
|
||||||
|
j.at("operation").get_to(l.operation);
|
||||||
|
j.at("line").get_to(l.line);
|
||||||
|
j.at("operand_lhs").get_to(l.operand_lhs);
|
||||||
|
j.at("operand_rhs").get_to(l.operand_rhs);
|
||||||
|
j.at("operand_result").get_to(l.operand_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
OperationStorage::OperationStorage(const std::string& output_filename)
|
||||||
|
: _output_filename(output_filename)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
OperationStorage::~OperationStorage()
|
||||||
|
{
|
||||||
|
_dumpToFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OperationStorage::pushOperation(const std::string& filename, const Log& op)
|
||||||
|
{
|
||||||
|
auto it = _operations.find(filename);
|
||||||
|
|
||||||
|
if (it == _operations.end())
|
||||||
|
it = _operations.insert({ filename, {} }).first;
|
||||||
|
|
||||||
|
it->second.push_back(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::unordered_map<std::string, std::vector<OperationStorage::Log>>& OperationStorage::getOperations() const
|
||||||
|
{
|
||||||
|
return _operations;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OperationStorage::_dumpToFile()
|
||||||
|
{
|
||||||
|
nlohmann::json json = _operations;
|
||||||
|
|
||||||
|
std::ofstream file(_output_filename);
|
||||||
|
|
||||||
|
file << json;
|
||||||
|
}
|
||||||
39
op-finder/OperationStorage.hpp
Normal file
39
op-finder/OperationStorage.hpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// Created by erki on 28.02.21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef C_ANALYZER_OPERATIONSTORAGE_HPP
|
||||||
|
#define C_ANALYZER_OPERATIONSTORAGE_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class OperationStorage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Log
|
||||||
|
{
|
||||||
|
std::string operation;
|
||||||
|
unsigned int line;
|
||||||
|
std::string operand_lhs;
|
||||||
|
std::string operand_rhs;
|
||||||
|
std::string operand_result;
|
||||||
|
};
|
||||||
|
|
||||||
|
OperationStorage() = delete;
|
||||||
|
OperationStorage(const OperationStorage&) = delete;
|
||||||
|
|
||||||
|
explicit OperationStorage(const std::string& output_filename);
|
||||||
|
~OperationStorage();
|
||||||
|
|
||||||
|
void pushOperation(const std::string& filename, const Log& op);
|
||||||
|
[[nodiscard]] const std::unordered_map<std::string, std::vector<Log>>& getOperations() const;
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::string, std::vector<Log>> _operations;
|
||||||
|
std::string _output_filename;
|
||||||
|
|
||||||
|
void _dumpToFile();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //C_ANALYZER_OPERATIONSTORAGE_HPP
|
||||||
@ -13,15 +13,20 @@ using namespace llvm;
|
|||||||
|
|
||||||
// Apply a custom category to all command-line options so that they are the
|
// Apply a custom category to all command-line options so that they are the
|
||||||
// only ones displayed.
|
// only ones displayed.
|
||||||
static llvm::cl::OptionCategory MyToolCategory("opcounter options");
|
static llvm::cl::OptionCategory MyToolCategory("op-finder options");
|
||||||
|
|
||||||
|
static llvm::cl::opt<std::string> OutputFile("o", cl::desc("File to output the JSON to."),
|
||||||
|
cl::cat(MyToolCategory));
|
||||||
|
|
||||||
// CommonOptionsParser declares HelpMessage with a description of the common
|
// CommonOptionsParser declares HelpMessage with a description of the common
|
||||||
// command-line options related to the compilation database and input files.
|
// command-line options related to the compilation database and input files.
|
||||||
// It's nice to have this help message in all tools.
|
// It's nice to have this help message in all tools.
|
||||||
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
|
static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
|
||||||
|
|
||||||
// A help message for this specific tool can be added afterwards.
|
// A help message for this specific tool can be added afterwards.
|
||||||
static cl::extrahelp MoreHelp("\nMore help text...\n");
|
static llvm::cl::extrahelp MoreHelp("\nThe program takes the input <source0> ... files, parses their\n"
|
||||||
|
"AST and outputs a singular file containing a list of all noteworthy operations\n"
|
||||||
|
"for later analysis.\n");
|
||||||
|
|
||||||
int main(int argc, const char** argv)
|
int main(int argc, const char** argv)
|
||||||
{
|
{
|
||||||
@ -37,7 +42,7 @@ int main(int argc, const char** argv)
|
|||||||
ClangTool Tool(OptionsParser.getCompilations(),
|
ClangTool Tool(OptionsParser.getCompilations(),
|
||||||
OptionsParser.getSourcePathList());
|
OptionsParser.getSourcePathList());
|
||||||
|
|
||||||
OperationFinder op_finder;
|
OperationFinder op_finder(OutputFile.getValue());
|
||||||
MatchFinder finder;
|
MatchFinder finder;
|
||||||
|
|
||||||
op_finder.addMatcher(finder);
|
op_finder.addMatcher(finder);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user