summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2014-08-08 17:31:14 +0000
committerFariborz Jahanian <fjahanian@apple.com>2014-08-08 17:31:14 +0000
commit495bc3f5f6a1924dddfeb3c090520175e637af4d (patch)
tree691b5a3a8bccc2e4c587ee19079b7098067a08e0 /clang
parent241fd486eb4134361de5f571ed6b929d1603241a (diff)
downloadbcm5719-llvm-495bc3f5f6a1924dddfeb3c090520175e637af4d.tar.gz
bcm5719-llvm-495bc3f5f6a1924dddfeb3c090520175e637af4d.zip
Objective-C ARC. Use of non-retain/autorelease API
for building Objective-C array literals in ARC mode. rdar://17554063 llvm-svn: 215232
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Sema/Sema.h3
-rw-r--r--clang/lib/Sema/Sema.cpp1
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp41
-rw-r--r--clang/test/CodeGenObjC/Inputs/literal-support.h1
-rw-r--r--clang/test/CodeGenObjC/arc-literals.m22
-rw-r--r--clang/test/CodeGenObjCXX/Inputs/literal-support.h1
-rw-r--r--clang/test/CodeGenObjCXX/literals.mm13
-rw-r--r--clang/test/SemaObjC/arc.m7
-rw-r--r--clang/test/SemaObjC/objc-literal-comparison.m1
9 files changed, 69 insertions, 21 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ed31a9f86e2..f82974e274a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -685,6 +685,9 @@ public:
/// \brief The declaration of the initWithObjects:forKeys:count: method.
ObjCMethodDecl *InitDictionaryWithObjectsMethod;
+ /// \brief The declaration for + (id) alloc method used in [NSArray alloc]
+ ObjCMethodDecl *ArrayAllocObjectsMethod;
+
/// \brief The declaration for + (id) alloc method used in [NSDictionary alloc]
ObjCMethodDecl *DictAllocObjectsMethod;
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 4ed5aa8a287..205081b656a 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -98,6 +98,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
InitArrayWithObjectsMethod(nullptr),
NSDictionaryDecl(nullptr), DictionaryWithObjectsMethod(nullptr),
InitDictionaryWithObjectsMethod(nullptr),
+ ArrayAllocObjectsMethod(nullptr),
DictAllocObjectsMethod(nullptr),
GlobalNewDeleteDeclared(false),
TUKind(TUKind),
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index e4625bc98c2..786637c205e 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -630,6 +630,7 @@ ExprResult Sema::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
}
ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
+ bool Arc = getLangOpts().ObjCAutoRefCount;
// Look up the NSArray class, if we haven't done so already.
if (!NSArrayDecl) {
NamedDecl *IF = LookupSingleName(TUScope,
@@ -649,18 +650,45 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
return ExprError();
}
}
-
- // Find the arrayWithObjects:count: method, if we haven't done so already.
QualType IdT = Context.getObjCIdType();
+ if (Arc && !ArrayAllocObjectsMethod) {
+ // Find +[NSArray alloc] method.
+ IdentifierInfo *II = &Context.Idents.get("alloc");
+ Selector AllocSel = Context.Selectors.getSelector(0, &II);
+ ArrayAllocObjectsMethod = NSArrayDecl->lookupClassMethod(AllocSel);
+ if (!ArrayAllocObjectsMethod && getLangOpts().DebuggerObjCLiteral) {
+ ArrayAllocObjectsMethod = ObjCMethodDecl::Create(Context,
+ SourceLocation(), SourceLocation(), AllocSel,
+ IdT,
+ nullptr /*TypeSourceInfo */,
+ Context.getTranslationUnitDecl(),
+ false /*Instance*/, false/*isVariadic*/,
+ /*isPropertyAccessor=*/false,
+ /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
+ ObjCMethodDecl::Required,
+ false);
+ SmallVector<ParmVarDecl *, 1> Params;
+ ArrayAllocObjectsMethod->setMethodParams(Context, Params, None);
+ }
+ if (!ArrayAllocObjectsMethod) {
+ Diag(SR.getBegin(), diag::err_undeclared_alloc);
+ return ExprError();
+ }
+ }
+ // Find the arrayWithObjects:count: method, if we haven't done so already.
if (!ArrayWithObjectsMethod) {
Selector
- Sel = NSAPIObj->getNSArraySelector(NSAPI::NSArr_arrayWithObjectsCount);
- ObjCMethodDecl *Method = NSArrayDecl->lookupClassMethod(Sel);
+ Sel = NSAPIObj->getNSArraySelector(
+ Arc? NSAPI::NSArr_initWithObjectsCount : NSAPI::NSArr_arrayWithObjectsCount);
+ ObjCMethodDecl *Method =
+ Arc? NSArrayDecl->lookupInstanceMethod(Sel)
+ : NSArrayDecl->lookupClassMethod(Sel);
if (!Method && getLangOpts().DebuggerObjCLiteral) {
TypeSourceInfo *ReturnTInfo = nullptr;
Method = ObjCMethodDecl::Create(
Context, SourceLocation(), SourceLocation(), Sel, IdT, ReturnTInfo,
- Context.getTranslationUnitDecl(), false /*Instance*/,
+ Context.getTranslationUnitDecl(),
+ Arc /*Instance for Arc, Class for MRR*/,
false /*isVariadic*/,
/*isPropertyAccessor=*/false,
/*isImplicitlyDeclared=*/true, /*isDefined=*/false,
@@ -740,7 +768,8 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
return MaybeBindToTemporary(
ObjCArrayLiteral::Create(Context, Elements, Ty,
- ArrayWithObjectsMethod, nullptr, SR));
+ ArrayWithObjectsMethod,
+ ArrayAllocObjectsMethod, SR));
}
ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR,
diff --git a/clang/test/CodeGenObjC/Inputs/literal-support.h b/clang/test/CodeGenObjC/Inputs/literal-support.h
index 475c86af241..caa69c24caf 100644
--- a/clang/test/CodeGenObjC/Inputs/literal-support.h
+++ b/clang/test/CodeGenObjC/Inputs/literal-support.h
@@ -30,6 +30,7 @@ typedef unsigned char BOOL;
@interface NSArray (NSArrayCreation)
+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
+- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt;
@end
@interface NSDictionary : NSObject
diff --git a/clang/test/CodeGenObjC/arc-literals.m b/clang/test/CodeGenObjC/arc-literals.m
index 427c65aa054..29f2b45a808 100644
--- a/clang/test/CodeGenObjC/arc-literals.m
+++ b/clang/test/CodeGenObjC/arc-literals.m
@@ -8,7 +8,7 @@
// CHECK: c"numberWithUnsignedInt:\00"
// CHECK: c"numberWithUnsignedLongLong:\00"
// CHECK: c"numberWithChar:\00"
-// CHECK: c"arrayWithObjects:count:\00"
+// CHECK: c"initWithObjects:count:\00"
// CHECK: c"initWithObjects:forKeys:count:\00"
// CHECK: c"prop\00"
@@ -53,10 +53,12 @@ void test_array(id a, id b) {
// 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:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2)
- // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]])
- // CHECK: call void (...)* @clang.arc.use(i8* [[V0]], i8* [[V1]])
+
+ // CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* [[T1]], i8* [[SEL]])
+ // CHECK-NEXT: [[T9:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+ // CHECK-NEXT: [[T10:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
+ // CHECK-NEXT: [[ARRAYINIT:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8**, i64)*)(i8* [[ALLOC]], i8* [[T9]], i8** [[T10]], i64 2)
+ // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V0]], i8* [[V1]])
id arr = @[a, b];
// CHECK: call void @objc_release
@@ -140,13 +142,15 @@ void test_property(B *b) {
// Store to array.
// CHECK-NEXT: store i8* [[V1]], i8** [[T0]]
- // Invoke arrayWithObjects:count:
+ // Invoke initWithObjects:count:
// 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 [1 x i8*]* [[OBJECTS]] to i8**
- // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1)
- // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue(i8* [[T3]])
+
+ // CHECK-NEXT: [[ALLOC:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* [[T1]], i8* [[SEL]])
+ // CHECK-NEXT: [[T9:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+ // CHECK-NEXT: [[T10:%.*]] = bitcast [1 x i8*]* [[OBJECTS]] to i8**
+ // CHECK-NEXT: [[INIT:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8**, i64)*)(i8* [[ALLOC]], i8* [[T9]], i8** [[T10]], i64 1)
// CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V1]])
// CHECK-NEXT: bitcast
// CHECK-NEXT: bitcast
diff --git a/clang/test/CodeGenObjCXX/Inputs/literal-support.h b/clang/test/CodeGenObjCXX/Inputs/literal-support.h
index fc80d88b13d..174ec3a83cf 100644
--- a/clang/test/CodeGenObjCXX/Inputs/literal-support.h
+++ b/clang/test/CodeGenObjCXX/Inputs/literal-support.h
@@ -30,6 +30,7 @@ typedef unsigned char BOOL;
@interface NSArray (NSArrayCreation)
+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
+- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt;
@end
@interface NSDictionary : NSObject
diff --git a/clang/test/CodeGenObjCXX/literals.mm b/clang/test/CodeGenObjCXX/literals.mm
index f21bba75f37..42ec4bee388 100644
--- a/clang/test/CodeGenObjCXX/literals.mm
+++ b/clang/test/CodeGenObjCXX/literals.mm
@@ -33,8 +33,15 @@ void test_array() {
// CHECK: store i8* [[RET1]], i8** [[ELEMENT1]]
// Build the array
- // CHECK: {{invoke.*@objc_msgSend}}
- // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+ // CHECK: [[T4:%.*]] = load [[CLASS:%.*]]** @"\01L_OBJC_CLASSLIST_REFERENCES_$_"
+ // CHECK-NEXT: [[T5:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
+ // CHECK-NEXT: [[T6:%.*]] = bitcast [[CLASS]]* [[T4]] to i8*
+ // CHECK-NEXT: [[ALLOC:%.*]] = {{invoke.*@objc_msgSend}}
+
+ // CHECK: [[T7:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
+ // CHECK-NEXT: [[T8:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
+ // CHECK-NEXT: [[INIT:%.*]] = {{invoke.*@objc_msgSend}}
+
id arr = @[ X(), Y() ];
// Destroy temporaries
@@ -81,7 +88,7 @@ void test_array_instantiation() {
// Build the array
// CHECK: {{invoke.*@objc_msgSend}}
- // CHECK: call i8* @objc_retainAutoreleasedReturnValue
+
id arr = @[ X(), Y() ];
// Destroy temporaries
diff --git a/clang/test/SemaObjC/arc.m b/clang/test/SemaObjC/arc.m
index e60fd970f38..285c7371ccc 100644
--- a/clang/test/SemaObjC/arc.m
+++ b/clang/test/SemaObjC/arc.m
@@ -21,8 +21,9 @@ id CFBridgingRelease(CFTypeRef);
@interface NSNumber
+ (NSNumber *)numberWithInt:(int)value;
@end
-@interface NSArray <NSFastEnumeration>
+@interface NSArray : NSObject <NSFastEnumeration>
+ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
+- (id)initWithObjects:(const id [])objects count:(NSUInteger)cnt;
@end
void test0(void (*fn)(int), int val) {
@@ -748,7 +749,7 @@ void rdar12569201(id key, id value) {
// Declarations.
__weak id x = @"foo"; // no-warning
__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 z = @[ value ]; // expected-warning {{assigning retained object to 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}}
__weak id e = @(42); // expected-warning {{assigning numeric literal to a weak variable; object will be released after assignment}}
@@ -756,7 +757,7 @@ void rdar12569201(id key, id value) {
// Assignments.
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}}
+ z = @[ value ]; // expected-warning {{assigning retained object to 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}}
e = @(42); // expected-warning {{assigning numeric literal to a weak variable; object will be released after assignment}}
diff --git a/clang/test/SemaObjC/objc-literal-comparison.m b/clang/test/SemaObjC/objc-literal-comparison.m
index febce3a2672..409d7134ef3 100644
--- a/clang/test/SemaObjC/objc-literal-comparison.m
+++ b/clang/test/SemaObjC/objc-literal-comparison.m
@@ -29,6 +29,7 @@ typedef signed char BOOL;
@interface NSArray : NSObject
+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
+- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt;
@end
@interface NSDictionary : NSObject
OpenPOWER on IntegriCloud