related: rename dinfo->equiv to dinfo->related
[smatch.git] / smatch_type.c
blob1dd12b8db4d73bc1fec4d729b868bdb2f6bf2595
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 struct symbol *get_real_base_type(struct symbol *sym)
19 struct symbol *ret;
21 ret = get_base_type(sym);
22 if (ret && ret->type == SYM_RESTRICT)
23 return get_real_base_type(ret);
24 return ret;
27 static struct symbol *get_type_symbol(struct expression *expr)
29 if (!expr || expr->type != EXPR_SYMBOL || !expr->symbol)
30 return NULL;
32 return get_real_base_type(expr->symbol);
35 static struct symbol *get_symbol_from_deref(struct expression *expr)
37 struct ident *member;
38 struct symbol *struct_sym;
39 struct symbol *tmp;
41 if (!expr || expr->type != EXPR_DEREF)
42 return NULL;
44 member = expr->member;
45 struct_sym = get_type(expr->deref);
46 if (!struct_sym) {
47 // sm_msg("could not find struct type");
48 return NULL;
50 if (struct_sym->type == SYM_PTR)
51 struct_sym = get_real_base_type(struct_sym);
52 FOR_EACH_PTR(struct_sym->symbol_list, tmp) {
53 if (tmp->ident == member)
54 return get_real_base_type(tmp);
55 } END_FOR_EACH_PTR(tmp);
56 return NULL;
59 static struct symbol *get_return_type(struct expression *expr)
61 struct symbol *tmp;
63 tmp = get_type(expr->fn);
64 if (!tmp)
65 return NULL;
66 return get_real_base_type(tmp);
69 static struct symbol *get_pointer_type(struct expression *expr)
71 struct symbol *sym;
73 sym = get_type(expr);
74 if (!sym || sym->type != SYM_PTR)
75 return NULL;
76 return get_real_base_type(sym);
79 static struct symbol *fake_pointer_sym(struct expression *expr)
81 struct symbol *sym;
82 struct symbol *base;
84 sym = alloc_symbol(expr->pos, SYM_PTR);
85 expr = expr->unop;
86 base = get_type(expr);
87 if (!base)
88 return NULL;
89 sym->ctype.base_type = base;
90 return sym;
93 struct symbol *get_type(struct expression *expr)
95 struct symbol *tmp;
97 if (!expr)
98 return NULL;
99 expr = strip_parens(expr);
101 switch (expr->type) {
102 case EXPR_SYMBOL:
103 return get_type_symbol(expr);
104 case EXPR_DEREF:
105 return get_symbol_from_deref(expr);
106 case EXPR_PREOP:
107 if (expr->op == '&')
108 return fake_pointer_sym(expr);
109 if (expr->op == '*')
110 return get_pointer_type(expr->unop);
111 return get_type(expr->unop);
112 case EXPR_CAST:
113 case EXPR_FORCE_CAST:
114 case EXPR_IMPLIED_CAST:
115 return get_real_base_type(expr->cast_type);
116 case EXPR_BINOP:
117 if (expr->op != '+')
118 return NULL;
119 tmp = get_type(expr->left);
120 if (!tmp || (tmp->type != SYM_ARRAY && tmp->type != SYM_PTR))
121 return NULL;
122 return get_real_base_type(tmp);
123 case EXPR_CALL:
124 return get_return_type(expr);
125 default:
126 return expr->ctype;
127 // sm_msg("unhandled type %d", expr->type);
131 return NULL;
134 int type_unsigned(struct symbol *base_type)
136 if (!base_type)
137 return 0;
138 if (base_type->ctype.modifiers & MOD_UNSIGNED)
139 return 1;
140 return 0;
143 long long type_max(struct symbol *base_type)
145 long long ret = whole_range.max;
146 int bits;
148 if (!base_type || !base_type->bit_size)
149 return ret;
150 bits = base_type->bit_size;
151 if (bits == 64)
152 return ret;
153 if (!type_unsigned(base_type))
154 bits--;
155 ret >>= (63 - bits);
156 return ret;
159 long long type_min(struct symbol *base_type)
161 long long ret = whole_range.min;
162 int bits;
164 if (!base_type || !base_type->bit_size)
165 return ret;
166 if (type_unsigned(base_type))
167 return 0;
168 ret = whole_range.max;
169 bits = base_type->bit_size - 1;
170 ret >>= (63 - bits);
171 return -(ret + 1);