2016-12-01 182 views
2

ITranslationUnit和IASTTranslationUnit接口分别代表单个C/C++源文件的翻译单元和AST。Eclipse CDT:获取C++项目的AST

有什么办法可以获得整个C++项目的AST,还是需要从主文件的AST开始,并通过include指令导航并为每个源单元生成单独的AST?

谢谢。

回答

3

CDT的AST不是为了扩展到整个项目而设计的。一旦你开始进入10000+ LOC范围,它很可能开始表现非常糟糕。

对于跨文件分析的目的,CDT有一个索引器,它解析项目中的每个文件(一次一个),并构建一个关于项目中整个代码的信息数据库(称为索引)。该索引通过接口IIndex进行访问,该实例可以通过在任何AST上调用IASTTranslationUnit.getIndex()来获得(例如)。

大多数代码分析和操作使用情况分为以下工作流程之一:

  • 只需使用索引。 IIndex给你很多的工作,比如:

    • findBindings()各种重载找到绑定匹配的姓名或名称前缀
    • findReferences(binding)给你一个结合
    • findDeclarations(binding)所有引用给你绑定的所有声明


    和许多其他。编辑器导航功能(如Open Declaration和Call Hierarchy)的工作方式就是这样。

  • 使用该索引标识需要AST的一小组源文件,然后解析这些文件。这就是重构的工作原理。例如,重命名重构使用索引来查找被重命名的绑定的使用,然后为包含这些用于执行重构的文件创建AST。

  • 如果以上都不够好,并且您确实需要项目中每个文件的AST级别信息,请为项目中的每个文件创建一个AST,然后从中提取您需要的信息每一个。这是索引器本身的工作原理。 (请注意,如果您选择此选项,则无需导航即可列出需要解析的所有文件,而只需枚举项目中的所有文件。有关示例,请参见PDOMRebuildTask.createDelegate()。)

如果您更多地了解您的用例,我可能会提供更具体的建议。

+0

我想你是说CDT自然分析单个源文件,但不是它的包含文件。那么,如果必要的声明信息在包含文件中,CDT如何解析“最令人头痛的解析”(或任何其他语法上模棱两可的构造)?请参阅http:// stackoverflow。com/questions/17388771/get-human-readable-ast-from-c-code/17393852#17393852 –

+0

@IraBaxter:索引器以依赖性顺序解析文件,并从索引中先前解析的文件中查找信息。 – HighCommander4

+0

根据关于预处理器条件变量状态的恒定性的一些假设? (可以想象一个CU正在执行#define FLAG TRUE,另一个CU正在执行#define FLAG FALSE,然后它们都包括一个检查该标志的头文件) –