1 | // RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -disable-O0-optnone -emit-llvm -o - | FileCheck %s |
2 | |
3 | // Test optnone on template instantiations. |
4 | |
5 | //-- Effect of optnone on generic add template function. |
6 | |
7 | template <typename T> T template_normal(T a) |
8 | { |
9 | return a + a; |
10 | } |
11 | |
12 | template <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. |
19 | int 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 | |
31 | template <typename T, typename U> class template_normal_base { |
32 | public: |
33 | T method(T t, U u) |
34 | { |
35 | return t + static_cast<T>(u); |
36 | } |
37 | }; |
38 | |
39 | template <typename U> class template_normal_base<int, U> |
40 | { |
41 | public: |
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). |
51 | void 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 | |
68 | template <typename T, typename U> class template_optnone_base { |
69 | public: |
70 | __attribute__((optnone)) T method(T t, U u) |
71 | { |
72 | return t + static_cast<T>(u); |
73 | } |
74 | }; |
75 | |
76 | template <typename U> class template_optnone_base<int, U> |
77 | { |
78 | public: |
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). |
88 | void 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 | |