symbol.h: let is_ptr_type() take NULL pointers
[smatch.git] / smatch_expressions.c
blob8e57401e44aaf457cd09ab47b94293e25c2ea2ee
1 #include "smatch.h"
3 __ALLOCATOR(struct expression, "temporary expr", tmp_expression);
5 static struct position get_cur_pos(void)
7 static struct position pos;
8 static struct position none;
9 struct expression *expr;
10 struct statement *stmt;
12 expr = last_ptr_list((struct ptr_list *)big_expression_stack);
13 stmt = last_ptr_list((struct ptr_list *)big_statement_stack);
14 if (expr)
15 pos = expr->pos;
16 else if (stmt)
17 pos = stmt->pos;
18 else
19 pos = none;
20 return pos;
23 struct expression *alloc_tmp_expression(struct position pos, int type)
25 struct expression *expr = __alloc_tmp_expression(0);
26 expr->type = type;
27 expr->pos = pos;
28 return expr;
31 void free_tmp_expressions(void)
33 clear_tmp_expression_alloc();
36 struct expression *zero_expr(void)
38 static struct expression *zero;
40 if (zero)
41 return zero;
43 zero = alloc_expression(get_cur_pos(), EXPR_VALUE);
44 zero->value = 0;
45 zero->ctype = &char_ctype;
46 return zero;
49 struct expression *value_expr(long long val)
51 struct expression *expr;
53 if (!val)
54 return zero_expr();
56 expr = alloc_tmp_expression(get_cur_pos(), EXPR_VALUE);
57 expr->value = val;
58 expr->ctype = &llong_ctype;
59 return expr;
62 struct expression *member_expression(struct expression *deref, int op, struct ident *member)
64 struct expression *expr;
66 expr = alloc_tmp_expression(deref->pos, EXPR_DEREF);
67 expr->op = op;
68 expr->deref = deref;
69 expr->member = member;
70 expr->member_offset = -1;
71 return expr;
74 struct expression *deref_expression(struct expression *expr)
76 struct expression *preop;
78 preop = alloc_tmp_expression(expr->pos, EXPR_PREOP);
79 preop->unop = expr;
80 preop->op = '*';
81 return preop;
84 struct expression *assign_expression(struct expression *left, struct expression *right)
86 struct expression *expr;
88 expr = alloc_tmp_expression(right->pos, EXPR_ASSIGNMENT);
89 expr->op = '=';
90 expr->left = left;
91 expr->right = right;
92 return expr;
95 struct expression *binop_expression(struct expression *left, int op, struct expression *right)
97 struct expression *expr;
99 expr = alloc_tmp_expression(right->pos, EXPR_BINOP);
100 expr->op = op;
101 expr->left = left;
102 expr->right = right;
103 return expr;
106 struct expression *array_element_expression(struct expression *array, struct expression *offset)
108 struct expression *expr;
110 expr = binop_expression(array, '+', offset);
111 return deref_expression(expr);
114 struct expression *symbol_expression(struct symbol *sym)
116 struct expression *expr;
118 expr = alloc_tmp_expression(sym->pos, EXPR_SYMBOL);
119 expr->symbol = sym;
120 expr->symbol_name = sym->ident;
121 return expr;
124 struct expression *compare_expression(struct expression *left, int op, struct expression *right)
126 struct expression *expr;
128 expr = alloc_tmp_expression(get_cur_pos(), EXPR_COMPARE);
129 expr->op = op;
130 expr->left = left;
131 expr->right = right;
132 return expr;
135 struct expression *gen_expression_from_key(struct expression *arg, const char *key)
137 struct expression *ret = NULL;
138 struct token *token, *end;
139 const char *p = key;
140 char buf[4095];
141 char *alloc;
142 size_t len;
144 /* The idea is that we can parse either $0->foo or $->foo */
145 if (key[0] != '$')
146 goto free;
147 p++;
148 while (*p >= '0' && *p <= '9')
149 p++;
150 len = snprintf(buf, sizeof(buf), "%s\n", p);
151 alloc = alloc_string(buf);
153 token = tokenize_buffer(alloc, len, &end);
154 if (!token)
155 goto free;
156 if (token_type(token) != TOKEN_STREAMBEGIN)
157 goto free;
158 token = token->next;
160 ret = arg;
161 while (token_type(token) == TOKEN_SPECIAL &&
162 token->special == SPECIAL_DEREFERENCE) {
163 token = token->next;
164 if (token_type(token) != TOKEN_IDENT) {
165 ret = NULL;
166 goto free;
168 ret = deref_expression(ret);
169 ret = member_expression(ret, '*', token->ident);
170 token = token->next;
173 if (token_type(token) != TOKEN_STREAMEND)
174 ret = NULL;
176 free:
177 return ret;