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 A
或 A
?
编辑:
在这种情况下,为 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 A
或 A
的东西链接起来。相反,解决方案变成了类似这样的东西:
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 类型名称,如上图
给定 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 A
或 A
?
编辑:
在这种情况下,为 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 A
或 A
的东西链接起来。相反,解决方案变成了类似这样的东西:
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 类型名称,如上图