Automatically add stem to GObject method names
[delight/core.git] / dmd2 / mangle.c
blob9565958bef342b682c15ac1e1d1e34327a81cd3f
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.
11 /* NOTE: This file has been patched from the original DMD distribution to
12 work with the GDC compiler.
14 Modified by David Friedman, December 2006
17 #include <stdio.h>
18 #include <string.h>
19 #include <ctype.h>
20 #include <assert.h>
22 #include "root.h"
24 #include "init.h"
25 #include "declaration.h"
26 #include "aggregate.h"
27 #include "mtype.h"
28 #include "attrib.h"
29 #include "template.h"
30 #include "id.h"
31 #include "module.h"
33 #if IN_GCC || TARGET_LINUX
34 char *cpp_mangle(Dsymbol *s);
35 #endif
37 char *mangle(Declaration *sthis)
39 OutBuffer buf;
40 char *id;
41 Dsymbol *s;
43 //printf("::mangle(%s)\n", sthis->toChars());
44 s = sthis;
47 //printf("mangle: s = %p, '%s', parent = %p\n", s, s->toChars(), s->parent);
48 if (s->ident)
50 FuncDeclaration *fd = s->isFuncDeclaration();
51 if (s != sthis && fd)
53 id = mangle(fd);
54 buf.prependstring(id);
55 goto L1;
57 else
59 id = s->ident->toChars();
60 int len = strlen(id);
61 char tmp[sizeof(len) * 3 + 1];
62 buf.prependstring(id);
63 sprintf(tmp, "%d", len);
64 buf.prependstring(tmp);
67 else
68 buf.prependstring("0");
69 s = s->parent;
70 } while (s);
72 // buf.prependstring("_D");
73 L1:
74 //printf("deco = '%s'\n", sthis->type->deco ? sthis->type->deco : "null");
75 //printf("sthis->type = %s\n", sthis->type->toChars());
76 FuncDeclaration *fd = sthis->isFuncDeclaration();
77 if (fd && (fd->needThis() || fd->isNested()))
78 buf.writeByte(Type::needThisPrefix());
79 if (sthis->type->deco)
81 /* It's too hard to figure out when a symbol came from D and when from Dlt,
82 * so strip the maybe IDs.
84 char *p = sthis->type->deco;
85 while (*p) {
86 if (*p != '?')
87 buf.writebyte(*p);
88 p++;
91 else
92 { assert(fd->inferRetType);
95 id = buf.toChars();
96 buf.data = NULL;
97 return id;
100 char *Declaration::mangle()
101 #if __DMC__
102 __out(result)
104 int len = strlen(result);
106 assert(len > 0);
107 //printf("mangle: '%s' => '%s'\n", toChars(), result);
108 for (int i = 0; i < len; i++)
110 assert(result[i] == '_' ||
111 result[i] == '@' ||
112 isalnum(result[i]) || result[i] & 0x80);
115 __body
116 #endif
118 //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n", this, toChars(), parent ? parent->toChars() : "null", linkage);
119 if (!parent || parent->isModule() || // if at global scope
120 linkage == LINKcpp ||
121 linkage == LINKgobject)
123 // If it's not a D declaration, no mangling
124 switch (linkage)
126 case LINKd:
127 break;
129 case LINKc:
130 case LINKwindows:
131 case LINKpascal:
132 return ident->toChars();
134 case LINKgobject:
135 { ClassDeclaration *cd = parent->isClassDeclaration();
136 if (cd)
138 OutBuffer buf;
139 char *cp = cd->ident->toChars();
140 bool start = true;
141 while (char c = *cp) {
142 if (isupper(c))
144 if (!start)
145 buf.writeByte('_');
146 buf.writeByte(tolower(c));
147 start = true;
149 else
151 buf.writeByte(c);
152 start = false;
154 cp++;
156 buf.writeByte('_');
157 buf.writestring(ident->toChars());
158 char *p = buf.toChars();
159 buf.data = NULL;
160 return p;
162 else
163 return ident->toChars();
165 case LINKcpp:
166 #if IN_GCC || TARGET_LINUX
167 return cpp_mangle(this);
168 #else
169 // Windows C++ mangling is done by C++ back end
170 return ident->toChars();
171 #endif
173 case LINKdefault:
174 error("forward declaration");
175 return ident->toChars();
177 default:
178 fprintf(stdmsg, "'%s', linkage = %d\n", toChars(), linkage);
179 assert(0);
182 char *p = ::mangle(this);
183 OutBuffer buf;
184 buf.writestring("_D");
185 buf.writestring(p);
186 p = buf.toChars();
187 buf.data = NULL;
188 //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d) = %s\n", this, toChars(), parent ? parent->toChars() : "null", linkage, p);
189 return p;
192 char *FuncDeclaration::mangle()
193 #if __DMC__
194 __out(result)
196 assert(strlen(result) > 0);
198 __body
199 #endif
201 if (isMain())
202 return "_Dmain";
204 if (isWinMain() || isDllMain())
205 return ident->toChars();
207 assert(this);
208 return Declaration::mangle();
212 char *StructDeclaration::mangle()
214 //printf("StructDeclaration::mangle() '%s'\n", toChars());
215 return Dsymbol::mangle();
219 char *TypedefDeclaration::mangle()
221 //printf("TypedefDeclaration::mangle() '%s'\n", toChars());
222 return Dsymbol::mangle();
226 char *ClassDeclaration::mangle()
228 Dsymbol *parentsave = parent;
230 //printf("ClassDeclaration::mangle() %s.%s\n", parent->toChars(), toChars());
232 /* These are reserved to the compiler, so keep simple
233 * names for them.
235 if (ident == Id::Exception)
236 { if (parent->ident == Id::object)
237 parent = NULL;
239 else if (ident == Id::TypeInfo ||
240 // ident == Id::Exception ||
241 ident == Id::TypeInfo_Struct ||
242 ident == Id::TypeInfo_Class ||
243 ident == Id::TypeInfo_Typedef ||
244 ident == Id::TypeInfo_Tuple ||
245 this == object ||
246 this == classinfo ||
247 this == Module::moduleinfo ||
248 memcmp(ident->toChars(), "TypeInfo_", 9) == 0
250 parent = NULL;
252 char *id = Dsymbol::mangle();
253 parent = parentsave;
254 return id;
258 char *TemplateInstance::mangle()
260 OutBuffer buf;
261 char *id;
263 #if 0
264 printf("TemplateInstance::mangle() %s", toChars());
265 if (parent)
266 printf(" parent = %s %s", parent->kind(), parent->toChars());
267 printf("\n");
268 #endif
269 id = ident ? ident->toChars() : toChars();
270 if (tempdecl->parent)
272 char *p = tempdecl->parent->mangle();
273 if (p[0] == '_' && p[1] == 'D')
274 p += 2;
275 buf.writestring(p);
277 buf.printf("%"PRIuSIZE"%s", strlen(id), id);
278 id = buf.toChars();
279 buf.data = NULL;
280 //printf("TemplateInstance::mangle() %s = %s\n", toChars(), id);
281 return id;
286 char *Dsymbol::mangle()
288 OutBuffer buf;
289 char *id;
291 #if 0
292 printf("Dsymbol::mangle() '%s'", toChars());
293 if (parent)
294 printf(" parent = %s %s", parent->kind(), parent->toChars());
295 printf("\n");
296 #endif
297 id = ident ? ident->toChars() : toChars();
298 if (parent)
300 char *p = parent->mangle();
301 if (p[0] == '_' && p[1] == 'D')
302 p += 2;
303 buf.writestring(p);
305 buf.printf("%"PRIuSIZE"%s", strlen(id), id);
306 id = buf.toChars();
307 buf.data = NULL;
308 //printf("Dsymbol::mangle() %s = %s\n", toChars(), id);
309 return id;