I want to find all the case statement having no break statement. I using clang-query to build my matcher. My matcher is failing in some of the test cases.
I wrote simple matcher as
match caseStmt(unless(has(breakStmt())))
it works with follwing test case
#include<stdlib.h>
int main(){
int x;
switch(x){
case 1:
break;
case 2:
default:
x++;
}
return 0;
}
int main()
{
int x = 1, y = 2;
// Outer Switch
switch (x) {
// If x == 1
case 1:
// Nested Switch
switch (y) {
// If y == 2
case 2:
//break;
// If y == 3
case 3:
break;
}
break;
// If x == 4
case 4:
break;
// If x == 5
case 5:
break;
default:
break;
}
return 0;
}
does not work well with following
#include <iostream>
using namespace std;
int main()
{
int x = 1, y = 2;
// Outer Switch
switch (x) {
// If x == 1
case 1:
// Nested Switch
switch (y) {
// If y == 2
case 2:
cout << "Choice is 2";
//break;
// If y == 3
case 3:
cout << "Choice is 3";
break;
}
//break;
// If x == 4
case 4:
cout << "Choice is 4";
break;
// If x == 5
case 5:
cout << "Choice is 5";
break;
default:
cout << "Choice is other than 1, 2 3, 4, or 5";
break;
}
return 0;
}
In above case it shows case statement that are having break statement along with case statement with no break statement.
what wrong i am doing ? please help :) I am following this http://releases.llvm.org/8.0.0/tools/clang/docs/LibASTMatchersTutorial.html
Unfortunately this is not going to work :-(
case
is technically a label
, and label
has only one statement as its child. If you print out AST you'll see that case
and break
statements will be at the same level:
| |-CaseStmt 0x5618732e1e30 <line:29:3, line:30:9>
| | |-IntegerLiteral 0x5618732e1e10 <line:29:8> 'int' 4
| | |-<<<NULL>>>
| | `-CallExpr 0x5618732e1f00 <line:30:5, col:9> 'void'
| | `-ImplicitCastExpr 0x5618732e1ee8 <col:5> 'void (*)()' <FunctionToPointerDecay>
| | `-DeclRefExpr 0x5618732e1ec0 <col:5> 'void ()' lvalue Function 0x5618732e16d0 'foo' 'void ()'
| |-BreakStmt 0x5618732e1f28 <line:31:5>
| |-CaseStmt 0x5618732e1f50 <line:34:3, line:35:9>
| | |-IntegerLiteral 0x5618732e1f30 <line:34:8> 'int' 5
| | |-<<<NULL>>>
| | `-CallExpr 0x5618732e2020 <line:35:5, col:9> 'void'
| | `-ImplicitCastExpr 0x5618732e2008 <col:5> 'void (*)()' <FunctionToPointerDecay>
| | `-DeclRefExpr 0x5618732e1fe0 <col:5> 'void ()' lvalue Function 0x5618732e16d0 'foo' 'void ()'
| |-BreakStmt 0x5618732e2048 <line:36:5>
Here you can see that CallExpr
is a child of CaseStmt
while BreakStmt
is not.
NOTE: to make example a bit easier I replaced std::cout << "..."
with foo()
.
You'll have to write a much more complex matcher that fetches for cases
that don't have break
statements between them and the following cases
.
I hope this is still helpful.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.