Подтвердить что ты не робот

Как я могу анализировать макросы в коде С++, используя CLANG в качестве синтаксического анализатора и Python в качестве языка сценариев?

Если у меня есть следующий макрос в некотором коде С++:

_Foo(arg1, arg2)

Я хотел бы использовать Python, чтобы найти все экземпляры и экстенты этого макроса, используя привязки Clang и Python, снабженные cindex.py. Я не хочу использовать регулярное выражение из Python в коде напрямую, потому что это дает мне 99% пути, но не 100%. Мне кажется, что, чтобы добраться до 100%, вам нужно использовать настоящий парсер С++, такой как Clang, для обработки всех случаев, когда люди делают глупые вещи, которые синтаксически правильны и компилируются, но не имеют смысла для регулярного выражения. Мне нужно обрабатывать 100% случаев, и поскольку мы используем Clang как один из наших компиляторов, имеет смысл использовать его в качестве анализатора для этой задачи.

Учитывая следующий код Python, я могу найти то, что представляется предопределенными типами, о которых знают привязки python Clang, но не макросы:

def find_typerefs(node):
    ref_node = clang.cindex.Cursor_ref(node)
    if ref_node:
        print 'Found %s Type %s DATA %s Extent %s [line=%s, col=%s]' % (
            ref_node.spelling, ref_node.kind, node.data, node.extent, node.location.line, node.location.column)

# Recurse for children of this node
for c in node.get_children():
    find_typerefs(c)

index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1])
find_typerefs(tu.cursor)

То, что я думаю, что я ищу, - это способ разобрать исходный AST для имени моего макроса _FOO(), но я не уверен. Может ли кто-нибудь предоставить некоторый код, который позволит мне передать имя макроса и вернуть объем или данные из Clang?

4b9b3361

Ответ 1

Вам необходимо передать соответствующий флаг options в Index.parse:

tu = index.parse(sys.argv[1], options=clang.cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD)

Остальная часть посетителя курсора может выглядеть так:

def visit(node):
    if node.kind in (clang.cindex.CursorKind.MACRO_INSTANTIATION, clang.cindex.CursorKind.MACRO_DEFINITION):
        print 'Found %s Type %s DATA %s Extent %s [line=%s, col=%s]' % (node.displayname, node.kind, node.data, node.extent, node.location.line, node.location.column)
    for c in node.get_children():
        visit(c)

Ответ 2

Я как-то написал script, чтобы отпечатать весь АСТ, который вы получаете от libclang, чтобы узнать, где найти информацию.

Вот он: https://gist.github.com/2503232