如何使用ASTMatcher排除无标签结构体?
用Clang ASTMatcher排除无标签结构体,仅匹配有标签结构体
问题场景
你需要提取有标签的结构体声明,排除如下示例中的无标签结构体:
#include <stdlib.h> struct { int b; } a; int func() { a.b = 1; return 0; }
你当前使用的匹配器无法排除这类无标签结构体,尝试过isAnonymousStructOrUnion()和unless(hasName(""))均无效。
解决方案
方法一:使用Clang内置的匿名结构体匹配器(推荐,Clang 3.9+)
Clang提供了isAnonymousStructOrUnion()匹配器,专门识别无标签的结构体/联合体,直接用unless()包裹即可排除目标:
auto structDeclMatcher = recordDecl( isExpansionInMainFile(), isDefinition(), unless(isAnonymousStructOrUnion()) ).bind("structDecl");
方法二:兼容旧版Clang的替代方案
如果你的Clang版本不支持isAnonymousStructOrUnion(),可以结合两个条件排除:
- 排除无标签名的结构体(
unless(hasName(""))) - 排除那些作为变量/字段内嵌类型定义的结构体(比如示例中绑定到变量
a的匿名结构体)
auto structDeclMatcher = recordDecl( isExpansionInMainFile(), isDefinition(), unless(hasName("")), unless(hasParent(varDecl())), unless(hasParent(fieldDecl())) // 若需排除字段内的匿名结构体可添加 ).bind("structDecl");
原理说明
- 无标签结构体在AST中以
RecordDecl节点存在,其特征是标签名为空,且通常作为变量/字段的类型内嵌定义(父节点为varDecl或fieldDecl)。 isAnonymousStructOrUnion()会直接匹配这类无标签结构体,是最精准的方式;旧版方案则通过标签名+上下文的组合来间接排除。
内容的提问来源于stack exchange,提问作者cardigan
相关产品推荐
相关产品推荐

