#clang #llvm #llvm-c -api
#clang #llvm #llvm-c -api
Вопрос:
Я пытаюсь написать внешний модификатор AST Clang, который переводит определения анонимных структур и объединений в другую форму. Например, у меня есть:
typedef struct test_case_t {
struct {
int value;
} first[1];
int second;
int third[1];
} test_case_t;
Я хотел бы преобразовать это в:
struct test_case_t {
struct first{
int value;
};
struct first first[1];
int second;
int third[1];
};
typedef struct test_case_t test_case_t;
Однако преобразование, похоже, отбрасывает struct first
объявление, так что это то, что я получаю вместо этого:
struct test_case_t {
struct{ // this should be "struct first"
int value;
};
struct first first[1];
int second;
int third[1];
};
typedef struct test_case_t test_case_t;
Как мне изменить определение структуры на месте и добавить имя first
объявления? У меня есть определение RecordDecl
первой переменной, но, похоже, я не могу понять, как преобразовать определение структуры.
Комментарии:
1. это помогло бы людям понять и ответить, если вы также покажете свой «внешний модификатор AST Clang».
Ответ №1:
В конечном счете, это довольно интересная особенность AST Clang. При представлении вложенных наборов структур и объединений вложенные объявления и определения разделяются на уникальные FieldDecls
. Сначала лексически анализируется объявление структуры, затем анализируется определение переменной. Для этого необходимо сохранить ссылку на объявление структуры / объединения и сопоставить ее с последующими определениями переменных. Этот процесс может быть довольно сложным, но имитирует следующее. В частности, мы ищем объявления структур, которые соответствуют не isFreeStanding()
for(RecordDecl::decl_iterator iter = RD->decls_begin(), end =
RD->decls_end(); iter != end; iter) {
Decl *StructDecl = nullptr;
if(FieldDecl *FD = dyn_cast_or_null<FieldDecl>(*iter)) {
// create new FD
if(const ElaboratedType * NET =
dyn_cast<ElaboratedType>(SemaRef.Context.getBaseElementType(NewFD->getType())))
{
if( StructDecl ){
RecordDecl *MyDecl = dyn_cast<RecordDecl>(StructDecl);
if( MyDecl )
MyDecl->setDeclName(FD->getDeclName());
}
}
}
}else if(TagDecl *TD = dyn_cast<TagDecl>(*iter)){
if(TD->isThisDeclarationADefinition() amp;amp; !TD->isFreeStanding()){
// save StructDecl
}
}
}