3

たとえば、次のクラスがあります。

template<typename T>
class Foo {
public:
    T getBar();

private:
    T bar_;
};

以下でインスタンス化されます。

using FooBarT = Foo<Bar>;

CXXRecordDeclの解決済みフィールドとメソッドを使用して を取得するにはどうすればよいFoo<bar>ですか?


私は試した:

const auto *typeAliasDecl = llvm::dyn_cast<clang::TypeAliasDecl>(decl);
typeAliasDecl->getUnderlyingType()->getAsCXXRecordDecl()->dump();

私が得る出力は次のとおりです。

ClassTemplateSpecializationDecl 0x0000000 class Foo
`-TemplateArgument type 'Bar'

ただし、CXXRecordDeclフィールドとメソッドも必要なので、それらを反復処理できます。私も試しました:

for (const auto *contextDecl: typeAliasDecl->getUnderlyingType()->getUnqualifiedDesugaredType()->getAsCXXRecordDecl()->getDeclContext()->decls()) {
    const auto *classTemplateDecl = llvm::dyn_cast<clang::ClassTemplateDecl>(contextDecl);
    classTemplateDecl->dump();
}

出力:

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'

ご覧のとおり、 は にアクセスできますが、の型のインスタンス化については知りませんが、CXXRecordDecl class Foo definitionはアクセスします。FieldDeclbar_ClassTemplateSpecializationDecl

CXXRecordDeclインスタンス化された型が欲しいFieldDecl bar_

4

2 に答える 2

2

参考までに、ClassTemplateSpecializationDecl は CXXRecordDecl のサブクラスであるため、必要な CXXRecordDecl は AST の ClassTemplateSpecializationDecl にすぎません。実際に必要なのは、既に持っている CXXRecordDecl ではなく、その CXXRecordDecl 内の FieldDecl です。

ClassTemplateSpecializationDecl の下に FieldDecl がないのは、テンプレートのインスタンス化コードで bar_ が使用されていないためです。以下のソースを試してください。

template<typename T>
class Foo {
public:
    T getBar() { return bar_; };

private:
    T bar_;
};
using FooBarT = Foo<int>;
void func() {
    FooBarT().getBar();
}

次に、 FieldDecl は 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'
于 2019-12-31T02:45:10.483 に答える