8

我正在研究多线程代码的覆盖率标准,作为它的一部分,我想记录对变量的访问。例如,在下面的代码中,我想记录变量x被写入y, z, a[i],和 i 被读取。

x = y * (int)z + a[i]

我一直在考虑使用 Clang 的 RecursiveASTVisitor 并修改源以包含录制功能。但是,我不确定这是否是一种明智的方法,因为我对 Clang 如何工作的理解非常不完整。

目前,当我找到一个语句时,我会检查它是否是BinaryOperator, UnaryOperator, Cast, or DeclRefExpr. (一旦我掌握了基础知识,我将扩展它的能力。)如果是,BinaryOperator, UnaryOperator, or Cast我检查表达式的子表达式。如果它是 DeclRefExpr,我可以检查表达式是左值还是右值(再次,现在简化),但是一旦我找到 DeclRefExpr,它们总是左值。为了确定它们是否被使用,因为lvalues or rvalues我必须检查它的父级,如果它是左值或值转换,它被用作右值。

我非常觉得我对这个问题采取了错误的方法,因为我只能看到它变得更加复杂,因为我必须考虑更复杂的代码。

有没有更好的方法来解决这个问题?

谢谢

编辑

我不打算静态地记录这些信息。我打算找到变量的用途并插入代码,这些代码将在代码运行时记录对这些变量的访问。

例如,给定上面的代码(x = y * (int)z + a[i];),我想产生类似的东西

x = y * (int)z + a[i];
recordAccess(<file>, <line>, "x",    &x,    WRITE);
recordAccess(<file>, <line>, "y",    &y,    READ);
recordAccess(<file>, <line>, "z",    &z,    READ);
recordAccess(<file>, <line>, "a[i]", &a[i], READ);
recordAccess(<file>, <line>, "i",    &i,    READ);
4

2 回答 2

1

正如其他人所指出的,混叠使这成为不可能。不可能对代码进行静态分析来回答您感兴趣的问题。如果有可能获取源代码文件并仅通过分析语法来确定输出,那么编译器将生成结果程序的输出,而不是编译程序的输出。简而言之,您正在尝试回答停机问题

动态分析是您真正需要回答您最可能感兴趣的问题。多线程软件的动态分析已经有很大的市场。

于 2013-03-09T03:29:44.553 回答
0

这里的主要问题是您没有考虑混叠。您将只能记录简单、直接的访问。

但在这种情况下,一个简单的表达式 AST 访问者是主要的方法。但是 Clang 的 RecursiveASTVisitor 应该能够从记忆中为您减少废话并允许您直接访问最终的变量节点。毕竟,它应该访问每个 AST 节点。

于 2013-03-06T16:08:04.957 回答