Read/Write Accesses of global variables in a Function body...

Hi everybody,

I am trying to write a recursive AST visitor that detects all read/write accesses of global
variables within the body of a given function declaration.

My Questions are:

  1. How to detect read/write accesses (for a given function) in a simple way?
  2. How to detect if a variable is global?

Currently I am experimenting with the following code…is it going into the right direction?

I hope someone can help…?

Thanks in advance!!!
Peter

bool VisitFunctionDecl (clang::FunctionDecl* decl)
{
if (decl->isThisDeclarationADefinition() && decl->hasBody())
{

clang::Stmt *stmt = decl->getBody();

for (clang::Stmt::child_iterator I = stmt->child_begin(), E = stmt->child_end(); I!=E; ++I)
{
if (clang::Stmt *child = I)
{
if (child->getStmtClass()==clang::Stmt::BinaryOperatorClass)
{
clang::BinaryOperator
B = llvm::castclang::BinaryOperator(child);
if (B->isAssignmentOp())
{
clang::CompoundAssignOperator *assign_opterator = llvm::castclang::CompoundAssignOperator(B);

clang::Expr *lhs = assign_opterator->getLHS();
clang::Expr *rhs = assign_opterator->getRHS();

//So far so good

//For the left hand side I can probably do the following.

if(lhs->getStmtClass() == clang::Expr::DeclRefExprClass)
{
clang::DeclRefExpr *lExpr = llvm::castclang::DeclRefExpr(lhs);
clang::ValueDecl *lValue = lExpr->getDecl();

//How to find out if the lvalue is global ??

Hi everybody,

I am trying to write a recursive AST visitor that detects all read/write
accesses of global
variables within the body of a given function declaration.

My Questions are:

1) How to detect read/write accesses (for a given function) in a simple way?

If you're just looking for simple assignments, your example code is in
the right direction, although I would suggest having the AST visitor
look for assignment operators rather than doing that part yourself.
Things get a lot more complicated if there's a possibility something
takes the address of a global you're interested in (using the "&"
operator, etc.).

2) How to detect if a variable is global?

hasLinkage(), or maybe hasGlobalStorage()? Depends on what exactly
you mean by global.

-Eli

Thanks a lot Eli,… for your reply…

having the AST visitor look for assignment operators rather than doing that part yourself.
I did everything myself because I wanted to start from a given function…
How do I make sure that my visitor only visits the body of a given function? Do I
have to implement two different visitors, one that only implements ‘VisitFunctionDecl’ to
find the function in question and then once found, call the other visitor with the function body
to only visit the ‘DeclRefExpr’ expressions?

hasLinkage(), or maybe hasGlobalStorage()?
…hasLinkage is what I was looking for… :wink:

If you’re just looking for simple assignments,
I guess for the write access I do, but for the read access I need any occurrence within
the function body. Does that mean I have to implement a visitor method for any possible rvalue
expression, or is it maybe enough to only visit the ‘DeclRefExpr’ ?

Thanks a lot!!!
Peter

Thanks a lot Eli,... for your reply...

having the AST visitor look for assignment operators rather than doing that
part yourself.

I did everything myself because I wanted to start from a given function...
How do I make sure that my visitor only visits the body of a given function?
Do I
have to implement two different visitors, one that only implements
'VisitFunctionDecl' to
find the function in question and then once found, call the other visitor
with the function body
to only visit the 'DeclRefExpr' expressions?

From the docs for RecursiveASTVisitor, it looks like you can override

TraverseFunctionDecl to suppress recursion if necessary.

hasLinkage(), or maybe hasGlobalStorage()?

...hasLinkage is what I was looking for... :wink:

If you're just looking for simple assignments,

I guess for the write access I do, but for the read access I need any
occurrence within
the function body. Does that mean I have to implement a visitor method for
any possible rvalue
expression, or is it maybe enough to only visit the 'DeclRefExpr' ?

Any use of the variable will have an associated DeclRefExpr, so you
won't miss any references to the variable.

-Eli

Thanks Eli, you helped me a lot…!!!

One last question, is there any way to find that a
a DeclRefExpr only occurred on the left hand site?

I can overwrite ‘VisitBinaryOperator’ to see if it occurred

on the left hand site. But how do I know, that it doesn’t occur
on the right hand site?

‘VisitDeclRefExpr’ finds any occurrences…and it looks like ‘DeclRefExpr’ doesn’t tell
me on which site is…

Thanks a lot!!!
Peter

How about you just record all the DeclRefExprs you see on the
left-hand side of an assignment, and see if you find any others?

-Eli

and see if you find any others?
…but of course…I can subtract the list found by ‘VisitBinaryOperator’ from the
list found by ‘VisitDeclRefExpr’…

only left site → 0
only right site → 1
left and right site ->2

Thaaaaaaanks so much Eli!!!