10 static jmp_buf kaboom;
12 static Type *parsename(char*, char**);
13 static Type *parseinfo(char*, char**);
14 static int parsenum(char*, int*, int*, char**);
15 static int parseattr(char*, char**, char**);
16 static Type *parsedefn(char *p, Type *t, char **pp);
17 static int parsebound(char**);
18 static vlong parsebigint(char**);
20 typedef struct Ftypes Ftypes;
33 estrndup(char *s, int n)
43 mkpath(char *dir, char *name)
49 s = emalloc(strlen(dir)+strlen(name)+1);
57 mkftypes(char *dir, char *name)
61 f = emalloc(sizeof(*f));
62 f->file = mkpath(dir, name);
69 findftypes(char *dir, char *name)
75 s = mkpath(dir, name);
76 for(f=allftypes; f; f=f->next)
77 if(strcmp(f->file, s) == 0)
88 /* find a : but skip over :: */
92 while((p = strchr(p, ':')) != nil && *(p+1) == ':')
120 return strtol(*pp, pp, 10);
124 name ::= symbol_opt info
127 parsename(char *desc, char **pp)
132 if(isdigit(*desc) || *desc=='-' || *desc=='(')
133 return parseinfo(desc, pp);
136 return parseinfo(desc+1, pp);
140 info ::= num | num '=' attr* defn
143 parseinfo(char *desc, char **pp)
149 parsenum(desc, &n1, &n2, &desc);
150 t = typebynum(n1, n2);
157 fstack->list = mktl(t, fstack->list);
158 while(parseattr(desc, &attr, &desc) >= 0){
160 t->xsizeof = atoi(attr+1)/8;
162 return parsedefn(desc, t, pp);
166 num ::= integer | '(' integer ',' integer ')'
169 parsenum(char *p, int *n1, int *n2, char **pp)
172 *n1 = strtol(p, &p, 10);
178 *n1 = strtol(p+1, &p, 10);
181 *n2 = strtol(p+1, &p, 10);
192 attr ::= '@' text ';'
195 'a' integer (alignment)
196 'p' integer (pointer class)
198 's' integer (size of type in bits)
199 'S' (string instead of array of chars)
202 parseattr(char *p, char **text, char **pp)
207 if((p = strchr(p, ';')) == nil)
214 typedef struct Basic Basic;
221 static Basic baseints[] =
224 /*1*/ 4, 'd', /* int32 */
225 /*2*/ 1, 'd', /* char8 */
226 /*3*/ 2, 'd', /* int16 */
227 /*4*/ 4, 'd', /* long int32 */
228 /*5*/ 1, 'x', /* uchar8 */
229 /*6*/ 1, 'd', /* schar8 */
230 /*7*/ 2, 'x', /* uint16 */
231 /*8*/ 4, 'x', /* uint32 */
232 /*9*/ 4, 'x', /* uint32 */
233 /*10*/ 4, 'x', /* ulong32 */
234 /*11*/ 0, 0, /* void */
235 /*12*/ 4, 'f', /* float */
236 /*13*/ 8, 'f', /* double */
237 /*14*/ 10, 'f', /* long double */
238 /*15*/ 4, 'd', /* int32 */
239 /*16*/ 4, 'd', /* bool32 */
240 /*17*/ 2, 'f', /* short real */
241 /*18*/ 4, 'f', /* real */
242 /*19*/ 4, 'x', /* stringptr */
243 /*20*/ 1, 'd', /* character8 */
244 /*21*/ 1, 'x', /* logical*1 */
245 /*22*/ 2, 'x', /* logical*2 */
246 /*23*/ 4, 'X', /* logical*4 */
247 /*24*/ 4, 'X', /* logical32 */
248 /*25*/ 8, 'F', /* complex (two single) */
249 /*26*/ 16, 'F', /* complex (two double) */
250 /*27*/ 1, 'd', /* integer*1 */
251 /*28*/ 2, 'd', /* integer*2 */
252 /*29*/ 4, 'd', /* integer*4 */
253 /*30*/ 2, 'x', /* wide char */
254 /*31*/ 8, 'd', /* int64 */
255 /*32*/ 8, 'x', /* uint64 */
256 /*33*/ 8, 'x', /* logical*8 */
257 /*34*/ 8, 'd', /* integer*8 */
260 static Basic basefloats[] =
263 /*1*/ 4, 'f', /* 32-bit */
264 /*2*/ 8, 'f', /* 64-bit */
265 /*3*/ 8, 'F', /* complex */
266 /*4*/ 4, 'F', /* complex16 */
267 /*5*/ 8, 'F', /* complex32 */
268 /*6*/ 10, 'f', /* long double */
273 | 'b' ('u' | 's') 'c'? width; offset; nbits; (builtin, signed/unsigned, char/not, width in bytes, offset & nbits of type)
274 | 'w' (aix wide char type, not used)
275 | 'R' fptype; bytes; (fptype 1=32-bit, 2=64-bit, 3=complex, 4=complex16, 5=complex32, 6=long double)
276 | 'g' typeinfo ';' nbits (aix floating, not used)
277 | 'c' typeinfo ';' nbits (aix complex, not used)
278 | 'b' typeinfo ';' bytes (ibm, no idea)
279 | 'B' typeinfo (volatile typref)
280 | 'd' typeinfo (file of typeref)
281 | 'k' typeinfo (const typeref)
282 | 'M' typeinfo ';' length (multiple instance type, fortran)
283 | 'S' typeinfo (set, typeref must have small number of values)
284 | '*' typeinfo (pointer to typeref)
285 | 'x' ('s'|'u'|'e') name ':' (struct, union, enum reference. name can have '::' in it)
286 | 'r' typeinfo ';' low ';' high ';' (subrange. typeref can be type being defined for base types!)
287 low and high are bounds
288 if bound is octal power of two, it's a big negative number
289 | ('a'|'P') indextypedef arraytypeinfo (array, index should be range type)
290 indextype is type definition not typeinfo (need not say typenum=)
292 | 'A' arraytypeinfo (open array (no index bounds))
293 | 'D' dims ';' typeinfo (dims-dimensional dynamic array)
294 | 'E' dims ';' typeinfo (subarray of N-dimensional array)
295 | 'n' typeinfo ';' bytes (max length string)
296 | 'z' typeinfo ';' bytes (no idea what difference is from 'n')
297 | 'N' (pascal stringptr)
298 | 'e' (name ':' bigint ',')* ';' (enum listing)
299 | ('s'|'u') bytes (name ':' type ',' bitoffset ',' bitsize ';')* ';' (struct/union defn)
300 tag is given as name in stabs entry, with 'T' symbol
301 | 'f' typeinfo ';' (function returning type)
302 | 'f' rettypeinfo ',' paramcount ';' (typeinfo ',' (0|1) ';')* ';'
303 | 'p' paramcount ';' (typeinfo ',' (0|1) ';')* ';'
304 | 'F' rettypeinfo ',' paramcount ';' (name ':' typeinfo ',' (0|1) ';')* ';'
305 | 'R' paramcount ';' (name ':' typeinfo ',' (0|1) ';')* ';'
306 (the 0 or 1 is pass-by-reference vs pass-by-value)
307 (the 0 or 1 is pass-by-reference vs pass-by-value)
311 parsedefn(char *p, Type *t, char **pp)
314 int ischar, namelen, n, wid, offset, bits, sign;
318 if(*p == '(' || isdigit(*p)){
320 t->sub = parseinfo(p, pp);
325 case '-': /* builtin */
326 n = strtol(p+1, &p, 10);
327 if(n >= nelem(baseints) || n < 0)
330 t->xsizeof = baseints[n].size;
331 t->printfmt = baseints[n].fmt;
333 case 'b': /* builtin */
335 if(*p != 'u' && *p != 's')
345 offset = parseint(&p);
356 case 'R': /* fp type */
363 if(n < 0 || n >= nelem(basefloats))
365 t->xsizeof = basefloats[n].size;
366 t->printfmt = basefloats[n].fmt;
368 case 'r': /* subrange */
370 t->sub = parseinfo(p+1, &p);
371 if(*(p-1) == ';' && *p != ';')
374 t->lo = parsebound(&p);
376 t->hi = parsebound(&p);
379 case 'B': /* volatile */
380 case 'k': /* const */
382 t->sub = parseinfo(p+1, &p);
384 case '*': /* pointer */
385 case 'A': /* open array */
387 t->sub = parseinfo(p+1, &p);
389 case 'a': /* array */
390 case 'P': /* packed array */
393 parsedefn(p+1, tt, &p); /* index type */
398 parsedefn(p, tt, &p); /* element type */
400 case 'e': /* enum listing */
407 namelen = (p-name)-1;
408 val = parsebigint(&p);
411 t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0]));
412 t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0]));
414 t->tname[t->n] = estrndup(name, namelen);
421 case 's': /* struct */
422 case 'u': /* union */
430 namelen = (p-name)-1;
431 tt = parseinfo(p, &p);
433 offset = parseint(&p);
438 t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0]));
439 t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0]));
440 t->t = erealloc(t->t, (t->n+32)*sizeof(t->t[0]));
442 t->tname[t->n] = estrndup(name, namelen);
443 t->val[t->n] = offset;
450 case 'x': /* struct, union, enum reference */
453 if(*p != 's' && *p != 'u' && *p != 'e')
458 name = estrndup(name, p-name);
459 t->sub = typebysue(c, name);
464 case 'f': /* function */
465 case 'p': /* procedure */
466 case 'F': /* Pascal function */
467 /* case 'R': /* Pascal procedure */
469 * Even though we don't use the info, we have
470 * to parse it in case it is embedded in other descriptions.
474 if(c == 'f' || c == 'F'){
475 t->sub = parseinfo(p, &p);
483 n = parseint(&p); /* number of params */
486 if(c == 'F' || c == 'R'){
487 name = p; /* parameter name */
490 parseinfo(p, &p); /* param type */
492 parseint(&p); /* bool: passed by value? */
499 case 'f': /* static function */
500 case 'F': /* global function */
503 t->sub = parseinfo(p, &p);
507 * We'll never see any of this stuff.
508 * When we do, we can worry about it.
510 case 'D': /* n-dimensional array */
511 case 'E': /* subarray of n-dimensional array */
512 case 'M': /* fortran multiple instance type */
513 case 'N': /* pascal string ptr */
515 case 'c': /* aix complex */
516 case 'd': /* file of */
517 case 'g': /* aix float */
518 case 'n': /* max length string */
519 case 'w': /* aix wide char */
520 case 'z': /* another max length string */
522 fprint(2, "unsupported type char %c (%d)\n", *p, *p);
531 'A' offset (bound is on stack by ref at offset offset from arg list)
532 | 'T' offset (bound is on stack by val at offset offset from arg list)
533 | 'a' regnum (bound passed by reference in register)
534 | 't' regnum (bound passed by value in register)
539 parsebound(char **pp)
547 case 'A': /* bound is on stack by reference at offset n from arg list */
548 case 'T': /* bound is on stack by value at offset n from arg list */
549 case 'a': /* bound is passed by reference in register n */
550 case 't': /* bound is passed by value in register n */
554 case 'J': /* no bound */
566 bigint ::= '-'? decimal
571 parsebigint(char **pp)
579 n = strtoll(p, &p, 8);
591 n = strtol(p, &p, 10);
601 stabs2acid(Stab *stabs, Biobuf *b)
604 char c, *dir, *fn, *file, *name, *desc, *p;
613 for(i=0; stabsym(stabs, i, &sym)>=0; i++){
617 if(sym.name[0] && sym.name[strlen(sym.name)-1] == '/')
628 f = mkftypes(dir, sym.name);
634 fstack = fstack->down;
638 if((f = findftypes(dir, sym.name)) == nil){
639 fprint(2, "cannot find remembered %s\n", sym.name);
642 renumber(f->list, fno);
657 if((p = strchr(name, ':')) == nil)
659 name = estrndup(name, p-name);
663 fprint(2, "skip constant %s\n", name);
667 fprint(2, "cannot parse %s\n", name);
670 t = parsename(desc, &p);
674 fprint(2, "extra desc '%s' in '%s'\n", p, desc);
675 /* void is defined as itself */
676 if(t->ty==Defer && t->sub==t && strcmp(name, "void")==0){
681 if(*name==' ' && *(name+1) == 0)
683 /* attach names to structs, unions, enums */
684 if(c=='T' && *name && t->sue){
688 tt = typebysue(t->sue, name);
698 /* define base c types */
699 if(t->ty==None || t->ty==Range){
700 if(strcmp(name, "char") == 0){
705 if(strcmp(name, "int") == 0){
711 /* record declaration in list for later. */
712 if(c != 't' && c != 'T')
715 addsymx(nil, name, t);
725 addsymx(fn, name, t);