function_implies_hook: fix bug when a function has 2 implications
[smatch.git] / smatch_type.c
blobc15067eb969789bfca95f92103dde5d01d72ffb2
1 /*
2 * sparse/smatch_types.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * The idea here is that you have an expression and you
12 * want to know what the type is for that.
15 #include "smatch.h"
17 static struct symbol *get_type_symbol(struct expression *expr)
19 if (!expr || expr->type != EXPR_SYMBOL)
20 return NULL;
22 return get_base_type(expr->symbol);
25 static struct symbol *get_symbol_from_deref(struct expression *expr)
27 struct ident *member;
28 struct symbol *struct_sym;
29 struct symbol *tmp;
31 if (!expr || expr->type != EXPR_DEREF)
32 return NULL;
34 member = expr->member;
35 struct_sym = get_type(expr->deref);
36 if (!struct_sym) {
37 // sm_msg("could not find struct type");
38 return NULL;
40 if (struct_sym->type == SYM_PTR)
41 struct_sym = get_base_type(struct_sym);
42 FOR_EACH_PTR(struct_sym->symbol_list, tmp) {
43 if (tmp->ident == member)
44 return get_base_type(tmp);
45 } END_FOR_EACH_PTR(tmp);
46 return NULL;
49 static struct symbol *get_return_type(struct expression *expr)
51 struct symbol *tmp;
53 tmp = get_type(expr->fn);
54 if (!tmp)
55 return NULL;
56 return get_base_type(tmp);
59 static struct symbol *fake_pointer_sym(struct expression *expr)
61 struct symbol *sym;
62 struct symbol *base;
64 sym = alloc_symbol(expr->pos, SYM_PTR);
65 expr = expr->unop;
66 base = get_type(expr);
67 if (!base)
68 return NULL;
69 sym->ctype.base_type = base;
70 return sym;
73 struct symbol *get_type(struct expression *expr)
75 struct symbol *tmp;
77 if (!expr)
78 return NULL;
79 expr = strip_parens(expr);
81 switch (expr->type) {
82 case EXPR_SYMBOL:
83 return get_type_symbol(expr);
84 case EXPR_DEREF:
85 return get_symbol_from_deref(expr);
86 case EXPR_PREOP:
87 if (expr->op == '&')
88 return fake_pointer_sym(expr);
89 return get_type(expr->unop);
90 case EXPR_CAST:
91 case EXPR_FORCE_CAST:
92 case EXPR_IMPLIED_CAST:
93 return get_base_type(expr->cast_type);
94 case EXPR_BINOP:
95 if (expr->op != '+')
96 return NULL;
97 tmp = get_type(expr->left);
98 if (!tmp || (tmp->type != SYM_ARRAY && tmp->type != SYM_PTR))
99 return NULL;
100 return get_base_type(tmp);
101 case EXPR_CALL:
102 return get_return_type(expr);
103 // default:
104 // sm_msg("unhandled type %d", expr->type);
108 return NULL;
111 long long type_max(struct symbol *base_type)
113 long long ret = whole_range.max;
114 int bits;
116 if (!base_type || !base_type->bit_size)
117 return ret;
118 bits = base_type->bit_size;
119 if (base_type->ctype.modifiers & MOD_SIGNED)
120 bits--;
121 ret >>= (63 - bits);
122 return ret;
125 long long type_min(struct symbol *base_type)
127 long long ret = whole_range.min;
128 int bits;
130 if (!base_type || !base_type->bit_size)
131 return ret;
132 if (base_type->ctype.modifiers & MOD_UNSIGNED)
133 return 0;
134 ret = whole_range.max;
135 bits = base_type->bit_size - 1;
136 ret >>= (63 - bits);
137 return -(ret + 1);