Print this page
11972 resync smatch
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/smatch_type.c
+++ new/usr/src/tools/smatch/src/smatch_type.c
1 1 /*
2 2 * Copyright (C) 2009 Dan Carpenter.
3 3 *
4 4 * This program is free software; you can redistribute it and/or
5 5 * modify it under the terms of the GNU General Public License
6 6 * as published by the Free Software Foundation; either version 2
7 7 * of the License, or (at your option) any later version.
8 8 *
9 9 * This program is distributed in the hope that it will be useful,
10 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 * GNU General Public License for more details.
13 13 *
14 14 * You should have received a copy of the GNU General Public License
15 15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16 16 */
17 17
18 18 /*
19 19 * The idea here is that you have an expression and you
20 20 * want to know what the type is for that.
21 21 */
22 22
23 23 #include "smatch.h"
24 24 #include "smatch_slist.h"
25 25
26 26 struct symbol *get_real_base_type(struct symbol *sym)
27 27 {
28 28 struct symbol *ret;
29 29
30 30 if (!sym)
31 31 return NULL;
32 32 if (sym->type == SYM_BASETYPE)
33 33 return sym;
34 34 ret = get_base_type(sym);
35 35 if (!ret)
36 36 return NULL;
37 37 if (ret->type == SYM_RESTRICT || ret->type == SYM_NODE)
38 38 return get_real_base_type(ret);
39 39 return ret;
40 40 }
41 41
42 42 int type_bytes(struct symbol *type)
43 43 {
44 44 int bits;
45 45
46 46 if (type && type->type == SYM_ARRAY)
47 47 return array_bytes(type);
48 48
49 49 bits = type_bits(type);
50 50 if (bits < 0)
51 51 return 0;
52 52 return bits_to_bytes(bits);
53 53 }
54 54
55 55 int array_bytes(struct symbol *type)
56 56 {
57 57 if (!type || type->type != SYM_ARRAY)
58 58 return 0;
59 59 return bits_to_bytes(type->bit_size);
60 60 }
61 61
62 62 static struct symbol *get_binop_type(struct expression *expr)
63 63 {
64 64 struct symbol *left, *right;
65 65
66 66 left = get_type(expr->left);
67 67 if (!left)
68 68 return NULL;
69 69
70 70 if (expr->op == SPECIAL_LEFTSHIFT ||
71 71 expr->op == SPECIAL_RIGHTSHIFT) {
72 72 if (type_positive_bits(left) < 31)
73 73 return &int_ctype;
74 74 return left;
75 75 }
76 76 right = get_type(expr->right);
77 77 if (!right)
78 78 return NULL;
79 79
80 80 if (expr->op == '-' &&
81 81 (is_ptr_type(left) && is_ptr_type(right)))
82 82 return ssize_t_ctype;
83 83
84 84 if (left->type == SYM_PTR || left->type == SYM_ARRAY)
85 85 return left;
86 86 if (right->type == SYM_PTR || right->type == SYM_ARRAY)
87 87 return right;
88 88
89 89 if (type_positive_bits(left) < 31 && type_positive_bits(right) < 31)
90 90 return &int_ctype;
91 91
92 92 if (type_positive_bits(left) > type_positive_bits(right))
93 93 return left;
94 94 return right;
95 95 }
96 96
97 97 static struct symbol *get_type_symbol(struct expression *expr)
98 98 {
99 99 if (!expr || expr->type != EXPR_SYMBOL || !expr->symbol)
100 100 return NULL;
101 101
102 102 return get_real_base_type(expr->symbol);
103 103 }
104 104
105 105 static struct symbol *get_member_symbol(struct symbol_list *symbol_list, struct ident *member)
106 106 {
107 107 struct symbol *tmp, *sub;
108 108
109 109 FOR_EACH_PTR(symbol_list, tmp) {
110 110 if (!tmp->ident) {
111 111 sub = get_real_base_type(tmp);
112 112 sub = get_member_symbol(sub->symbol_list, member);
113 113 if (sub)
114 114 return sub;
115 115 continue;
116 116 }
117 117 if (tmp->ident == member)
118 118 return tmp;
119 119 } END_FOR_EACH_PTR(tmp);
120 120
121 121 return NULL;
122 122 }
123 123
124 124 static struct symbol *get_symbol_from_deref(struct expression *expr)
125 125 {
126 126 struct ident *member;
127 127 struct symbol *sym;
128 128
129 129 if (!expr || expr->type != EXPR_DEREF)
130 130 return NULL;
131 131
132 132 member = expr->member;
133 133 sym = get_type(expr->deref);
134 134 if (!sym) {
135 135 // sm_msg("could not find struct type");
136 136 return NULL;
137 137 }
138 138 if (sym->type == SYM_PTR)
139 139 sym = get_real_base_type(sym);
140 140 sym = get_member_symbol(sym->symbol_list, member);
141 141 if (!sym)
142 142 return NULL;
143 143 return get_real_base_type(sym);
144 144 }
145 145
146 146 static struct symbol *get_return_type(struct expression *expr)
147 147 {
148 148 struct symbol *tmp;
149 149
150 150 tmp = get_type(expr->fn);
151 151 if (!tmp)
152 152 return NULL;
153 153 /* this is to handle __builtin_constant_p() */
154 154 if (tmp->type != SYM_FN)
155 155 tmp = get_base_type(tmp);
156 156 return get_real_base_type(tmp);
157 157 }
158 158
159 159 static struct symbol *get_expr_stmt_type(struct statement *stmt)
160 160 {
161 161 if (stmt->type != STMT_COMPOUND)
162 162 return NULL;
163 163 stmt = last_ptr_list((struct ptr_list *)stmt->stmts);
164 164 if (stmt->type == STMT_LABEL)
165 165 stmt = stmt->label_statement;
166 166 if (stmt->type != STMT_EXPRESSION)
167 167 return NULL;
168 168 return get_type(stmt->expression);
169 169 }
170 170
171 171 static struct symbol *get_select_type(struct expression *expr)
172 172 {
173 173 struct symbol *one, *two;
174 174
175 175 one = get_type(expr->cond_true);
176 176 two = get_type(expr->cond_false);
177 177 if (!one || !two)
178 178 return NULL;
179 179 /*
180 180 * This is a hack. If the types are not equiv then we
181 181 * really don't know the type. But I think guessing is
182 182 * probably Ok here.
183 183 */
184 184 if (type_positive_bits(one) > type_positive_bits(two))
185 185 return one;
186 186 return two;
187 187 }
188 188
189 189 struct symbol *get_pointer_type(struct expression *expr)
190 190 {
191 191 struct symbol *sym;
192 192
193 193 sym = get_type(expr);
194 194 if (!sym)
195 195 return NULL;
196 196 if (sym->type == SYM_NODE) {
197 197 sym = get_real_base_type(sym);
198 198 if (!sym)
199 199 return NULL;
200 200 }
201 201 if (sym->type != SYM_PTR && sym->type != SYM_ARRAY)
202 202 return NULL;
203 203 return get_real_base_type(sym);
204 204 }
205 205
206 206 static struct symbol *fake_pointer_sym(struct expression *expr)
207 207 {
208 208 struct symbol *sym;
209 209 struct symbol *base;
210 210
211 211 sym = alloc_symbol(expr->pos, SYM_PTR);
212 212 expr = expr->unop;
213 213 base = get_type(expr);
214 214 if (!base)
215 215 return NULL;
216 216 sym->ctype.base_type = base;
217 217 return sym;
218 218 }
219 219
220 220 static struct symbol *get_type_helper(struct expression *expr)
221 221 {
222 222 struct symbol *ret;
223 223
224 224 expr = strip_parens(expr);
225 225 if (!expr)
226 226 return NULL;
227 227
228 228 if (expr->ctype)
229 229 return expr->ctype;
230 230
231 231 switch (expr->type) {
232 232 case EXPR_STRING:
233 233 ret = &string_ctype;
234 234 break;
235 235 case EXPR_SYMBOL:
236 236 ret = get_type_symbol(expr);
237 237 break;
238 238 case EXPR_DEREF:
239 239 ret = get_symbol_from_deref(expr);
240 240 break;
241 241 case EXPR_PREOP:
242 242 case EXPR_POSTOP:
243 243 if (expr->op == '&')
244 244 ret = fake_pointer_sym(expr);
245 245 else if (expr->op == '*')
246 246 ret = get_pointer_type(expr->unop);
247 247 else
248 248 ret = get_type(expr->unop);
249 249 break;
250 250 case EXPR_ASSIGNMENT:
251 251 ret = get_type(expr->left);
252 252 break;
253 253 case EXPR_CAST:
254 254 case EXPR_FORCE_CAST:
255 255 case EXPR_IMPLIED_CAST:
256 256 ret = get_real_base_type(expr->cast_type);
257 257 break;
258 258 case EXPR_COMPARE:
259 259 case EXPR_BINOP:
260 260 ret = get_binop_type(expr);
261 261 break;
262 262 case EXPR_CALL:
263 263 ret = get_return_type(expr);
264 264 break;
265 265 case EXPR_STATEMENT:
266 266 ret = get_expr_stmt_type(expr->statement);
267 267 break;
268 268 case EXPR_CONDITIONAL:
269 269 case EXPR_SELECT:
270 270 ret = get_select_type(expr);
271 271 break;
272 272 case EXPR_SIZEOF:
273 273 ret = &ulong_ctype;
274 274 break;
275 275 case EXPR_LOGICAL:
276 276 ret = &int_ctype;
277 277 break;
278 278 case EXPR_OFFSETOF:
279 279 ret = &ulong_ctype;
280 280 break;
281 281 default:
282 282 return NULL;
283 283 }
284 284
285 285 if (ret && ret->type == SYM_TYPEOF)
286 286 ret = get_type(ret->initializer);
287 287
288 288 expr->ctype = ret;
289 289 return ret;
290 290 }
291 291
292 292 static struct symbol *get_final_type_helper(struct expression *expr)
293 293 {
294 294 /*
295 295 * The problem is that I wrote a bunch of Smatch to think that
296 296 * you could do get_type() on an expression and it would give
297 297 * you what the comparison was type promoted to. This is wrong
298 298 * but fixing it is a big of work... Hence this horrible hack.
299 299 *
300 300 */
301 301
302 302 expr = strip_parens(expr);
303 303 if (!expr)
304 304 return NULL;
305 305
306 306 if (expr->type == EXPR_COMPARE)
307 307 return &int_ctype;
308 308
309 309 return NULL;
310 310 }
311 311
312 312 struct symbol *get_type(struct expression *expr)
313 313 {
314 314 return get_type_helper(expr);
315 315 }
316 316
317 317 struct symbol *get_final_type(struct expression *expr)
318 318 {
319 319 struct symbol *ret;
320 320
321 321 ret = get_final_type_helper(expr);
322 322 if (ret)
323 323 return ret;
324 324 return get_type_helper(expr);
325 325 }
326 326
327 327 struct symbol *get_promoted_type(struct symbol *left, struct symbol *right)
328 328 {
329 329 struct symbol *ret = &int_ctype;
330 330
331 331 if (type_positive_bits(left) > type_positive_bits(ret))
332 332 ret = left;
333 333 if (type_positive_bits(right) > type_positive_bits(ret))
334 334 ret = right;
335 335
336 336 if (type_is_ptr(left))
337 337 ret = left;
338 338 if (type_is_ptr(right))
339 339 ret = right;
340 340
341 341 return ret;
342 342 }
343 343
344 344 int type_signed(struct symbol *base_type)
345 345 {
346 346 if (!base_type)
347 347 return 0;
348 348 if (base_type->ctype.modifiers & MOD_SIGNED)
349 349 return 1;
350 350 return 0;
351 351 }
352 352
353 353 int expr_unsigned(struct expression *expr)
354 354 {
355 355 struct symbol *sym;
356 356
357 357 sym = get_type(expr);
358 358 if (!sym)
359 359 return 0;
360 360 if (type_unsigned(sym))
361 361 return 1;
362 362 return 0;
363 363 }
364 364
365 365 int expr_signed(struct expression *expr)
366 366 {
367 367 struct symbol *sym;
368 368
369 369 sym = get_type(expr);
370 370 if (!sym)
371 371 return 0;
372 372 if (type_signed(sym))
373 373 return 1;
374 374 return 0;
375 375 }
376 376
377 377 int returns_unsigned(struct symbol *sym)
378 378 {
379 379 if (!sym)
380 380 return 0;
381 381 sym = get_base_type(sym);
382 382 if (!sym || sym->type != SYM_FN)
383 383 return 0;
384 384 sym = get_base_type(sym);
385 385 return type_unsigned(sym);
386 386 }
387 387
388 388 int is_pointer(struct expression *expr)
389 389 {
390 390 return type_is_ptr(get_type(expr));
↓ open down ↓ |
390 lines elided |
↑ open up ↑ |
391 391 }
392 392
393 393 int returns_pointer(struct symbol *sym)
394 394 {
395 395 if (!sym)
396 396 return 0;
397 397 sym = get_base_type(sym);
398 398 if (!sym || sym->type != SYM_FN)
399 399 return 0;
400 400 sym = get_base_type(sym);
401 - if (sym->type == SYM_PTR)
401 + if (sym && sym->type == SYM_PTR)
402 402 return 1;
403 403 return 0;
404 404 }
405 405
406 406 sval_t sval_type_max(struct symbol *base_type)
407 407 {
408 408 sval_t ret;
409 409
410 410 if (!base_type || !type_bits(base_type))
411 411 base_type = &llong_ctype;
412 412 ret.type = base_type;
413 413
414 414 ret.value = (~0ULL) >> (64 - type_positive_bits(base_type));
415 415 return ret;
416 416 }
417 417
418 418 sval_t sval_type_min(struct symbol *base_type)
419 419 {
420 420 sval_t ret;
421 421
422 422 if (!base_type || !type_bits(base_type))
423 423 base_type = &llong_ctype;
424 424 ret.type = base_type;
425 425
426 426 if (type_unsigned(base_type) || is_ptr_type(base_type)) {
427 427 ret.value = 0;
428 428 return ret;
429 429 }
430 430
431 431 ret.value = (~0ULL) << type_positive_bits(base_type);
432 432
433 433 return ret;
434 434 }
435 435
436 436 int nr_bits(struct expression *expr)
437 437 {
438 438 struct symbol *type;
439 439
440 440 type = get_type(expr);
441 441 if (!type)
442 442 return 0;
443 443 return type_bits(type);
444 444 }
445 445
446 446 int is_void_pointer(struct expression *expr)
447 447 {
448 448 struct symbol *type;
449 449
450 450 type = get_type(expr);
451 451 if (!type || type->type != SYM_PTR)
452 452 return 0;
453 453 type = get_real_base_type(type);
454 454 if (type == &void_ctype)
455 455 return 1;
456 456 return 0;
457 457 }
458 458
459 459 int is_char_pointer(struct expression *expr)
460 460 {
461 461 struct symbol *type;
462 462
463 463 type = get_type(expr);
464 464 if (!type || type->type != SYM_PTR)
465 465 return 0;
466 466 type = get_real_base_type(type);
467 467 if (type == &char_ctype)
468 468 return 1;
469 469 return 0;
470 470 }
471 471
472 472 int is_string(struct expression *expr)
473 473 {
474 474 expr = strip_expr(expr);
475 475 if (!expr || expr->type != EXPR_STRING)
476 476 return 0;
477 477 if (expr->string)
478 478 return 1;
479 479 return 0;
480 480 }
481 481
482 482 int is_static(struct expression *expr)
483 483 {
484 484 char *name;
485 485 struct symbol *sym;
486 486 int ret = 0;
487 487
488 488 name = expr_to_str_sym(expr, &sym);
↓ open down ↓ |
77 lines elided |
↑ open up ↑ |
489 489 if (!name || !sym)
490 490 goto free;
491 491
492 492 if (sym->ctype.modifiers & MOD_STATIC)
493 493 ret = 1;
494 494 free:
495 495 free_string(name);
496 496 return ret;
497 497 }
498 498
499 -int is_local_variable(struct expression *expr)
499 +bool is_local_variable(struct expression *expr)
500 500 {
501 501 struct symbol *sym;
502 - char *name;
503 502
504 - name = expr_to_var_sym(expr, &sym);
505 - free_string(name);
506 - if (!sym || !sym->scope || !sym->scope->token || !cur_func_sym)
507 - return 0;
508 - if (cmp_pos(sym->scope->token->pos, cur_func_sym->pos) < 0)
509 - return 0;
510 - if (is_static(expr))
511 - return 0;
512 - return 1;
503 + if (!expr || expr->type != EXPR_SYMBOL || !expr->symbol)
504 + return false;
505 + sym = expr->symbol;
506 + if (!(sym->ctype.modifiers & MOD_TOPLEVEL))
507 + return true;
508 + return false;
513 509 }
514 510
515 511 int types_equiv(struct symbol *one, struct symbol *two)
516 512 {
517 513 if (!one && !two)
518 514 return 1;
519 515 if (!one || !two)
520 516 return 0;
521 517 if (one->type != two->type)
522 518 return 0;
523 519 if (one->type == SYM_PTR)
524 520 return types_equiv(get_real_base_type(one), get_real_base_type(two));
525 521 if (type_positive_bits(one) != type_positive_bits(two))
526 522 return 0;
527 523 return 1;
528 524 }
529 525
530 526 int fn_static(void)
531 527 {
532 528 return !!(cur_func_sym->ctype.modifiers & MOD_STATIC);
533 529 }
534 530
535 531 const char *global_static(void)
536 532 {
537 533 if (cur_func_sym->ctype.modifiers & MOD_STATIC)
538 534 return "static";
539 535 else
540 536 return "global";
541 537 }
542 538
543 539 struct symbol *cur_func_return_type(void)
544 540 {
545 541 struct symbol *sym;
546 542
547 543 sym = get_real_base_type(cur_func_sym);
548 544 if (!sym || sym->type != SYM_FN)
549 545 return NULL;
550 546 sym = get_real_base_type(sym);
551 547 return sym;
552 548 }
553 549
554 550 struct symbol *get_arg_type(struct expression *fn, int arg)
555 551 {
556 552 struct symbol *fn_type;
557 553 struct symbol *tmp;
558 554 struct symbol *arg_type;
559 555 int i;
560 556
561 557 fn_type = get_type(fn);
562 558 if (!fn_type)
563 559 return NULL;
564 560 if (fn_type->type == SYM_PTR)
565 561 fn_type = get_real_base_type(fn_type);
566 562 if (fn_type->type != SYM_FN)
567 563 return NULL;
568 564
569 565 i = 0;
570 566 FOR_EACH_PTR(fn_type->arguments, tmp) {
571 567 arg_type = get_real_base_type(tmp);
572 568 if (i == arg) {
573 569 return arg_type;
574 570 }
575 571 i++;
576 572 } END_FOR_EACH_PTR(tmp);
577 573
578 574 return NULL;
579 575 }
580 576
581 577 static struct symbol *get_member_from_string(struct symbol_list *symbol_list, const char *name)
582 578 {
583 579 struct symbol *tmp, *sub;
584 580 int chunk_len;
585 581
586 582 if (strncmp(name, ".", 1) == 0)
587 583 name += 1;
588 584 else if (strncmp(name, "->", 2) == 0)
589 585 name += 2;
590 586
591 587 FOR_EACH_PTR(symbol_list, tmp) {
592 588 if (!tmp->ident) {
593 589 sub = get_real_base_type(tmp);
594 590 sub = get_member_from_string(sub->symbol_list, name);
595 591 if (sub)
596 592 return sub;
597 593 continue;
598 594 }
599 595
600 596 if (strcmp(tmp->ident->name, name) == 0)
601 597 return tmp;
602 598
603 599 chunk_len = tmp->ident->len;
604 600 if (strncmp(tmp->ident->name, name, chunk_len) == 0 &&
605 601 (name[chunk_len] == '.' || name[chunk_len] == '-')) {
606 602 sub = get_real_base_type(tmp);
607 603 if (sub->type == SYM_PTR)
608 604 sub = get_real_base_type(sub);
609 605 return get_member_from_string(sub->symbol_list, name + chunk_len);
610 606 }
611 607
612 608 } END_FOR_EACH_PTR(tmp);
613 609
614 610 return NULL;
615 611 }
616 612
617 613 struct symbol *get_member_type_from_key(struct expression *expr, const char *key)
618 614 {
619 615 struct symbol *sym;
620 616
621 617 if (strcmp(key, "$") == 0)
622 618 return get_type(expr);
623 619
624 620 if (strcmp(key, "*$") == 0) {
625 621 sym = get_type(expr);
626 622 if (!sym || sym->type != SYM_PTR)
627 623 return NULL;
628 624 return get_real_base_type(sym);
629 625 }
630 626
631 627 sym = get_type(expr);
632 628 if (!sym)
633 629 return NULL;
634 630 if (sym->type == SYM_PTR)
635 631 sym = get_real_base_type(sym);
636 632
637 633 key = key + 1;
638 634 sym = get_member_from_string(sym->symbol_list, key);
639 635 if (!sym)
640 636 return NULL;
641 637 return get_real_base_type(sym);
642 638 }
643 639
644 640 struct symbol *get_arg_type_from_key(struct expression *fn, int param, struct expression *arg, const char *key)
645 641 {
646 642 struct symbol *type;
647 643
648 644 if (!key)
649 645 return NULL;
650 646 if (strcmp(key, "$") == 0)
651 647 return get_arg_type(fn, param);
652 648 if (strcmp(key, "*$") == 0) {
653 649 type = get_arg_type(fn, param);
654 650 if (!type || type->type != SYM_PTR)
655 651 return NULL;
656 652 return get_real_base_type(type);
657 653 }
658 654 return get_member_type_from_key(arg, key);
659 655 }
660 656
661 657 int is_struct(struct expression *expr)
662 658 {
663 659 struct symbol *type;
664 660
665 661 type = get_type(expr);
666 662 if (type && type->type == SYM_STRUCT)
667 663 return 1;
668 664 return 0;
669 665 }
670 666
671 667 static struct {
672 668 struct symbol *sym;
673 669 const char *name;
674 670 } base_types[] = {
675 671 {&bool_ctype, "bool"},
676 672 {&void_ctype, "void"},
677 673 {&type_ctype, "type"},
678 674 {&char_ctype, "char"},
679 675 {&schar_ctype, "schar"},
680 676 {&uchar_ctype, "uchar"},
681 677 {&short_ctype, "short"},
682 678 {&sshort_ctype, "sshort"},
683 679 {&ushort_ctype, "ushort"},
684 680 {&int_ctype, "int"},
685 681 {&sint_ctype, "sint"},
686 682 {&uint_ctype, "uint"},
687 683 {&long_ctype, "long"},
688 684 {&slong_ctype, "slong"},
689 685 {&ulong_ctype, "ulong"},
690 686 {&llong_ctype, "llong"},
691 687 {&sllong_ctype, "sllong"},
692 688 {&ullong_ctype, "ullong"},
693 689 {&lllong_ctype, "lllong"},
694 690 {&slllong_ctype, "slllong"},
695 691 {&ulllong_ctype, "ulllong"},
696 692 {&float_ctype, "float"},
697 693 {&double_ctype, "double"},
698 694 {&ldouble_ctype, "ldouble"},
699 695 {&string_ctype, "string"},
700 696 {&ptr_ctype, "ptr"},
701 697 {&lazy_ptr_ctype, "lazy_ptr"},
702 698 {&incomplete_ctype, "incomplete"},
703 699 {&label_ctype, "label"},
704 700 {&bad_ctype, "bad"},
705 701 {&null_ctype, "null"},
706 702 };
707 703
708 704 static const char *base_type_str(struct symbol *sym)
709 705 {
710 706 int i;
711 707
712 708 for (i = 0; i < ARRAY_SIZE(base_types); i++) {
713 709 if (sym == base_types[i].sym)
714 710 return base_types[i].name;
715 711 }
716 712 return "<unknown>";
717 713 }
718 714
719 715 static int type_str_helper(char *buf, int size, struct symbol *type)
720 716 {
721 717 int n;
722 718
723 719 if (!type)
724 720 return snprintf(buf, size, "<unknown>");
725 721
726 722 if (type->type == SYM_BASETYPE) {
727 723 return snprintf(buf, size, "%s", base_type_str(type));
728 724 } else if (type->type == SYM_PTR) {
729 725 type = get_real_base_type(type);
730 726 n = type_str_helper(buf, size, type);
731 727 if (n > size)
732 728 return n;
733 729 return n + snprintf(buf + n, size - n, "*");
734 730 } else if (type->type == SYM_ARRAY) {
735 731 type = get_real_base_type(type);
736 732 n = type_str_helper(buf, size, type);
737 733 if (n > size)
738 734 return n;
739 735 return n + snprintf(buf + n, size - n, "[]");
740 736 } else if (type->type == SYM_STRUCT) {
741 737 return snprintf(buf, size, "struct %s", type->ident ? type->ident->name : "");
742 738 } else if (type->type == SYM_UNION) {
743 739 if (type->ident)
744 740 return snprintf(buf, size, "union %s", type->ident->name);
745 741 else
746 742 return snprintf(buf, size, "anonymous union");
747 743 } else if (type->type == SYM_FN) {
748 744 struct symbol *arg, *return_type, *arg_type;
749 745 int i;
750 746
751 747 return_type = get_real_base_type(type);
752 748 n = type_str_helper(buf, size, return_type);
753 749 if (n > size)
754 750 return n;
755 751 n += snprintf(buf + n, size - n, "(*)(");
756 752 if (n > size)
757 753 return n;
758 754
759 755 i = 0;
760 756 FOR_EACH_PTR(type->arguments, arg) {
761 757 if (i++)
762 758 n += snprintf(buf + n, size - n, ", ");
763 759 if (n > size)
764 760 return n;
765 761 arg_type = get_real_base_type(arg);
766 762 n += type_str_helper(buf + n, size - n, arg_type);
767 763 if (n > size)
768 764 return n;
769 765 } END_FOR_EACH_PTR(arg);
770 766
771 767 return n + snprintf(buf + n, size - n, ")");
772 768 } else if (type->type == SYM_NODE) {
773 769 n = snprintf(buf, size, "node {");
774 770 if (n > size)
775 771 return n;
776 772 type = get_real_base_type(type);
777 773 n += type_str_helper(buf + n, size - n, type);
778 774 if (n > size)
779 775 return n;
780 776 return n + snprintf(buf + n, size - n, "}");
781 777 } else if (type->type == SYM_ENUM) {
782 778 return snprintf(buf, size, "enum %s", type->ident ? type->ident->name : "<unknown>");
783 779 } else {
784 780 return snprintf(buf, size, "<type %d>", type->type);
785 781 }
786 782 }
787 783
788 784 char *type_to_str(struct symbol *type)
789 785 {
790 786 static char buf[256];
791 787
792 788 buf[0] = '\0';
793 789 type_str_helper(buf, sizeof(buf), type);
794 790 return buf;
795 791 }
↓ open down ↓ |
273 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX