libclang clang_getSpellingLocation нарушение прав доступа

Я пытаюсь запустить учебник по библиотеке libclang, но при вызове функции получаю нарушение прав доступа clang_getSpellingLocation(), Другая информация об ошибке сообщается правильно с количеством ошибок, строкой и столбцом.

Моя среда: C ++ Builder XE pro, Windows 7 32bit, LLVM 3.4, libCLang.lib преобразован
используя coff2omf, libCLang.dll.

Я тестировал тот же код на Visual C ++ 2010, и он работает правильно.

Пожалуйста, кто-нибудь может мне помочь с этим вопросом?

Мой простой код

//---------------------------------------------------------------------------
void __fastcall TForm8::Button1Click(TObject *Sender)
{

unsigned line, column;
CXIndex index = clang_createIndex(0, 0);

const  char  * args []  =  {
"-I/usr/include" ,
"-I."};

int  numArgs  =  sizeof ( args )  /  sizeof ( * args );

CXTranslationUnit tu = clang_parseTranslationUnit(index, "G:\\projects\\LibCLang  \\File2.cpp", args, numArgs, NULL, 0, CXTranslationUnit_None);

unsigned  diagnosticCount  =  clang_getNumDiagnostics ( tu );

for ( unsigned  i  =  0 ;  i  <  diagnosticCount ;  i++ )
{
CXDiagnostic  diagnostic   =  clang_getDiagnostic ( tu ,  i );
CXSourceLocation location = clang_getDiagnosticLocation(diagnostic);
clang_getSpellingLocation(location, NULL, &line, &column, NULL);
CXString text = clang_getDiagnosticSpelling(diagnostic);
UnicodeString s = clang_getCString(text);
}
}

0

Решение

Вы уверены, что AV включен clang_getSpellingLocation() и не clang_getDiagnosticSpelling()?

При использовании __cdecl Соглашение о вызовах, компиляторы от разных поставщиков могут делать все, что они хотят, когда дело доходит до возврата структуры по значению, когда размер структуры <= 8 байт. В случае clang_getDiagnosticSpelling(), CXString 8 байтов в 32-битной среде. Некоторые компиляторы, такие как Visual C ++, возвращают содержимое 8-байтовой структуры непосредственно в EAX:EDX Регистры ЦП, тогда как другие компиляторы, такие как C ++ Builder, используют скрытый выходной параметр, который передает ссылку на временную структуру.

clang_getDiagnosticSpelling() (и другие подобные функции) возвращают CXString с помощью EAX:EDX, но C ++ Builder вместо этого использует скрытый параметр. Для этого есть простой обходной путь. C ++ Builder ожидает __cdecl функция для возврата __int64 с помощью EAX:EDX, и с тех пор CXString а также __int64 одинакового размера в 32 бита, вы можете сделать следующее:

typedef __int64 __cdecl (*clang_getDiagnosticSpellingHack)(CXDiagnostic);

//CXString text = clang_getDiagnosticSpelling(diagnostic);
clang_getDiagnosticSpellingHack func = reinterpret_cast<clang_getDiagnosticSpellingHack>(&clang_getDiagnosticSpelling);
__int64 tmp = func(diagnostic);
CXString text = reinterpret_cast<CXString&>(tmp);

Кроме того, вы можете использовать C ++ Builder _EAX а также _EDX : встроенные функции

typedef void __cdecl (*clang_getDiagnosticSpellingHack)(CXDiagnostic);

//CXString text = clang_getDiagnosticSpelling(diagnostic);
clang_getDiagnosticSpellingHack func = reinterpret_cast<clang_getDiagnosticSpellingHack>(&clang_getDiagnosticSpelling);
CXString text;
func(diagnostic);
text.ptr_data = (void*) _EAX;
text.int_data = _EDX;

Что касается clang_getSpellingLocation()Я бы не ожидал, что в соглашениях будет такое несоответствие, поскольку оно не имеет возвращаемого значения, если только clang_getSpellingLocation() были скомпилированы, чтобы принять его CXSourceLocation параметр отличается от того, как C ++ Builder передает его. C ++ Builder отправляет все три значения данных из CXSourceLocation прямо на стек вызовов. Вам придется посмотреть на разборку clang_getSpellingLocation() чтобы увидеть, как это на самом деле доступ к значениям его CXSourceLocation параметра, а затем при необходимости скорректируйте код C ++ Builder соответствующим образом.

Вы должны также дважды проверить, как clang_getDiagnosticLocation() возвращает свое CXSourceLocation чтобы убедиться, что он соответствует тому, как C ++ Builder ожидает его возврата (через скрытый выходной параметр по ссылке), чтобы гарантировать, что память не будет повреждена до clang_getSpellingLocation() называется Так что возможно, что clang_getSpellingLocation() сам не может быть виновником. Трудно сказать, не видя разборки для обоих clang_getDiagnosticLocation() а также clang_getSpellingLocation() (Я видел разборку для функций, которые возвращают CXStringВот так я точно знаю, что Clang использует EAX:EDX для этого).

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]