概述

Clang 工具是独立的命令行(以及潜在的 GUI)工具,专为已经使用并享受 Clang 作为其编译器的 C++ 开发人员设计。这些工具提供面向开发人员的功能,例如快速语法检查、自动格式化、重构等。

在主 Clang 树中只保留了少数最基本和最基础的工具。其他工具保存在一个单独的目录树中,clang-tools-extra

本文档描述了 Clang 工具在项目中的组织结构的概览,以及对一些更重要的工具的介绍。但是,需要注意的是,本文档目前侧重于 Clang 和 Clang 工具开发人员,而不是这些工具的最终用户。

Clang 工具组织结构

Clang 工具是 CLI 或 GUI 程序,旨在供 C++ 开发人员直接使用。也就是说,它们不是主要供 Clang 开发人员使用,尽管它们有望对碰巧在 Clang 上工作的 C++ 开发人员有所帮助,并且我们努力积极地尝试他们的功能。它们在三个组件中开发:基于 Clang 构建独立工具的基础设施、以重构和重写库形式存在的许多不同工具使用的核心共享逻辑以及工具本身。

Clang 工具的基础设施是 LibTooling 平台。有关此基础设施工作原理的更详细的信息,请参阅其文档。常见的重构和重写工具包式库也是 LibTooling 组织的一部分。

一些 Clang 工具与核心 Clang 库一起开发,作为基本功能的示例和测试用例。但是,大多数工具都在一个辅助存储库中开发,以便于与核心库分离。我们故意不支持辅助存储库中的公共库,因为我们希望仔细审查并为从几个工具中提取到核心 Clang 库集中的库找到合适的 API。

无论 Clang 工具代码驻留在哪个存储库中,所有 Clang 工具的开发流程和实践都与 Clang 本身完全相同。它们完全在 Clang 项目中,无论版本控制方案如何。

核心 Clang 工具

位于主存储库中的核心 Clang 工具集是专门补充并允许使用和测试Clang特定功能的工具。

clang-check

ClangCheck 将用于运行 Clang 工具的 LibTooling 框架与基本的 Clang 诊断结合起来,通过快速、命令行界面语法检查特定文件。它还可以接受标志以在不同的格式中使用不同的标志重新显示诊断信息,适合用于驱动 IDE 或编辑器。此外,它可以在 fixit 模式下使用,以直接应用 clang 提供的 fixit 提示。有关如何设置和使用 clang-check 的说明,请参阅 如何为 LLVM 设置 Clang 工具

clang-format

Clang-format 既是 ,也是 独立工具,其目标是根据可配置的样式指南自动重新格式化 C++ 源代码文件。为此,clang-format 使用 Clang 的 Lexer 将输入文件转换为标记流,然后更改这些标记周围的所有空格。clang-format 的目标是既可以用作用户工具(理想情况下具有强大的 IDE 集成),也可以用作其他重构工具的一部分,例如对重命名期间更改的所有行进行重新格式化。

额外 Clang 工具

随着各种类别的 Clang 工具被添加到额外存储库中,它们将在此处进行跟踪。本文档的重点是工具的范围和功能,供其他工具开发人员使用;每个工具都应该提供自己的面向用户的文档。

clang-tidy

clang-tidy 是一个基于 clang 的 C++ 静态分析工具。它提供了一个可扩展的框架,用于构建基于编译器的静态分析,以检测和修复容易出错的模式、性能、可移植性和可维护性问题。

新工具的想法

  • C++ 类型转换工具。将转换 C 样式转换 ((type) value) 为适当的 C++ 类型转换 (static_castconst_castreinterpret_cast)。

  • 非成员 begin()end() 转换工具。将 foo.begin() 转换为 begin(foo),类似地,end() 也是如此,其中 foo 是一个标准容器。我们还可以检测数组的类似模式。

  • tr1 移除工具。将从使用 TR1 库功能迁移源代码到 C++11 库。例如

    #include <tr1/unordered_map>
    int main()
    {
        std::tr1::unordered_map <int, int> ma;
        std::cout << ma.size () << std::endl;
        return 0;
    }
    

    应该改写为

    #include <unordered_map>
    int main()
    {
        std::unordered_map <int, int> ma;
        std::cout << ma.size () << std::endl;
        return 0;
    }
    
  • 一个用于移除 auto 的工具。将 auto 转换为显式类型或添加带有推断类型的注释。其动机是,有些开发人员不想使用 auto,因为他们担心可能会失去对代码的控制。

  • C++14:更简洁的操作符函数对象 (N3421)。例如

    sort(v.begin(), v.end(), greater<ValueType>());
    

    应该改写为

    sort(v.begin(), v.end(), greater<>());