2
|
1 static void
|
|
2 cbc_finish_labeled_goto (location_t loc,
|
|
3 tree label, tree retval)
|
|
4 {
|
|
5 tree tlab;
|
|
6 tree cond;
|
|
7
|
|
8 tree cstmt = c_begin_compound_stmt (true);
|
|
9
|
|
10 tlab = define_label (loc, label);
|
|
11 gcc_assert (tlab);
|
|
12 decl_attributes (&tlab, NULL_TREE, 0);
|
|
13 add_stmt (build_stmt (LABEL_EXPR, tlab));
|
|
14
|
|
15 tree ret = c_finish_return (retval);
|
|
16 TREE_USED(ret) = 1;
|
|
17
|
|
18 cond = integer_zero_node;
|
|
19 tree if_body = c_end_compound_stmt (cstmt, true);
|
|
20 TREE_SIDE_EFFECTS (cstmt) = 1;
|
|
21 c_finish_if_stmt (loc, cond, if_body, NULL_TREE, false);
|
|
22 }
|
|
23
|
|
24
|
|
25 static tree
|
|
26 cbc_finish_nested_function (location_t loc,
|
|
27 tree label, tree retval_decl)
|
|
28 {
|
|
29
|
|
30 tree fnbody;
|
|
31 tree _retval_decl, _envp_decl;
|
|
32 struct c_declarator *declarator;
|
|
33 tree ident;
|
|
34 struct c_arg_info *args;
|
|
35 struct c_declspecs *specs;
|
|
36 struct c_typespec t;
|
|
37 {
|
|
38 push_scope ();
|
|
39 declare_parm_level ();
|
|
40 /*tree retval_type = TREE_TYPE(retval_decl);*/
|
|
41
|
|
42 _retval_decl = build_decl (PARM_DECL,
|
|
43 get_identifier ("_retval"),
|
|
44 TREE_TYPE (retval_decl));
|
|
45 DECL_SOURCE_LOCATION (_retval_decl) = loc;
|
|
46 DECL_ARTIFICIAL (_retval_decl) = 1;
|
|
47 DECL_ARG_TYPE (_retval_decl) = TREE_TYPE(retval_decl);
|
|
48 pushdecl (_retval_decl);
|
|
49 finish_decl (_retval_decl, NULL_TREE, NULL_TREE);
|
|
50
|
|
51 _envp_decl = build_decl (PARM_DECL,
|
|
52 get_identifier ("_envp"),
|
|
53 ptr_type_node );
|
|
54 DECL_SOURCE_LOCATION (_envp_decl) = loc;
|
|
55 DECL_ARTIFICIAL (_envp_decl) = 1;
|
|
56 DECL_ARG_TYPE (_envp_decl) = ptr_type_node;
|
|
57 pushdecl (_envp_decl);
|
|
58 finish_decl (_envp_decl, NULL_TREE, NULL_TREE);
|
|
59
|
|
60 args = get_parm_info(false);
|
|
61 pop_scope();
|
|
62 }
|
|
63
|
|
64 t.kind = ctsk_resword;
|
|
65 t.spec = get_identifier("void");
|
|
66 specs = build_null_declspecs();
|
|
67 declspecs_add_type (specs, t);
|
|
68 finish_declspecs (specs);
|
|
69
|
|
70 /* make nested function. */
|
|
71 declarator =
|
|
72 build_id_declarator (
|
|
73 get_identifier ("_cbc_internal_return"));
|
|
74 declarator = build_function_declarator (args, declarator);
|
|
75
|
|
76 c_push_function_context ();
|
|
77
|
|
78 if (!start_function (specs, declarator, NULL_TREE))
|
|
79 {
|
|
80 c_pop_function_context();
|
|
81 gcc_assert (0);
|
|
82 }
|
|
83 store_parm_decls ();
|
|
84
|
|
85
|
|
86 /* start compound statement. */
|
|
87 tree cstmt = c_begin_compound_stmt (true);
|
|
88
|
|
89 add_stmt (build_modify_expr
|
|
90 (loc, retval_decl,
|
|
91 NOP_EXPR, _retval_decl));
|
|
92 tree stmt = c_finish_goto_label (label);
|
|
93
|
|
94 /* end compound statement. */
|
|
95 fnbody = c_end_compound_stmt (cstmt, true);
|
|
96 TREE_SIDE_EFFECTS (cstmt) = 1;
|
|
97
|
|
98 /* finish declaration of nested function. */
|
|
99 tree decl = current_function_decl;
|
|
100 add_stmt (fnbody);
|
|
101 finish_function ();
|
|
102 c_pop_function_context ();
|
|
103
|
|
104 add_stmt (build_stmt (DECL_EXPR, decl));
|
|
105 return decl;
|
|
106
|
|
107 }
|