В LibClang AST отсутствуют узлы в результате расширения макроса? - PullRequest
0 голосов
/ 14 февраля 2019

Я пытаюсь получить полный 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(...) не посещает эти поддеревья?

...