Thanks Richard for the explanation! | | | |-IfStmt 0x78b6d90 <line:82:13, line:89:13> | | | | |-<<<NULL>>> | | | | |-<<<NULL>>> | | | | |-BinaryOperator 0x78b5f08 <line:82:17, col:34> 'int' '==' | | | | | |-ImplicitCastExpr 0x78b5eb0 <col:17, col:23> 'int' <IntegralCast> | | | | | | `-ImplicitCastExpr 0x78b5e58 <col:17, col:23> 'example_tree':'enum example_tree_type_' <LValueToRValue> | | | | | | `-MemberExpr 0x78b5d78 <col:17, col:23> 'example_tree':'enum example_tree_type_' lvalue ->*bal* 0x75a3ab0 | | | | | | `-ImplicitCastExpr 0x78b5d20 <col:17> 'example_tree_node *' <LValueToRValue> | | | | | | `-*DeclRefExpr* 0x78b5cb8 <col:17> 'example_tree_node *' lvalue Var 0x78b1d48 'left' 'example_tree_node *'
Is there a way to get an access to the MemberExpr and ImplicitCastExpr from VisitDeclRefExpr. Thanks for the help! Reagrds. On Thu, Aug 1, 2019 at 8:14 PM Richard Trieu <rtr...@google.com> wrote: > Adding back the mailing list. Please reply all to keep the discussion on > the mailing list. > > On Thu, Aug 1, 2019 at 2:47 PM Ayush Mittal <bellavistagh...@gmail.com> > wrote: > >> Thanks Richard for the explanation. Really appreciate it. >> One quick question, Within VisitStmt (BinaryOperator) how could I get an >> access to DeclRefExpr class. >> > > You should be defining a VisitBinaryOperator(BinaryOperator*) function. > VisitStmt(BinaryOperator) won't be called because the base visitor class > doesn't know about it. > >> >> For example, >> *-IfStmt* 0x88b5698 <line:13:3, line:16:12> >> | |-<<<NULL>>> >> | |-<<<NULL>>> >> | |-BinaryOperator 0x88b54a0 <line:13:7, col:13> 'int' '==' >> | | |-ImplicitCastExpr 0x88b5420 <col:7> 'int' <LValueToRValue> >> | | | `-*DeclRefExpr* 0x88b5358 <col:7> 'int' lvalue ParmVar >> 0x88604b0 'argc' 'int' >> >> 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. > > BinaryOperator *BO = ...; > Expr *E = BO->getLHS(); > E = E->IgnoreImpCasts(); > if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { > // Do your stuff here. > } > > or just: > > BinaryOperator *BO = ...; > if (DeclRefExpr *DRE = > dyn_cast<DeclRefExpr>(E->getLHS()->IgnoreImpCasts())) { > // Do your stuff here. > } > > * 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. > >> >> Thanks and Regards. >> >> On Tue, Jul 30, 2019 at 9:11 PM Richard Trieu <rtr...@google.com> wrote: >> >>> Hi Ayush, >>> >>> 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. >>> >>> 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: >>> >>> void VisitStmt(Stmt *S) { >>> if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) { >>> // Process BinaryOperator here >>> } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(S)) { >>> ... >>> } // other checks here >>> } >>> >>> void VisitStmt(Stmt *S) { >>> switch (S->getStmtClass()) { >>> case Stmt::BinaryOperatorClass: { >>> BinaryOperator *BO = cast<BinaryOperator>(S); >>> // Process BinaryOperator here >>> } >>> case Stmt::UnaryOperatorClass: { >>> UnaryOperator *UO = cast<UnaryOperator>(S); >>> } >>> // Other cases here >>> } >>> } >>> >>> 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. >>> >>> 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. >>> >>> On Tue, Jul 30, 2019 at 4:25 PM Ayush Mittal via cfe-users < >>> cfe-users@lists.llvm.org> wrote: >>> >>>> Hello Clangers, >>>> >>>> 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: *VisitStmt(Stmt *S)*. My question >>>> is how could I traverse If, while, for loop, boolean and Unary Operators- >>>> inside this function. >>>> >>>> Thanks and Regards. >>>> _______________________________________________ >>>> cfe-users mailing list >>>> cfe-users@lists.llvm.org >>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users >>>> >>>
_______________________________________________ cfe-users mailing list cfe-users@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users