1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 2// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s 3 4template <typename T> 5struct Foo { 6private: 7 T x; 8 9public: 10 Foo(T x) : x(x) {} 11 ~Foo() {} 12 13 T get() { return x; } 14 void set(T _x) { x = _x; } 15}; 16 17template <typename T> 18struct Bar { 19private: 20 struct Foo<T> foo; 21 22public: 23 Bar(T x) : foo(x) {} 24 ~Bar() {} 25 26 T get() { return foo.get(); } 27 void set(T _x) { foo.set(_x); } 28}; 29 30template <typename T> 31struct Baz : Foo<T> { 32public: 33 Baz(T x) : Foo<T>(x) {} 34 ~Baz() {} 35}; 36 37// These two specializations should generate lines for all of Foo's methods. 38 39// CHECK-LABEL: @_ZN3FooIcEC1Ec( 40// CHECK-NEXT: entry: 41// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 42// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i8, align 1 43// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 44// CHECK-NEXT: store i8 [[X:%.*]], ptr [[X_ADDR]], align 1 45// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 46// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[X_ADDR]], align 1 47// CHECK-NEXT: call void @_ZN3FooIcEC2Ec(ptr noundef nonnull align 1 dereferenceable(1) [[THIS1]], i8 noundef signext [[TMP0]]) 48// CHECK-NEXT: ret void 49// 50// CHECK-LABEL: @_ZN3FooIcED1Ev( 51// CHECK-NEXT: entry: 52// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 53// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 54// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 55// CHECK-NEXT: call void @_ZN3FooIcED2Ev(ptr noundef nonnull align 1 dereferenceable(1) [[THIS1]]) #[[ATTR1:[0-9]+]] 56// CHECK-NEXT: ret void 57// 58// CHECK-LABEL: @_ZN3FooIcE3getEv( 59// CHECK-NEXT: entry: 60// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 61// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 62// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 63// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_FOO:%.*]], ptr [[THIS1]], i32 0, i32 0 64// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[X]], align 1 65// CHECK-NEXT: ret i8 [[TMP0]] 66// 67// CHECK-LABEL: @_ZN3FooIcE3setEc( 68// CHECK-NEXT: entry: 69// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 70// CHECK-NEXT: [[_X_ADDR:%.*]] = alloca i8, align 1 71// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 72// CHECK-NEXT: store i8 [[_X:%.*]], ptr [[_X_ADDR]], align 1 73// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 74// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[_X_ADDR]], align 1 75// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_FOO:%.*]], ptr [[THIS1]], i32 0, i32 0 76// CHECK-NEXT: store i8 [[TMP0]], ptr [[X]], align 1 77// CHECK-NEXT: ret void 78// 79template struct Foo<char>; 80 81// CHECK-LABEL: @_ZN3FooIsEC1Es( 82// CHECK-NEXT: entry: 83// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 84// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i16, align 2 85// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 86// CHECK-NEXT: store i16 [[X:%.*]], ptr [[X_ADDR]], align 2 87// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 88// CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[X_ADDR]], align 2 89// CHECK-NEXT: call void @_ZN3FooIsEC2Es(ptr noundef nonnull align 2 dereferenceable(2) [[THIS1]], i16 noundef signext [[TMP0]]) 90// CHECK-NEXT: ret void 91// 92// CHECK-LABEL: @_ZN3FooIsED1Ev( 93// CHECK-NEXT: entry: 94// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 95// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 96// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 97// CHECK-NEXT: call void @_ZN3FooIsED2Ev(ptr noundef nonnull align 2 dereferenceable(2) [[THIS1]]) #[[ATTR1]] 98// CHECK-NEXT: ret void 99// 100// CHECK-LABEL: @_ZN3FooIsE3getEv( 101// CHECK-NEXT: entry: 102// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 103// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 104// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 105// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_FOO_0:%.*]], ptr [[THIS1]], i32 0, i32 0 106// CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[X]], align 2 107// CHECK-NEXT: ret i16 [[TMP0]] 108// 109// CHECK-LABEL: @_ZN3FooIsE3setEs( 110// CHECK-NEXT: entry: 111// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 112// CHECK-NEXT: [[_X_ADDR:%.*]] = alloca i16, align 2 113// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 114// CHECK-NEXT: store i16 [[_X:%.*]], ptr [[_X_ADDR]], align 2 115// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 116// CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[_X_ADDR]], align 2 117// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_FOO_0:%.*]], ptr [[THIS1]], i32 0, i32 0 118// CHECK-NEXT: store i16 [[TMP0]], ptr [[X]], align 2 119// CHECK-NEXT: ret void 120// 121template struct Foo<short>; 122 123// This should not generate lines for the implicit specialization of Foo, but 124// should generate lines for the explicit specialization of Bar. 125 126// CHECK-LABEL: @_ZN3BarIiEC1Ei( 127// CHECK-NEXT: entry: 128// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 129// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 130// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 131// CHECK-NEXT: store i32 [[X:%.*]], ptr [[X_ADDR]], align 4 132// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 133// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 134// CHECK-NEXT: call void @_ZN3BarIiEC2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]]) 135// CHECK-NEXT: ret void 136// 137// CHECK-LABEL: @_ZN3BarIiED1Ev( 138// CHECK-NEXT: entry: 139// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 140// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 141// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 142// CHECK-NEXT: call void @_ZN3BarIiED2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR1]] 143// CHECK-NEXT: ret void 144// 145// CHECK-LABEL: @_ZN3BarIiE3getEv( 146// CHECK-NEXT: entry: 147// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 148// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 149// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 150// CHECK-NEXT: [[FOO:%.*]] = getelementptr inbounds nuw [[STRUCT_BAR:%.*]], ptr [[THIS1]], i32 0, i32 0 151// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN3FooIiE3getEv(ptr noundef nonnull align 4 dereferenceable(4) [[FOO]]) 152// CHECK-NEXT: ret i32 [[CALL]] 153// 154// CHECK-LABEL: @_ZN3BarIiE3setEi( 155// CHECK-NEXT: entry: 156// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 157// CHECK-NEXT: [[_X_ADDR:%.*]] = alloca i32, align 4 158// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 159// CHECK-NEXT: store i32 [[_X:%.*]], ptr [[_X_ADDR]], align 4 160// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 161// CHECK-NEXT: [[FOO:%.*]] = getelementptr inbounds nuw [[STRUCT_BAR:%.*]], ptr [[THIS1]], i32 0, i32 0 162// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[_X_ADDR]], align 4 163// CHECK-NEXT: call void @_ZN3FooIiE3setEi(ptr noundef nonnull align 4 dereferenceable(4) [[FOO]], i32 noundef [[TMP0]]) 164// CHECK-NEXT: ret void 165// 166template struct Bar<int>; 167 168// This should not generate lines for the implicit specialization of Foo, but 169// should generate lines for the explicit specialization of Baz. 170 171// CHECK-LABEL: @_ZN3BazIlEC1El( 172// CHECK-NEXT: entry: 173// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 174// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i64, align 8 175// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 176// CHECK-NEXT: store i64 [[X:%.*]], ptr [[X_ADDR]], align 8 177// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 178// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[X_ADDR]], align 8 179// CHECK-NEXT: call void @_ZN3BazIlEC2El(ptr noundef nonnull align 8 dereferenceable(8) [[THIS1]], i64 noundef [[TMP0]]) 180// CHECK-NEXT: ret void 181// 182// CHECK-LABEL: @_ZN3BazIlED1Ev( 183// CHECK-NEXT: entry: 184// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 185// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 186// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 187// CHECK-NEXT: call void @_ZN3BazIlED2Ev(ptr noundef nonnull align 8 dereferenceable(8) [[THIS1]]) #[[ATTR1]] 188// CHECK-NEXT: ret void 189// 190template struct Baz<long>; 191