如何将 Clang AST 中的 TemplateTypeParm 节点与 AST_Matchers 匹配?

How to match TemplateTypeParm node in Clang AST with AST_Matchers?

我正在尝试获取 TypeAliasDecl 的 RHS 模板类型。

示例:

using AliasOfType = AliasedType; // AliasedType itself is a template

我可以使用 clang::ast_matchers::typeAliasDecl 在 AST 中检索 AliasOfType。我想用 clang::ast_matchers::.

检索 AliasedType

clang::ast_matchers::typeAliasDecl 的 AST 转储看起来像:

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 根据 documentation:

Matches AST nodes that have child AST nodes that match the provided matcher.

另一个重点是类型别名肯定会有 TypeLoc 作为 child。这是关于 Types 和 TypeLocs 之间区别的小引用(来自 Internals Manual):

we reuse Type nodes when representing the same type (but maintain separate TypeLocs for each instance where a type is written)

将它们放在一起我们得到以下匹配器:

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 愉快!