Показаны сообщения с ярлыком clang. Показать все сообщения
Показаны сообщения с ярлыком clang. Показать все сообщения

21 марта 2016 г.

CLang API: связь с реальным миром (clang-3.7)

Попробуем теперь использовать получившуюся программу рисования диаграммы наследования с реальным кодом, т.е. взятым из реального мира. Вопрос в том, какой именно код взять? Лучший кандидат для проверки - наша программа рисования, testclang.cpp! Что может быть реальнее? :)

10 февраля 2016 г.

CLang API: рисуем диаграмму наследования (clang-3.7)

Попробуем использовать CLang API для чего-нибудь полезного, например, для рисования диаграммы наследования.

В Clang API уже есть подобный функционал - функция CXXRecordDecl::viewInheritance(). Функция viewInheritance рисует диаграмму наследования для заданного класса используя библиотеку GraphViz. Но делает она это не совсем так, как мне бы хотелось. Поэтому я попробую написать свою собственную процедуру рисования диаграммы наследования, используя программу dot из пакета GraphViz.

3 февраля 2016 г.

CLang API: обход AST (clang-3.7)

Попробуем теперь реализовать обход AST встроенными методами (по мотивам статьи "How to write RecursiveASTVisitor based ASTFrontendActions"). На мой взгляд, реализация этой задачи стала намного проще по сравнению с версией 2.8.

20 января 2016 г.

CLang API: минимальный проект (clang-3.7)

После долгого перерыва я решил вернуться к попыткам использования clang API по нескольким причинам. Во-первых, clang API за это время продвинулся довольно далеко и стал "мощнее", так что хочется попробовать новые версии. Во-вторых, в старых статьях используется более ранние версии clang, а мне регулярно задают вопросы типа "почему у меня не компилируется/линкуется", поэтому хочется и обновить свои знания и добавить статьям актуальности. В-третьих, за пять лет внятных примеров с использованием clang так и не появилось, надо исправить такую несправедливость. Ну и в конце концов меня не оставляет надежда реализовать одну идею со статическим анализом кода, о которой, может быть, напишу позже.

Итак, попробуем написать и собрать минимальный проект для clang API на платформе Linux, используя последнюю стабильную версию llvm и clang. На момент написания статьи это версия 3.7.0.

6 декабря 2010 г.

Clang API: обход AST (clang-2.8)

В прошлом посте про Clang мы получали абстрактное синтаксическое дерево в виде XML. Теперь попробуем выполнить обход AST вручную. Вручную — это значит создать и инициализировать в программе экземпляры классов, необходимых для анализа исходного файла, построить дерево и получить в коде программы доступ к каждому узлу по очереди, чтобы сотворить с узлами какое-нибудь действо.

26 ноября 2010 г.

Clang API: получение AST в виде XML


Задача: с помощью Clang API получить XML-файл, описывающий абстрактное синтаксическое дерево (AST) исходного кода. Это можно сделать и простым запуском команды clang с параметром -ast-print-xml в командной строке, но через API — интереснее :)

22 ноября 2010 г.

Проблемы линковки библиотек clang и llvm

При линковке приложения с библиотеками clang и llvm может возникнуть такая проблема, что нужно передавать линковщику список библиотек в строгом порядке, иначе может возникнуть ошибка "undefined reference" даже если нужная библиотека указана в параметрах линковки. (Как здесь, например. Правда, там у человека еще и строка линковки некорректна.)

Пример:

$ g++ -o ./a.out main.o `llvm-config --ldflags` -lclangFrontend -lclangBasic -lclangDriver -lclangSerialization -lclangCodeGen -lclangSema -lclangChecker -lclangAnalysis -lclangIndex -lclangRewrite -lclangAST -lclangParse -lclangLex `llvm-config --libs`

libclangParse.a(Parser.o): In function `clang::Parser::ExpectAndConsume(clang::tok::TokenKind, unsigned int, char const*, clang::tok::TokenKind)':
Parser.cpp:151: undefined reference to `clang::tok::getTokenSimpleSpelling(clang::tok::TokenKind)'
libclangLex.a(Preprocessor.o): In function `clang::Preprocessor::DumpToken(clang::Token const&, bool) const':
Preprocessor.cpp:155: undefined reference to `clang::tok::getTokenName(clang::tok::TokenKind)'
collect2: ld returned 1 exit status



Все нужные библиотеки указаны, но не в том порядке, в каком хотелось бы линковщику. Проблема в том, что линковщик ищет в каждой библиотеке по одному разу и именно в том порядке, в каком они указаны в командной строке. Например, символ clang::tok::getTokenName находится в библиотеке libclangBasic.a, которая в списке линковки указана раньше.

Можно попытаться поискать правильный порядок (долгая и неблагодарная работа), а можно воспользоваться возможностью группировки библиотек:

$ g++ -o ./a.out ../build/obj/testclang.o `llvm-config --ldflags` -lgtest -lgtest_main -Wl,--start-group -lclangFrontend -lclangBasic -lclangDriver -lclangSerialization -lclangCodeGen -lclangSema -lclangChecker -lclangAnalysis -lclangIndex -lclangRewrite -lclangAST -lclangParse -lclangLex `llvm-config --libs` -Wl,--end-group

Линковщик будет перебирать библиотеки, указанные между ключами --start-group и --end-group снова и снова, пока не отыщет все требуемые символы.

Теперь всё ОК.

9 ноября 2010 г.

g++ 4.5 и clang

В Ubuntu 10.10 уже входит gcc 4.5, и я вчера решил собрать clang из репозитория. Всё было хорошо, пока процесс линковки не сожрал полтора гигабайта памяти. После этого он был торжественно убит системой, потому что у меня для виртуалки выделено всего полтора гигабайта. Попробовал собрать с gcc 4.4 — собрался без проблем.

Жаль, но gcc 4.5 всё-таки еще сыроват.

UPD: Смог добиться того, чтобы gcc 4.4 тоже сожрал больше 1,5 Гб. Для этого нужно включить дебаг-режим, включить ассерты и expensive checks, и выключить оптимизатор. Но это, конечно, извращение.

Еще жаль, что clang нельзя собрать без сборки llvm. Или я чего-то не знаю?