clang - 编写 AST 匹配器以查找所有没有 break 语句的 case 语句
问题描述
我想找到所有没有 break 语句的 case 语句。我使用 clang-query 来构建我的匹配器。我的匹配器在某些测试用例中失败。
我写了简单的匹配器
匹配 caseStmt(除非(有(breakStmt())))
它适用于以下测试用例
#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;
}
#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;
}
在上述情况下,它显示了带有 break 语句的 case 语句以及没有 break 语句的 case 语句。
我在做什么错?请帮助:)我正在关注这个 http://releases.llvm.org/8.0.0/tools/clang/docs/LibASTMatchersTutorial.html
解决方案
不幸的是,这不起作用:-(
case
在技术上是 a label
,并且label
只有一个语句作为它的子级。如果您打印出 AST,您会看到case
和break
语句将处于同一级别:
| |-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>
在这里你可以看到while is notCallExpr
的 child 。CaseStmt
BreakStmt
注意:为了使示例更容易,我将其替换std::cout << "..."
为foo()
.
您必须编写一个更复杂的匹配器来获取它们与以下内容之间cases
没有语句的匹配器。break
cases
我希望这仍然有帮助。
推荐阅读
- post - Solr post.jar 因“prolog 中不允许内容”而崩溃
- c++ - 如何使用对象数组访问类中的变量?
- pandas - Pandas - 合并两个数据框时保持原始间距
- time-complexity - 在网络流中使用 Ford-Fulkerson 的时间复杂度
- c++ - Eigen::Matrix 的值在循环后消失
- c# - 如何在 asp.net core 2 中使用集合软删除实体中的记录?
- javascript - 页面加载错误上的 Flask 发布请求
- julia - 在 DiffEqPhysics Julia 中进行一些收敛测试后终止 ode 的集成
- php - 如何从 PHP 中的 MySQL 数据库中检索大小有限的记录集?
- lua - 在love2d中产生更多对象?