2 * smatch/smatch_dinfo.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
11 * smatch_dinfo.c has helper functions for handling data_info structs
22 #include "smatch_slist.h"
23 #include "smatch_extra.h"
25 struct data_range whole_range
= {
30 struct data_info
*get_dinfo(struct smatch_state
*state
)
34 return (struct data_info
*)state
->data
;
38 struct range_list
*estate_ranges(struct smatch_state
*state
)
42 return get_dinfo(state
)->value_ranges
;
45 struct related_list
*estate_related(struct smatch_state
*state
)
49 return get_dinfo(state
)->related
;
52 long long estate_min(struct smatch_state
*state
)
54 return rl_min(estate_ranges(state
));
57 long long estate_max(struct smatch_state
*state
)
59 return rl_max(estate_ranges(state
));
62 static struct data_info
*alloc_dinfo(void)
64 struct data_info
*ret
;
66 ret
= __alloc_data_info(0);
68 ret
->type
= DATA_RANGE
;
69 ret
->value_ranges
= NULL
;
73 static struct data_info
*alloc_dinfo_range(long long min
, long long max
)
75 struct data_info
*ret
;
78 add_range(&ret
->value_ranges
, min
, max
);
82 static struct data_info
*alloc_dinfo_range_list(struct range_list
*rl
)
84 struct data_info
*ret
;
87 ret
->value_ranges
= rl
;
91 static struct data_info
*clone_dinfo(struct data_info
*dinfo
)
93 struct data_info
*ret
;
96 ret
->related
= clone_related_list(dinfo
->related
);
97 ret
->value_ranges
= clone_range_list(dinfo
->value_ranges
);
101 struct smatch_state
*clone_estate(struct smatch_state
*state
)
103 struct smatch_state
*ret
;
105 ret
= __alloc_smatch_state(0);
106 ret
->name
= state
->name
;
107 ret
->data
= clone_dinfo(get_dinfo(state
));
111 struct smatch_state
*alloc_estate_empty(void)
113 struct smatch_state
*state
;
114 struct data_info
*dinfo
;
116 dinfo
= alloc_dinfo();
117 state
= __alloc_smatch_state(0);
123 static struct smatch_state
*alloc_estate_no_name(int val
)
125 struct smatch_state
*state
;
127 state
= __alloc_smatch_state(0);
128 state
->data
= (void *)alloc_dinfo_range(val
, val
);
132 /* We do this because ->value_ranges is a list */
133 struct smatch_state
*extra_undefined(void)
135 struct data_info
*dinfo
;
136 static struct smatch_state
*ret
;
137 static struct symbol
*prev_func
;
139 if (prev_func
== cur_func_sym
)
141 prev_func
= cur_func_sym
;
143 dinfo
= alloc_dinfo_range(whole_range
.min
, whole_range
.max
);
144 ret
= __alloc_smatch_state(0);
145 ret
->name
= "unknown";
150 struct smatch_state
*extra_empty(void)
152 static struct smatch_state
*ret
;
153 static struct symbol
*prev_func
;
155 if (prev_func
== cur_func_sym
)
157 prev_func
= cur_func_sym
;
159 ret
= __alloc_smatch_state(0);
161 ret
->data
= alloc_dinfo();
165 struct smatch_state
*alloc_estate(long long val
)
167 struct smatch_state
*state
;
169 state
= alloc_estate_no_name(val
);
170 state
->name
= show_ranges(get_dinfo(state
)->value_ranges
);
174 struct smatch_state
*alloc_estate_range(long long min
, long long max
)
176 struct smatch_state
*state
;
178 if (min
== whole_range
.min
&& max
== whole_range
.max
)
179 return extra_undefined();
180 state
= __alloc_smatch_state(0);
181 state
->data
= (void *)alloc_dinfo_range(min
, max
);
182 state
->name
= show_ranges(get_dinfo(state
)->value_ranges
);
186 struct smatch_state
*alloc_estate_range_list(struct range_list
*rl
)
188 struct smatch_state
*state
;
191 return extra_empty();
193 if (is_whole_range_rl(rl
))
194 return extra_undefined();
196 state
= __alloc_smatch_state(0);
197 state
->data
= (void *)alloc_dinfo_range_list(rl
);
198 state
->name
= show_ranges(get_dinfo(state
)->value_ranges
);