Mercurial > projects > ldc
comparison dmd2/cppmangle.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | |
children | e4f7b5d9c68a |
comparison
equal
deleted
inserted
replaced
1423:42bd767ec5a4 | 1452:638d16625da2 |
---|---|
1 | |
2 // Compiler implementation of the D programming language | |
3 // Copyright (c) 1999-2007 by Digital Mars | |
4 // All Rights Reserved | |
5 // written by Walter Bright | |
6 // http://www.digitalmars.com | |
7 // License for redistribution is by either the Artistic License | |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | |
9 // See the included readme.txt for details. | |
10 | |
11 #include <stdio.h> | |
12 #include <assert.h> | |
13 | |
14 #include "mars.h" | |
15 #include "dsymbol.h" | |
16 #include "mtype.h" | |
17 #include "scope.h" | |
18 #include "init.h" | |
19 #include "expression.h" | |
20 #include "attrib.h" | |
21 #include "declaration.h" | |
22 #include "template.h" | |
23 #include "id.h" | |
24 #include "enum.h" | |
25 #include "import.h" | |
26 #include "aggregate.h" | |
27 | |
28 #if DMDV2 | |
29 | |
30 /* Do mangling for C++ linkage. | |
31 * Follows Itanium C++ ABI 1.86 | |
32 * No attempt is made to support mangling of templates, operator | |
33 * overloading, or special functions. | |
34 * | |
35 * So why don't we use the C++ ABI for D name mangling? | |
36 * Because D supports a lot of things (like modules) that the C++ | |
37 * ABI has no concept of. These affect every D mangled name, | |
38 * so nothing would be compatible anyway. | |
39 */ | |
40 | |
41 struct CppMangleState | |
42 { | |
43 static Array components; | |
44 | |
45 int substitute(OutBuffer *buf, void *p); | |
46 }; | |
47 | |
48 Array CppMangleState::components; | |
49 | |
50 | |
51 void writeBase36(OutBuffer *buf, unsigned i) | |
52 { | |
53 if (i >= 36) | |
54 { | |
55 writeBase36(buf, i / 36); | |
56 i %= 36; | |
57 } | |
58 if (i < 10) | |
59 buf->writeByte(i + '0'); | |
60 else if (i < 36) | |
61 buf->writeByte(i - 10 + 'A'); | |
62 else | |
63 assert(0); | |
64 } | |
65 | |
66 int CppMangleState::substitute(OutBuffer *buf, void *p) | |
67 { | |
68 for (size_t i = 0; i < components.dim; i++) | |
69 { | |
70 if (p == components.data[i]) | |
71 { | |
72 /* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ... | |
73 */ | |
74 buf->writeByte('S'); | |
75 if (i) | |
76 writeBase36(buf, i - 1); | |
77 buf->writeByte('_'); | |
78 return 1; | |
79 } | |
80 } | |
81 components.push(p); | |
82 return 0; | |
83 } | |
84 | |
85 void source_name(OutBuffer *buf, Dsymbol *s) | |
86 { | |
87 char *name = s->ident->toChars(); | |
88 buf->printf("%d%s", strlen(name), name); | |
89 } | |
90 | |
91 void prefix_name(OutBuffer *buf, CppMangleState *cms, Dsymbol *s) | |
92 { | |
93 if (!cms->substitute(buf, s)) | |
94 { | |
95 Dsymbol *p = s->toParent(); | |
96 if (p && !p->isModule()) | |
97 { | |
98 prefix_name(buf, cms, p); | |
99 } | |
100 source_name(buf, s); | |
101 } | |
102 } | |
103 | |
104 void cpp_mangle_name(OutBuffer *buf, CppMangleState *cms, Dsymbol *s) | |
105 { | |
106 Dsymbol *p = s->toParent(); | |
107 if (p && !p->isModule()) | |
108 { | |
109 buf->writeByte('N'); | |
110 | |
111 FuncDeclaration *fd = s->isFuncDeclaration(); | |
112 if (fd->isConst()) | |
113 buf->writeByte('K'); | |
114 | |
115 prefix_name(buf, cms, p); | |
116 source_name(buf, s); | |
117 | |
118 buf->writeByte('E'); | |
119 } | |
120 else | |
121 source_name(buf, s); | |
122 } | |
123 | |
124 | |
125 char *cpp_mangle(Dsymbol *s) | |
126 { | |
127 /* | |
128 * <mangled-name> ::= _Z <encoding> | |
129 * <encoding> ::= <function name> <bare-function-type> | |
130 * ::= <data name> | |
131 * ::= <special-name> | |
132 */ | |
133 | |
134 CppMangleState cms; | |
135 memset(&cms, 0, sizeof(cms)); | |
136 cms.components.setDim(0); | |
137 | |
138 OutBuffer buf; | |
139 #if MACHOBJ | |
140 buf.writestring("__Z"); | |
141 #else | |
142 buf.writestring("_Z"); | |
143 #endif | |
144 | |
145 cpp_mangle_name(&buf, &cms, s); | |
146 | |
147 FuncDeclaration *fd = s->isFuncDeclaration(); | |
148 if (fd) | |
149 { // add <bare-function-type> | |
150 TypeFunction *tf = (TypeFunction *)fd->type; | |
151 assert(tf->ty == Tfunction); | |
152 Argument::argsCppMangle(&buf, &cms, tf->parameters, tf->varargs); | |
153 } | |
154 buf.writeByte(0); | |
155 return (char *)buf.extractData(); | |
156 } | |
157 | |
158 /* ============= Type Encodings ============================================= */ | |
159 | |
160 void Type::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
161 { | |
162 /* Make this the 'vendor extended type' when there is no | |
163 * C++ analog. | |
164 * u <source-name> | |
165 */ | |
166 if (!cms->substitute(buf, this)) | |
167 { assert(deco); | |
168 buf->printf("u%d%s", strlen(deco), deco); | |
169 } | |
170 } | |
171 | |
172 void TypeBasic::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
173 { char c; | |
174 char p = 0; | |
175 | |
176 /* ABI spec says: | |
177 * v void | |
178 * w wchar_t | |
179 * b bool | |
180 * c char | |
181 * a signed char | |
182 * h unsigned char | |
183 * s short | |
184 * t unsigned short | |
185 * i int | |
186 * j unsigned int | |
187 * l long | |
188 * m unsigned long | |
189 * x long long, __int64 | |
190 * y unsigned long long, __int64 | |
191 * n __int128 | |
192 * o unsigned __int128 | |
193 * f float | |
194 * d double | |
195 * e long double, __float80 | |
196 * g __float128 | |
197 * z ellipsis | |
198 * u <source-name> # vendor extended type | |
199 */ | |
200 | |
201 switch (ty) | |
202 { | |
203 case Tvoid: c = 'v'; break; | |
204 case Tint8: c = 'a'; break; | |
205 case Tuns8: c = 'h'; break; | |
206 case Tint16: c = 's'; break; | |
207 case Tuns16: c = 't'; break; | |
208 case Tint32: c = 'i'; break; | |
209 case Tuns32: c = 'j'; break; | |
210 case Tfloat32: c = 'f'; break; | |
211 case Tint64: c = 'x'; break; | |
212 case Tuns64: c = 'y'; break; | |
213 case Tfloat64: c = 'd'; break; | |
214 case Tfloat80: c = 'e'; break; | |
215 case Tbool: c = 'b'; break; | |
216 case Tchar: c = 'c'; break; | |
217 case Twchar: c = 't'; break; | |
218 case Tdchar: c = 'w'; break; | |
219 | |
220 case Timaginary32: p = 'G'; c = 'f'; break; | |
221 case Timaginary64: p = 'G'; c = 'd'; break; | |
222 case Timaginary80: p = 'G'; c = 'e'; break; | |
223 case Tcomplex32: p = 'C'; c = 'f'; break; | |
224 case Tcomplex64: p = 'C'; c = 'd'; break; | |
225 case Tcomplex80: p = 'C'; c = 'e'; break; | |
226 | |
227 default: assert(0); | |
228 } | |
229 if (p) | |
230 { | |
231 if (cms->substitute(buf, this)) | |
232 return; | |
233 buf->writeByte(p); | |
234 } | |
235 buf->writeByte(c); | |
236 } | |
237 | |
238 | |
239 void TypeSArray::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
240 { | |
241 if (!cms->substitute(buf, this)) | |
242 { buf->printf("A%ju_", dim ? dim->toInteger() : 0); | |
243 next->toCppMangle(buf, cms); | |
244 } | |
245 } | |
246 | |
247 void TypeDArray::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
248 { | |
249 Type::toCppMangle(buf, cms); | |
250 } | |
251 | |
252 | |
253 void TypeAArray::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
254 { | |
255 Type::toCppMangle(buf, cms); | |
256 } | |
257 | |
258 | |
259 void TypePointer::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
260 { | |
261 if (!cms->substitute(buf, this)) | |
262 { buf->writeByte('P'); | |
263 next->toCppMangle(buf, cms); | |
264 } | |
265 } | |
266 | |
267 | |
268 void TypeReference::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
269 { | |
270 if (!cms->substitute(buf, this)) | |
271 { buf->writeByte('R'); | |
272 next->toCppMangle(buf, cms); | |
273 } | |
274 } | |
275 | |
276 | |
277 void TypeFunction::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
278 { /* | |
279 * <function-type> ::= F [Y] <bare-function-type> E | |
280 * <bare-function-type> ::= <signature type>+ | |
281 * # types are possible return type, then parameter types | |
282 */ | |
283 | |
284 /* ABI says: | |
285 "The type of a non-static member function is considered to be different, | |
286 for the purposes of substitution, from the type of a namespace-scope or | |
287 static member function whose type appears similar. The types of two | |
288 non-static member functions are considered to be different, for the | |
289 purposes of substitution, if the functions are members of different | |
290 classes. In other words, for the purposes of substitution, the class of | |
291 which the function is a member is considered part of the type of | |
292 function." | |
293 | |
294 BUG: Right now, types of functions are never merged, so our simplistic | |
295 component matcher always finds them to be different. | |
296 We should use Type::equals on these, and use different | |
297 TypeFunctions for non-static member functions, and non-static | |
298 member functions of different classes. | |
299 */ | |
300 if (!cms->substitute(buf, this)) | |
301 { | |
302 buf->writeByte('F'); | |
303 if (linkage == LINKc) | |
304 buf->writeByte('Y'); | |
305 next->toCppMangle(buf, cms); | |
306 Argument::argsCppMangle(buf, cms, parameters, varargs); | |
307 buf->writeByte('E'); | |
308 } | |
309 } | |
310 | |
311 | |
312 void TypeDelegate::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
313 { | |
314 Type::toCppMangle(buf, cms); | |
315 } | |
316 | |
317 | |
318 void TypeStruct::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
319 { | |
320 if (!cms->substitute(buf, sym)) | |
321 cpp_mangle_name(buf, cms, sym); | |
322 } | |
323 | |
324 | |
325 void TypeEnum::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
326 { | |
327 if (!cms->substitute(buf, sym)) | |
328 cpp_mangle_name(buf, cms, sym); | |
329 } | |
330 | |
331 | |
332 void TypeTypedef::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
333 { | |
334 Type::toCppMangle(buf, cms); | |
335 } | |
336 | |
337 | |
338 void TypeClass::toCppMangle(OutBuffer *buf, CppMangleState *cms) | |
339 { | |
340 if (!cms->substitute(buf, this)) | |
341 { buf->writeByte('P'); | |
342 if (!cms->substitute(buf, sym)) | |
343 cpp_mangle_name(buf, cms, sym); | |
344 } | |
345 } | |
346 | |
347 | |
348 | |
349 void Argument::argsCppMangle(OutBuffer *buf, CppMangleState *cms, Arguments *arguments, int varargs) | |
350 { int n = 0; | |
351 if (arguments) | |
352 { | |
353 for (size_t i = 0; i < arguments->dim; i++) | |
354 { Argument *arg = (Argument *)arguments->data[i]; | |
355 Type *t = arg->type; | |
356 if (arg->storageClass & (STCout | STCref)) | |
357 t = t->referenceTo(); | |
358 else if (arg->storageClass & STClazy) | |
359 { // Mangle as delegate | |
360 Type *td = new TypeFunction(NULL, t, 0, LINKd); | |
361 td = new TypeDelegate(td); | |
362 t = t->merge(); | |
363 } | |
364 if (t->ty == Tsarray) | |
365 { // Mangle static arrays as pointers | |
366 t = t->pointerTo(); | |
367 } | |
368 t->toCppMangle(buf, cms); | |
369 | |
370 n++; | |
371 } | |
372 } | |
373 if (varargs) | |
374 buf->writestring("z"); | |
375 else if (!n) | |
376 buf->writeByte('v'); // encode ( ) arguments | |
377 } | |
378 | |
379 | |
380 #endif | |
381 |