2016-05-16 5 views
1

Я пишу скрипт для обнаружения ошибок форматирования в моем коде на C++. (например, убедитесь, что все переменные-члены имеют префикс m_). Одна из вещей, которую я хочу сделать, - убедиться, что типы указателей имеют астерикс, прикрепленный к типу (int* num, а не int *num).Получить фактическое написание курсора lib clang/type

Так что мне нужно получить текст типа, как в исходном коде. Однако получение орфографии курсора или типа возвращает довольно печатную версию, она всегда будет возвращать int *, даже если источник имеет int*.

Чтобы обойти это, я получаю размер курсора и получаю подстроку из исходного файла и проверяю это. Однако, похоже, нет способа получить размер типа, и поэтому я не могу получить фактическое правописание? Есть ли способ сделать это? возможно, получив маркеры этого типа, а затем получив их размеры?

(Я использую питон привязки, но могу переключиться на API C при необходимости)

ответ

0

Вы могли бы попробовать что-то вроде этого. Получить орфографию:

std::string symbol = clang_getCString(clang_getCursorSpelling(Cursor)); 

Посмотрите на указатель описателя:

case CXType_Pointer: 
{ 
    // ... 
} 

Используйте clang_tokenize, а затем использовать их для поиска размещения в *.

// Tokens retrieved with clang_tokenize 
// symbol declared earlier 
auto finder = std::find(tokens.begin(), tokens.end(), symbol); 
if (*(finder) == "*") 
{ 
    if (*(finder + 1)) == " ") { /* ... */ } // int* asdf 
} else if (*(finder) == " ") { 
    if (*(finder + 1)) == "*") { /* ... */ } // int *asdf 
} 

Конечно, это псевдокод. Код не тронут руками компилятора.

+0

Я уверен, что жетоны не включают пробел. –

0

Libclang - отличный инструмент для поиска переменных-членов, которые соответствуют (или не соответствуют шаблону), но есть гораздо более простой способ решить проблему с точными указателями печати и ссылками в вашей кодовой базе, и это должно использовать clang-format, что это инструмент для форматирования кода C/C++/Java/JavaScript/Objective-C/Protobuf.

Clang-формат имеет огромное количество options, но тот, который, вероятно, наибольший интерес представляет PointerAlignment, который может иметь одно из следующих значений: влево, вправо или Посередине, который переформатирует указатели (и ссылки) соответственно.

Вы можете создать новый конфигурационный файл для лязгом-формате одного из инструментов онлайн или от встроенного стиля:

clang-format -style=llvm -dump-config > .clang-format 

Редактирование этого файла для установки PointerAlignment налево и бега:

clang-format main.cpp 

на "плохо" отформатированный кусок кода, как:

// main.cpp 
int main() 
{ 
    int a; 
    int* b; 
    int *c; 
    int& d; 
    int &d; 
    int * e; 
    const int * f; 
    const int * const g; 
    return 0; 
} 

I ге t:

// main.cpp 
int main() { 
    int a; 
    int* b; 
    int* c; 
    int& d; 
    int& d; 
    int* e; 
    const int* f; 
    const int* const g; 
    return 0; 
} 

Аналогичные результаты для других настроек.

Если вы действительно должны сделать это из кода, который вы можете использовать libformat, библиотеку, которая лежит в основе лязг-формат, или вы можете использовать вызвать лязг-формат from a subprocess, который, как и другие инструменты в звоне кодового сделать это.

+0

Я смотрел в формат clang, но, казалось, не было способа определить пользовательские правила. Я не смотрел на libformat, но с первого взгляда кажется, что он может только вызвать процесс форматирования, а не определять пользовательские правила. –

+0

Подумайте об этом в два этапа - на первом этапе вы можете использовать libclang или [clang replacementments] (https://github.com/eliben/llvm-clang-samples/blob/master/src_clang/matchers_replacements.cpp), чтобы найти (и, возможно, заменить переменные-члены), а затем исправить указатели/ссылки во втором проходе. –