191 lines · plain
1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py2// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s3 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 842// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i8, align 143// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 844// CHECK-NEXT: store i8 [[X:%.*]], ptr [[X_ADDR]], align 145// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 846// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[X_ADDR]], align 147// CHECK-NEXT: call void @_ZN3FooIcEC2Ec(ptr noundef nonnull align 1 dereferenceable(1) [[THIS1]], i8 noundef signext [[TMP0]])48// CHECK-NEXT: ret void49//50// CHECK-LABEL: @_ZN3FooIcED1Ev(51// CHECK-NEXT: entry:52// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 853// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 854// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 855// CHECK-NEXT: call void @_ZN3FooIcED2Ev(ptr noundef nonnull align 1 dereferenceable(1) [[THIS1]]) #[[ATTR1:[0-9]+]]56// CHECK-NEXT: ret void57//58// CHECK-LABEL: @_ZN3FooIcE3getEv(59// CHECK-NEXT: entry:60// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 861// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 862// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 863// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_FOO:%.*]], ptr [[THIS1]], i32 0, i32 064// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[X]], align 165// CHECK-NEXT: ret i8 [[TMP0]]66//67// CHECK-LABEL: @_ZN3FooIcE3setEc(68// CHECK-NEXT: entry:69// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 870// CHECK-NEXT: [[_X_ADDR:%.*]] = alloca i8, align 171// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 872// CHECK-NEXT: store i8 [[_X:%.*]], ptr [[_X_ADDR]], align 173// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 874// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[_X_ADDR]], align 175// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_FOO:%.*]], ptr [[THIS1]], i32 0, i32 076// CHECK-NEXT: store i8 [[TMP0]], ptr [[X]], align 177// CHECK-NEXT: ret void78//79template struct Foo<char>;80 81// CHECK-LABEL: @_ZN3FooIsEC1Es(82// CHECK-NEXT: entry:83// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 884// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i16, align 285// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 886// CHECK-NEXT: store i16 [[X:%.*]], ptr [[X_ADDR]], align 287// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 888// CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[X_ADDR]], align 289// CHECK-NEXT: call void @_ZN3FooIsEC2Es(ptr noundef nonnull align 2 dereferenceable(2) [[THIS1]], i16 noundef signext [[TMP0]])90// CHECK-NEXT: ret void91//92// CHECK-LABEL: @_ZN3FooIsED1Ev(93// CHECK-NEXT: entry:94// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 895// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 896// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 897// CHECK-NEXT: call void @_ZN3FooIsED2Ev(ptr noundef nonnull align 2 dereferenceable(2) [[THIS1]]) #[[ATTR1]]98// CHECK-NEXT: ret void99//100// CHECK-LABEL: @_ZN3FooIsE3getEv(101// CHECK-NEXT: entry:102// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8103// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8104// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8105// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_FOO_0:%.*]], ptr [[THIS1]], i32 0, i32 0106// CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[X]], align 2107// CHECK-NEXT: ret i16 [[TMP0]]108//109// CHECK-LABEL: @_ZN3FooIsE3setEs(110// CHECK-NEXT: entry:111// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8112// CHECK-NEXT: [[_X_ADDR:%.*]] = alloca i16, align 2113// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8114// CHECK-NEXT: store i16 [[_X:%.*]], ptr [[_X_ADDR]], align 2115// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8116// CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[_X_ADDR]], align 2117// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_FOO_0:%.*]], ptr [[THIS1]], i32 0, i32 0118// CHECK-NEXT: store i16 [[TMP0]], ptr [[X]], align 2119// CHECK-NEXT: ret void120//121template struct Foo<short>;122 123// This should not generate lines for the implicit specialization of Foo, but124// 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 8129// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4130// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8131// CHECK-NEXT: store i32 [[X:%.*]], ptr [[X_ADDR]], align 4132// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8133// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4134// CHECK-NEXT: call void @_ZN3BarIiEC2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]])135// CHECK-NEXT: ret void136//137// CHECK-LABEL: @_ZN3BarIiED1Ev(138// CHECK-NEXT: entry:139// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8140// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8141// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8142// CHECK-NEXT: call void @_ZN3BarIiED2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR1]]143// CHECK-NEXT: ret void144//145// CHECK-LABEL: @_ZN3BarIiE3getEv(146// CHECK-NEXT: entry:147// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8148// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8149// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8150// CHECK-NEXT: [[FOO:%.*]] = getelementptr inbounds nuw [[STRUCT_BAR:%.*]], ptr [[THIS1]], i32 0, i32 0151// 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 8157// CHECK-NEXT: [[_X_ADDR:%.*]] = alloca i32, align 4158// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8159// CHECK-NEXT: store i32 [[_X:%.*]], ptr [[_X_ADDR]], align 4160// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8161// CHECK-NEXT: [[FOO:%.*]] = getelementptr inbounds nuw [[STRUCT_BAR:%.*]], ptr [[THIS1]], i32 0, i32 0162// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[_X_ADDR]], align 4163// CHECK-NEXT: call void @_ZN3FooIiE3setEi(ptr noundef nonnull align 4 dereferenceable(4) [[FOO]], i32 noundef [[TMP0]])164// CHECK-NEXT: ret void165//166template struct Bar<int>;167 168// This should not generate lines for the implicit specialization of Foo, but169// 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 8174// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i64, align 8175// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8176// CHECK-NEXT: store i64 [[X:%.*]], ptr [[X_ADDR]], align 8177// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8178// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[X_ADDR]], align 8179// CHECK-NEXT: call void @_ZN3BazIlEC2El(ptr noundef nonnull align 8 dereferenceable(8) [[THIS1]], i64 noundef [[TMP0]])180// CHECK-NEXT: ret void181//182// CHECK-LABEL: @_ZN3BazIlED1Ev(183// CHECK-NEXT: entry:184// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8185// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8186// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8187// CHECK-NEXT: call void @_ZN3BazIlED2Ev(ptr noundef nonnull align 8 dereferenceable(8) [[THIS1]]) #[[ATTR1]]188// CHECK-NEXT: ret void189//190template struct Baz<long>;191