学习 LLVM(2) isa<> 模板函数
2012-07-25 21:17
120 查看
从 http://llvm.org/docs/ProgrammersManual.html 开始学习的话,遇到的第一个 api 是 isa<>,
不仔细学习下好像也看不懂后面的程序吧?
isa<> 是一个模板函数,定义在 llvm/include/llvm/Support/Casting.h 中。其工作类似于
java 中的 "instanceof" 操作符。它判定一个指针或一个引用是否是指定类的实例。参见:
http://llvm.org/docs/ProgrammersManual.html#isa
定义:
template <class X, class Y>
inline bool isa(const Y &Val) { ... }
使用例:
if (isa<Type>(myVal)) { ... }
== 实现机理 ==
=== simplify_type<> ===
模板 template <T> struct simplify_type 用于提供 SimpleType 定义和 getSimplifiedValue() 函数。但是其特化版本 simplify_type<const T> 却似乎不是很正确?(其 getSimplifiedValue() 函数不能被编译通过?)
需要将其中的 static_cast<> 变为 const_cast<> 才能编译通过,可能是一个错误?
在其它类的定义中,可能为配合 isa<> 等,实现有自己的 simplify_type<> 特化版。需要我们在看到哪些类的时候,才能深入理解这个模板的更多用途。而且它们在特化版本中也有用 static_cast<> 的,可是我觉得那也同样无法编译通过?
=== 辅助模板 isa_impl<> ===
isa_impl<TO, FROM> 用于帮助实现 isa<X>. 实际计算 TO::classof(const FROM* p) <br>
这意味着,让类 TO 判断指针 p 所指向的对象是否为 TO 类型的。
实际实现中,对于一个类的继承结构如 B 继承 A,如果 p 指针指向的对象是 B, TO 为 B, FROM 为 A,则需要 classof() 函数能够实际判定出 p 确实是 B 对象,即使 p 当前的指针类型为 A*。具体如何实现 classof() 函数,我们在研究 LLVM 中的 Value 类及其派生体系的时候具体进行。那里使用了一种较为传统的 subClassID 的方式来识别子类类型。
=== 辅助模板 isa_impl_cl<> ===
isa_impl_cl<TO, FROM> 用于调用 isa_impl<>, 其特化 FROM 的多种版本,使得对 isa_impl<> 的调用成为有效的。有效的指 isa_impl<> 内调用 TO::classof() 能够给出正确的参数形式和类型。
本模板的特化版本有:
* template <To, From> struct isa_impl_cl<To, const From>
* template <To, From> struct isa_impl_cl<To, From*>
* template <To, From> struct isa_impl_cl<To, const From*>
* template <To, From> struct isa_impl_cl<To, const From * const>
=== 辅助模板 isa_impl_wrap<> ===
模板类 isa_impl_wrap<To, From, SimpleFrom> 实现对 isa_impl_cl<To, From> 的调用。
其中如果 From == SimpleFrom 使用的特化版本会直接调用 isa_impl_cl。
如果 From != SimpleFrom,则麻烦出在这里,我使用的测试例子如 isa_impl_wrap<A, B, const B> 会导致无法编译,或者导致使用 simplify_type<> 无法编译。我觉得这里要么模板有问题,要么模板要求传入的类参数 SimpleFrom 有特定的要求,但是没有注释。也许看到别的地方才能彻底理解这里。
=== 模板函数 isa<> ===
定义为 template <class X, class Y> inline bool isa(const Y &Val)。
设 YY = simplify_type<Y>::SimpleType,一般就是 Y。则 isa<X, Y>
实际实现调用为 isa_impl_wrap<X, Y, YY>。
对于特定类,如 Optional<T>,它实现了对 simplify_type< Optional<T> > 的特化版本,这样导致 Y != YY。也即导致对 isa_impl_wrap<> 的普通版本的调用。具体到研究 Optional<T> 的时候我再仔细看这里吧。
不仔细学习下好像也看不懂后面的程序吧?
isa<> 是一个模板函数,定义在 llvm/include/llvm/Support/Casting.h 中。其工作类似于
java 中的 "instanceof" 操作符。它判定一个指针或一个引用是否是指定类的实例。参见:
http://llvm.org/docs/ProgrammersManual.html#isa
定义:
template <class X, class Y>
inline bool isa(const Y &Val) { ... }
使用例:
if (isa<Type>(myVal)) { ... }
== 实现机理 ==
=== simplify_type<> ===
模板 template <T> struct simplify_type 用于提供 SimpleType 定义和 getSimplifiedValue() 函数。但是其特化版本 simplify_type<const T> 却似乎不是很正确?(其 getSimplifiedValue() 函数不能被编译通过?)
需要将其中的 static_cast<> 变为 const_cast<> 才能编译通过,可能是一个错误?
在其它类的定义中,可能为配合 isa<> 等,实现有自己的 simplify_type<> 特化版。需要我们在看到哪些类的时候,才能深入理解这个模板的更多用途。而且它们在特化版本中也有用 static_cast<> 的,可是我觉得那也同样无法编译通过?
=== 辅助模板 isa_impl<> ===
isa_impl<TO, FROM> 用于帮助实现 isa<X>. 实际计算 TO::classof(const FROM* p) <br>
这意味着,让类 TO 判断指针 p 所指向的对象是否为 TO 类型的。
实际实现中,对于一个类的继承结构如 B 继承 A,如果 p 指针指向的对象是 B, TO 为 B, FROM 为 A,则需要 classof() 函数能够实际判定出 p 确实是 B 对象,即使 p 当前的指针类型为 A*。具体如何实现 classof() 函数,我们在研究 LLVM 中的 Value 类及其派生体系的时候具体进行。那里使用了一种较为传统的 subClassID 的方式来识别子类类型。
=== 辅助模板 isa_impl_cl<> ===
isa_impl_cl<TO, FROM> 用于调用 isa_impl<>, 其特化 FROM 的多种版本,使得对 isa_impl<> 的调用成为有效的。有效的指 isa_impl<> 内调用 TO::classof() 能够给出正确的参数形式和类型。
本模板的特化版本有:
* template <To, From> struct isa_impl_cl<To, const From>
* template <To, From> struct isa_impl_cl<To, From*>
* template <To, From> struct isa_impl_cl<To, const From*>
* template <To, From> struct isa_impl_cl<To, const From * const>
=== 辅助模板 isa_impl_wrap<> ===
模板类 isa_impl_wrap<To, From, SimpleFrom> 实现对 isa_impl_cl<To, From> 的调用。
其中如果 From == SimpleFrom 使用的特化版本会直接调用 isa_impl_cl。
如果 From != SimpleFrom,则麻烦出在这里,我使用的测试例子如 isa_impl_wrap<A, B, const B> 会导致无法编译,或者导致使用 simplify_type<> 无法编译。我觉得这里要么模板有问题,要么模板要求传入的类参数 SimpleFrom 有特定的要求,但是没有注释。也许看到别的地方才能彻底理解这里。
=== 模板函数 isa<> ===
定义为 template <class X, class Y> inline bool isa(const Y &Val)。
设 YY = simplify_type<Y>::SimpleType,一般就是 Y。则 isa<X, Y>
实际实现调用为 isa_impl_wrap<X, Y, YY>。
对于特定类,如 Optional<T>,它实现了对 simplify_type< Optional<T> > 的特化版本,这样导致 Y != YY。也即导致对 isa_impl_wrap<> 的普通版本的调用。具体到研究 Optional<T> 的时候我再仔细看这里吧。
相关文章推荐
- 学习笔记 LLVM(3) cast<> 模板函数
- 学习笔记——JAVA设计模式<4>原型模式
- Struts2学习笔记之<s:token/>防止表单重复提交
- HTML学习笔记<5>[CSS]
- linux系统学习第十六天-<<工程师技术>>
- HTML学习 <一>
- 由Cannot create a generic array of ArrayList<xx>引出的学习--Java范型
- 【学习ios之路:Objective-C错误】Collection <__NSArrayM: 0xb550c30> was mutated while being enumerated.
- C#基础学习日志===&gt;数组&lt;===
- 集合框架学习笔记<二>
- [原]java专业程序代写(qq:928900200),学习笔记之基础入门<反射>(二十九)
- Box2d源码学习<二>内存管理之SOA的实现
- <中秋送祝福>山寨网页终于完成,分享学习心得!
- git学习——<二>git配置文件
- ASP.NET&C#学习笔录4(<authentication mode="Windows|Forms|Passport|None"> )
- (转)MFC学习技巧<三>
- RT-Thread 学习笔记(十一)--- 开启基于RTGUI的LCD显示功能(1)<LCD驱动接口移植>
- 【Java编程】Java学习笔记<二>
- List<T> 排序学习
- <一>Strom实时计算学习笔记