root/trunk/src/mangle.c

Revision 793, 6.8 kB (checked in by walter, 1 year ago)

Brad's fix for fail278 regression

  • Property svn:eol-style set to native
Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2010 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <assert.h>
14
15 #include "root.h"
16
17 #include "init.h"
18 #include "declaration.h"
19 #include "aggregate.h"
20 #include "mtype.h"
21 #include "attrib.h"
22 #include "template.h"
23 #include "id.h"
24 #include "module.h"
25
26 #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
27 char *cpp_mangle(Dsymbol *s);
28 #endif
29
30 char *mangle(Declaration *sthis)
31 {
32     OutBuffer buf;
33     char *id;
34     Dsymbol *s;
35
36     //printf("::mangle(%s)\n", sthis->toChars());
37     s = sthis;
38     do
39     {
40         //printf("mangle: s = %p, '%s', parent = %p\n", s, s->toChars(), s->parent);
41         if (s->ident)
42         {
43             FuncDeclaration *fd = s->isFuncDeclaration();
44             if (s != sthis && fd)
45             {
46                 id = mangle(fd);
47                 buf.prependstring(id);
48                 goto L1;
49             }
50             else
51             {
52                 id = s->ident->toChars();
53                 int len = strlen(id);
54                 char tmp[sizeof(len) * 3 + 1];
55                 buf.prependstring(id);
56                 sprintf(tmp, "%d", len);
57                 buf.prependstring(tmp);
58             }
59         }
60         else
61             buf.prependstring("0");
62         s = s->parent;
63     } while (s);
64
65 //    buf.prependstring("_D");
66 L1:
67     //printf("deco = '%s'\n", sthis->type->deco ? sthis->type->deco : "null");
68     //printf("sthis->type = %s\n", sthis->type->toChars());
69     FuncDeclaration *fd = sthis->isFuncDeclaration();
70     if (fd && (fd->needThis() || fd->isNested()))
71         buf.writeByte(Type::needThisPrefix());
72     if (sthis->type->deco)
73         buf.writestring(sthis->type->deco);
74     else
75     {
76 #ifdef DEBUG
77         if (!fd->inferRetType)
78             printf("%s\n", fd->toChars());
79 #endif
80         assert(fd && fd->inferRetType);
81     }
82
83     id = buf.toChars();
84     buf.data = NULL;
85     return id;
86 }
87
88 char *Declaration::mangle()
89 #if __DMC__
90     __out(result)
91     {
92         int len = strlen(result);
93
94         assert(len > 0);
95         //printf("mangle: '%s' => '%s'\n", toChars(), result);
96         for (int i = 0; i < len; i++)
97         {
98             assert(result[i] == '_' ||
99                    result[i] == '@' ||
100                    isalnum(result[i]) || result[i] & 0x80);
101         }
102     }
103     __body
104 #endif
105     {
106         //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n", this, toChars(), parent ? parent->toChars() : "null", linkage);
107         if (!parent || parent->isModule() || linkage == LINKcpp) // if at global scope
108         {
109             // If it's not a D declaration, no mangling
110             switch (linkage)
111             {
112                 case LINKd:
113                     break;
114
115                 case LINKc:
116                 case LINKwindows:
117                 case LINKpascal:
118                     return ident->toChars();
119
120                 case LINKcpp:
121 #if CPP_MANGLE
122                     return cpp_mangle(this);
123 #else
124                     // Windows C++ mangling is done by C++ back end
125                     return ident->toChars();
126 #endif
127
128                 case LINKdefault:
129                     error("forward declaration");
130                     return ident->toChars();
131
132                 default:
133                     fprintf(stdmsg, "'%s', linkage = %d\n", toChars(), linkage);
134                     assert(0);
135             }
136         }
137         char *p = ::mangle(this);
138         OutBuffer buf;
139         buf.writestring("_D");
140         buf.writestring(p);
141         p = buf.toChars();
142         buf.data = NULL;
143         //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d) = %s\n", this, toChars(), parent ? parent->toChars() : "null", linkage, p);
144         return p;
145     }
146
147 char *FuncDeclaration::mangle()
148 #if __DMC__
149     __out(result)
150     {
151         assert(strlen(result) > 0);
152     }
153     __body
154 #endif
155     {
156         if (isMain())
157             return (char *)"_Dmain";
158
159         if (isWinMain() || isDllMain() || ident == Id::tls_get_addr)
160             return ident->toChars();
161
162         assert(this);
163         return Declaration::mangle();
164     }
165
166 char *StructDeclaration::mangle()
167 {
168     //printf("StructDeclaration::mangle() '%s'\n", toChars());
169     return Dsymbol::mangle();
170 }
171
172
173 char *TypedefDeclaration::mangle()
174 {
175     //printf("TypedefDeclaration::mangle() '%s'\n", toChars());
176     return Dsymbol::mangle();
177 }
178
179
180 char *ClassDeclaration::mangle()
181 {
182     Dsymbol *parentsave = parent;
183
184     //printf("ClassDeclaration::mangle() %s.%s\n", parent->toChars(), toChars());
185
186     /* These are reserved to the compiler, so keep simple
187      * names for them.
188      */
189     if (ident == Id::Exception)
190     {   if (parent->ident == Id::object)
191             parent = NULL;
192     }
193     else if (ident == Id::TypeInfo   ||
194 //      ident == Id::Exception ||
195         ident == Id::TypeInfo_Struct   ||
196         ident == Id::TypeInfo_Class    ||
197         ident == Id::TypeInfo_Typedef  ||
198         ident == Id::TypeInfo_Tuple ||
199         this == object     ||
200         this == classinfo  ||
201         this == Module::moduleinfo ||
202         memcmp(ident->toChars(), "TypeInfo_", 9) == 0
203        )
204         parent = NULL;
205
206     char *id = Dsymbol::mangle();
207     parent = parentsave;
208     return id;
209 }
210
211
212 char *TemplateInstance::mangle()
213 {
214     OutBuffer buf;
215
216 #if 0
217     printf("TemplateInstance::mangle() %p %s", this, toChars());
218     if (parent)
219         printf("  parent = %s %s", parent->kind(), parent->toChars());
220     printf("\n");
221 #endif
222     char *id = ident ? ident->toChars() : toChars();
223     if (!tempdecl)
224         error("is not defined");
225     else
226     {
227         Dsymbol *par = isnested || isTemplateMixin() ? parent : tempdecl->parent;
228         if (par)
229         {
230             char *p = par->mangle();
231             if (p[0] == '_' && p[1] == 'D')
232                 p += 2;
233             buf.writestring(p);
234         }
235     }
236     buf.printf("%zu%s", strlen(id), id);
237     id = buf.toChars();
238     buf.data = NULL;
239     //printf("TemplateInstance::mangle() %s = %s\n", toChars(), id);
240     return id;
241 }
242
243
244
245 char *Dsymbol::mangle()
246 {
247     OutBuffer buf;
248     char *id;
249
250 #if 0
251     printf("Dsymbol::mangle() '%s'", toChars());
252     if (parent)
253         printf("  parent = %s %s", parent->kind(), parent->toChars());
254     printf("\n");
255 #endif
256     id = ident ? ident->toChars() : toChars();
257     if (parent)
258     {
259         char *p = parent->mangle();
260         if (p[0] == '_' && p[1] == 'D')
261             p += 2;
262         buf.writestring(p);
263     }
264     buf.printf("%zu%s", strlen(id), id);
265     id = buf.toChars();
266     buf.data = NULL;
267     //printf("Dsymbol::mangle() %s = %s\n", toChars(), id);
268     return id;
269 }
Note: See TracBrowser for help on using the browser.