LibClang: проанализировать файл заголовка с определениями из другого файла заголовка?
Я использую последний LibClang для анализа некоторых заголовочных файлов C. Код, который я обрабатываю, взят из CXUnsavedFile (он все генерируется динамически, и на диске ничего нет). Например:
FileA.h содержит:
struct STRUCT_A {
int a;
struct STRUCT_B foo;
};
FileB.h содержит:
struct STRUCT_B {
int b;
};
При разборе файла A.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 STRUCT_B.
Добавление "#include fatal error: 'fileB.h' file not found
).
Как заставить синтаксический анализ fileA.h работать, когда одно или несколько необходимых определений присутствуют в другом файле CXUnsavedFileB.h?
1 ответ
Не уверен, что это поможет вам, но вот два замечания:
Хотя это явно не упоминается в документации, я думаю, что
Filename
поле должно содержать полный путь к файлу (что может быть важно для включений, особенно когда в командной строке есть ключи "-I")из документации libclang (выделено мое):
const char* CXUnsavedFile::Filename
Файл, содержимое которого еще не сохранено. Этот файл уже должен существовать в файловой системе.
Я подозреваю
libclang
полагается на файловую систему практически во всем (поиск нужного файла, проверка его существования, ...) и только учетCXUnsavedFile
s на последнем шаге, когда фактический контент должен быть прочитан.
Если вы можете, я бы предложил создать пустые файлы в файловой системе памяти. Это не потребует большого количества ресурсов и может помочь libclang
найти правильные включаемые файлы.