2 * sparse/smatch_helper.c
4 * Copyright (C) 2006 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
11 * Miscellaneous helper functions.
22 char *alloc_string(const char *str
)
28 tmp
= malloc(strlen(str
) + 1);
33 void free_string(char *str
)
38 static void append(char *dest
, const char *data
, int buff_len
)
40 strncat(dest
, data
, buff_len
- strlen(dest
) - 1);
44 * If you have "foo(a, b, 1);" then use
45 * get_argument_from_call_expr(expr, 0) to return the expression for
46 * a. Yes, it does start counting from 0.
48 struct expression
*get_argument_from_call_expr(struct expression_list
*args
,
51 struct expression
*expr
;
57 FOR_EACH_PTR(args
, expr
) {
61 } END_FOR_EACH_PTR(expr
);
65 static void __get_variable_from_expr(struct symbol
**sym_ptr
, char *buf
,
66 struct expression
*expr
, int len
,
69 struct expression
*tmp
;
74 if (!strcmp(show_special(tmp
->op
), "*")) {
77 __get_variable_from_expr(sym_ptr
, buf
, tmp
, len
, complicated
);
80 if (!strcmp(show_special(tmp
->op
), "*")) {
81 append(buf
, "->", len
);
83 append(buf
, ".", len
);
85 append(buf
, expr
->member
->name
, len
);
89 if (expr
->symbol_name
)
90 append(buf
, expr
->symbol_name
->name
, len
);
94 *sym_ptr
= expr
->symbol
;
100 if (get_block_thing(expr
)) {
106 tmp
= show_special(expr
->op
);
107 append(buf
, tmp
, len
);
108 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
112 append(buf
, ")", len
);
115 if ((!strcmp(tmp
, "--")) || (!strcmp(tmp
, "++")))
123 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
125 tmp
= show_special(expr
->op
);
126 append(buf
, tmp
, len
);
128 if ((!strcmp(tmp
, "--")) || (!strcmp(tmp
, "++")))
137 append(buf
, "(", len
);
138 __get_variable_from_expr(NULL
, buf
, expr
->left
, len
,
140 tmp
= show_special(expr
->op
);
141 append(buf
, tmp
, len
);
142 __get_variable_from_expr(sym_ptr
, buf
, expr
->right
,
144 append(buf
, ")", len
);
150 snprintf(tmp
, 25, "%lld", expr
->value
);
151 append(buf
, tmp
, len
);
155 append(buf
, expr
->string
->data
, len
);
158 struct expression
*tmp
;
162 __get_variable_from_expr(NULL
, buf
, expr
->fn
, len
,
164 append(buf
, "(", len
);
166 FOR_EACH_PTR_REVERSE(expr
->args
, tmp
) {
168 append(buf
, ", ", len
);
169 __get_variable_from_expr(NULL
, buf
, tmp
, len
,
171 } END_FOR_EACH_PTR_REVERSE(tmp
);
172 append(buf
, ")", len
);
176 __get_variable_from_expr(sym_ptr
, buf
,
177 expr
->cast_expression
, len
,
184 if (expr
->cast_type
&& get_base_type(expr
->cast_type
)) {
185 size
= (get_base_type(expr
->cast_type
))->bit_size
;
186 snprintf(tmp
, 25, "%d", size
);
187 append(buf
, tmp
, len
);
193 //printf("unknown type = %d\n", expr->type);
200 * This is returns a stylized "c looking" representation of the
203 * It uses the same buffer every time so you have to save the result
204 * yourself if you want to keep it.
208 char *get_variable_from_expr_complex(struct expression
*expr
, struct symbol
**sym_ptr
)
210 static char var_name
[VAR_LEN
];
219 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
222 return alloc_string(var_name
);
228 * get_variable_from_expr_simple() only returns simple variables.
229 * If it's a complicated variable like a->foo instead of just 'a'
230 * then it returns NULL.
233 char *get_variable_from_expr(struct expression
*expr
,
234 struct symbol
**sym_ptr
)
236 static char var_name
[VAR_LEN
];
245 expr
= strip_expr(expr
);
246 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
254 return alloc_string(var_name
);
257 struct symbol
*get_ptr_type_ptr(struct symbol
*sym
)
263 if (sym
->type
!= SYM_NODE
)
265 sym
= get_base_type(sym
);
266 if (sym
->type
!= SYM_PTR
)
268 sym
= get_base_type(sym
);
272 static struct symbol
*get_struct_sym(struct expression
*expr
)
274 struct symbol
*base_type
;
275 struct symbol
*parent_struct
;
278 if (expr
->type
!= EXPR_PREOP
)
282 if (expr
->type
== EXPR_DEREF
) {
283 parent_struct
= get_struct_sym(expr
->deref
);
287 FOR_EACH_PTR(parent_struct
->symbol_list
, tmp
) {
288 if (tmp
->ident
== expr
->member
)
290 } END_FOR_EACH_PTR(tmp
);
291 if (!tmp
|| tmp
->ident
!= expr
->member
)
293 base_type
= get_base_type(tmp
);
294 } else if (expr
->type
== EXPR_SYMBOL
) {
295 base_type
= get_base_type(expr
->symbol
);
299 if (base_type
->type
!= SYM_PTR
)
301 base_type
= get_base_type(base_type
);
302 if (base_type
->type
!= SYM_STRUCT
&& base_type
->type
!= SYM_UNION
)
307 struct symbol
*get_deref_type(struct expression
*expr
)
309 struct ident
*member
= expr
->member
;
310 struct symbol
*struct_sym
;
313 struct_sym
= get_struct_sym(expr
->deref
);
314 if (!struct_sym
|| (struct_sym
->type
!= SYM_STRUCT
315 && struct_sym
->type
!= SYM_UNION
))
317 FOR_EACH_PTR(struct_sym
->symbol_list
, tmp
) {
318 if (tmp
->ident
== member
)
319 return get_ptr_type_ptr(tmp
);
320 } END_FOR_EACH_PTR(tmp
);
324 struct symbol
*get_ptr_type(struct expression
*expr
)
326 struct symbol
*ptr_type
= NULL
;
330 if (expr
->type
== EXPR_DEREF
)
331 ptr_type
= get_deref_type(expr
);
332 if (expr
->type
== EXPR_SYMBOL
)
333 ptr_type
= get_ptr_type_ptr(expr
->symbol
);
337 int sym_name_is(const char *name
, struct expression
*expr
)
341 if (expr
->type
!= EXPR_SYMBOL
)
343 if (!strcmp(expr
->symbol_name
->name
, name
))
351 static int _get_value(struct expression
*expr
, int *discard
, int implied
)
363 expr
= strip_expr(expr
);
370 if (!strcmp("-", show_special(expr
->op
)))
371 ret
= - _get_value(expr
->unop
, discard
, implied
);
378 if (!show_special(expr
->op
)) {
382 left
= _get_value(expr
->left
, discard
, implied
);
383 right
= _get_value(expr
->right
, discard
, implied
);
384 if (!strcmp("*", show_special(expr
->op
))) {
386 } else if (!strcmp("/", show_special(expr
->op
))) {
388 } else if (!strcmp("+", show_special(expr
->op
))) {
390 } else if (!strcmp("-", show_special(expr
->op
))) {
392 } else if (!strcmp("|", show_special(expr
->op
))) {
394 } else if (!strcmp("&", show_special(expr
->op
))) {
396 } else if (!strcmp(">>", show_special(expr
->op
))) {
398 } else if (!strcmp("<<", show_special(expr
->op
))) {
407 ret
= get_expression_value(expr
);
411 ret
= get_implied_single_val(expr
);
412 if (ret
== UNDEFINED
)
423 /* returns UNDEFINED on error */
424 int get_value(struct expression
*expr
)
426 return _get_value(expr
, NULL
, NOTIMPLIED
);
429 int get_implied_value(struct expression
*expr
)
431 return _get_value(expr
, NULL
, IMPLIED
);
434 int is_zero(struct expression
*expr
)
436 if (get_value(expr
) == 0)
441 int is_array(struct expression
*expr
)
443 expr
= strip_expr(expr
);
444 if (expr
->type
!= EXPR_PREOP
|| strcmp(show_special(expr
->op
), "*"))
447 if (strcmp(show_special(expr
->op
), "+"))
452 struct expression
*get_array_name(struct expression
*expr
)
456 return expr
->unop
->left
;
459 struct expression
*get_array_offset(struct expression
*expr
)
463 return expr
->unop
->right
;
466 const char *show_state(struct smatch_state
*state
)
473 struct statement
*get_block_thing(struct expression
*expr
)
475 /* What are those things called? if (({....; ret;})) { ...*/
477 if (expr
->type
!= EXPR_PREOP
)
481 if (expr
->unop
->type
!= EXPR_STATEMENT
)
483 if (expr
->unop
->statement
->type
!= STMT_COMPOUND
)
485 return expr
->unop
->statement
;
488 struct expression
*strip_expr(struct expression
*expr
)
495 return strip_expr(expr
->cast_expression
);
497 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
498 expr
->unop
->statement
->type
== STMT_COMPOUND
)
501 return strip_expr(expr
->unop
);
506 static void delete_state_tracker(struct tracker
*t
)
508 delete_state(t
->owner
, t
->name
, t
->sym
);
512 void scoped_state(const char *name
, int my_id
, struct symbol
*sym
)
516 t
= alloc_tracker(my_id
, name
, sym
);
517 add_scope_hook((scope_hook
*)&delete_state_tracker
, t
);