1 /* GDC -- D front-end for GCC
2 Copyright (C) 2007 David Friedman
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "d-gcc-includes.h"
26 #include "d-codegen.h"
28 // Declared in dmd/mangle.c
29 char *cpp_mangle(Dsymbol
*s
);
32 to_base36(unsigned n
, OutBuffer
* buf
)
34 static const char base_36_digits
[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
43 char *p
= cbuf
+ sizeof(cbuf
);
48 *--p
= base_36_digits
[n
- d
* 36];
51 buf
->write(p
, sizeof(cbuf
) - (p
- cbuf
));
60 bool _hasSubstitute(void * p
, OutBuffer
* buf
)
62 for (unsigned i
= 0; i
< substitutions
.dim
; ++i
)
63 if ( substitutions
.data
[i
] == p
)
69 to_base36(i
- 1, buf
);
77 bool hasSubstitute(Type
* type
, OutBuffer
* buf
)
79 return _hasSubstitute(type
, buf
);
81 bool hasSubstitute(Dsymbol
* sym
, OutBuffer
* buf
)
83 return _hasSubstitute(sym
, buf
);
85 void add(Dsymbol
* sym
)
87 substitutions
.push(sym
);
91 substitutions
.push(typ
);
96 cpp_mangle_arguments(TypeFunction
* tf
, OutBuffer
* buf
, CppMangleState
*cms
)
98 bool have_some_args
= false;
102 size_t dim
= Argument::dim(tf
->parameters
);
103 for (size_t i
= 0; i
< dim
; i
++)
104 { Argument
*arg
= Argument::getNth(tf
->parameters
, i
);
106 have_some_args
= true;
107 if (arg
->storageClass
& (STClazy
))
109 // DMD does not report an error...
110 cms
->topSymbol
->error("cannot represent lazy parameter in C++");
112 else if (arg
->storageClass
& (STCout
| STCref
))
114 arg
->type
->referenceTo()->toCppMangle(buf
, cms
);
117 else if (arg
->type
->ty
== Tsarray
)
119 /* C++ would encode as pointer-to-elem-type, but DMD encodes
120 as pointer-to-array-type. */
121 arg
->type
->pointerTo()->toCppMangle(buf
, cms
);
125 // %% const/invariant not translated?
127 arg
->type
->toCppMangle(buf
, cms
);
130 if (tf
->varargs
== 1)
132 else if (! have_some_args
)
137 cpp_mangle1(Dsymbol
*sthis
, OutBuffer
* buf
, CppMangleState
* cms
)
139 if (cms
->hasSubstitute(sthis
, buf
))
143 bool is_nested_ident
= false;
144 FuncDeclaration
* fd
;
150 if ( s
!= sthis
&& s
->isFuncDeclaration() )
153 cpp_mangle1(s
, buf
, cms
);
158 is_nested_ident
= true;
161 s
= s
->parent
; // %% ?
162 } while (s
&& ! s
->isModule());
168 for (ii
= 0; ii
< pfxs
.dim
; ++ii
)
170 s
= (Dsymbol
*) pfxs
.data
[ii
];
171 if (cms
->hasSubstitute(s
, buf
))
176 s
= (Dsymbol
*) pfxs
.data
[--ii
];
179 buf
->printf("%d", (int) s
->ident
->len
);
180 buf
->write(s
->ident
->string
, s
->ident
->len
);
184 if (! s
->isFuncDeclaration())
191 if ( (fd
= sthis
->isFuncDeclaration()) )
193 cpp_mangle_arguments((TypeFunction
*) fd
->type
, buf
, cms
);
198 cpp_mangle(Dsymbol
*s
)
206 cpp_mangle1(s
, & o
, & cms
);
209 return (char*) o
.extractData();
213 Type::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
215 //error("cannot represent type '%s' in C++", toChars());
216 // DMD uses D type mangle.
218 if (! cms
->hasSubstitute(this, buf
))
221 toDecoBuffer(& o
, 0);
222 buf
->printf("%d", (int) o
.offset
);
230 cpp_mangle_fp(Type
* t
, const char * mngl
, OutBuffer
*buf
, CppMangleState
*cms
)
232 if (! cms
->hasSubstitute(t
, buf
))
234 buf
->writestring(mngl
);
241 TypeBasic::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
247 case Tvoid
: c
= 'v'; break;
248 case Tint8
: c
= 'a'; break;
249 case Tuns8
: c
= 'h'; break;
250 case Tint16
: c
= 's'; break;
251 case Tuns16
: c
= 't'; break;
252 case Tint32
: c
= 'i'; break;
253 case Tuns32
: c
= 'j'; break;
254 case Tint64
: c
= 'x'; break;
255 case Tuns64
: c
= 'y'; break;
256 case Tfloat32
: c
= 'f'; break;
257 case Tfloat64
: c
= 'd'; break;
258 case Tfloat80
: c
= 'e'; break; // %% could change in the future when D real vs. C long double type is corrected
260 case Timaginary32
: s
= "Gf"; goto do_fp
;
261 case Timaginary64
: s
= "Gd"; goto do_fp
;
262 case Timaginary80
: s
= "Ge"; goto do_fp
; // %% ditto
263 case Tcomplex32
: s
= "Cf"; goto do_fp
;
264 case Tcomplex64
: s
= "Cd"; goto do_fp
;
265 case Tcomplex80
: s
= "Ce"; // %% ditto
267 cpp_mangle_fp(this, s
, buf
, cms
);
270 case Tbool
: c
= 'b'; break;
272 case Tchar
: c
= 'c'; break;
273 #ifdef WCHAR_TYPE_SIZE
275 if (WCHAR_TYPE_SIZE
== 16)
281 if (WCHAR_TYPE_SIZE
== 32)
287 case Twchar
: c
= 't'; break;
288 case Tdchar
: c
= 'j'; break;
292 Type::toCppMangle(buf
, cms
);
299 TypeSArray::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
301 if (! cms
->hasSubstitute(this, buf
))
304 buf
->printf("A%"PRIuMAX
, dim
->toInteger());
307 next
->toCppMangle(buf
, cms
);
309 assert(! cms
->hasSubstitute(this, NULL
));
316 TypeDArray::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
318 return Type::toCppMangle(buf
, cms
);
322 TypeAArray::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
324 return Type::toCppMangle(buf
, cms
);
328 TypePointer::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
330 if (! cms
->hasSubstitute(this, buf
))
334 next
->toCppMangle(buf
, cms
);
336 assert(! cms
->hasSubstitute(this, NULL
));
343 TypeReference::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
345 if (! cms
->hasSubstitute(this, buf
))
349 next
->toCppMangle(buf
, cms
);
351 assert(! cms
->hasSubstitute(this, NULL
));
358 TypeFunction::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
360 if (! cms
->hasSubstitute(this, buf
))
364 next
->toCppMangle(buf
, cms
);
365 cpp_mangle_arguments(this, buf
, cms
);
368 assert(! cms
->hasSubstitute(this, NULL
));
375 TypeDelegate::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
377 Type::toCppMangle(buf
, cms
);
381 TypeStruct::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
383 cpp_mangle1(sym
, buf
, cms
);
387 TypeEnum::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
389 cpp_mangle1(sym
, buf
, cms
);
393 TypeTypedef::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
395 // DMD uses the D mangled typedef name.
396 Type::toCppMangle(buf
, cms
);
400 TypeClass::toCppMangle(OutBuffer
*buf
, CppMangleState
*cms
)
402 if (! cms
->hasSubstitute(this, buf
))
405 cpp_mangle1(sym
, buf
, cms
);
407 assert(! cms
->hasSubstitute(this, NULL
));