#c #c #refactoring #llvm-clang
#c #c #рефакторинг #llvm-clang
Вопрос:
Я делаю небольшой инструмент для рефакторинга, который поможет мне в некоторой автоматической генерации кода на C, и для этого я использую clang API. Я разработал инструмент, который работает со всеми, кроме одного конкретного тестового примера:
typedef int mytype;
typedef float mytype2;
union ab
{
mytype a;
mytype2 b;
};
int fun(int);
int foo(mytype bar)
{
return fun( ((union{ mytype a; mytype2 b; })bar).a );
}
В этом коде я хочу преобразовать вхождения «mytype» в новый «mytype3», для этого я создаю сопоставитель TypeLoc AST ( typeLoc().bind(«id»)), чтобы найти все типы и заменить их инструментом рефакторинга (стандартная процедура рефакторинга, встречающаяся повсюдув Интернете). Но для этого конкретного случая AST, похоже, не содержит определения для анонимного объединения, используемого для выполнения кастинга, я сбросил AST с помощью XClang:
`-FunctionDecl 0x6b757f0 <line:12:1, line:15:1> line:12:5 foo 'int (mytype)'
|-ParmVarDecl 0x6b75730 <col:9, col:16> col:16 bar 'mytype':'int'
`-CompoundStmt 0x6b75bb0 <line:13:1, line:15:1>
`-ReturnStmt 0x6b75b90 <line:14:2, col:53>
`-CallExpr 0x6b75b60 <col:9, col:53> 'int'
|-ImplicitCastExpr 0x6b75b48 <col:9> 'int (*)(int)' <FunctionToPointerDecay>
| `-DeclRefExpr 0x6b75898 <col:9> 'int (int)' Function 0x6b2f790 'fun' 'int (int)'
`-MemberExpr 0x6b75af0 <col:14, col:51> 'mytype':'int' .a 0x6b75970
`-ParenExpr 0x6b75ad0 <col:14, col:49> 'union (anonymous union at unions.c:14:16)':'union (anonymous at unions.c:14:16)'
`-CStyleCastExpr 0x6b75aa8 <col:15, col:46> 'union (anonymous union at unions.c:14:16)':'union (anonymous at unions.c:14:16)' <ToUnion>
`-ImplicitCastExpr 0x6b75a90 <col:46> 'mytype':'int' <LValueToRValue>
`-DeclRefExpr 0x6b75a18 <col:46> 'mytype':'int' lvalue ParmVar 0x6b75730 'bar' 'mytype':'int'
И на самом деле, похоже, что он полностью игнорирует тело объединения. Итак, есть ли решение этой «проблемы» или, по крайней мере, альтернатива для этого рефакторинга?
В качестве альтернативы я попытался перечислить поля анонимного объединения из объекта RecordDecl, но не смог найти, как это сделать.
Спасибо.