1 // RUN: %clang_cc1 -fms-extensions -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
2 
3 template<typename T>
4 class Class {
5  public:
6   void method() {}
7 };
8 
9 class Typename { };
10 
11 template<typename T>
12 class Nested { };
13 
14 template<bool flag>
15 class BoolTemplate {
16  public:
17   BoolTemplate() {}
18 };
19 
20 template<int param>
21 class IntTemplate {
22  public:
23   IntTemplate() {}
24 };
25 
26 template<>
27 class BoolTemplate<true> {
28  public:
29   BoolTemplate() {}
30   template<class T> void Foo(T arg) {}
31 };
32 
33 void template_mangling() {
34   Class<Typename> c1;
35   c1.method();
36 // CHECK: call {{.*}} @"\01?method@?$Class@VTypename@@@@QAEXXZ"
37 
38   Class<const Typename> c1_const;
39   Class<volatile Typename> c1_volatile;
40   Class<const volatile Typename> c1_cv;
41   c1_const.method();
42   c1_volatile.method();
43   c1_cv.method();
44 // Types with qualifiers have an extra $$C escape when used as template
45 // arguments.  Not sure why.
46 // CHECK: call {{.*}} @"\01?method@?$Class@$$CBVTypename@@@@QAEXXZ"
47 // CHECK: call {{.*}} @"\01?method@?$Class@$$CCVTypename@@@@QAEXXZ"
48 // CHECK: call {{.*}} @"\01?method@?$Class@$$CDVTypename@@@@QAEXXZ"
49 
50   Class<Nested<Typename> > c2;
51   c2.method();
52 // CHECK: call {{.*}} @"\01?method@?$Class@V?$Nested@VTypename@@@@@@QAEXXZ"
53 
54   BoolTemplate<false> _false;
55 // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QAE@XZ"
56 
57   BoolTemplate<true> _true;
58   // PR13158
59   _true.Foo(1);
60 // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$00@@QAE@XZ"
61 // CHECK: call {{.*}} @"\01??$Foo@H@?$BoolTemplate@$00@@QAEXH@Z"
62 
63   IntTemplate<0> zero;
64 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0A@@@QAE@XZ"
65 
66   IntTemplate<5> five;
67 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$04@@QAE@XZ"
68 
69   IntTemplate<11> eleven;
70 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0L@@@QAE@XZ"
71 
72   IntTemplate<256> _256;
73 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0BAA@@@QAE@XZ"
74 
75   IntTemplate<513> _513;
76 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0CAB@@@QAE@XZ"
77 
78   IntTemplate<1026> _1026;
79 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0EAC@@@QAE@XZ"
80 
81   IntTemplate<65535> ffff;
82 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QAE@XZ"
83 }
84 
85 namespace space {
86   template<class T> const T& foo(const T& l) { return l; }
87 }
88 // CHECK: "\01??$foo@H@space@@YAABHABH@Z"
89 
90 void use() {
91   space::foo(42);
92 }
93 
94 // PR13455
95 typedef void (*FunctionPointer)(void);
96 
97 template <FunctionPointer function>
98 void FunctionPointerTemplate() {
99   function();
100 }
101 
102 void spam() {
103   FunctionPointerTemplate<spam>();
104 // CHECK: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
105 }
106