check_unused_ret.c: fix check for local variables
[smatch.git] / smatch_type.c
blobaa9b5f69cc669e4d004f4bb334349c7df8ba8777
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);
26 static struct symbol *get_symbol_from_deref(struct expression *expr)
28 struct ident *member;
29 struct symbol *struct_sym;
30 struct symbol *tmp;
32 if (!expr || expr->type != EXPR_DEREF)
33 return NULL;
35 member = expr->member;
36 struct_sym = get_type(expr->deref);
37 if (!struct_sym) {
38 // sm_msg("could not find struct type");
39 return NULL;
41 if (struct_sym->type == SYM_PTR)
42 struct_sym = get_base_type(struct_sym);
43 FOR_EACH_PTR(struct_sym->symbol_list, tmp) {
44 if (tmp->ident == member)
45 return get_base_type(tmp);
46 } END_FOR_EACH_PTR(tmp);
47 return NULL;
50 static struct symbol *get_return_type(struct expression *expr)
52 struct symbol *tmp;
54 tmp = get_type(expr->fn);
55 if (!tmp)
56 return NULL;
57 return get_base_type(tmp);
60 static struct symbol *fake_pointer_sym(struct expression *expr)
62 struct symbol *sym;
63 struct symbol *base;
65 sym = alloc_symbol(expr->pos, SYM_PTR);
66 expr = expr->unop;
67 base = get_type(expr);
68 if (!base)
69 return NULL;
70 sym->ctype.base_type = base;
71 return sym;
74 struct symbol *get_type(struct expression *expr)
76 struct symbol *tmp;
78 if (!expr)
79 return NULL;
80 expr = strip_expr(expr);
82 switch(expr->type) {
83 case EXPR_SYMBOL:
84 return get_type_symbol(expr);
85 case EXPR_DEREF:
86 return get_symbol_from_deref(expr);
87 case EXPR_PREOP:
88 if (expr->op == '&')
89 return fake_pointer_sym(expr);
90 return get_type(expr->unop);
91 case EXPR_BINOP:
92 if (expr->op != '+')
93 return NULL;
94 tmp = get_type(expr->left);
95 if (!tmp || (tmp->type != SYM_ARRAY && tmp->type != SYM_PTR))
96 return NULL;
97 return get_base_type(tmp);
98 case EXPR_CALL:
99 return get_return_type(expr);
100 // default:
101 // sm_msg("unhandled type %d", expr->type);
105 return NULL;