/************************************ gcc/main.c *****************************************/ /* main.c: defines main() for cc1, cc1plus, etc. Copyright (C) 2007 Free Software Foundation, Inc. . */ /* We define main() to call toplev_main(), which is defined in toplev.c. We do this in a separate file in order to allow the language front-end to define a different main(), if it so desires. */ int main (int argc, char **argv) { return toplev_main (argc, (const char **) argv); } /************************************ toplev.c *****************************************/ /* Entry point of cc1, cc1plus, jc1, f771, etc. Exit code is FATAL_EXIT_CODE if can't open files or if there were any errors, or SUCCESS_EXIT_CODE if compilation succeeded. It is not safe to call this function more than once. */ int toplev_main (unsigned int argc, const char **argv) { decode_options (argc, argv); /* Exit early if we can (e.g. -help). */ if (!exit_after_options) do_compile (); } /* Initialize the compiler, and compile the input file. */ static void do_compile (void) { if (!errorcount) { /* Language-dependent initialization. Returns true on success. */ if (lang_dependent_init (main_input_filename)) compile_file (); finalize (); } } /* Compile an entire translation unit. Write a file of assembly output and various debugging dumps. */ static void compile_file (void) { /* Initialize yet another pass. */ ggc_protect_identifiers = true; init_cgraph (); /* Call the parser, which parses the entire file (calling rest_of_compilation for each function). */ lang_hooks.parse_file (set_yydebug); /* Compilation is now finished except for writing what's left of the symbol table output. */ lang_hooks.decls.final_write_globals (); varpool_assemble_pending_decls (); finish_aliases_2 (); /* Flush any pending external directives. */ process_pending_assemble_externals (); /* This must be at the end. Some target ports emit end of file directives into the assembly file here, and hence we can not output anything to the assembly file after this point. */ targetm.asm_out.file_end (); } /********************************* c-objc-common.h *********************************/ /* Lang hooks that are shared between C and ObjC are defined here. Hooks specific to C or ObjC go in c-lang.c and objc/objc-lang.c, respectively. */ #define LANG_HOOKS_FINISH c_common_finish #define LANG_HOOKS_EXPAND_EXPR c_expand_expr #define LANG_HOOKS_PARSE_FILE c_common_parse_file /********************************* c-opts.c *********************************/ /* Initialize the integrated preprocessor after debug output has been initialized; loop over each input file. */ void c_common_parse_file (int set_yydebug) { i = 0; for (;;) { push_file_scope (); c_parse_file (); finish_file (); pop_file_scope (); } } void pop_file_scope (void) { cgraph_finalize_compilation_unit (); } /********************************* c-parser.c *********************************/ /* Parse a single source file. */ void c_parse_file (void) { c_parser_translation_unit (the_parser); } /* Parse a translation unit (C90 6.7, C99 6.9). translation-unit: external-declarations external-declarations: external-declaration external-declarations external-declaration GNU extensions: translation-unit: empty */ static void c_parser_translation_unit (c_parser *parser) { do { c_parser_external_declaration (parser); } while (c_parser_next_token_is_not (parser, CPP_EOF)); } static void c_parser_external_declaration (c_parser *parser) { default: decl_or_fndef: /* A declaration or a function definition. We can only tell which after parsing the declaration specifiers, if any, and the first declarator. */ c_parser_declaration_or_fndef (parser, true, true, false, true); } /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99 6.7, 6.9.1). If FNDEF_OK is true, a function definition is declaration: declaration-specifiers init-declarator-list[opt] ; function-definition: declaration-specifiers[opt] declarator declaration-list[opt] compound-statement declaration-list: declaration declaration-list declaration init-declarator-list: init-declarator init-declarator-list , init-declarator init-declarator: declarator simple-asm-expr[opt] attributes[opt] declarator simple-asm-expr[opt] attributes[opt] = initializer GNU extensions: nested-function-definition: declaration-specifiers declarator declaration-list[opt] compound-statement */ static void c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok, bool nested, bool start_attr_ok) { finish_function (); } /********************************* c-decl.c *********************************/ /* Finish up a function declaration and compile that function all the way to assembler language output. The free the storage for the function definition. This is called after parsing the body of the function definition. */ void finish_function (void) { /* Genericize before inlining. Delay genericizing nested functions until their parent function is genericized. Since finalizing requires GENERIC, delay that as well. */ { c_genericize (fndecl); cgraph_finalize_function (fndecl, false); } } } /********************************* c-gimplify.c *********************************/ void c_genericize (tree fndecl) { /* Go ahead and gimplify for now. */ gimplify_function_tree (fndecl); } void gimplify_function_tree (tree fndecl) { bind = gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl, true); } gimple gimplify_body (tree *body_p, tree fndecl, bool do_parms) { gimplify_stmt (body_p, &seq); } bool gimplify_stmt (tree *stmt_p, gimple_seq *seq_p) { gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none); } enum gimplify_status gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, bool (*gimple_test_f) (tree), fallback_t fallback) { ret = gimplify_self_mod_expr (expr_p, pre_p, post_p, break; ret = gimplify_compound_lval (expr_p, pre_p, post_p, fallback ? fallback : fb_rvalue); break; ret = gimplify_cond_expr (expr_p, pre_p, fallback); break; ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none); break; ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none); break; ret = gimplify_modify_expr (expr_p, pre_p, post_p, fallback != fb_none); break; ret = gimplify_boolean_expr (expr_p); break; ret = gimplify_addr_expr (expr_p, pre_p, post_p); break; ret = gimplify_va_arg_expr (expr_p, pre_p, post_p); break; ret = gimplify_decl_expr (expr_p, pre_p); break; ret = gimplify_bind_expr (expr_p, pre_p); break; ret = gimplify_loop_expr (expr_p, pre_p); break; ret = gimplify_switch_expr (expr_p, pre_p); break; ret = gimplify_exit_expr (expr_p); break; ret = gimplify_case_label_expr (expr_p, pre_p); break; case RETURN_EXPR: ret = gimplify_return_expr (*expr_p, pre_p); break; ret = gimplify_save_expr (expr_p, pre_p, post_p); break; ret = gimplify_asm_expr (expr_p, pre_p, post_p); break; ret = gimplify_cleanup_point_expr (expr_p, pre_p); break; ret = gimplify_target_expr (expr_p, pre_p, post_p); break; ret = gimplify_statement_list (expr_p, pre_p); break; ret = gimplify_var_or_parm_decl (expr_p); break; return ret; } /***************************** Comment in passes.c **************************/ /* Construct the pass tree. The sequencing of passes is driven by the cgraph routines: cgraph_finalize_compilation_unit () for each node N in the cgraph cgraph_analyze_function (N) cgraph_lower_function (N) -> all_lowering_passes If we are optimizing, cgraph_optimize is then invoked: cgraph_optimize () ipa_passes () -> all_ipa_passes cgraph_expand_all_functions () for each node N in the cgraph cgraph_expand_function (N) tree_rest_of_compilation (DECL (N)) -> all_passes execute_pass_list */