我有一个关于区分StructType的问题,无论它是否是LLVM Pass中的多态类。
我认为在clang中,区分非多态和多态类很容易。
但是,我不知道如何在LLVM Pass中执行此操作。
另外,我搜索了下面的链接。但是,我找不到有用的功能。
(结构布局)http://llvm.org/docs/doxygen/html/classllvm_1_1StructLayout.html
(数据布局)http://llvm.org/docs/doxygen/html/classllvm_1_1DataLayout.html
你能否回答一下如何区分StructType是否是多态类?
For example, In the LLVM Pass, Type *AI ......... StructType *STy = dyn_cast(AI) (question) How to check whether STy is polymorphic class ?? .........``
答案 0 :(得分:2)
TLDR:你不能.LLVM没有类知识。 Clang将它们降低到结构,此时它们与C结构没有什么不同。
你可以模仿匹配它有一个vtable的事实:
struct MyClass {
virtual void foo() {}
};
void bar(MyClass &C) { C.foo(); }
IR包含:%class.MyClass = type { i32 (...)** }
请注意,由于此文件未实例化MyClass,因此不会发出表,因此您无法检查它。如果源以这种方式改变:
struct MyClass {
virtual void foo() {}
};
MyClass C;
void bar() { C.foo(); }
现在你得到一个vtable:
%struct.MyClass = type { i32 (...)** }
@C = global %struct.MyClass zeroinitializer, align 8
@_ZTV7MyClass = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI7MyClass to i8*), i8* bitcast (void (%struct.MyClass*)* @_ZN7MyClass3fooEv to i8*)], align 8
@_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
@_ZTS7MyClass = linkonce_odr constant [9 x i8] c"7MyClass\00"
@_ZTI7MyClass = linkonce_odr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @_ZTS7MyClass, i32 0, i32 0) }
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_class.cpp, i8* null }]
后来是一个初始化它的构造函数:
define linkonce_odr void @_ZN7MyClassC2Ev(%struct.MyClass*) unnamed_addr #1 align 2 {
%2 = alloca %struct.MyClass*, align 8
store %struct.MyClass* %0, %struct.MyClass** %2, align 8
%3 = load %struct.MyClass*, %struct.MyClass** %2, align 8
%4 = bitcast %struct.MyClass* %3 to i32 (...)***
store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV7MyClass, i64 0, i64 2) to i32 (...)**), i32 (...)*** %4, align 8
ret void
}
然而,在启用优化的情况下,这一切都会消失:
@C = global %struct.MyClass { i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV7MyClass, i64 0, i64 2) to i32 (...)**) }, align 8
@_ZTV7MyClass = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI7MyClass to i8*), i8* bitcast (void (%struct.MyClass*)* @_ZN7MyClass3fooEv to i8*)], align 8
另请注意,这是特定于ABI的(例如,在Windows和Linux上看起来不一样)