如何让RecursiveASTVisitor中止当前子树

问题描述 投票:1回答:1

使用Clang LibTooling的RecursiveASTVisitor时,如何告诉库中止当前访问的AST节点下的子树的扫描?

RecursiveASTVisitor在AST上使用深度优先遍历,可能很容易中止某些子树并继续遍历。

例如(请阅读代码中的注释):

virtual bool VisitCXXRecordDecl(CXXRecordDecl *decl) {
    //some code to tell the lib not to traverse the subtree
    //under the currently visited node i.e. decl 
    //but still continue the traversal 
    //so that the scan process will skip all AST nodes under any 
    //CXXRecordDecl in the AST
}

我以为从Visit ***方法返回false会达到这个目标,但确实告诉lib结束遍历,而不是跳过子树。

由于目标只是标题中所述的目标,因此不考虑ASTMatchers。

c++ clang libtooling
1个回答
0
投票
上使用深度优先遍历

实际上,从false函数之一返回VisitXXX将终止整个遍历。

要跳过AST节点,您可以覆盖TraverseXXX并有选择地回退到超类型(即RecursiveASTVisitor)实现:

class ASTVisitor : public RecursiveASTVisitor<ASTVisitor> {
public:
    bool TraverseCXXRecordDecl(CXXRecordDecl *decl) {
        // Don't traverse skip_me
        if (auto name = decl->getName(); std::string_view{name.data(), name.size()} == "skip_me") {

            // Return true to continue AST traversal,
            // but don't visit the node
            return true;
        }

        // Call RecursiveASTVisitor's implementation to visit this node
        return RecursiveASTVisitor<ASTVisitor>::TraverseCXXRecordDecl(decl);
    }

    bool VisitFieldDecl(FieldDecl *decl) {
        std::cout << "Visited field " << decl->getName().str() << '\n';

        return true;
    }
};

在此文件上测试此访客:

struct skip_me {
    int skipped;
};

struct dont_skip_me {
    int not_skipped;
};

产生以下输出:

Skipping skip_me
Visited field not_skipped
© www.soinside.com 2019 - 2024. All rights reserved.