<div dir="ltr"><div>The declarations are "ptr" and "bar".  "*ptr" and "&bar" are expressions since * and & are C++ operators.  If you want the type of "*ptr" or "&bar", then you need to get the associated UnaryOperator (a sub-class of Expr) and call getType() on it.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Aug 7, 2019 at 2:28 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">Sure, Not a problem. <div><br></div><div>What's the way to get the declarations such as *ptr and &bar as it is inside the <b>DeclRefExpr </b>block<b>. </b><br></div><div><b><i>Example: </i></b></div><div>void foo(){</div><div>    int bar=1;</div><div>    int **ptr;</div><div><b>*ptr = &bar;</b> // this line</div><div>}</div><div><div><br></div><div><b>If I query like this way:</b></div><div>if (const ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl())){<br>     OS << VD->getType() //returns the original type of that declaration, not the one that was used.<b><br></b></div></div><div>}</div><div><br></div><div>Thanks and Regards.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Aug 6, 2019 at 7:41 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">RecursiveASTVisitor should have an ASTContext available.  ASTContext has a getParents function, which may be of some use.  Unfortunately, I haven't used this part of the ASTContext before, so I can't give any more concrete advice.  As you've seen, it's easier to traverse down the AST than up it.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Aug 6, 2019 at 11:56 AM 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! <div><br></div><div>|       | | |-IfStmt 0x78b6d90 <line:82:13, line:89:13><br>|       | | | |-<<<NULL>>><br>|       | | | |-<<<NULL>>><br>|       | | | |-BinaryOperator 0x78b5f08 <line:82:17, col:34> 'int' '=='<br>|       | | | | |-ImplicitCastExpr 0x78b5eb0 <col:17, col:23> 'int' <IntegralCast><br>|       | | | | | `-ImplicitCastExpr 0x78b5e58 <col:17, col:23> 'example_tree':'enum example_tree_type_' <LValueToRValue><br>|       | | | | |   `-MemberExpr 0x78b5d78 <col:17, col:23> 'example_tree':'enum example_tree_type_' lvalue -><b>bal</b> 0x75a3ab0<br>|       | | | | |     `-ImplicitCastExpr 0x78b5d20 <col:17> 'example_tree_node *' <LValueToRValue><br>|       | | | | |       `-<b>DeclRefExpr</b> 0x78b5cb8 <col:17> 'example_tree_node *' lvalue Var 0x78b1d48 'left' 'example_tree_node *'</div><div><br></div><div><br></div><div>Is there a way to get an access to the MemberExpr and ImplicitCastExpr from VisitDeclRefExpr. </div><div><br></div><div>Thanks for the help!</div><div><br></div><div>Reagrds.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Aug 1, 2019 at 8:14 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>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>
</blockquote></div>
</blockquote></div>
</blockquote></div>
</blockquote></div></div>