Clang плагин: изменить AST во время компиляции

Я разрабатываю плагин clang для вывода строк журнала (чтобы уменьшить двоичный размер для встроенного проекта), который должен модифицировать AST (то есть после препроцессора, перед компиляцией).

В настоящее время я успешно могу сопоставить узлы, которые я хочу заменить (используя RecursiveASTVisitor<T>) и правильно извлекать данные, необходимые для построения замены.

в VisitStmt метод моего посетителя, я перебираю дочерние узлы, и при поиске совпадения я пытаюсь заменить совпадающие узлы выражения (CallExpr, возвращая int) с новым узлом (IntegerLiteral) присваивая через итератор:


*it = clang::IntegerLiteral::Create(context, { 32, value, false }, context.IntTy, old->getLocStart()).

Однако, когда я пытаюсь скомпилировать пример программы, используя мой плагин, clang возвращает код состояния успеха, но объектный файл не создается:

$ clang -std=c11 -Xclang -load -Xclang /tmp/plugin.so -Xclang -plugin -Xclang string-externalise -Xclang -plugin-arg-string-externalise -Xclang -lut-file=lut.txt -c -o example.o example.c

$ echo $?
0

$ stat example.o
stat: cannot stat 'example.o': No such file or directory

Если я пытаюсь сбросить AST, чтобы убедиться, что я изменил его правильно, то clang также не выдаст вывод. Но если я отключу свой плагин (удаляю все аргументы clang, относящиеся к нему), тогда я могу сбросить (оригинальный, неизмененный) AST.

Конкретные модификации AST, которые я пытаюсь сделать, — это замена вызовов функции-заполнителя (возвращающей int) на целочисленные литералы (значение определяется плагином).

Например, заменив это CallExpr поддерево с IntegerLiteral:

| |-CallExpr 0x556d460b3ab8 <line:7:42, col:78> 'int'
| | |-ImplicitCastExpr 0x556d460b3aa0 <col:42> 'int (*)(const char *, int)' <FunctionToPointerDecay>
| | | `-DeclRefExpr 0x556d460b3a20 <col:42> 'int (const char *, int)' Function 0x556d460b22d8 '__externalise_location' 'int (const char *, int)'
| | |-ImplicitCastExpr 0x556d460b3b08 <<scratch space>:26:1> 'const char *' <BitCast>
| | | `-ImplicitCastExpr 0x556d460b3af0 <col:1> 'char *' <ArrayToPointerDecay>
| | |   `-StringLiteral 0x556d460b3a48 <col:1> 'char [10]' lvalue "example.c"| | `-IntegerLiteral 0x556d460b3a80 <line:27:1> 'int' 22

Или заменить это CallExpr поддерево с IntegerLiteral:

| |-CallExpr 0x556d460b3b98 <example.c:6:26, col:46> 'int'
| | |-ImplicitCastExpr 0x556d460b3b80 <col:26> 'int (*)(const char *)' <FunctionToPointerDecay>
| | | `-DeclRefExpr 0x556d460b3b20 <col:26> 'int (const char *)' Function 0x556d460b20c0 '__externalise' 'int (const char *)'
| | `-ImplicitCastExpr 0x556d460b3be0 <line:22:6> 'const char *' <BitCast>
| |   `-ImplicitCastExpr 0x556d460b3bc8 <col:6> 'char *' <ArrayToPointerDecay>
| |     `-StringLiteral 0x556d460b3b48 <col:6> 'char [10]' lvalue "hello %s\n"

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector