expressions: make assign_expression() take an op argument
[smatch.git] / smatch_expressions.c
blob201f9910ae1f3f2f0af686db8c2d91bd412b7180
1 #include "smatch.h"
2 #include "smatch_extra.h"
4 __ALLOCATOR(struct expression, "temporary expr", tmp_expression);
6 static struct position get_cur_pos(void)
8 static struct position pos;
9 static struct position none;
10 struct expression *expr;
11 struct statement *stmt;
13 expr = last_ptr_list((struct ptr_list *)big_expression_stack);
14 stmt = last_ptr_list((struct ptr_list *)big_statement_stack);
15 if (expr)
16 pos = expr->pos;
17 else if (stmt)
18 pos = stmt->pos;
19 else
20 pos = none;
21 return pos;
24 struct expression *alloc_tmp_expression(struct position pos, int type)
26 struct expression *expr;
28 expr = __alloc_tmp_expression(0);
29 expr->smatch_flags |= Fake;
30 expr->type = type;
31 expr->pos = pos;
32 return expr;
35 void free_tmp_expressions(void)
37 clear_tmp_expression_alloc();
40 struct expression *zero_expr(void)
42 struct expression *zero;
44 zero = alloc_tmp_expression(get_cur_pos(), EXPR_VALUE);
45 zero->value = 0;
46 zero->ctype = &int_ctype;
47 return zero;
50 struct expression *value_expr(long long val)
52 struct expression *expr;
54 if (!val)
55 return zero_expr();
57 expr = alloc_tmp_expression(get_cur_pos(), EXPR_VALUE);
58 expr->value = val;
59 expr->ctype = &llong_ctype;
60 return expr;
63 struct expression *member_expression(struct expression *deref, int op, struct ident *member)
65 struct expression *expr;
67 expr = alloc_tmp_expression(deref->pos, EXPR_DEREF);
68 expr->op = op;
69 expr->deref = deref;
70 expr->member = member;
71 expr->member_offset = -1;
72 return expr;
75 struct expression *deref_expression(struct expression *expr)
77 struct expression *preop;
79 preop = alloc_tmp_expression(expr->pos, EXPR_PREOP);
80 preop->unop = expr;
81 preop->op = '*';
82 return preop;
85 struct expression *assign_expression(struct expression *left, int op, struct expression *right)
87 struct expression *expr;
89 expr = alloc_tmp_expression(right->pos, EXPR_ASSIGNMENT);
90 expr->op = op;
91 expr->left = left;
92 expr->right = right;
93 return expr;
96 struct expression *binop_expression(struct expression *left, int op, struct expression *right)
98 struct expression *expr;
100 expr = alloc_tmp_expression(right->pos, EXPR_BINOP);
101 expr->op = op;
102 expr->left = left;
103 expr->right = right;
104 return expr;
107 struct expression *array_element_expression(struct expression *array, struct expression *offset)
109 struct expression *expr;
111 expr = binop_expression(array, '+', offset);
112 return deref_expression(expr);
115 struct expression *symbol_expression(struct symbol *sym)
117 struct expression *expr;
119 expr = alloc_tmp_expression(sym->pos, EXPR_SYMBOL);
120 expr->symbol = sym;
121 expr->symbol_name = sym->ident;
122 return expr;
125 struct expression *compare_expression(struct expression *left, int op, struct expression *right)
127 struct expression *expr;
129 expr = alloc_tmp_expression(get_cur_pos(), EXPR_COMPARE);
130 expr->op = op;
131 expr->left = left;
132 expr->right = right;
133 return expr;
136 struct expression *gen_expression_from_key(struct expression *arg, const char *key)
138 struct expression *ret;
139 struct token *token, *end;
140 const char *p = key;
141 char buf[4095];
142 char *alloc;
143 size_t len;
145 /* The idea is that we can parse either $0->foo or $->foo */
146 if (key[0] != '$')
147 return NULL;
148 p++;
149 while (*p >= '0' && *p <= '9')
150 p++;
151 len = snprintf(buf, sizeof(buf), "%s\n", p);
152 alloc = alloc_string(buf);
154 token = tokenize_buffer(alloc, len, &end);
155 if (!token)
156 return NULL;
157 if (token_type(token) != TOKEN_STREAMBEGIN)
158 return NULL;
159 token = token->next;
161 ret = arg;
162 while (token_type(token) == TOKEN_SPECIAL &&
163 token->special == SPECIAL_DEREFERENCE) {
164 token = token->next;
165 if (token_type(token) != TOKEN_IDENT)
166 return NULL;
167 ret = deref_expression(ret);
168 ret = member_expression(ret, '*', token->ident);
169 token = token->next;
172 if (token_type(token) != TOKEN_STREAMEND)
173 return NULL;
175 return ret;
178 void expr_set_parent_expr(struct expression *expr, struct expression *parent)
180 if (!expr)
181 return;
182 if (parent->smatch_flags & Fake)
183 return;
185 expr->parent = (unsigned long)parent | 0x1UL;
188 void expr_set_parent_stmt(struct expression *expr, struct statement *parent)
190 if (!expr)
191 return;
192 expr->parent = (unsigned long)parent;
195 struct expression *expr_get_parent_expr(struct expression *expr)
197 if (!expr)
198 return NULL;
199 if (!(expr->parent & 0x1UL))
200 return NULL;
201 return (struct expression *)(expr->parent & ~0x1UL);
204 struct statement *expr_get_parent_stmt(struct expression *expr)
206 if (!expr)
207 return NULL;
208 if (expr->parent & 0x1UL)
209 return NULL;
210 return (struct statement *)expr->parent;