1// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - | FileCheck %s
2
3// Test optnone on template instantiations.
4
5//-- Effect of optnone on generic add template function.
6
7template <typename T> T template_normal(T a)
8{
9  return a + a;
10}
11
12template <typename T> __attribute__((optnone)) T template_optnone(T a)
13{
14  return a + a + a;
15}
16
17// This function should cause instantiations of each template, one marked
18// with the 'optnone' attribute.
19int container(int i)
20{
21  return template_normal<int>(i) + template_optnone<int>(i);
22}
23
24// CHECK: @_Z15template_normalIiET_S0_({{.*}}) [[NORMAL:#[0-9]+]]
25// CHECK: @_Z16template_optnoneIiET_S0_({{.*}}) [[OPTNONE:#[0-9]+]]
26
27
28//-- Effect of optnone on a partial specialization.
29//   FIRST TEST: a method becomes marked with optnone in the specialization.
30
31template <typename T, typename U> class template_normal_base {
32public:
33  T method(T t, U u)
34  {
35    return t + static_cast<T>(u);
36  }
37};
38
39template <typename U> class template_normal_base<int, U>
40{
41public:
42  __attribute__((optnone)) int method (int t, U u)
43  {
44    return t - static_cast<int>(u);
45  }
46};
47
48// This function should cause an instantiation of the full template (whose
49// method is not marked optnone) and an instantiation of the partially
50// specialized template (whose method is marked optnone).
51void container2()
52{
53  int y = 2;
54  float z = 3.0;
55  template_normal_base<float, int> class_normal;
56  template_normal_base<int, float> class_optnone;
57  float r1 = class_normal.method(z, y);
58  float r2 = class_optnone.method(y, z);
59}
60
61// CHECK: @_ZN20template_normal_baseIfiE6methodEfi({{.*}}) [[NORMAL]]
62// CHECK: @_ZN20template_normal_baseIifE6methodEif({{.*}}) [[OPTNONE]]
63
64
65//-- Effect of optnone on a partial specialization.
66//   SECOND TEST: a method loses optnone in the specialization.
67
68template <typename T, typename U> class template_optnone_base {
69public:
70  __attribute__((optnone)) T method(T t, U u)
71  {
72    return t + static_cast<T>(u);
73  }
74};
75
76template <typename U> class template_optnone_base<int, U>
77{
78public:
79  int method (int t, U u)
80  {
81    return t - static_cast<int>(u);
82  }
83};
84
85// This function should cause an instantiation of the full template (whose
86// method is marked optnone) and an instantiation of the partially
87// specialized template (whose method is not marked optnone).
88void container3()
89{
90  int y = 2;
91  float z = 3.0;
92  template_optnone_base<float, int> class_optnone;
93  template_optnone_base<int, float> class_normal;
94  float r1 = class_optnone.method(z, y);
95  float r2 = class_normal.method(y, z);
96}
97
98// CHECK: @_ZN21template_optnone_baseIfiE6methodEfi({{.*}}) [[OPTNONE]]
99// CHECK: @_ZN21template_optnone_baseIifE6methodEif({{.*}}) [[NORMAL]]
100
101
102// CHECK: attributes [[NORMAL]] =
103// CHECK-NOT: optnone
104// CHECK: attributes [[OPTNONE]] = {{.*}} optnone
105