Nネストされたforループと一致させる方法はありませんが、一致させたい深さNごとにN個のマッチャを作成する必要はありません。 など。
StatementMatcher forLoopLevel2 = forStmt(<someMatcher>, hasDescendant(forStmt())).bind("loop2");
間違いやって価値がない
StatementMatcher forLoopLevel3 = forStmt(<someMatcher>, hasDescendant(forStmt(<someMatcher>,hasDescendant(forStmt())))).bind("loop3");
!
私がアドバイスするのは、単一のforループのためのマッチャーを作成することです。コールバックはNレベルのネストforループ(各forループごとに1回)に対してN回だけ呼び出されます。これらのコールバックインスタンスのそれぞれから変数名を取得することができ、それはどんな深さでも機能します。ここで、ループ初期化し、conditionalizesを確保する
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();
}
文の
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