[cfe-dev] Traverse AST
Richard Smith via cfe-dev
cfe-dev at lists.llvm.org
Wed Feb 17 14:15:49 PST 2016
On Wed, Feb 17, 2016 at 10:00 AM, Kai Wang via cfe-dev
<cfe-dev at lists.llvm.org> wrote:
> Hi all,
>
> I'm using clang AST to do some static analysis.
> In my case, I want to find all assignment statements for pointer variables.
> For example, here is the source code snippet:
> int *a, int **b;
> **b = *a;
> I want to know there is an assignment from "*a" to "**b".
>
> I use RecursiveASTVistor to traverse AST. I rewrite VistitStmt() to check if
> AST Node is an assignment statement.
>
> bool VisitStmt(Stmt *s) {
>
> if(BinaryOperator *binaryOperator = dyn_cast<BinaryOperator>(s)) {
>
> if(binaryOperator->isAssignmentOp()) { do something}
>
> }
>
> Here is the AST for the source code snippet above:
>
> BinaryOperator 0x9532d48 <line:66:2, col:14> 'int' '='
>
> | |-UnaryOperator 0x9532cb0 <col:2, col:4> 'int' lvalue prefix '*'
>
> | | `-ImplicitCastExpr 0x9532c98 <col:3, col:4> 'int *' <LValueToRValue>
>
> | | `-UnaryOperator 0x9532c78 <col:3, col:4> 'int *' lvalue prefix '*'
>
> | | `-ImplicitCastExpr 0x9532c60 <col:4> 'int **' <LValueToRValue>
>
> | | `-DeclRefExpr 0x9532c38 <col:4> 'int **' lvalue Var 0x9532b00
> 'b' 'int **'
>
> | `-ImplicitCastExpr 0x9532d30 <col:13, col:14> 'int' <LValueToRValue>
>
> | `-UnaryOperator 0x9532d10 <col:13, col:14> 'int' lvalue prefix '*'
>
> | `-ImplicitCastExpr 0x9532cf8 <col:14> 'int *' <LValueToRValue>
>
> | `-DeclRefExpr 0x9532cd0 <col:14> 'int *' lvalue Var 0x9532a88
> 'a' 'int *'
>
>
> In VisitStmt() function, at the point when this BinaryOperator is visited, I
> only have the information of the current AST Node.
> How can I traverse the subtree of this BinaryOperator so that I can get all
> the info, such as variable name a, b, prefix * ,** ?
You can call BinaryOperator::getLHS() and BinaryOperator::getRHS() and
use the results to manually visit the left- and right-hand sides of
the operator. However, for your use case the ASTMatchers interface may
be a better approach -- see the documentation here:
http://clang.llvm.org/docs/LibASTMatchers.html
You could use a matcher like this:
auto hasPointerType = ...; // not sure exactly what you want here
binaryOperator(hasOperatorName("="), hasLHS(hasPointerType),
hasRHS(hasPointerType))
More information about the cfe-dev
mailing list