<div dir="ltr"><div>Adding back the mailing list.  Please reply all to keep the discussion on the mailing list.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Aug 1, 2019 at 2:47 PM Ayush Mittal <<a href="mailto:bellavistaghome@gmail.com" target="_blank">bellavistaghome@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Thanks Richard for the explanation. Really appreciate it. <div>One quick question, Within VisitStmt (BinaryOperator) how could I get an access to DeclRefExpr class.</div></div></blockquote><div><br></div><div>You should be defining a VisitBinaryOperator(BinaryOperator*) function.  VisitStmt(BinaryOperator) won't be called because the base visitor class doesn't know about it.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><br></div><div>For example,</div><div><b>-IfStmt</b> 0x88b5698 <line:13:3, line:16:12><br>    | |-<<<NULL>>><br>    | |-<<<NULL>>><br>    | |-BinaryOperator 0x88b54a0 <line:13:7, col:13> 'int' '=='<br>    | | |-ImplicitCastExpr 0x88b5420 <col:7> 'int' <LValueToRValue><br>    | | | `-<b>DeclRefExpr</b> 0x88b5358 <col:7> 'int' lvalue ParmVar 0x88604b0 'argc' 'int'<br></div><div><br></div></div></blockquote><div>BinaryOperator has two methods, getLHS() and getRHS() which get the left-hand side and right-hand side expressions.  Given your BinaryOperator, getLHS() will return the ImplicitCastExpr.  The Expr class has several methods to remove nodes in the AST.  Expr::IgnoreImpCasts() is probably what you want here*.   Then you need to check the final Expr if it is DeclRefExpr and use that.</div><div><br></div><div>BinaryOperator *BO = ...;</div><div>Expr *E = BO->getLHS();</div><div>E = E->IgnoreImpCasts();</div><div>if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {</div><div>  // Do your stuff here.</div><div>}</div><div><br></div><div>or just:</div><div><br></div><div><div>BinaryOperator *BO = ...;<br></div><div>if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getLHS()->IgnoreImpCasts())) {<br></div><div>  // Do your stuff here.</div><div>}</div></div><div><br></div><div>* There's several Expr::Ignore* functions that recursively strips aways different AST nodes from Expr's.  In your examples, IgnoreImpCasts will strip away the LValue to RValue cast, but if there was something like integral cast between different int types, that would stripped away too.  If you need more fine-grained control, you'll need to do the AST traversal yourself.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div></div><div><br></div><div>Thanks and Regards.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jul 30, 2019 at 9:11 PM Richard Trieu <<a href="mailto:rtrieu@google.com" target="_blank">rtrieu@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hi Ayush,</div><div><br></div><div>First, you need to know the classes associated with each of your target AST nodes.  These are IfStmt, WhileStmt, ForStmt, BinaryOperator, and UnaryOperator.  Each of these are sub-classes of Stmt.  IfStmt, WhileStmt, ForStmt and direct sub-classes while BinaryOperator and UnaryOperator are sub-classes of Expr, which is a sub-class of ValueStmt, which is a sub-class of Stmt.  There's also two other related classes, CXXForRangeStmt and DoStmt, which represent ranged-based for-loops and do/while loops.</div><div><br></div><div>Second, pointers can be changed between classes with the cast and dyn_cast functions and Stmt::getStmtClass() will tell the type of the Stmt.  They are used as follows:</div><div><br></div><div>void VisitStmt(Stmt *S) {</div><div>  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) {</div><div>    // Process BinaryOperator here</div><div>  } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(S)) {</div><div>    ...</div><div>  } // other checks here</div><div>}</div><div><br></div><div>void VisitStmt(Stmt *S) {<br></div><div>  switch (S->getStmtClass()) {</div><div>  case Stmt::BinaryOperatorClass: {</div><div>    BinaryOperator *BO = cast<BinaryOperator>(S);</div><div>    // Process BinaryOperator here</div><div>  }</div><div>  case Stmt::UnaryOperatorClass: {</div><div>    UnaryOperator *UO = cast<UnaryOperator>(S);</div><div>  }</div><div>  // Other cases here</div><div>  }</div><div>}</div><div><br></div><div>The difference between cast and dyn_cast is that cast expects the pointer is the correct type without checking while dyn_cast does check the target type and returns a null pointer on a type mismatch.  Chains of dyn_cast's are used if the list of nodes is short while using a switch on Stmt::getStmtClass() is used when checking a lot of node types.</div><div><br></div><div>There's also a third way.  Since you are already using a visitor, the visitor will have a visit function for each AST node.  Instead of writing just VisitStmt, you will write a VisitBinaryOperator(BinaryOperator *), VisitUnaryOperator(UnaryOperator *), and so on for each one you're interested in.  Hope this is enough to get you started.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jul 30, 2019 at 4:25 PM Ayush Mittal via cfe-users <<a href="mailto:cfe-users@lists.llvm.org" target="_blank">cfe-users@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hello Clangers,<div><br></div><div>I'm new to clang. I'm writing an AST Consumer plug-in to visit the statements node and record the data in one of my table with line numbers. I've this function callback ready: <b>VisitStmt(Stmt *S)</b>. My question is how could I traverse If, while, for loop, boolean and Unary Operators- inside this function.</div><div><br></div><div>Thanks and Regards.<br></div></div>
_______________________________________________<br>
cfe-users mailing list<br>
<a href="mailto:cfe-users@lists.llvm.org" target="_blank">cfe-users@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users</a><br>
</blockquote></div></div>
</blockquote></div>
</blockquote></div></div>