class 父声明的适当 AST 匹配器

Appropriate AST Matcher for class parent declaration

给定 class 层次结构:

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

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

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

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

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

编辑:

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

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

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

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

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

我们发现对class 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 直接获取基本 class 引用,而不是迭代和检查基本 class 类型名称,如上图