我尝试使用clang StatementMatcher 在嵌套循环中查找变量
for(i=0;i<10;i++)
for(j=0;j<10;j++)
//I have i and j
我不确定它是否可以使用单个匹配器处理任何级别的嵌套循环,但如果它可以的话会很好。
现在我可以找到下面有matcher的循环,它不能处理多个嵌套循环和变量(从llvm示例中得到这个)。如果有人可以帮助我,我感激不尽。
StatementMatcher LoopMatcher =
forStmt(hasLoopInit(declStmt(
hasSingleDecl(varDecl(hasInitializer(integerLiteral(equals(0))))
.bind("initVarName")))),
hasIncrement(unaryOperator(
hasOperatorName("++"),
hasUnaryOperand(declRefExpr(
to(varDecl(hasType(isInteger())).bind("incVarName")))))),
hasCondition(binaryOperator(
hasOperatorName("<"),
hasLHS(ignoringParenImpCasts(declRefExpr(
to(varDecl(hasType(isInteger())).bind("condVarName"))))),
hasRHS(expr(hasType(isInteger())))))).bind("forLoop");
ps:如果它变得更容易,我正在寻找像上面那样完美的嵌套循环,内圈周围没有{}。
答案 0 :(得分:0)
没有办法(据我所知)匹配N-nested for循环而不为每个可能的深度N创建N匹配器。 E.g。
StatementMatcher forLoopLevel2 = forStmt(<someMatcher>, hasDescendant(forStmt())).bind("loop2");
和
StatementMatcher forLoopLevel3 = forStmt(<someMatcher>, hasDescendant(forStmt(<someMatcher>,hasDescendant(forStmt())))).bind("loop3");
绝对不值得做!
我建议为单个for循环创建一个匹配器,并且对于N级嵌套for循环(每个for循环一次),回调将被简单地触发N次。然后,您可以从每个回调实例中检索变量名称,这将适用于任何深度。这是一些代码..
主要
int main(int argc, const char **argv) {
MyPrinter Printer;
MatchFinder Finder;
StatementMatcher forLoopMatcher = forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl().bind("initVar")))),
hasCondition(binaryOperator(hasLHS(ignoringParenImpCasts(declRefExpr(to(varDecl().bind("condVar"))))))),
hasIncrement(unaryOperator(hasUnaryOperand(declRefExpr(to(varDecl().bind("incVar"))))))
).bind("loop");
Finder.addMatcher(forLoopMatcher, &Printer);
return Tool.run(newFrontendActionFactory(&Finder).get());
}
确保循环初始化,条件化和递增相同变量的方法。
static bool areSameVariable(const ValueDecl *First, const ValueDecl *Second) {
return First && Second && First->getCanonicalDecl() == Second->getCanonicalDecl();
}
每当找到for语句时匹配回调
class MyPrinter : public MatchFinder::MatchCallback {
public:
virtual void run(const MatchFinder::MatchResult &Result) {
ASTContext *context = Result.Context;
if(const ForStmt *F = Result.Nodes.getNodeAs<clang::ForStmt>("loop")){
const VarDecl *initVar = Result.Nodes.getNodeAs<clang::VarDecl>("initVar");
const VarDecl *condVar = Result.Nodes.getNodeAs<clang::VarDecl>("condVar");
const VarDecl *incVar = Result.Nodes.getNodeAs<clang::VarDecl>("incVar");
if(areSameVariable(initVar,condVar) && areSameVariable(initVar, incVar)){
string name = initVar->getNameAsString();
outs() << "Variable name is: " + name + "\n";
}
}
}
};
示例输入文件:
int main(void) {
for(int a=0; a<10; a++){
for(int b=0; b<10; b++){
}
}
return 0;
}
输出
Variable name is: a
Variable name is: b