dma_on_stack: &foo means it's an error too
[smatch.git] / smatch_type.c
blobacfd29b347326fd13831523487a1a547c10a72d9
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_expr(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_BINOP:
91 if (expr->op != '+')
92 return NULL;
93 tmp = get_type(expr->left);
94 if (!tmp || (tmp->type != SYM_ARRAY && tmp->type != SYM_PTR))
95 return NULL;
96 return get_base_type(tmp);
97 case EXPR_CALL:
98 return get_return_type(expr);
99 // default:
100 // sm_msg("unhandled type %d", expr->type);
104 return NULL;