1 | // RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -std=c++11 -fms-extensions -verify -o - %s | FileCheck %s |
2 | // expected-no-diagnostics |
3 | |
4 | // Class member templates |
5 | |
6 | #pragma code_seg(push, "something") |
7 | |
8 | template <typename T> |
9 | struct __declspec(code_seg("foo_one")) ClassOne { |
10 | int bar1(T t) { return int(t); } |
11 | int bar2(T t); |
12 | int bar3(T t); |
13 | }; |
14 | |
15 | template <typename T> |
16 | int ClassOne<T>::bar2(T t) { |
17 | return int(t); |
18 | } |
19 | |
20 | int caller1() { |
21 | ClassOne<int> coi; |
22 | return coi.bar1(6) + coi.bar2(3); |
23 | } |
24 | |
25 | //CHECK: define {{.*}}bar1@?$ClassOne{{.*}} section "foo_one" |
26 | //CHECK: define {{.*}}bar2@?$ClassOne{{.*}} section "foo_one" |
27 | |
28 | |
29 | template <typename T> |
30 | struct ClassTwo { |
31 | int bar11(T t) { return int(t); } |
32 | int bar22(T t); |
33 | int bar33(T t); |
34 | }; |
35 | |
36 | #pragma code_seg("newone") |
37 | |
38 | template <typename T> |
39 | int ClassTwo<T>::bar22(T t) { |
40 | return int(t); |
41 | } |
42 | |
43 | #pragma code_seg("someother") |
44 | |
45 | template <typename T> |
46 | int ClassTwo<T>::bar33(T t) { |
47 | return int(t); |
48 | } |
49 | |
50 | #pragma code_seg("yetanother") |
51 | |
52 | int caller2() { |
53 | ClassTwo<int> coi; |
54 | return coi.bar11(6) + coi.bar22(3) + coi.bar33(44); |
55 | } |
56 | |
57 | //CHECK: define {{.*}}bar11@?$ClassTwo{{.*}} section "something" |
58 | //CHECK: define {{.*}}bar22@?$ClassTwo{{.*}} section "newone" |
59 | //CHECK: define {{.*}}bar33@?$ClassTwo{{.*}} section "someother" |
60 | |
61 | template<> |
62 | struct ClassOne<double> |
63 | { |
64 | int bar44(double d) { return 1; } |
65 | }; |
66 | template<> |
67 | struct __declspec(code_seg("foo_three")) ClassOne<long> |
68 | { |
69 | int bar55(long d) { return 1; } |
70 | }; |
71 | |
72 | #pragma code_seg("onemore") |
73 | int caller3() { |
74 | ClassOne<double> d; |
75 | ClassOne<long> l; |
76 | return d.bar44(1.0)+l.bar55(1); |
77 | } |
78 | |
79 | //CHECK: define {{.*}}bar44{{.*}} section "yetanother" |
80 | //CHECK: define {{.*}}bar55{{.*}} section "foo_three" |
81 | |
82 | |
83 | // Function templates |
84 | template <typename T> |
85 | int __declspec(code_seg("foo_four")) bar66(T t) { return int(t); } |
86 | |
87 | // specializations do not take the segment from primary |
88 | template<> |
89 | int bar66(int i) { return 0; } |
90 | |
91 | #pragma code_seg(pop) |
92 | |
93 | template<> |
94 | int bar66(char c) { return 0; } |
95 | |
96 | struct A1 {int i;}; |
97 | template<> |
98 | int __declspec(code_seg("foo_five")) bar66(A1 a) { return a.i; } |
99 | |
100 | int caller4() |
101 | { |
102 | // but instantiations do use the section from the primary |
103 | return bar66(0) + bar66(1.0) + bar66('c'); |
104 | } |
105 | //CHECK: define {{.*}}bar66@H{{.*}} section "onemore" |
106 | //CHECK-NOT: define {{.*}}bar66@D{{.*}} section |
107 | //CHECK: define {{.*}}bar66@UA1{{.*}} section "foo_five" |
108 | //CHECK: define {{.*}}bar66@N{{.*}} section "foo_four" |
109 | |
110 | |
111 | |
112 | |