clang libTooling: Как узнать, из какого заголовка вышел элемент AST?
Примеры, найденные в Интернете для инструментов clang, всегда выполняются на игрушечных примерах, которые обычно являются действительно тривиальными программами на Си.
Я создаю инструмент, который выполняет преобразования исходного кода в код C++, что, очевидно, является очень, очень сложной задачей, но Clang справляется с этой задачей.
Проблема, с которой я сейчас сталкиваюсь, заключается в том, что AST, который генерирует clang для любого кода C++, использующего STL, огромен. Например, у меня есть код C++, для которого clang++ -ast-dump ... | wc -l
67 018 строк ужасающего гобелена AST!
99% это стандартные библиотечные вещи, которые я стараюсь игнорировать в своей задаче метапрограммирования от источника к источнику. Итак, для достижения этого я хочу просто отфильтровать файлы. Предположим, что я хочу посмотреть только определения классов в заголовках проекта, который я анализирую (и игнорирую все содержимое стандартных библиотечных заголовков), мне нужно просто выяснить, какой заголовок каждого из моих CXXRecordDecl
пришло!
Можно ли это сделать?
Редактировать: Надеюсь, что это способ сделать это. Попробуем это сейчас... Важным моментом является то, что он должен сообщить мне заголовок, из которого вышел decls, а не файл cpp, соответствующий единице перевода.
2 ответа
По моему опыту, "источник" некоторого данного узла AST лучше всего получать с помощью Locations. Например, каждый узел, по крайней мере, имеет начальное местоположение, и когда вы его распечатаете, он будет содержать путь к файлу заголовка.
Затем можно использовать этот путь, чтобы решить, является ли это системная библиотека или часть кода вашего приложения, которую вы все еще хотите исследовать.
Один из маршрутов, на который я смотрю, - это узкие спички с такими вещами, как hasName()
(как найдено здесь. Например:
recordDecl(hasName("MyBaseClass")) // etc.
Однако ваш комментарий выше, используя -ast-dump
это то, что я тоже пытался найти в своем собственном инструменте CLang. Я нашел этот пост очень полезным. Вооружившись их предложением, я использовал clang-check
отфильтровать по определенному имени класса и передать его мой CPP-файл верхнего уровня. Результатом было намного более управляемые несколько сотен строк, представляющих объявления классов и определения интереса.