// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s
;
;
NSArray *
// CHECK: define{{.*}} [[NSARRAY:%.*]]* @_Z7nsarrayv()
void ;
// rdar://problem/9315552
// The analogous ObjC testcase test46 in arr.m.
void
// rdar://problem/9320648
;
// CHECK: define internal noundef i8* @"\01-[Test1 .cxx_construct]"(
// CHECK: call void @_ZN12Test1_helperC1Ev(
// CHECK-NEXT: load
// CHECK-NEXT: bitcast
// CHECK-NEXT: ret i8*
void
;
// CHECK-LABEL: define{{.*}} void @_Z6test3513Test35_HelperPS_
void
// CHECK-LABEL: define{{.*}} void @_Z7test35b13Test35_HelperPS_
void
// rdar://problem/9603128
// CHECK-LABEL: define{{.*}} i8* @_Z6test36P11objc_object(
id
// Template instantiation side of rdar://problem/9817306
void
extern ;
;
// CHECK-LABEL: define weak_odr void @_Z6test37I6Test37EvPT_(
// CHECK: [[T2:%.*]] = call noundef [[NSARRAY]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to [[NSARRAY]]* (i8*, i8*)*)({{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T2]])
// Make sure it's not immediately released before starting the iteration.
// CHECK-NEXT: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8*
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: @objc_msgSend
// This bitcast is for the mutation check.
// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8*
// CHECK-NEXT: @objc_enumerationMutation
// This bitcast is for the 'next' message send.
// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8*
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: @objc_msgSend
// This bitcast is for the final release.
// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8*
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
void
// CHECK-LABEL: define weak_odr void @_Z12send_releaseIiEvv(
// CHECK: call noundef %0* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(
// CHECK-NEXT: bitcast
// CHECK-NEXT: call void @llvm.objc.release
// CHECK-NEXT: ret void
;
Test37 *
// CHECK-LABEL: define weak_odr noundef %2* @_Z16instantiate_initIiEP6Test37v
// CHECK: call noundef i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
// CHECK: call noundef i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
// CHECK: call i8* @llvm.objc.retain
// CHECK: call void @llvm.objc.release
// CHECK: call i8* @llvm.objc.autoreleaseReturnValue
;
// Just make sure that the AST invariants hold properly here,
// i.e. that we don't crash.
// The block should get bound in the full-expression outside
// the statement-expression.
;
// CHECK-LABEL: define weak_odr void @_ZN6Test38IiE4testEi(
;
// rdar://problem/11964832
;
;
;
id
// Note lack of autorelease.
// CHECK-LABEL: define{{.*}} i8* @_ZThn8_N6Test393barEv(
// CHECK: call noundef i8* @_ZN6Test393barEv(
// CHECK-NEXT: ret i8*
// rdar://13617051
// Just a basic correctness check that IR-gen still works after instantiating
// a non-dependent message send that requires writeback.
void ;
;
// CHECK-LABEL: define weak_odr void @_Z13test40_helperIiEvv()
// CHECK: [[X:%.*]] = alloca i8*
// CHECK-NEXT: [[TEMP:%.*]] = alloca i8*
// CHECK-NEXT: [[XP:%.*]] = bitcast i8** [[X]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XP]])
// CHECK-NEXT: store i8* null, i8** [[X]]
// CHECK: [[T0:%.*]] = load i8*, i8** [[X]]
// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP]]
// CHECK: @objc_msgSend
// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[TEMP]]
// CHECK-NEXT: call i8* @llvm.objc.retain(i8* [[T0]])
// Check that moves out of __weak variables are compiled to use objc_moveWeak.
void
// CHECK-LABEL: define{{.*}} void @_Z6test41OU6__weakP11objc_object
// CHECK: [[X:%.*]] = alloca i8**
// CHECK: [[Y:%.*]] = alloca i8*
// CHECK: [[T0:%.*]] = load i8**, i8*** [[X]]
// CHECK-NEXT: call void @llvm.objc.moveWeak(i8** [[Y]], i8** [[T0]])
// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[Y]])
void
// Check that the pointer returned by test42_0 is released after the full expression.
// CHECK-LABEL: define void @_Z6test42v()
// CHECK: %[[CALL:.*]] = call noundef i8* @_Z8test42_0v()
// CHECK: call void @_Z8test42_2OU15__autoreleasingP11objc_object(
// CHECK: call void @llvm.objc.release(i8* %[[CALL]])