我有一个模板类 SafeInt<T>
(由微软)。
这个类在理论上可以用来代替 POD 整数类型,并且可以检测算术运算期间的任何整数溢出。
对于这个类,我写了一些自定义的模板化重载算术运算符(+、-、*、/)函数,它们的两个参数都是 SafeInt<T>
的对象。 .
我将我所有的整数类型定义为 SafeInt 类类型。
我想在我的代码库中搜索上述二元运算符的实例,其中两个操作数都是 SafeInt 类型。
我能想到的一些方法
使用正则表达式搜索字符串并筛选代码以检测两个操作数都是 SafeInt 对象的运算符使用实例。
编写一个 clang 工具并处理 AST 来执行此搜索(我还没有学习如何编写这样的工具。)
以某种方式添加一个计数器来计算自定义重载运算符被实例化的次数。我花了很多时间尝试这个但似乎没有用。
谁能提出更好的方法?
如果我需要澄清任何事情,请告诉我。
谢谢。
最佳答案
简答
您可以使用 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/