可以解析CRTP模式
can libclang parse the CRTP pattern?
我正在尝试使用libclang来解析C ,但是CRTP模式似乎存在问题,即当类从派生类实例化的模板中继承时:
// The Curiously Recurring Template Pattern (CRTP)
template<class T>
class Base
{
// methods within Base can use template to access members of Derived
};
class Derived : public Base<Derived>
{
// ...
};
我希望libclang找到光标类型cxcursor_cxxxbasespecifier,但它只给了我cxcursor_classdecl。
如果基本不是模板类,则libclang会找到cxcursor_cxxxbasespecifier。
我想完成的是找到从基础继承的类,但是当libclang只提供classDecl种类时,这是不可能的。"公共基础"没有给出光标,似乎被忽略了。
有人知道如何解决这个问题吗?
具有一种CXX_BASE_SPECIFIER
的光标将具有子光标,使您可以确定此信息。如果基本说明符引用模板类,则它将具有两个子节点(类型)template_ref和type_ref。您可以在template_ref节点中使用该信息与类模板光标进行比较。
为了更清楚,我将举一个小例子。漂亮打印以下AST的(libclang)版本:
template<class T>
class Base { };
class X1 : public Base<X1> {};
class Y1 {};
class X2 : public Y1 {};
给出:
TRANSLATION_UNIT tmp.cpp
+--CLASS_TEMPLATE Base
| +--TEMPLATE_TYPE_PARAMETER T
+--CLASS_DECL X1
| +--CXX_BASE_SPECIFIER Base<class X1>
| +--TEMPLATE_REF Base
| +--TYPE_REF class X1
+--CLASS_DECL Y1
+--CLASS_DECL X2
+--CXX_BASE_SPECIFIER class Y1
+--TYPE_REF class Y1
所以一种基本方法是:
- 每个班级
- 找到所有有
CXX_BASE_SPECIFIER
种类的孩子 - 对于基本节点,找到所有这些都有两个孩子(其中一个是
TEMPLATE_REF
) - 对于
TEMPLATE_REF
节点,请检查它们是否具有感兴趣类模板的共同定义。
鉴于这将是C/C (对于stackoverflow)中的一个很大的代码,我将提供一个实现这些步骤的Python 2版本,应该很容易翻译。
import clang
from clang.cindex import CursorKind
def find_template_class(name):
for c in tu.cursor.walk_preorder():
if (c.kind == CursorKind.CLASS_TEMPLATE) and (c.spelling == name):
return c
def inherits_from_template_class(node, base):
for c in node.get_children():
if c.kind != CursorKind.CXX_BASE_SPECIFIER:
continue
children = list(c.get_children())
if len(children) != 2:
continue
if children[0].kind != CursorKind.TEMPLATE_REF:
continue
ctd = children[0].get_definition()
if ctd == base:
return True
return False
idx = clang.cindex.Index.create()
tu = idx.parse('tmp.cpp', unsaved_files=[('tmp.cpp', s)], args='-xc++'.split())
base = find_template_class('Base')
for c in tu.cursor.walk_preorder():
if CursorKind.CLASS_DECL != c.kind:
continue
if inherits_from_template_class(c, base):
print c.spelling
相关文章:
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 为什么在保护模式下继承升级不起作用
- 如何在全屏模式下(在OpenGL中)使背景透明
- 为什么使用__LINE_的代码在发布模式下在MSVC下编译,而不是在调试模式下
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 简化使用 CRTP 模式的类的声明
- CRTP 模式不会触发完整的模板实例化
- 为什么这些 CRTP 模式中只有一个可以编译?
- 为什么奇怪的重复模板模式 (CRTP) 有效
- CRTP 模式 但是在数据结构中存储非同构类型
- 为什么CRTP(奇怪的递归模板模式)试图选择另一个私有基类的另一个同名函数
- 可以解析CRTP模式
- C++和CRTP模式的实现与编译器困境
- 奇怪的重复模板模式(CRTP)和派生的构造函数参数
- 奇怪的重复模板模式 (CRTP),在 Clang 中使用静态 constexpr
- C++中的两种不同的mixin模式.(混合蛋白?CRTP?)
- 使用 CRTP 和'anonymous types/template'实现观察者模式
- 通过值传递的CRTP模式的未初始化副本
- 奇怪的循环模板模式(CRTP),自动列表和c++
- 使用奇怪循环模板模式(CRTP)和其他类型参数