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