我正在尝试编写一个 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
的成员访问?
谢谢。
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;
^