c++ - 如何计算在具有特定类型操作数的代码库中使用重载运算符的次数

标签 c++ templates metaprogramming static-analysis clang-static-analyzer

我有一个模板类 SafeInt<T> (由微软)。

这个类在理论上可以用来代替 POD 整数类型,并且可以检测算术运算期间的任何整数溢出。

对于这个类,我写了一些自定义的模板化重载算术运算符(+、-、*、/)函数,它们的两个参数都是 SafeInt<T> 的对象。 .

我将我所有的整数类型定义为 SafeInt 类类型。

我想在我的代码库中搜索上述二元运算符的实例,其中两个操作数都是 SafeInt 类型。

我能想到的一些方法

  1. 使用正则表达式搜索字符串并筛选代码以检测两个操作数都是 SafeInt 对象的运算符使用实例。

  2. 编写一个 clang 工具并处理 AST 来执行此搜索(我还没有学习如何编写这样的工具。)

  3. 以某种方式添加一个计数器来计算自定义重载运算符被实例化的次数。我花了很多时间尝试这个但似乎没有用。

谁能提出更好的方法?

如果我需要澄清任何事情,请告诉我。

谢谢。

最佳答案

简答

您可以使用 clang-query 命令执行此操作:

$ clang-query \
  -c='m cxxOperatorCallExpr(callee(functionDecl(hasName("operator+"))), hasArgument(0, expr(hasType(cxxRecordDecl(hasName("SafeInt"))))), hasArgument(1, expr(hasType(cxxRecordDecl(hasName("SafeInt"))))))' \
  use-si.cc --

Match #1:

/home/scott/wrk/learn/clang/clang-query1/use-si.cc:10:3: note: "root" binds here
  x + y;           // reported
  ^~~~~
1 match.

什么是 clang-query?

clang-query是一个旨在促进写作的实用程序 clang-tidy检查。特别是它理解 AST Matchers 的语言并可用于交互式探索给定匹配表达式匹配的内容。然而,如此处所示,它也可以非交互式地用于查找任意 AST 树模式。

博文Exploring Clang Tooling Part 2: Examining the Clang AST with clang-query通过 Stephen Kelly很好地介绍了如何使用 clang-query

clang-query 程序包含在 pre-built LLVM binaries 中,或者它可以按照 AST Matchers Tutorial 中的描述从源代码构建。 .

上述命令是如何工作的?

-c 参数提供了一个非交互式运行的命令。添加空格后,命令为:

m                                  // Match (and report) every
cxxOperatorCallExpr(               // operator function call
  callee(functionDecl(             // where the callee
    hasName("operator+"))),        // is "operator+", and
  hasArgument(0,                   // where the first argument
    expr(hasType(cxxRecordDecl(    // is a class type
      hasName("SafeInt"))))),      // called "SafeInt",
  hasArgument(1,                   // and the second argument
    expr(hasType(cxxRecordDecl(    // is also a class type
      hasName("SafeInt"))))))      // called "SafeInt".

命令行以use-si.cc --结尾,意思是分析use-si.cc不需要额外的编译标志clang 来解释它。

clang-query 命令行的基本结构与clang-tidy 相同。 ,包括通过 -p compile_commands.json 一次扫描多个文件的能力,每个文件可能使用不同的编译器选项。

示例输入

为了完整起见,我用来测试匹配器的输入是use-si.cc:

// use-si.cc

#include "SafeInt.hpp"         // SafeInt

void f1()
{
  SafeInt<int> x(2);
  SafeInt<int> y(3);

  x + y;           // reported

  x + 2;           // not reported

  2 + x;           // not reported
}

SafeInt.hpp 来自 https://github.com/dcleblanc/SafeInt ,在 Microsoft SafeInt page 上命名的 repo 协议(protocol).

关于c++ - 如何计算在具有特定类型操作数的代码库中使用重载运算符的次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36952595/

相关文章:

c++ - 分配 vector 大小与保留 vector 大小

c++ - C++中#undef的含义

c++ - OPENCV 无法在 Debug模式下打开我的图像

c++ - 在任何类类型的模板方法中使用 new

c++ - 遵守 C\C++ 标准有哪些责任?

c++ - 模板元编程 :why flat type is failure

c++ - 是否有等效于 #if 的可以评估模板参数?

c# - C# : Automatic ToString Method 中的元编程

scala - Scala 3 编译器操作中用于类型类派生的元组

c++ - 具有某种条件的宏