【问题标题】:How to extract headers from source file using clang?如何使用clang从源文件中提取标题?
【发布时间】:2018-06-20 13:32:33
【问题描述】:

我正在使用 clang ast 匹配器从源文件中提取一些信息。现在,我还想知道源文件正在使用的标头和依赖标头的列表。例如,源文件 abc.c 的头文件如下:

#include <def.h>
//#include <def_private.h>

在 clang matcher 期间,我需要确保 clang 知道 def.h,它位于同一目录中。 def.h 包含以下标头:

#include <iostream.h>
#include <string.h>
#include <float.h>
#include <math.h>
/*#include <boost>
* #inclde <fstream>*/

我使用 ast matcher 从 abc.c 中提取或识别信息。现在,我想提取所有标题或包含。这应该包括所有这些:

#include <def.h>
#include <iostream.h>
#include <string.h>
#include <float.h>
#include <math.h>

为此我做了一些在线研究,不幸的是,所有这些都涉及正则表达式 (Regular expression to extract header name from c file) 或如何在 Visual Studio 中执行 (Displaying the #include hierarchy for a C++ file in Visual Studio)。

我想知道是否可以使用clang。另外,请告诉我是否有任何其他方法可以以编程方式提取标题,而不仅仅是使用正则表达式。

【问题讨论】:

  • “任何其他方式”是指“使用 clang”,还是任何其他可以让您获得正确答案的方式,无论是否是 clang?
  • 以编程方式提取标题的任何其他方法不仅仅是使用正则表达式。换句话说,方法(没有clang也可以,但是程序应该理解header tree)应该能够理解header是什么意思,并且能够区分cmets内部的headers。
  • "区分 cmets 中的标头"??评论可能包含看起来像#include 但它不是的文本,它只是评论文本。您只是指出不应考虑评论内容,对吗?同样的字符串文字内容。 (这对正则表达式来说充其量是尴尬的,同意)。
  • @IraBaxter 你是对的,我只是指出不应考虑评论内容。我将在我的问题中更新这一点,感谢您的澄清。

标签: c++ clang header-files llvm-clang


【解决方案1】:

OP 说 以编程方式提取标题的任何其他方法不仅仅是使用正则表达式。 ....没有clang是可以的

我们都同意正则表达式根本无法做到这一点。您需要将源文本解析为树,并在树中显式显示#include 指令。

我不是 Clang 专家。我怀疑它的内部树反映了预处理的源,所以#include 结构已经消失了。那么问题就在于坚持对源文本进行预处理以对其进行解析。

我们的DMS Software Reengineering Toolkit 及其C++17 capable parser 可以在不扩展指令的情况下处理此类解析。它可以通过两种方式做到这一点: a) 在预处理器指令相对于源代码“结构良好”的情况下,C++ 前端可以配置为捕获解析树,其中指令在适当的位置也被解析为树;这在实践中效果很好,代价是有时不得不手动修补一个特别丑陋的条件或宏调用以使其“结构良好,或者 b) 解析捕获以(几乎)任意方式放置的预处理器指令;这捕获指令有时以自动复制少量代码为代价,本质上会导致案例 a) 所喜欢的良好重组。

在任何一种情况下,#include 指令现在都显式地出现在 AST 中,包含的文件几乎构建为代表包含文件的辅助树。这样的树节点很容易通过查找此类显式包含节点的树遍历找到。 DMS 的 ASTInterface 提供 ScanTree 来遍历节点并在某些提供的谓词对节点为真时采取行动;检查#include 节点很容易。值得注意的是,因为条件指令也被保留,所以通过从 #include onr 向上遍历树可以构造实际包含该包含文件的条件。

当然,头文件本身也被解析,生成一棵树。任何包含它已出现在其树体中的内容。必须在每棵树上运行 ScanTree 才能收集所有包含。

OP 没有说他想用#includes 做什么。 DMS 提供了很多超越解析来帮助 OP 实现她的目的,包括符号表构建、控制和数据流分析、树模式匹配、以源语言 (C++) 语法表示的树到树转换,最后是源代码(重新)从修改后的语法树生成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-06
    • 2022-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多