In my coding standard checking tool, it limits comma expression usage, except in a for statment, i.e:
x++, x+=1; // this will be marked as invalid usage
for (x = 0, y = 0; …) // but this comma expression is valid
I can implement VisitBinComma, this function will be called when parsed comma expression. But how to know if this comma expression is in a for statment ?
In my coding standard checking tool, it limits comma expression usage,
except in a for statment, i.e:
x++, x+=1; // this will be marked as invalid usage
for (x = 0, y = 0; ...) // but this comma expression is valid
I can implement `VisitBinComma`, this function will be called when parsed
comma expression. But how to know if this comma expression is in a for
statment ?
... you can use -ast-dump to see what the AST for a representative
sample looks like:
--
// commaop.cpp
int main() {
int x = 0;
x++, x += 1;
for (int x = 0, y = 0; x < 10; ++x, --y)
;
}
--
--
$ clang -cc1 -ast-dump commaop.cpp
(TranslationUnitDecl 0x600960 <<invalid sloc>>
(TypedefDecl 0x600c50 <<invalid sloc>> __builtin_va_list 'char *')
(FunctionDecl 0x600cc0 <D:\temp\commaop.cpp:2:1, line:9:1> main 'int (void)'
(CompoundStmt 0x601050 <line:2:12, line:9:1>
(DeclStmt 0x600db0 <line:3:3, col:12>
(VarDecl 0x600d60 <col:3, col:11> x 'int'
(IntegerLiteral 0x600d90 <col:11> 'int' 0)))
(BinaryOperator 0x600e48 <line:5:3, col:13> 'int' lvalue ','
(UnaryOperator 0x600dd8 <col:3, col:4> 'int' postfix '++'
(DeclRefExpr 0x600dc0 <col:3> 'int' lvalue Var 0x600d60 'x' 'int'))
(CompoundAssignOperator 0x600e28 <col:8, col:13> 'int' lvalue
'+=' ComputeLHSTy='int' ComputeResultTy='int'
(DeclRefExpr 0x600dec <col:8> 'int' lvalue Var 0x600d60 'x' 'int')
(IntegerLiteral 0x600e08 <col:13> 'int' 1)))
(ForStmt 0x601028 <line:7:3, line:8:5>
(DeclStmt 0x600f30 <line:7:8, col:24>
(VarDecl 0x600e70 <col:8, col:16> x 'int'
(IntegerLiteral 0x600ea0 <col:16> 'int' 0))
(VarDecl 0x600ed0 <col:8, col:23> y 'int'
(IntegerLiteral 0x600f00 <col:23> 'int' 0)))
(<<<NULL>>>)
(BinaryOperator 0x600f88 <col:26, col:30> '_Bool' '<'
(ImplicitCastExpr 0x600f78 <col:26> 'int' <LValueToRValue>
(DeclRefExpr 0x600f40 <col:26> 'int' lvalue Var 0x600e70 'x' 'int'))
(IntegerLiteral 0x600f58 <col:30> 'int' 10))
(BinaryOperator 0x601000 <col:34, col:41> 'int' lvalue ','
(UnaryOperator 0x600fb8 <col:34, col:36> 'int' lvalue prefix '++'
(DeclRefExpr 0x600fa0 <col:36> 'int' lvalue Var 0x600e70 'x' 'int'))
(UnaryOperator 0x600fe8 <col:39, col:41> 'int' lvalue prefix '--'
(DeclRefExpr 0x600fcc <col:41> 'int' lvalue Var 0x600ed0
'y' 'int')))
(NullStmt 0x601018 <line:8:5>)))))
--
It doesn't look like the comma in the for statement declaration is
represented in the AST, but maybe you can trigger on the fact that
there are multiple VarDecls under the DeclStmt?
Commas in declarations aren't the same as comma operators in
expressions. If you declare x and y outside of the for statement, then
you will see the comma in the AST.
In my coding standard checking tool, it limits comma expression usage,
except in a for statment, i.e:
x++, x+=1; // this will be marked as invalid usage
for (x = 0, y = 0; ...) // but this comma expression is valid
I can implement `VisitBinComma`, this function will be called when parsed
comma expression. But how to know if this comma expression is in a for
statment ?
The simplest way is to implement TraverseForStmt, and set a flag to
indicate you are within a for statement.
I think that solves it nicely for kevinlynx, because it looks like he
wants to ban the comma operator for everything that isn't a
declaration, except when the parent is a ForStmt.