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