2016-09-18 6 views
1

LLVMパスでポリモーフィックなクラスかどうかを区別するための質問があります。LLVM PASSで非多型と多型を区別する方法は?

クラングでは、非多型と多型の区別が容易だと思います。

しかし、私はLLVMパスでこれを行う方法がわかりません。

また、以下のリンクを検索しました。しかし、私は有用な機能を見つけることができませんでした。

あなたは私にそれが多型クラスであるかどうかStructTypeを区別するためにどのように答える与えてもらえますか?

 
For example, In the LLVM Pass, 

Type *AI 
......... 
StructType *STy = dyn_cast(AI) 
(question) How to check whether STy is polymorphic class ?? 
.........`` 

答えて

2

TLDR:あなたはできません.LLVMはクラスの知識がありません。 Clangはそれらを構造体に降ろしました。その時点では、構造体と実際には違いはありません。

あなたはパターンそれは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では同じように見えません)