diff options
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 74 |
1 files changed, 68 insertions, 6 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 0c7e80e13c5..050ee84eaba 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see #include "pointer-set.h" #include "plugin.h" #include "c-family/c-ada-spec.h" +#include "cilk.h" /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context @@ -640,7 +641,8 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible, b->shadowed = 0; b->decl = decl; b->id = name; - b->depth = scope->depth; + if (scope) + b->depth = scope->depth; b->invisible = invisible; b->nested = nested; b->inner_comp = 0; @@ -649,8 +651,11 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible, b->u.type = NULL; - b->prev = scope->bindings; - scope->bindings = b; + if (scope) + { + b->prev = scope->bindings; + scope->bindings = b; + } if (decl_jump_unsafe (decl)) scope->has_jump_unsafe_decl = 1; @@ -678,9 +683,11 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible, /* Locate the appropriate place in the chain of shadowed decls to insert this binding. Normally, scope == current_scope and this does nothing. */ - while (*here && (*here)->depth > scope->depth) - here = &(*here)->shadowed; - + if (scope) + { + while (*here && (*here)->depth > scope->depth) + here = &(*here)->shadowed; + } b->shadowed = *here; *here = b; } @@ -1119,6 +1126,11 @@ pop_scope (void) if (TREE_USED (p) && !DECL_INITIAL (p)) { error ("label %q+D used but not defined", p); + if (flag_enable_cilk) + { + fnotice(stderr, "compliation terminated due to errors.\n"); + exit(ICE_EXIT_CODE); + } DECL_INITIAL (p) = error_mark_node; } else @@ -10142,4 +10154,54 @@ c_register_addr_space (const char *word, addr_space_t as) ridpointers [rid] = id; } +/* This function will make the appropriate Frames needed for a Cilk spawn + * call + */ +tree +c_make_cilk_frame (void) +{ + tree decl = cfun->cilk_frame_decl; + tree addr, body, ctor, dtor, orig_body; + tree enter_begin, enter_end; + gcc_assert (flag_enable_cilk); + + if (decl == NULL_TREE) + { + tree *saved_tree = &DECL_SAVED_TREE (current_function_decl); + decl = make_cilk_frame (current_function_decl); + + add_local_decl (cfun, decl); + addr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, decl); + ctor = build_call_expr (cilk_enter_fndecl, 1, addr); + dtor = build_cilk_function_exit (decl, false, true); + + enter_begin = build_call_expr (cilk_enter_begin_fndecl, 1, addr); + enter_end = build_call_expr (cilk_enter_end_fndecl, 1, addr); + + + /* The new body will be + ctor + try old body finally dtor + */ + body = alloc_stmt_list (); + orig_body = *saved_tree; + /* Some inner block has a chain pointing to orig_body. + orig_body must point to the new body and remain as + a separate statement list. */ + gcc_assert (TREE_CODE (orig_body) == STATEMENT_LIST); + append_to_statement_list_force (enter_begin , &body); + append_to_statement_list_force (ctor, &body); + append_to_statement_list_force (enter_end, &body); + + append_to_statement_list_force (build_stmt (UNKNOWN_LOCATION, + TRY_FINALLY_EXPR, + orig_body, dtor), + &body); + TREE_CHAIN (orig_body) = body; + *saved_tree = body; + } + return decl; +} + + #include "gt-c-decl.h" |