1 // clang-format off
2 // REQUIRES: lld, x86
3 
4 // RUN: %clang_cl --target=x86_64-windows-msvc -Od -Z7 -c /Fo%t.obj -- %s
5 // RUN: lld-link -debug:full -nodefaultlib -entry:main %t.obj -out:%t.exe -pdb:%t.pdb
6 // RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \
7 // RUN:     %p/Inputs/function-types-builtins.lldbinit | FileCheck %s
8 
9 // Test that we can display function signatures with simple builtin
10 // and pointer types.  We do this by using `target variable` in lldb
11 // with global variables of type ptr-to-function or reference-to-function.
12 // This technique in general allows us to exercise most of LLDB's type
13 // system without a running process.
14 
15 // Define _fltused, since we're not linking against the MS C runtime, but use
16 // floats.
17 extern "C" int _fltused = 0;
18 
19 template<typename T>
20 struct MakeResult {
resultMakeResult21   static T result() {
22     return T{};
23   }
24 };
25 
26 template<typename T>
27 struct MakeResult<T&> {
resultMakeResult28   static T& result() {
29     static T t;
30     return t;
31   }
32 };
33 
34 template<typename T>
35 struct MakeResult<T&&> {
resultMakeResult36   static T&& result() {
37     static T t;
38     return static_cast<T&&>(t);
39   }
40 };
41 
42 
nullary()43 void nullary() {}
44 
45 template<typename Arg>
unary(Arg)46 void unary(Arg) { }
47 
48 template<typename Ret, int N>
unaryret()49 Ret unaryret() { return MakeResult<Ret>::result(); }
50 
51 template<typename A1, typename A2>
binary(A1,A2)52 void binary(A1, A2) { }
53 
varargs(int,int,...)54 int varargs(int, int, ...) { return 0; }
55 
56 // Make sure to test every builtin type at least once for completeness.  We
57 // test these in the globals-fundamentals.cpp when they are the types of
58 // variables but it's possible to imagine a situation where things behave
59 // differently as function arguments or return values than they do with
60 // global variables.
61 
62 // some interesting cases with argument types.
63 auto aa = &unary<bool>;
64 // CHECK: (void (*)(bool)) aa = {{.*}}
65 auto ab = &unary<char>;
66 // CHECK: (void (*)(char)) ab = {{.*}}
67 auto ac = &unary<signed char>;
68 // CHECK: (void (*)(signed char)) ac = {{.*}}
69 auto ad = &unary<unsigned char>;
70 // CHECK: (void (*)(unsigned char)) ad = {{.*}}
71 auto ae = &unary<char16_t>;
72 // CHECK: (void (*)(char16_t)) ae = {{.*}}
73 auto af = &unary<char32_t>;
74 // CHECK: (void (*)(char32_t)) af = {{.*}}
75 auto ag = &unary<wchar_t>;
76 // CHECK: (void (*)(wchar_t)) ag = {{.*}}
77 auto ah = &unary<short>;
78 // CHECK: (void (*)(short)) ah = {{.*}}
79 auto ai = &unary<unsigned short>;
80 // CHECK: (void (*)(unsigned short)) ai = {{.*}}
81 auto aj = &unary<int>;
82 // CHECK: (void (*)(int)) aj = {{.*}}
83 auto ak = &unary<unsigned int>;
84 // CHECK: (void (*)(unsigned int)) ak = {{.*}}
85 auto al = &unary<long>;
86 // CHECK: (void (*)(long)) al = {{.*}}
87 auto am = &unary<unsigned long>;
88 // CHECK: (void (*)(unsigned long)) am = {{.*}}
89 auto an = &unary<long long>;
90 // CHECK: (void (*)(long long)) an = {{.*}}
91 auto ao = &unary<unsigned long long>;
92 // CHECK: (void (*)(unsigned long long)) ao = {{.*}}
93 auto aq = &unary<float>;
94 // CHECK: (void (*)(float)) aq = {{.*}}
95 auto ar = &unary<double>;
96 // CHECK: (void (*)(double)) ar = {{.*}}
97 
98 auto as = &unary<int*>;
99 // CHECK: (void (*)(int *)) as = {{.*}}
100 auto at = &unary<int**>;
101 // CHECK: (void (*)(int **)) at = {{.*}}
102 auto au = &unary<int&>;
103 // CHECK: (void (*)(int &)) au = {{.*}}
104 auto av = &unary<int&&>;
105 // CHECK: (void (*)(int &&)) av = {{.*}}
106 auto aw = &unary<const int*>;
107 // CHECK: (void (*)(const int *)) aw = {{.*}}
108 auto ax = &unary<volatile int*>;
109 // CHECK: (void (*)(volatile int *)) ax = {{.*}}
110 auto ay = &unary<const volatile int*>;
111 // CHECK: (void (*)(const volatile int *)) ay = {{.*}}
112 auto az = &unary<void*&>;
113 // CHECK: (void (*)(void *&)) az = {{.*}}
114 auto aaa = &unary<int(&)[5]>;
115 // CHECK: (void (*)(int (&)[5])) aaa = {{.*}}
116 auto aab = &unary<int(*)[5]>;
117 // CHECK: (void (*)(int (*)[5])) aab = {{.*}}
118 auto aac = &unary<int(&&)[5]>;
119 // CHECK: (void (*)(int (&&)[5])) aac = {{.*}}
120 auto aad = &unary<int(*const)[5]>;
121 // CHECK: (void (*)(int (*const)[5])) aad = {{.*}}
122 
123 
124 // same test cases with return values, note we can't overload on return type
125 // so we need to use a different instantiation each time.
126 auto ra = &unaryret<bool, 0>;
127 // CHECK: (bool (*)()) ra = {{.*}}
128 auto rb = &unaryret<char, 1>;
129 // CHECK: (char (*)()) rb = {{.*}}
130 auto rc = &unaryret<signed char, 2>;
131 // CHECK: (signed char (*)()) rc = {{.*}}
132 auto rd = &unaryret<unsigned char, 3>;
133 // CHECK: (unsigned char (*)()) rd = {{.*}}
134 auto re = &unaryret<char16_t, 4>;
135 // CHECK: (char16_t (*)()) re = {{.*}}
136 auto rf = &unaryret<char32_t, 5>;
137 // CHECK: (char32_t (*)()) rf = {{.*}}
138 auto rg = &unaryret<wchar_t, 6>;
139 // CHECK: (wchar_t (*)()) rg = {{.*}}
140 auto rh = &unaryret<short, 7>;
141 // CHECK: (short (*)()) rh = {{.*}}
142 auto ri = &unaryret<unsigned short, 8>;
143 // CHECK: (unsigned short (*)()) ri = {{.*}}
144 auto rj = &unaryret<int, 9>;
145 // CHECK: (int (*)()) rj = {{.*}}
146 auto rk = &unaryret<unsigned int, 10>;
147 // CHECK: (unsigned int (*)()) rk = {{.*}}
148 auto rl = &unaryret<long, 11>;
149 // CHECK: (long (*)()) rl = {{.*}}
150 auto rm = &unaryret<unsigned long, 12>;
151 // CHECK: (unsigned long (*)()) rm = {{.*}}
152 auto rn = &unaryret<long long, 13>;
153 // CHECK: (long long (*)()) rn = {{.*}}
154 auto ro = &unaryret<unsigned long long, 14>;
155 // CHECK: (unsigned long long (*)()) ro = {{.*}}
156 auto rq = &unaryret<float, 15>;
157 // CHECK: (float (*)()) rq = {{.*}}
158 auto rr = &unaryret<double, 16>;
159 // CHECK: (double (*)()) rr = {{.*}}
160 
161 auto rs = &unaryret<int*, 17>;
162 // CHECK: (int *(*)()) rs = {{.*}}
163 auto rt = &unaryret<int**, 18>;
164 // CHECK: (int **(*)()) rt = {{.*}}
165 auto ru = &unaryret<int&, 19>;
166 // CHECK: (int &(*)()) ru = {{.*}}
167 auto rv = &unaryret<int&&, 20>;
168 // CHECK: (int &&(*)()) rv = {{.*}}
169 auto rw = &unaryret<const int*, 21>;
170 // CHECK: (const int *(*)()) rw = {{.*}}
171 auto rx = &unaryret<volatile int*, 22>;
172 // CHECK: (volatile int *(*)()) rx = {{.*}}
173 auto ry = &unaryret<const volatile int*, 23>;
174 // CHECK: (const volatile int *(*)()) ry = {{.*}}
175 auto rz = &unaryret<void*&, 24>;
176 // CHECK: (void *&(*)()) rz = {{.*}}
177 
178 // FIXME: This output doesn't really look correct.  It should probably be
179 // formatting this as `int(&)[5] (*)()`.
180 auto raa = &unaryret<int(&)[5], 25>;
181 // CHECK: (int (&(*)())[5]) raa = {{.*}}
182 auto rab = &unaryret<int(*)[5], 26>;
183 // CHECK: (int (*(*)())[5]) rab = {{.*}}
184 auto rac = &unaryret<int(&&)[5], 27>;
185 // CHECK: (int (&&(*)())[5]) rac = {{.*}}
186 auto rad = &unaryret<int(*const)[5], 28>;
187 // CHECK: (int (*const (*)())[5]) rad = {{.*}}
188 
189 
190 
191 // Function references, we only need a couple of these since most of the
192 // interesting cases are already tested.
193 auto &ref = unary<bool>;
194 // CHECK: (void (&)(bool)) ref = {{.*}} (&::ref = <no summary available>)
195 auto &ref2 = unary<volatile int*>;
196 // CHECK: (void (&)(volatile int *)) ref2 = {{.*}} (&::ref2 = <no summary available>)
197 auto &ref3 = varargs;
198 // CHECK: (int (&)(int, int, ...)) ref3 = {{.*}} (&::ref3 = <no summary available>)
199 
200 // Multiple arguments, as before, just something to make sure it works.
201 auto binp = &binary<int*, const int*>;
202 // CHECK: (void (*)(int *, const int *)) binp = {{.*}}
203 auto &binr = binary<int*, const int*>;
204 // CHECK: (void (&)(int *, const int *)) binr = {{.*}} (&::binr = <no summary available>)
205 
206 // And finally, a function with no arguments.
207 auto null = &nullary;
208 // CHECK: (void (*)()) null = {{.*}}
209 
210 // FIXME: These currently don't work because clang-cl emits incorrect debug info
211 // for std::nullptr_t.  We should fix these in clang-cl.
212 auto rae = &unaryret<decltype(nullptr), 29>;
213 // CHECK: (std::nullptr_t (*)()) rae = {{.*}}
214 auto aae = &unary<decltype(nullptr)>;
215 // CHECK: (void (*)(std::nullptr_t)) aae = {{.*}}
216 
main(int argc,char ** argv)217 int main(int argc, char **argv) {
218   return 0;
219 }
220