1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 1996-2002 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <limits.h>
30 #include <stdarg.h>
31 #include <stdio.h>
32
33 #include "stabs.h"
34
35 static struct tdesc *hash_table[BUCKETS];
36 static struct tdesc *name_table[BUCKETS];
37
38 static void reset(void);
39 static jmp_buf resetbuf;
40
41 static char *get_line(void);
42 static void parseline(char *cp);
43 static char *soudef(char *cp, enum type type, struct tdesc **rtdp);
44 static void enumdef(char *cp, struct tdesc **rtdp);
45 static int compute_sum(char *w);
46 static struct tdesc *lookup(int h);
47
48 static char *number(char *cp, int *n);
49 static char *name(char *cp, char **w);
50 static char *id(char *cp, int *h);
51 static char *offsize(char *cp, struct mlist *mlp);
52 static char *whitesp(char *cp);
53 static void addhash(struct tdesc *tdp, int num);
54 static void tagadd(char *w, int h, struct tdesc *tdp);
55 static void tagdecl(char *cp, struct tdesc **rtdp, int h, char *w);
56 static char *tdefdecl(char *cp, int h, struct tdesc **rtdp);
57 static char *intrinsic(char *cp, struct tdesc **rtdp);
58 static char *arraydef(char *cp, struct tdesc **rtdp);
59
60 static int line_number = 0;
61 static int debug_line = 0;
62 static char linebuf[MAXLINE];
63
64 extern int debug_level;
65
66 static void
debug(int level,char * cp,char * fmt,...)67 debug(int level, char *cp, char *fmt, ...)
68 {
69 va_list ap;
70 char buf[1024];
71 char tmp[32];
72 int i;
73
74 if (level > debug_level)
75 return;
76
77 if (cp != NULL) {
78 for (i = 0; i < 30; i++) {
79 if (cp[i] == '\0')
80 break;
81 if (!iscntrl(cp[i]))
82 tmp[i] = cp[i];
83 }
84 tmp[i] = '\0';
85 (void) sprintf(buf, "%s [cp='%s']\n", fmt, tmp);
86 } else {
87 strcpy(buf, fmt);
88 strcat(buf, "\n");
89 }
90
91 va_start(ap, fmt);
92 (void) vfprintf(stderr, buf, ap);
93 va_end(ap);
94 }
95
96
97 /* Report unexpected syntax in stabs. */
98 static void
expected(char * who,char * what,char * where)99 expected(
100 char *who, /* what function, or part thereof, is reporting */
101 char *what, /* what was expected */
102 char *where) /* where we were in the line of input */
103 {
104 fprintf(stderr, "%s, input line %d: expecting \"%s\" at \"%s\"\n",
105 who, line_number, what, where);
106 exit(1);
107 }
108
109 /* Read a line from stdin into linebuf and increment line_number. */
110 static char *
get_line(void)111 get_line(void)
112 {
113 char *cp = fgets(linebuf, MAXLINE, stdin);
114 line_number++;
115
116 /* For debugging, you can set debug_line to a line to stop on. */
117 if (line_number == debug_line) {
118 fprintf(stderr, "Hit debug line number %d\n", line_number);
119 for (;;)
120 sleep(1);
121 }
122 return (cp);
123 }
124
125 /* Get the continuation of the current input line. */
126 static char *
get_continuation(void)127 get_continuation(void)
128 {
129 char *cp = get_line();
130 if (!cp) {
131 fprintf(stderr, "expecting continuation line, "
132 "got end of input\n");
133 exit(1);
134 }
135
136 /* Skip to the quoted stuff. */
137 while (*cp++ != '"')
138 ;
139 return (cp);
140 }
141
142 void
parse_input(void)143 parse_input(void)
144 {
145 char *cp;
146 int i = 0;
147
148 for (i = 0; i < BUCKETS; i++) {
149 hash_table[i] = NULL;
150 name_table[i] = NULL;
151 }
152
153 /*
154 * get a line at a time from the .s stabs file and parse.
155 */
156 while ((cp = get_line()) != NULL)
157 parseline(cp);
158 }
159
160 /*
161 * Parse each line of the .s file (stabs entry) gather meaningful information
162 * like name of type, size, offsets of fields etc.
163 */
164 static void
parseline(char * cp)165 parseline(char *cp)
166 {
167 struct tdesc *tdp;
168 char c, *w;
169 int h, tagdef;
170
171 /*
172 * setup for reset()
173 */
174 if (setjmp(resetbuf))
175 return;
176
177 /*
178 * Look for lines of the form
179 * .stabs "str",n,n,n,n
180 * The part in '"' is then parsed.
181 */
182 cp = whitesp(cp);
183 #define STLEN 6
184 debug(2, cp, "parseline");
185 if (strncmp(cp, ".stabs", STLEN) != 0)
186 reset();
187 cp += STLEN;
188 #undef STLEN
189 cp = whitesp(cp);
190 if (*cp++ != '"')
191 reset();
192
193 /*
194 * name:type variable (ignored)
195 * name:ttype typedef
196 * name:Ttype struct tag define
197 */
198 cp = whitesp(cp);
199 cp = name(cp, &w);
200
201 tagdef = 0;
202 switch (c = *cp++) {
203 case 't': /* type */
204 break;
205 case 'T': /* struct, union, enum */
206 tagdef = 1;
207 break;
208 default:
209 reset();
210 }
211
212 /*
213 * The type id and definition follow.
214 */
215 cp = id(cp, &h);
216 if (*cp == '"') {
217 struct tdesc *ntdp;
218
219 cp++;
220 ntdp = lookup(h);
221 if (ntdp == NULL) { /* if that type isn't defined yet */
222 if (*cp++ != '=') /* better be defining it now */
223 expected("parseline/'0-9'", "=", cp - 1);
224 cp = tdefdecl(cp, h, &tdp);
225 addhash(tdp, h); /* for *(x,y) types */
226 } else { /* that type is already defined */
227 tdp = malloc(sizeof (*tdp));
228 tdp->type = TYPEOF;
229 tdp->name = (w != NULL) ? strdup(w) : NULL;
230 tdp->data.tdesc = ntdp;
231 addhash(tdp, h); /* for *(x,y) types */
232 debug(3, NULL, " %s defined as %s(%d)", w,
233 (ntdp->name != NULL) ? ntdp->name : "anon", h);
234 }
235 return;
236 } else if (*cp++ != '=') {
237 expected("parseline", "=", cp - 1);
238 }
239 if (tagdef) {
240 tagdecl(cp, &tdp, h, w);
241 } else {
242 tdefdecl(cp, h, &tdp);
243 tagadd(w, h, tdp);
244 }
245 }
246
247 /*
248 * Check if we have this node in the hash table already
249 */
250 static struct tdesc *
lookup(int h)251 lookup(int h)
252 {
253 int hash = HASH(h);
254 struct tdesc *tdp = hash_table[hash];
255
256 while (tdp != NULL) {
257 if (tdp->id == h)
258 return (tdp);
259 tdp = tdp->hash;
260 }
261 return (NULL);
262 }
263
264 static char *
whitesp(char * cp)265 whitesp(char *cp)
266 {
267 char *orig, c;
268
269 orig = cp;
270 for (c = *cp++; isspace(c); c = *cp++)
271 ;
272 --cp;
273 return (cp);
274 }
275
276 static char *
name(char * cp,char ** w)277 name(char *cp, char **w)
278 {
279 char *new, *orig, c;
280 int len;
281
282 orig = cp;
283 c = *cp++;
284 if (c == ':')
285 *w = NULL;
286 else if (isalpha(c) || c == '_') {
287 for (c = *cp++; isalnum(c) || c == ' ' || c == '_'; c = *cp++)
288 ;
289 if (c != ':')
290 reset();
291 len = cp - orig;
292 new = malloc(len);
293 while (orig < cp - 1)
294 *new++ = *orig++;
295 *new = '\0';
296 *w = new - (len - 1);
297 } else
298 reset();
299
300 return (cp);
301 }
302
303 static char *
number(char * cp,int * n)304 number(char *cp, int *n)
305 {
306 char *next;
307
308 *n = (int)strtol(cp, &next, 10);
309 if (next == cp)
310 expected("number", "<number>", cp);
311 return (next);
312 }
313
314 static char *
id(char * cp,int * h)315 id(char *cp, int *h)
316 {
317 int n1, n2;
318
319 if (*cp == '(') { /* SunPro style */
320 cp++;
321 cp = number(cp, &n1);
322 if (*cp++ != ',')
323 expected("id", ",", cp - 1);
324 cp = number(cp, &n2);
325 if (*cp++ != ')')
326 expected("id", ")", cp - 1);
327 *h = n1 * 1000 + n2;
328 } else if (isdigit(*cp)) { /* gcc style */
329 cp = number(cp, &n1);
330 *h = n1;
331 } else {
332 expected("id", "(/0-9", cp);
333 }
334 return (cp);
335 }
336
337 static void
tagadd(char * w,int h,struct tdesc * tdp)338 tagadd(char *w, int h, struct tdesc *tdp)
339 {
340 struct tdesc *otdp;
341
342 tdp->name = w;
343 if (!(otdp = lookup(h)))
344 addhash(tdp, h);
345 else if (otdp != tdp) {
346 fprintf(stderr, "duplicate entry\n");
347 fprintf(stderr, "old: %s %d %d %d\n",
348 otdp->name ? otdp->name : "NULL",
349 otdp->type, otdp->id / 1000, otdp->id % 1000);
350 fprintf(stderr, "new: %s %d %d %d\n",
351 tdp->name ? tdp->name : "NULL",
352 tdp->type, tdp->id / 1000, tdp->id % 1000);
353 }
354 }
355
356 static void
tagdecl(char * cp,struct tdesc ** rtdp,int h,char * w)357 tagdecl(char *cp, struct tdesc **rtdp, int h, char *w)
358 {
359 debug(1, NULL, "tagdecl: declaring '%s'", w ? w : "(anon)");
360 if ((*rtdp = lookup(h)) != NULL) {
361 if (w != NULL) {
362 if ((*rtdp)->name != NULL &&
363 strcmp((*rtdp)->name, w) != 0) {
364 struct tdesc *tdp;
365
366 tdp = malloc(sizeof (*tdp));
367 tdp->name = strdup(w);
368 tdp->type = TYPEOF;
369 tdp->data.tdesc = *rtdp;
370 addhash(tdp, h); /* for *(x,y) types */
371 debug(3, NULL, " %s defined as %s(%d)", w,
372 ((*rtdp)->name != NULL) ?
373 (*rtdp)->name : "anon", h);
374 } else if ((*rtdp)->name == NULL) {
375 (*rtdp)->name = w;
376 addhash(*rtdp, h);
377 }
378 }
379 } else {
380 *rtdp = malloc(sizeof (**rtdp));
381 (*rtdp)->name = w;
382 addhash(*rtdp, h);
383 }
384
385 switch (*cp++) {
386 case 's':
387 soudef(cp, STRUCT, rtdp);
388 break;
389 case 'u':
390 soudef(cp, UNION, rtdp);
391 break;
392 case 'e':
393 enumdef(cp, rtdp);
394 break;
395 default:
396 expected("tagdecl", "<tag type s/u/e>", cp - 1);
397 break;
398 }
399 }
400
401 static char *
tdefdecl(char * cp,int h,struct tdesc ** rtdp)402 tdefdecl(char *cp, int h, struct tdesc **rtdp)
403 {
404 struct tdesc *ntdp;
405 char *w;
406 int c, h2;
407 char type;
408
409 debug(3, cp, "tdefdecl h=%d", h);
410
411 /* Type codes */
412 switch (type = *cp) {
413 case 'b': /* integer */
414 c = *++cp;
415 if (c != 's' && c != 'u')
416 expected("tdefdecl/b", "[su]", cp - 1);
417 c = *++cp;
418 if (c == 'c')
419 cp++;
420 cp = intrinsic(cp, rtdp);
421 break;
422 case 'R': /* fp */
423 /* skip up to and past ';' */
424 while (*cp++ != ';')
425 /* NULL */;
426 cp = intrinsic(cp, rtdp);
427 break;
428 case '(': /* equiv to another type */
429 cp = id(cp, &h2);
430 ntdp = lookup(h2);
431 if (ntdp == NULL) { /* if that type isn't defined yet */
432 if (*cp++ != '=') /* better be defining it now */
433 expected("tdefdecl/'('", "=", cp - 1);
434 cp = tdefdecl(cp, h2, rtdp);
435 ntdp = malloc(sizeof (*ntdp));
436 ntdp->type = TYPEOF;
437 ntdp->data.tdesc = *rtdp;
438 addhash(ntdp, h2);
439 } else { /* that type is already defined */
440 *rtdp = malloc(sizeof (**rtdp));
441 (*rtdp)->type = TYPEOF;
442 (*rtdp)->data.tdesc = ntdp;
443 }
444 break;
445 case '*':
446 ntdp = NULL;
447 cp = tdefdecl(cp + 1, h, &ntdp);
448 if (ntdp == NULL)
449 expected("tdefdecl/*", "id", cp);
450
451 *rtdp = malloc(sizeof (**rtdp));
452 (*rtdp)->type = POINTER;
453 (*rtdp)->size = model->pointersize;
454 (*rtdp)->name = "pointer";
455 (*rtdp)->data.tdesc = ntdp;
456 break;
457 case 'f':
458 cp = tdefdecl(cp + 1, h, &ntdp);
459 *rtdp = malloc(sizeof (**rtdp));
460 (*rtdp)->type = FUNCTION;
461 (*rtdp)->size = model->pointersize;
462 (*rtdp)->name = "function";
463 (*rtdp)->data.tdesc = ntdp;
464 break;
465 case 'a':
466 cp++;
467 if (*cp++ != 'r')
468 expected("tdefdecl/a", "r", cp - 1);
469 *rtdp = malloc(sizeof (**rtdp));
470 (*rtdp)->type = ARRAY;
471 (*rtdp)->name = "array";
472 cp = arraydef(cp, rtdp);
473 break;
474 case 'x':
475 c = *++cp;
476 if (c != 's' && c != 'u' && c != 'e')
477 expected("tdefdecl/x", "[sue]", cp - 1);
478 cp = name(cp + 1, &w);
479 *rtdp = malloc(sizeof (**rtdp));
480 (*rtdp)->type = FORWARD;
481 (*rtdp)->name = w;
482 break;
483 case 'B': /* volatile */
484 cp = tdefdecl(cp + 1, h, &ntdp);
485 *rtdp = malloc(sizeof (**rtdp));
486 (*rtdp)->type = VOLATILE;
487 (*rtdp)->size = 0;
488 (*rtdp)->name = "volatile";
489 (*rtdp)->data.tdesc = ntdp;
490 break;
491 case 'k': /* const */
492 cp = tdefdecl(cp + 1, h, &ntdp);
493 *rtdp = malloc(sizeof (**rtdp));
494 (*rtdp)->type = CONST;
495 (*rtdp)->size = 0;
496 (*rtdp)->name = "const";
497 (*rtdp)->data.tdesc = ntdp;
498 break;
499 case '0': case '1': case '2': case '3': case '4':
500 case '5': case '6': case '7': case '8': case '9':
501 /* gcc equiv to another type */
502 cp = id(cp, &h2);
503 ntdp = lookup(h2);
504 if (ntdp == NULL) { /* if that type isn't defined yet */
505 /* better be defining it now */
506 if (*cp++ != '=') {
507 if (h != h2)
508 expected("tdefdecl/'0-9'", "=", cp - 1);
509 /* defined in terms of itself */
510 *rtdp = malloc(sizeof (**rtdp));
511 (*rtdp)->type = INTRINSIC;
512 (*rtdp)->name = "void";
513 (*rtdp)->size = 0;
514 } else {
515 cp = tdefdecl(cp, h2, rtdp);
516 ntdp = malloc(sizeof (*ntdp));
517 ntdp->type = TYPEOF;
518 ntdp->data.tdesc = *rtdp;
519 addhash(ntdp, h2);
520 }
521 } else { /* that type is already defined */
522 *rtdp = malloc(sizeof (**rtdp));
523 (*rtdp)->type = TYPEOF;
524 (*rtdp)->data.tdesc = ntdp;
525 }
526 break;
527 case 'u':
528 case 's':
529 cp++;
530
531 *rtdp = malloc(sizeof (**rtdp));
532 (*rtdp)->name = NULL;
533 cp = soudef(cp, (type == 'u') ? UNION : STRUCT, rtdp);
534 break;
535 default:
536 expected("tdefdecl", "<type code>", cp);
537 }
538 return (cp);
539 }
540
541 static char *
intrinsic(char * cp,struct tdesc ** rtdp)542 intrinsic(char *cp, struct tdesc **rtdp)
543 {
544 struct tdesc *tdp;
545 int size;
546
547 cp = number(cp, &size);
548 tdp = malloc(sizeof (*tdp));
549 tdp->type = INTRINSIC;
550 tdp->size = size;
551 tdp->name = NULL;
552 debug(3, NULL, "intrinsic: size=%ld", size);
553 *rtdp = tdp;
554 return (cp);
555 }
556
557 static char *
soudef(char * cp,enum type type,struct tdesc ** rtdp)558 soudef(char *cp, enum type type, struct tdesc **rtdp)
559 {
560 struct mlist **next_pp, *prev_p = NULL;
561 char *w;
562 int size;
563 struct tdesc *tdp;
564
565 cp = number(cp, &size);
566 (*rtdp)->size = size;
567 (*rtdp)->type = type; /* s or u */
568
569 /*
570 * An '@' here indicates a bitmask follows. This is so the
571 * compiler can pass information to debuggers about how structures
572 * are passed in the v9 world. We don't need this information
573 * so we skip over it.
574 */
575 if (cp[0] == '@')
576 cp += 3;
577
578 debug(3, cp, "soudef: %s size=%d",
579 (*rtdp)->name ? (*rtdp)->name : "(anonsou)",
580 (*rtdp)->size);
581
582 next_pp = &((*rtdp)->data.members.forw); /* head for forward linklist */
583 /* fill up the fields */
584 while ((*cp != '"') && (*cp != ';')) { /* signifies end of fields */
585 int h;
586 struct mlist *mlp = malloc(sizeof (*mlp));
587
588 mlp->prev = prev_p; /* links for the backward list */
589 prev_p = mlp;
590 *next_pp = mlp; /* links for the forward list */
591 next_pp = &mlp->next;
592
593 cp = name(cp, &w);
594 mlp->name = w;
595 cp = id(cp, &h);
596 /*
597 * find the tdesc struct in the hash table for this type
598 * and stick a ptr in here
599 */
600 tdp = lookup(h);
601 if (tdp == NULL) { /* not in hash list */
602 debug(3, NULL, " defines %s (%d)", w, h);
603 if (*cp++ != '=')
604 expected("soudef", "=", cp - 1);
605 cp = tdefdecl(cp, h, &tdp);
606 addhash(tdp, h);
607 debug(4, cp, " soudef now looking at ");
608 cp++;
609
610 } else {
611 debug(3, NULL, " refers to %s (%d, %s)",
612 w ? w : "anon", h, tdp->name ? tdp->name : "anon");
613 }
614
615 mlp->fdesc = tdp;
616 cp = offsize(cp, mlp); /* cp is now pointing to next field */
617 if (*cp == '\\') /* could be a continuation */
618 cp = get_continuation();
619 }
620 (*rtdp)->data.members.back = prev_p; /* head for backward linklist */
621 return (cp);
622 }
623
624 static char *
offsize(char * cp,struct mlist * mlp)625 offsize(char *cp, struct mlist *mlp)
626 {
627 int offset, size;
628
629 if (*cp == ',')
630 cp++;
631 cp = number(cp, &offset);
632 if (*cp++ != ',')
633 expected("offsize/2", ",", cp - 1);
634 cp = number(cp, &size);
635 if (*cp++ != ';')
636 expected("offsize/3", ";", cp - 1);
637 mlp->offset = offset;
638 mlp->size = size;
639 return (cp);
640 }
641
642 static char *
arraydef(char * cp,struct tdesc ** rtdp)643 arraydef(char *cp, struct tdesc **rtdp)
644 {
645 int h;
646 int start, end;
647
648 cp = id(cp, &h);
649 if (*cp++ != ';')
650 expected("arraydef/1", ";", cp - 1);
651
652 (*rtdp)->data.ardef = malloc(sizeof (struct ardef));
653 (*rtdp)->data.ardef->indices = malloc(sizeof (struct element));
654 (*rtdp)->data.ardef->indices->index_type = lookup(h);
655
656 cp = number(cp, &start); /* lower */
657 if (*cp++ != ';')
658 expected("arraydef/2", ";", cp - 1);
659 cp = number(cp, &end); /* upper */
660 if (*cp++ != ';')
661 expected("arraydef/3", ";", cp - 1);
662 (*rtdp)->data.ardef->indices->range_start = start;
663 (*rtdp)->data.ardef->indices->range_end = end;
664 #if 0
665 if (isdigit(*cp)) {
666 cp = number(cp, &contents_type); /* lower */
667 tdp = lookup(contents_type);
668 if (tdp != NULL) {
669 (*rtdp)->data.ardef->contents = tdp;
670 } else {
671 if (*cp != '=')
672 expected("arraydef/4", "=", cp);
673 cp = tdefdecl(cp + 1, h, &tdp);
674 addhash(tdp, h); /* for *(x,y) types */
675 (*rtdp)->data.ardef->contents = tdp;
676 }
677 } /* else */
678 #endif
679 cp = tdefdecl(cp, h, &((*rtdp)->data.ardef->contents));
680 return (cp);
681 }
682
683 static void
enumdef(char * cp,struct tdesc ** rtdp)684 enumdef(char *cp, struct tdesc **rtdp)
685 {
686 struct elist *elp, **prev;
687 char *w;
688
689 (*rtdp)->type = ENUM;
690 (*rtdp)->data.emem = NULL;
691
692 prev = &((*rtdp)->data.emem);
693 while (*cp != ';') {
694 elp = malloc(sizeof (*elp));
695 elp->next = NULL;
696 *prev = elp;
697 cp = name(cp, &w);
698 elp->name = w;
699 cp = number(cp, &elp->number);
700 debug(3, NULL, "enum %s: %s=%ld",
701 (*rtdp)->name ? (*rtdp)->name : "(anon enum)",
702 elp->name, elp->number);
703 prev = &elp->next;
704 if (*cp++ != ',')
705 expected("enumdef", ",", cp - 1);
706 if (*cp == '\\')
707 cp = get_continuation();
708 }
709 }
710
711 /*
712 * Add a node to the hash queues.
713 */
714 static void
addhash(struct tdesc * tdp,int num)715 addhash(struct tdesc *tdp, int num)
716 {
717 int hash = HASH(num);
718 struct tdesc *ttdp;
719 char added_num = 0, added_name = 0;
720
721 /*
722 * If it already exists in the hash table don't add it again
723 * (but still check to see if the name should be hashed).
724 */
725 ttdp = lookup(num);
726 if (ttdp == NULL) {
727 tdp->id = num;
728 tdp->hash = hash_table[hash];
729 hash_table[hash] = tdp;
730 added_num = 1;
731 }
732
733 if (tdp->name != NULL) {
734 ttdp = lookupname(tdp->name);
735 if (ttdp == NULL) {
736 hash = compute_sum(tdp->name);
737 tdp->next = name_table[hash];
738 name_table[hash] = tdp;
739 added_name = 1;
740 }
741 }
742 if (!added_num && !added_name) {
743 fprintf(stderr, "stabs: broken hash\n");
744 exit(1);
745 }
746 }
747
748 struct tdesc *
lookupname(char * name)749 lookupname(char *name)
750 {
751 int hash = compute_sum(name);
752 struct tdesc *tdp, *ttdp = NULL;
753
754 for (tdp = name_table[hash]; tdp != NULL; tdp = tdp->next) {
755 if (tdp->name != NULL && strcmp(tdp->name, name) == 0) {
756 if (tdp->type == STRUCT || tdp->type == UNION ||
757 tdp->type == ENUM || tdp->type == INTRINSIC)
758 return (tdp);
759 if (tdp->type == TYPEOF)
760 ttdp = tdp;
761 }
762 }
763 return (ttdp);
764 }
765
766 static int
compute_sum(char * w)767 compute_sum(char *w)
768 {
769 char c;
770 int sum;
771
772 for (sum = 0; (c = *w) != '\0'; sum += c, w++)
773 ;
774 return (HASH(sum));
775 }
776
777 static void
reset(void)778 reset(void)
779 {
780 longjmp(resetbuf, 1);
781 /* NOTREACHED */
782 }
783