Re: [cfe-users] Why doesn't clang use colors for diagnostics by default?

2015-09-09 Thread Richard Trieu via cfe-users
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

2016-05-24 Thread Richard Trieu via cfe-users
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

2016-11-11 Thread Richard Trieu via cfe-users
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?

2018-02-21 Thread Richard Trieu via cfe-users
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 *)

2019-07-30 Thread Richard Trieu via cfe-users
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 *)

2019-08-01 Thread Richard Trieu via cfe-users
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 *)

2019-08-06 Thread Richard Trieu via cfe-users
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 *)

2019-08-07 Thread Richard Trieu via cfe-users
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:
>>
>