From: Fariborz Jahanian Date: Thu, 7 Aug 2014 20:57:35 +0000 (+0000) Subject: Objective-C arc. Switch the Objective-C dictionary literal in ARC mode X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=62e61562427fa3514633c3e91093b8f4390ad7bc;p=clang Objective-C arc. Switch the Objective-C dictionary literal in ARC mode to use non-retain/autorelease API variants of ObjC objects. wip. rdar://17554063 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@215146 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index a67e900a17..fe30d373df 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -185,6 +185,15 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, = InterfacePointerType->getObjectType()->getInterface(); CGObjCRuntime &Runtime = CGM.getObjCRuntime(); llvm::Value *Receiver = Runtime.GetClass(*this, Class); + if (AllocMethod) { + // Generate the "alloc" message send. + CallArgList Args; + Selector AllocMethodSel = AllocMethod->getSelector(); + RValue result = Runtime.GenerateMessageSend( + *this, ReturnValueSlot(), AllocMethod->getReturnType(), AllocMethodSel, + Receiver, Args, Class, AllocMethod); + Receiver = result.getScalarVal(); + } // Generate the message send. RValue result = Runtime.GenerateMessageSend( diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index b4d3d4de36..e4625bc98c 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -792,19 +792,22 @@ ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, } } - // Find the dictionaryWithObjects:forKeys:count: method, if we haven't done - // so already. + // Find the dictionaryWithObjects:forKeys:count: or initWithObjects:forKeys:count: + // (for arc) method, if we haven't done so already. if (!DictionaryWithObjectsMethod) { - Selector Sel = NSAPIObj->getNSDictionarySelector( - NSAPI::NSDict_dictionaryWithObjectsForKeysCount); - ObjCMethodDecl *Method = NSDictionaryDecl->lookupClassMethod(Sel); + Selector Sel = + NSAPIObj->getNSDictionarySelector(Arc? NSAPI::NSDict_initWithObjectsForKeysCount + : NSAPI::NSDict_dictionaryWithObjectsForKeysCount); + ObjCMethodDecl *Method = + Arc ? NSDictionaryDecl->lookupInstanceMethod(Sel) + : NSDictionaryDecl->lookupClassMethod(Sel); if (!Method && getLangOpts().DebuggerObjCLiteral) { Method = ObjCMethodDecl::Create(Context, SourceLocation(), SourceLocation(), Sel, IdT, nullptr /*TypeSourceInfo */, Context.getTranslationUnitDecl(), - false /*Instance*/, false/*isVariadic*/, + Arc /*Instance for Arc, Class for MRR*/, false/*isVariadic*/, /*isPropertyAccessor=*/false, /*isImplicitlyDeclared=*/true, /*isDefined=*/false, ObjCMethodDecl::Required, diff --git a/test/CodeGenObjC/Inputs/literal-support.h b/test/CodeGenObjC/Inputs/literal-support.h index fc80d88b13..475c86af24 100644 --- a/test/CodeGenObjC/Inputs/literal-support.h +++ b/test/CodeGenObjC/Inputs/literal-support.h @@ -34,6 +34,7 @@ typedef unsigned char BOOL; @interface NSDictionary : NSObject + (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +- (instancetype)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; @end #endif // OBJC_LITERAL_SUPPORT_H diff --git a/test/CodeGenObjC/arc-literals.m b/test/CodeGenObjC/arc-literals.m index 19a5516dc7..427c65aa05 100644 --- a/test/CodeGenObjC/arc-literals.m +++ b/test/CodeGenObjC/arc-literals.m @@ -9,7 +9,7 @@ // CHECK: c"numberWithUnsignedLongLong:\00" // CHECK: c"numberWithChar:\00" // CHECK: c"arrayWithObjects:count:\00" -// CHECK: c"dictionaryWithObjects:forKeys:count:\00" +// CHECK: c"initWithObjects:forKeys:count:\00" // CHECK: c"prop\00" // CHECK-LABEL: define void @test_numeric() @@ -96,10 +96,12 @@ void test_dictionary(id k1, id o1, id k2, id o2) { // CHECK-NEXT: [[T0:%.*]] = load [[CLASS_T:%.*]]** @"\01L_OBJC_CLASSLIST // CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8** - // CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8** - // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2) - // CHECK-NEXT: [[T5:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T4]]) + + // CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* [[T1]], i8* [[SEL]]) + // CHECK-NEXT: [[T15:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES + // CHECK-NEXT: [[T16:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8** + // CHECK-NEXT: [[T17:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8** + // CHECK-NEXT: [[INIT:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8**, i8**, i64)*)(i8* [[ALLOC]], i8* [[T15]], i8** [[T16]], i8** [[T17]], i64 2) // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]]) id dict = @{ k1 : o1, k2 : o2 }; diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m index c162d7fdf7..e60fd970f3 100644 --- a/test/SemaObjC/arc.m +++ b/test/SemaObjC/arc.m @@ -12,6 +12,7 @@ id CFBridgingRelease(CFTypeRef); @interface NSDictionary : NSObject + (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt; - (void)setObject:(id)object forKeyedSubscript:(id)key; +- (instancetype)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt; @end @class NSFastEnumerationState; @protocol NSFastEnumeration @@ -746,7 +747,7 @@ void _NSCalcBeze(NSColor* color, NSColor* bezelColors[]); // expected-error {{mu void rdar12569201(id key, id value) { // Declarations. __weak id x = @"foo"; // no-warning - __weak id y = @{ key : value }; // expected-warning {{assigning dictionary literal to a weak variable; object will be released after assignment}} + __weak id y = @{ key : value }; // expected-warning {{assigning retained object to weak variable; object will be released after assignment}} __weak id z = @[ value ]; // expected-warning {{assigning array literal to a weak variable; object will be released after assignment}} __weak id b = ^() {}; // expected-warning {{assigning block literal to a weak variable; object will be released after assignment}} __weak id n = @42; // expected-warning {{assigning numeric literal to a weak variable; object will be released after assignment}} @@ -754,7 +755,7 @@ void rdar12569201(id key, id value) { __weak id m = @(41 + 1); // expected-warning {{assigning boxed expression to a weak variable; object will be released after assignment}} // Assignments. - y = @{ key : value }; // expected-warning {{assigning dictionary literal to a weak variable; object will be released after assignment}} + y = @{ key : value }; // expected-warning {{assigning retained object to weak variable; object will be released after assignment}} z = @[ value ]; // expected-warning {{assigning array literal to a weak variable; object will be released after assignment}} b = ^() {}; // expected-warning {{assigning block literal to a weak variable; object will be released after assignment}} n = @42; // expected-warning {{assigning numeric literal to a weak variable; object will be released after assignment}} diff --git a/test/SemaObjC/objc-literal-comparison.m b/test/SemaObjC/objc-literal-comparison.m index 68ac419ea2..febce3a267 100644 --- a/test/SemaObjC/objc-literal-comparison.m +++ b/test/SemaObjC/objc-literal-comparison.m @@ -10,6 +10,8 @@ typedef signed char BOOL; +@protocol NSCopying @end + @interface BaseObject + (instancetype)new; @end @@ -31,6 +33,7 @@ typedef signed char BOOL; @interface NSDictionary : NSObject + (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +- (instancetype)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; @end @interface NSString : NSObject