【问题标题】:Appropriate AST Matcher for class parent declaration类父声明的适当 AST 匹配器
【发布时间】:2015-08-12 15:27:45
【问题描述】:

给定一个类层次结构:

class A {};
class B {};
class C : public A {};
class D : public C {};

我正在尝试重构 C 类以从 B 类而不是 A 类继承。我可以使用 recordDecl 轻松获得定义语句:

recordDecl(hasName("C"), isDefinition()).bind("MyClass")

通过关联的 MatchCallback,我可以dump() 类来验证它是否匹配正确的节点。但是我还没有找到一种方法来绑定到public A,或者更好的是,只是A

什么是合适的 AST 匹配器来捕获 C 类的 public AA

编辑:

clang -ast-dump 在这种情况下过滤为 C 类的输出将显示类似于以下内容:

CXXRecordDecl [address] <line numbers> <loc> class C definition
|- public 'class A'
|- CXXRecordDecl [address 2] <columns> <loc> implicit referenced class C

好像在 ast-dump 中没有 AST Node 类型来表示父类声明。

【问题讨论】:

    标签: clang abstract-syntax-tree llvm-clang


    【解决方案1】:

    我发现这个link 提供了一些关于如何向下钻取的上下文。值得注意的是,一个教程建议在返回节点的匹配处理程序中使用RecordDecl,而此引用使用CXXRecordDecl。因此,如果我们在匹配处理程序中输出每个碱基:

    if (const CXXRecord *entityBase = Result.Nodes.getNodeAs<clang::CXXRecordDecl>("entityBase")) {
        for (auto &p : entityBase->bases()) {
            p.dump();
        }
    }
    

    我们发现对A类的引用是RecordType,它被CXXRecord引用。但是使用clang-query,我没有找到一种方法将match recordType(...) 与任何有助于拉动public AA 的东西联系起来。相反,解决方案变成了类似这样:

    std::string qual = "public ";
    std::string parentName = "A";
    std::string parentType = "class " + parentName;
    if (0 == parentType.compare(p.getType().getAsString())) {
        Replacement Rep(*(Result.SourceManager),
            p.getLocStart().getLocWithOffset(qual.length()),
            parentName.length(),
            "B");
        Replace->insert(Rep);
    }
    

    我还没有将此标记为答案,以防万一有人有办法使用 recordType 直接获取基类引用,而不是迭代和检查基类类型名称,如上所示。

    【讨论】:

      猜你喜欢
      • 2015-02-03
      • 1970-01-01
      • 1970-01-01
      • 2019-08-03
      • 2020-10-05
      • 2012-01-01
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多