Я пытаюсь получить полный AST с помощью LibClang.Используя следующий код в качестве рабочего примера:
foo.c
#define FOO 13u
#define BAR ((1u << FOO) - 1u)
int foo(unsigned int x) {
return (x > BAR);
}
Используя рекурсивный посетитель, я прохожу AST и выдает следующее:
foo.out
macro definition <"foo.c", 8, 15> FOO ''
macro definition <"foo.c", 24, 46> BAR ''
macro expansion <"foo.c", 88, 91> BAR ''
FunctionDecl <"foo.c", 48, 95> foo 'int (unsigned int)'
ParmDecl <"foo.c", 56, 70> x 'unsigned int'
CompoundStmt <"foo.c", 72, 95> ''
ReturnStmt <"foo.c", 76, 92> ''
ParenExpr <"foo.c", 83, 92> 'int'
BinaryOperator <"foo.c", 84, 91> 'int' '>'
UnexposedExpr <"foo.c", 84, 85> x 'unsigned int'
DeclRefExpr <"foo.c", 84, 85> x 'unsigned int'
Второй операнд для двоичного оператора >
отсутствует в результирующем обходе AST.Если я полностью предварительно обработаю foo.c, я получу ожидаемый AST.
bar.c
int foo(unsigned int x) {
return (x > ((1u << 13u) - 1u));
}
bar.out
FunctionDecl <"bar.c", 3, 65> foo 'int (unsigned int)'
ParmDecl <"bar.c", 11, 25> x 'unsigned int'
CompoundStmt <"bar.c", 27, 65> ''
ReturnStmt <"bar.c", 31, 62> ''
ParenExpr <"bar.c", 38, 62> 'int'
BinaryOperator <"bar.c", 39, 61> 'int' '>'
UnexposedExpr <"bar.c", 39, 40> x 'unsigned int'
DeclRefExpr <"bar.c", 39, 40> x 'unsigned int'
ParenExpr <"bar.c", 43, 61> 'unsigned int'
BinaryOperator <"bar.c", 44, 60> 'unsigned int' '-'
ParenExpr <"bar.c", 44, 55> 'unsigned int'
BinaryOperator <"bar.c", 45, 54> 'unsigned int' '<<'
IntegerLiteral <"bar.c", 45, 47> 'unsigned int' 1u
IntegerLiteral <"bar.c", 51, 54> 'unsigned int' 13u
IntegerLiteral <"bar.c", 58, 60> 'unsigned int' 1u
Однако, если яизменив foo.c таким образом, чтобы у двоичного оператора были макроподключения для обоих операндов, я получаю следующий вывод:
baz.c
#define FOO 13u
#define BAR ((1u << FOO) - 1u)
int foo(unsigned int x) {
return (FOO > BAR);
}
baz.out
macro definition <"baz.c", 8, 15> FOO ''
macro definition <"baz.c", 24, 46> BAR ''
macro expansion <"baz.c", 84, 87> FOO ''
macro expansion <"baz.c", 90, 93> BAR ''
FunctionDecl <"baz.c", 48, 97> foo 'int (unsigned int)'
ParmDecl <"baz.c", 56, 70> x 'unsigned int'
CompoundStmt <"baz.c", 72, 97> ''
ReturnStmt <"baz.c", 76, 94> ''
ParenExpr <"baz.c", 83, 94> 'int'
Теперь оба операнда и оператора отсутствуют в результирующем обходе AST.
Из-за неявного аргумента -fsyntax-only
для clang_parseTranslationUnit(...)
предварительная обработка должна быть выполнена в некоторомно пока я не вижу макрорасширенные поддеревья в обходе AST.
Вопрос: Где находятся макрорасширенные поддеревья AST?Или, скорее, почему clang_visitChildren(...)
не посещает эти поддеревья?