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.
On Wed, Aug 7, 2019 at 2:28 PM Ayush Mittal <bellavistagh...@gmail.com> wrote: > Sure, Not a problem. > > What's the way to get the declarations such as *ptr and &bar as it is > inside the *DeclRefExpr *block*. * > *Example: * > void foo(){ > int bar=1; > int **ptr; > **ptr = &bar;* // this line > } > > *If I query like this way:* > if (const ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl())){ > OS << VD->getType() //returns the original type of that declaration, > not the one that was used. > } > > Thanks and Regards. > > On Tue, Aug 6, 2019 at 7:41 PM Richard Trieu <rtr...@google.com> wrote: > >> 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. >> >> On Tue, Aug 6, 2019 at 11:56 AM Ayush Mittal <bellavistagh...@gmail.com> >> wrote: >> >>> 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