static void gfc_be_parse_file (void) { gfc_create_decls (); gfc_parse_file (); gfc_generate_constructors (); /* Clear the binding level stack. */ while (!global_bindings_p ()) poplevel (0, 0); /* Finalize all of the globals. Emulated tls lowering needs to see all TLS variables before we call finalize_compilation_unit. The C/C++ front ends manage this by calling decl_rest_of_compilation on each global and static variable as they are seen. The Fortran front end waits until here. */ for (tree decl = getdecls (); decl ; decl = DECL_CHAIN (decl)) rest_of_decl_compilation (decl, true, true); /* Switch to the default tree diagnostics here, because there may be diagnostics before gfc_finish(). */ gfc_diagnostics_finish (); global_decl_processing (); }
tree gfc_finish_block (stmtblock_t * stmtblock) { tree decl; tree expr; tree block; expr = stmtblock->head; if (!expr) expr = build_empty_stmt (); stmtblock->head = NULL_TREE; if (stmtblock->has_scope) { decl = getdecls (); if (decl) { block = poplevel (1, 0, 0); expr = build3_v (BIND_EXPR, decl, expr, block); } else poplevel (0, 0, 0); } return expr; }
static void gfc_write_global_declarations (void) { tree decl; /* Finalize all of the globals. */ for (decl = getdecls(); decl ; decl = DECL_CHAIN (decl)) rest_of_decl_compilation (decl, true, true); write_global_declarations (); }
void c_objc_common_finish_file (void) { if (pch_file) c_common_write_pch (); /* If multiple translation units were built, copy information between them based on linkage rules. */ merge_translation_unit_decls (); cgraph_finalize_compilation_unit (); cgraph_optimize (); if (static_ctors) { tree body = start_cdtor ('I'); for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors)) c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors), NULL_TREE)); finish_cdtor (body); } if (static_dtors) { tree body = start_cdtor ('D'); for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors)) c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors), NULL_TREE)); finish_cdtor (body); } { int flags; FILE *stream = dump_begin (TDI_all, &flags); if (stream) { dump_node (getdecls (), flags & ~TDF_SLIM, stream); dump_end (TDI_all, stream); } } }
void gfc_merge_block_scope (stmtblock_t * block) { tree decl; tree next; gcc_assert (block->has_scope); block->has_scope = 0; /* Remember the decls in this scope. */ decl = getdecls (); poplevel (0, 0, 0); /* Add them to the parent scope. */ while (decl != NULL_TREE) { next = TREE_CHAIN (decl); TREE_CHAIN (decl) = NULL_TREE; pushdecl (decl); decl = next; } }
tree poplevel (int keep, int functionbody) { /* Points to a BLOCK tree node. This is the BLOCK node constructed for the binding level that we are about to exit and which is returned by this routine. */ tree block_node = NULL_TREE; tree decl_chain = getdecls (); tree subblock_chain = current_binding_level->blocks; tree subblock_node; /* If there were any declarations in the current binding level, or if this binding level is a function body, or if there are any nested blocks then create a BLOCK node to record them for the life of this function. */ if (keep || functionbody) block_node = build_block (keep ? decl_chain : 0, subblock_chain, 0, 0); /* Record the BLOCK node just built as the subblock its enclosing scope. */ for (subblock_node = subblock_chain; subblock_node; subblock_node = BLOCK_CHAIN (subblock_node)) BLOCK_SUPERCONTEXT (subblock_node) = block_node; /* Clear out the meanings of the local variables of this level. */ for (subblock_node = decl_chain; subblock_node; subblock_node = DECL_CHAIN (subblock_node)) if (DECL_NAME (subblock_node) != 0) /* If the identifier was used or addressed via a local extern decl, don't forget that fact. */ if (DECL_EXTERNAL (subblock_node)) { if (TREE_USED (subblock_node)) TREE_USED (DECL_NAME (subblock_node)) = 1; if (TREE_ADDRESSABLE (subblock_node)) TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (subblock_node)) = 1; } /* Pop the current level. */ current_binding_level = current_binding_level->level_chain; if (functionbody) /* This is the top level block of a function. */ DECL_INITIAL (current_function_decl) = block_node; else if (current_binding_level == global_binding_level) /* When using gfc_start_block/gfc_finish_block from middle-end hooks, don't add newly created BLOCKs as subblocks of global_binding_level. */ ; else if (block_node) { current_binding_level->blocks = block_chainon (current_binding_level->blocks, block_node); } /* If we did not make a block for the level just exited, any blocks made for inner levels (since they cannot be recorded as subblocks in that level) must be carried forward so they will later become subblocks of something else. */ else if (subblock_chain) current_binding_level->blocks = block_chainon (current_binding_level->blocks, subblock_chain); if (block_node) TREE_USED (block_node) = 1; return block_node; }
/* Output code for start of function; the decl of the function is in PREV_SAVED (as created by tree_code_create_function_prototype), the function is at line number LINENO in file FILENAME. The parameter details are in the lists PARMS. Returns nothing. */ void tree_code_create_function_initial (tree prev_saved, unsigned char* filename, int lineno, struct prod_token_parm_item* parms) { tree fn_decl; tree param_decl; tree next_param; tree first_param; tree parm_decl; tree parm_list; tree resultdecl; struct prod_token_parm_item* this_parm; struct prod_token_parm_item* parm; fn_decl = prev_saved; if (!fn_decl) abort (); /* Output message if not -quiet. */ announce_function (fn_decl); /* This has something to do with forcing output also. */ pushdecl (fn_decl); /* Set current function for error msgs etc. */ current_function_decl = fn_decl; DECL_INITIAL (fn_decl) = error_mark_node; DECL_SOURCE_FILE (fn_decl) = (const char *)filename; DECL_SOURCE_LINE (fn_decl) = lineno; /* Prepare creation of rtl for a new function. */ resultdecl = DECL_RESULT (fn_decl) = build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (TREE_TYPE (fn_decl))); DECL_CONTEXT (DECL_RESULT (fn_decl)) = fn_decl; DECL_SOURCE_FILE (resultdecl) = (const char *)filename; DECL_SOURCE_LINE (resultdecl) = lineno; /* Work out the size. ??? is this needed. */ layout_decl (DECL_RESULT (fn_decl), 0); /* Make the argument variable decls. */ parm_list = NULL_TREE; for (parm = parms; parm; parm = parm->tp.par.next) { parm_decl = build_decl (PARM_DECL, get_identifier ((const char*) (parm->tp.par.variable_name)), get_type_for_numeric_type (parm->type)); /* Some languages have different nominal and real types. */ DECL_ARG_TYPE (parm_decl) = TREE_TYPE (parm_decl); if (!DECL_ARG_TYPE (parm_decl)) abort (); if (!fn_decl) abort (); DECL_CONTEXT (parm_decl) = fn_decl; DECL_SOURCE_FILE (parm_decl) = (const char *)filename; DECL_SOURCE_LINE (parm_decl) = lineno; parm_list = chainon (parm_decl, parm_list); } /* Back into reverse order as the back end likes them. */ parm_list = nreverse (parm_list); DECL_ARGUMENTS (fn_decl) = parm_list; /* Save the decls for use when the args are referred to. */ for (param_decl = DECL_ARGUMENTS (fn_decl), this_parm = parms; param_decl; param_decl = TREE_CHAIN (param_decl), this_parm = this_parm->tp.par.next) { if (!this_parm) abort (); /* Too few. */ *this_parm->tp.par.where_to_put_var_tree = param_decl; } if (this_parm) abort (); /* Too many. */ /* Output the decl rtl (not the rtl for the function code). ???. If the function is not defined in this file, when should you execute this? */ make_decl_rtl (fn_decl, NULL); /* Use filename/lineno from above. */ init_function_start (fn_decl, (const char *)filename, lineno); /* Create rtl for startup code of function, such as saving registers. */ expand_function_start (fn_decl, 0); /* Function.c requires a push at the start of the function. that looks like a bug to me but let's make it happy. */ (*lang_hooks.decls.pushlevel) (0); /* Create rtl for the start of a new scope. */ expand_start_bindings (2); /* Put the parameters into the symbol table. */ for (first_param = param_decl = nreverse (DECL_ARGUMENTS (fn_decl)); param_decl; param_decl = next_param) { next_param = TREE_CHAIN (param_decl); TREE_CHAIN (param_decl) = NULL; /* layout_decl (param_decl, 0); Already done in build_decl tej 13/4/2002. */ pushdecl (param_decl); if (DECL_CONTEXT (param_decl) != current_function_decl) abort (); } /* Store back the PARM_DECL nodes. They appear in the right order. */ DECL_ARGUMENTS (fn_decl) = getdecls (); /* Force it to be output, else may be solely inlined. */ TREE_ADDRESSABLE (fn_decl) = 1; /* Stop -O3 from deleting it. */ TREE_USED (fn_decl) = 1; /* Add a new level to the debugger symbol table. */ (*lang_hooks.decls.pushlevel) (0); /* Create rtl for the start of a new scope. */ expand_start_bindings (0); emit_line_note ((const char *)filename, lineno); /* Output the line number information. */ }