How to match a struct member access using clang AST matcher?

问题描述 投票:0回答:1

我正在尝试编写一个 clang-tidy 检查来重命名结构成员。 为此,我需要匹配访问特定成员的

MemberExpr
节点,来自特定结构。

在下面的代码中,它应该只匹配

member
在类型
S1
S2
上的所有使用(总共8个匹配)。

typedef struct S1 { int member; int v; } S1; typedef struct MS1 {S1 s1; } MS1;
typedef struct S2 { int member; int v; } S2; typedef struct MS2 {S2 s2; } MS2;
typedef struct S3 { int member; int v; } S3; typedef struct MS3 {S2 s3; } MS3;

void f() {
  S1 *s1a, s1b; MS1 *ms1a, ms1b;
  S2 *s2a, s2b; MS2 *ms2a, ms2b;
  S3 *s3a, s3b; MS3 *ms3a, ms3b;

  (void)s1a->member; (void)s1b.member; (void)ms1a->s1.member; (void)ms1b.s1.member;
  (void)s2a->member; (void)s2b.member; (void)ms2a->s2.member; (void)ms2b.s2.member;
  (void)s3a->member; (void)s3b.member; (void)ms3a->s3.member; (void)ms3b.s3.member;

  (void)s1a->v; (void)s1b.v; (void)ms1a->s1.v; (void)ms1b.s1.v;
  (void)s2a->v; (void)s2b.v; (void)ms2a->s2.v; (void)ms2b.s2.v;
  (void)s3a->v; (void)s3b.v; (void)ms3a->s3.v; (void)ms3b.s3.v;
}

匹配器

memberExpr(member(hasName("member")))
太宽泛,还包括类型
S3
.

如何限制匹配器只返回

S1
S2
的成员访问? 谢谢。

clang llvm clang-ast-matchers
1个回答
0
投票

也许令人惊讶的是,

hasName
选择器可用于限制成员的包含类或命名空间及其简单标识符名称。引用链接文档:

Matches NamedDecl nodes that have the specified name.

Supports specifying enclosing namespaces or classes by prefixing the name
with '<enclosing>::'.
Does not match typedefs of an underlying type with the given name.

Example matches X (Name == "X")
  class X;

Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X")
  namespace a { namespace b { class X; } }

这意味着我们可以像这样匹配

S1::member
S2::member

memberExpr(member(anyOf(hasName("S1::member"),hasName("S2::member"))))

我们也可以用

matchesName
用正则表达式来表达条件:

memberExpr(member(matchesName("S[12]::member")))

使用以上任一方法,我在你的测试用例上得到了八场比赛,但只有在修复这一行中明显的错字之后:

typedef struct S3 { int member; int v; } S3; typedef struct MS3 {S2 s3; } MS3;

我认为应该是:

typedef struct S3 { int member; int v; } S3; typedef struct MS3 {S3 s3; } MS3;
                                                                  ^
© www.soinside.com 2019 - 2024. All rights reserved.