Erich Keane | 7963e8b | 2018-07-18 20:04:48 +0000 | [diff] [blame] | 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 | |