Reputation: 810
For example, I have a class:
template<typename T>
class Foo {
public:
T getBar();
private:
T bar_;
};
It is instantiated with:
using FooBarT = Foo<Bar>;
How do I get the CXXRecordDecl
with resolved fields and methods for Foo<bar>
?
I tried:
const auto *typeAliasDecl = llvm::dyn_cast<clang::TypeAliasDecl>(decl);
typeAliasDecl->getUnderlyingType()->getAsCXXRecordDecl()->dump();
The output I get is:
ClassTemplateSpecializationDecl 0x0000000 class Foo
`-TemplateArgument type 'Bar'
However, I want the CXXRecordDecl
with the fields and methods too so I can iterate through them. I've also tried:
for (const auto *contextDecl: typeAliasDecl->getUnderlyingType()->getUnqualifiedDesugaredType()->getAsCXXRecordDecl()->getDeclContext()->decls()) {
const auto *classTemplateDecl = llvm::dyn_cast<clang::ClassTemplateDecl>(contextDecl);
classTemplateDecl->dump();
}
The output:
ClassTemplateDecl Foo
|-TemplateTypeParmDecl 0x0000000 referenced typename depth 0 index 0 T
|-CXXRecordDecl class Foo definition
| ...
| |-FieldDecl 0x0000000 referenced bar_ 'T'
|-ClassTemplateSpecializationDecl 0x0000000 class Foo
`-TemplateArgument type 'Bar'
As you can see the CXXRecordDecl class Foo definition
has access to the FieldDecl
, but doesn't know about the type instantiation of bar_
, while the ClassTemplateSpecializationDecl
does.
I want the CXXRecordDecl
with the instantiated type for FieldDecl bar_
Upvotes: 3
Views: 1564
Reputation: 1785
FYI the CXXRecordDecl you wanted is just the ClassTemplateSpecializationDecl in the AST, since ClassTemplateSpecializationDecl is a subclass of CXXRecordDecl. The real thing you want is not the CXXRecordDecl which you already have, but is the FieldDecl in that CXXRecordDecl.
The reason that you don't have FieldDecl under the ClassTemplateSpecializationDecl is that your template instantiation code doesn't use bar_. Try the bellow source:
template<typename T>
class Foo {
public:
T getBar() { return bar_; };
private:
T bar_;
};
using FooBarT = Foo<int>;
void func() {
FooBarT().getBar();
}
Then FieldDecl will be under ClassTemplateSpecializationDecl :
| `-ClassTemplateSpecializationDecl 0x1fe7f2a9d80 <line:2:1, line:9:1> line:3:7 class Foo definition
...
| |-FieldDecl 0x1fe7f2aa3c8 <line:8:2, col:4> col:4 referenced bar_ 'int':'int'
Upvotes: 2
Reputation: 559
This worked for me:
ClassTemplateSpecializationDecl
to DeclContext
,DeclContext::decls()
,dyn_cast
iterated Decl
s to FieldDecl
and getType()
- this will be an instantiated type of a member variable.dyn_cast
to CXXMethodDecl
for member functions and continue similarly - I haven't
got to trying it for myself.All this I learned by stepping through and studying how ASTDumper
works.
Upvotes: 1