什么是AST,CFG,CLANG,我们如何在死码去除算法中使用它?

我将使用C语言为我们的团队编写一个用于在线事件的死代码删除算法。

要求是……

  1. 读取C程序源文件,其中包含多种forms的死代码。
  2. 我们的输出应该是一个文件,它没有任何死码。

在浏览互联网时,我们遇到了SO链接……

我怎么知道代码中的哪些部分从未使用过?

传统C / C ++项目中的死代码检测

在看到这些链接之前,我们有了基本的想法……使用普通文件流逐行读取输入C文件并存储在字符串数组中。 然后分析这些字符串并确定非常基本的死代码,如if(0)和if(1)等。并制作一个堆栈,用于维护括号。 还有更多……

但这有一个很大的问题,这个想法将引导我们用字符串操作做更多事情,而不是删除死码。

但看到这些链接后…我们开始了解Clang库,抽象语法树,控制流图等…

但我们对这些图书馆和那些概念都是新手。 我们开始知道它们用于解析C代码。

因此,我们需要一些关于AST,CFG和一些基本指导的基本想法,解释我们如何在我们的代码中使用它…

我们可以将clang库作为像math.h这样的普通库包含在内吗?

我们在哪里可以下载该库?

我们可以在Windows中使用那些Clang库吗?

我可以向您解释控制流图的概念,但我不熟悉库本身。

这个概念很简单。 想象一下任何连续的代码行(没有ifgoto或函数调用或标签)作为图形的一个节点。 每个goto或函数调用都会创建一个从当前节点到goto标签所在节点或它正在调用的函数的方向链接。 请记住,函数本身可以是图形而不是简单节点,因为它可能具有内部的s或其他函数调用。 每个函数调用还创建一个方向链接,从函数的叶节点(函数return s)到包含函数调用之后的代码的节点。 (这可以创建从函数图中传出的大量链接,因为可以在代码的许多部分调用该函数)

同样,如果你有一个if ,你有两个方向链接,从当前节点到if语句的if部分和else部分(除非你检测if(0)if(1)就像你说的那样在那种情况下只有一个链接到正确的位置)

图的根是main的入口点。 现在你必须做的就是找到死代码只是从根位置遍历图形(例如使用DFS或BFS),最后看看哪些节点没有被访问过。 这会向您显示死代码,即代码中的位置,无论您的程序采用何种方向,它都不会到达这些位置。

如果你想自己实现它,你可以采用递归方法(类似于解析代码但更简单)。 例如,如果您看到if您说:

 typedef char *line; FlowGraph *get_flow_graph(line *code) { FlowGraph *current_node = malloc(sizeof *current_node); current_node->flow_to = malloc(some_maximum * sizeof *current_node->flow_to); current_node->flow_to_count = 0; ... if (is_if_statement(code[0])) { FlowGraph *if_part = get_flow_graph(code + 1); FlowGraph *else_part = get_flow_graph(code + find_matching_else(code)); current_node->flow_to[current_node->flow_to_count++] = if_part; current_node->flow_to[current_node->flow_to_count++] = else_part; } else ... } 

您可以看到DMS Software Reengineering Toolkit提取的控制和数据流图的示例。

我们使用DMS的数据流分析机器及其C前端在非常大的应用程序(2600万行C)上完成了这项工作,包括点分析,如果你真的想在大型中找到死函数,这是一个实际需要C系统。