-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFuncAnalyzer.cpp
More file actions
148 lines (124 loc) · 4.42 KB
/
FuncAnalyzer.cpp
File metadata and controls
148 lines (124 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
* Simple LibTool that counts the number of functions in the source file
*/
#include "clang/Basic/SourceManager.h"
#include "clang/Driver/Options.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include<fstream>
using namespace std;
using namespace clang;
using namespace clang::driver;
using namespace clang::tooling;
using namespace llvm;
static llvm::cl::OptionCategory MyToolCategory("Function Analyzer options");
unsigned noOfLoops = 0;
unsigned noOfInstructions = 0;
/*
* The RecursiveASTVisitor: real magic happens here!
*/
class FuncAnalysisVisitor : public RecursiveASTVisitor<FuncAnalysisVisitor> {
private:
ASTContext *astContext;
public:
explicit FuncAnalysisVisitor(CompilerInstance *CI)
: astContext(&(CI->getASTContext())) {}
virtual bool VisitFunctionDecl(FunctionDecl *func) {
if(func->isThisDeclarationADefinition()==0)
{
return true;
}
string funcName = func->getQualifiedNameAsString();
llvm::outs() << "Function name: " << funcName << "\n";
int numP = func->getNumParams();
llvm::outs() << "Number of parameters: " << numP << "\n";
// llvm::outs() << "Definition: " << func->isThisDeclarationADefinition() << "\n";
llvm::outs() << "Number of Loops: " << noOfLoops << "\n";
llvm::outs() << "Number of Instruction: " << noOfInstructions << "\n";
llvm::outs() << "___________________________________________________" << "\n";
noOfLoops = 0;
noOfInstructions = 0;
/* const FunctionDecl* def = func->getDefinition();
Stmt* bods = func->getBody(def);
StmtVisitor *vis = new StmtVisitor(astContext);
CompoundStmt* bgs = (CompoundStmt*) bods->getStmtClass();
if(!bgs) llvm::outs() << "Yes" << "\n";
else llvm::outs() << "No, is" << "\n";
unsigned a = 0;
for(Stmt::const_child_iterator i = bods->child_begin(); i != bods->child_end(); i++)
{
vis->TraverseStmt(*i);
a++;
};
llvm::outs() << bods->getStmtClassName() << "\n";
llvm::outs() << "New ins" << a << "\n";
*/
return true;
}
virtual bool VisitStmt(Stmt *stmt) {
string instructionClass = stmt->getStmtClassName();
if(instructionClass == "ForStmt" || instructionClass == "DoStmt" || instructionClass =="WhileStmt")
{
noOfLoops++;
}
noOfInstructions++;
return true;
}
};
/*
* The ASTConsumer: essentially just a wrapper for the Visitors
*/
class FuncAnalysisASTConsumer : public ASTConsumer {
private:
FuncAnalysisVisitor *visitor;
public:
/* instantiate the visitor and pass the current context */
explicit FuncAnalysisASTConsumer(CompilerInstance *CI)
: visitor(new FuncAnalysisVisitor(CI)) { }
/* override call to HandleTranslationUnit() */
virtual void HandleTranslationUnit(ASTContext &Context) {
/* TranslationUnit represents the entire source file (and all expanded headers)
We can iterate through top-level decls and just select the ones that appear
in the main source file
*/
SourceManager& SM = Context.getSourceManager();
auto Decls = Context.getTranslationUnitDecl()->decls();
for (auto &Decl : Decls) {
const auto& FileID = SM.getFileID(Decl->getLocation());
if (FileID != SM.getMainFileID())
continue;
visitor->TraverseDecl(Decl);
}
}
};
/*
* The FrontEndAction class simply creates an AST Consumer
*
* What is the front-end action?
* consume (i.e., process) the AST
*/
class FuncAnalysisFrontendAction : public ASTFrontendAction {
public:
virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(clang::CompilerInstance &CI,
llvm::StringRef file) {
return std::unique_ptr<ASTConsumer>(new FuncAnalysisASTConsumer(&CI));
}
};
int main(int argc, const char **argv) {
// parse the command-line args passed to your code
CommonOptionsParser op(argc, argv, MyToolCategory);
// create a new LibTool instance
ClangTool Tool(op.getCompilations(), op.getSourcePathList());
// run the tool, creating a new FrontendAction
int result = Tool.run(newFrontendActionFactory<FuncAnalysisFrontendAction>().get());
return result;
}