| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 
 | // RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -no-enable-noundef-analysis -o - %s | FileCheck %s
#include "literal-support.h"
// Check the various selector names we'll be using, in order.
// CHECK: c"numberWithInt:\00"
// CHECK: c"numberWithUnsignedInt:\00"
// CHECK: c"numberWithUnsignedLongLong:\00"
// CHECK: c"numberWithChar:\00"
// CHECK: c"arrayWithObjects:count:\00"
// CHECK: c"dictionaryWithObjects:forKeys:count:\00"
// CHECK: c"prop\00"
// CHECK-LABEL: define{{.*}} void @test_numeric()
void test_numeric(void) {
  // CHECK: {{call.*objc_msgSend.*i32 17.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}}
  id ilit = @17;
  // CHECK: {{call.*objc_msgSend.*i32 25.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}}
  id ulit = @25u;
  // CHECK: {{call.*objc_msgSend.*i64 42.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}}
  id ulllit = @42ull;
  // CHECK: {{call.*objc_msgSend.*i8 signext 97.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}}
  id charlit = @'a';
  // CHECK: call void @llvm.objc.release
  // CHECK: call void @llvm.lifetime.end
  // CHECK: call void @llvm.objc.release
  // CHECK: call void @llvm.lifetime.end
  // CHECK: call void @llvm.objc.release
  // CHECK: call void @llvm.lifetime.end
  // CHECK: call void @llvm.objc.release
  // CHECK: call void @llvm.lifetime.end
  // CHECK-NEXT: ret void
}
// CHECK-LABEL: define{{.*}} void @test_array
void test_array(id a, id b) {
  // CHECK: [[A:%.*]] = alloca ptr,
  // CHECK: [[B:%.*]] = alloca ptr,
  // Retaining parameters
  // CHECK: call ptr @llvm.objc.retain(ptr
  // CHECK: call ptr @llvm.objc.retain(ptr
  // Constructing the array
  // CHECK:      [[T0:%.*]] = getelementptr inbounds [2 x ptr], ptr [[OBJECTS:%[A-Za-z0-9]+]], i64 0, i64 0
  // CHECK-NEXT: [[V0:%.*]] = load ptr, ptr [[A]],
  // CHECK-NEXT: store ptr [[V0]], ptr [[T0]]
  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x ptr], ptr [[OBJECTS]], i64 0, i64 1
  // CHECK-NEXT: [[V1:%.*]] = load ptr, ptr [[B]],
  // CHECK-NEXT: store ptr [[V1]], ptr [[T0]]
  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr @"OBJC_CLASSLIST
  // CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES
  // CHECK-NEXT: [[T3:%.*]] = call ptr @objc_msgSend(ptr [[T0]], ptr [[SEL]], ptr [[OBJECTS]], i64 2) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
  // CHECK: call void (...) @llvm.objc.clang.arc.use(ptr [[V0]], ptr [[V1]])
  id arr = @[a, b];
  // CHECK: call void @llvm.objc.release
  // CHECK: call void @llvm.objc.release
  // CHECK: call void @llvm.objc.release
  // CHECK-NEXT: ret void
}
// CHECK-LABEL: define{{.*}} void @test_dictionary
void test_dictionary(id k1, id o1, id k2, id o2) {
  // CHECK: [[K1:%.*]] = alloca ptr,
  // CHECK: [[O1:%.*]] = alloca ptr,
  // CHECK: [[K2:%.*]] = alloca ptr,
  // CHECK: [[O2:%.*]] = alloca ptr,
  // Retaining parameters
  // CHECK: call ptr @llvm.objc.retain(ptr
  // CHECK: call ptr @llvm.objc.retain(ptr
  // CHECK: call ptr @llvm.objc.retain(ptr
  // CHECK: call ptr @llvm.objc.retain(ptr
  // Constructing the arrays
  // CHECK:      [[T0:%.*]] = getelementptr inbounds [2 x ptr], ptr [[KEYS:%[A-Za-z0-9]+]], i64 0, i64 0
  // CHECK-NEXT: [[V0:%.*]] = load ptr, ptr [[K1]],
  // CHECK-NEXT: store ptr [[V0]], ptr [[T0]]
  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x ptr], ptr [[OBJECTS:%[A-Za-z0-9]+]], i64 0, i64 0
  // CHECK-NEXT: [[V1:%.*]] = load ptr, ptr [[O1]],
  // CHECK-NEXT: store ptr [[V1]], ptr [[T0]]
  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x ptr], ptr [[KEYS]], i64 0, i64 1
  // CHECK-NEXT: [[V2:%.*]] = load ptr, ptr [[K2]],
  // CHECK-NEXT: store ptr [[V2]], ptr [[T0]]
  // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [2 x ptr], ptr [[OBJECTS]], i64 0, i64 1
  // CHECK-NEXT: [[V3:%.*]] = load ptr, ptr [[O2]],
  // CHECK-NEXT: store ptr [[V3]], ptr [[T0]]
  // Constructing the dictionary
  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr @"OBJC_CLASSLIST
  // CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES
  // CHECK-NEXT: [[T4:%.*]] = call ptr @objc_msgSend(ptr [[T0]], ptr [[SEL]], ptr [[OBJECTS]], ptr [[KEYS]], i64 2) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T4]])
  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[V0]], ptr [[V1]], ptr [[V2]], ptr [[V3]])
  id dict = @{ k1 : o1, k2 : o2 };
  // CHECK: call void @llvm.objc.release
  // CHECK: call void @llvm.objc.release
  // CHECK: call void @llvm.objc.release
  // CHECK: call void @llvm.objc.release
  // CHECK: call void @llvm.objc.release
  // CHECK-NEXT: ret void
}
@interface A
@end
@interface B
@property (retain) A* prop;
@end
// CHECK-LABEL: define{{.*}} void @test_property
void test_property(B *b) {
  // Retain parameter
  // CHECK: call ptr @llvm.objc.retain
  // CHECK:      [[T0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[OBJECTS:%.*]], i64 0, i64 0
  // Invoke 'prop'
  // CHECK:      [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES
  // CHECK-NEXT: [[V0:%.*]] = call ptr @objc_msgSend(ptr {{.*}}, ptr [[SEL]]) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[V0]])
  // Store to array.
  // CHECK-NEXT: store ptr [[V0]], ptr [[T0]]
  // Invoke arrayWithObjects:count:
  // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr @"OBJC_CLASSLIST
  // CHECK-NEXT: [[SEL:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES
  // CHECK-NEXT: [[T3:%.*]] = call ptr @objc_msgSend(ptr [[T0]], ptr [[SEL]], ptr [[OBJECTS]], i64 1) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T3]])
  // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(ptr [[V0]])
  // CHECK-NEXT: store
  id arr = @[ b.prop ];
  // Release b.prop
  // CHECK-NEXT: call void @llvm.objc.release(ptr [[V0]])
  // Destroy arr
  // CHECK: call void @llvm.objc.release
  // Destroy b
  // CHECK: call void @llvm.objc.release
  // CHECK-NEXT: ret void
}
 |