讲师中心 微信公众号
AI工具推荐 视频效率加速

C++ 怎么编写自定义的 Clang-Tidy 静态检查插件检查团队特定的编码规范

雨明姑娘_4411

雨明姑娘_4411

发布时间:2026-10-22 13:50:20

|

881人浏览过

|

来源于php中文网

原创

Clang-Tidy插件必须实现ClangTidyCheck派生类并注册到ClangTidyModule,缺一不可;需用AST匹配器定位模式,check()中须三重防护避免崩溃。

c++ 怎么编写自定义的 clang-tidy 静态检查插件检查团队特定的编码规范

Clang-Tidy 插件需要什么基础组件

必须实现 ClangTidyCheck 派生类,并注册到 ClangTidyModule;不提供完整模块注册,插件加载时会静默失败,连 -list-checks 都看不到你的检查项。

关键结构缺一不可:

  • MyCustomCheck 类继承自 clang::tidy::ClangTidyCheck,重写 registerMatchers() 和 check()
  • 一个继承 ClangTidyModule 的模块类,重写 createCheck() 并在 addCheckFactories() 中注册
  • CMakeLists.txt 里用 add_clang_library() 构建动态库(不是可执行文件),且链接 clangTooling、clangAST、clangLex 等依赖
  • 编译产物必须是 .so(Linux/macOS)或 .dll(Windows),且文件名符合 libMyModule.so 格式(Clang-Tidy 通过前缀 lib + 模块名识别)

怎么写 registerMatchers 定位团队规范中的典型模式

不能靠字符串匹配,必须用 Clang AST 匹配器(ast_matchers)。比如团队禁止裸指针成员变量,就得匹配 fieldDecl(hasType(pointerType())),而不是搜 "*"。

常见误判点:

立即学习“C++免费学习笔记(深入)”;

  • 忽略模板上下文:用 fieldDecl() 默认不匹配类模板中的成员,需加 unless(isInstantiated()) 或显式处理 isTemplateInstantiation()
  • 过度匹配:varDecl() 会抓到函数内局部变量,加 hasParent(cxxRecordDecl()) 才能限定为类成员
  • 类型穿透不足:pointerType() 不匹配 const T*,要用 pointsTo(anything()) 或组合 qualType(hasCanonicalType(pointerType()))

示例:检查是否用了非 const 引用参数(团队要求输入参数尽量 const&)

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
void MyCustomCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(
      parmVarDecl(
          hasType(references(qualType(unless(isConstQualified()),
                                      hasCanonicalType(referenceType(pointee(qualType()))))))
      ).bind("nonConstRefParam"), this);
}

check() 里怎么安全生成诊断信息并避免崩溃

AST 节点可能为空、未完成解析或跨翻译单元失效,直接调 Node.getNodeAs<ParmVarDecl>("nonConstRefParam")->getType().getAsString() 很容易段错误。

必须做三重防护:

  • 用 if (const auto *Param = Node.getNodeAs<ParmVarDecl>("nonConstRefParam")) 判空
  • 用 Param->getType().isNull() 检查类型有效性(尤其模板推导失败时)
  • 诊断位置用 Param->getLocation(),但要先 if (!Param->getLocation().isValid()) return;
  • 修复建议(FixItHint)只对源码存在的 token 生效;若想改模板特化里的参数,基本不可行——别硬塞 FixItHint::CreateReplacement()

示例中生成警告:

void MyCustomCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *Param = Result.Nodes.getNodeAs<ParmVarDecl>("nonConstRefParam");
  if (!Param || !Param->getLocation().isValid() || Param->getType().isNull())
    return;
  diag(Param->getLocation(), "non-const lvalue reference parameter violates team guideline")
      << FixItHint::CreateInsertion(Param->getLocation(), "const ");
}

怎么让插件被 clang-tidy 正确加载和调试

加载失败时不会报错,只会跳过——最常见原因是路径、命名或符号导出问题。

  • 插件路径必须通过 -plugin-path= 显式指定,且该路径下只能放 .so 文件,不能有子目录
  • 模块名(即 ClangTidyModule 子类名)必须与 add_clang_library(libMyModule) 中的库名一致,且首字母小写(Clang-Tidy 内部会把模块名转成小写再拼接 lib 前缀)
  • 确保符号可见:CMake 中添加 set_property(TARGET MyModule PROPERTY POSITION_INDEPENDENT_CODE ON),并用 __attribute__((visibility("default"))) 导出模块类
  • 调试时加 -debug 参数,观察日志里是否有 Loading module 'mymodule';没有就说明注册或路径错了

运行命令示例:

clang-tidy -plugin-path=/path/to/plugins -checks="-*,mymodule-non-const-ref-param" foo.cpp

最难调的是匹配逻辑和 AST 生命周期——节点在 check() 里看似可用,但一旦涉及 getDescribedClassTemplate() 或 getTemplateSpecializationKind(),极易因 Sema 未完成而返回空。这类问题没有通用解法,只能结合 -ast-dump 看实际 AST 结构,再调整 matcher 条件。

热门AI工具

更多
Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2248

2024.03.14

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

1019

2024.03.14

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

447

2024.03.14

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

327

2024.03.14

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

406

2024.03.14

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

580

2024.03.14

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

1409

2024.03.21

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

1217

2024.03.22

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C语言中文开发手册
C语言中文开发手册

共0课时 | 0.2万人学习

极客学院ASP.NET视频教程
极客学院ASP.NET视频教程

共90课时 | 24.3万人学习

Go语言教程手册
Go语言教程手册

共23课时 | 27万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn