-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patheventHandler.h
101 lines (86 loc) · 4.26 KB
/
eventHandler.h
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
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "callGraphAnalysis.h"
#include <fstream>
using namespace clang;
using namespace clang::ast_matchers;
StatementMatcher BindThread=callExpr(callee(functionDecl(hasName("bbiTcbb_eventMediator_bindThread"))),hasAncestor(functionDecl().bind("ThreadCaller"))).bind("bThread");
StatementMatcher BindActivator=callExpr(callee(functionDecl(hasName("bbiTcbb_eventMediator_bindActivator"))),hasAncestor(functionDecl().bind("ActivatorCaller"))).bind("bActivator");
StatementMatcher JoinConfig=callExpr(callee(functionDecl(hasName("bbiTcbb_eventMediator_joinConfig"))),hasAncestor(functionDecl().bind("JoinCaller"))).bind("bJoinConfig");
StatementMatcher Trigger=callExpr(callee(functionDecl(hasName("bbiTcbb_eventMediator_trigger"))),hasAncestor(functionDecl().bind("TrigCaller"))).bind("bTrigger");
class EventRecorder : public MatchFinder::MatchCallback {
std::ofstream & EventFile;
CGReachability cgR;
public :
EventRecorder(std::ofstream & o, CallGraph *cg,std::vector<std::string> startFuncsEvents):EventFile(o),cgR(cg,startFuncsEvents){}
const clang::Expr* IgnoreOtherCastParenExpr(const clang::Expr *E)
{
if (const ImplicitCastExpr *P = dyn_cast<ImplicitCastExpr>(E))
return IgnoreOtherCastParenExpr(P->getSubExpr()->IgnoreImplicit()->IgnoreParenCasts());
else if (const CStyleCastExpr *P = dyn_cast<CStyleCastExpr>(E))
return IgnoreOtherCastParenExpr(P->getSubExpr()->IgnoreImplicit()->IgnoreParenCasts());
else if (const ParenExpr *P = dyn_cast<ParenExpr>(E))
return IgnoreOtherCastParenExpr(P->IgnoreParenCasts()->IgnoreImplicit());
else return E->IgnoreParenCasts()->IgnoreImplicit();
}
std::string getArgumentName(const clang::Expr * exp)
{
// Expr is a DeclRefExpr
if(const clang::DeclRefExpr *ref = clang::dyn_cast<clang::DeclRefExpr>(exp))
if(const clang::ValueDecl *vDecl=dyn_cast<clang::ValueDecl>(ref->getDecl()))
return vDecl->getNameAsString();
// Expr is a DeclRefExpr preceded by some unary operator
if(const clang::UnaryOperator *uop=dyn_cast<clang::UnaryOperator>(exp))
if(const clang::Expr *subexp=uop->getSubExpr()->IgnoreImplicit())
return getArgumentName(subexp);
if(const clang::StringLiteral *strExpr=clang::dyn_cast<clang::StringLiteral>(exp)){
std::string str=strExpr->getString().str();
return str.substr(17);
}
//exp->dump();
//llvm::errs()<<"Graph: blabla\n";
return "item_not_found";
}
void recordCallArguments(const CallExpr *call)
{
for(unsigned i=1;i<call->getNumArgs();i++){
const clang::Expr* exp=call->getArg(i)->IgnoreImplicit()->IgnoreParenCasts();
const clang::Expr* E=IgnoreOtherCastParenExpr(exp);
EventFile<<"\""<<getArgumentName(E)<<"\"";
if(i==call->getNumArgs()-1) EventFile<<")."; else EventFile<<",";
}
EventFile<<std::endl;
}
virtual void run(const MatchFinder::MatchResult &Result) {
if (const CallExpr *call= Result.Nodes.getNodeAs<clang::CallExpr>("bThread"))
//if(const FunctionDecl *caller= Result.Nodes.getNodeAs<clang::FunctionDecl>("ThreadCaller"))
{
// llvm::errs()<<"threadEvent\n";
EventFile<<"threadEvent(";
recordCallArguments(call);
}
if(const CallExpr *call= Result.Nodes.getNodeAs<clang::CallExpr>("bActivator"))
//if(const FunctionDecl *caller= Result.Nodes.getNodeAs<clang::FunctionDecl>("ActivatorCaller"))
{
//llvm::errs()<<"ActivatorEvent\n";
EventFile<<"activatorEvent(";
recordCallArguments(call);
}
if (const CallExpr *call= Result.Nodes.getNodeAs<clang::CallExpr>("bJoinConfig"))
// if(const FunctionDecl *caller= Result.Nodes.getNodeAs<clang::FunctionDecl>("JoinCaller"))
{
EventFile<<"joinConfigEvent(";
recordCallArguments(call);
}
if (const CallExpr *call= Result.Nodes.getNodeAs<clang::CallExpr>("bTrigger"))
if(const FunctionDecl *caller= Result.Nodes.getNodeAs<clang::FunctionDecl>("TrigCaller")) {
std::string callerName=caller->getNameInfo().getAsString();
std::string from=cgR.reachableFrom(callerName);
std::string sName;
if(from=="not_found") sName=callerName;
else sName=from;
EventFile<<"triggerEvent(\""<<sName<<"\",";
recordCallArguments(call);
}
}
};