Clang 确定是否实例化了CXXMethodDelcl

Clang 确定是否实例化了CXXMethodDelcl,clang,clang++,llvm-clang,Clang,Clang++,Llvm Clang,我正在编写一个工具,它遍历一个叮当作响的AST并以特定的格式打印出来,但我不想打印函数模板,只想打印它们的(完整的)专门化。我想知道如何确定const cxxmethoddel*代表的是完全实例化的方法(要么不是模板化的,要么是模板化方法的完全实例化),要么不是完全实例化的方法。以下是我在工具中看到的示例: 模板 P类 { int查找(); }; 模板 intp::lookup() { 返回Z::f(); } 结构X{ 静态int f(); }; 模板类P; 构造以下AST。我不想看到第一个c

我正在编写一个工具,它遍历一个叮当作响的AST并以特定的格式打印出来,但我不想打印函数模板,只想打印它们的(完整的)专门化。我想知道如何确定const cxxmethoddel*代表的是完全实例化的方法(要么不是模板化的,要么是模板化方法的完全实例化),要么不是完全实例化的方法。以下是我在工具中看到的示例:

模板
P类
{
int查找();
};
模板
intp::lookup()
{
返回Z::f();
}
结构X{
静态int f();
};
模板类P;
构造以下AST。我不想看到第一个
cxrecorddecl
,因为它没有完全实例化,但我确实想看到第二个(完全实例化)

|-ClassTemplateDecl 0x3eff5b8行:2:7 Pte
||-TemplateTypeParmDecl 0x3eff480列:20 typename深度0索引0 PTT
||-CXXRecordDecl 0x3eff530行:2:7类Pte定义
|| |-定义数据空聚合标准_布局普通_可复制pod普通文本具有_constexpr _non _copy _move _ctorcan _const _default _init
|| | | |-DefaultConstructor存在平凡的constexpr需要_隐式默认_为_constexpr
|| | | |-CopyConstructor simple triple has_const_param needs_implicit_has_const_param
|| | |-MoveConstructor存在简单的琐碎需求
|| | | |-CopyAssignment琐碎has_const_param needs_implicit_has_const_param
|| | |-MoveAssignment存在简单的琐碎需求
|| |`-析构函数简单无关的琐碎需求
|| |-CXXRecordDecl 0x3eff800列:7隐式类Pte
||`-CXxMethodDeleCl 0x3eff910列:9查找'int()'
|`-ClassTemplateSpecialization 0x3f00010'Pte'
|-CXxMethodDeleCl 0x3effbb0父级0x3eff530上一个0x3eff910行:8:15查找“int()”
^^^^^^^^^^^^^^^^^^^^^^^^^^我不想看到这个
|`-CompoundStmt 0x3effd50
|`-ReturnStmt 0x3effd40
|`-CallExpr 0x3effd20“”
|`-CXXDependentScopeMemberExpr 0x3effcd8''左值->f
|-CXXRecordDecl 0x3effd68行:13:8引用的结构X定义
||-DefinitionData pass_in_寄存器空聚合标准_布局普通_可复制pod普通文本具有_constexpr_non_copy_move_ctor can_const_default_init
|| |-DefaultConstructor存在平凡的constexpr需要_隐式默认_为_constexpr
|| |-CopyConstructor simple triple has_const_param needs_implicit implicit_has_const_param
|| |-MoveConstructor存在简单的琐碎需求
|| |-CopyAssignment琐碎has_const_param needs_implicit_has_const_param
|| |-MoveAssignment存在简单的琐碎需求
||`-析构函数简单无关的琐碎需求
||-CXXRecordDecl 0x3effe78列:8隐式结构X
|`-CXxMethodDeleCl 0x3efff50列:16用于“int()”静态
`-ClassTemplateSpecializationDecl 0x3f00010列:16类Pte定义
|-定义数据传递\u in \u寄存器空聚合标准\u布局普通\u可复制pod普通文本具有\u constexpr\u非复制\u移动\u构造函数可以\u const\u默认\u init
||-DefaultConstructor存在平凡的constexpr需要_隐式默认_为_constexpr
||-CopyConstructor simple triple has_const_param needs_implicit_has_const_param
||-MoveConstructor存在简单的琐碎需求
||-CopyAssignment琐碎has_const_param needs_implicit_has_const_param
||-MoveAssignment存在简单的琐碎需求
|`-析构函数简单无关的琐碎需求\u隐式
|-TemplateArgument类型“X”
|-CXXRecordDecl 0x3f001f8上一个0x3f00010列:7隐式类Pte
`-CXxMethodDelecl 0x3f00280行:4:9查找“int()”
^^^^^^^^^^^^^^^^^^^^^^^^^^^^我想看看这个
`-复合材料STMT 0x3f2e1b0
`-返回STMT 0x3f2e1a0
`-调用者0x3f2e180'内部'
`-隐式卡斯特xpr 0x3f2e168'int(*)()'
`-DeclRefExpr 0x3f2e110'int()'左值CXX方法0x3eff50'f''int()'

每当类型/函数/变量在模板中声明或是模板时,clang将其称为依赖上下文。您可能已经在模板中的AST节点周围看到了单词dependent

我修改了您的原始测试用例,将模板化方法包含在非模板类型中:

模板
P类
{
int查找();
};
模板
intp::lookup()
{
返回Z::f();
}
结构X{
静态int f(){return 42;}
};
结构{
模板
int foo(){return Z::f();}
};
模板类P;
下面是一个非常简单的递归函数,它只打印出您感兴趣的函数:

类非依赖性方法访问者
:公共叮当声::消费者,
public clang::RecursiveASTVisitor{
公众:
void HandleTranslationUnit(叮当::ASTContext和Context){
这->遍历TransferTranslationUnitDecl(Context.getTranslationUnitDecl());
}
bool shouldVisiteTemplateInstances()常量{return true;}
bool VisitCXXMethodDecl(clang::CXXMethodDecl*MD){
如果(!MD->isDependentContext()){
MD->dump();
}
返回true;
}
};
它为测试代码段生成以下输出:

CXXMethodDecl 0x384eda0 <$TEST_DIR/test.cpp:14:5, col:33> col:16 used f 'int ()' static
`-CompoundStmt 0x384ee80 <col:20, col:33>
  `-ReturnStmt 0x384ee70 <col:22, col:29>
    `-IntegerLiteral 0x384ee50 <col:29> 'int' 42
CXXMethodDecl 0x387e170 <$TEST_DIR/test.cpp:8:1, line:11:1> line:4:9 lookup 'int ()'
`-CompoundStmt 0x387e450 <line:9:1, line:11:1>
  `-ReturnStmt 0x387e440 <line:10:5, col:17>
    `-CallExpr 0x387e420 <col:12, col:17> 'int'
      `-ImplicitCastExpr 0x387e408 <col:12, col:15> 'int (*)()' <FunctionToPointerDecay>
        `-DeclRefExpr 0x387e3b0 <col:12, col:15> 'int ()' lvalue CXXMethod 0x384eda0 'f' 'int ()'

CXxMethodDeleCl 0x384eda0列:16用于“int()”静态
`-复合材料STMT 0x384ee80
`-返回STMT 0x384ee70
`-集成文件0x384ee50'内部'42
CXxMethodDeleCl 0x387e170行:4:9查找“int()”
`-复合材料STMT 0x387e450
`-返回STMT 0x387e440
`-调用者0x387e420'内部'
`-隐式卡斯特xpr 0x387e408'int(*)()'
`-DeclRefExpr 0x387e3b0'int()'左值CXX方法0x384eda0'f''int()'

我希望这能回答你的问题

每当类型/函数/变量在模板中声明或是模板时,clang将其称为依赖上下文。您可能已经在模板中的AST节点周围看到了单词dependent

我已经修改了您的原始测试用例,在no中包含了一个模板化方法