10e79a948SJessica Clarke// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2*b16a3b4fSNikita Popov// RUN: %clang_cc1 -no-opaque-pointers -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
30e79a948SJessica Clarke
40e79a948SJessica Clarketemplate <typename T>
50e79a948SJessica Clarkestruct Foo {
60e79a948SJessica Clarkeprivate:
70e79a948SJessica Clarke  T x;
80e79a948SJessica Clarke
90e79a948SJessica Clarkepublic:
100e79a948SJessica Clarke  Foo(T x) : x(x) {}
110e79a948SJessica Clarke  ~Foo() {}
120e79a948SJessica Clarke
130e79a948SJessica Clarke  T get() { return x; }
140e79a948SJessica Clarke  void set(T _x) { x = _x; }
150e79a948SJessica Clarke};
160e79a948SJessica Clarke
170e79a948SJessica Clarketemplate <typename T>
180e79a948SJessica Clarkestruct Bar {
190e79a948SJessica Clarkeprivate:
200e79a948SJessica Clarke  struct Foo<T> foo;
210e79a948SJessica Clarke
220e79a948SJessica Clarkepublic:
230e79a948SJessica Clarke  Bar(T x) : foo(x) {}
240e79a948SJessica Clarke  ~Bar() {}
250e79a948SJessica Clarke
260e79a948SJessica Clarke  T get() { return foo.get(); }
270e79a948SJessica Clarke  void set(T _x) { foo.set(_x); }
280e79a948SJessica Clarke};
290e79a948SJessica Clarke
300e79a948SJessica Clarketemplate <typename T>
310e79a948SJessica Clarkestruct Baz : Foo<T> {
320e79a948SJessica Clarkepublic:
330e79a948SJessica Clarke  Baz(T x) : Foo<T>(x) {}
340e79a948SJessica Clarke  ~Baz() {}
350e79a948SJessica Clarke};
360e79a948SJessica Clarke
370e79a948SJessica Clarke// These two specializations should generate lines for all of Foo's methods.
380e79a948SJessica Clarke
390e79a948SJessica Clarke// CHECK-LABEL: @_ZN3FooIcEC1Ec(
400e79a948SJessica Clarke// CHECK-NEXT:  entry:
410e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Foo*, align 8
420e79a948SJessica Clarke// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i8, align 1
430e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Foo* [[THIS:%.*]], %struct.Foo** [[THIS_ADDR]], align 8
440e79a948SJessica Clarke// CHECK-NEXT:    store i8 [[X:%.*]], i8* [[X_ADDR]], align 1
450e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Foo*, %struct.Foo** [[THIS_ADDR]], align 8
460e79a948SJessica Clarke// CHECK-NEXT:    [[TMP0:%.*]] = load i8, i8* [[X_ADDR]], align 1
4767aa314bSFlorian Hahn// CHECK-NEXT:    call void @_ZN3FooIcEC2Ec(%struct.Foo* noundef nonnull align 1 dereferenceable(1) [[THIS1]], i8 noundef signext [[TMP0]])
480e79a948SJessica Clarke// CHECK-NEXT:    ret void
490e79a948SJessica Clarke//
500e79a948SJessica Clarke// CHECK-LABEL: @_ZN3FooIcED1Ev(
510e79a948SJessica Clarke// CHECK-NEXT:  entry:
520e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Foo*, align 8
530e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Foo* [[THIS:%.*]], %struct.Foo** [[THIS_ADDR]], align 8
540e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Foo*, %struct.Foo** [[THIS_ADDR]], align 8
5567aa314bSFlorian Hahn// CHECK-NEXT:    call void @_ZN3FooIcED2Ev(%struct.Foo* noundef nonnull align 1 dereferenceable(1) [[THIS1]]) #[[ATTR2:[0-9]+]]
560e79a948SJessica Clarke// CHECK-NEXT:    ret void
570e79a948SJessica Clarke//
580e79a948SJessica Clarke// CHECK-LABEL: @_ZN3FooIcE3getEv(
590e79a948SJessica Clarke// CHECK-NEXT:  entry:
600e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Foo*, align 8
610e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Foo* [[THIS:%.*]], %struct.Foo** [[THIS_ADDR]], align 8
620e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Foo*, %struct.Foo** [[THIS_ADDR]], align 8
630e79a948SJessica Clarke// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_FOO:%.*]], %struct.Foo* [[THIS1]], i32 0, i32 0
640e79a948SJessica Clarke// CHECK-NEXT:    [[TMP0:%.*]] = load i8, i8* [[X]], align 1
650e79a948SJessica Clarke// CHECK-NEXT:    ret i8 [[TMP0]]
660e79a948SJessica Clarke//
670e79a948SJessica Clarke// CHECK-LABEL: @_ZN3FooIcE3setEc(
680e79a948SJessica Clarke// CHECK-NEXT:  entry:
690e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Foo*, align 8
700e79a948SJessica Clarke// CHECK-NEXT:    [[_X_ADDR:%.*]] = alloca i8, align 1
710e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Foo* [[THIS:%.*]], %struct.Foo** [[THIS_ADDR]], align 8
720e79a948SJessica Clarke// CHECK-NEXT:    store i8 [[_X:%.*]], i8* [[_X_ADDR]], align 1
730e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Foo*, %struct.Foo** [[THIS_ADDR]], align 8
740e79a948SJessica Clarke// CHECK-NEXT:    [[TMP0:%.*]] = load i8, i8* [[_X_ADDR]], align 1
750e79a948SJessica Clarke// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_FOO:%.*]], %struct.Foo* [[THIS1]], i32 0, i32 0
760e79a948SJessica Clarke// CHECK-NEXT:    store i8 [[TMP0]], i8* [[X]], align 1
770e79a948SJessica Clarke// CHECK-NEXT:    ret void
780e79a948SJessica Clarke//
790e79a948SJessica Clarketemplate struct Foo<char>;
800e79a948SJessica Clarke
810e79a948SJessica Clarke// CHECK-LABEL: @_ZN3FooIsEC1Es(
820e79a948SJessica Clarke// CHECK-NEXT:  entry:
830e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Foo.0*, align 8
840e79a948SJessica Clarke// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i16, align 2
850e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Foo.0* [[THIS:%.*]], %struct.Foo.0** [[THIS_ADDR]], align 8
860e79a948SJessica Clarke// CHECK-NEXT:    store i16 [[X:%.*]], i16* [[X_ADDR]], align 2
870e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Foo.0*, %struct.Foo.0** [[THIS_ADDR]], align 8
880e79a948SJessica Clarke// CHECK-NEXT:    [[TMP0:%.*]] = load i16, i16* [[X_ADDR]], align 2
8967aa314bSFlorian Hahn// CHECK-NEXT:    call void @_ZN3FooIsEC2Es(%struct.Foo.0* noundef nonnull align 2 dereferenceable(2) [[THIS1]], i16 noundef signext [[TMP0]])
900e79a948SJessica Clarke// CHECK-NEXT:    ret void
910e79a948SJessica Clarke//
920e79a948SJessica Clarke// CHECK-LABEL: @_ZN3FooIsED1Ev(
930e79a948SJessica Clarke// CHECK-NEXT:  entry:
940e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Foo.0*, align 8
950e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Foo.0* [[THIS:%.*]], %struct.Foo.0** [[THIS_ADDR]], align 8
960e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Foo.0*, %struct.Foo.0** [[THIS_ADDR]], align 8
9767aa314bSFlorian Hahn// CHECK-NEXT:    call void @_ZN3FooIsED2Ev(%struct.Foo.0* noundef nonnull align 2 dereferenceable(2) [[THIS1]]) #[[ATTR2]]
980e79a948SJessica Clarke// CHECK-NEXT:    ret void
990e79a948SJessica Clarke//
1000e79a948SJessica Clarke// CHECK-LABEL: @_ZN3FooIsE3getEv(
1010e79a948SJessica Clarke// CHECK-NEXT:  entry:
1020e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Foo.0*, align 8
1030e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Foo.0* [[THIS:%.*]], %struct.Foo.0** [[THIS_ADDR]], align 8
1040e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Foo.0*, %struct.Foo.0** [[THIS_ADDR]], align 8
1050e79a948SJessica Clarke// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_FOO_0:%.*]], %struct.Foo.0* [[THIS1]], i32 0, i32 0
1060e79a948SJessica Clarke// CHECK-NEXT:    [[TMP0:%.*]] = load i16, i16* [[X]], align 2
1070e79a948SJessica Clarke// CHECK-NEXT:    ret i16 [[TMP0]]
1080e79a948SJessica Clarke//
1090e79a948SJessica Clarke// CHECK-LABEL: @_ZN3FooIsE3setEs(
1100e79a948SJessica Clarke// CHECK-NEXT:  entry:
1110e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Foo.0*, align 8
1120e79a948SJessica Clarke// CHECK-NEXT:    [[_X_ADDR:%.*]] = alloca i16, align 2
1130e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Foo.0* [[THIS:%.*]], %struct.Foo.0** [[THIS_ADDR]], align 8
1140e79a948SJessica Clarke// CHECK-NEXT:    store i16 [[_X:%.*]], i16* [[_X_ADDR]], align 2
1150e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Foo.0*, %struct.Foo.0** [[THIS_ADDR]], align 8
1160e79a948SJessica Clarke// CHECK-NEXT:    [[TMP0:%.*]] = load i16, i16* [[_X_ADDR]], align 2
1170e79a948SJessica Clarke// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_FOO_0:%.*]], %struct.Foo.0* [[THIS1]], i32 0, i32 0
1180e79a948SJessica Clarke// CHECK-NEXT:    store i16 [[TMP0]], i16* [[X]], align 2
1190e79a948SJessica Clarke// CHECK-NEXT:    ret void
1200e79a948SJessica Clarke//
1210e79a948SJessica Clarketemplate struct Foo<short>;
1220e79a948SJessica Clarke
1230e79a948SJessica Clarke// This should not generate lines for the implicit specialization of Foo, but
1240e79a948SJessica Clarke// should generate lines for the explicit specialization of Bar.
1250e79a948SJessica Clarke
1260e79a948SJessica Clarke// CHECK-LABEL: @_ZN3BarIiEC1Ei(
1270e79a948SJessica Clarke// CHECK-NEXT:  entry:
1280e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Bar*, align 8
1290e79a948SJessica Clarke// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
1300e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Bar* [[THIS:%.*]], %struct.Bar** [[THIS_ADDR]], align 8
1310e79a948SJessica Clarke// CHECK-NEXT:    store i32 [[X:%.*]], i32* [[X_ADDR]], align 4
1320e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Bar*, %struct.Bar** [[THIS_ADDR]], align 8
1330e79a948SJessica Clarke// CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
13467aa314bSFlorian Hahn// CHECK-NEXT:    call void @_ZN3BarIiEC2Ei(%struct.Bar* noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]])
1350e79a948SJessica Clarke// CHECK-NEXT:    ret void
1360e79a948SJessica Clarke//
1370e79a948SJessica Clarke// CHECK-LABEL: @_ZN3BarIiED1Ev(
1380e79a948SJessica Clarke// CHECK-NEXT:  entry:
1390e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Bar*, align 8
1400e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Bar* [[THIS:%.*]], %struct.Bar** [[THIS_ADDR]], align 8
1410e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Bar*, %struct.Bar** [[THIS_ADDR]], align 8
14267aa314bSFlorian Hahn// CHECK-NEXT:    call void @_ZN3BarIiED2Ev(%struct.Bar* noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR2]]
1430e79a948SJessica Clarke// CHECK-NEXT:    ret void
1440e79a948SJessica Clarke//
1450e79a948SJessica Clarke// CHECK-LABEL: @_ZN3BarIiE3getEv(
1460e79a948SJessica Clarke// CHECK-NEXT:  entry:
1470e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Bar*, align 8
1480e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Bar* [[THIS:%.*]], %struct.Bar** [[THIS_ADDR]], align 8
1490e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Bar*, %struct.Bar** [[THIS_ADDR]], align 8
1500e79a948SJessica Clarke// CHECK-NEXT:    [[FOO:%.*]] = getelementptr inbounds [[STRUCT_BAR:%.*]], %struct.Bar* [[THIS1]], i32 0, i32 0
15167aa314bSFlorian Hahn// CHECK-NEXT:    [[CALL:%.*]] = call noundef i32 @_ZN3FooIiE3getEv(%struct.Foo.1* noundef nonnull align 4 dereferenceable(4) [[FOO]])
1520e79a948SJessica Clarke// CHECK-NEXT:    ret i32 [[CALL]]
1530e79a948SJessica Clarke//
1540e79a948SJessica Clarke// CHECK-LABEL: @_ZN3BarIiE3setEi(
1550e79a948SJessica Clarke// CHECK-NEXT:  entry:
1560e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Bar*, align 8
1570e79a948SJessica Clarke// CHECK-NEXT:    [[_X_ADDR:%.*]] = alloca i32, align 4
1580e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Bar* [[THIS:%.*]], %struct.Bar** [[THIS_ADDR]], align 8
1590e79a948SJessica Clarke// CHECK-NEXT:    store i32 [[_X:%.*]], i32* [[_X_ADDR]], align 4
1600e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Bar*, %struct.Bar** [[THIS_ADDR]], align 8
1610e79a948SJessica Clarke// CHECK-NEXT:    [[FOO:%.*]] = getelementptr inbounds [[STRUCT_BAR:%.*]], %struct.Bar* [[THIS1]], i32 0, i32 0
1620e79a948SJessica Clarke// CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[_X_ADDR]], align 4
16367aa314bSFlorian Hahn// CHECK-NEXT:    call void @_ZN3FooIiE3setEi(%struct.Foo.1* noundef nonnull align 4 dereferenceable(4) [[FOO]], i32 noundef [[TMP0]])
1640e79a948SJessica Clarke// CHECK-NEXT:    ret void
1650e79a948SJessica Clarke//
1660e79a948SJessica Clarketemplate struct Bar<int>;
1670e79a948SJessica Clarke
1680e79a948SJessica Clarke// This should not generate lines for the implicit specialization of Foo, but
1690e79a948SJessica Clarke// should generate lines for the explicit specialization of Baz.
1700e79a948SJessica Clarke
1710e79a948SJessica Clarke// CHECK-LABEL: @_ZN3BazIlEC1El(
1720e79a948SJessica Clarke// CHECK-NEXT:  entry:
1730e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Baz*, align 8
1740e79a948SJessica Clarke// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i64, align 8
1750e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Baz* [[THIS:%.*]], %struct.Baz** [[THIS_ADDR]], align 8
1760e79a948SJessica Clarke// CHECK-NEXT:    store i64 [[X:%.*]], i64* [[X_ADDR]], align 8
1770e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Baz*, %struct.Baz** [[THIS_ADDR]], align 8
1780e79a948SJessica Clarke// CHECK-NEXT:    [[TMP0:%.*]] = load i64, i64* [[X_ADDR]], align 8
17967aa314bSFlorian Hahn// CHECK-NEXT:    call void @_ZN3BazIlEC2El(%struct.Baz* noundef nonnull align 8 dereferenceable(8) [[THIS1]], i64 noundef [[TMP0]])
1800e79a948SJessica Clarke// CHECK-NEXT:    ret void
1810e79a948SJessica Clarke//
1820e79a948SJessica Clarke// CHECK-LABEL: @_ZN3BazIlED1Ev(
1830e79a948SJessica Clarke// CHECK-NEXT:  entry:
1840e79a948SJessica Clarke// CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca %struct.Baz*, align 8
1850e79a948SJessica Clarke// CHECK-NEXT:    store %struct.Baz* [[THIS:%.*]], %struct.Baz** [[THIS_ADDR]], align 8
1860e79a948SJessica Clarke// CHECK-NEXT:    [[THIS1:%.*]] = load %struct.Baz*, %struct.Baz** [[THIS_ADDR]], align 8
18767aa314bSFlorian Hahn// CHECK-NEXT:    call void @_ZN3BazIlED2Ev(%struct.Baz* noundef nonnull align 8 dereferenceable(8) [[THIS1]]) #[[ATTR2]]
1880e79a948SJessica Clarke// CHECK-NEXT:    ret void
1890e79a948SJessica Clarke//
1900e79a948SJessica Clarketemplate struct Baz<long>;
191