-
Notifications
You must be signed in to change notification settings - Fork 12.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary: This includes initial support for the (hopefully final) updated Objective-C ABI, developed here: https://github.com/davidchisnall/clang-gnustep-abi-2 It also includes some cleanups and refactoring from older GNU ABIs. The current version is ELF only, other formats to follow. Reviewers: rjmccall, DHowett-MSFT Reviewed By: rjmccall Subscribers: smeenai, cfe-commits Differential Revision: https://reviews.llvm.org/D46052 llvm-svn: 332950
- Loading branch information
David Chisnall
committed
May 22, 2018
1 parent
b818482
commit 79356ee
Showing
15 changed files
with
1,691 additions
and
364 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| // RUN: %clang -S -emit-llvm %s -o - -x objective-c -fobjc-runtime=gnustep-1.5 | FileCheck %s | ||
|
|
||
| // Regression test: check that we don't crash when referencing a forward-declared protocol. | ||
| @protocol P; | ||
|
|
||
| Protocol *getProtocol(void) | ||
| { | ||
| return @protocol(P); | ||
| } | ||
|
|
||
| // CHECK: @.objc_protocol |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| // RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s -check-prefix=CHECK-NEW | ||
| // RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-1.8 -o - %s | FileCheck %s -check-prefix=CHECK-OLD | ||
|
|
||
| // Almost minimal Objective-C file, check that it emits calls to the correct | ||
| // runtime entry points. | ||
| @interface X @end | ||
| @implementation X @end | ||
|
|
||
|
|
||
| // Check that we emit a class ref | ||
| // CHECK-NEW: @._OBJC_REF_CLASS_X | ||
| // CHECK-NEW-SAME: section "__objc_class_refs" | ||
|
|
||
| // Check that we get a class ref to the defined class. | ||
| // CHECK-NEW: @._OBJC_INIT_CLASS_X = global | ||
| // CHECK-NEW-SAME* @._OBJC_CLASS_X, section "__objc_classes" | ||
|
|
||
| // Check that we emit the section start and end symbols as hidden globals. | ||
| // CHECK-NEW: @__start___objc_selectors = external hidden global i8* | ||
| // CHECK-NEW: @__stop___objc_selectors = external hidden global i8* | ||
| // CHECK-NEW: @__start___objc_classes = external hidden global i8* | ||
| // CHECK-NEW: @__stop___objc_classes = external hidden global i8* | ||
| // CHECK-NEW: @__start___objc_class_refs = external hidden global i8* | ||
| // CHECK-NEW: @__stop___objc_class_refs = external hidden global i8* | ||
| // CHECK-NEW: @__start___objc_cats = external hidden global i8* | ||
| // CHECK-NEW: @__stop___objc_cats = external hidden global i8* | ||
| // CHECK-NEW: @__start___objc_protocols = external hidden global i8* | ||
| // CHECK-NEW: @__stop___objc_protocols = external hidden global i8* | ||
| // CHECK-NEW: @__start___objc_protocol_refs = external hidden global i8* | ||
| // CHECK-NEW: @__stop___objc_protocol_refs = external hidden global i8* | ||
| // CHECK-NEW: @__start___objc_class_aliases = external hidden global i8* | ||
| // CHECK-NEW: @__stop___objc_class_aliases = external hidden global i8* | ||
| // CHECK-NEW: @__start___objc_constant_string = external hidden global i8* | ||
| // CHECK-NEW: @__stop___objc_constant_string = external hidden global i8* | ||
|
|
||
| // Check that we emit the init structure correctly, including in a comdat. | ||
| // CHECK-NEW: @.objc_init = linkonce_odr hidden global { i64, i8**, i8**, i8**, i8**, i8**, i8**, i8**, i8**, i8**, i8**, i8**, i8**, i8**, i8**, i8**, i8** } { i64 0, i8** @__start___objc_selectors, i8** @__stop___objc_selectors, i8** @__start___objc_classes, i8** @__stop___objc_classes, i8** @__start___objc_class_refs, i8** @__stop___objc_class_refs, i8** @__start___objc_cats, i8** @__stop___objc_cats, i8** @__start___objc_protocols, i8** @__stop___objc_protocols, i8** @__start___objc_protocol_refs, i8** @__stop___objc_protocol_refs, i8** @__start___objc_class_aliases, i8** @__stop___objc_class_aliases, i8** @__start___objc_constant_string, i8** @__stop___objc_constant_string }, comdat, align 8 | ||
|
|
||
| // Check that the load function is manually inserted into .ctors. | ||
| // CHECK-NEW: @.objc_ctor = linkonce hidden constant void ()* @.objcv2_load_function, section ".ctors", comdat | ||
|
|
||
|
|
||
| // Make sure that we provide null versions of everything so the __start / | ||
| // __stop symbols work. | ||
| // CHECK-NEW: @.objc_null_selector = linkonce_odr hidden global { i8*, i8* } zeroinitializer, section "__objc_selectors", comdat, align 8 | ||
| // CHECK-NEW: @.objc_null_category = linkonce_odr hidden global { i8*, i8*, i8*, i8*, i8*, i8*, i8* } zeroinitializer, section "__objc_cats", comdat, align 8 | ||
| // CHECK-NEW: @.objc_null_protocol = linkonce_odr hidden global { i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8* } zeroinitializer, section "__objc_protocols", comdat, align 8 | ||
| // CHECK-NEW: @.objc_null_protocol_ref = linkonce_odr hidden global { i8* } zeroinitializer, section "__objc_protocol_refs", comdat, align 8 | ||
| // CHECK-NEW: @.objc_null_class_alias = linkonce_odr hidden global { i8*, i8* } zeroinitializer, section "__objc_class_aliases", comdat, align 8 | ||
| // CHECK-NEW: @.objc_null_constant_string = linkonce_odr hidden global { i8*, i32, i32, i32, i32, i8* } zeroinitializer, section "__objc_constant_string", comdat, align 8 | ||
| // Make sure that the null symbols are not going to be removed, even by linking. | ||
| // CHECK-NEW: @llvm.used = appending global [7 x i8*] [i8* bitcast ({ { i8*, i8*, i8*, i64, i64, i64, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i64, i8* }*, i8*, i8*, i64, i64, i64, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i64, i8* }** @._OBJC_INIT_CLASS_X to i8*), i8* bitcast ({ i8*, i8* }* @.objc_null_selector to i8*), i8* bitcast ({ i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @.objc_null_category to i8*), i8* bitcast ({ i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @.objc_null_protocol to i8*), i8* bitcast ({ i8* }* @.objc_null_protocol_ref to i8*), i8* bitcast ({ i8*, i8* }* @.objc_null_class_alias to i8*), i8* bitcast ({ i8*, i32, i32, i32, i32, i8* }* @.objc_null_constant_string to i8*)], section "llvm.metadata" | ||
| // Make sure that the load function and the reference to it are marked as used. | ||
| // CHECK-NEW: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast (void ()* @.objcv2_load_function to i8*), i8* bitcast (void ()** @.objc_ctor to i8*)], section "llvm.metadata" | ||
|
|
||
| // Check that we emit the load function in a comdat and that it does the right thing. | ||
| // CHECK-NEW: define linkonce_odr hidden void @.objcv2_load_function() comdat { | ||
| // CHECK-NEW-NEXT: entry: | ||
| // CHECK-NEW-NEXT: call void @__objc_load( | ||
| // CHECK-NEW-SAME: @.objc_init | ||
| // CHECK-NEW-NEXT: ret void | ||
|
|
||
| // CHECK-OLD: @4 = internal global { i64, i64, i8*, { i64, { i8*, i8* }*, i16, i16, [4 x i8*] }* } { i64 9, i64 32, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @.objc_source_file_name, i64 0, i64 0), { i64, { i8*, i8* }*, i16, i16, [4 x i8*] }* @3 }, align 8 | ||
| // CHECK-OLD: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @.objc_load_function, i8* null }] | ||
|
|
||
| // CHECK-OLD: define internal void @.objc_load_function() { | ||
| // CHECK-OLD-NEXT: entry: | ||
| // CHECK-OLD-NEXT: call void ({ i64, i64, i8*, { i64, { i8*, i8* }*, i16, i16, [4 x i8*] }* }*, ...) @__objc_exec_class({ i64, i64, i8*, { i64, { i8*, i8* }*, i16, i16, [4 x i8*] }* }* @4) | ||
|
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| // RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s | ||
|
|
||
|
|
||
| // Check that we have a method list that refers to the correct thing method: | ||
| // CHECK: internal global { i8*, i32, i64, [1 x { i8* (i8*, i8*, ...)*, i8*, i8* }] } { i8* null, i32 1, i64 24, | ||
| // CHECK-SAME: @_i_X_Cat_x | ||
| // CHECK-SAME: @".objc_selector_x_i16\010:8" | ||
|
|
||
| // Check that we emit the correct encoding for the property (somewhere) | ||
| // CHECK: c"Ti,R\00" | ||
|
|
||
| // Check that we emit a single-element property list of the correct form. | ||
| // CHECK: internal global { i32, i32, i8*, [1 x { i8*, i8*, i8*, i8*, i8* }] } | ||
|
|
||
| // CHECK: @.objc_category_XCat = internal global { i8*, i8*, i8*, i8*, i8*, i8*, i8* } | ||
| // CHECK-SAME: section "__objc_cats", align 8 | ||
|
|
||
| @interface X @end | ||
|
|
||
| @interface X (Cat) | ||
| @property (readonly) int x; | ||
| @end | ||
|
|
||
| @implementation X (Cat) | ||
| - (int)x { return 12; } | ||
| @end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| // RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s | ||
|
|
||
| @interface Super @end | ||
|
|
||
| @interface X : Super | ||
| { | ||
| int ivar1; | ||
| id ivar2; | ||
| } | ||
| @property (readonly) int x; | ||
| @property id y; | ||
| @end | ||
|
|
||
| @implementation X | ||
| @synthesize y; | ||
|
|
||
| - (int)x { return 12; } | ||
| + (int)clsMeth { return 42; } | ||
| - (id)meth { return ivar2; } | ||
| @end | ||
|
|
||
| // Check that we get an ivar offset variable for the synthesised ivar. | ||
| // CHECK: @"__objc_ivar_offset_X.y.\01" = hidden global i32 16 | ||
| // | ||
| // Check that we get a sensible metaclass method list. | ||
| // CHECK: internal global { i8*, i32, i64, [1 x { i8* (i8*, i8*, ...)*, i8*, i8* }] } | ||
| // CHECK-SAME: @_c_X__clsMeth | ||
|
|
||
| // Check that we get a metaclass and that it is not an exposed symbol: | ||
| // CHECK: @._OBJC_METACLASS_X = internal global | ||
|
|
||
| // Check that we get a reference to the superclass symbol: | ||
| // CHECK: @._OBJC_CLASS_Super = external global i8* | ||
|
|
||
| // Check that we get an ivar list with all three ivars, in the correct order | ||
| // CHECK: private global { i32, i64, [3 x { i8*, i8*, i32*, i32, i32 }] } | ||
| // CHECK-SAME: @__objc_ivar_offset_X.ivar1.i | ||
| // CHECK-SAME: @"__objc_ivar_offset_X.ivar2.\01" | ||
| // CHECK-SAME: @"__objc_ivar_offset_X.y.\01" | ||
|
|
||
| // Check that we get some plausible property metadata. | ||
| // CHECK: private unnamed_addr constant [5 x i8] c"Ti,R\00", align 1 | ||
| // CHECK: private unnamed_addr constant [6 x i8] c"T@,Vy\00", align 1 | ||
| // CHECK: = internal global { i32, i32, i8*, [2 x { i8*, i8*, i8*, i8*, i8* }] } { i32 2, i32 40, i8* null, | ||
|
|
||
| // Check that we get a class structure. | ||
| // CHECK: @._OBJC_CLASS_X = global { { i8*, i8*, i8*, i64, i64, i64, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i64, i8* }*, i8*, i8*, i64, i64, i64, { i32, i64, [3 x { i8*, i8*, i32*, i32, i32 }] }*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i64, { i32, i32, i8*, [2 x { i8*, i8*, i8*, i8*, i8* }] }* } | ||
| // CHECK-SAME: @._OBJC_METACLASS_X | ||
| // CHECK-SAME: @._OBJC_CLASS_Super | ||
|
|
||
| // And check that we get a pointer to it in the right place | ||
| // CHECK: @._OBJC_REF_CLASS_X = global | ||
| // CHECK-SAME: @._OBJC_CLASS_X | ||
| // CHECK-SAMEsection "__objc_class_refs" | ||
|
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| // RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s | ||
|
|
||
|
|
||
| @class NSString; | ||
|
|
||
| @interface ANObject { | ||
| @public | ||
| // Public ivars have default visibility | ||
| // CHECK: @"__objc_ivar_offset_ANObject.isa.\01" = global i32 0 | ||
| struct objc_object *isa; | ||
| @private | ||
| // Private and package ivars should have hidden linkage. | ||
| // Check that in the GNUstep v2 ABI, instance variable offset names include | ||
| // type encodings (with @ mangled to \01 to avoid collisions with ELF symbol | ||
| // versions). | ||
| // CHECK: private unnamed_addr constant [12 x i8] c"@\22NSString\22\00" | ||
| // CHECK: @"__objc_ivar_offset_ANObject._stringIvar.\01" = hidden global i32 8 | ||
| NSString *_stringIvar; | ||
| @package | ||
| // CHECK: @__objc_ivar_offset_ANObject._intIvar.i = hidden global i32 16 | ||
| int _intIvar; | ||
| } | ||
| @end | ||
| @implementation ANObject @end | ||
|
|
||
| // Check that the ivar metadata contains 3 entries of the correct form and correctly sets the size. | ||
| // CHECK: @.objc_ivar_list = private global { i32, i64, [3 x { i8*, i8*, i32*, i32, i32 }] } { i32 3, i64 32, | ||
| // Check that we're emitting the extended type encoding for the string ivar. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| // RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s | ||
|
|
||
| @protocol X | ||
| @optional | ||
| - (id)x; | ||
| @required | ||
| + (void*)y; | ||
| @property int reqProp; | ||
| @optional | ||
| @property int optProp; | ||
| @end | ||
|
|
||
| // Check that we get some plausible-looking method lists. | ||
| // CHECK: internal global { i32, i32, [2 x { i8*, i8* }] } { i32 2, i32 16, | ||
| // CHECK-SAME: @".objc_selector_reqProp_i16\010:8" | ||
| // CHECK-SAME: @".objc_selector_setReqProp:_v20\010:8i16" | ||
| // CHECK: internal global { i32, i32, [3 x { i8*, i8* }] } { i32 3, i32 16, | ||
| // CHECK-SAME: @".objc_selector_x_\0116\010:8" | ||
| // CHECK-SAME: @".objc_selector_optProp_i16\010:8" | ||
| // CHECK-SAME: @".objc_selector_setOptProp:_v20\010:8i16" | ||
|
|
||
|
|
||
| // Check that we're emitting the protocol and a correctly initialised | ||
| // indirection variable. | ||
| // CHECK: @._OBJC_PROTOCOL_X = global | ||
| // CHECK-SAME: , section "__objc_protocols", comdat, align 8 | ||
| // CHECK: @._OBJC_REF_PROTOCOL_X = global | ||
| // CHECK-SAME: @._OBJC_PROTOCOL_X | ||
| // CHECK-SAME: , section "__objc_protocol_refs", align 8 | ||
|
|
||
|
|
||
| // Check that we load from the indirection variable on protocol references. | ||
| // CHECK: define i8* @x() | ||
| // CHECK: = load | ||
| // CHECK-SAME: @._OBJC_REF_PROTOCOL_X, align 8 | ||
| void *x() | ||
| { | ||
| return @protocol(X); | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters