Re: [cfe-users] Why doesn't clang use colors for diagnostics by default?
Are you invoking Clang with "clang foo.cc" or "clang -cc1 foo.cc"? The first should detect if you have a color capable terminal and automatically turn on color diagnostics while the second needs the flag explicitly. The other possibility is that the Clang you are using was compiled with the libraries needed to detect a color terminal, and defaults to no color. On Mon, Sep 7, 2015 at 5:15 AM, Victor via cfe-users < cfe-users@lists.llvm.org> wrote: > Hello, all. > > Why doesn't clang use colors for diagnostics by default? > My environment: > > $ cat /etc/*-release > Red Hat Enterprise Linux Server release 6.3 (Santiago) > > $ echo $TERM > xterm > > Doc here > http://clang.llvm.org/docs/UsersManual.html#formatting-of-diagnostics > says: "This option, which defaults to on when a color-capable terminal is > detected". Isn't xterm "a color-capable terminal"? > > If I give -fcolor-diagnostics explicitly, all works as expected. But why > must I do that? GCC uses colors by default. > ___ > cfe-users mailing list > cfe-users@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users > ___ cfe-users mailing list cfe-users@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
Re: [cfe-users] 3.8 indentation with -fdiagnostics-show-template-tree doesn't show tree
Hi Larry, Right now, the template type diffing only works when there are two templated types in the diagnostics message, and the templated types share the same base. It your first example, the two types are vector and vector. In the second error message, only one type is printed with the diagnostic message. This does not trigger the template type diffing. The first message is "no member named 'size' in <>" and the second message is "in instantiation of function template specialization <> requested here" Richard On Tue, May 24, 2016 at 9:39 AM, Larry Evans via cfe-users < cfe-users@lists.llvm.org> wrote: > I've downloaded: > > ~/dwnlds/llvm/3.8/prebuilt $ wget > http://www.llvm.org/releases/3.8.0/clang+llvm-3.8.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.sig > > untarred it, and compiled a simple program: > > #include > > int main() > { > std::vector vecf(2); > std::vector vecd(2); > vecf = vecd; > return 0; > } > > resulting in, as expected, an indented error message showing the tree: > > candidate function not viable: no known conversion from argument > type to parameter type for 1st argument > vector< > [double != float], > allocator< > [double != float]>> > vector& operator=(vector&& __x) > ^ > > However, when compiling a much more complex template program, there's no > tree evident by the indentation: > > /home/evansl/dwnlds/llvm/3.8/prebuilt/clang+llvm-3.8.0-x86_64-linux-gnu-ubuntu-14.04/bin/clang++ > -c -O0 -stdlib=libc++ -std=c++14 -ftemplate-backtrace-limit=0 > -fdiagnostics-show-template-tree -fno-elide-type -fmacro-backtrace-limit=0 > -I/home/evansl/prog_dev/boost/github/TBoost.Conversion > -I/home/evansl/prog_dev/boost/sandbox/lje/non_variadic_templates > -I/home/evansl/prog_dev/clang/libcxx/sandbox/libs/composite_storage/include > -I../../../../../../boost/sandbox/lje/sandbox/lje > -I/home/evansl/prog_dev/boost/releases/ro/boost_1_59_0 -DTYPE_AT_IMPL=0 > -ftemplate-depth=100 texpressions.cpp -MMD -o > /tmp/build/clangxx3_8_pkg/clang/libcxx/sandbox/libs/gram_stk/sandbox/texpressions.o > > In file included from texpressions.cpp:1: > ./texpressions.hpp:1264:46: error: no member named 'size' in > 'texpressions::gram_defs > > composite_storage::type_sequence::gram_def1::syms::varble0, > def_ops::def_act, composite_storage::top (), > var_ptr_bool::var_ptr_yes, > > texpressions::gram_expr associativity::assoc_left>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl0>>, > > texpressions::gram_expr associativity::assoc_left>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl1>>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl0>> > > > > > >::attr_expr associativity::assoc_left>, > texpressions::gram_defs > > composite_storage::type_sequence::gram_def1::syms::varble0, > def_ops::def_act, composite_storage::top (), > var_ptr_bool::var_ptr_yes, > > texpressions::gram_expr associativity::assoc_left>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl0>>, > > texpressions::gram_expr associativity::assoc_left>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl1>>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl0>> > > > > > > >::attr_expr::op_symb my_symbols::syms::literl0>>, > texpressions::gram_defs > > composite_storage::type_sequence::gram_def1::syms::varble0, > def_ops::def_act, composite_storage::top (), > var_ptr_bool::var_ptr_yes, > > texpressions::gram_expr associativity::assoc_left>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl0>>, > > texpressions::gram_expr associativity::assoc_left>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl1>>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl0>> > > > > > >::attr_expr associativity::assoc_left>, > texpressions::gram_defs > > composite_storage::type_sequence::gram_def1::syms::varble0, > def_ops::def_act, composite_storage::top (), > var_ptr_bool::var_ptr_yes, > > texpressions::gram_expr associativity::assoc_left>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl0>>, > > texpressions::gram_expr associativity::assoc_left>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl1>>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl0>> > > > > > > >::attr_expr::op_symb my_symbols::syms::literl1>>, > texpressions::gram_defs > > composite_storage::type_sequence::gram_def1::syms::varble0, > def_ops::def_act, composite_storage::top (), > var_ptr_bool::var_ptr_yes, > > texpressions::gram_expr associativity::assoc_left>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl0>>, > > texpressions::gram_expr associativity::assoc_left>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl1>>, > > > texpressions::gram_expr::op_symb my_symbols::syms::literl0>> > > > > > > >::attr_expr::o
Re: [cfe-users] finding in which function/method/scope a Decl is in, the parent so to say
It sounds like you want the DeclContext. Use the function Decl::getDeclContext() to get a DeclContext pointer. See http://clang.llvm.org/doxygen/classclang_1_1DeclContext.html for details about DeclContext. DeclContext::isTranslationUnit() for globals and DeclContext::isFunctionOrMethod() for function/method scope. DeclContext can also be cast to other Decl types, so for example you could use dyn_cast to get the function scope. On Fri, Nov 11, 2016 at 4:06 AM, folkert via cfe-users < cfe-users@lists.llvm.org> wrote: > Hi, > > How can I find the parent of a VarDecl? The scope it is in. E.g. > function/method or a global. > > > Folkert van Heusden > ___ > cfe-users mailing list > cfe-users@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users > ___ cfe-users mailing list cfe-users@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
Re: [cfe-users] Format of AST entries?
Hi Ray, First off, understand that the AST dumper provides a human readable view of the AST that may be missing information and can change over time. It's good for a quick look into Clang's AST, but there are better options for tooling to work on the AST. (https://clang.llvm.org/docs/Tooling.html) (https://clang.llvm.org/docs/IntroductionToTheClangAST.html) This is an introduction to the AST, which has links to the Doxygen generated documentation for the AST nodes. Stmt, Decl, and Type are good places to start. For your specific question, you have a DeclRefExpr and a FunctionDecl. DeclRefExpr (https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html) DeclRefExpr is a sub class of Expr which is a sub class of Stmt FunctionDecl (http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html) FunctionDecl->DeclaratorDecl->ValueDecl->NamedDecl->Decl The AST dumper code is in lib/AST/ASTDumper.cpp. To dump a DeclRefExpr node, it first dumps the Stmt portion, followed by the Expr portion, then DeclRefExpr portion. Stmt prints "DeclRefExpr 0x862c118 " which is the specific Stmt kind, the pointer address, and the code location. Expr prints "'float (int, char)' lvalue" which is the Type and value type. DeclRefExpr is pretty much just a holder for a Decl, so it dumps the Decl. For all Decl's, it prints the Decl kind and the pointer address. Since FunctionDecl is a NamedDecl, it prints the name next. And finally, since it is a ValueDecl, it also prints the type. So, the first 'float (int, char)' is the type of the DeclRefExpr while the second 'float (int, char)' is the type of the FunctionDecl. There can be some conversions between the Decl type and the Expr type, so they may not always be the same. Hope that helps. On Tue, Feb 20, 2018 at 9:50 PM, Ray Mitchell via cfe-users < cfe-users@lists.llvm.org> wrote: > I am attempting to do some basic parsing of the AST using C#. So far I've > had success extracting a few things simply by writing some test C++ code, > generating an AST for it, making some changes, regenerating an AST, and > observing what changes in the AST entries. However, this empirical > approach is pretty brutal and requires a lot of questionable assumptions. > Is there any documentation that explicitly explains the possible > permutations and field meanings of each AST entry type? If so I'd greatly > appreciate a link to it. I've done pretty well figuring out the > FunctionDecl item and a few others but a document describing them would > really be helpful. For example, in the following I know that 'ABCDE' > represents the name of the function and 'float (int, char)' represents its > data type, but there are two copies of 'float (int, char)' and I'd like to > know why and if they both represent the same thing: > > || `-DeclRefExpr 0x862c118 'float (int, char)' lvalue Function > 0x85deae0 'ABCDE' 'float (int, char)' > > I have similar questions about most of the entry types. > Thanks, > Ray > > > ___ > cfe-users mailing list > cfe-users@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users > > ___ cfe-users mailing list cfe-users@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
Re: [cfe-users] AST Recursive Visitor- Statements (Stmt *)
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(S)) { // Process BinaryOperator here } else if (UnaryOperator *UO = dyn_cast(S)) { ... } // other checks here } void VisitStmt(Stmt *S) { switch (S->getStmtClass()) { case Stmt::BinaryOperatorClass: { BinaryOperator *BO = cast(S); // Process BinaryOperator here } case Stmt::UnaryOperatorClass: { UnaryOperator *UO = cast(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
Re: [cfe-users] AST Recursive Visitor- Statements (Stmt *)
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 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 > | |-<<>> > | |-<<>> > | |-BinaryOperator 0x88b54a0 'int' '==' > | | |-ImplicitCastExpr 0x88b5420 'int' > | | | `-*DeclRefExpr* 0x88b5358 '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(E)) { // Do your stuff here. } or just: BinaryOperator *BO = ...; if (DeclRefExpr *DRE = dyn_cast(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 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(S)) { >> // Process BinaryOperator here >> } else if (UnaryOperator *UO = dyn_cast(S)) { >> ... >> } // other checks here >> } >> >> void VisitStmt(Stmt *S) { >> switch (S->getStmtClass()) { >> case Stmt::BinaryOperatorClass: { >> BinaryOperator *BO = cast(S); >> // Process BinaryOperator here >> } >> case Stmt::UnaryOperatorClass: { >> UnaryOperator *UO = cast(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
Re: [cfe-users] AST Recursive Visitor- Statements (Stmt *)
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 wrote: > Thanks Richard for the explanation! > > | | | |-IfStmt 0x78b6d90 > | | | | |-<<>> > | | | | |-<<>> > | | | | |-BinaryOperator 0x78b5f08 'int' '==' > | | | | | |-ImplicitCastExpr 0x78b5eb0 'int' > > | | | | | | `-ImplicitCastExpr 0x78b5e58 > 'example_tree':'enum example_tree_type_' > | | | | | | `-MemberExpr 0x78b5d78 > 'example_tree':'enum example_tree_type_' lvalue ->*bal* 0x75a3ab0 > | | | | | | `-ImplicitCastExpr 0x78b5d20 > 'example_tree_node *' > | | | | | | `-*DeclRefExpr* 0x78b5cb8 > '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 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 >> 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 >>> | |-<<>> >>> | |-<<>> >>> | |-BinaryOperator 0x88b54a0 'int' '==' >>> | | |-ImplicitCastExpr 0x88b5420 'int' >>> | | | `-*DeclRefExpr* 0x88b5358 '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(E)) { >> // Do your stuff here. >> } >> >> or just: >> >> BinaryOperator *BO = ...; >> if (DeclRefExpr *DRE = >> dyn_cast(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 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(S)) { // Process BinaryOperator here } else if (UnaryOperator *UO = dyn_cast(S)) { ... } // other checks here } void VisitStmt(Stmt *S) { switch (S->getStmtClass()) { case Stmt::BinaryOperatorClass: { BinaryOperator *BO = cast(S); // Process BinaryOperator here } case Stmt::UnaryOperatorClass: { UnaryOperator *UO = cast(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 func
Re: [cfe-users] AST Recursive Visitor- Statements (Stmt *)
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 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(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 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 >> wrote: >> >>> Thanks Richard for the explanation! >>> >>> | | | |-IfStmt 0x78b6d90 >>> | | | | |-<<>> >>> | | | | |-<<>> >>> | | | | |-BinaryOperator 0x78b5f08 'int' '==' >>> | | | | | |-ImplicitCastExpr 0x78b5eb0 'int' >>> >>> | | | | | | `-ImplicitCastExpr 0x78b5e58 >>> 'example_tree':'enum example_tree_type_' >>> | | | | | | `-MemberExpr 0x78b5d78 >>> 'example_tree':'enum example_tree_type_' lvalue ->*bal* 0x75a3ab0 >>> | | | | | | `-ImplicitCastExpr 0x78b5d20 >>> 'example_tree_node *' >>> | | | | | | `-*DeclRefExpr* 0x78b5cb8 >>> '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 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 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 > | |-<<>> > | |-<<>> > | |-BinaryOperator 0x88b54a0 'int' '==' > | | |-ImplicitCastExpr 0x88b5420 'int' > | | | `-*DeclRefExpr* 0x88b5358 '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(E)) { // Do your stuff here. } or just: BinaryOperator *BO = ...; if (DeclRefExpr *DRE = dyn_cast(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 > 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: >> >