1 #ifndef KILLED_LOCALS_H
2 #define KILLED_LOCALS_H
7 #include <clang/Basic/SourceManager.h>
8 #include <clang/AST/Decl.h>
9 #include <clang/AST/Expr.h>
10 #include <clang/AST/Stmt.h>
11 #include <clang/AST/RecursiveASTVisitor.h>
13 /* Structure for keeping track of local variables that can be killed
15 * In particular, variables of interest are first added to "locals"
16 * Then the Stmt in which the variable declaration appears is scanned
17 * for any possible leak of a pointer or any use after a specified scop.
18 * In such cases, the variable is removed from "locals".
19 * The scop is assumed to appear at the same level of the declaration.
20 * In particular, it does not appear inside a nested control structure,
21 * meaning that it is sufficient to look at uses of the variables
22 * that textually appear after the specified scop.
24 * locals is the set of variables of interest.
25 * accessed keeps track of the variables that are accessed inside the scop.
26 * scop_start is the start of the scop
27 * scop_end is the end of the scop
28 * addr_end is the end of the latest visited address_of expression.
29 * expr_end is the end of the latest handled expression.
31 struct pet_killed_locals
: clang::RecursiveASTVisitor
<pet_killed_locals
> {
32 clang::SourceManager
&SM
;
33 std::set
<clang::ValueDecl
*> locals
;
34 std::set
<clang::ValueDecl
*> accessed
;
40 pet_killed_locals(clang::SourceManager
&SM
) : SM(SM
) {}
42 void add_local(clang::Decl
*decl
);
43 void add_locals(clang::DeclStmt
*stmt
);
44 void set_addr_end(clang::UnaryOperator
*expr
);
45 bool check_decl_in_expr(clang::Expr
*expr
);
46 void remove_accessed_after(clang::Stmt
*stmt
,
47 unsigned start
, unsigned end
);
48 bool VisitUnaryOperator(clang::UnaryOperator
*expr
) {
49 if (expr
->getOpcode() == clang::UO_AddrOf
)
53 bool VisitArraySubscriptExpr(clang::ArraySubscriptExpr
*expr
) {
54 return check_decl_in_expr(expr
);
56 bool VisitDeclRefExpr(clang::DeclRefExpr
*expr
) {
57 return check_decl_in_expr(expr
);
60 std::set
<clang::ValueDecl
*>::iterator it
;
61 std::cerr
<< "local" << std::endl
;
62 for (it
= locals
.begin(); it
!= locals
.end(); ++it
)
64 std::cerr
<< "accessed" << std::endl
;
65 for (it
= accessed
.begin(); it
!= accessed
.end(); ++it
)