如何用Clang AST匹配器匹配任意传递方式的指定类型函数参数
问题
现有如下Clang AST匹配器,可匹配参数为任意类型std::vector(值传递或引用传递)的函数:
DeclarationMatcher funcMatcher = functionDecl( anyOf(hasAnyParameter( hasType(references(recordDecl(matchesName("std::vector"))))), hasAnyParameter(hasType(recordDecl(matchesName("std::vector"))))));
是否存在可同时匹配std::vector、std::vector&和std::vector*的匹配器?显然可手动扩展匹配器适配指针情况,但想了解Clang AST是否有“底层类型”相关概念,已查阅官方文档。
回答
Clang AST确实支持针对底层类型的匹配逻辑,不用手动拆分多个anyOf分支来分别处理值、引用、指针三种传递方式。
你可以通过组合pointsTo()、references()和原始类型匹配来覆盖所有场景,写法更简洁:
DeclarationMatcher funcMatcher = functionDecl( hasAnyParameter( hasType( anyOf( // 匹配值传递的std::vector recordDecl(matchesName("std::vector")), // 匹配引用类型的std::vector references(recordDecl(matchesName("std::vector"))), // 匹配指针类型的std::vector pointsTo(recordDecl(matchesName("std::vector"))) ) ) ) );
另外,Clang AST里的hasUnqualifiedDesugaredType()还能跳过typedef、类型别名这类语法糖,直接定位到最原始的底层类型声明。如果你的场景中存在using Vec = std::vector<int>这类别名,用hasUnqualifiedDesugaredType(recordDecl(matchesName("std::vector")))替换上述的类型匹配逻辑,能更精准地匹配到所有本质是std::vector的参数类型。
本质上,Clang AST会对指针、引用类型做层级化解析,pointsTo()和references()就是用来穿透这些类型包装,获取其底层指向/引用的原始类型,这就是你要找的“底层类型”相关概念。
内容的提问来源于stack exchange,提问作者Joe Todd
相关产品推荐
相关产品推荐

