2016-12-14 66 views
0

我宣佈一個類中的伊娃:伊娃顯示爲私人全球在LLVMIR

@implementation LLVMIRTest{ 
    NSString* ivarTest; 
} 

當我檢查了LLVM IR它讓我看到:

@OBJC_METH_VAR_NAME_ = private global [9 x i8] c"ivarTest\00", section "__TEXT,__objc_methname,cstring_literals", align 1 
@OBJC_METH_VAR_TYPE_ = private global [12 x i8] c"@\22NSString\22\00", section "__TEXT,__objc_methtype,cstring_literals", align 1 

我要問,爲什麼它是LLVM IR提供私人全球提及。爲什麼不只是私人?

這是滿模塊LLVM IR:

; ModuleID = 'LLVMIRTest.m' 
source_filename = "LLVMIRTest.m" 
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 
target triple = "x86_64-apple-macosx10.12.0" 

%struct._objc_cache = type opaque 
%struct._class_t = type { %struct._class_t*, %struct._class_t*, %struct._objc_cache*, i8* (i8*, i8*)**, %struct._class_ro_t* } 
%struct._class_ro_t = type { i32, i32, i32, i8*, i8*, %struct.__method_list_t*, %struct._objc_protocol_list*, %struct._ivar_list_t*, i8*, %struct._prop_list_t* } 
%struct.__method_list_t = type { i32, i32, [0 x %struct._objc_method] } 
%struct._objc_method = type { i8*, i8*, i8* } 
%struct._objc_protocol_list = type { i64, [0 x %struct._protocol_t*] } 
%struct._protocol_t = type { i8*, i8*, %struct._objc_protocol_list*, %struct.__method_list_t*, %struct.__method_list_t*, %struct.__method_list_t*, %struct.__method_list_t*, %struct._prop_list_t*, i32, i32, i8**, i8*, %struct._prop_list_t* } 
%struct._ivar_list_t = type { i32, i32, [0 x %struct._ivar_t] } 
%struct._ivar_t = type { i64*, i8*, i8*, i32, i32 } 
%struct._prop_list_t = type { i32, i32, [0 x %struct._prop_t] } 
%struct._prop_t = type { i8*, i8* } 

@_objc_empty_cache = external global %struct._objc_cache 
@"OBJC_METACLASS_$_NSObject" = external global %struct._class_t 
@OBJC_CLASS_NAME_ = private global [11 x i8] c"LLVMIRTest\00", section "__TEXT,__objc_classname,cstring_literals", align 1 
@"\01l_OBJC_METACLASS_RO_$_LLVMIRTest" = private global %struct._class_ro_t { i32 1, i32 40, i32 40, i8* null, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @OBJC_CLASS_NAME_, i32 0, i32 0), %struct.__method_list_t* null, %struct._objc_protocol_list* null, %struct._ivar_list_t* null, i8* null, %struct._prop_list_t* null }, section "__DATA, __objc_const", align 8 
@"OBJC_METACLASS_$_LLVMIRTest" = global %struct._class_t { %struct._class_t* @"OBJC_METACLASS_$_NSObject", %struct._class_t* @"OBJC_METACLASS_$_NSObject", %struct._objc_cache* @_objc_empty_cache, i8* (i8*, i8*)** null, %struct._class_ro_t* @"\01l_OBJC_METACLASS_RO_$_LLVMIRTest" }, section "__DATA, __objc_data", align 8 
@"OBJC_CLASS_$_NSObject" = external global %struct._class_t 
@"OBJC_IVAR_$_LLVMIRTest.ivarTest" = hidden global i64 8, section "__DATA, __objc_ivar", align 8 
@OBJC_METH_VAR_NAME_ = private global [9 x i8] c"ivarTest\00", section "__TEXT,__objc_methname,cstring_literals", align 1 
@OBJC_METH_VAR_TYPE_ = private global [12 x i8] c"@\22NSString\22\00", section "__TEXT,__objc_methtype,cstring_literals", align 1 
@"\01l_OBJC_$_INSTANCE_VARIABLES_LLVMIRTest" = private global { i32, i32, [1 x %struct._ivar_t] } { i32 32, i32 1, [1 x %struct._ivar_t] [%struct._ivar_t { i64* @"OBJC_IVAR_$_LLVMIRTest.ivarTest", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @OBJC_METH_VAR_NAME_, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @OBJC_METH_VAR_TYPE_, i32 0, i32 0), i32 3, i32 8 }] }, section "__DATA, __objc_const", align 8 
@"\01l_OBJC_CLASS_RO_$_LLVMIRTest" = private global %struct._class_ro_t { i32 0, i32 8, i32 16, i8* null, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @OBJC_CLASS_NAME_, i32 0, i32 0), %struct.__method_list_t* null, %struct._objc_protocol_list* null, %struct._ivar_list_t* bitcast ({ i32, i32, [1 x %struct._ivar_t] }* @"\01l_OBJC_$_INSTANCE_VARIABLES_LLVMIRTest" to %struct._ivar_list_t*), i8* null, %struct._prop_list_t* null }, section "__DATA, __objc_const", align 8 
@"OBJC_CLASS_$_LLVMIRTest" = global %struct._class_t { %struct._class_t* @"OBJC_METACLASS_$_LLVMIRTest", %struct._class_t* @"OBJC_CLASS_$_NSObject", %struct._objc_cache* @_objc_empty_cache, i8* (i8*, i8*)** null, %struct._class_ro_t* @"\01l_OBJC_CLASS_RO_$_LLVMIRTest" }, section "__DATA, __objc_data", align 8 
@"OBJC_LABEL_CLASS_$" = private global [1 x i8*] [i8* bitcast (%struct._class_t* @"OBJC_CLASS_$_LLVMIRTest" to i8*)], section "__DATA, __objc_classlist, regular, no_dead_strip", align 8 
@llvm.compiler.used = appending global [5 x i8*] [i8* getelementptr inbounds ([11 x i8], [11 x i8]* @OBJC_CLASS_NAME_, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @OBJC_METH_VAR_NAME_, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @OBJC_METH_VAR_TYPE_, i32 0, i32 0), i8* bitcast ({ i32, i32, [1 x %struct._ivar_t] }* @"\01l_OBJC_$_INSTANCE_VARIABLES_LLVMIRTest" to i8*), i8* bitcast ([1 x i8*]* @"OBJC_LABEL_CLASS_$" to i8*)], section "llvm.metadata" 

!llvm.module.flags = !{!0, !1, !2, !3, !4, !5} 
!llvm.ident = !{!6} 

!0 = !{i32 1, !"Objective-C Version", i32 2} 
!1 = !{i32 1, !"Objective-C Image Info Version", i32 0} 
!2 = !{i32 1, !"Objective-C Image Info Section", !"__DATA, __objc_imageinfo, regular, no_dead_strip"} 
!3 = !{i32 4, !"Objective-C Garbage Collection", i32 0} 
!4 = !{i32 1, !"Objective-C Class Properties", i32 64} 
!5 = !{i32 1, !"PIC Level", i32 2} 
!6 = !{!"Apple LLVM version 8.0.0 (clang-800.0.38)"} 

回答

0

全局變量被認爲是模塊作用域被在編譯時間與運行時間初始化。

LLVM的大部分前端都將字符串放在模塊範圍內,這些前端需要globalconstant標記。有一種方法可以將字符串存儲在堆棧上,但這在我的經驗中很少見。我通常創建字符串爲

@somename = internal constant...

private指示不要在模塊外部暴露符號。

我認爲這是Objective-C如何爲類添加類型和工具支持。如果查看其餘的輸出,那麼在某些調用之前,指向這些字符串的指針可能會傳遞到RT庫(例如%x = load ...)。 OP後

更新補充上市

您列出什麼是代表你的類的「靜態」模塊級結構。如果仔細觀察,類聲明由許多嵌入式結構和字符串組成。由於這些聲明位於模塊級別,因此它們被聲明爲global,因爲它是數據部分而不是方法實現,所以它們如您所期望的那樣放置在數據段中。把你的班級想象成一個structure,它不僅包含變量'iVar'的空間,還包含Objective-C RT所需的附加信息。

因此,類和它們的變量被認爲是模塊級聲明,它們被表示爲模塊級的數據結構,它被LLVM標準標記爲global。請參閱LLVM Global Variable文檔。

+0

嗨@frank我唯一擔心的是如果我聲明任何iVar,那麼爲什麼它聲明它是全局的?它與String無關。 –

+0

@SauravNagpal如上所述,字符串由編譯器爲Objective-C支持生成。如果你用實際的Class和iVar的輸出擴展你的問題,可能會更容易理解這種差異。它並不意味着iVar是全球性的,只是描述它的字符串對於我所提交的內容來說會比運行時類型信息(RTTI)典型地支持反思。 –

+0

嗨@frank,謝謝你的回覆。但是我仍然感到困惑,並且我已經在全班加入了這個問題。我唯一的問題是爲什麼全球提及iVar? –