3

我正在使用最新的 LibClang 来解析一些 C 头文件。我处理的代码来自 CXUnsavedFile(它都是动态生成的,磁盘上没有任何内容)。例如:

FileA.h 包含:

struct STRUCT_A {
  int a;
  struct STRUCT_B foo;
};

FileB.h 包含:

struct STRUCT_B {
  int b;
};

使用以下代码片段解析 fileA.h 时:

CXUnsavedFile unsaved_files[2];

unsaved_files[0].Filename = "fileA.h";
unsaved_files[0].Contents = fileA_contents;
unsaved_files[0].Length   = strlen( fileA_contents );

unsaved_files[1].Filename = "fileB.h";
unsaved_files[1].Contents = fileB_contents;
unsaved_files[1].Length   = strlen( fileB_contents );

tu = clang_parseTranslationUnit(
    index,
    "fileA.h",
    argv, // "-x c-header -target i386-pc-win32"
    argc,
    (CXUnsavedFile *)&unsaved_files,
    2,
    CXTranslationUnit_None
);

CXCursor cur = clang_getTranslationUnitCursor( tu );

clang_visitChildren( cur, visitor, NULL );

我收到错误“ field has incomplete type 'struct STRUCT_B'”,这是有道理的,因为我没有包含 fileB.h 来定义结构 STRUCT_B。

添加“#include <fileB.h>”不起作用(fatal error: 'fileB.h' file not found)。

当另一个 CXUnsavedFile fileB.h 中存在一个或多个需要的定义时,如何让解析 fileA.h 工作?

4

1 回答 1

4

不确定这会对您有所帮助,但这里有两点说明:

  1. 尽管文档中没有明确提及,但我认为该Filename字段应该包含文件的完整路径(这对于包含可能很重要,尤其是当命令行中有“-I”开关时)

  2. 来自libclang 的文档(重点是我的):

    const char* CXUnsavedFile::Filename


    内容尚未保存的文件。 该文件必须已经存在于文件系统中。

    我怀疑libclang几乎所有事情都依赖文件系统(找到要包含的正确文件,检查它是否存在,......)并且只CXUnsavedFile在最后一步考虑 s ,此时必须读取实际内容。

如果可以的话,我建议在内存文件系统中创建空文件。这不会导致过多的资源使用,并且可以帮助libclang找到正确的包含文件。

于 2013-10-30T22:34:24.150 回答