⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 toplev.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* If stack_reg dump desired, open the output file.  */  if (stack_reg_dump)    stack_reg_dump_file = open_dump_file (dump_base_name, ".stack");#endif  /* Open assembler code output file.  */  if (! name_specified && asm_file_name == 0)    asm_out_file = stdout;  else    {      int len = strlen (dump_base_name);      register char *dumpname = (char *) xmalloc (len + 6);      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;  /* 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;  /* 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;  if (!output_bytecode)    {      ASM_FILE_START (asm_out_file);    }  /* Output something to inform GDB that this compilation was by GCC.  Also     serves to tell GDB file consists of bytecodes. */  if (output_bytecode)    fprintf (asm_out_file, "bc_gcc2_compiled.:\n");  else    {#ifndef ASM_IDENTIFY_GCC      fprintf (asm_out_file, "gcc2_compiled.:\n");#else      ASM_IDENTIFY_GCC (asm_out_file);#endif    }  /* Output something to identify which front-end produced this file. */#ifdef ASM_IDENTIFY_LANGUAGE  ASM_IDENTIFY_LANGUAGE (asm_out_file);#endif  if (output_bytecode)    {      if (profile_flag || profile_block_flag)	error ("profiling not supported in bytecode compilation");    }  else    {      /* ??? Note: There used to be a conditional here	 to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.	 This was to guarantee separation between gcc_compiled. and	 the first function, for the sake of dbx on Suns.	 However, having the extra zero here confused the Emacs	 code for unexec, and might confuse other programs too.	 Therefore, I took out that change.	 In future versions we should find another way to solve	 that dbx problem.  -- rms, 23 May 93.  */            /* 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.  */  if (!output_bytecode)    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)");      /* In case there were missing closebraces,	 get us back to the global binding level.  */      while (! global_bindings_p ())	poplevel (0, 0, 0);    }  /* 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;    int reconsider = 1;    /* 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];	/* We're not deferring this any longer.  */	DECL_DEFER_OUTPUT (decl) = 0;	if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0	    && incomplete_decl_finalize_hook != 0)	  (*incomplete_decl_finalize_hook) (decl);      }    /* Now emit any global variables or functions that we have been putting       off.  We need to loop in case one of the things emitted here       references another one which comes earlier in the list.  */    while (reconsider)      {	reconsider = 0;	for (i = 0; i < len; i++)	  {	    decl = vec[i];	    if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl))	      continue;	    /* Don't write out static consts, unless we still need them.	       We also keep static consts if not optimizing (for debugging).	       ??? They might be better written into the debug information.	       This is possible when using DWARF.	       A language processor that wants static constants to be always	       written out (even if it is not used) is responsible for	       calling rest_of_decl_compilation itself.  E.g. the C front-end	       calls rest_of_decl_compilation from finish_decl.	       One motivation for this is that is conventional in some	       environments to write things like:	           static const char rcsid[] = "... version string ...";	       intending to force the string to be in the executable.	       A language processor that would prefer to have unneeded	       static constants "optimized away" would just defer writing	       them out until here.  E.g. C++ does this, because static	       constants are often defined in header files.	       ??? A tempting alternative (for both C and C++) would be	       to force a constant to be written if and only if it is	       defined in a main file, as opposed to an include file. */	    if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)		&& (! TREE_READONLY (decl)		    || TREE_PUBLIC (decl)		    || !optimize		    || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))	      {		reconsider = 1;		rest_of_decl_compilation (decl, NULL_PTR, 1, 1);	      }	    if (TREE_CODE (decl) == FUNCTION_DECL		&& DECL_INITIAL (decl) != 0		&& DECL_SAVED_INSNS (decl) != 0		&& (flag_keep_inline_functions		    || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))	      {		reconsider = 1;		temporary_allocation ();		output_inline_function (decl);		permanent_allocation (1);	      }	  }      }    for (i = 0; i < len; i++)      {	decl = vec[i];	if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)	    && ! TREE_ASM_WRITTEN (decl))	  /* 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;	/* 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 (TREE_CODE (decl) == FUNCTION_DECL	    && (warn_unused		|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))	    && DECL_INITIAL (decl) == 0	    && DECL_EXTERNAL (decl)	    && ! TREE_PUBLIC (decl))	  {	    pedwarn_with_decl (decl, 			       "`%s' declared `static' but never defined");	    /* This symbol is effectively an "extern" declaration now.  */	    TREE_PUBLIC (decl) = 1;	    assemble_external (decl);	  }	/* Warn about static fns or vars defined but not used,	   but not about inline functions or static consts	   since defining those in header files is normal practice.  */	if (warn_unused	    && ((TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl))		|| (TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl)))	    && ! DECL_IN_SYSTEM_HEADER (decl)	    && ! DECL_EXTERNAL (decl)	    && ! TREE_PUBLIC (decl)	    && ! TREE_USED (decl)	    && ! DECL_REGISTER (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_EXTERNAL (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_EXTERNAL (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      }  }  /* Write out any pending weak symbol declarations.  */  weak_finish ();  /* Do dbx symbols */#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)    TIMEVAR (symout_time,	     {	       dbxout_finish (asm_out_file, main_input_filename);	     });#endif#ifdef DWARF_DEBUGGING_INFO  if (write_symbols == DWARF_DEBUG)    TIMEVAR (symout_time,	     {	       dwarfout_finish ();	     });#endif  /* Output some stuff at end of file if nec.  */  if (!output_bytecode)    {      end_final (main_input_filename);#ifdef ASM_FILE_END      ASM_FILE_END (asm_out_file);#endif    }  /* Language-specific end of compilation actions.  */  lang_finish ();  if (output_bytecode)    bc_write_file (asm_out_file);  /* Close the dump files.  */  if (flag_gen_aux_info)    {      fclose (aux_info_file);      if (errorcount)	unlink (aux_info_file_name);    }  if (rtl_dump)    fclose (rtl_dump_file);  if (jump_opt_dump)    fclose (jump_opt_dump_file);  if (cse_dump)    fclose (cse_dump_file);  if (loop_dump)    fclose (loop_dump_file);  if (cse2_dump)    fclose (cse2_dump_file);  if (flow_dump)    fclose (flow_dump_file);  if (combine_dump)    {      dump_combine_total_stats (combine_dump_file);      fclose (combine_dump_file);    }  if (sched_dump)    fclose (sched_dump_file);  if (local_reg_dump)    fclose (local_reg_dump_file);  if (global_reg_dump)    fclose (global_reg_dump_file);  if (sched2_dump)    fclose (sched2_dump_file);  if (jump2_opt_dump)    fclose (jump2_opt_dump_file);  if (dbr_sched_dump)    fclose (dbr_sched_dump_file);#ifdef STACK_REGS  if (stack_reg_dump)    fclose (stack_reg_dump_file);#endif  /* Close non-debugging input and output files.  Take special care to note     whether fclose returns an error, since the pages might still be on the     buffer chain while the file is open.  */  fclose (finput);  if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0)    fatal_io_error (asm_file_name);  /* Print the times.  */  if (! quiet_flag)    {      fprintf (stderr,"\n");      print_time ("parse", parse_time);      if (!output_bytecode)	{	  print_time ("integration", integration_time);	  print_time ("jump", jump_time);	  print_time ("cse", cse_time);	  print_time ("loop", loop_time);	  print_time ("cse2", cse2_time);	  print_time ("flow", flow_time);	  print_time ("combine", combine_time);	  print_time ("sched", sched_time);	  print_time ("local-alloc", local_alloc_time);	  print_time ("global-alloc", global_alloc_time);	  print_time ("sched2", sched2_time);	  print_time ("dbranch", dbr_sched_time);	  print_time ("shorten-branch", shorten_branch_time);	  print_time ("stack-reg", stack_reg_time);	  print_time ("final", final_time);	  print_time ("varconst", varconst_time);	  print_time ("symout", symout_time);	  print_time ("dump", dump_time);	}    }}/* This is called from various places for FUNCTION_DECL, VAR_DECL,   and TYPE_DECL nodes.   This does nothing for local (non-static) variables.   Otherwise, it sets up the RTL and outputs any assembler code   (label definition, storage allocation and initialization).   DECL is the declaration.  If ASMSPEC is nonzero, it specifies   the assembler symbol name to be used.  TOP_LEVEL is nonzero   if this declaration is not within a function.  */voidrest_of_decl_compilation (decl, asmspec, top_level, at_end)     tree decl;     char *asmspec;     int top_level;     int at_end;{  /* Declarations of variables, and of functions defined elsewhere.  *//* The most obvious approach, to put an #ifndef around where   this macro is used, doesn't work since it's inside a macro call.  */#ifndef ASM_FINISH_DECLARE_OBJECT#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)#endif  /* Forward declarations for nested functions are not "external",     but we need to treat them as if they were.  */  if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)      || TREE_CODE (decl) == FUNCTION_DECL)    TIMEVAR (varconst_time,	     {	       make_decl_rtl (decl, asmspec, top_level);	       /* Initialized extern variable exists to be replaced		  with its value, or represents something that will be		  output in another file.  */	       if (! (TREE_CODE (decl) == VAR_DECL		      && DECL_EXTERNAL (decl) && TREE_READONLY (decl)		      && DECL_INITIAL (decl) != 0		      && DECL_INITIAL (decl) != error_mark_node))		 /* Don't output anything		    when a tentative file-scope definition is seen.		    But at end of compilation, do output code for them.  */		 if (! (! at_end && top_level			&& (DECL_INITIAL (decl) == 0			    || DECL_INITIAL (decl) == error_mark_node)))		   assemble_variable (decl, top_level, at_end, 0);	       if (decl == last_assemble_variable_decl)		 {		   ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,					      top_level, at_end);		 }	     });  else if (DECL_REGISTER (decl) && asmspec != 0)    {      if (decode_reg_name (asmspec) >= 0)	{	  DECL_RTL (decl) = 0;	  make_decl_rtl (decl, asmspec, top_level);	}      else	error ("invalid register name `%s' for register variable", asmspec);    }#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)  else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)	   && TREE_CODE (decl) == TYPE_DECL)    TIMEVAR (symout_time, dbxout_symbol (decl, 0));#endif#ifdef SDB_DEBUGGING_INFO  else if (write_symbols == SDB_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -