[cfe-dev] Dividing statements

Csaba Raduly rcsaba at gmail.com
Sat Mar 1 04:22:11 PST 2014


Hi Pedro,

On Thu, Feb 27, 2014 at 12:36 PM, Pedro Delgado Perez  wrote:
> Hi,
>
> I have a sentence like this:
>
> method( b )    ,        a = 3     ,        b++;
>
> This sentence is a statement composed of three substatements. What I need is
> to difference those three substatements which are between commas to save
> them in a list:
>
> Statement 1 -> method( b )
> Statement 2->  a = 3
> Statement 3 -> b++
>
> So I tried using the "child_iterator" in the class Stmt, which I though it
> would be easy.
> In the first iteration, the statement is subdivided in:
>
> [method( b )  ,  a = 3]    and     [b++;]
>
> The first sentence is then subdivided again in:
>
> [method( b )]   and    [a = 3]
>
> The problem is that  I don't know when I should stop the division because,
> now, the first statement is divided again to my surprise, taking the
> argument "b" as a new statement. Thus, I'm getting more than three
> statements, what is a major issue in my case.
>
> Is there any way to count the number of statements separated by commas?

"You keep using that word. I do not think it means what you think it means."

In C++ the word "statement" has a precise meaning. There is no such
thing in C++ as "substatement".

Your "sentence" is _one_ statement. It contains an expression (whose
result you're throwing away, but that's normal).

There is no such thing as "statements separated by commas". There's
not even "expressions separated by commas".
You have been tricked by the fact that evaluation of comma expressions
proceeds from left to right, into believing that the expression is
represented as a linear data structure. It's not. It's a tree.
Here's the output of clang -cc1 -ast-dump:

    `-BinaryOperator 0x6000c4d78 <line:9:3, col:47> 'int' ','
      |-BinaryOperator 0x6000c4d08 <col:3, col:31> 'int' ','
      | |-CallExpr 0x6000c4c50 <col:3, col:13> 'void'
      | | |-ImplicitCastExpr 0x6000c4c38 <col:3> 'void (*)(int)'
<FunctionToPointerDecay>
      | | | `-DeclRefExpr 0x6000c4bc0 <col:3> 'void (int)' Function
0x60007e640 'method' 'void (int)'
      | | `-ImplicitCastExpr 0x6000c4c80 <col:11> 'int' <LValueToRValue>
      | |   `-DeclRefExpr 0x6000c4be8 <col:11> 'int' lvalue Var
0x60007e8f0 'b' 'int'
      | `-BinaryOperator 0x6000c4ce0 <col:27, col:31> 'int' '='
      |   |-DeclRefExpr 0x6000c4c98 <col:27> 'int' lvalue Var
0x60007e880 'a' 'int'
      |   `-IntegerLiteral 0x6000c4cc0 <col:31> 'int' 3
      `-UnaryOperator 0x6000c4d58 <col:46, col:47> 'int' postfix '++'
        `-DeclRefExpr 0x6000c4d30 <col:46> 'int' lvalue Var
0x60007e8f0 'b' 'int'

What you have is a binary expression: a comma operator and its two
operands. One of the operands is a binary expression: a comma operator
and its operands.

You could perhaps try to navigate this tree and stop if the
BinaryOperator is not a ',' .


Csaba
-- 
GCS a+ e++ d- C++ ULS$ L+$ !E- W++ P+++$ w++$ tv+ b++ DI D++ 5++
The Tao of math: The numbers you can count are not the real numbers.
Life is complex, with real and imaginary parts.
"Ok, it boots. Which means it must be bug-free and perfect. " -- Linus Torvalds
"People disagree with me. I just ignore them." -- Linus Torvalds



More information about the cfe-dev mailing list