📄 toplev.c
字号:
}/* Output a file name in the form wanted by System V. */voidoutput_file_directive (asm_file, input_name) FILE *asm_file; char *input_name;{ int len = strlen (input_name); char *na = input_name + len; /* NA gets INPUT_NAME sans directory names. */ while (na > input_name) { if (na[-1] == '/') break; na--; }#ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na);#else#ifdef ASM_OUTPUT_SOURCE_FILENAME ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);#else fprintf (asm_file, "\t.file\t\"%s\"\n", na);#endif#endif}/* Compile an entire file of output from cpp, named NAME. Write a file of assembly output and various debugging dumps. */static voidcompile_file (name) char *name;{ tree globals; int start_time; int dump_base_name_length; int name_specified = name != 0; if (dump_base_name == 0) dump_base_name = name ? name : "gccdump"; dump_base_name_length = strlen (dump_base_name); parse_time = 0; varconst_time = 0; integration_time = 0; jump_time = 0; cse_time = 0; loop_time = 0; cse2_time = 0; flow_time = 0; combine_time = 0; sched_time = 0; local_alloc_time = 0; global_alloc_time = 0; sched2_time = 0; dbr_sched_time = 0; shorten_branch_time = 0; stack_reg_time = 0; final_time = 0; symout_time = 0; dump_time = 0; /* Open input file. */ if (name == 0 || !strcmp (name, "-")) { finput = stdin; name = "stdin"; } else finput = fopen (name, "r"); if (finput == 0) pfatal_with_name (name);#ifdef IO_BUFFER_SIZE setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);#endif /* Initialize data in various passes. */ init_obstacks (); init_tree_codes (); init_lex (); init_rtl (); init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL || debug_info_level == DINFO_LEVEL_VERBOSE); init_decl_processing (); init_optabs (); init_stmt (); init_expmed (); init_expr_once (); init_loop (); init_reload (); if (flag_caller_saves) init_caller_save (); /* If auxiliary info generation is desired, open the output file. This goes in the same directory as the source file--unlike all the other output files. */ if (flag_gen_aux_info) { aux_info_file = fopen (aux_info_file_name, "w"); if (aux_info_file == 0) pfatal_with_name (aux_info_file_name); } /* If rtl dump desired, open the output file. */ if (rtl_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); strcpy (dumpname, dump_base_name); strcat (dumpname, ".rtl"); rtl_dump_file = fopen (dumpname, "w"); if (rtl_dump_file == 0) pfatal_with_name (dumpname); } /* If jump_opt dump desired, open the output file. */ if (jump_opt_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); strcpy (dumpname, dump_base_name); strcat (dumpname, ".jump"); jump_opt_dump_file = fopen (dumpname, "w"); if (jump_opt_dump_file == 0) pfatal_with_name (dumpname); } /* If cse dump desired, open the output file. */ if (cse_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); strcpy (dumpname, dump_base_name); strcat (dumpname, ".cse"); cse_dump_file = fopen (dumpname, "w"); if (cse_dump_file == 0) pfatal_with_name (dumpname); } /* If loop dump desired, open the output file. */ if (loop_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); strcpy (dumpname, dump_base_name); strcat (dumpname, ".loop"); loop_dump_file = fopen (dumpname, "w"); if (loop_dump_file == 0) pfatal_with_name (dumpname); } /* If cse2 dump desired, open the output file. */ if (cse2_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); strcpy (dumpname, dump_base_name); strcat (dumpname, ".cse2"); cse2_dump_file = fopen (dumpname, "w"); if (cse2_dump_file == 0) pfatal_with_name (dumpname); } /* If flow dump desired, open the output file. */ if (flow_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); strcpy (dumpname, dump_base_name); strcat (dumpname, ".flow"); flow_dump_file = fopen (dumpname, "w"); if (flow_dump_file == 0) pfatal_with_name (dumpname); } /* If combine dump desired, open the output file. */ if (combine_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 10); strcpy (dumpname, dump_base_name); strcat (dumpname, ".combine"); combine_dump_file = fopen (dumpname, "w"); if (combine_dump_file == 0) pfatal_with_name (dumpname); } /* If scheduling dump desired, open the output file. */ if (sched_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); strcpy (dumpname, dump_base_name); strcat (dumpname, ".sched"); sched_dump_file = fopen (dumpname, "w"); if (sched_dump_file == 0) pfatal_with_name (dumpname); } /* If local_reg dump desired, open the output file. */ if (local_reg_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); strcpy (dumpname, dump_base_name); strcat (dumpname, ".lreg"); local_reg_dump_file = fopen (dumpname, "w"); if (local_reg_dump_file == 0) pfatal_with_name (dumpname); } /* If global_reg dump desired, open the output file. */ if (global_reg_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); strcpy (dumpname, dump_base_name); strcat (dumpname, ".greg"); global_reg_dump_file = fopen (dumpname, "w"); if (global_reg_dump_file == 0) pfatal_with_name (dumpname); } /* If 2nd scheduling dump desired, open the output file. */ if (sched2_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 8); strcpy (dumpname, dump_base_name); strcat (dumpname, ".sched2"); sched2_dump_file = fopen (dumpname, "w"); if (sched2_dump_file == 0) pfatal_with_name (dumpname); } /* If jump2_opt dump desired, open the output file. */ if (jump2_opt_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); strcpy (dumpname, dump_base_name); strcat (dumpname, ".jump2"); jump2_opt_dump_file = fopen (dumpname, "w"); if (jump2_opt_dump_file == 0) pfatal_with_name (dumpname); } /* If dbr_sched dump desired, open the output file. */ if (dbr_sched_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); strcpy (dumpname, dump_base_name); strcat (dumpname, ".dbr"); dbr_sched_dump_file = fopen (dumpname, "w"); if (dbr_sched_dump_file == 0) pfatal_with_name (dumpname); }#ifdef STACK_REGS /* If stack_reg dump desired, open the output file. */ if (stack_reg_dump) { register char *dumpname = (char *) xmalloc (dump_base_name_length + 10); strcpy (dumpname, dump_base_name); strcat (dumpname, ".stack"); stack_reg_dump_file = fopen (dumpname, "w"); if (stack_reg_dump_file == 0) pfatal_with_name (dumpname); }#endif /* Open assembler code output file. */ if (! name_specified && asm_file_name == 0) asm_out_file = stdout; else { register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); int len = strlen (dump_base_name); strcpy (dumpname, dump_base_name); strip_off_ending (dumpname, len); strcat (dumpname, ".s"); if (asm_file_name == 0) { asm_file_name = (char *) xmalloc (strlen (dumpname) + 1); strcpy (asm_file_name, dumpname); } if (!strcmp (asm_file_name, "-")) asm_out_file = stdout; else asm_out_file = fopen (asm_file_name, "w"); if (asm_out_file == 0) pfatal_with_name (asm_file_name); }#ifdef IO_BUFFER_SIZE setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);#endif input_filename = name; /* Perform language-specific initialization. This may set main_input_filename. */ lang_init (); /* If the input doesn't start with a #line, use the input name as the official input file name. */ if (main_input_filename == 0) main_input_filename = name; /* Put an entry on the input file stack for the main input file. */ input_file_stack = (struct file_stack *) xmalloc (sizeof (struct file_stack)); input_file_stack->next = 0; input_file_stack->name = input_filename; ASM_FILE_START (asm_out_file); /* Output something to inform GDB that this compilation was by GCC. */#ifndef ASM_IDENTIFY_GCC fprintf (asm_out_file, "gcc2_compiled.:\n");#else ASM_IDENTIFY_GCC (asm_out_file);#endif /* Don't let the first function fall at the same address as gcc_compiled., if profiling. */ if (profile_flag || profile_block_flag) assemble_zeros (UNITS_PER_WORD); /* If dbx symbol table desired, initialize writing it and output the predefined types. */#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename, getdecls ()));#endif#ifdef SDB_DEBUGGING_INFO if (write_symbols == SDB_DEBUG) TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename, getdecls ()));#endif#ifdef DWARF_DEBUGGING_INFO if (write_symbols == DWARF_DEBUG) TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename));#endif /* Initialize yet another pass. */ init_final (main_input_filename); start_time = get_run_time (); /* Call the parser, which parses the entire file (calling rest_of_compilation for each function). */ if (yyparse () != 0) if (errorcount == 0) fprintf (stderr, "Errors detected in input file (your bison.simple is out of date)"); /* Compilation is now finished except for writing what's left of the symbol table output. */ parse_time += get_run_time () - start_time; parse_time -= integration_time; parse_time -= varconst_time; globals = getdecls (); /* Really define vars that have had only a tentative definition. Really output inline functions that must actually be callable and have not been output so far. */ { int len = list_length (globals); tree *vec = (tree *) alloca (sizeof (tree) * len); int i; tree decl; /* Process the decls in reverse order--earliest first. Put them into VEC from back to front, then take out from front. */ for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl)) vec[len - i - 1] = decl; for (i = 0; i < len; i++) { decl = vec[i]; if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) && ! TREE_ASM_WRITTEN (decl)) { /* Don't write out static consts, unless we used them. (This used to write them out only if the address was taken, but that was wrong; if the variable was simply referred to, it still needs to exist or else it will be undefined in the linker.) */ if (! TREE_READONLY (decl) || TREE_PUBLIC (decl) || TREE_USED (decl) || TREE_ADDRESSABLE (decl) || TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (decl))) rest_of_decl_compilation (decl, NULL_PTR, 1, 1); else /* Cancel the RTL for this decl so that, if debugging info output for global variables is still to come, this one will be omitted. */ DECL_RTL (decl) = NULL; } if (TREE_CODE (decl) == FUNCTION_DECL && ! TREE_ASM_WRITTEN (decl) && DECL_INITIAL (decl) != 0 && (TREE_ADDRESSABLE (decl) || TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (decl))) && ! DECL_EXTERNAL (decl)) output_inline_function (decl); /* Warn about any function declared static but not defined. We don't warn about variables, because many programs have static variables that exist only to get some text into the object file. */ if ((warn_unused || TREE_USED (decl) || (DECL_NAME (decl) && TREE_USED (DECL_NAME (decl)))) && TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl) == 0 && DECL_EXTERNAL (decl) && ! TREE_PUBLIC (decl)) warning_with_decl (decl, "`%s' declared `static' but never defined"); /* Warn about static fns or vars defined but not used, but not about inline functions since unused inline statics is normal practice. */ if (warn_unused && (TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL) && ! DECL_IN_SYSTEM_HEADER (decl) && ! DECL_EXTERNAL (decl) && ! TREE_PUBLIC (decl) && ! TREE_USED (decl) && ! DECL_INLINE (decl) /* The TREE_USED bit for file-scope decls is kept in the identifier, to handle multiple external decls in different scopes. */ && ! TREE_USED (DECL_NAME (decl))) warning_with_decl (decl, "`%s' defined but not used");#ifdef SDB_DEBUGGING_INFO /* The COFF linker can move initialized global vars to the end. And that can screw up the symbol ordering. By putting the symbols in that order to begin with, we avoid a problem. mcsun!unido!fauern!tumuc!pes@uunet.uu.net. */ if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL && TREE_PUBLIC (decl) && DECL_INITIAL (decl) && DECL_RTL (decl) != 0) TIMEVAR (symout_time, sdbout_symbol (decl, 0)); /* Output COFF information for non-global file-scope initialized variables. */ if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl) && DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == MEM) TIMEVAR (symout_time, sdbout_toplevel_data (decl));#endif /* SDB_DEBUGGING_INFO */#ifdef DWARF_DEBUGGING_INFO /* Output DWARF information for file-scope tentative data object declarations, file-scope (extern) function declarations (which had no corresponding body) and file-scope tagged type declarations and definitions which have not yet been forced out. */ if (write_symbols == DWARF_DEBUG && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))) TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));#endif } } /* Do dbx symbols */#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -