scope: fix is_outer_stmt()
[smatch.git] / smatch_expressions.c
blobf9c5e275b189d71cfe3afac1f5b36385b09dccaf
1 #include "smatch.h"
2 #include "smatch_extra.h"
4 DECLARE_ALLOCATOR(sname);
5 __ALLOCATOR(struct expression, "temporary expr", tmp_expression);
7 static struct position get_cur_pos(void)
9 static struct position pos;
10 static struct position none;
11 struct expression *expr;
12 struct statement *stmt;
14 expr = last_ptr_list((struct ptr_list *)big_expression_stack);
15 stmt = last_ptr_list((struct ptr_list *)big_statement_stack);
16 if (expr)
17 pos = expr->pos;
18 else if (stmt)
19 pos = stmt->pos;
20 else
21 pos = none;
22 return pos;
25 struct expression *alloc_tmp_expression(struct position pos, int type)
27 struct expression *expr;
29 expr = __alloc_tmp_expression(0);
30 expr->smatch_flags |= Fake;
31 expr->type = type;
32 expr->pos = pos;
33 return expr;
36 void free_tmp_expressions(void)
38 clear_tmp_expression_alloc();
41 struct expression *zero_expr(void)
43 struct expression *zero;
45 zero = alloc_tmp_expression(get_cur_pos(), EXPR_VALUE);
46 zero->value = 0;
47 zero->ctype = &int_ctype;
48 return zero;
51 struct expression *value_expr(long long val)
53 struct expression *expr;
55 if (!val)
56 return zero_expr();
58 expr = alloc_tmp_expression(get_cur_pos(), EXPR_VALUE);
59 expr->value = val;
60 expr->ctype = &llong_ctype;
61 return expr;
64 struct expression *member_expression(struct expression *deref, int op, struct ident *member)
66 struct expression *expr;
68 expr = alloc_tmp_expression(deref->pos, EXPR_DEREF);
69 expr->op = op;
70 expr->deref = deref;
71 expr->member = member;
72 expr->member_offset = -1;
73 return expr;
76 struct expression *preop_expression(struct expression *expr, int op)
78 struct expression *preop;
80 preop = alloc_tmp_expression(expr->pos, EXPR_PREOP);
81 preop->unop = expr;
82 preop->op = op;
83 return preop;
86 struct expression *deref_expression(struct expression *expr)
88 return preop_expression(expr, '*');
91 struct expression *assign_expression(struct expression *left, int op, struct expression *right)
93 struct expression *expr;
95 /* FIXME: make this a tmp expression. */
96 expr = alloc_expression(right->pos, EXPR_ASSIGNMENT);
97 expr->op = op;
98 expr->left = left;
99 expr->right = right;
100 return expr;
103 struct expression *binop_expression(struct expression *left, int op, struct expression *right)
105 struct expression *expr;
107 expr = alloc_tmp_expression(right->pos, EXPR_BINOP);
108 expr->op = op;
109 expr->left = left;
110 expr->right = right;
111 return expr;
114 struct expression *array_element_expression(struct expression *array, struct expression *offset)
116 struct expression *expr;
118 expr = binop_expression(array, '+', offset);
119 return deref_expression(expr);
122 struct expression *symbol_expression(struct symbol *sym)
124 struct expression *expr;
126 expr = alloc_tmp_expression(sym->pos, EXPR_SYMBOL);
127 expr->symbol = sym;
128 expr->symbol_name = sym->ident;
129 return expr;
132 struct expression *compare_expression(struct expression *left, int op, struct expression *right)
134 struct expression *expr;
136 expr = alloc_tmp_expression(get_cur_pos(), EXPR_COMPARE);
137 expr->op = op;
138 expr->left = left;
139 expr->right = right;
140 return expr;
143 struct expression *string_expression(char *str)
145 struct expression *ret;
146 struct string *string;
147 int len;
149 len = strlen(str) + 1;
150 string = (void *)__alloc_sname(4 + len);
151 string->length = len;
152 string->immutable = 0;
153 memcpy(string->data, str, len);
155 ret = alloc_tmp_expression(get_cur_pos(), EXPR_STRING);
156 ret->wide = 0;
157 ret->string = string;
159 return ret;
162 struct expression *gen_expression_from_key(struct expression *arg, const char *key)
164 struct expression *ret;
165 struct token *token, *end;
166 const char *p = key;
167 char buf[4095];
168 char *alloc;
169 size_t len;
171 /* The idea is that we can parse either $0->foo or $->foo */
172 if (key[0] != '$')
173 return NULL;
174 p++;
175 while (*p >= '0' && *p <= '9')
176 p++;
177 len = snprintf(buf, sizeof(buf), "%s\n", p);
178 alloc = alloc_string(buf);
180 token = tokenize_buffer(alloc, len, &end);
181 if (!token)
182 return NULL;
183 if (token_type(token) != TOKEN_STREAMBEGIN)
184 return NULL;
185 token = token->next;
187 ret = arg;
188 while (token_type(token) == TOKEN_SPECIAL &&
189 token->special == SPECIAL_DEREFERENCE) {
190 token = token->next;
191 if (token_type(token) != TOKEN_IDENT)
192 return NULL;
193 ret = deref_expression(ret);
194 ret = member_expression(ret, '*', token->ident);
195 token = token->next;
198 if (token_type(token) != TOKEN_STREAMEND)
199 return NULL;
201 return ret;
204 void expr_set_parent_expr(struct expression *expr, struct expression *parent)
206 if (!expr)
207 return;
208 if (parent->smatch_flags & Fake)
209 return;
211 expr->parent = (unsigned long)parent | 0x1UL;
214 void expr_set_parent_stmt(struct expression *expr, struct statement *parent)
216 if (!expr)
217 return;
218 expr->parent = (unsigned long)parent;
221 struct expression *expr_get_parent_expr(struct expression *expr)
223 if (!expr)
224 return NULL;
225 if (!(expr->parent & 0x1UL))
226 return NULL;
227 return (struct expression *)(expr->parent & ~0x1UL);
230 struct statement *expr_get_parent_stmt(struct expression *expr)
232 if (!expr)
233 return NULL;
234 if (expr->parent & 0x1UL)
235 return NULL;
236 return (struct statement *)expr->parent;