From c5965445004e35ac7eeef47c877457caf5d2f9a0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 30 Jul 2015 13:44:10 +0300 Subject: [PATCH] flow: add a ->parent member to statement structs You know how I have the big_expression_stack but eventually that didn't work and I had to add a ->parent member to the expression struct? This is the same thing except with statements. This lets you find out if you are inside an if statement for example. I have a user for this but it's going to take a while before it's ready to push. For now, I'm just pushing the infrastructure. Signed-off-by: Dan Carpenter --- parse.h | 1 + smatch_flow.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/parse.h b/parse.h index 0c34ec28..bbd83292 100644 --- a/parse.h +++ b/parse.h @@ -47,6 +47,7 @@ enum statement_type { struct statement { enum statement_type type; struct position pos; + struct statement *parent; union { struct /* declaration */ { struct symbol_list *declaration; diff --git a/smatch_flow.c b/smatch_flow.c index f23b4f4e..85492aec 100644 --- a/smatch_flow.c +++ b/smatch_flow.c @@ -145,6 +145,13 @@ static void set_parent(struct expression *expr, struct expression *parent) expr->parent = parent; } +static void set_parent_stmt(struct statement *stmt, struct statement *parent) +{ + if (!stmt) + return; + stmt->parent = parent; +} + int is_assigned_call(struct expression *expr) { struct expression *tmp; @@ -811,6 +818,9 @@ static void split_compound(struct statement *stmt) __push_scope_hooks(); FOR_EACH_PTR(stmt->stmts, next) { + /* just set them all ahead of time */ + set_parent_stmt(next, stmt); + if (cur) { __prev_stmt = prev; __next_stmt = next; @@ -871,6 +881,9 @@ void __split_stmt(struct statement *stmt) split_compound(stmt); break; case STMT_IF: + set_parent_stmt(stmt->if_true, stmt); + set_parent_stmt(stmt->if_false, stmt); + if (known_condition_true(stmt->if_conditional)) { __split_stmt(stmt->if_true); break; @@ -903,6 +916,10 @@ void __split_stmt(struct statement *stmt) __merge_true_states(); break; case STMT_ITERATOR: + set_parent_stmt(stmt->iterator_pre_statement, stmt); + set_parent_stmt(stmt->iterator_statement, stmt); + set_parent_stmt(stmt->iterator_post_statement, stmt); + if (stmt->iterator_pre_condition) handle_pre_loop(stmt); else if (stmt->iterator_post_condition) @@ -913,6 +930,8 @@ void __split_stmt(struct statement *stmt) } break; case STMT_SWITCH: + set_parent_stmt(stmt->switch_statement, stmt); + if (get_value(stmt->switch_expression, &sval)) { split_known_switch(stmt, sval); break; -- 2.11.4.GIT