微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 AST 匹配器匹配可变参数模板参数

如何解决使用 AST 匹配器匹配可变参数模板参数

我有以下示例代码

template<class T,class... Args>
T add(T first,Args... rest) {
    return first + add(rest...);
}

int add(int a,int b) {
    return a + b;
}

当我通过 clang-check -ast-dump 运行它时,我得到以下树。

FunctionDecl 0x4df0b08 <tmp.cpp:2:1,line:4:1> line:2:3 add 'T (T,Args...)'
|-ParmVarDecl 0x4df0928 <col:7,col:9> col:9 referenced first 'T'
|-ParmVarDecl 0x4df09f8 <col:16,col:24> col:24 referenced rest 'Args...' pack
`-CompoundStmt 0x4df0dd0 <col:30,line:4:1>
  `-ReturnStmt 0x4df0dc0 <line:3:5,col:31>
    `-BinaryOperator 0x4df0da0 <col:12,col:31> '<dependent type>' '+'
      |-DeclRefExpr 0x4df0cd0 <col:12> 'T' lvalue ParmVar 0x4df0928 'first' 'T'
      `-CallExpr 0x4df0d78 <col:20,col:31> '<dependent type>'
        |-UnresolvedLookupExpr 0x4df0cf0 <col:20> '<overloaded function type>' lvalue (ADL) = 'add' 0x4df0ba8
        `-PackExpansionExpr 0x4df0d58 <col:24,col:28> '<dependent type>' lvalue
          `-DeclRefExpr 0x4df0d38 <col:24> 'Args' lvalue ParmVar 0x4df09f8 'rest' 'Args...'

FunctionDecl 0x4df0f60 <tmp.cpp:6:1,line:8:1> line:6:5 add 'int (int,int)'
|-ParmVarDecl 0x4df0e00 <col:9,col:13> col:13 used a 'int'
|-ParmVarDecl 0x4df0e80 <col:16,col:20> col:20 used b 'int'
`-CompoundStmt 0x4df10b0 <col:23,line:8:1>
  `-ReturnStmt 0x4df10a0 <line:7:5,col:16>
    `-BinaryOperator 0x4df1080 <col:12,col:16> 'int' '+'
      |-DeclRefExpr 0x4df1010 <col:12> 'int' lvalue ParmVar 0x4df0e00 'a' 'int'
      `-DeclRefExpr 0x4df1030 <col:16> 'int' lvalue ParmVar 0x4df0e80 'b' 'int'

我想为第一种情况编写一个匹配器,其中函数一个参数是可变参数。从 AST Matcher Reference 中,我发现有一个 isVariadic 匹配器,尽管正如文档所说,

Example matches f,but not g or h. The function i will not match,even when
compiled in C mode.
  void f(...);
  void g(int);
  template <typename... Ts> void h(Ts...);
  void i();

有没有办法匹配可变参数函数声明,并进一步将可变参数声明绑定到某个节点?我想做类似 functionDecl(has(parmVarDecl(hasType(packExpansionType().bind("parameter_type"))))) 的事情,但似乎这是不可能的,因为没有 packExpansionType 匹配器。我在这里遗漏了什么吗?

解决方法

为了将来参考,我找到了解决方案。实际上可以在检查中定义自定义匹配器。

namespace {
    const AstTypeMatcher<PackExpansionType> packExpansionType;
    const internal::VariadicDynCastAllOfMatcher<Stmt,PackExpansionExpr> packExpansionExpr;
}

// You can also use the macros from ASTMatchersMacros.h

...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。