Я пытаюсь просмотреть объявления в заголовочном файле с помощью API RecursiveASTVisitor из LibTooling Clang.
Мой заголовочный файл выглядит следующим образом:
template< typename T >
struct Node
{
Node< T > * next;
};
struct IntList
{
Node< int > * head;
};
Мой RecursiveASTVisitor выглядит такthis:
class MyASTVisitor : public RecursiveASTVisitor< MyASTVisitor >
{
public:
bool VisitCXXRecordDecl( CXXRecordDecl * decl )
{
llvm::errs( ) << "---------------------------------\n";
decl->dump( );
return true;
}
bool VisitClassTemplateDecl( ClassTemplateDecl * decl )
{
for( auto const * spec : decl->specializations( ) )
{
llvm::errs( ) << "---------------------------------\n";
spec->dump( );
for( auto const * field : spec->fields( ) )
{
llvm::errs( ) << "field: " << field->getNameAsString( ) << "\n";
}
}
return true;
}
};
Вывод выглядит следующим образом:
---------------------------------
ClassTemplateSpecializationDecl 0x7fcab004f9e8 </Users/george/dev/Test0.hpp:3:1, line:7:1> line:4:8 struct Node
`-TemplateArgument type 'int'
---------------------------------
CXXRecordDecl 0x7fcab004f360 </Users/george/dev/Test0.hpp:4:1, line:7:1> line:4:8 struct Node definition
|-DefinitionData aggregate standard_layout trivially_copyable pod trivial
| |-DefaultConstructor exists trivial needs_implicit
| |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
| |-MoveConstructor exists simple trivial needs_implicit
| |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
| |-MoveAssignment exists simple trivial needs_implicit
| `-Destructor simple irrelevant trivial needs_implicit
|-CXXRecordDecl 0x7fcab004f630 <col:1, col:8> col:8 implicit struct Node
`-FieldDecl 0x7fcab004f7d0 <line:6:3, col:18> col:18 next 'Node<Data> *'
---------------------------------
CXXRecordDecl 0x7fcab004f830 </Users/george/dev/Test0.hpp:9:1, line:12:1> line:9:8 struct List definition
|-DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
| |-DefaultConstructor exists trivial needs_implicit
| |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
| |-MoveConstructor exists simple trivial needs_implicit
| |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
| |-MoveAssignment exists simple trivial needs_implicit
| `-Destructor simple irrelevant trivial needs_implicit
|-CXXRecordDecl 0x7fcab004f948 <col:1, col:8> col:8 implicit struct List
`-FieldDecl 0x7fcab004fbe0 <line:11:3, col:17> col:17 head 'Node<int> *'
Поскольку головной элемент Node является указателем на себя, ClassTemplateSpecializationDecl для Node не имеет никаких определенных полей. Есть ли способ принудительно создать экземпляр шаблона Node для int, чтобы перебирать его поля и получать доступ ко всем типам полей?
По сути, мне просто нужно сделать что-то вроде этого:
for( auto const * spec : decl->specializations( ) )
{
llvm::errs( ) << "---------------------------------\n";
spec->dump( );
for( auto const * field : spec->fields( ) )
{
processField( field->getNameAsString( ), field->getType( ) );
}
}
Есть ли способ сделать это без ручного сопоставления параметров создания шаблона (из VisitClassTemplateDecl) с объявлениями шаблона (из VisitCXXRecordDecl) для типов, которые содержат элементы с указателями на себя?