自动标记c中未使用的结构体成员



我需要一个工具来自动标记C代码库中未使用的结构成员。我对"未使用"的定义很简单—如果从代码中删除了结构成员定义,并且代码编译成功,则声明该结构成员未使用。问题是,如何用自动化的方式来完成?(由于代码库很小,速度不是太重要)。

关于这个主题的现有堆栈溢出文章似乎暗示,目前还没有现有的静态分析工具可以做到这一点。另一方面,考虑到Clang的模块化,我觉得这应该可以通过AST操作实现。让我们以单个文件为例。我想做的事情如下(稍后可以将其推广到代码库中的一组源文件):

  1. 从C代码生成AST
  2. 递归访问所有结构字段定义,并逐个删除它们。我们可以保持"视线"。字典,以确保我们不会删除已经看到的字段定义节点。
    • 过滤出字段定义,只分析那些存在于代码库中的字段定义(例如,避免在标准库中定义)。
  3. 编译代码
  4. 如果代码编译成功,则相应的字段声明未使用并被标记。
  5. 继续#1

上面的关键字是remove。如何删除字段定义?似乎有两种使用Clang的方法。

  1. 在源代码级别,我们可以使用Clang Rewriter删除字段声明(有一个"RemoveText(SourceRange)"&;选项)。但是,我不知道这是否会一直工作(例如:使用MACRO扩展自动生成结构)。
  2. 从AST中删除字段声明节点,然后"重新编译";AST(不管那是什么意思)。

在上面的两个选项中,#1似乎有些粗糙—您需要创建源文件的副本,在删除字段定义后重新编写它,然后重新编译修改后的源文件。而且,我不确定当有复杂的宏涉及到生成结构字段定义时,它将如何工作。

#2似乎很干净,但从谷歌上看,似乎没有"删除AST节点"这样的事情。(它是不可变的)。如果我说错了,请纠正我。即使我成功地做到了这一点,我如何从这一点开始重新评估AST对结构字段的引用缺失?("compilation"一步)。

感谢任何建议(提前感谢!)。我已经用上面的第一个方法取得了一些初步的成功,但我觉得这不是正确的方向。

cppcheck可以这样做。例如:

// test.cpp
struct Struct
{
int used;
int unused;
};
int main()
{
Struct s;
s.used = 0;
return s.used;
}
$ cppcheck test.cpp --enable=all
Checking test.cpp ...
test.cpp:5:9: style: struct member 'Struct::unused' is never used. [unusedStructMember]
int unused;
^

当我在示例中使用c++代码时,它的行为与C相同。

最新更新