6

如果我在一个大型项目中有多个文件,所有文件都共享大量包含的头文件,有没有办法共享解析头文件的工作?我曾希望创建一个索引,然后向其中添加多个翻译单元可能会导致一些工作被共享 - 但是即使是(伪代码)行的代码

index = clang_createIndex();
clang_parseTranslationUnit(index, "myfile");
clang_parseTranslationUnit(index, "myfile");

每次调用 parseTranslationUnit 似乎都花费了全部时间,性能并不比

index1 = clang_createIndex();
clang_parseTranslationUnit(index1, "myfile");
index2 = clang_createIndex();
clang_parseTranslationUnit(index2, "myfile");

我知道有专门的功能可以重新解析完全相同的文件;但是我真正想要的是解析“myfile1”和“myfile2”可以共享解析“myheader.h”的工作,而特定于重新解析的函数在那里无济于事。

作为一个子问题,重用索引和为每个翻译单元创建新索引之间是否有任何有意义的区别?

4

1 回答 1

6

一种方法是从项目中的共享标头创建预编译标头(PCH 文件)。

这些方面的东西似乎有效(您可以在此处查看整个示例):

  auto Idx = clang_createIndex (0, 0);
  CXTranslationUnit TU;
  Timer t;

  {
    char const *args[] = { "-xc++", "foo.hxx" };
    int nargs = 2;

    t.reset();
    TU = clang_parseTranslationUnit(Idx, 0, args, nargs, 0, 0, CXTranslationUnit_ForSerialization);
    std::cerr << "PCH parse time: " << t.get() << std::endl;
    displayDiagnostics (TU);
    clang_saveTranslationUnit (TU, "foo.pch", clang_defaultSaveOptions(TU));
    clang_disposeTranslationUnit (TU);
  }

  {
    char const *args[] = { "-include-pch", "foo.pch", "foo.cxx" };
    int nargs = 3;

    t.reset();
    TU = clang_createTranslationUnitFromSourceFile(Idx, 0, nargs, args, 0, 0);
    std::cerr << "foo.cxx parse time: " << t.get() << std::endl;
    displayDiagnostics (TU);
    clang_disposeTranslationUnit (TU);
  }

  {
    char const *args[] = { "-include-pch", "foo.pch", "foo2.cxx" };
    int nargs = 3;

    t.reset();
    TU = clang_createTranslationUnitFromSourceFile(Idx, 0, nargs, args, 0, 0);
    std::cerr << "foo2.cxx parse time: " << t.get() << std::endl;
    displayDiagnostics (TU);
    clang_disposeTranslationUnit (TU);
  }

产生以下输出:

PCH parse time: 5.35074
0 diagnostics

foo1.cxx parse time: 0.158232
0 diagnostics

foo2.cxx parse time: 0.143654
0 diagnostics

我在 API 文档中没有找到太多关于 libclang 和预编译头的信息,但是这里有几个页面出现了关键字:CINDEXTRANSLATION_UNIT

请注意,这个解决方案无论如何都不是最优的。我期待看到更好的答案。尤其:

  1. 每个源文件最多可以有一个预编译头文件
  2. 这里没有什么是libclang特定的;clang这与使用标准命令行进行构建时间优化的策略完全相同。
  3. 它并不是真正自动化的,因为您必须显式创建预编译头文件(因此必须知道共享头文件的名称)
  4. 我认为在这里使用不同的 CXIndex 对象不会有任何不同
于 2014-01-06T14:54:42.997 回答