Blame


1 7d6f5677 2005-11-28 devnull /*
2 7d6f5677 2005-11-28 devnull * gcc2 name demangler.
3 2eb30524 2005-11-29 devnull *
4 2eb30524 2005-11-29 devnull * gcc2 follows the C++ Annotated Reference Manual section 7.2.1
5 2eb30524 2005-11-29 devnull * name mangling description with a few changes.
6 2eb30524 2005-11-29 devnull * See gpcompare.texi, gxxint_15.html in this directory for the changes.
7 2eb30524 2005-11-29 devnull *
8 2eb30524 2005-11-29 devnull * Not implemented:
9 2eb30524 2005-11-29 devnull * unicode mangling
10 dfbfbecf 2006-02-14 devnull * renaming of operator functions
11 7d6f5677 2005-11-28 devnull */
12 2eb30524 2005-11-29 devnull /*
13 2eb30524 2005-11-29 devnull RULES TO ADD:
14 2eb30524 2005-11-29 devnull
15 2eb30524 2005-11-29 devnull _10CycleTimer.cycles_per_ms_ => CycleTimer::cycles_per_ms_
16 2eb30524 2005-11-29 devnull
17 2eb30524 2005-11-29 devnull
18 2eb30524 2005-11-29 devnull */
19 7d6f5677 2005-11-28 devnull #include <u.h>
20 7d6f5677 2005-11-28 devnull #include <libc.h>
21 7d6f5677 2005-11-28 devnull #include <bio.h>
22 7d6f5677 2005-11-28 devnull #include <mach.h>
23 7d6f5677 2005-11-28 devnull
24 7d6f5677 2005-11-28 devnull #define debug 0
25 7d6f5677 2005-11-28 devnull
26 7d6f5677 2005-11-28 devnull typedef struct Chartab Chartab;
27 7d6f5677 2005-11-28 devnull struct Chartab
28 7d6f5677 2005-11-28 devnull {
29 7d6f5677 2005-11-28 devnull char c;
30 7d6f5677 2005-11-28 devnull char *s;
31 7d6f5677 2005-11-28 devnull };
32 7d6f5677 2005-11-28 devnull
33 7d6f5677 2005-11-28 devnull static char*
34 7d6f5677 2005-11-28 devnull chartabsearch(Chartab *ct, int c)
35 7d6f5677 2005-11-28 devnull {
36 7d6f5677 2005-11-28 devnull for(; ct->c; ct++)
37 7d6f5677 2005-11-28 devnull if(ct->c == c)
38 7d6f5677 2005-11-28 devnull return ct->s;
39 7d6f5677 2005-11-28 devnull return nil;
40 7d6f5677 2005-11-28 devnull }
41 7d6f5677 2005-11-28 devnull
42 2eb30524 2005-11-29 devnull static Chartab typetab[] =
43 7d6f5677 2005-11-28 devnull {
44 2eb30524 2005-11-29 devnull 'b', "bool",
45 2eb30524 2005-11-29 devnull 'c', "char",
46 2eb30524 2005-11-29 devnull 'd', "double",
47 2eb30524 2005-11-29 devnull 'e', "...",
48 2eb30524 2005-11-29 devnull 'f', "float",
49 2eb30524 2005-11-29 devnull 'i', "int",
50 2eb30524 2005-11-29 devnull 'J', "complex",
51 2eb30524 2005-11-29 devnull 'l', "long",
52 2eb30524 2005-11-29 devnull 'r', "long double",
53 2eb30524 2005-11-29 devnull 's', "short",
54 2eb30524 2005-11-29 devnull 'v', "void",
55 2eb30524 2005-11-29 devnull 'w', "wchar_t",
56 2eb30524 2005-11-29 devnull 'x', "long long",
57 2eb30524 2005-11-29 devnull 0, 0
58 7d6f5677 2005-11-28 devnull };
59 2eb30524 2005-11-29 devnull
60 2eb30524 2005-11-29 devnull static Chartab modifiertab[] =
61 2eb30524 2005-11-29 devnull {
62 2eb30524 2005-11-29 devnull 'C', "const",
63 2eb30524 2005-11-29 devnull 'S', "signed", /* means static for member functions */
64 2eb30524 2005-11-29 devnull 'U', "unsigned",
65 2eb30524 2005-11-29 devnull 'V', "volatile",
66 fa325e9b 2020-01-10 cross
67 2eb30524 2005-11-29 devnull 'G', "garbage", /* no idea what this is */
68 2eb30524 2005-11-29 devnull 0, 0
69 2eb30524 2005-11-29 devnull };
70 2eb30524 2005-11-29 devnull
71 2eb30524 2005-11-29 devnull static char constructor[] = "constructor";
72 2eb30524 2005-11-29 devnull static char destructor[] = "destructor";
73 2eb30524 2005-11-29 devnull static char gconstructor[] = "$gconstructor"; /* global destructor */
74 2eb30524 2005-11-29 devnull static char gdestructor[] = "$gdestructor"; /* global destructor */
75 2eb30524 2005-11-29 devnull
76 2eb30524 2005-11-29 devnull static char manglestarts[] = "123456789CFHQSUVt";
77 2eb30524 2005-11-29 devnull
78 2eb30524 2005-11-29 devnull static int gccname(char**, char**);
79 2eb30524 2005-11-29 devnull static char *demanglegcc2a(char*, char*);
80 2eb30524 2005-11-29 devnull static char *demanglegcc2b(char*, char*);
81 2eb30524 2005-11-29 devnull static char *demanglegcc2c(char*, char*);
82 2eb30524 2005-11-29 devnull static int gccnumber(char**, int*, int);
83 2eb30524 2005-11-29 devnull
84 7d6f5677 2005-11-28 devnull char*
85 7d6f5677 2005-11-28 devnull demanglegcc2(char *s, char *buf)
86 7d6f5677 2005-11-28 devnull {
87 2eb30524 2005-11-29 devnull char *name, *os, *p, *t;
88 2eb30524 2005-11-29 devnull int isfn, namelen;
89 7d6f5677 2005-11-28 devnull
90 fa325e9b 2020-01-10 cross
91 2eb30524 2005-11-29 devnull /*
92 2eb30524 2005-11-29 devnull * Pick off some cases that seem not to fit the pattern.
93 2eb30524 2005-11-29 devnull */
94 2eb30524 2005-11-29 devnull if((t = demanglegcc2a(s, buf)) != nil)
95 2eb30524 2005-11-29 devnull return t;
96 2eb30524 2005-11-29 devnull if((t = demanglegcc2b(s, buf)) != nil)
97 2eb30524 2005-11-29 devnull return t;
98 2eb30524 2005-11-29 devnull if((t = demanglegcc2c(s, buf)) != nil)
99 2eb30524 2005-11-29 devnull return t;
100 2eb30524 2005-11-29 devnull
101 2eb30524 2005-11-29 devnull /*
102 2eb30524 2005-11-29 devnull * First, figure out whether this is a mangled name.
103 2eb30524 2005-11-29 devnull * The name begins with a short version of the name, then __.
104 2eb30524 2005-11-29 devnull * Of course, some C names begin with __ too, so the ultimate
105 2eb30524 2005-11-29 devnull * test is whether what follows __ looks reasonable.
106 2eb30524 2005-11-29 devnull * We use a test on the first letter instead.
107 2eb30524 2005-11-29 devnull *
108 2eb30524 2005-11-29 devnull * Constructors have no name - they begin __ (double underscore).
109 2eb30524 2005-11-29 devnull * Destructors break the rule - they begin _._ (underscore, dot, underscore).
110 2eb30524 2005-11-29 devnull */
111 2eb30524 2005-11-29 devnull os = s;
112 2eb30524 2005-11-29 devnull isfn = 0;
113 2eb30524 2005-11-29 devnull if(memcmp(s, "_._", 3) == 0){
114 2eb30524 2005-11-29 devnull isfn = 1;
115 2eb30524 2005-11-29 devnull name = destructor;
116 7d6f5677 2005-11-28 devnull namelen = strlen(name);
117 2eb30524 2005-11-29 devnull s += 3;
118 2eb30524 2005-11-29 devnull }else if(memcmp(s, "_GLOBAL_.D.__", 13) == 0){
119 2eb30524 2005-11-29 devnull isfn = 1;
120 2eb30524 2005-11-29 devnull name = gdestructor;
121 2eb30524 2005-11-29 devnull namelen = strlen(name);
122 fa325e9b 2020-01-10 cross s += 13;
123 2eb30524 2005-11-29 devnull }else if(memcmp(s, "_GLOBAL_.D._", 12) == 0){
124 2eb30524 2005-11-29 devnull isfn = 0;
125 2eb30524 2005-11-29 devnull name = gdestructor;
126 2eb30524 2005-11-29 devnull namelen = strlen(name);
127 fa325e9b 2020-01-10 cross s += 12;
128 2eb30524 2005-11-29 devnull }else if(memcmp(s, "_GLOBAL_.I.__", 13) == 0){
129 2eb30524 2005-11-29 devnull isfn = 1;
130 2eb30524 2005-11-29 devnull name = gconstructor;
131 2eb30524 2005-11-29 devnull namelen = strlen(name);
132 fa325e9b 2020-01-10 cross s += 13;
133 2eb30524 2005-11-29 devnull }else if(memcmp(s, "_GLOBAL_.I._", 12) == 0){
134 2eb30524 2005-11-29 devnull isfn = 0;
135 2eb30524 2005-11-29 devnull name = gconstructor;
136 2eb30524 2005-11-29 devnull namelen = strlen(name);
137 fa325e9b 2020-01-10 cross s += 12;
138 7d6f5677 2005-11-28 devnull }else{
139 2eb30524 2005-11-29 devnull t = strstr(os, "__");
140 2eb30524 2005-11-29 devnull if(t == nil)
141 7d6f5677 2005-11-28 devnull return os;
142 7d6f5677 2005-11-28 devnull do{
143 2eb30524 2005-11-29 devnull s = t;
144 2eb30524 2005-11-29 devnull if(strchr(manglestarts, *(s+2)))
145 7d6f5677 2005-11-28 devnull break;
146 2eb30524 2005-11-29 devnull }while((t = strstr(s+1, "__")) != nil);
147 fa325e9b 2020-01-10 cross
148 7d6f5677 2005-11-28 devnull name = os;
149 2eb30524 2005-11-29 devnull namelen = s - os;
150 7d6f5677 2005-11-28 devnull if(namelen == 0){
151 2eb30524 2005-11-29 devnull isfn = 1;
152 2eb30524 2005-11-29 devnull name = constructor;
153 7d6f5677 2005-11-28 devnull namelen = strlen(name);
154 7d6f5677 2005-11-28 devnull }
155 7d6f5677 2005-11-28 devnull s += 2;
156 7d6f5677 2005-11-28 devnull }
157 fa325e9b 2020-01-10 cross
158 2eb30524 2005-11-29 devnull /*
159 2eb30524 2005-11-29 devnull * Now s points at the mangled crap (maybe).
160 2eb30524 2005-11-29 devnull * and name is the final element of the name.
161 2eb30524 2005-11-29 devnull */
162 2eb30524 2005-11-29 devnull if(strchr(manglestarts, *s) == nil)
163 7d6f5677 2005-11-28 devnull return os;
164 fa325e9b 2020-01-10 cross
165 2eb30524 2005-11-29 devnull p = buf;
166 2eb30524 2005-11-29 devnull if(*s == 'F'){
167 2eb30524 2005-11-29 devnull /* global function, no extra name pieces, just types */
168 2eb30524 2005-11-29 devnull isfn = 1;
169 2eb30524 2005-11-29 devnull }else{
170 2eb30524 2005-11-29 devnull /* parse extra name pieces */
171 2eb30524 2005-11-29 devnull if(!gccname(&s, &p)){
172 2eb30524 2005-11-29 devnull if(debug)
173 2eb30524 2005-11-29 devnull fprint(2, "parsename %s: %r\n", s);
174 7d6f5677 2005-11-28 devnull return os;
175 7d6f5677 2005-11-28 devnull }
176 fa325e9b 2020-01-10 cross
177 2eb30524 2005-11-29 devnull /* if we have a constructor or destructor, try to use the C++ name */
178 2eb30524 2005-11-29 devnull t = nil;
179 2eb30524 2005-11-29 devnull if(name == constructor || name == destructor){
180 2eb30524 2005-11-29 devnull *p = 0;
181 2eb30524 2005-11-29 devnull t = strrchr(buf, ':');
182 7dc9c4c6 2005-11-29 devnull if(t)
183 7dc9c4c6 2005-11-29 devnull t++;
184 7dc9c4c6 2005-11-29 devnull else
185 2eb30524 2005-11-29 devnull t = buf;
186 2eb30524 2005-11-29 devnull }
187 7d6f5677 2005-11-28 devnull strcpy(p, "::");
188 7d6f5677 2005-11-28 devnull p += 2;
189 2eb30524 2005-11-29 devnull if(t){
190 2eb30524 2005-11-29 devnull namelen = strlen(t)-2;
191 2eb30524 2005-11-29 devnull if(name == destructor)
192 2eb30524 2005-11-29 devnull *p++ = '~';
193 2eb30524 2005-11-29 devnull name = t;
194 2eb30524 2005-11-29 devnull }
195 7d6f5677 2005-11-28 devnull }
196 7dc9c4c6 2005-11-29 devnull if(p >= buf+2 && memcmp(p-2, "::", 2) == 0 && *(p-3) == ')')
197 7dc9c4c6 2005-11-29 devnull p -= 2;
198 7d6f5677 2005-11-28 devnull memmove(p, name, namelen);
199 7d6f5677 2005-11-28 devnull p += namelen;
200 fa325e9b 2020-01-10 cross
201 2eb30524 2005-11-29 devnull if(*s == 'F'){
202 2eb30524 2005-11-29 devnull /* might be from above, or might follow name pieces */
203 2eb30524 2005-11-29 devnull s++;
204 2eb30524 2005-11-29 devnull isfn = 1;
205 2eb30524 2005-11-29 devnull }
206 7d6f5677 2005-11-28 devnull
207 2eb30524 2005-11-29 devnull /* the rest of the name is argument types - could skip this */
208 2eb30524 2005-11-29 devnull if(*s || isfn){
209 7d6f5677 2005-11-28 devnull *p++ = '(';
210 2eb30524 2005-11-29 devnull while(*s != 0 && *s != '_'){
211 2eb30524 2005-11-29 devnull if(!gccname(&s, &p))
212 2eb30524 2005-11-29 devnull break;
213 7d6f5677 2005-11-28 devnull *p++ = ',';
214 2eb30524 2005-11-29 devnull }
215 7d6f5677 2005-11-28 devnull if(*(p-1) == ',')
216 7d6f5677 2005-11-28 devnull p--;
217 7d6f5677 2005-11-28 devnull *p++ = ')';
218 7d6f5677 2005-11-28 devnull }
219 7d6f5677 2005-11-28 devnull
220 2eb30524 2005-11-29 devnull if(*s == '_'){
221 2eb30524 2005-11-29 devnull /* return type (left over from H) */
222 fa325e9b 2020-01-10 cross }
223 fa325e9b 2020-01-10 cross
224 7d6f5677 2005-11-28 devnull *p = 0;
225 7d6f5677 2005-11-28 devnull return buf;
226 7d6f5677 2005-11-28 devnull }
227 7d6f5677 2005-11-28 devnull
228 2eb30524 2005-11-29 devnull /*
229 2eb30524 2005-11-29 devnull * _10CycleTimer.cycles_per_ms_ => CycleTimer::cycles_per_ms_
230 2eb30524 2005-11-29 devnull * _t12basic_string3ZcZt11char_traits1ZcZt9allocator1Zc.npos
231 2eb30524 2005-11-29 devnull * (maybe the funny syntax means they are private)
232 2eb30524 2005-11-29 devnull */
233 2eb30524 2005-11-29 devnull static char*
234 2eb30524 2005-11-29 devnull demanglegcc2a(char *s, char *buf)
235 7d6f5677 2005-11-28 devnull {
236 2eb30524 2005-11-29 devnull char *p;
237 fa325e9b 2020-01-10 cross
238 2eb30524 2005-11-29 devnull if(*s != '_' || strchr(manglestarts, *(s+1)) == nil)
239 2eb30524 2005-11-29 devnull return nil;
240 2eb30524 2005-11-29 devnull p = buf;
241 2eb30524 2005-11-29 devnull s++;
242 2eb30524 2005-11-29 devnull if(!gccname(&s, &p))
243 2eb30524 2005-11-29 devnull return nil;
244 2eb30524 2005-11-29 devnull if(*s != '.')
245 2eb30524 2005-11-29 devnull return nil;
246 2eb30524 2005-11-29 devnull s++;
247 2eb30524 2005-11-29 devnull strcpy(p, "::");
248 2eb30524 2005-11-29 devnull p += 2;
249 2eb30524 2005-11-29 devnull strcpy(p, s);
250 2eb30524 2005-11-29 devnull return buf;
251 2eb30524 2005-11-29 devnull }
252 7d6f5677 2005-11-28 devnull
253 2eb30524 2005-11-29 devnull /*
254 2eb30524 2005-11-29 devnull * _tfb => type info for bool
255 2eb30524 2005-11-29 devnull * __vt_7ostream => vtbl for ostream
256 2eb30524 2005-11-29 devnull */
257 2eb30524 2005-11-29 devnull static char*
258 2eb30524 2005-11-29 devnull demanglegcc2b(char *s, char *buf)
259 2eb30524 2005-11-29 devnull {
260 2eb30524 2005-11-29 devnull char *p;
261 2eb30524 2005-11-29 devnull char *t;
262 fa325e9b 2020-01-10 cross
263 2eb30524 2005-11-29 devnull if(memcmp(s, "__ti", 4) == 0){
264 2eb30524 2005-11-29 devnull t = "$typeinfo";
265 2eb30524 2005-11-29 devnull s += 4;
266 2eb30524 2005-11-29 devnull }else if(memcmp(s, "__tf", 4) == 0){
267 2eb30524 2005-11-29 devnull t = "$typeinfofn";
268 2eb30524 2005-11-29 devnull s += 4;
269 2eb30524 2005-11-29 devnull }else if(memcmp(s, "__vt_", 5) == 0){
270 2eb30524 2005-11-29 devnull t = "$vtbl";
271 2eb30524 2005-11-29 devnull s += 5;
272 2eb30524 2005-11-29 devnull }else
273 2eb30524 2005-11-29 devnull return nil;
274 2eb30524 2005-11-29 devnull
275 2eb30524 2005-11-29 devnull p = buf;
276 2eb30524 2005-11-29 devnull for(;;){
277 2eb30524 2005-11-29 devnull if(*s == 0 || !gccname(&s, &p))
278 2eb30524 2005-11-29 devnull return nil;
279 2eb30524 2005-11-29 devnull if(*s == 0)
280 2eb30524 2005-11-29 devnull break;
281 2eb30524 2005-11-29 devnull if(*s != '.' && *s != '$')
282 2eb30524 2005-11-29 devnull return nil;
283 2eb30524 2005-11-29 devnull strcpy(p, "::");
284 2eb30524 2005-11-29 devnull p += 2;
285 2eb30524 2005-11-29 devnull s++;
286 2eb30524 2005-11-29 devnull }
287 2eb30524 2005-11-29 devnull strcpy(p, "::");
288 2eb30524 2005-11-29 devnull p += 2;
289 2eb30524 2005-11-29 devnull strcpy(p, t);
290 2eb30524 2005-11-29 devnull return buf;
291 2eb30524 2005-11-29 devnull }
292 2eb30524 2005-11-29 devnull
293 2eb30524 2005-11-29 devnull /*
294 2eb30524 2005-11-29 devnull * __thunk_176__._Q210LogMessage9LogStream => thunk (offset -176) for LogMessage::LogStream
295 2eb30524 2005-11-29 devnull */
296 2eb30524 2005-11-29 devnull static char*
297 2eb30524 2005-11-29 devnull demanglegcc2c(char *s, char *buf)
298 2eb30524 2005-11-29 devnull {
299 2eb30524 2005-11-29 devnull int n;
300 2eb30524 2005-11-29 devnull char *p;
301 2eb30524 2005-11-29 devnull
302 2eb30524 2005-11-29 devnull if(memcmp(s, "__thunk_", 8) != 0)
303 2eb30524 2005-11-29 devnull return nil;
304 2eb30524 2005-11-29 devnull s += 8;
305 2eb30524 2005-11-29 devnull if(!gccnumber(&s, &n, 1))
306 2eb30524 2005-11-29 devnull return nil;
307 2eb30524 2005-11-29 devnull if(memcmp(s, "__._", 4) != 0) /* might as well be morse code */
308 2eb30524 2005-11-29 devnull return nil;
309 2eb30524 2005-11-29 devnull s += 4;
310 2eb30524 2005-11-29 devnull p = buf;
311 2eb30524 2005-11-29 devnull if(!gccname(&s, &p))
312 2eb30524 2005-11-29 devnull return nil;
313 2eb30524 2005-11-29 devnull strcpy(p, "::$thunk");
314 2eb30524 2005-11-29 devnull return buf;
315 2eb30524 2005-11-29 devnull }
316 2eb30524 2005-11-29 devnull
317 2eb30524 2005-11-29 devnull /*
318 2eb30524 2005-11-29 devnull * Parse a number, a non-empty run of digits.
319 2eb30524 2005-11-29 devnull * If many==0, then only one digit is used, even
320 2eb30524 2005-11-29 devnull * if it is followed by more. When we need a big
321 2eb30524 2005-11-29 devnull * number in a one-digit slot, it gets bracketed by underscores.
322 2eb30524 2005-11-29 devnull */
323 7d6f5677 2005-11-28 devnull static int
324 2eb30524 2005-11-29 devnull gccnumber(char **ps, int *pn, int many)
325 7d6f5677 2005-11-28 devnull {
326 7d6f5677 2005-11-28 devnull char *s;
327 2eb30524 2005-11-29 devnull int n, eatunderscore;
328 fa325e9b 2020-01-10 cross
329 7d6f5677 2005-11-28 devnull s = *ps;
330 2eb30524 2005-11-29 devnull eatunderscore = 0;
331 2eb30524 2005-11-29 devnull if(!many && *s == '_'){
332 2eb30524 2005-11-29 devnull many = 1;
333 7d6f5677 2005-11-28 devnull s++;
334 2eb30524 2005-11-29 devnull eatunderscore = 1;
335 2eb30524 2005-11-29 devnull }
336 2eb30524 2005-11-29 devnull if(!isdigit((uchar)*s)){
337 2eb30524 2005-11-29 devnull bad:
338 2eb30524 2005-11-29 devnull werrstr("bad number %.20s", *ps);
339 2eb30524 2005-11-29 devnull return 0;
340 2eb30524 2005-11-29 devnull }
341 2eb30524 2005-11-29 devnull if(many)
342 2eb30524 2005-11-29 devnull n = strtol(s, &s, 10);
343 2eb30524 2005-11-29 devnull else
344 2eb30524 2005-11-29 devnull n = *s++ - '0';
345 2eb30524 2005-11-29 devnull if(eatunderscore){
346 2eb30524 2005-11-29 devnull if(*s != '_')
347 2eb30524 2005-11-29 devnull goto bad;
348 2eb30524 2005-11-29 devnull s++;
349 2eb30524 2005-11-29 devnull }
350 7d6f5677 2005-11-28 devnull *ps = s;
351 7d6f5677 2005-11-28 devnull *pn = n;
352 7d6f5677 2005-11-28 devnull return 1;
353 7d6f5677 2005-11-28 devnull }
354 7d6f5677 2005-11-28 devnull
355 7d6f5677 2005-11-28 devnull /*
356 7d6f5677 2005-11-28 devnull * Pick apart the next mangled name section.
357 7d6f5677 2005-11-28 devnull * Names and types are treated as the same.
358 7d6f5677 2005-11-28 devnull * Let's see how far we can go before that becomes a problem.
359 7d6f5677 2005-11-28 devnull */
360 7d6f5677 2005-11-28 devnull static int
361 2eb30524 2005-11-29 devnull gccname(char **ps, char **pp)
362 7d6f5677 2005-11-28 devnull {
363 7d6f5677 2005-11-28 devnull int i, n, m, val;
364 2eb30524 2005-11-29 devnull char *os, *s, *t, *p, *p0, *p1;
365 fa325e9b 2020-01-10 cross
366 7d6f5677 2005-11-28 devnull s = *ps;
367 7d6f5677 2005-11-28 devnull os = s;
368 7d6f5677 2005-11-28 devnull p = *pp;
369 7d6f5677 2005-11-28 devnull
370 7d6f5677 2005-11-28 devnull /* print("\tgccname: %s\n", s); */
371 7d6f5677 2005-11-28 devnull
372 7d6f5677 2005-11-28 devnull /* basic types */
373 7d6f5677 2005-11-28 devnull if((t = chartabsearch(typetab, *s)) != nil){
374 7d6f5677 2005-11-28 devnull s++;
375 7d6f5677 2005-11-28 devnull strcpy(p, t);
376 7d6f5677 2005-11-28 devnull p += strlen(t);
377 2eb30524 2005-11-29 devnull goto out;
378 7d6f5677 2005-11-28 devnull }
379 fa325e9b 2020-01-10 cross
380 2eb30524 2005-11-29 devnull /* modifiers */
381 2eb30524 2005-11-29 devnull if((t = chartabsearch(modifiertab, *s)) != nil){
382 2eb30524 2005-11-29 devnull s++;
383 2eb30524 2005-11-29 devnull if(!gccname(&s, &p))
384 2eb30524 2005-11-29 devnull return 0;
385 2eb30524 2005-11-29 devnull /*
386 2eb30524 2005-11-29 devnull * These don't end up in the right place
387 2eb30524 2005-11-29 devnull * and i don't care anyway
388 2eb30524 2005-11-29 devnull * (AssertHeld__C17ReaderWriterMutex)
389 2eb30524 2005-11-29 devnull */
390 2eb30524 2005-11-29 devnull /*
391 2eb30524 2005-11-29 devnull *p++ = ' ';
392 2eb30524 2005-11-29 devnull strcpy(p, t);
393 2eb30524 2005-11-29 devnull p += strlen(p);
394 2eb30524 2005-11-29 devnull */
395 2eb30524 2005-11-29 devnull goto out;
396 2eb30524 2005-11-29 devnull }
397 fa325e9b 2020-01-10 cross
398 7d6f5677 2005-11-28 devnull switch(*s){
399 7d6f5677 2005-11-28 devnull default:
400 7d6f5677 2005-11-28 devnull bad:
401 2eb30524 2005-11-29 devnull if(debug)
402 2eb30524 2005-11-29 devnull fprint(2, "gccname: %s (%s)\n", os, s);
403 2eb30524 2005-11-29 devnull werrstr("bad name %.20s", s);
404 7d6f5677 2005-11-28 devnull return 0;
405 7d6f5677 2005-11-28 devnull
406 2eb30524 2005-11-29 devnull case '1': case '2': case '3': case '4': /* length-prefixed string */
407 7d6f5677 2005-11-28 devnull case '5': case '6': case '7': case '8': case '9':
408 2eb30524 2005-11-29 devnull if(!gccnumber(&s, &n, 1))
409 2eb30524 2005-11-29 devnull return 0;
410 7d6f5677 2005-11-28 devnull memmove(p, s, n);
411 7d6f5677 2005-11-28 devnull p += n;
412 7d6f5677 2005-11-28 devnull s += n;
413 7d6f5677 2005-11-28 devnull break;
414 7d6f5677 2005-11-28 devnull
415 2eb30524 2005-11-29 devnull case 'A': /* array */
416 2eb30524 2005-11-29 devnull t = s;
417 7d6f5677 2005-11-28 devnull s++;
418 2eb30524 2005-11-29 devnull if(!gccnumber(&s, &n, 1))
419 7d6f5677 2005-11-28 devnull return 0;
420 2eb30524 2005-11-29 devnull if(*s != '_'){
421 2eb30524 2005-11-29 devnull werrstr("bad array %.20s", t);
422 2eb30524 2005-11-29 devnull return 0;
423 2eb30524 2005-11-29 devnull }
424 2eb30524 2005-11-29 devnull s++;
425 2eb30524 2005-11-29 devnull sprint(p, "array[%d] ", n);
426 2eb30524 2005-11-29 devnull p += strlen(p);
427 7d6f5677 2005-11-28 devnull break;
428 7d6f5677 2005-11-28 devnull
429 2eb30524 2005-11-29 devnull case 'F': /* function */
430 2eb30524 2005-11-29 devnull t = s;
431 7d6f5677 2005-11-28 devnull s++;
432 2eb30524 2005-11-29 devnull strcpy(p, "fn(");
433 2eb30524 2005-11-29 devnull p += 3;
434 2eb30524 2005-11-29 devnull /* arguments */
435 2eb30524 2005-11-29 devnull while(*s && *s != '_')
436 2eb30524 2005-11-29 devnull if(!gccname(&s, &p))
437 2eb30524 2005-11-29 devnull return 0;
438 2eb30524 2005-11-29 devnull if(*s != '_'){
439 2eb30524 2005-11-29 devnull werrstr("unexpected end in function: %s", t);
440 7d6f5677 2005-11-28 devnull return 0;
441 2eb30524 2005-11-29 devnull }
442 2eb30524 2005-11-29 devnull s++;
443 2eb30524 2005-11-29 devnull strcpy(p, " => ");
444 2eb30524 2005-11-29 devnull p += 4;
445 2eb30524 2005-11-29 devnull /* return type */
446 2eb30524 2005-11-29 devnull if(!gccname(&s, &p))
447 2eb30524 2005-11-29 devnull return 0;
448 2eb30524 2005-11-29 devnull *p++ = ')';
449 7d6f5677 2005-11-28 devnull break;
450 7d6f5677 2005-11-28 devnull
451 2eb30524 2005-11-29 devnull case 'H': /* template specialization */
452 7dc9c4c6 2005-11-29 devnull if(memcmp(s-2, "__", 2) != 0)
453 7dc9c4c6 2005-11-29 devnull fprint(2, "wow: %s\n", s-2);
454 7d6f5677 2005-11-28 devnull t = s;
455 7d6f5677 2005-11-28 devnull s++;
456 2eb30524 2005-11-29 devnull if(!gccnumber(&s, &n, 0))
457 7d6f5677 2005-11-28 devnull return 0;
458 2eb30524 2005-11-29 devnull p0 = p;
459 2eb30524 2005-11-29 devnull /* template arguments */
460 2eb30524 2005-11-29 devnull *p++ = '<';
461 2eb30524 2005-11-29 devnull for(i=0; i<n; i++){
462 2eb30524 2005-11-29 devnull val = 1;
463 2eb30524 2005-11-29 devnull if(*s == 'Z'){ /* argument is a type, not value */
464 2eb30524 2005-11-29 devnull val = 0;
465 2eb30524 2005-11-29 devnull s++;
466 2eb30524 2005-11-29 devnull }
467 2eb30524 2005-11-29 devnull if(!gccname(&s, &p))
468 2eb30524 2005-11-29 devnull return 0;
469 2eb30524 2005-11-29 devnull if(val){
470 2eb30524 2005-11-29 devnull if(!gccnumber(&s, &m, 1)) /* gccnumber: 1 or 0? */
471 2eb30524 2005-11-29 devnull return 0;
472 2eb30524 2005-11-29 devnull sprint(p, "=%d", m);
473 2eb30524 2005-11-29 devnull p += strlen(p);
474 2eb30524 2005-11-29 devnull }
475 2eb30524 2005-11-29 devnull if(i+1<n)
476 2eb30524 2005-11-29 devnull *p++ = ',';
477 7d6f5677 2005-11-28 devnull }
478 2eb30524 2005-11-29 devnull *p++ = '>';
479 2eb30524 2005-11-29 devnull if(*s != '_'){
480 2eb30524 2005-11-29 devnull werrstr("bad template %s", t);
481 7d6f5677 2005-11-28 devnull return 0;
482 7d6f5677 2005-11-28 devnull }
483 7d6f5677 2005-11-28 devnull s++;
484 7dc9c4c6 2005-11-29 devnull
485 7dc9c4c6 2005-11-29 devnull /*
486 7dc9c4c6 2005-11-29 devnull * Can't seem to tell difference between a qualifying name
487 7dc9c4c6 2005-11-29 devnull * and arguments. Not sure which is which. It appears that if
488 7dc9c4c6 2005-11-29 devnull * you get a name, use it, otherwise look for types.
489 7dc9c4c6 2005-11-29 devnull * The G type qualifier appears to have no effect other than
490 7dc9c4c6 2005-11-29 devnull * turning an ambiguous name into a definite type.
491 7dc9c4c6 2005-11-29 devnull *
492 7dc9c4c6 2005-11-29 devnull * SetFlag__H1Zb_P15FlagSettingMode_v
493 7dc9c4c6 2005-11-29 devnull * => void SetFlag<bool>(FlagSettingMode *)
494 7dc9c4c6 2005-11-29 devnull * SetFlag__H1Zb_15FlagSettingMode_v
495 7dc9c4c6 2005-11-29 devnull * => void FlagSettingMode::SetFlag<bool>()
496 7dc9c4c6 2005-11-29 devnull * SetFlag__H1Zb_G15FlagSettingMode_v
497 7dc9c4c6 2005-11-29 devnull * => void SetFlag<bool>(FlagSettingMode)
498 7dc9c4c6 2005-11-29 devnull */
499 7dc9c4c6 2005-11-29 devnull if(strchr("ACFGPRSUVX", *s)){
500 7dc9c4c6 2005-11-29 devnull /* args */
501 7dc9c4c6 2005-11-29 devnull t = s;
502 7dc9c4c6 2005-11-29 devnull p1 = p;
503 7dc9c4c6 2005-11-29 devnull *p++ = '(';
504 7dc9c4c6 2005-11-29 devnull while(*s != '_'){
505 7dc9c4c6 2005-11-29 devnull if(*s == 0 || !gccname(&s, &p)){
506 7dc9c4c6 2005-11-29 devnull werrstr("bad H args: %s", t);
507 7dc9c4c6 2005-11-29 devnull return 0;
508 7dc9c4c6 2005-11-29 devnull }
509 7dc9c4c6 2005-11-29 devnull }
510 7dc9c4c6 2005-11-29 devnull *p++ = ')';
511 7dc9c4c6 2005-11-29 devnull s++;
512 7dc9c4c6 2005-11-29 devnull }else{
513 7dc9c4c6 2005-11-29 devnull p1 = p;
514 7dc9c4c6 2005-11-29 devnull /* name */
515 7dc9c4c6 2005-11-29 devnull if(!gccname(&s, &p))
516 7dc9c4c6 2005-11-29 devnull return 0;
517 7dc9c4c6 2005-11-29 devnull }
518 7dc9c4c6 2005-11-29 devnull /*
519 7dc9c4c6 2005-11-29 devnull * Need to do some rearrangement of <> () and names here.
520 7dc9c4c6 2005-11-29 devnull * Doesn't matter since we strip out the <> and () anyway.
521 7dc9c4c6 2005-11-29 devnull */
522 7d6f5677 2005-11-28 devnull break;
523 7d6f5677 2005-11-28 devnull
524 2eb30524 2005-11-29 devnull case 'M': /* M1S: pointer to member */
525 2eb30524 2005-11-29 devnull if(*(s+1) != '1' || *(s+2) != 'S')
526 7d6f5677 2005-11-28 devnull goto bad;
527 2eb30524 2005-11-29 devnull s += 3;
528 2eb30524 2005-11-29 devnull strcpy(p, "mptr ");
529 2eb30524 2005-11-29 devnull p += 5;
530 2eb30524 2005-11-29 devnull if(!gccname(&s, &p))
531 2eb30524 2005-11-29 devnull return 0;
532 2eb30524 2005-11-29 devnull break;
533 2eb30524 2005-11-29 devnull
534 2eb30524 2005-11-29 devnull case 'N': /* multiply-repeated type */
535 2eb30524 2005-11-29 devnull s++;
536 2eb30524 2005-11-29 devnull if(!gccnumber(&s, &n, 0) || !gccnumber(&s, &m, 0))
537 2eb30524 2005-11-29 devnull return 0;
538 2eb30524 2005-11-29 devnull sprint(p, "T%dx%d", m, n);
539 7d6f5677 2005-11-28 devnull p += strlen(p);
540 7d6f5677 2005-11-28 devnull break;
541 7d6f5677 2005-11-28 devnull
542 2eb30524 2005-11-29 devnull case 'P': /* pointer */
543 7d6f5677 2005-11-28 devnull s++;
544 2eb30524 2005-11-29 devnull strcpy(p, "ptr ");
545 2eb30524 2005-11-29 devnull p += 4;
546 2eb30524 2005-11-29 devnull if(!gccname(&s, &p))
547 2eb30524 2005-11-29 devnull return 0;
548 2eb30524 2005-11-29 devnull break;
549 fa325e9b 2020-01-10 cross
550 2eb30524 2005-11-29 devnull case 'Q': /* qualified name */
551 2eb30524 2005-11-29 devnull s++;
552 2eb30524 2005-11-29 devnull if(!gccnumber(&s, &n, 0))
553 2eb30524 2005-11-29 devnull return 0;
554 7d6f5677 2005-11-28 devnull for(i=0; i<n; i++){
555 2eb30524 2005-11-29 devnull if(!gccname(&s, &p)){
556 2eb30524 2005-11-29 devnull werrstr("in hierarchy: %r");
557 7d6f5677 2005-11-28 devnull return 0;
558 7d6f5677 2005-11-28 devnull }
559 7d6f5677 2005-11-28 devnull if(i+1 < n){
560 7d6f5677 2005-11-28 devnull strcpy(p, "::");
561 7d6f5677 2005-11-28 devnull p += 2;
562 7d6f5677 2005-11-28 devnull }
563 7d6f5677 2005-11-28 devnull }
564 7d6f5677 2005-11-28 devnull break;
565 7d6f5677 2005-11-28 devnull
566 2eb30524 2005-11-29 devnull case 'R': /* reference */
567 7d6f5677 2005-11-28 devnull s++;
568 2eb30524 2005-11-29 devnull strcpy(p, "ref ");
569 2eb30524 2005-11-29 devnull p += 4;
570 2eb30524 2005-11-29 devnull if(!gccname(&s, &p))
571 7d6f5677 2005-11-28 devnull return 0;
572 7d6f5677 2005-11-28 devnull break;
573 7d6f5677 2005-11-28 devnull
574 2eb30524 2005-11-29 devnull case 't': /* class template instantiation */
575 2eb30524 2005-11-29 devnull /* should share code with case 'H' */
576 2eb30524 2005-11-29 devnull t = s;
577 7d6f5677 2005-11-28 devnull s++;
578 2eb30524 2005-11-29 devnull if(!gccname(&s, &p))
579 7d6f5677 2005-11-28 devnull return 0;
580 2eb30524 2005-11-29 devnull if(!gccnumber(&s, &n, 0))
581 2eb30524 2005-11-29 devnull return 0;
582 2eb30524 2005-11-29 devnull p0 = p;
583 2eb30524 2005-11-29 devnull /* template arguments */
584 7d6f5677 2005-11-28 devnull *p++ = '<';
585 7d6f5677 2005-11-28 devnull for(i=0; i<n; i++){
586 7d6f5677 2005-11-28 devnull val = 1;
587 2eb30524 2005-11-29 devnull if(*s == 'Z'){ /* argument is a type, not value */
588 7d6f5677 2005-11-28 devnull val = 0;
589 7d6f5677 2005-11-28 devnull s++;
590 7d6f5677 2005-11-28 devnull }
591 2eb30524 2005-11-29 devnull if(!gccname(&s, &p))
592 2eb30524 2005-11-29 devnull return 0;
593 7d6f5677 2005-11-28 devnull if(val){
594 2eb30524 2005-11-29 devnull if(!gccnumber(&s, &m, 1)) /* gccnumber: 1 or 0? */
595 2eb30524 2005-11-29 devnull return 0;
596 7d6f5677 2005-11-28 devnull sprint(p, "=%d", m);
597 7d6f5677 2005-11-28 devnull p += strlen(p);
598 7d6f5677 2005-11-28 devnull }
599 2eb30524 2005-11-29 devnull if(i+1<n)
600 7d6f5677 2005-11-28 devnull *p++ = ',';
601 7d6f5677 2005-11-28 devnull }
602 7d6f5677 2005-11-28 devnull *p++ = '>';
603 7d6f5677 2005-11-28 devnull break;
604 fa325e9b 2020-01-10 cross
605 2eb30524 2005-11-29 devnull case 'T': /* once-repeated type */
606 2eb30524 2005-11-29 devnull s++;
607 2eb30524 2005-11-29 devnull if(!gccnumber(&s, &n, 0))
608 2eb30524 2005-11-29 devnull return 0;
609 2eb30524 2005-11-29 devnull sprint(p, "T%d", n);
610 2eb30524 2005-11-29 devnull p += strlen(p);
611 2eb30524 2005-11-29 devnull break;
612 fa325e9b 2020-01-10 cross
613 2eb30524 2005-11-29 devnull case 'X': /* type parameter in 'H' */
614 2eb30524 2005-11-29 devnull if(!isdigit((uchar)*(s+1)) || !isdigit((uchar)*(s+2)))
615 2eb30524 2005-11-29 devnull goto bad;
616 2eb30524 2005-11-29 devnull memmove(p, s, 3);
617 2eb30524 2005-11-29 devnull p += 3;
618 2eb30524 2005-11-29 devnull s += 3;
619 2eb30524 2005-11-29 devnull break;
620 7d6f5677 2005-11-28 devnull }
621 7d6f5677 2005-11-28 devnull
622 443d6288 2012-02-19 rsc USED(p1);
623 443d6288 2012-02-19 rsc USED(p0);
624 443d6288 2012-02-19 rsc
625 fa325e9b 2020-01-10 cross out:
626 7d6f5677 2005-11-28 devnull *ps = s;
627 7d6f5677 2005-11-28 devnull *pp = p;
628 7d6f5677 2005-11-28 devnull return 1;
629 7d6f5677 2005-11-28 devnull }