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