forked from OSchip/llvm-project
GNUstep Objective-C ABI version 2
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
This commit is contained in:
parent
b81848272d
commit
79356eefc0
|
@ -1620,6 +1620,14 @@ public:
|
|||
bool isUTF32() const { return Kind == UTF32; }
|
||||
bool isPascal() const { return IsPascal; }
|
||||
|
||||
bool containsNonAscii() const {
|
||||
StringRef Str = getString();
|
||||
for (unsigned i = 0, e = Str.size(); i != e; ++i)
|
||||
if (!isASCII(Str[i]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool containsNonAsciiOrNull() const {
|
||||
StringRef Str = getString();
|
||||
for (unsigned i = 0, e = Str.size(); i != e; ++i)
|
||||
|
|
|
@ -193,6 +193,8 @@ def err_drv_mg_requires_m_or_mm : Error<
|
|||
"option '-MG' requires '-M' or '-MM'">;
|
||||
def err_drv_unknown_objc_runtime : Error<
|
||||
"unknown or ill-formed Objective-C runtime '%0'">;
|
||||
def err_drv_gnustep_objc_runtime_incompatible_binary : Error<
|
||||
"GNUstep Objective-C runtime version %0 incompatible with target binary format">;
|
||||
def err_drv_emit_llvm_link : Error<
|
||||
"-emit-llvm cannot be used when linking">;
|
||||
def err_drv_optimization_remark_pattern : Error<
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4852,6 +4852,13 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
|
|||
getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime)
|
||||
<< value;
|
||||
}
|
||||
if ((runtime.getKind() == ObjCRuntime::GNUstep) &&
|
||||
(runtime.getVersion() >= VersionTuple(2, 0)))
|
||||
if (!getToolChain().getTriple().isOSBinFormatELF()) {
|
||||
getToolChain().getDriver().Diag(
|
||||
diag::err_drv_gnustep_objc_runtime_incompatible_binary)
|
||||
<< runtime.getVersion().getMajor();
|
||||
}
|
||||
|
||||
runtimeArg->render(args, cmdArgs);
|
||||
return runtime;
|
||||
|
@ -4945,7 +4952,7 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
|
|||
// Legacy behaviour is to target the gnustep runtime if we are in
|
||||
// non-fragile mode or the GCC runtime in fragile mode.
|
||||
if (isNonFragile)
|
||||
runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1, 6));
|
||||
runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(2, 0));
|
||||
else
|
||||
runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
|
||||
}
|
||||
|
|
|
@ -645,6 +645,19 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
|
|||
if (LangOpts.ObjCRuntime.isNeXTFamily())
|
||||
Builder.defineMacro("__NEXT_RUNTIME__");
|
||||
|
||||
if (LangOpts.ObjCRuntime.getKind() == ObjCRuntime::GNUstep) {
|
||||
auto version = LangOpts.ObjCRuntime.getVersion();
|
||||
std::string versionString = "1";
|
||||
// Don't rely on the tuple argument, because we can be asked to target
|
||||
// later ABIs than we actually support, so clamp these values to those
|
||||
// currently supported
|
||||
if (version >= VersionTuple(2, 0))
|
||||
Builder.defineMacro("__OBJC_GNUSTEP_RUNTIME_ABI__", "20");
|
||||
else
|
||||
Builder.defineMacro("__OBJC_GNUSTEP_RUNTIME_ABI__",
|
||||
"1" + Twine(std::min(8U, version.getMinor().getValueOr(0))));
|
||||
}
|
||||
|
||||
if (LangOpts.ObjCRuntime.getKind() == ObjCRuntime::ObjFW) {
|
||||
VersionTuple tuple = LangOpts.ObjCRuntime.getVersion();
|
||||
|
||||
|
|
|
@ -14,5 +14,18 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-macho -fobjc-runtime=gcc -fconstant-string-class NSConstantString -emit-llvm -o %t %s
|
||||
// RUN: FileCheck --check-prefix=CHECK-GNU-WITH-CLASS < %t %s
|
||||
// CHECK-GNU-WITH-CLASS: NSConstantString
|
||||
id a = @"Hello World!";
|
||||
//
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -fobjc-runtime=gnustep-2.0 -emit-llvm -o %t %s
|
||||
// RUN: FileCheck --check-prefix=CHECK-GNUSTEP2 < %t %s
|
||||
|
||||
// CHECK-GNUSTEP2: @._OBJC_CLASS_NSConstantString = external global i8*
|
||||
// CHECK-GNUSTEP2: @0 = private unnamed_addr constant [13 x i8] c"Hello World!\00", align 1
|
||||
// CHECK-GNUSTEP2: @.objc_string = private global { i8**, i32, i32, i32, i32, i8* } { i8** @._OBJC_CLASS_NSConstantString, i32 0, i32 12, i32 12, i32 0, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @0, i64 0, i64 0) }, section "__objc_constant_string", align 8
|
||||
// CHECK-GNUSTEP2: @b = global i8* inttoptr (i64 -3340545023602065388 to i8*), align 8
|
||||
// CHECK-GNUSTEP2: @.objc_str_Hello_World = linkonce_odr hidden global { i8**, i32, i32, i32, i32, i8* } { i8** @._OBJC_CLASS_NSConstantString, i32 0, i32 11, i32 11, i32 0, i8* getelementptr inbounds ([12 x i8], [12 x i8]* @1, i64 0, i64 0) }, section "__objc_constant_string", comdat, align 8
|
||||
// CHECK-GNUSTEP2: @c =
|
||||
// CHECK-SAME-GNUSTEP2: @.objc_str_Hello_World
|
||||
//
|
||||
id a = @"Hello World!";
|
||||
id b = @"hi";
|
||||
id c = @"Hello World";
|
||||
|
|
|
@ -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
|
|
@ -9,17 +9,18 @@ __attribute__((objc_root_class))
|
|||
@implementation Z
|
||||
@end
|
||||
|
||||
|
||||
// CHECK: @.objc_protocol_list = internal global { i8*, i32, [0 x i8*] } zeroinitializer, align 4
|
||||
// CHECK: @.objc_method_list = internal global { i32, [0 x { i8*, i8* }] } zeroinitializer, align 4
|
||||
// CHECK: @.objc_protocol_name = private unnamed_addr constant [2 x i8] c"X\00", align 1
|
||||
// CHECK: @.objc_protocol = internal global { i8*, i8*, { i8*, i32, [0 x i8*] }*, { i32, [0 x { i8*, i8* }] }*, { i32, [0 x { i8*, i8* }] }*, { i32, [0 x { i8*, i8* }] }*, { i32, [0 x { i8*, i8* }] }*, i8*, i8* } {
|
||||
// CHECK: @._OBJC_PROTOCOL_X = internal global { i8*, i8*, { i8*, i32, [0 x i8*] }*, i8*, i8*, i8*, i8*, i8*, i8* } {
|
||||
// CHECK-SAME: i8* inttoptr (i32 3 to i8*),
|
||||
// CHECK-SAME: i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.objc_protocol_name, i32 0, i32 0),
|
||||
// CHECK-SAME: { i8*, i32, [0 x i8*] }* @.objc_protocol_list,
|
||||
// CHECK-SAME: { i32, [0 x { i8*, i8* }] }* @.objc_method_list,
|
||||
// CHECK-SAME: { i32, [0 x { i8*, i8* }] }* @.objc_method_list,
|
||||
// CHECK-SAME: { i32, [0 x { i8*, i8* }] }* @.objc_method_list,
|
||||
// CHECK-SAME: { i32, [0 x { i8*, i8* }] }* @.objc_method_list,
|
||||
// CHECK-SAME: i8* null,
|
||||
// CHECK-SAME: { i8*, i32, [0 x i8*] }* @.objc_protocol_list
|
||||
// CHECK-SAME: { i32, [0 x { i8*, i8* }] }* @.objc_method_list
|
||||
// CHECK-SAME: { i32, [0 x { i8*, i8* }] }* @.objc_method_list
|
||||
// CHECK-SAME: { i32, [0 x { i8*, i8* }] }* @.objc_method_list
|
||||
// CHECK-SAME: { i32, [0 x { i8*, i8* }] }* @.objc_method_list
|
||||
// CHECK-SAME: i8* null
|
||||
// CHECK-SAME: i8* null
|
||||
// CHECK-SAME: }, align 4
|
||||
|
|
|
@ -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)
|
||||
|
|
@ -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
|
|
@ -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"
|
||||
|
|
@ -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.
|
|
@ -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);
|
||||
}
|
|
@ -29,10 +29,10 @@ int main() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// CHECK: @0 = private unnamed_addr constant [12 x i8] c"_stringIvar\00"
|
||||
// CHECK: @1 = private unnamed_addr constant [12 x i8] c"@\22NSString\22\00"
|
||||
// CHECK: @2 = private unnamed_addr constant [9 x i8] c"_intIvar\00"
|
||||
// CHECK: @3 = private unnamed_addr constant [2 x i8] c"i\00"
|
||||
// CHECK: = private unnamed_addr constant [12 x i8] c"_stringIvar\00"
|
||||
// CHECK: = private unnamed_addr constant [12 x i8] c"@\22NSString\22\00"
|
||||
// CHECK: = private unnamed_addr constant [9 x i8] c"_intIvar\00"
|
||||
// CHECK: = private unnamed_addr constant [2 x i8] c"i\00"
|
||||
|
||||
@interface Class1 {
|
||||
int : 3;
|
||||
|
|
|
@ -9002,6 +9002,13 @@
|
|||
// RUN: %clang_cc1 -x c++ -triple sparc-rtems-elf -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GNUSOURCE %s
|
||||
// GNUSOURCE:#define _GNU_SOURCE 1
|
||||
//
|
||||
// Check that the GNUstep Objective-C ABI defines exist and are clamped at the
|
||||
// highest supported version.
|
||||
// RUN: %clang_cc1 -x objective-c -triple i386-unknown-freebsd -fobjc-runtime=gnustep-1.9 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GNUSTEP1 %s
|
||||
// GNUSTEP1:#define __OBJC_GNUSTEP_RUNTIME_ABI__ 18
|
||||
// RUN: %clang_cc1 -x objective-c -triple i386-unknown-freebsd -fobjc-runtime=gnustep-2.5 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GNUSTEP2 %s
|
||||
// GNUSTEP2:#define __OBJC_GNUSTEP_RUNTIME_ABI__ 20
|
||||
//
|
||||
// RUN: %clang_cc1 -x c++ -std=c++98 -fno-rtti -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix NORTTI %s
|
||||
// NORTTI: #define __GXX_ABI_VERSION {{.*}}
|
||||
// NORTTI-NOT:#define __GXX_RTTI
|
||||
|
|
Loading…
Reference in New Issue