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