Clang LibTooling - Как я могу получить поля ClassTemplateSpecializationDecl для структуры «Node» с членом типа «Node *»? - PullRequest
0 голосов
/ 21 октября 2019

Я пытаюсь просмотреть объявления в заголовочном файле с помощью 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) для типов, которые содержат элементы с указателями на себя?

...