c++ - 如何将 Clang AST 中的 TemplateTypeParm 节点与 AST_Matchers 匹配?
问题描述
我正在尝试获取 TypeAliasDecl 的 RHS 模板类型。
例子:
using AliasOfType = AliasedType; // AliasedType itself is a template
我可以AliasOfType
使用 AST 在 AST中检索clang::ast_matchers::typeAliasDecl
。我想AliasedType
用clang::ast_matchers::
.
AST 转储clang::ast_matchers::typeAliasDecl
看起来像:
TypeAliasDecl 0x4fe22cf8 AliasOfType
-SubstTemplateTypeParmType 0x4fe22cc0
|-TemplateTypeParmType 0x4fe1a840 `AliasedType` dependent depth 0 index 0
| `-TemplateTypeParm 0x4fe1a7f8 'AliasedType'
所以直观地说,我想匹配TemplateTypeParm
哪个有我以前的匹配作为祖先。但是,我还没有找到ast_matcher
这样做的。有clang::ast_matchers::templateTypeParmType
,但如果我尝试将任何内容作为缩小参数,它会给出错误,例如:
templateTypeParmType(hasName("AliasedType"))
我尝试时得到的错误是:
clang/ASTMatchers/ASTMatchersInternal.h:1347:13: error: ‘clang::ast_matchers::internal::Matcher< <template-parameter-1-1> >::Matcher(const clang::ast_matchers::internal::DynTypedMatcher&) [with T = clang::TemplateTypeParmType]’ is private within this context
return {Matcher<T>(std::get<Is>(Params))...};
解决方案
你是对的,没有直接匹配器来检查类型别名的别名类型(你自己实现它并不难,但我想这应该是最后的手段)。
has
但是,根据文档,有一个匹配器:
匹配具有与提供的匹配器匹配的子 AST 节点的 AST 节点。
另一个重要的一点是类型别名肯定会有一个TypeLoc
作为孩子的。Type
这是关于s 和s之间区别的小引用TypeLoc
(来自Internals Manual):
我们在表示相同类型时重用 Type 节点(但为每个写入类型的实例维护单独的 TypeLocs)
综上所述,我们得到以下匹配器:
typeAliasDecl(has(typeLoc(loc(templateTypeParmType())).bind("x")))
对于此代码段:
using NotInterestingAlias = int;
template <class AliasedType> class TemplateClass {
using AliasOfType = AliasedType;
using AliasOfSomeOtherType = double;
};
int main() { return 0; }
匹配器将产生以下输出:
main.cpp:4:3: note: "root" binds here
using AliasOfType = AliasedType;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:4:23: note: "x" binds here
using AliasOfType = AliasedType;
^~~~~~~~~~~
我希望这些信息有用。与 Clang 一起愉快地黑客攻击!
推荐阅读
- python-3.x - 迭代合并不同数量的行
- arduino - 如何将 Bacnet 集成到 arduino
- flutter - 在 SharedPreferences 和对象解码上颤振“NoSuchMethodError(NoSuchMethodError:getter 'length' was called on null” *仅限首次启动*
- spring-boot - 如果没有休息控制器,没有请求映射注释,swagger 将如何与 spring boot 一起工作?
- javascript - 带有 cocos creator 问题的 ARjs
- selenium - 无法验证 Klarna 付款,结帐时未保留为出生日期键入的值(Selenium、Chrome 驱动程序)
- docker - 为什么docker容器中的某些目录可以挂载和共享文件而有些不能
- c# - Asp.net 核心拒绝客户端:本地主机上的 403 但 Kubernetes 集群中的异常
- python - 取列表中字典的第二个或第 n 个元素
- perl - 是否可以处理与模式匹配的文本行并将其移动到与另一个模式匹配的另一个位置(在同一文件中)?