toplev.c revision 69460
119370Spst/* Top level of GNU C compiler 219370Spst Copyright (C) 1987, 88, 89, 92-99, 2000 Free Software Foundation, Inc. 398944Sobrien 4130803SmarcelThis file is part of GNU CC. 5130803Smarcel 619370SpstGNU CC is free software; you can redistribute it and/or modify 798944Sobrienit under the terms of the GNU General Public License as published by 819370Spstthe Free Software Foundation; either version 2, or (at your option) 998944Sobrienany later version. 1098944Sobrien 1198944SobrienGNU CC is distributed in the hope that it will be useful, 1298944Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of 1319370SpstMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1498944SobrienGNU General Public License for more details. 1598944Sobrien 1698944SobrienYou should have received a copy of the GNU General Public License 1798944Sobrienalong with GNU CC; see the file COPYING. If not, write to 1819370Spstthe Free Software Foundation, 59 Temple Place - Suite 330, 1998944SobrienBoston, MA 02111-1307, USA. */ 2098944Sobrien 2198944Sobrien/* $FreeBSD: head/contrib/gcc/toplev.c 69460 2000-12-01 10:20:17Z obrien $ */ 2298944Sobrien 2398944Sobrien/* This is the top level of cc1/c++. 2446283Sdfr It parses command args, opens files, invokes the various passes 2519370Spst in the proper order, and counts the time used by each. 2619370Spst Error messages and low-level interface to malloc also handled here. */ 2719370Spst 2819370Spst#include "config.h" 2919370Spst#undef FLOAT /* This is for hpux. They should change hpux. */ 3019370Spst#undef FFS /* Some systems define this in param.h. */ 3119370Spst#include "system.h" 3219370Spst#include <signal.h> 3319370Spst#include <setjmp.h> 3419370Spst 3519370Spst#ifdef HAVE_SYS_RESOURCE_H 36130803Smarcel# include <sys/resource.h> 3719370Spst#endif 3819370Spst 3919370Spst#ifdef HAVE_SYS_TIMES_H 4019370Spst# include <sys/times.h> 4198944Sobrien#endif 42130803Smarcel 43130803Smarcel#include "input.h" 44130803Smarcel#include "tree.h" 45130803Smarcel#include "rtl.h" 46130803Smarcel#include "flags.h" 47130803Smarcel#include "insn-attr.h" 4819370Spst#include "insn-codes.h" 4946283Sdfr#include "insn-config.h" 5046283Sdfr#include "recog.h" 5198944Sobrien#include "defaults.h" 5246283Sdfr#include "output.h" 5398944Sobrien#include "except.h" 5446283Sdfr#include "toplev.h" 5598944Sobrien#include "expr.h" 5646283Sdfr#include "basic-block.h" 5798944Sobrien#include "intl.h" 5846283Sdfr 5946283Sdfr#ifdef DWARF_DEBUGGING_INFO 6046283Sdfr#include "dwarfout.h" 6198944Sobrien#endif 6219370Spst 6398944Sobrien#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) 6446283Sdfr#include "dwarf2out.h" 6598944Sobrien#endif 6619370Spst 6798944Sobrien#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) 6819370Spst#include "dbxout.h" 6998944Sobrien#endif 7046283Sdfr 7198944Sobrien#ifdef SDB_DEBUGGING_INFO 7219370Spst#include "sdbout.h" 7398944Sobrien#endif 7419370Spst 7598944Sobrien#ifdef XCOFF_DEBUGGING_INFO 7619370Spst#include "xcoffout.h" 7798944Sobrien#endif 7819370Spst 7998944Sobrien#ifdef VMS 8019370Spst/* The extra parameters substantially improve the I/O performance. */ 8198944Sobrienstatic FILE * 8219370Spstvms_fopen (fname, type) 8398944Sobrien char * fname; 8498944Sobrien char * type; 8519370Spst{ 8698944Sobrien /* The <stdio.h> in the gcc-vms-1.42 distribution prototypes fopen with two 8798944Sobrien fixed arguments, which matches ANSI's specification but not VAXCRTL's 8819370Spst pre-ANSI implementation. This hack circumvents the mismatch problem. */ 8998944Sobrien FILE *(*vmslib_fopen)() = (FILE *(*)()) fopen; 9098944Sobrien 9119370Spst if (*type == 'w') 9298944Sobrien return (*vmslib_fopen) (fname, type, "mbc=32", 9398944Sobrien "deq=64", "fop=tef", "shr=nil"); 9498944Sobrien else 9598944Sobrien return (*vmslib_fopen) (fname, type, "mbc=32"); 9646283Sdfr} 9798944Sobrien#define fopen vms_fopen 9898944Sobrien#endif /* VMS */ 9998944Sobrien 10098944Sobrien#ifndef DEFAULT_GDB_EXTENSIONS 10198944Sobrien#define DEFAULT_GDB_EXTENSIONS 1 10219370Spst#endif 10398944Sobrien 10498944Sobrien/* If more than one debugging type is supported, you must define 10598944Sobrien PREFERRED_DEBUGGING_TYPE to choose a format in a system-dependent way. 10698944Sobrien 10798944Sobrien This is one long line cause VAXC can't handle a \-newline. */ 10898944Sobrien#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO)) 10919370Spst#ifndef PREFERRED_DEBUGGING_TYPE 11019370SpstYou Lose! You must define PREFERRED_DEBUGGING_TYPE! 11119370Spst#endif /* no PREFERRED_DEBUGGING_TYPE */ 11219370Spst#else /* Only one debugging format supported. Define PREFERRED_DEBUGGING_TYPE 11319370Spst so the following code needn't care. */ 11419370Spst#ifdef DBX_DEBUGGING_INFO 11519370Spst#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG 11619370Spst#endif 11719370Spst#ifdef SDB_DEBUGGING_INFO 11819370Spst#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG 11919370Spst#endif 12098944Sobrien#ifdef DWARF_DEBUGGING_INFO 12198944Sobrien#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG 12298944Sobrien#endif 12398944Sobrien#ifdef DWARF2_DEBUGGING_INFO 12498944Sobrien#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG 12598944Sobrien#endif 12698944Sobrien#ifdef XCOFF_DEBUGGING_INFO 12719370Spst#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG 12846283Sdfr#endif 12946283Sdfr#endif /* More than one debugger format enabled. */ 13098944Sobrien 13146283Sdfr/* If still not defined, must have been because no debugging formats 13298944Sobrien are supported. */ 13346283Sdfr#ifndef PREFERRED_DEBUGGING_TYPE 13498944Sobrien#define PREFERRED_DEBUGGING_TYPE NO_DEBUG 13546283Sdfr#endif 136130803Smarcel 13746283Sdfr#ifndef DIR_SEPARATOR 13846283Sdfr#define DIR_SEPARATOR '/' 13946283Sdfr#endif 140130803Smarcel 14119370Spstextern int rtx_equal_function_value_matters; 14219370Spst 14319370Spst#if ! (defined (VMS) || defined (OS2)) 14419370Spstextern char **environ; 14519370Spst#endif 14619370Spstextern char *version_string, *language_string; 14719370Spst 14819370Spst/* Carry information from ASM_DECLARE_OBJECT_NAME 14919370Spst to ASM_FINISH_DECLARE_OBJECT. */ 150130803Smarcel 151130803Smarcelextern int size_directive_output; 15246283Sdfrextern tree last_assemble_variable_decl; 15346283Sdfr 15446283Sdfrextern char *init_parse PVPROTO((char *)); 15546283Sdfrextern void finish_parse (); 15646283Sdfrextern void init_decl_processing (); 15746283Sdfrextern void init_obstacks (); 15846283Sdfrextern void init_tree_codes (); 15946283Sdfrextern void init_rtl (); 160130803Smarcelextern void init_regs (); 161130803Smarcelextern void init_optabs (); 162130803Smarcelextern void init_stmt (); 163130803Smarcelextern void init_reg_sets (); 164130803Smarcelextern void dump_flow_info (); 165130803Smarcelextern void dump_sched_info (); 166130803Smarcelextern void dump_local_alloc (); 167130803Smarcelextern void regset_release_memory (); 168130803Smarcel 169130803Smarcelextern void print_rtl (); 170130803Smarcelextern void print_rtl_with_bb (); 171130803Smarcel 172130803Smarcelvoid rest_of_decl_compilation (); 173130803Smarcelvoid error_with_file_and_line PVPROTO((const char *file, 174130803Smarcel int line, const char *s, ...)); 175130803Smarcelvoid error_with_decl PVPROTO((tree decl, const char *s, ...)); 176130803Smarcelvoid error_for_asm PVPROTO((rtx insn, const char *s, ...)); 177130803Smarcelvoid notice PVPROTO((const char *s, ...)); 178130803Smarcelvoid error PVPROTO((const char *s, ...)); 179130803Smarcelvoid fatal PVPROTO((const char *s, ...)); 180130803Smarcelvoid warning_with_file_and_line PVPROTO((const char *file, 181130803Smarcel int line, const char *s, ...)); 182130803Smarcelvoid warning_with_decl PVPROTO((tree decl, const char *s, ...)); 183130803Smarcelvoid warning PVPROTO((const char *s, ...)); 184130803Smarcelvoid pedwarn PVPROTO((const char *s, ...)); 185130803Smarcelvoid pedwarn_with_decl PVPROTO((tree decl, const char *s, ...)); 186130803Smarcelvoid pedwarn_with_file_and_line PVPROTO((const char *file, 187130803Smarcel int line, const char *s, ...)); 188130803Smarcelvoid sorry PVPROTO((const char *s, ...)); 189130803Smarcelstatic void set_target_switch PROTO((const char *)); 190130803Smarcelstatic char *decl_name PROTO((tree, int)); 191130803Smarcelstatic void vmessage PROTO((const char *, const char *, va_list)); 192130803Smarcelstatic void v_message_with_file_and_line PROTO((const char *, int, int, 193130803Smarcel const char *, va_list)); 194130803Smarcelstatic void v_message_with_decl PROTO((tree, int, const char *, va_list)); 195130803Smarcelstatic void file_and_line_for_asm PROTO((rtx, char **, int *)); 196130803Smarcelstatic void v_error_with_file_and_line PROTO((const char *, int, 197130803Smarcel const char *, va_list)); 198130803Smarcelstatic void v_error_with_decl PROTO((tree, const char *, va_list)); 19946283Sdfrstatic void v_error_for_asm PROTO((rtx, const char *, va_list)); 20046283Sdfrstatic void verror PROTO((const char *, va_list)); 201130803Smarcelstatic void vfatal PROTO((const char *, va_list)) ATTRIBUTE_NORETURN; 202130803Smarcelstatic void v_warning_with_file_and_line PROTO ((const char *, int, 203130803Smarcel const char *, va_list)); 20446283Sdfrstatic void v_warning_with_decl PROTO((tree, const char *, va_list)); 205130803Smarcelstatic void v_warning_for_asm PROTO((rtx, const char *, va_list)); 206130803Smarcelstatic void vwarning PROTO((const char *, va_list)); 207130803Smarcelstatic void vpedwarn PROTO((const char *, va_list)); 20846283Sdfrstatic void v_pedwarn_with_decl PROTO((tree, const char *, va_list)); 209130803Smarcelstatic void v_pedwarn_with_file_and_line PROTO((const char *, int, 210130803Smarcel const char *, va_list)); 211130803Smarcelstatic void vsorry PROTO((const char *, va_list)); 21246283Sdfrstatic void float_signal PROTO((int)) ATTRIBUTE_NORETURN; 213130803Smarcelstatic void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN; 214130803Smarcel#ifdef ASM_IDENTIFY_LANGUAGE 215130803Smarcel/* This might or might not be used in ASM_IDENTIFY_LANGUAGE. */ 216130803Smarcelstatic void output_lang_identify PROTO((FILE *)) ATTRIBUTE_UNUSED; 217130803Smarcel#endif 218130803Smarcelstatic void open_dump_file PROTO((const char *, const char *)); 219130803Smarcelstatic void close_dump_file PROTO((void (*) (FILE *, rtx), rtx)); 220130803Smarcelstatic void dump_rtl PROTO((const char *, tree, void (*) (FILE *, rtx), rtx)); 221130803Smarcelstatic void clean_dump_file PROTO((const char *)); 222130803Smarcelstatic void compile_file PROTO((char *)); 223130803Smarcelstatic void display_help PROTO ((void)); 224130803Smarcel 225130803Smarcelstatic void print_version PROTO((FILE *, const char *)); 226130803Smarcelstatic int print_single_switch PROTO((FILE *, int, int, const char *, 22746283Sdfr const char *, const char *, 228130803Smarcel const char *, const char *)); 229130803Smarcelstatic void print_switch_values PROTO((FILE *, int, int, const char *, 23046283Sdfr const char *, const char *)); 231130803Smarcel 232130803Smarcelvoid print_rtl_graph_with_bb PROTO ((const char *, const char *, rtx)); 233130803Smarcelvoid clean_graph_dump_file PROTO ((const char *, const char *)); 23446283Sdfrvoid finish_graph_dump_file PROTO ((const char *, const char *)); 235130803Smarcel/* Length of line when printing switch values. */ 236130803Smarcel#define MAX_LINE 75 237130803Smarcel 23846283Sdfr/* Name of program invoked, sans directories. */ 239130803Smarcel 240130803Smarcelchar *progname; 24146283Sdfr 242130803Smarcel/* Copy of arguments to main. */ 243130803Smarcelint save_argc; 244130803Smarcelchar **save_argv; 245130803Smarcel 246130803Smarcel/* Name of current original source file (what was input to cpp). 247130803Smarcel This comes from each #-command in the actual input. */ 248130803Smarcel 24946283Sdfrchar *input_filename; 250130803Smarcel 251130803Smarcel/* Name of top-level original source file (what was input to cpp). 252130803Smarcel This comes from the #-command at the beginning of the actual input. 253130803Smarcel If there isn't any there, then this is the cc1 input file name. */ 254130803Smarcel 25519370Spstchar *main_input_filename; 256130803Smarcel 257130803Smarcel/* Current line number in real source file. */ 258130803Smarcel 259130803Smarcelint lineno; 26019370Spst 261130803Smarcel/* Nonzero if it is unsafe to create any new pseudo registers. */ 262130803Smarcelint no_new_pseudos; 263130803Smarcel 26419370Spst/* Stack of currently pending input files. */ 265130803Smarcel 266130803Smarcelstruct file_stack *input_file_stack; 267130803Smarcel 268130803Smarcel/* Incremented on each change to input_file_stack. */ 269130803Smarcelint input_file_stack_tick; 270130803Smarcel 271130803Smarcel/* FUNCTION_DECL for function now being parsed or compiled. */ 272130803Smarcel 27346283Sdfrextern tree current_function_decl; 274130803Smarcel 275130803Smarcel/* Name to use as base of names for dump output files. */ 276130803Smarcel 277130803Smarcelconst char *dump_base_name; 27846283Sdfr 279130803Smarcel/* Bit flags that specify the machine subtype we are compiling for. 280130803Smarcel Bits are tested using macros TARGET_... defined in the tm.h file 281130803Smarcel and set by `-m...' switches. Must be defined in rtlanal.c. */ 282130803Smarcel 283130803Smarcelextern int target_flags; 284130803Smarcel 285130803Smarcel/* Flags saying which kinds of debugging dump have been requested. */ 286130803Smarcel 287130803Smarcelint rtl_dump = 0; 288130803Smarcelint rtl_dump_and_exit = 0; 289130803Smarcelint jump_opt_dump = 0; 290130803Smarcelint addressof_dump = 0; 29146283Sdfrint cse_dump = 0; 292130803Smarcelint gcse_dump = 0; 293130803Smarcelint loop_dump = 0; 294130803Smarcelint cse2_dump = 0; 295130803Smarcelint branch_prob_dump = 0; 296130803Smarcelint flow_dump = 0; 297130803Smarcelint combine_dump = 0; 298130803Smarcelint regmove_dump = 0; 299130803Smarcelint sched_dump = 0; 300130803Smarcelint local_reg_dump = 0; 301130803Smarcelint global_reg_dump = 0; 302130803Smarcelint flow2_dump = 0; 303130803Smarcelint sched2_dump = 0; 30446283Sdfrint jump2_opt_dump = 0; 305130803Smarcel#ifdef DELAY_SLOTS 306130803Smarcelint dbr_sched_dump = 0; 307130803Smarcel#endif 308130803Smarcelint flag_print_asm_name = 0; 309130803Smarcel#ifdef STACK_REGS 310130803Smarcelint stack_reg_dump = 0; 31146283Sdfr#endif 312130803Smarcel#ifdef MACHINE_DEPENDENT_REORG 313130803Smarcelint mach_dep_reorg_dump = 0; 314130803Smarcel#endif 315130803Smarcelenum graph_dump_types graph_dump_format; 316130803Smarcel 317130803Smarcel/* Name for output file of assembly code, specified with -o. */ 31819370Spst 319130803Smarcelchar *asm_file_name; 320130803Smarcel 321130803Smarcel/* Value of the -G xx switch, and whether it was passed or not. */ 322130803Smarcelint g_switch_value; 323130803Smarcelint g_switch_set; 32419370Spst 325130803Smarcel/* Type(s) of debugging information we are producing (if any). 326130803Smarcel See flags.h for the definitions of the different possible 327130803Smarcel types of debugging information. */ 328130803Smarcelenum debug_info_type write_symbols = NO_DEBUG; 329130803Smarcel 330130803Smarcel/* Level of debugging information we are producing. See flags.h 331130803Smarcel for the definitions of the different possible levels. */ 332130803Smarcelenum debug_info_level debug_info_level = DINFO_LEVEL_NONE; 333130803Smarcel 334130803Smarcel/* Nonzero means use GNU-only extensions in the generated symbolic 335130803Smarcel debugging information. */ 336130803Smarcel/* Currently, this only has an effect when write_symbols is set to 337130803Smarcel DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */ 338130803Smarcelint use_gnu_debug_info_extensions = 0; 339130803Smarcel 340130803Smarcel/* Nonzero means do optimizations. -O. 341130803Smarcel Particular numeric values stand for particular amounts of optimization; 342130803Smarcel thus, -O2 stores 2 here. However, the optimizations beyond the basic 343130803Smarcel ones are not controlled directly by this variable. Instead, they are 344130803Smarcel controlled by individual `flag_...' variables that are defaulted 345130803Smarcel based on this variable. */ 346130803Smarcel 347130803Smarcelint optimize = 0; 348130803Smarcel 349130803Smarcel/* Nonzero means optimize for size. -Os. 350130803Smarcel The only valid values are zero and non-zero. When optimize_size is 351130803Smarcel non-zero, optimize defaults to 2, but certain individual code 352130803Smarcel bloating optimizations are disabled. */ 353130803Smarcel 354130803Smarcelint optimize_size = 0; 355130803Smarcel 356130803Smarcel/* Number of error messages and warning messages so far. */ 357242936Semaste 358130803Smarcelint errorcount = 0; 359130803Smarcelint warningcount = 0; 360130803Smarcelint sorrycount = 0; 361130803Smarcel 362130803Smarcel/* Pointer to function to compute the name to use to print a declaration. 363130803Smarcel DECL is the declaration in question. 364130803Smarcel VERBOSITY determines what information will be printed: 365130803Smarcel 0: DECL_NAME, demangled as necessary. 366130803Smarcel 1: and scope information. 367130803Smarcel 2: and any other information that might be interesting, such as function 368130803Smarcel parameter types in C++. */ 369130803Smarcel 370130803Smarcelchar *(*decl_printable_name) PROTO ((tree, int)); 371130803Smarcel 372130803Smarcel/* Pointer to function to compute rtl for a language-specific tree code. */ 373130803Smarcel 374130803Smarceltypedef rtx (*lang_expand_expr_t) 375130803Smarcel PROTO ((union tree_node *, rtx, enum machine_mode, 376130803Smarcel enum expand_modifier modifier)); 377130803Smarcel 378130803Smarcellang_expand_expr_t lang_expand_expr = 0; 379130803Smarcel 380130803Smarceltree (*lang_expand_constant) PROTO((tree)) = 0; 381130803Smarcel 382130803Smarcel/* Pointer to function to finish handling an incomplete decl at the 383130803Smarcel end of compilation. */ 384130803Smarcel 385130803Smarcelvoid (*incomplete_decl_finalize_hook) PROTO((tree)) = 0; 386130803Smarcel 387130803Smarcel/* Nonzero if generating code to do profiling. */ 388130803Smarcel 38919370Spstint profile_flag = 0; 39019370Spst 39119370Spst/* Nonzero if generating code to do profiling on a line-by-line basis. */ 392130803Smarcel 39319370Spstint profile_block_flag; 39419370Spst 39598944Sobrien/* Nonzero if generating code to profile program flow graph arcs. */ 39619370Spst 397130803Smarcelint profile_arc_flag = 0; 398130803Smarcel 399130803Smarcel/* Nonzero if generating info for gcov to calculate line test coverage. */ 400130803Smarcel 401130803Smarcelint flag_test_coverage = 0; 402130803Smarcel 403130803Smarcel/* Nonzero indicates that branch taken probabilities should be calculated. */ 40498944Sobrien 40519370Spstint flag_branch_probabilities = 0; 40619370Spst 40719370Spst/* Nonzero for -pedantic switch: warn about anything 40846283Sdfr that standard spec forbids. */ 40998944Sobrien 41098944Sobrienint pedantic = 0; 41198944Sobrien 41298944Sobrien/* Temporarily suppress certain warnings. 41398944Sobrien This is set while reading code from a system header file. */ 41498944Sobrien 41598944Sobrienint in_system_header = 0; 41698944Sobrien 41719370Spst/* Nonzero means do stupid register allocation. 418130803Smarcel Currently, this is 1 if `optimize' is 0. */ 419130803Smarcel 42019370Spstint obey_regdecls = 0; 42119370Spst 42298944Sobrien/* Don't print functions as they are compiled and don't print 42398944Sobrien times taken by the various passes. -quiet. */ 42419370Spst 425130803Smarcelint quiet_flag = 0; 426130803Smarcel 427130803Smarcel/* -f flags. */ 428130803Smarcel 429130803Smarcel/* Nonzero means `char' should be signed. */ 43019370Spst 431130803Smarcelint flag_signed_char; 43219370Spst 43319370Spst/* Nonzero means give an enum type only as many bytes as it needs. */ 43498944Sobrien 43519370Spstint flag_short_enums; 436130803Smarcel 437130803Smarcel/* Nonzero for -fcaller-saves: allocate values in regs that need to 438130803Smarcel be saved across function calls, if that produces overall better code. 439130803Smarcel Optional now, so people can test it. */ 440130803Smarcel 441130803Smarcel#ifdef DEFAULT_CALLER_SAVES 442130803Smarcelint flag_caller_saves = 1; 443130803Smarcel#else 444130803Smarcelint flag_caller_saves = 0; 445130803Smarcel#endif 446130803Smarcel 447130803Smarcel/* Nonzero if structures and unions should be returned in memory. 448130803Smarcel 449130803Smarcel This should only be defined if compatibility with another compiler or 450130803Smarcel with an ABI is needed, because it results in slower code. */ 451130803Smarcel 452130803Smarcel#ifndef DEFAULT_PCC_STRUCT_RETURN 453130803Smarcel#define DEFAULT_PCC_STRUCT_RETURN 1 454130803Smarcel#endif 455130803Smarcel 456130803Smarcel/* Nonzero for -fpcc-struct-return: return values the same way PCC does. */ 457130803Smarcel 45819370Spstint flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN; 45919370Spst 460130803Smarcel/* Nonzero for -fforce-mem: load memory value into a register 46119370Spst before arithmetic on it. This makes better cse but slower compilation. */ 46219370Spst 46319370Spstint flag_force_mem = 0; 46419370Spst 465130803Smarcel/* Nonzero for -fforce-addr: load memory address into a register before 466130803Smarcel reference to memory. This makes better cse but slower compilation. */ 467130803Smarcel 468130803Smarcelint flag_force_addr = 0; 469130803Smarcel 470130803Smarcel/* Nonzero for -fdefer-pop: don't pop args after each function call; 47119370Spst instead save them up to pop many calls' args with one insns. */ 47298944Sobrien 47398944Sobrienint flag_defer_pop = 0; 47498944Sobrien 47598944Sobrien/* Nonzero for -ffloat-store: don't allocate floats and doubles 47698944Sobrien in extended-precision registers. */ 47798944Sobrien 47898944Sobrienint flag_float_store = 0; 47998944Sobrien 48098944Sobrien/* Nonzero for -fcse-follow-jumps: 481130803Smarcel have cse follow jumps to do a more extensive job. */ 482130803Smarcel 483130803Smarcelint flag_cse_follow_jumps; 48498944Sobrien 48598944Sobrien/* Nonzero for -fcse-skip-blocks: 486130803Smarcel have cse follow a branch around a block. */ 48798944Sobrienint flag_cse_skip_blocks; 488130803Smarcel 48998944Sobrien/* Nonzero for -fexpensive-optimizations: 49098944Sobrien perform miscellaneous relatively-expensive optimizations. */ 49198944Sobrienint flag_expensive_optimizations; 492130803Smarcel 49398944Sobrien/* Nonzero for -fthread-jumps: 49498944Sobrien have jump optimize output of loop. */ 49598944Sobrien 496130803Smarcelint flag_thread_jumps; 49798944Sobrien 49898944Sobrien/* Nonzero enables strength-reduction in loop.c. */ 49998944Sobrien 50098944Sobrienint flag_strength_reduce = 0; 50198944Sobrien 50298944Sobrien/* Nonzero enables loop unrolling in unroll.c. Only loops for which the 50398944Sobrien number of iterations can be calculated at compile-time (UNROLL_COMPLETELY, 50498944Sobrien UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are 50598944Sobrien unrolled. */ 50698944Sobrien 50798944Sobrienint flag_unroll_loops; 50898944Sobrien 509130803Smarcel/* Nonzero enables loop unrolling in unroll.c. All loops are unrolled. 51098944Sobrien This is generally not a win. */ 51198944Sobrien 51298944Sobrienint flag_unroll_all_loops; 51398944Sobrien 51498944Sobrien/* Nonzero forces all invariant computations in loops to be moved 51598944Sobrien outside the loop. */ 516130803Smarcel 517130803Smarcelint flag_move_all_movables = 0; 518130803Smarcel 519130803Smarcel/* Nonzero forces all general induction variables in loops to be 520130803Smarcel strength reduced. */ 52198944Sobrien 52298944Sobrienint flag_reduce_all_givs = 0; 52398944Sobrien 524130803Smarcel/* Nonzero to perform full register move optimization passes. This is the 52598944Sobrien default for -O2. */ 52698944Sobrien 52798944Sobrienint flag_regmove = 0; 52898944Sobrien 52998944Sobrien/* Nonzero for -fwritable-strings: 53098944Sobrien store string constants in data segment and don't uniquize them. */ 53198944Sobrien 53298944Sobrienint flag_writable_strings = 0; 53398944Sobrien 53498944Sobrien/* Nonzero means don't put addresses of constant functions in registers. 53598944Sobrien Used for compiling the Unix kernel, where strange substitutions are 53698944Sobrien done on the assembly output. */ 53798944Sobrien 53898944Sobrienint flag_no_function_cse = 0; 539130803Smarcel 54098944Sobrien/* Nonzero for -fomit-frame-pointer: 54198944Sobrien don't make a frame pointer in simple functions that don't require one. */ 54298944Sobrien 54398944Sobrienint flag_omit_frame_pointer = 0; 54498944Sobrien 54598944Sobrien/* Nonzero means place each function into its own section on those platforms 54698944Sobrien which support arbitrary section names and unlimited numbers of sections. */ 54798944Sobrien 548130803Smarcelint flag_function_sections = 0; 54919370Spst 55019370Spst/* ... and similar for data. */ 55119370Spst 55298944Sobrienint flag_data_sections = 0; 55398944Sobrien 55498944Sobrien/* Nonzero to inhibit use of define_optimization peephole opts. */ 55598944Sobrien 55698944Sobrienint flag_no_peephole = 0; 55798944Sobrien 55898944Sobrien/* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math 55919370Spst operations in the interest of optimization. For example it allows 56098944Sobrien GCC to assume arguments to sqrt are nonnegative numbers, allowing 56198944Sobrien faster code for sqrt to be generated. */ 56298944Sobrien 56398944Sobrienint flag_fast_math = 0; 56498944Sobrien 56598944Sobrien/* Nonzero means the front end generally wants `errno' maintained by math 56619370Spst operations, like built-in SQRT, unless overridden by flag_fast_math. */ 567130803Smarcel 56819370Spstint flag_errno_math = 1; 56998944Sobrien 57019370Spst/* 0 means straightforward implementation of complex divide acceptable. 57119370Spst 1 means wide ranges of inputs must work for complex divide. 57219370Spst 2 means C9X-like requirements for complex divide (not yet implemented). */ 57319370Spst 57419370Spstint flag_complex_divide_method = 0; 57519370Spst 57619370Spst/* Nonzero means all references through pointers are volatile. */ 57719370Spst 57819370Spstint flag_volatile; 57919370Spst 58019370Spst/* Nonzero means treat all global and extern variables as volatile. */ 58119370Spst 58219370Spstint flag_volatile_global; 583130803Smarcel 58419370Spst/* Nonzero means treat all static variables as volatile. */ 58519370Spst 58619370Spstint flag_volatile_static; 58719370Spst 588130803Smarcel/* Nonzero means just do syntax checking; don't output anything. */ 58998944Sobrien 59098944Sobrienint flag_syntax_only = 0; 59198944Sobrien 59298944Sobrien/* Nonzero means perform global cse. */ 59398944Sobrien 59498944Sobrienstatic int flag_gcse; 59598944Sobrien 59698944Sobrien/* Nonzero means to rerun cse after loop optimization. This increases 59798944Sobrien compilation time about 20% and picks up a few more common expressions. */ 59898944Sobrien 59998944Sobrienstatic int flag_rerun_cse_after_loop; 600130803Smarcel 60119370Spst/* Nonzero means to run loop optimizations twice. */ 60298944Sobrien 60398944Sobrienint flag_rerun_loop_opt; 60498944Sobrien 60598944Sobrien/* Nonzero for -finline-functions: ok to inline functions that look like 60698944Sobrien good inline candidates. */ 60798944Sobrien 60898944Sobrienint flag_inline_functions; 609130803Smarcel 61098944Sobrien/* Nonzero for -fkeep-inline-functions: even if we make a function 61119370Spst go inline everywhere, keep its definition around for debugging 61219370Spst purposes. */ 61319370Spst 61419370Spstint flag_keep_inline_functions; 615130803Smarcel 61646283Sdfr/* Nonzero means that functions will not be inlined. */ 61719370Spst 618130803Smarcelint flag_no_inline; 61946283Sdfr 62019370Spst/* Nonzero means that we should emit static const variables 62119370Spst regardless of whether or not optimization is turned on. */ 62219370Spst 623130803Smarcelint flag_keep_static_consts = 1; 62419370Spst 62598944Sobrien/* Nonzero means we should be saving declaration info into a .X file. */ 62619370Spst 62798944Sobrienint flag_gen_aux_info = 0; 62898944Sobrien 62998944Sobrien/* Specified name of aux-info file. */ 630130803Smarcel 63119370Spststatic char *aux_info_file_name; 63298944Sobrien 633130803Smarcel/* Nonzero means make the text shared if supported. */ 634130803Smarcel 635130803Smarcelint flag_shared_data; 63698944Sobrien 63798944Sobrien/* Nonzero means schedule into delayed branch slots if supported. */ 638130803Smarcel 63998944Sobrienint flag_delayed_branch; 64098944Sobrien 64198944Sobrien/* Nonzero if we are compiling pure (sharable) code. 64298944Sobrien Value is 1 if we are doing reasonable (i.e. simple 64398944Sobrien offset into offset table) pic. Value is 2 if we can 64498944Sobrien only perform register offsets. */ 64598944Sobrien 64698944Sobrienint flag_pic; 64798944Sobrien 64898944Sobrien/* Nonzero means generate extra code for exception handling and enable 64998944Sobrien exception handling. */ 65098944Sobrien 65198944Sobrienint flag_exceptions; 65298944Sobrien 65398944Sobrien/* Nonzero means use the new model for exception handling. Replaces 65498944Sobrien -DNEW_EH_MODEL as a compile option. */ 65598944Sobrien 65698944Sobrienint flag_new_exceptions = 0; 65798944Sobrien 65898944Sobrien/* Nonzero means don't place uninitialized global data in common storage 65998944Sobrien by default. */ 66098944Sobrien 66198944Sobrienint flag_no_common; 66298944Sobrien 66398944Sobrien/* Nonzero means pretend it is OK to examine bits of target floats, 66498944Sobrien even if that isn't true. The resulting code will have incorrect constants, 66598944Sobrien but the same series of instructions that the native compiler would make. */ 66698944Sobrien 66798944Sobrienint flag_pretend_float; 66898944Sobrien 66998944Sobrien/* Nonzero means change certain warnings into errors. 67098944Sobrien Usually these are warnings about failure to conform to some standard. */ 67198944Sobrien 67298944Sobrienint flag_pedantic_errors = 0; 67398944Sobrien 67498944Sobrien/* flag_schedule_insns means schedule insns within basic blocks (before 67598944Sobrien local_alloc). 67698944Sobrien flag_schedule_insns_after_reload means schedule insns after 67798944Sobrien global_alloc. */ 67898944Sobrien 67919370Spstint flag_schedule_insns = 0; 68098944Sobrienint flag_schedule_insns_after_reload = 0; 68198944Sobrien 68219370Spst#ifdef HAIFA 683130803Smarcel/* The following flags have effect only for scheduling before register 68498944Sobrien allocation: 68519370Spst 68698944Sobrien flag_schedule_interblock means schedule insns accross basic blocks. 68798944Sobrien flag_schedule_speculative means allow speculative motion of non-load insns. 68898944Sobrien flag_schedule_speculative_load means allow speculative motion of some 68998944Sobrien load insns. 69019370Spst flag_schedule_speculative_load_dangerous allows speculative motion of more 69119370Spst load insns. */ 69298944Sobrien 69319370Spstint flag_schedule_interblock = 1; 69498944Sobrienint flag_schedule_speculative = 1; 69598944Sobrienint flag_schedule_speculative_load = 0; 69698944Sobrienint flag_schedule_speculative_load_dangerous = 0; 69798944Sobrien#endif /* HAIFA */ 69819370Spst 69946283Sdfr/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple 70046283Sdfr by a cheaper branch, on a count register. */ 70146283Sdfrint flag_branch_on_count_reg; 70246283Sdfr 70398944Sobrien/* -finhibit-size-directive inhibits output of .size for ELF. 70446283Sdfr This is used only for compiling crtstuff.c, 70546283Sdfr and it may be extended to other effects 70698944Sobrien needed for crtstuff.c on other systems. */ 70746283Sdfrint flag_inhibit_size_directive = 0; 70819370Spst 70919370Spst/* -fverbose-asm causes extra commentary information to be produced in 71019370Spst the generated assembly code (to make it more readable). This option 71119370Spst is generally only of use to those who actually need to read the 71246283Sdfr generated assembly code (perhaps while debugging the compiler itself). 71398944Sobrien -fno-verbose-asm, the default, causes the extra information 71419370Spst to be omitted and is useful when comparing two assembler files. */ 71519370Spst 71619370Spstint flag_verbose_asm = 0; 71719370Spst 71898944Sobrien/* -dA causes debug commentary information to be produced in 71998944Sobrien the generated assembly code (to make it more readable). This option 72019370Spst is generally only of use to those who actually need to read the 72119370Spst generated assembly code (perhaps while debugging the compiler itself). 72219370Spst Currently, this switch is only used by dwarfout.c; however, it is intended 72319370Spst to be a catchall for printing debug information in the assembler file. */ 72419370Spst 72598944Sobrienint flag_debug_asm = 0; 72698944Sobrien 72719370Spst/* -fgnu-linker specifies use of the GNU linker for initializations. 72819370Spst (Or, more generally, a linker that handles initializations.) 72919370Spst -fno-gnu-linker says that collect2 will be used. */ 73019370Spst#ifdef USE_COLLECT2 73119370Spstint flag_gnu_linker = 0; 73219370Spst#else 73398944Sobrienint flag_gnu_linker = 1; 73419370Spst#endif 73598944Sobrien 73619370Spst/* Tag all structures with __attribute__(packed) */ 73719370Spstint flag_pack_struct = 0; 73898944Sobrien 73998944Sobrien/* Nonzero means that -Wformat accepts certain system-dependent formats. */ 74098944Sobrienint flag_format_extensions = 0; 74198944Sobrien 74298944Sobrien/* Emit code to check for stack overflow; also may cause large objects 74398944Sobrien to be allocated dynamically. */ 74498944Sobrienint flag_stack_check; 74598944Sobrien 74698944Sobrien/* -fcheck-memory-usage causes extra code to be generated in order to check 74798944Sobrien memory accesses. This is used by a detector of bad memory accesses such 74898944Sobrien as Checker. */ 74998944Sobrienint flag_check_memory_usage = 0; 75098944Sobrien 75198944Sobrien/* -fprefix-function-name causes function name to be prefixed. This 75219370Spst can be used with -fcheck-memory-usage to isolate code compiled with 75319370Spst -fcheck-memory-usage. */ 75419370Spstint flag_prefix_function_name = 0; 75519370Spst 75698944Sobrien/* 0 if pointer arguments may alias each other. True in C. 75798944Sobrien 1 if pointer arguments may not alias each other but may alias 75819370Spst global variables. 75919370Spst 2 if pointer arguments may not alias each other and may not 76019370Spst alias global variables. True in Fortran. 76119370Spst This defaults to 0 for C. */ 76219370Spstint flag_argument_noalias = 0; 76319370Spst 76419370Spst/* Nonzero if we should do (language-dependent) alias analysis. 765130803Smarcel Typically, this analysis will assume that expressions of certain 76619370Spst types do not alias expressions of certain other types. Only used 767130803Smarcel if alias analysis (in general) is enabled. */ 76819370Spstint flag_strict_aliasing = 0; 76919370Spst 77019370Spst/* Instrument functions with calls at entry and exit, for profiling. */ 77119370Spstint flag_instrument_function_entry_exit = 0; 77298944Sobrien 77319370Spst/* Nonzero means ignore `#ident' directives. 0 means handle them. 77419370Spst On SVR4 targets, it also controls whether or not to emit a 77519370Spst string identifying the compiler. */ 77619370Spst 77719370Spstint flag_no_ident = 0; 77819370Spst 77919370Spst/* Table of supported debugging formats. */ 78019370Spststatic struct 78119370Spst{ 78219370Spst const char * arg; 78319370Spst /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a 78419370Spst constant expression, we use NO_DEBUG in its place. */ 78519370Spst enum debug_info_type debug_type; 78619370Spst int use_extensions_p; 78719370Spst const char * description; 78819370Spst} *da, 78919370Spstdebug_args[] = 79019370Spst{ 79119370Spst { "g", NO_DEBUG, DEFAULT_GDB_EXTENSIONS, 792130803Smarcel "Generate default debug format output" }, 79319370Spst { "ggdb", NO_DEBUG, 1, "Generate default extended debug format output" }, 79419370Spst#ifdef DBX_DEBUGGING_INFO 79519370Spst { "gstabs", DBX_DEBUG, 0, "Generate STABS format debug output" }, 79619370Spst { "gstabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" }, 79719370Spst#endif 79819370Spst#ifdef DWARF_DEBUGGING_INFO 799130803Smarcel { "gdwarf", DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"}, 80019370Spst { "gdwarf+", DWARF_DEBUG, 1, 80119370Spst "Generated extended DWARF-1 format debug output" }, 80219370Spst#endif 80319370Spst#ifdef DWARF2_DEBUGGING_INFO 80419370Spst { "gdwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" }, 805130803Smarcel#endif 80619370Spst#ifdef XCOFF_DEBUGGING_INFO 80798944Sobrien { "gxcoff", XCOFF_DEBUG, 0, "Generate XCOFF format debug output" }, 80819370Spst { "gxcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" }, 80919370Spst#endif 81019370Spst#ifdef SDB_DEBUGGING_INFO 81119370Spst { "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" }, 81298944Sobrien#endif 81319370Spst { 0, 0, 0, 0 } 81419370Spst}; 81519370Spst 81619370Spsttypedef struct 81798944Sobrien{ 81819370Spst const char * string; 81919370Spst int * variable; 82019370Spst int on_value; 82119370Spst const char * description; 82219370Spst} 82319370Spstlang_independent_options; 82419370Spst 82519370Spst/* Add or remove a leading underscore from user symbols. */ 82619370Spstint flag_leading_underscore = -1; 82719370Spst 82819370Spst/* The user symbol prefix after having resolved same. */ 82919370Spstconst char *user_label_prefix; 83019370Spst 83198944Sobrien/* A default for same. */ 83219370Spst#ifndef USER_LABEL_PREFIX 83319370Spst#define USER_LABEL_PREFIX "" 83419370Spst#endif 83519370Spst 83619370Spst/* Table of language-independent -f options. 83719370Spst STRING is the option name. VARIABLE is the address of the variable. 83819370Spst ON_VALUE is the value to store in VARIABLE 83919370Spst if `-fSTRING' is seen as an option. 84019370Spst (If `-fno-STRING' is seen as an option, the opposite value is stored.) */ 841130803Smarcel 84219370Spstlang_independent_options f_options[] = 84319370Spst{ 84419370Spst {"float-store", &flag_float_store, 1, 84519370Spst "Do not store floats in registers" }, 846130803Smarcel {"volatile", &flag_volatile, 1, 847130803Smarcel "Consider all mem refs through pointers as volatile"}, 848130803Smarcel {"volatile-global", &flag_volatile_global, 1, 849130803Smarcel "Consider all mem refs to global data to be volatile" }, 850130803Smarcel {"volatile-static", &flag_volatile_static, 1, 851130803Smarcel "Consider all mem refs to static data to be volatile" }, 852130803Smarcel {"defer-pop", &flag_defer_pop, 1, 853130803Smarcel "Defer popping functions args from stack until later" }, 854130803Smarcel {"omit-frame-pointer", &flag_omit_frame_pointer, 1, 855130803Smarcel "When possible do not generate stack frames"}, 856130803Smarcel {"cse-follow-jumps", &flag_cse_follow_jumps, 1, 857130803Smarcel "When running CSE, follow jumps to their targets" }, 858130803Smarcel {"cse-skip-blocks", &flag_cse_skip_blocks, 1, 859130803Smarcel "When running CSE, follow conditional jumps" }, 86019370Spst {"expensive-optimizations", &flag_expensive_optimizations, 1, 86119370Spst "Perform a number of minor, expensive optimisations" }, 86219370Spst {"thread-jumps", &flag_thread_jumps, 1, 86319370Spst "Perform jump threading optimisations"}, 864130803Smarcel {"strength-reduce", &flag_strength_reduce, 1, 86519370Spst "Perform strength reduction optimisations" }, 866130803Smarcel {"unroll-loops", &flag_unroll_loops, 1, 867130803Smarcel "Perform loop unrolling when iteration count is known" }, 868130803Smarcel {"unroll-all-loops", &flag_unroll_all_loops, 1, 86919370Spst "Perform loop unrolling for all loops" }, 87019370Spst {"move-all-movables", &flag_move_all_movables, 1, 871130803Smarcel "Force all loop invariant computations out of loops" }, 87246283Sdfr {"reduce-all-givs", &flag_reduce_all_givs, 1, 87346283Sdfr "Strength reduce all loop general induction variables" }, 87446283Sdfr {"writable-strings", &flag_writable_strings, 1, 87546283Sdfr "Store strings in writable data section" }, 87646283Sdfr {"peephole", &flag_no_peephole, 0, 87746283Sdfr "Enable machine specific peephole optimisations" }, 87846283Sdfr {"force-mem", &flag_force_mem, 1, 87946283Sdfr "Copy memory operands into registers before using" }, 88046283Sdfr {"force-addr", &flag_force_addr, 1, 88146283Sdfr "Copy memory address constants into regs before using" }, 88246283Sdfr {"function-cse", &flag_no_function_cse, 0, 88346283Sdfr "Allow function addresses to be held in registers" }, 88498944Sobrien {"inline-functions", &flag_inline_functions, 1, 885130803Smarcel "Integrate simple functions into their callers" }, 88698944Sobrien {"keep-inline-functions", &flag_keep_inline_functions, 1, 88798944Sobrien "Generate code for funcs even if they are fully inlined" }, 88898944Sobrien {"inline", &flag_no_inline, 0, 88998944Sobrien "Pay attention to the 'inline' keyword"}, 89098944Sobrien {"keep-static-consts", &flag_keep_static_consts, 1, 89198944Sobrien "Emit static const variables even if they are not used" }, 89298944Sobrien {"syntax-only", &flag_syntax_only, 1, 89398944Sobrien "Check for syntax errors, then stop" }, 89498944Sobrien {"shared-data", &flag_shared_data, 1, 895130803Smarcel "Mark data as shared rather than private" }, 89698944Sobrien {"caller-saves", &flag_caller_saves, 1, 89719370Spst "Enable saving registers around function calls" }, 89819370Spst {"pcc-struct-return", &flag_pcc_struct_return, 1, 89919370Spst "Return 'short' aggregates in memory, not registers" }, 900130803Smarcel {"reg-struct-return", &flag_pcc_struct_return, 0, 90119370Spst "Return 'short' aggregates in registers" }, 90219370Spst {"delayed-branch", &flag_delayed_branch, 1, 903130803Smarcel "Attempt to fill delay slots of branch instructions" }, 90419370Spst {"gcse", &flag_gcse, 1, 90519370Spst "Perform the global common subexpression elimination" }, 90619370Spst {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1, 90719370Spst "Run CSE pass after loop optimisations"}, 90819370Spst {"rerun-loop-opt", &flag_rerun_loop_opt, 1, 909130803Smarcel "Run the loop optimiser twice"}, 91019370Spst {"pretend-float", &flag_pretend_float, 1, 911130803Smarcel "Pretend that host and target use the same FP format"}, 912130803Smarcel {"schedule-insns", &flag_schedule_insns, 1, 913130803Smarcel "Reschedule instructions to avoid pipeline stalls"}, 91419370Spst {"schedule-insns2", &flag_schedule_insns_after_reload, 1, 91519370Spst "Run two passes of the instruction scheduler"}, 91619370Spst#ifdef HAIFA 91719370Spst {"sched-interblock",&flag_schedule_interblock, 1, 91819370Spst "Enable scheduling across basic blocks" }, 919130803Smarcel {"sched-spec",&flag_schedule_speculative, 1, 92019370Spst "Allow speculative motion of non-loads" }, 92119370Spst {"sched-spec-load",&flag_schedule_speculative_load, 1, 922130803Smarcel "Allow speculative motion of some loads" }, 923130803Smarcel {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1, 92419370Spst "Allow speculative motion of more loads" }, 92519370Spst#endif /* HAIFA */ 92619370Spst {"branch-count-reg",&flag_branch_on_count_reg, 1, 92719370Spst "Replace add,compare,branch with branch on count reg"}, 92819370Spst {"pic", &flag_pic, 1, 92919370Spst "Generate position independent code, if possible"}, 93019370Spst {"PIC", &flag_pic, 2, ""}, 93119370Spst {"exceptions", &flag_exceptions, 1, 93219370Spst "Enable exception handling" }, 93319370Spst {"new-exceptions", &flag_new_exceptions, 1, 93419370Spst "Use the new model for exception handling" }, 93519370Spst {"sjlj-exceptions", &exceptions_via_longjmp, 1, 93619370Spst "Use setjmp/longjmp to handle exceptions" }, 937130803Smarcel {"asynchronous-exceptions", &asynchronous_exceptions, 1, 938130803Smarcel "Support asynchronous exceptions" }, 93919370Spst {"profile-arcs", &profile_arc_flag, 1, 94019370Spst "Insert arc based program profiling code" }, 94119370Spst {"test-coverage", &flag_test_coverage, 1, 94298944Sobrien "Create data files needed by gcov" }, 943130803Smarcel {"branch-probabilities", &flag_branch_probabilities, 1, 944130803Smarcel "Use profiling information for branch probabilities" }, 94519370Spst {"fast-math", &flag_fast_math, 1, 94619370Spst "Improve FP speed by violating ANSI & IEEE rules" }, 94719370Spst {"common", &flag_no_common, 0, 94819370Spst "Do not put unitialised globals in the common section" }, 94919370Spst {"inhibit-size-directive", &flag_inhibit_size_directive, 1, 95019370Spst "Do not generate .size directives" }, 95119370Spst {"function-sections", &flag_function_sections, 1, 952130803Smarcel "place each function into its own section" }, 953130803Smarcel {"data-sections", &flag_data_sections, 1, 95419370Spst "place data items into their own section" }, 955130803Smarcel {"verbose-asm", &flag_verbose_asm, 1, 95619370Spst "Add extra commentry to assembler output"}, 95719370Spst {"gnu-linker", &flag_gnu_linker, 1, 958130803Smarcel "Output GNU ld formatted global initialisers"}, 95919370Spst {"regmove", &flag_regmove, 1, 96019370Spst "Enables a register move optimisation"}, 961130803Smarcel {"optimize-register-move", &flag_regmove, 1, 962130803Smarcel "Do the full regmove optimization pass"}, 96319370Spst {"pack-struct", &flag_pack_struct, 1, 964130803Smarcel "Pack structure members together without holes" }, 96519370Spst {"format-extensions", &flag_format_extensions, 1, 96619370Spst "-Wformat accepts certain FreeBSD system-dependent formats" }, 967130803Smarcel {"stack-check", &flag_stack_check, 1, 968130803Smarcel "Insert stack checking code into the program" }, 96919370Spst {"argument-alias", &flag_argument_noalias, 0, 97019370Spst "Specify that arguments may alias each other & globals"}, 97119370Spst {"argument-noalias", &flag_argument_noalias, 1, 972130803Smarcel "Assume arguments may alias globals but not each other"}, 97319370Spst {"argument-noalias-global", &flag_argument_noalias, 2, 97419370Spst "Assume arguments do not alias each other or globals" }, 97519370Spst {"strict-aliasing", &flag_strict_aliasing, 1, 97619370Spst "Assume strict aliasing rules apply" }, 97719370Spst {"check-memory-usage", &flag_check_memory_usage, 1, 97819370Spst "Generate code to check every memory access" }, 97919370Spst {"prefix-function-name", &flag_prefix_function_name, 1, 98019370Spst "Add a prefix to all function names" }, 98119370Spst {"dump-unnumbered", &flag_dump_unnumbered, 1, 98219370Spst "Suppress output of instruction numbers and line number notes in debugging dumps"}, 98319370Spst {"instrument-functions", &flag_instrument_function_entry_exit, 1, 984130803Smarcel "Instrument function entry/exit with profiling calls"}, 985130803Smarcel {"leading-underscore", &flag_leading_underscore, 1, 986130803Smarcel "External symbols have a leading underscore" }, 987130803Smarcel {"ident", &flag_no_ident, 0, 988130803Smarcel "Process #ident directives"} 98919370Spst}; 990130803Smarcel 991130803Smarcel#define NUM_ELEM(a) (sizeof (a) / sizeof ((a)[0])) 992130803Smarcel 993130803Smarcel/* Table of language-specific options. */ 994130803Smarcel 995130803Smarcelstatic struct lang_opt 996130803Smarcel{ 997130803Smarcel const char * option; 998130803Smarcel const char * description; 999130803Smarcel} 100019370Spstdocumented_lang_options[] = 100119370Spst{ 100219370Spst /* In order not to overload the --help output, the convention 100319370Spst used here is to only describe those options which are not 100419370Spst enabled by default. */ 100519370Spst 1006130803Smarcel { "-ansi", "Compile just for ANSI C" }, 100719370Spst { "-fallow-single-precision", 100819370Spst "Do not promote floats to double if using -traditional" }, 100919370Spst { "-std= ", "Determine language standard"}, 101019370Spst 101119370Spst { "-fsigned-bitfields", "" }, 101219370Spst { "-funsigned-bitfields","Make bitfields by unsigned by default" }, 101319370Spst { "-fno-signed-bitfields", "" }, 101419370Spst { "-fno-unsigned-bitfields","" }, 101519370Spst { "-fsigned-char", "Make 'char' be signed by default"}, 101619370Spst { "-funsigned-char", "Make 'char' be unsigned by default"}, 101719370Spst { "-fno-signed-char", "" }, 1018130803Smarcel { "-fno-unsigned-char", "" }, 1019130803Smarcel 1020130803Smarcel { "-ftraditional", "" }, 1021130803Smarcel { "-traditional", "Attempt to support traditional K&R style C"}, 1022130803Smarcel { "-fnotraditional", "" }, 1023130803Smarcel { "-fno-traditional", "" }, 1024130803Smarcel 1025130803Smarcel { "-fasm", "" }, 1026130803Smarcel { "-fno-asm", "Do not recognise the 'asm' keyword" }, 1027130803Smarcel { "-fbuiltin", "" }, 1028130803Smarcel { "-fno-builtin", "Do not recognise any built in functions" }, 1029130803Smarcel { "-fhosted", "Assume normal C execution environment" }, 1030130803Smarcel { "-fno-hosted", "" }, 1031130803Smarcel { "-ffreestanding", 1032130803Smarcel "Assume that standard libraries & main might not exist" }, 1033130803Smarcel { "-fno-freestanding", "" }, 1034130803Smarcel { "-fcond-mismatch", "Allow different types as args of ? operator"}, 1035130803Smarcel { "-fno-cond-mismatch", "" }, 1036130803Smarcel { "-fdollars-in-identifiers", "Allow the use of $ inside identifiers" }, 1037130803Smarcel { "-fno-dollars-in-identifiers", "" }, 1038130803Smarcel { "-fshort-double", "Use the same size for double as for float" }, 1039130803Smarcel { "-fno-short-double", "" }, 1040130803Smarcel { "-fshort-enums", "Use the smallest fitting integer to hold enums"}, 1041130803Smarcel { "-fno-short-enums", "" }, 1042130803Smarcel 1043130803Smarcel { "-Wall", "Enable most warning messages" }, 104446283Sdfr { "-Wbad-function-cast", 1045130803Smarcel "Warn about casting functions to incompatible types" }, 1046130803Smarcel { "-Wno-bad-function-cast", "" }, 1047130803Smarcel { "-Wmissing-noreturn", 1048130803Smarcel "Warn about functions which might be candidates for attribute noreturn" }, 1049130803Smarcel { "-Wno-missing-noreturn", "" }, 1050130803Smarcel { "-Wcast-qual", "Warn about casts which discard qualifiers"}, 1051130803Smarcel { "-Wno-cast-qual", "" }, 1052130803Smarcel { "-Wchar-subscripts", "Warn about subscripts whose type is 'char'"}, 1053130803Smarcel { "-Wno-char-subscripts", "" }, 1054130803Smarcel { "-Wcomment", "Warn if nested comments are detected" }, 1055130803Smarcel { "-Wno-comment", "" }, 1056130803Smarcel { "-Wcomments", "Warn if nested comments are detected" }, 105746283Sdfr { "-Wno-comments", "" }, 1058130803Smarcel { "-Wconversion", "Warn about possibly confusing type conversions" }, 1059130803Smarcel { "-Wno-conversion", "" }, 1060130803Smarcel { "-Wformat", "Warn about printf format anomalies" }, 1061130803Smarcel { "-Wno-format", "" }, 1062130803Smarcel { "-Wimplicit-function-declaration", 1063130803Smarcel "Warn about implicit function declarations" }, 1064130803Smarcel { "-Wno-implicit-function-declaration", "" }, 1065130803Smarcel { "-Werror-implicit-function-declaration", "" }, 1066130803Smarcel { "-Wimplicit-int", "Warn when a declaration does not specify a type" }, 1067130803Smarcel { "-Wno-implicit-int", "" }, 1068130803Smarcel { "-Wimplicit", "" }, 1069130803Smarcel { "-Wno-implicit", "" }, 1070130803Smarcel { "-Wimport", "Warn about the use of the #import directive" }, 1071130803Smarcel { "-Wno-import", "" }, 1072130803Smarcel { "-Wlong-long","" }, 1073130803Smarcel { "-Wno-long-long", "Do not warn about using 'long long' when -pedantic" }, 1074130803Smarcel { "-Wmain", "Warn about suspicious declarations of main" }, 1075130803Smarcel { "-Wno-main", "" }, 1076130803Smarcel { "-Wmissing-braces", 1077130803Smarcel "Warn about possibly missing braces around initialisers" }, 1078130803Smarcel { "-Wno-missing-braces", "" }, 1079130803Smarcel { "-Wmissing-declarations", 1080130803Smarcel "Warn about global funcs without previous declarations"}, 1081130803Smarcel { "-Wno-missing-declarations", "" }, 1082130803Smarcel { "-Wmissing-prototypes", "Warn about global funcs without prototypes" }, 1083130803Smarcel { "-Wno-missing-prototypes", "" }, 1084130803Smarcel { "-Wmultichar", "Warn about use of multicharacter literals"}, 1085130803Smarcel { "-Wno-multichar", "" }, 1086130803Smarcel { "-Wnested-externs", "Warn about externs not at file scope level" }, 1087130803Smarcel { "-Wno-nested-externs", "" }, 1088130803Smarcel { "-Wparentheses", "Warn about possible missing parentheses" }, 1089130803Smarcel { "-Wno-parentheses", "" }, 1090130803Smarcel { "-Wpointer-arith", "Warn about function pointer arithmetic" }, 1091130803Smarcel { "-Wno-pointer-arith", "" }, 1092130803Smarcel { "-Wredundant-decls", 1093130803Smarcel "Warn about multiple declarations of the same object" }, 1094130803Smarcel { "-Wno-redundant-decls", "" }, 1095130803Smarcel { "-Wsign-compare", "Warn about signed/unsigned comparisons" }, 1096130803Smarcel { "-Wno-sign-compare", "" }, 1097130803Smarcel { "-Wunknown-pragmas", "Warn about unrecognised pragmas" }, 1098130803Smarcel { "-Wno-unknown-pragmas", "" }, 109946283Sdfr { "-Wstrict-prototypes", "Warn about non-prototyped function decls" }, 1100130803Smarcel { "-Wno-strict-prototypes", "" }, 110119370Spst { "-Wtraditional", "Warn about constructs whose meaning change in ANSI C"}, 110219370Spst { "-Wno-traditional", "" }, 110319370Spst { "-Wtrigraphs", "Warn when trigraphs are encountered" }, 110419370Spst { "-Wno-trigraphs", "" }, 110519370Spst { "-Wundef", "" }, 110619370Spst { "-Wno-undef", "" }, 110719370Spst { "-Wwrite-strings", "Mark strings as 'const char *'"}, 110819370Spst { "-Wno-write-strings", "" }, 110919370Spst 111098944Sobrien /* These are for languages with USE_CPPLIB. */ 111119370Spst /* These options are already documented in cpplib.c */ 111298944Sobrien { "--help", "" }, 111319370Spst { "-A", "" }, 111419370Spst { "-D", "" }, 111519370Spst { "-I", "" }, 111619370Spst#if USE_CPPLIB 111719370Spst { "-MD", "Print dependencies to FILE.d" }, 111819370Spst { "-MMD", "Print dependencies to FILE.d" }, 111919370Spst { "-M", "Print dependencies to stdout" }, 112019370Spst { "-MM", "Print dependencies to stdout" }, 112198944Sobrien#endif /* USE_CPPLIB */ 112219370Spst { "-U", "" }, 112319370Spst { "-H", "" }, 112419370Spst { "-idirafter", "" }, 112519370Spst { "-imacros", "" }, 112619370Spst { "-include", "" }, 112719370Spst { "-iprefix", "" }, 112819370Spst { "-isystem", "" }, 112919370Spst { "-iwithprefix", "" }, 113019370Spst { "-iwithprefixbefore", "" }, 113119370Spst { "-lang-c", "" }, 113298944Sobrien { "-lang-c89", "" }, 113398944Sobrien { "-lang-c++", "" }, 113419370Spst { "-remap", "" }, 113598944Sobrien { "-nostdinc", "" }, 113619370Spst { "-nostdinc++", "" }, 113719370Spst { "-trigraphs", "" }, 1138130803Smarcel { "-undef", "" }, 1139130803Smarcel 1140130803Smarcel#define DEFINE_LANG_NAME(NAME) { NULL, NAME }, 1141130803Smarcel 114219370Spst /* These are for obj c. */ 114319370Spst DEFINE_LANG_NAME ("Objective C") 114419370Spst 114519370Spst { "-lang-objc", "" }, 114619370Spst { "-gen-decls", "Dump decls to a .decl file" }, 114719370Spst { "-fgnu-runtime", "Generate code for GNU runtime environment" }, 114819370Spst { "-fno-gnu-runtime", "" }, 114919370Spst { "-fnext-runtime", "Generate code for NeXT runtime environment" }, 115019370Spst { "-fno-next-runtime", "" }, 115198944Sobrien { "-Wselector", "Warn if a selector has multiple methods" }, 115298944Sobrien { "-Wno-selector", "" }, 115398944Sobrien { "-Wprotocol", "" }, 115498944Sobrien { "-Wno-protocol", "Do not warn if inherited methods are unimplemented"}, 115598944Sobrien { "-print-objc-runtime-info", 115698944Sobrien "Generate C header of platform specific features" }, 115719370Spst 115819370Spst#include "options.h" 115919370Spst 116098944Sobrien}; 116119370Spst 116219370Spst/* Here is a table, controlled by the tm.h file, listing each -m switch 116319370Spst and which bits in `target_switches' it should set or clear. 116419370Spst If VALUE is positive, it is bits to set. 116519370Spst If VALUE is negative, -VALUE is bits to clear. 116619370Spst (The sign bit is not used so there is no confusion.) */ 116719370Spst 116819370Spststruct 116919370Spst{ 117019370Spst const char * name; 117119370Spst int value; 117219370Spst const char * description; 117398944Sobrien} 117419370Spsttarget_switches [] = TARGET_SWITCHES; 117519370Spst 117619370Spst/* This table is similar, but allows the switch to have a value. */ 117719370Spst 117819370Spst#ifdef TARGET_OPTIONS 117919370Spststruct 118019370Spst{ 118119370Spst const char * prefix; 118219370Spst const char ** variable; 118398944Sobrien const char * description; 118419370Spst} 118519370Spsttarget_options [] = TARGET_OPTIONS; 118619370Spst#endif 118719370Spst 118819370Spst/* Options controlling warnings */ 118919370Spst 119019370Spst/* Don't print warning messages. -w. */ 119119370Spst 119219370Spstint inhibit_warnings = 0; 119398944Sobrien 119419370Spst/* Print various extra warnings. -W. */ 119598944Sobrien 119698944Sobrienint extra_warnings = 0; 119798944Sobrien 119898944Sobrien/* Treat warnings as errors. -Werror. */ 119919370Spst 120019370Spstint warnings_are_errors = 0; 120119370Spst 120219370Spst/* Nonzero to warn about unused local variables. */ 120319370Spst 120419370Spstint warn_unused; 1205130803Smarcel 120619370Spst/* Nonzero to warn about variables used before they are initialized. */ 120719370Spst 120819370Spstint warn_uninitialized; 120919370Spst 121019370Spst/* Nonzero means warn about all declarations which shadow others. */ 121119370Spst 121219370Spstint warn_shadow; 121319370Spst 121419370Spst/* Warn if a switch on an enum fails to have a case for every enum value. */ 121519370Spst 121619370Spstint warn_switch; 121719370Spst 121898944Sobrien/* Nonzero means warn about function definitions that default the return type 121998944Sobrien or that use a null return and have a return-type other than void. */ 122098944Sobrien 1221130803Smarcelint warn_return_type; 122246283Sdfr 122398944Sobrien/* Nonzero means warn about pointer casts that increase the required 122419370Spst alignment of the target type (and might therefore lead to a crash 122519370Spst due to a misaligned access). */ 122619370Spst 122719370Spstint warn_cast_align; 122819370Spst 122919370Spst/* Nonzero means warn about any identifiers that match in the first N 123046283Sdfr characters. The value N is in `id_clash_len'. */ 1231194061Savg 1232194061Savgint warn_id_clash; 1233194061Savgunsigned id_clash_len; 1234194061Savg 1235194061Savg/* Nonzero means warn about any objects definitions whose size is larger 1236194061Savg than N bytes. Also want about function definitions whose returned 1237194061Savg values are larger than N bytes. The value N is in `larger_than_size'. */ 1238194061Savg 1239194061Savgint warn_larger_than; 1240194061Savgunsigned larger_than_size; 1241194061Savg 1242194061Savg/* Nonzero means warn if inline function is too large. */ 1243194061Savg 1244194061Savgint warn_inline; 1245194061Savg 1246194061Savg/* Warn if a function returns an aggregate, 124746283Sdfr since there are often incompatible calling conventions for doing this. */ 124898944Sobrien 124946283Sdfrint warn_aggregate_return; 125098944Sobrien 125198944Sobrien/* Likewise for -W. */ 125298944Sobrien 125398944Sobrienlang_independent_options W_options[] = 1254194061Savg{ 125546283Sdfr {"unused", &warn_unused, 1, "Warn when a variable is unused" }, 125698944Sobrien {"error", &warnings_are_errors, 1, ""}, 125746283Sdfr {"shadow", &warn_shadow, 1, "Warn when one local variable shadows another" }, 125846283Sdfr {"switch", &warn_switch, 1, 125946283Sdfr "Warn about enumerated switches missing a specific case" }, 126098944Sobrien {"aggregate-return", &warn_aggregate_return, 1, 126198944Sobrien "Warn about returning structures, unions or arrays" }, 126246283Sdfr {"cast-align", &warn_cast_align, 1, 126398944Sobrien "Warn about pointer casts which increase alignment" }, 126498944Sobrien {"uninitialized", &warn_uninitialized, 1, 126598944Sobrien "Warn about unitialized automatic variables"}, 126646283Sdfr {"inline", &warn_inline, 1, 126798944Sobrien "Warn when an inlined function cannot be inlined"} 126898944Sobrien}; 126946283Sdfr 127098944Sobrien/* Output files for assembler code (real compiler output) 127198944Sobrien and debugging dumps. */ 127298944Sobrien 127398944SobrienFILE *asm_out_file; 127498944SobrienFILE *aux_info_file; 127598944SobrienFILE *rtl_dump_file = NULL; 127698944Sobrien 127798944Sobrien/* Decode the string P as an integral parameter. 127846283Sdfr If the string is indeed an integer return its numeric value else 127946283Sdfr issue an Invalid Option error for the option PNAME and return DEFVAL. 128098944Sobrien If PNAME is zero just return DEFVAL, do not call error. */ 128198944Sobrien 128298944Sobrienint 128398944Sobrienread_integral_parameter (p, pname, defval) 128498944Sobrien const char *p; 128598944Sobrien const char *pname; 128698944Sobrien const int defval; 128798944Sobrien{ 128898944Sobrien const char *endp = p; 128998944Sobrien 129098944Sobrien while (*endp) 129198944Sobrien { 129298944Sobrien if (*endp >= '0' && *endp <= '9') 129398944Sobrien endp++; 129498944Sobrien else 129598944Sobrien break; 129698944Sobrien } 129798944Sobrien 129898944Sobrien if (*endp != 0) 129998944Sobrien { 130098944Sobrien if (pname != 0) 130198944Sobrien error ("Invalid option `%s'", pname); 130246283Sdfr return defval; 130346283Sdfr } 1304194061Savg 1305194061Savg return atoi (p); 1306194061Savg} 1307194061Savg 130846283Sdfr 130946283Sdfr/* Time accumulators, to count the total time spent in various passes. */ 131098944Sobrien 131146283Sdfrint parse_time; 131246283Sdfrint varconst_time; 131398944Sobrienint integration_time; 131446283Sdfrint jump_time; 131546283Sdfrint cse_time; 131698944Sobrienint gcse_time; 131746283Sdfrint loop_time; 131898944Sobrienint cse2_time; 131946283Sdfrint branch_prob_time; 1320194061Savgint flow_time; 1321194061Savgint combine_time; 1322194061Savgint regmove_time; 1323194061Savgint sched_time; 1324194061Savgint local_alloc_time; 132546283Sdfrint global_alloc_time; 132698944Sobrienint flow2_time; 132746283Sdfrint sched2_time; 132819370Spst#ifdef DELAY_SLOTS 132919370Spstint dbr_sched_time; 133019370Spst#endif 133119370Spstint shorten_branch_time; 1332130803Smarcelint stack_reg_time; 1333130803Smarcelint final_time; 133419370Spstint symout_time; 1335130803Smarcelint dump_time; 1336130803Smarcel 1337130803Smarcel/* Return time used so far, in microseconds. */ 1338130803Smarcel 133919370Spstlong 1340130803Smarcelget_run_time () 134119370Spst{ 134219370Spst if (quiet_flag) 134319370Spst return 0; 134419370Spst 134519370Spst#ifdef __BEOS__ 134619370Spst return 0; 134719370Spst#else /* not BeOS */ 1348130803Smarcel#if defined (_WIN32) && !defined (__CYGWIN__) 134919370Spst if (clock() < 0) 135046283Sdfr return 0; 135198944Sobrien else 1352130803Smarcel return (clock() * 1000); 135319370Spst#else /* not _WIN32 */ 135419370Spst#ifdef _SC_CLK_TCK 135519370Spst { 135619370Spst static int tick; 135719370Spst struct tms tms; 135819370Spst if (tick == 0) 135919370Spst tick = 1000000 / sysconf(_SC_CLK_TCK); 136019370Spst times (&tms); 136119370Spst return (tms.tms_utime + tms.tms_stime) * tick; 136219370Spst } 136319370Spst#else 136419370Spst#ifdef USG 136519370Spst { 136619370Spst struct tms tms; 136719370Spst# if HAVE_SYSCONF && defined _SC_CLK_TCK 136819370Spst# define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */ 136998944Sobrien# else 1370130803Smarcel# ifdef CLK_TCK 137119370Spst# define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */ 1372130803Smarcel# else 1373130803Smarcel# define TICKS_PER_SECOND HZ /* traditional UNIX */ 1374130803Smarcel# endif 137519370Spst# endif 1376130803Smarcel times (&tms); 137719370Spst return (tms.tms_utime + tms.tms_stime) * (1000000 / TICKS_PER_SECOND); 1378130803Smarcel } 137919370Spst#else 138019370Spst#ifndef VMS 138119370Spst { 138219370Spst struct rusage rusage; 138319370Spst getrusage (0, &rusage); 138419370Spst return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec 138519370Spst + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec); 138619370Spst } 138719370Spst#else /* VMS */ 138819370Spst { 1389130803Smarcel struct 139019370Spst { 139119370Spst int proc_user_time; 139219370Spst int proc_system_time; 139319370Spst int child_user_time; 139419370Spst int child_system_time; 139519370Spst } vms_times; 139619370Spst times ((void *) &vms_times); 139719370Spst return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000; 139819370Spst } 139919370Spst#endif /* VMS */ 140019370Spst#endif /* USG */ 140119370Spst#endif /* _SC_CLK_TCK */ 140219370Spst#endif /* _WIN32 */ 140319370Spst#endif /* __BEOS__ */ 140419370Spst} 140519370Spst 140619370Spst#define TIMEVAR(VAR, BODY) \ 140719370Spstdo { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0) 140819370Spst 140919370Spstvoid 141019370Spstprint_time (str, total) 1411130803Smarcel const char *str; 1412130803Smarcel int total; 141319370Spst{ 1414130803Smarcel fprintf (stderr, 1415130803Smarcel "time in %s: %d.%06d\n", 141619370Spst str, total / 1000000, total % 1000000); 141719370Spst} 141819370Spst 141919370Spst/* Count an error or warning. Return 1 if the message should be printed. */ 142019370Spst 142119370Spstint 142298944Sobriencount_error (warningp) 142319370Spst int warningp; 142419370Spst{ 142546283Sdfr if (warningp && inhibit_warnings) 142619370Spst return 0; 142719370Spst 142898944Sobrien if (warningp && !warnings_are_errors) 142998944Sobrien warningcount++; 143019370Spst else 143119370Spst { 143219370Spst static int warning_message = 0; 143319370Spst 143419370Spst if (warningp && !warning_message) 143519370Spst { 143619370Spst notice ("%s: warnings being treated as errors\n", progname); 143719370Spst warning_message = 1; 143819370Spst } 143919370Spst errorcount++; 144019370Spst } 144119370Spst 144219370Spst return 1; 144319370Spst} 1444130803Smarcel 1445130803Smarcel/* Print a fatal error message. NAME is the text. 144619370Spst Also include a system error message based on `errno'. */ 1447130803Smarcel 1448130803Smarcelvoid 1449130803Smarcelpfatal_with_name (name) 145019370Spst const char *name; 145119370Spst{ 1452130803Smarcel fprintf (stderr, "%s: ", progname); 145319370Spst perror (name); 145419370Spst exit (FATAL_EXIT_CODE); 145519370Spst} 145619370Spst 145719370Spstvoid 145819370Spstfatal_io_error (name) 145919370Spst const char *name; 146019370Spst{ 146119370Spst notice ("%s: %s: I/O error\n", progname, name); 146219370Spst exit (FATAL_EXIT_CODE); 146319370Spst} 146419370Spst 146519370Spst/* Called to give a better error message for a bad insn rather than 146619370Spst just calling abort(). */ 146719370Spst 146819370Spstvoid 146919370Spstfatal_insn VPROTO((const char *msgid, rtx insn, ...)) 147019370Spst{ 147119370Spst#ifndef ANSI_PROTOTYPES 147219370Spst const char *msgid; 147319370Spst rtx insn; 147419370Spst#endif 147519370Spst va_list ap; 147619370Spst 147719370Spst VA_START (ap, insn); 147819370Spst 147919370Spst#ifndef ANSI_PROTOTYPES 148019370Spst msgid = va_arg (ap, const char *); 148119370Spst insn = va_arg (ap, rtx); 148219370Spst#endif 148319370Spst 148419370Spst verror (msgid, ap); 148519370Spst debug_rtx (insn); 148619370Spst exit (FATAL_EXIT_CODE); 148719370Spst} 148819370Spst 148919370Spst/* Called to give a better error message when we don't have an insn to match 149019370Spst what we are looking for or if the insn's constraints aren't satisfied, 149119370Spst rather than just calling abort(). */ 149219370Spst 149319370Spstvoid 149419370Spstfatal_insn_not_found (insn) 149519370Spst rtx insn; 149619370Spst{ 149719370Spst if (INSN_CODE (insn) < 0) 149898944Sobrien fatal_insn ("internal error--unrecognizable insn:", insn); 149998944Sobrien else 150019370Spst fatal_insn ("internal error--insn does not satisfy its constraints:", insn); 150119370Spst} 150219370Spst 150319370Spst/* This is the default decl_printable_name function. */ 150419370Spst 150519370Spststatic char * 150619370Spstdecl_name (decl, verbosity) 150719370Spst tree decl; 150819370Spst int verbosity ATTRIBUTE_UNUSED; 150919370Spst{ 151019370Spst return IDENTIFIER_POINTER (DECL_NAME (decl)); 151146283Sdfr} 151298944Sobrien 151319370Spststatic int need_error_newline; 1514130803Smarcel 151519370Spst/* Function of last error message; 1516130803Smarcel more generally, function such that if next error message is in it 151719370Spst then we don't have to mention the function name. */ 151819370Spststatic tree last_error_function = NULL; 151919370Spst 152098944Sobrien/* Used to detect when input_file_stack has changed since last described. */ 152119370Spststatic int last_error_tick; 152298944Sobrien 152346283Sdfr/* Called when the start of a function definition is parsed, 152498944Sobrien this function prints on stderr the name of the function. */ 152546283Sdfr 152646283Sdfrvoid 152746283Sdfrannounce_function (decl) 152846283Sdfr tree decl; 152946283Sdfr{ 153046283Sdfr if (! quiet_flag) 153146283Sdfr { 153246283Sdfr if (rtl_dump_and_exit) 1533130803Smarcel fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl))); 153498944Sobrien else 153546283Sdfr fprintf (stderr, " %s", (*decl_printable_name) (decl, 2)); 153646283Sdfr fflush (stderr); 153746283Sdfr need_error_newline = 1; 153846283Sdfr last_error_function = current_function_decl; 153998944Sobrien } 1540130803Smarcel} 154198944Sobrien 154298944Sobrien/* The default function to print out name of current function that caused 1543130803Smarcel an error. */ 154446283Sdfr 154519370Spstvoid 154619370Spstdefault_print_error_function (file) 154719370Spst const char *file; 1548130803Smarcel{ 1549130803Smarcel if (last_error_function != current_function_decl) 155019370Spst { 155119370Spst if (file) 1552130803Smarcel fprintf (stderr, "%s: ", file); 1553130803Smarcel 1554130803Smarcel if (current_function_decl == NULL) 1555130803Smarcel notice ("At top level:\n"); 155619370Spst else 155719370Spst notice ((TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE 155819370Spst ? "In method `%s':\n" 155919370Spst : "In function `%s':\n"), 156019370Spst (*decl_printable_name) (current_function_decl, 2)); 156119370Spst 156219370Spst last_error_function = current_function_decl; 156319370Spst } 1564130803Smarcel} 156519370Spst 156619370Spst/* Called by report_error_function to print out function name. 156719370Spst * Default may be overridden by language front-ends. */ 156819370Spst 156919370Spstvoid (*print_error_function) PROTO((const char *)) = 157019370Spst default_print_error_function; 157119370Spst 157219370Spst/* Prints out, if necessary, the name of the current function 157319370Spst that caused an error. Called from all error and warning functions. 1574130803Smarcel We ignore the FILE parameter, as it cannot be relied upon. */ 157519370Spst 1576130803Smarcelvoid 157719370Spstreport_error_function (file) 157819370Spst const char *file ATTRIBUTE_UNUSED; 157919370Spst{ 158019370Spst struct file_stack *p; 158119370Spst 158219370Spst if (need_error_newline) 158319370Spst { 158419370Spst fprintf (stderr, "\n"); 158519370Spst need_error_newline = 0; 158619370Spst } 158719370Spst 158819370Spst if (input_file_stack && input_file_stack->next != 0 158919370Spst && input_file_stack_tick != last_error_tick) 1590130803Smarcel { 1591130803Smarcel for (p = input_file_stack->next; p; p = p->next) 159219370Spst notice ((p == input_file_stack->next 159319370Spst ? "In file included from %s:%d" 159419370Spst : ",\n from %s:%d"), 159519370Spst p->name, p->line); 159619370Spst fprintf (stderr, ":\n"); 159719370Spst last_error_tick = input_file_stack_tick; 159819370Spst } 159919370Spst 160019370Spst (*print_error_function) (input_filename); 160119370Spst} 160219370Spst 160319370Spst/* Print a message. */ 160419370Spst 160519370Spststatic void 160619370Spstvnotice (file, msgid, ap) 160746283Sdfr FILE *file; 160898944Sobrien char *msgid; 160919370Spst va_list ap; 1610130803Smarcel{ 161119370Spst vfprintf (file, _(msgid), ap); 1612130803Smarcel} 161319370Spst 161446283Sdfrvoid 161546283Sdfrnotice VPROTO((const char *msgid, ...)) 161646283Sdfr{ 161798944Sobrien#ifndef ANSI_PROTOTYPES 161846283Sdfr char *msgid; 161998944Sobrien#endif 162098944Sobrien va_list ap; 162146283Sdfr 162298944Sobrien VA_START (ap, msgid); 162346283Sdfr 1624130803Smarcel#ifndef ANSI_PROTOTYPES 1625130803Smarcel msgid = va_arg (ap, char *); 1626130803Smarcel#endif 1627130803Smarcel 162819370Spst vnotice (stderr, msgid, ap); 1629130803Smarcel va_end (ap); 163019370Spst} 163198944Sobrien 1632130803Smarcelvoid 163319370Spstfnotice VPROTO((FILE *file, const char *msgid, ...)) 163419370Spst{ 163598944Sobrien#ifndef ANSI_PROTOTYPES 1636130803Smarcel FILE *file; 1637130803Smarcel const char *msgid; 163819370Spst#endif 1639130803Smarcel va_list ap; 1640130803Smarcel 1641130803Smarcel VA_START (ap, msgid); 164246283Sdfr 164319370Spst#ifndef ANSI_PROTOTYPES 1644130803Smarcel file = va_arg (ap, FILE *); 164519370Spst msgid = va_arg (ap, const char *); 164619370Spst#endif 164719370Spst 164819370Spst vnotice (file, msgid, ap); 1649130803Smarcel va_end (ap); 1650130803Smarcel} 1651130803Smarcel 1652130803Smarcel/* Report FILE and LINE (or program name), and optionally just WARN. */ 1653130803Smarcel 1654130803Smarcelstatic void 1655130803Smarcelreport_file_and_line (file, line, warn) 1656130803Smarcel char *file; 1657130803Smarcel int line; 1658130803Smarcel int warn; 1659130803Smarcel{ 1660130803Smarcel if (file) 1661130803Smarcel fprintf (stderr, "%s:%d: ", file, line); 1662130803Smarcel else 1663130803Smarcel fprintf (stderr, "%s: ", progname); 1664130803Smarcel 1665130803Smarcel if (warn) 1666130803Smarcel notice ("warning: "); 166719370Spst} 166819370Spst 166919370Spst/* Print a message. */ 167019370Spst 167119370Spststatic void 167219370Spstvmessage (prefix, msgid, ap) 167319370Spst const char *prefix; 167419370Spst const char *msgid; 167519370Spst va_list ap; 167619370Spst{ 167719370Spst if (prefix) 167819370Spst fprintf (stderr, "%s: ", prefix); 1679130803Smarcel 1680130803Smarcel vfprintf (stderr, msgid, ap); 168119370Spst} 1682130803Smarcel 1683130803Smarcel/* Print a message relevant to line LINE of file FILE. */ 168419370Spst 168519370Spststatic void 168619370Spstv_message_with_file_and_line (file, line, warn, msgid, ap) 168719370Spst const char *file; 168819370Spst int line; 168919370Spst int warn; 169019370Spst const char *msgid; 169119370Spst va_list ap; 169219370Spst{ 169319370Spst report_file_and_line (file, line, warn); 169419370Spst vnotice (stderr, msgid, ap); 169519370Spst fputc ('\n', stderr); 169619370Spst} 169719370Spst 169898944Sobrien/* Print a message relevant to the given DECL. */ 169998944Sobrien 170098944Sobrienstatic void 170198944Sobrienv_message_with_decl (decl, warn, msgid, ap) 170298944Sobrien tree decl; 170398944Sobrien int warn; 170498944Sobrien const char *msgid; 170598944Sobrien va_list ap; 170619370Spst{ 170719370Spst const char *p; 170819370Spst 170919370Spst report_file_and_line (DECL_SOURCE_FILE (decl), 171019370Spst DECL_SOURCE_LINE (decl), warn); 171119370Spst 171219370Spst /* Do magic to get around lack of varargs support for insertion 171319370Spst of arguments into existing list. We know that the decl is first; 171419370Spst we ass_u_me that it will be printed with "%s". */ 171519370Spst 171698944Sobrien for (p = _(msgid); *p; ++p) 171798944Sobrien { 171819370Spst if (*p == '%') 1719130803Smarcel { 1720130803Smarcel if (*(p + 1) == '%') 172119370Spst ++p; 172219370Spst else if (*(p + 1) != 's') 172319370Spst abort (); 172419370Spst else 172519370Spst break; 172619370Spst } 1727130803Smarcel } 1728130803Smarcel 1729130803Smarcel if (p > _(msgid)) /* Print the left-hand substring. */ 173019370Spst { 173119370Spst char fmt[sizeof "%.255s"]; 173219370Spst long width = p - _(msgid); 173319370Spst 173419370Spst if (width > 255L) width = 255L; /* arbitrary */ 173519370Spst sprintf (fmt, "%%.%lds", width); 173646283Sdfr fprintf (stderr, fmt, _(msgid)); 173798944Sobrien } 173819370Spst 173919370Spst if (*p == '%') /* Print the name. */ 1740130803Smarcel { 1741130803Smarcel const char *n = (DECL_NAME (decl) 174219370Spst ? (*decl_printable_name) (decl, 2) 174319370Spst : "((anonymous))"); 174446283Sdfr fputs (n, stderr); 174546283Sdfr while (*p) 174698944Sobrien { 174798944Sobrien ++p; 174846283Sdfr if (ISALPHA (*(p - 1) & 0xFF)) 1749130803Smarcel break; 175098944Sobrien } 1751130803Smarcel } 1752130803Smarcel 175398944Sobrien if (*p) /* Print the rest of the message. */ 175446283Sdfr vmessage ((char *)NULL, p, ap); 175519370Spst 175619370Spst fputc ('\n', stderr); 175719370Spst} 175819370Spst 175998944Sobrien/* Figure file and line of the given INSN. */ 176019370Spst 1761130803Smarcelstatic void 176219370Spstfile_and_line_for_asm (insn, pfile, pline) 176319370Spst rtx insn; 176498944Sobrien char **pfile; 176519370Spst int *pline; 176698944Sobrien{ 1767130803Smarcel rtx body = PATTERN (insn); 176819370Spst rtx asmop; 176919370Spst 1770130803Smarcel /* Find the (or one of the) ASM_OPERANDS in the insn. */ 177119370Spst if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) 177219370Spst asmop = SET_SRC (body); 1773130803Smarcel else if (GET_CODE (body) == ASM_OPERANDS) 1774130803Smarcel asmop = body; 177519370Spst else if (GET_CODE (body) == PARALLEL 177619370Spst && GET_CODE (XVECEXP (body, 0, 0)) == SET) 177719370Spst asmop = SET_SRC (XVECEXP (body, 0, 0)); 177898944Sobrien else if (GET_CODE (body) == PARALLEL 177946283Sdfr && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) 178098944Sobrien asmop = XVECEXP (body, 0, 0); 178146283Sdfr else 178246283Sdfr asmop = NULL; 178346283Sdfr 178498944Sobrien if (asmop) 178519370Spst { 178646283Sdfr *pfile = ASM_OPERANDS_SOURCE_FILE (asmop); 1787130803Smarcel *pline = ASM_OPERANDS_SOURCE_LINE (asmop); 1788130803Smarcel } 178919370Spst else 179019370Spst { 179119370Spst *pfile = input_filename; 179219370Spst *pline = lineno; 179319370Spst } 179419370Spst} 179598944Sobrien 179619370Spst/* Report an error at line LINE of file FILE. */ 1797130803Smarcel 179819370Spststatic void 179919370Spstv_error_with_file_and_line (file, line, msgid, ap) 180098944Sobrien const char *file; 180119370Spst int line; 180298944Sobrien const char *msgid; 1803130803Smarcel va_list ap; 180419370Spst{ 180519370Spst count_error (0); 1806130803Smarcel report_error_function (file); 180719370Spst v_message_with_file_and_line (file, line, 0, msgid, ap); 180819370Spst} 180919370Spst 181019370Spstvoid 181198944Sobrienerror_with_file_and_line VPROTO((const char *file, int line, 181298944Sobrien const char *msgid, ...)) 181398944Sobrien{ 181419370Spst#ifndef ANSI_PROTOTYPES 181519370Spst const char *file; 181619370Spst int line; 181719370Spst const char *msgid; 1818130803Smarcel#endif 1819130803Smarcel va_list ap; 182019370Spst 182119370Spst VA_START (ap, msgid); 182246283Sdfr 182398944Sobrien#ifndef ANSI_PROTOTYPES 182446283Sdfr file = va_arg (ap, const char *); 182546283Sdfr line = va_arg (ap, int); 182646283Sdfr msgid = va_arg (ap, const char *); 182719370Spst#endif 182819370Spst 182998944Sobrien v_error_with_file_and_line (file, line, msgid, ap); 183019370Spst va_end (ap); 183146283Sdfr} 1832130803Smarcel 1833130803Smarcel/* Report an error at the declaration DECL. 183419370Spst MSGID is a format string which uses %s to substitute the declaration 183519370Spst name; subsequent substitutions are a la printf. */ 183698944Sobrien 183798944Sobrienstatic void 183819370Spstv_error_with_decl (decl, msgid, ap) 183919370Spst tree decl; 184098944Sobrien const char *msgid; 1841130803Smarcel va_list ap; 184219370Spst{ 1843130803Smarcel count_error (0); 1844130803Smarcel report_error_function (DECL_SOURCE_FILE (decl)); 1845130803Smarcel v_message_with_decl (decl, 0, msgid, ap); 1846130803Smarcel} 1847130803Smarcel 184819370Spstvoid 1849130803Smarcelerror_with_decl VPROTO((tree decl, const char *msgid, ...)) 185019370Spst{ 1851130803Smarcel#ifndef ANSI_PROTOTYPES 1852130803Smarcel tree decl; 1853130803Smarcel const char *msgid; 1854130803Smarcel#endif 185519370Spst va_list ap; 185619370Spst 185719370Spst VA_START (ap, msgid); 185819370Spst 1859130803Smarcel#ifndef ANSI_PROTOTYPES 1860130803Smarcel decl = va_arg (ap, tree); 186119370Spst msgid = va_arg (ap, const char *); 186219370Spst#endif 1863130803Smarcel 1864130803Smarcel v_error_with_decl (decl, msgid, ap); 186519370Spst va_end (ap); 186619370Spst} 186719370Spst 186819370Spst/* Report an error at the line number of the insn INSN. 186919370Spst This is used only when INSN is an `asm' with operands, 187019370Spst and each ASM_OPERANDS records its own source file and line. */ 1871130803Smarcel 1872130803Smarcelstatic void 187319370Spstv_error_for_asm (insn, msgid, ap) 187419370Spst rtx insn; 1875130803Smarcel const char *msgid; 1876130803Smarcel va_list ap; 1877130803Smarcel{ 1878130803Smarcel char *file; 1879130803Smarcel int line; 1880130803Smarcel 1881130803Smarcel count_error (0); 1882130803Smarcel file_and_line_for_asm (insn, &file, &line); 1883130803Smarcel report_error_function (file); 1884130803Smarcel v_message_with_file_and_line (file, line, 0, msgid, ap); 1885130803Smarcel} 1886130803Smarcel 1887130803Smarcelvoid 1888130803Smarcelerror_for_asm VPROTO((rtx insn, const char *msgid, ...)) 1889130803Smarcel{ 1890130803Smarcel#ifndef ANSI_PROTOTYPES 1891130803Smarcel rtx insn; 1892130803Smarcel const char *msgid; 1893130803Smarcel#endif 1894130803Smarcel va_list ap; 1895130803Smarcel 1896130803Smarcel VA_START (ap, msgid); 1897130803Smarcel 1898130803Smarcel#ifndef ANSI_PROTOTYPES 1899130803Smarcel insn = va_arg (ap, rtx); 1900130803Smarcel msgid = va_arg (ap, const char *); 1901130803Smarcel#endif 1902130803Smarcel 1903130803Smarcel v_error_for_asm (insn, msgid, ap); 1904130803Smarcel va_end (ap); 1905130803Smarcel} 190619370Spst 190719370Spst/* Report an error at the current line number. */ 1908130803Smarcel 1909130803Smarcelstatic void 1910130803Smarcelverror (msgid, ap) 191119370Spst const char *msgid; 191219370Spst va_list ap; 1913130803Smarcel{ 1914130803Smarcel v_error_with_file_and_line (input_filename, lineno, msgid, ap); 1915130803Smarcel} 1916130803Smarcel 1917130803Smarcelvoid 1918130803Smarcelerror VPROTO((const char *msgid, ...)) 1919130803Smarcel{ 1920130803Smarcel#ifndef ANSI_PROTOTYPES 1921130803Smarcel const char *msgid; 192219370Spst#endif 192319370Spst va_list ap; 1924130803Smarcel 1925130803Smarcel VA_START (ap, msgid); 1926130803Smarcel 192719370Spst#ifndef ANSI_PROTOTYPES 1928130803Smarcel msgid = va_arg (ap, const char *); 1929130803Smarcel#endif 1930130803Smarcel 1931130803Smarcel verror (msgid, ap); 1932130803Smarcel va_end (ap); 1933130803Smarcel} 1934130803Smarcel 1935130803Smarcel/* Report a fatal error at the current line number. */ 1936130803Smarcel 1937130803Smarcelstatic void 1938130803Smarcelvfatal (msgid, ap) 1939130803Smarcel const char *msgid; 1940130803Smarcel va_list ap; 194119370Spst{ 1942130803Smarcel verror (msgid, ap); 1943130803Smarcel exit (FATAL_EXIT_CODE); 1944130803Smarcel} 194519370Spst 1946130803Smarcelvoid 1947130803Smarcelfatal VPROTO((const char *msgid, ...)) 1948130803Smarcel{ 1949130803Smarcel#ifndef ANSI_PROTOTYPES 1950130803Smarcel const char *msgid; 1951130803Smarcel#endif 1952130803Smarcel va_list ap; 1953130803Smarcel 1954130803Smarcel VA_START (ap, msgid); 1955130803Smarcel 1956130803Smarcel#ifndef ANSI_PROTOTYPES 1957130803Smarcel msgid = va_arg (ap, const char *); 1958130803Smarcel#endif 1959130803Smarcel 1960130803Smarcel vfatal (msgid, ap); 1961130803Smarcel va_end (ap); 1962130803Smarcel} 1963130803Smarcel 1964130803Smarcel/* Report a warning at line LINE of file FILE. */ 1965130803Smarcel 1966130803Smarcelstatic void 1967130803Smarcelv_warning_with_file_and_line (file, line, msgid, ap) 1968130803Smarcel const char *file; 196919370Spst int line; 1970130803Smarcel const char *msgid; 1971130803Smarcel va_list ap; 1972130803Smarcel{ 1973130803Smarcel if (count_error (1)) 1974130803Smarcel { 1975130803Smarcel report_error_function (file); 1976130803Smarcel v_message_with_file_and_line (file, line, 1, msgid, ap); 1977130803Smarcel } 1978130803Smarcel} 1979130803Smarcel 1980130803Smarcelvoid 1981130803Smarcelwarning_with_file_and_line VPROTO((const char *file, int line, 1982130803Smarcel const char *msgid, ...)) 1983130803Smarcel{ 1984130803Smarcel#ifndef ANSI_PROTOTYPES 1985130803Smarcel const char *file; 198619370Spst int line; 198719370Spst const char *msgid; 198819370Spst#endif 198919370Spst va_list ap; 199019370Spst 199119370Spst VA_START (ap, msgid); 199219370Spst 199319370Spst#ifndef ANSI_PROTOTYPES 199446283Sdfr file = va_arg (ap, const char *); 199546283Sdfr line = va_arg (ap, int); 199646283Sdfr msgid = va_arg (ap, const char *); 199746283Sdfr#endif 199846283Sdfr 199946283Sdfr v_warning_with_file_and_line (file, line, msgid, ap); 200046283Sdfr va_end (ap); 200146283Sdfr} 200298944Sobrien 200346283Sdfr/* Report a warning at the declaration DECL. 200498944Sobrien MSGID is a format string which uses %s to substitute the declaration 200546283Sdfr name; subsequent substitutions are a la printf. */ 200646283Sdfr 200746283Sdfrstatic void 200846283Sdfrv_warning_with_decl (decl, msgid, ap) 200946283Sdfr tree decl; 201046283Sdfr const char *msgid; 201146283Sdfr va_list ap; 201246283Sdfr{ 201346283Sdfr if (count_error (1)) 201446283Sdfr { 201546283Sdfr report_error_function (DECL_SOURCE_FILE (decl)); 201646283Sdfr v_message_with_decl (decl, 1, msgid, ap); 201746283Sdfr } 201846283Sdfr} 201946283Sdfr 202046283Sdfrvoid 202146283Sdfrwarning_with_decl VPROTO((tree decl, const char *msgid, ...)) 202246283Sdfr{ 202346283Sdfr#ifndef ANSI_PROTOTYPES 202446283Sdfr tree decl; 202546283Sdfr const char *msgid; 202646283Sdfr#endif 202746283Sdfr va_list ap; 202846283Sdfr 202946283Sdfr VA_START (ap, msgid); 203046283Sdfr 203146283Sdfr#ifndef ANSI_PROTOTYPES 203246283Sdfr decl = va_arg (ap, tree); 203346283Sdfr msgid = va_arg (ap, const char *); 203446283Sdfr#endif 203546283Sdfr 2036130803Smarcel v_warning_with_decl (decl, msgid, ap); 2037130803Smarcel va_end (ap); 203846283Sdfr} 203946283Sdfr 204046283Sdfr/* Report a warning at the line number of the insn INSN. 204146283Sdfr This is used only when INSN is an `asm' with operands, 204246283Sdfr and each ASM_OPERANDS records its own source file and line. */ 204346283Sdfr 204446283Sdfrstatic void 204546283Sdfrv_warning_for_asm (insn, msgid, ap) 204646283Sdfr rtx insn; 204798944Sobrien const char *msgid; 204846283Sdfr va_list ap; 204946283Sdfr{ 205046283Sdfr if (count_error (1)) 2051130803Smarcel { 2052130803Smarcel char *file; 205346283Sdfr int line; 205446283Sdfr 205519370Spst file_and_line_for_asm (insn, &file, &line); 205619370Spst report_error_function (file); 205719370Spst v_message_with_file_and_line (file, line, 1, msgid, ap); 205898944Sobrien } 205919370Spst} 2060130803Smarcel 206119370Spstvoid 206298944Sobrienwarning_for_asm VPROTO((rtx insn, const char *msgid, ...)) 2063130803Smarcel{ 206419370Spst#ifndef ANSI_PROTOTYPES 2065130803Smarcel rtx insn; 2066130803Smarcel const char *msgid; 2067130803Smarcel#endif 2068130803Smarcel va_list ap; 2069130803Smarcel 2070130803Smarcel VA_START (ap, msgid); 2071130803Smarcel 2072130803Smarcel#ifndef ANSI_PROTOTYPES 207319370Spst insn = va_arg (ap, rtx); 207419370Spst msgid = va_arg (ap, const char *); 207519370Spst#endif 207619370Spst 207719370Spst v_warning_for_asm (insn, msgid, ap); 207819370Spst va_end (ap); 207919370Spst} 208019370Spst 208119370Spst/* Report a warning at the current line number. */ 208219370Spst 208319370Spststatic void 208419370Spstvwarning (msgid, ap) 208598944Sobrien const char *msgid; 208619370Spst va_list ap; 208798944Sobrien{ 208819370Spst v_warning_with_file_and_line (input_filename, lineno, msgid, ap); 208919370Spst} 209019370Spst 209119370Spstvoid 209219370Spstwarning VPROTO((const char *msgid, ...)) 209319370Spst{ 209419370Spst#ifndef ANSI_PROTOTYPES 209519370Spst const char *msgid; 209619370Spst#endif 209719370Spst va_list ap; 209819370Spst 209919370Spst VA_START (ap, msgid); 210019370Spst 210119370Spst#ifndef ANSI_PROTOTYPES 210219370Spst msgid = va_arg (ap, const char *); 210319370Spst#endif 210419370Spst 210519370Spst vwarning (msgid, ap); 210619370Spst va_end (ap); 210719370Spst} 210819370Spst 210919370Spst/* These functions issue either warnings or errors depending on 211019370Spst -pedantic-errors. */ 211119370Spst 211219370Spststatic void 211319370Spstvpedwarn (msgid, ap) 211419370Spst const char *msgid; 211519370Spst va_list ap; 211619370Spst{ 211719370Spst if (flag_pedantic_errors) 211819370Spst verror (msgid, ap); 211919370Spst else 212019370Spst vwarning (msgid, ap); 212119370Spst} 212219370Spst 212346283Sdfrvoid 212446283Sdfrpedwarn VPROTO((const char *msgid, ...)) 212598944Sobrien{ 212698944Sobrien#ifndef ANSI_PROTOTYPES 212746283Sdfr const char *msgid; 212846283Sdfr#endif 212919370Spst va_list ap; 213019370Spst 213119370Spst VA_START (ap, msgid); 213219370Spst 213319370Spst#ifndef ANSI_PROTOTYPES 213419370Spst msgid = va_arg (ap, const char *); 213519370Spst#endif 213646283Sdfr 213746283Sdfr vpedwarn (msgid, ap); 213819370Spst va_end (ap); 213946283Sdfr} 214046283Sdfr 214146283Sdfrstatic void 214246283Sdfrv_pedwarn_with_decl (decl, msgid, ap) 214398944Sobrien tree decl; 214446283Sdfr const char *msgid; 214546283Sdfr va_list ap; 214646283Sdfr{ 214746283Sdfr /* We don't want -pedantic-errors to cause the compilation to fail from 214846283Sdfr "errors" in system header files. Sometimes fixincludes can't fix what's 214919370Spst broken (eg: unsigned char bitfields - fixing it may change the alignment 215019370Spst which will cause programs to mysteriously fail because the C library 215119370Spst or kernel uses the original layout). There's no point in issuing a 215219370Spst warning either, it's just unnecessary noise. */ 215319370Spst 215419370Spst if (! DECL_IN_SYSTEM_HEADER (decl)) 215519370Spst { 215619370Spst if (flag_pedantic_errors) 215719370Spst v_error_with_decl (decl, msgid, ap); 215819370Spst else 215919370Spst v_warning_with_decl (decl, msgid, ap); 216046283Sdfr } 216198944Sobrien} 216298944Sobrien 216346283Sdfrvoid 216446283Sdfrpedwarn_with_decl VPROTO((tree decl, const char *msgid, ...)) 216598944Sobrien{ 216698944Sobrien#ifndef ANSI_PROTOTYPES 216746283Sdfr tree decl; 216819370Spst const char *msgid; 216919370Spst#endif 217019370Spst va_list ap; 217119370Spst 217298944Sobrien VA_START (ap, msgid); 217398944Sobrien 217419370Spst#ifndef ANSI_PROTOTYPES 217519370Spst decl = va_arg (ap, tree); 217698944Sobrien msgid = va_arg (ap, const char *); 217719370Spst#endif 217819370Spst 2179 v_pedwarn_with_decl (decl, msgid, ap); 2180 va_end (ap); 2181} 2182 2183static void 2184v_pedwarn_with_file_and_line (file, line, msgid, ap) 2185 const char *file; 2186 int line; 2187 const char *msgid; 2188 va_list ap; 2189{ 2190 if (flag_pedantic_errors) 2191 v_error_with_file_and_line (file, line, msgid, ap); 2192 else 2193 v_warning_with_file_and_line (file, line, msgid, ap); 2194} 2195 2196void 2197pedwarn_with_file_and_line VPROTO((const char *file, int line, 2198 const char *msgid, ...)) 2199{ 2200#ifndef ANSI_PROTOTYPES 2201 const char *file; 2202 int line; 2203 const char *msgid; 2204#endif 2205 va_list ap; 2206 2207 VA_START (ap, msgid); 2208 2209#ifndef ANSI_PROTOTYPES 2210 file = va_arg (ap, const char *); 2211 line = va_arg (ap, int); 2212 msgid = va_arg (ap, const char *); 2213#endif 2214 2215 v_pedwarn_with_file_and_line (file, line, msgid, ap); 2216 va_end (ap); 2217} 2218 2219/* Apologize for not implementing some feature. */ 2220 2221static void 2222vsorry (msgid, ap) 2223 const char *msgid; 2224 va_list ap; 2225{ 2226 sorrycount++; 2227 if (input_filename) 2228 fprintf (stderr, "%s:%d: ", input_filename, lineno); 2229 else 2230 fprintf (stderr, "%s: ", progname); 2231 notice ("sorry, not implemented: "); 2232 vnotice (stderr, msgid, ap); 2233 fputc ('\n', stderr); 2234} 2235 2236void 2237sorry VPROTO((const char *msgid, ...)) 2238{ 2239#ifndef ANSI_PROTOTYPES 2240 const char *msgid; 2241#endif 2242 va_list ap; 2243 2244 VA_START (ap, msgid); 2245 2246#ifndef ANSI_PROTOTYPES 2247 msgid = va_arg (ap, const char *); 2248#endif 2249 2250 vsorry (msgid, ap); 2251 va_end (ap); 2252} 2253 2254/* Given a partial pathname as input, return another pathname that shares 2255 no elements with the pathname of __FILE__. This is used by abort() to 2256 print `Internal compiler error in expr.c' instead of `Internal compiler 2257 error in ../../egcs/gcc/expr.c'. */ 2258const char * 2259trim_filename (name) 2260 const char *name; 2261{ 2262 static const char *this_file = __FILE__; 2263 const char *p = name, *q = this_file; 2264 2265 while (*p == *q && *p != 0 && *q != 0) p++, q++; 2266 while (p > name && p[-1] != DIR_SEPARATOR 2267#ifdef DIR_SEPARATOR_2 2268 && p[-1] != DIR_SEPARATOR_2 2269#endif 2270 ) 2271 p--; 2272 2273 return p; 2274} 2275 2276/* More 'friendly' abort that prints the line and file. 2277 config.h can #define abort fancy_abort if you like that sort of thing. 2278 2279 I don't think this is actually a good idea. 2280 Other sorts of crashes will look a certain way. 2281 It is a good thing if crashes from calling abort look the same way. 2282 -- RMS */ 2283 2284void 2285fancy_abort () 2286{ 2287 fatal ("internal gcc abort"); 2288} 2289 2290/* This calls abort and is used to avoid problems when abort if a macro. 2291 It is used when we need to pass the address of abort. */ 2292 2293void 2294do_abort () 2295{ 2296 abort (); 2297} 2298 2299/* When `malloc.c' is compiled with `rcheck' defined, 2300 it calls this function to report clobberage. */ 2301 2302void 2303botch (s) 2304 const char * s ATTRIBUTE_UNUSED; 2305{ 2306 abort (); 2307} 2308 2309/* Same as `malloc' but report error if no memory available. */ 2310 2311PTR 2312xmalloc (size) 2313 size_t size; 2314{ 2315 register PTR value; 2316 2317 if (size == 0) 2318 size = 1; 2319 2320 value = (PTR) malloc (size); 2321 if (value == 0) 2322 fatal ("virtual memory exhausted"); 2323 return value; 2324} 2325 2326/* Same as `calloc' but report error if no memory available. */ 2327 2328PTR 2329xcalloc (size1, size2) 2330 size_t size1, size2; 2331{ 2332 register PTR value; 2333 2334 if (size1 == 0 || size2 == 0) 2335 size1 = size2 = 1; 2336 2337 value = (PTR) calloc (size1, size2); 2338 if (value == 0) 2339 fatal ("virtual memory exhausted"); 2340 return value; 2341} 2342 2343 2344/* Same as `realloc' but report error if no memory available. 2345 Also handle null PTR even if the vendor realloc gets it wrong. */ 2346 2347PTR 2348xrealloc (ptr, size) 2349 PTR ptr; 2350 size_t size; 2351{ 2352 register PTR result; 2353 2354 if (size == 0) 2355 size = 1; 2356 2357 result = (ptr ? (PTR) realloc (ptr, size) : (PTR) malloc (size)); 2358 2359 if (!result) 2360 fatal ("virtual memory exhausted"); 2361 2362 return result; 2363} 2364 2365/* Same as `strdup' but report error if no memory available. */ 2366 2367char * 2368xstrdup (s) 2369 register const char *s; 2370{ 2371 register char *result = (char *) malloc (strlen (s) + 1); 2372 2373 if (! result) 2374 fatal ("virtual memory exhausted"); 2375 strcpy (result, s); 2376 return result; 2377} 2378 2379/* Return the logarithm of X, base 2, considering X unsigned, 2380 if X is a power of 2. Otherwise, returns -1. 2381 2382 This should be used via the `exact_log2' macro. */ 2383 2384int 2385exact_log2_wide (x) 2386 register unsigned HOST_WIDE_INT x; 2387{ 2388 register int log = 0; 2389 /* Test for 0 or a power of 2. */ 2390 if (x == 0 || x != (x & -x)) 2391 return -1; 2392 while ((x >>= 1) != 0) 2393 log++; 2394 return log; 2395} 2396 2397/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X. 2398 If X is 0, return -1. 2399 2400 This should be used via the floor_log2 macro. */ 2401 2402int 2403floor_log2_wide (x) 2404 register unsigned HOST_WIDE_INT x; 2405{ 2406 register int log = -1; 2407 while (x != 0) 2408 log++, 2409 x >>= 1; 2410 return log; 2411} 2412 2413static int float_handler_set; 2414int float_handled; 2415jmp_buf float_handler; 2416 2417/* Signals actually come here. */ 2418 2419static void 2420float_signal (signo) 2421 /* If this is missing, some compilers complain. */ 2422 int signo ATTRIBUTE_UNUSED; 2423{ 2424 if (float_handled == 0) 2425 abort (); 2426#if defined (USG) || defined (hpux) 2427 signal (SIGFPE, float_signal); /* re-enable the signal catcher */ 2428#endif 2429 float_handled = 0; 2430 signal (SIGFPE, float_signal); 2431 longjmp (float_handler, 1); 2432} 2433 2434/* Specify where to longjmp to when a floating arithmetic error happens. 2435 If HANDLER is 0, it means don't handle the errors any more. */ 2436 2437void 2438set_float_handler (handler) 2439 jmp_buf handler; 2440{ 2441 float_handled = (handler != 0); 2442 if (handler) 2443 bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler)); 2444 2445 if (float_handled && ! float_handler_set) 2446 { 2447 signal (SIGFPE, float_signal); 2448 float_handler_set = 1; 2449 } 2450} 2451 2452/* This is a wrapper function for code which might elicit an 2453 arithmetic exception. That code should be passed in as a function 2454 pointer FN, and one argument DATA. DATA is usually a struct which 2455 contains the real input and output for function FN. This function 2456 returns 0 (failure) if longjmp was called (i.e. an exception 2457 occured.) It returns 1 (success) otherwise. */ 2458 2459int 2460do_float_handler (fn, data) 2461 void (*fn) PROTO ((PTR)); 2462 PTR data; 2463{ 2464 jmp_buf buf; 2465 2466 if (setjmp (buf)) 2467 { 2468 /* We got here via longjmp() caused by an exception in function fn() */ 2469 set_float_handler (NULL); 2470 return 0; 2471 } 2472 2473 set_float_handler (buf); 2474 (*fn)(data); 2475 set_float_handler (NULL); 2476 return 1; 2477} 2478 2479/* Specify, in HANDLER, where to longjmp to when a floating arithmetic 2480 error happens, pushing the previous specification into OLD_HANDLER. 2481 Return an indication of whether there was a previous handler in effect. */ 2482 2483int 2484push_float_handler (handler, old_handler) 2485 jmp_buf handler, old_handler; 2486{ 2487 int was_handled = float_handled; 2488 2489 float_handled = 1; 2490 if (was_handled) 2491 memcpy ((char *) old_handler, (char *) float_handler, 2492 sizeof (float_handler)); 2493 2494 memcpy ((char *) float_handler, (char *) handler, sizeof (float_handler)); 2495 return was_handled; 2496} 2497 2498/* Restore the previous specification of whether and where to longjmp to 2499 when a floating arithmetic error happens. */ 2500 2501void 2502pop_float_handler (handled, handler) 2503 int handled; 2504 jmp_buf handler; 2505{ 2506 float_handled = handled; 2507 if (handled) 2508 bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler)); 2509} 2510 2511/* Handler for SIGPIPE. */ 2512 2513static void 2514pipe_closed (signo) 2515 /* If this is missing, some compilers complain. */ 2516 int signo ATTRIBUTE_UNUSED; 2517{ 2518 fatal ("output pipe has been closed"); 2519} 2520 2521/* Strip off a legitimate source ending from the input string NAME of 2522 length LEN. Rather than having to know the names used by all of 2523 our front ends, we strip off an ending of a period followed by 2524 up to five characters. (Java uses ".class".) */ 2525 2526void 2527strip_off_ending (name, len) 2528 char *name; 2529 int len; 2530{ 2531 int i; 2532 for (i = 2; i < 6 && len > i; i++) 2533 { 2534 if (name[len - i] == '.') 2535 { 2536 name[len - i] = '\0'; 2537 break; 2538 } 2539 } 2540} 2541 2542/* Output a quoted string. */ 2543 2544void 2545output_quoted_string (asm_file, string) 2546 FILE *asm_file; 2547 const char *string; 2548{ 2549#ifdef OUTPUT_QUOTED_STRING 2550 OUTPUT_QUOTED_STRING (asm_file, string); 2551#else 2552 char c; 2553 2554 putc ('\"', asm_file); 2555 while ((c = *string++) != 0) 2556 { 2557 if (c == '\"' || c == '\\') 2558 putc ('\\', asm_file); 2559 putc (c, asm_file); 2560 } 2561 putc ('\"', asm_file); 2562#endif 2563} 2564 2565/* Output a file name in the form wanted by System V. */ 2566 2567void 2568output_file_directive (asm_file, input_name) 2569 FILE *asm_file; 2570 const char *input_name; 2571{ 2572 int len = strlen (input_name); 2573 const char *na = input_name + len; 2574 2575 /* NA gets INPUT_NAME sans directory names. */ 2576 while (na > input_name) 2577 { 2578 if (na[-1] == '/') 2579 break; 2580#ifdef DIR_SEPARATOR 2581 if (na[-1] == DIR_SEPARATOR) 2582 break; 2583#endif 2584 na--; 2585 } 2586 2587#ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME 2588 ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na); 2589#else 2590#ifdef ASM_OUTPUT_SOURCE_FILENAME 2591 ASM_OUTPUT_SOURCE_FILENAME (asm_file, na); 2592#else 2593 fprintf (asm_file, "\t.file\t"); 2594 output_quoted_string (asm_file, na); 2595 fputc ('\n', asm_file); 2596#endif 2597#endif 2598} 2599 2600#ifdef ASM_IDENTIFY_LANGUAGE 2601/* Routine to build language identifier for object file. */ 2602static void 2603output_lang_identify (asm_out_file) 2604 FILE *asm_out_file; 2605{ 2606 int len = strlen (lang_identify ()) + sizeof ("__gnu_compiled_") + 1; 2607 char *s = (char *) alloca (len); 2608 sprintf (s, "__gnu_compiled_%s", lang_identify ()); 2609 ASM_OUTPUT_LABEL (asm_out_file, s); 2610} 2611#endif 2612 2613/* Routine to open a dump file. */ 2614static void 2615open_dump_file (suffix, function_name) 2616 const char *suffix; 2617 const char *function_name; 2618{ 2619 char *dumpname; 2620 2621 TIMEVAR 2622 (dump_time, 2623 { 2624 dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1); 2625 2626 if (rtl_dump_file != NULL) 2627 fclose (rtl_dump_file); 2628 2629 strcpy (dumpname, dump_base_name); 2630 strcat (dumpname, suffix); 2631 2632 rtl_dump_file = fopen (dumpname, "a"); 2633 2634 if (rtl_dump_file == NULL) 2635 pfatal_with_name (dumpname); 2636 2637 free (dumpname); 2638 2639 if (function_name) 2640 fprintf (rtl_dump_file, "\n;; Function %s\n\n", function_name); 2641 }); 2642 2643 return; 2644} 2645 2646/* Routine to close a dump file. */ 2647static void 2648close_dump_file (func, insns) 2649 void (*func) PROTO ((FILE *, rtx)); 2650 rtx insns; 2651{ 2652 TIMEVAR 2653 (dump_time, 2654 { 2655 if (func) 2656 func (rtl_dump_file, insns); 2657 2658 fflush (rtl_dump_file); 2659 fclose (rtl_dump_file); 2660 2661 rtl_dump_file = NULL; 2662 }); 2663 2664 return; 2665} 2666 2667/* Routine to dump rtl into a file. */ 2668static void 2669dump_rtl (suffix, decl, func, insns) 2670 const char *suffix; 2671 tree decl; 2672 void (*func) PROTO ((FILE *, rtx)); 2673 rtx insns; 2674{ 2675 open_dump_file (suffix, decl_printable_name (decl, 2)); 2676 close_dump_file (func, insns); 2677} 2678 2679/* Routine to empty a dump file. */ 2680static void 2681clean_dump_file (suffix) 2682 const char *suffix; 2683{ 2684 char *dumpname; 2685 2686 dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1); 2687 2688 strcpy (dumpname, dump_base_name); 2689 strcat (dumpname, suffix); 2690 2691 rtl_dump_file = fopen (dumpname, "w"); 2692 2693 if (rtl_dump_file == NULL) 2694 pfatal_with_name (dumpname); 2695 2696 free (dumpname); 2697 2698 fclose (rtl_dump_file); 2699 rtl_dump_file = NULL; 2700 2701 return; 2702} 2703 2704/* Do any final processing required for the declarations in VEC, of 2705 which there are LEN. We write out inline functions and variables 2706 that have been deferred until this point, but which are required. 2707 Returns non-zero if anything was put out. */ 2708int 2709wrapup_global_declarations (vec, len) 2710 tree *vec; 2711 int len; 2712{ 2713 tree decl; 2714 int i; 2715 int reconsider; 2716 int output_something = 0; 2717 2718 for (i = 0; i < len; i++) 2719 { 2720 decl = vec[i]; 2721 2722 /* We're not deferring this any longer. */ 2723 DECL_DEFER_OUTPUT (decl) = 0; 2724 2725 if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0 2726 && incomplete_decl_finalize_hook != 0) 2727 (*incomplete_decl_finalize_hook) (decl); 2728 } 2729 2730 /* Now emit any global variables or functions that we have been 2731 putting off. We need to loop in case one of the things emitted 2732 here references another one which comes earlier in the list. */ 2733 do 2734 { 2735 reconsider = 0; 2736 for (i = 0; i < len; i++) 2737 { 2738 decl = vec[i]; 2739 2740 if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl)) 2741 continue; 2742 2743 /* Don't write out static consts, unless we still need them. 2744 2745 We also keep static consts if not optimizing (for debugging), 2746 unless the user specified -fno-keep-static-consts. 2747 ??? They might be better written into the debug information. 2748 This is possible when using DWARF. 2749 2750 A language processor that wants static constants to be always 2751 written out (even if it is not used) is responsible for 2752 calling rest_of_decl_compilation itself. E.g. the C front-end 2753 calls rest_of_decl_compilation from finish_decl. 2754 One motivation for this is that is conventional in some 2755 environments to write things like: 2756 static const char rcsid[] = "... version string ..."; 2757 intending to force the string to be in the executable. 2758 2759 A language processor that would prefer to have unneeded 2760 static constants "optimized away" would just defer writing 2761 them out until here. E.g. C++ does this, because static 2762 constants are often defined in header files. 2763 2764 ??? A tempting alternative (for both C and C++) would be 2765 to force a constant to be written if and only if it is 2766 defined in a main file, as opposed to an include file. */ 2767 2768 if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) 2769 && (! TREE_READONLY (decl) 2770 || TREE_PUBLIC (decl) 2771 || (!optimize && flag_keep_static_consts) 2772 || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) 2773 { 2774 reconsider = 1; 2775 rest_of_decl_compilation (decl, NULL_PTR, 1, 1); 2776 } 2777 2778 if (TREE_CODE (decl) == FUNCTION_DECL 2779 && DECL_INITIAL (decl) != 0 2780 && DECL_SAVED_INSNS (decl) != 0 2781 && (flag_keep_inline_functions 2782 || (TREE_PUBLIC (decl) && !DECL_COMDAT (decl)) 2783 || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) 2784 { 2785 reconsider = 1; 2786 temporary_allocation (); 2787 output_inline_function (decl); 2788 permanent_allocation (1); 2789 } 2790 } 2791 2792 if (reconsider) 2793 output_something = 1; 2794 } 2795 while (reconsider); 2796 2797 return output_something; 2798} 2799 2800/* Issue appropriate warnings for the global declarations in VEC (of 2801 which there are LEN). Output debugging information for them. */ 2802void 2803check_global_declarations (vec, len) 2804 tree *vec; 2805 int len; 2806{ 2807 tree decl; 2808 int i; 2809 2810 for (i = 0; i < len; i++) 2811 { 2812 decl = vec[i]; 2813 2814 if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) 2815 && ! TREE_ASM_WRITTEN (decl)) 2816 /* Cancel the RTL for this decl so that, if debugging info 2817 output for global variables is still to come, 2818 this one will be omitted. */ 2819 DECL_RTL (decl) = NULL; 2820 2821 /* Warn about any function 2822 declared static but not defined. 2823 We don't warn about variables, 2824 because many programs have static variables 2825 that exist only to get some text into the object file. */ 2826 if (TREE_CODE (decl) == FUNCTION_DECL 2827 && (warn_unused 2828 || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 2829 && DECL_INITIAL (decl) == 0 2830 && DECL_EXTERNAL (decl) 2831 && ! DECL_ARTIFICIAL (decl) 2832 && ! TREE_PUBLIC (decl)) 2833 { 2834 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 2835 pedwarn_with_decl (decl, 2836 "`%s' used but never defined"); 2837 else 2838 warning_with_decl (decl, 2839 "`%s' declared `static' but never defined"); 2840 /* This symbol is effectively an "extern" declaration now. */ 2841 TREE_PUBLIC (decl) = 1; 2842 assemble_external (decl); 2843 } 2844 2845 /* Warn about static fns or vars defined but not used, 2846 but not about inline functions or static consts 2847 since defining those in header files is normal practice. */ 2848 if (warn_unused 2849 && ((TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl)) 2850 || (TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl))) 2851 && ! DECL_IN_SYSTEM_HEADER (decl) 2852 && ! DECL_EXTERNAL (decl) 2853 && ! TREE_PUBLIC (decl) 2854 && ! TREE_USED (decl) 2855 && (TREE_CODE (decl) == FUNCTION_DECL || ! DECL_REGISTER (decl)) 2856 /* The TREE_USED bit for file-scope decls 2857 is kept in the identifier, to handle multiple 2858 external decls in different scopes. */ 2859 && ! TREE_USED (DECL_NAME (decl))) 2860 warning_with_decl (decl, "`%s' defined but not used"); 2861 2862#ifdef SDB_DEBUGGING_INFO 2863 /* The COFF linker can move initialized global vars to the end. 2864 And that can screw up the symbol ordering. 2865 By putting the symbols in that order to begin with, 2866 we avoid a problem. mcsun!unido!fauern!tumuc!pes@uunet.uu.net. */ 2867 if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL 2868 && TREE_PUBLIC (decl) && DECL_INITIAL (decl) 2869 && ! DECL_EXTERNAL (decl) 2870 && DECL_RTL (decl) != 0) 2871 TIMEVAR (symout_time, sdbout_symbol (decl, 0)); 2872 2873 /* Output COFF information for non-global 2874 file-scope initialized variables. */ 2875 if (write_symbols == SDB_DEBUG 2876 && TREE_CODE (decl) == VAR_DECL 2877 && DECL_INITIAL (decl) 2878 && ! DECL_EXTERNAL (decl) 2879 && DECL_RTL (decl) != 0 2880 && GET_CODE (DECL_RTL (decl)) == MEM) 2881 TIMEVAR (symout_time, sdbout_toplevel_data (decl)); 2882#endif /* SDB_DEBUGGING_INFO */ 2883#ifdef DWARF_DEBUGGING_INFO 2884 /* Output DWARF information for file-scope tentative data object 2885 declarations, file-scope (extern) function declarations (which 2886 had no corresponding body) and file-scope tagged type declarations 2887 and definitions which have not yet been forced out. */ 2888 2889 if (write_symbols == DWARF_DEBUG 2890 && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))) 2891 TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1)); 2892#endif 2893#ifdef DWARF2_DEBUGGING_INFO 2894 /* Output DWARF2 information for file-scope tentative data object 2895 declarations, file-scope (extern) function declarations (which 2896 had no corresponding body) and file-scope tagged type declarations 2897 and definitions which have not yet been forced out. */ 2898 2899 if (write_symbols == DWARF2_DEBUG 2900 && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))) 2901 TIMEVAR (symout_time, dwarf2out_decl (decl)); 2902#endif 2903 } 2904} 2905 2906/* Compile an entire file of output from cpp, named NAME. 2907 Write a file of assembly output and various debugging dumps. */ 2908 2909static void 2910compile_file (name) 2911 char *name; 2912{ 2913 tree globals; 2914 int start_time; 2915 2916 int name_specified = name != 0; 2917 2918 if (dump_base_name == 0) 2919 dump_base_name = name ? name : "gccdump"; 2920 2921 parse_time = 0; 2922 varconst_time = 0; 2923 integration_time = 0; 2924 jump_time = 0; 2925 cse_time = 0; 2926 gcse_time = 0; 2927 loop_time = 0; 2928 cse2_time = 0; 2929 branch_prob_time = 0; 2930 flow_time = 0; 2931 combine_time = 0; 2932 regmove_time = 0; 2933 sched_time = 0; 2934 local_alloc_time = 0; 2935 global_alloc_time = 0; 2936 flow2_time = 0; 2937 sched2_time = 0; 2938#ifdef DELAY_SLOTS 2939 dbr_sched_time = 0; 2940#endif 2941 shorten_branch_time = 0; 2942 stack_reg_time = 0; 2943 final_time = 0; 2944 symout_time = 0; 2945 dump_time = 0; 2946 2947 /* Initialize data in various passes. */ 2948 2949 init_obstacks (); 2950 init_tree_codes (); 2951 name = init_parse (name); 2952 init_rtl (); 2953 init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL 2954 || debug_info_level == DINFO_LEVEL_VERBOSE 2955 || flag_test_coverage); 2956 init_regs (); 2957 init_decl_processing (); 2958 init_optabs (); 2959 init_stmt (); 2960 init_expmed (); 2961 init_expr_once (); 2962 init_loop (); 2963 init_reload (); 2964 init_alias_once (); 2965 2966 if (flag_caller_saves) 2967 init_caller_save (); 2968 2969 /* If auxiliary info generation is desired, open the output file. 2970 This goes in the same directory as the source file--unlike 2971 all the other output files. */ 2972 if (flag_gen_aux_info) 2973 { 2974 aux_info_file = fopen (aux_info_file_name, "w"); 2975 if (aux_info_file == 0) 2976 pfatal_with_name (aux_info_file_name); 2977 } 2978 2979 /* Clear the dump files. */ 2980 if (rtl_dump) 2981 clean_dump_file (".rtl"); 2982 if (jump_opt_dump) 2983 { 2984 clean_dump_file (".jump"); 2985 if (graph_dump_format != no_graph) 2986 clean_graph_dump_file (dump_base_name, ".jump"); 2987 } 2988 if (addressof_dump) 2989 { 2990 clean_dump_file (".addressof"); 2991 if (graph_dump_format != no_graph) 2992 clean_graph_dump_file (dump_base_name, ".addressof"); 2993 } 2994 if (cse_dump) 2995 { 2996 clean_dump_file (".cse"); 2997 if (graph_dump_format != no_graph) 2998 clean_graph_dump_file (dump_base_name, ".cse"); 2999 } 3000 if (loop_dump) 3001 { 3002 clean_dump_file (".loop"); 3003 if (graph_dump_format != no_graph) 3004 clean_graph_dump_file (dump_base_name, ".loop"); 3005 } 3006 if (cse2_dump) 3007 { 3008 clean_dump_file (".cse2"); 3009 if (graph_dump_format != no_graph) 3010 clean_graph_dump_file (dump_base_name, ".cse2"); 3011 } 3012 if (branch_prob_dump) 3013 { 3014 clean_dump_file (".bp"); 3015 if (graph_dump_format != no_graph) 3016 clean_graph_dump_file (dump_base_name, ".bp"); 3017 } 3018 if (flow_dump) 3019 { 3020 clean_dump_file (".flow"); 3021 if (graph_dump_format != no_graph) 3022 clean_graph_dump_file (dump_base_name, ".flow"); 3023 } 3024 if (combine_dump) 3025 { 3026 clean_dump_file (".combine"); 3027 if (graph_dump_format != no_graph) 3028 clean_graph_dump_file (dump_base_name, ".combine"); 3029 } 3030 if (regmove_dump) 3031 { 3032 clean_dump_file (".regmove"); 3033 if (graph_dump_format != no_graph) 3034 clean_graph_dump_file (dump_base_name, ".regmove"); 3035 } 3036 if (sched_dump) 3037 { 3038 clean_dump_file (".sched"); 3039 if (graph_dump_format != no_graph) 3040 clean_graph_dump_file (dump_base_name, ".sched"); 3041 } 3042 if (local_reg_dump) 3043 { 3044 clean_dump_file (".lreg"); 3045 if (graph_dump_format != no_graph) 3046 clean_graph_dump_file (dump_base_name, ".lreg"); 3047 } 3048 if (global_reg_dump) 3049 { 3050 clean_dump_file (".greg"); 3051 if (graph_dump_format != no_graph) 3052 clean_graph_dump_file (dump_base_name, ".greg"); 3053 } 3054 if (flow2_dump) 3055 { 3056 clean_dump_file (".flow2"); 3057 if (graph_dump_format != no_graph) 3058 clean_graph_dump_file (dump_base_name, ".flow2"); 3059 } 3060 if (sched2_dump) 3061 { 3062 clean_dump_file (".sched2"); 3063 if (graph_dump_format != no_graph) 3064 clean_graph_dump_file (dump_base_name, ".sched2"); 3065 } 3066 if (jump2_opt_dump) 3067 { 3068 clean_dump_file (".jump2"); 3069 if (graph_dump_format != no_graph) 3070 clean_graph_dump_file (dump_base_name, ".jump2"); 3071 } 3072#ifdef DELAY_SLOTS 3073 if (dbr_sched_dump) 3074 { 3075 clean_dump_file (".dbr"); 3076 if (graph_dump_format != no_graph) 3077 clean_graph_dump_file (dump_base_name, ".dbr"); 3078 } 3079#endif 3080 if (gcse_dump) 3081 { 3082 clean_dump_file (".gcse"); 3083 if (graph_dump_format != no_graph) 3084 clean_graph_dump_file (dump_base_name, ".gcse"); 3085 } 3086#ifdef STACK_REGS 3087 if (stack_reg_dump) 3088 { 3089 clean_dump_file (".stack"); 3090 if (graph_dump_format != no_graph) 3091 clean_graph_dump_file (dump_base_name, ".stack"); 3092 } 3093#endif 3094#ifdef MACHINE_DEPENDENT_REORG 3095 if (mach_dep_reorg_dump) 3096 { 3097 clean_dump_file (".mach"); 3098 if (graph_dump_format != no_graph) 3099 clean_graph_dump_file (dump_base_name, ".mach"); 3100 } 3101#endif 3102 3103 /* Open assembler code output file. */ 3104 3105 if (flag_syntax_only) 3106 asm_out_file = NULL; 3107 else 3108 { 3109 if (! name_specified && asm_file_name == 0) 3110 asm_out_file = stdout; 3111 else 3112 { 3113 int len = strlen (dump_base_name); 3114 register char *dumpname = (char *) xmalloc (len + 6); 3115 strcpy (dumpname, dump_base_name); 3116 strip_off_ending (dumpname, len); 3117 strcat (dumpname, ".s"); 3118 if (asm_file_name == 0) 3119 { 3120 asm_file_name = (char *) xmalloc (strlen (dumpname) + 1); 3121 strcpy (asm_file_name, dumpname); 3122 } 3123 if (!strcmp (asm_file_name, "-")) 3124 asm_out_file = stdout; 3125 else 3126 asm_out_file = fopen (asm_file_name, "w"); 3127 if (asm_out_file == 0) 3128 pfatal_with_name (asm_file_name); 3129 } 3130 3131#ifdef IO_BUFFER_SIZE 3132 setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE), 3133 _IOFBF, IO_BUFFER_SIZE); 3134#endif 3135 } 3136 3137 input_filename = name; 3138 3139 /* Put an entry on the input file stack for the main input file. */ 3140 input_file_stack 3141 = (struct file_stack *) xmalloc (sizeof (struct file_stack)); 3142 input_file_stack->next = 0; 3143 input_file_stack->name = input_filename; 3144 3145 /* Perform language-specific initialization. 3146 This may set main_input_filename. */ 3147 lang_init (); 3148 3149 /* If the input doesn't start with a #line, use the input name 3150 as the official input file name. */ 3151 if (main_input_filename == 0) 3152 main_input_filename = name; 3153 3154 if (flag_syntax_only) 3155 { 3156 write_symbols = NO_DEBUG; 3157 profile_flag = 0; 3158 profile_block_flag = 0; 3159 } 3160 else 3161 { 3162 ASM_FILE_START (asm_out_file); 3163 3164#ifdef ASM_COMMENT_START 3165 if (flag_verbose_asm) 3166 { 3167 /* Print the list of options in effect. */ 3168 print_version (asm_out_file, ASM_COMMENT_START); 3169 print_switch_values (asm_out_file, 0, MAX_LINE, 3170 ASM_COMMENT_START, " ", "\n"); 3171 /* Add a blank line here so it appears in assembler output but not 3172 screen output. */ 3173 fprintf (asm_out_file, "\n"); 3174 } 3175#endif 3176 3177 /* Output something to inform GDB that this compilation was by GCC. */ 3178#ifndef ASM_IDENTIFY_GCC 3179 fprintf (asm_out_file, "gcc2_compiled.:\n"); 3180#else 3181 ASM_IDENTIFY_GCC (asm_out_file); 3182#endif 3183 3184 /* Output something to identify which front-end produced this file. */ 3185#ifdef ASM_IDENTIFY_LANGUAGE 3186 ASM_IDENTIFY_LANGUAGE (asm_out_file); 3187#endif 3188 } /* ! flag_syntax_only */ 3189 3190#ifndef ASM_OUTPUT_SECTION_NAME 3191 if (flag_function_sections) 3192 { 3193 warning ("-ffunction-sections not supported for this target."); 3194 flag_function_sections = 0; 3195 } 3196 if (flag_data_sections) 3197 { 3198 warning ("-fdata-sections not supported for this target."); 3199 flag_data_sections = 0; 3200 } 3201#endif 3202 3203 if (flag_function_sections 3204 && (profile_flag || profile_block_flag)) 3205 { 3206 warning ("-ffunction-sections disabled; it makes profiling impossible."); 3207 flag_function_sections = 0; 3208 } 3209 3210#ifndef OBJECT_FORMAT_ELF 3211 if (flag_function_sections && write_symbols != NO_DEBUG) 3212 warning ("-ffunction-sections may affect debugging on some targets."); 3213#endif 3214 3215 /* ??? Note: There used to be a conditional here 3216 to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined. 3217 This was to guarantee separation between gcc_compiled. and 3218 the first function, for the sake of dbx on Suns. 3219 However, having the extra zero here confused the Emacs 3220 code for unexec, and might confuse other programs too. 3221 Therefore, I took out that change. 3222 In future versions we should find another way to solve 3223 that dbx problem. -- rms, 23 May 93. */ 3224 3225 /* Don't let the first function fall at the same address 3226 as gcc_compiled., if profiling. */ 3227 if (profile_flag || profile_block_flag) 3228 { 3229 /* It's best if we can write a nop here since some 3230 assemblers don't tolerate zeros in the text section. */ 3231 if (insn_template[CODE_FOR_nop] != 0) 3232 output_asm_insn (insn_template[CODE_FOR_nop], NULL_PTR); 3233 else 3234 assemble_zeros (UNITS_PER_WORD); 3235 } 3236 3237 /* If dbx symbol table desired, initialize writing it 3238 and output the predefined types. */ 3239#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 3240 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 3241 TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename, 3242 getdecls ())); 3243#endif 3244#ifdef SDB_DEBUGGING_INFO 3245 if (write_symbols == SDB_DEBUG) 3246 TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename, 3247 getdecls ())); 3248#endif 3249#ifdef DWARF_DEBUGGING_INFO 3250 if (write_symbols == DWARF_DEBUG) 3251 TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename)); 3252#endif 3253#ifdef DWARF2_UNWIND_INFO 3254 if (dwarf2out_do_frame ()) 3255 dwarf2out_frame_init (); 3256#endif 3257#ifdef DWARF2_DEBUGGING_INFO 3258 if (write_symbols == DWARF2_DEBUG) 3259 TIMEVAR (symout_time, dwarf2out_init (asm_out_file, main_input_filename)); 3260#endif 3261 3262 /* Initialize yet another pass. */ 3263 3264 init_final (main_input_filename); 3265 init_branch_prob (dump_base_name); 3266 3267 start_time = get_run_time (); 3268 3269 /* Call the parser, which parses the entire file 3270 (calling rest_of_compilation for each function). */ 3271 3272 if (yyparse () != 0) 3273 { 3274 if (errorcount == 0) 3275 notice ("Errors detected in input file (your bison.simple is out of date)\n"); 3276 3277 /* In case there were missing closebraces, 3278 get us back to the global binding level. */ 3279 while (! global_bindings_p ()) 3280 poplevel (0, 0, 0); 3281 } 3282 3283 /* Compilation is now finished except for writing 3284 what's left of the symbol table output. */ 3285 3286 parse_time += get_run_time () - start_time; 3287 3288 parse_time -= integration_time; 3289 parse_time -= varconst_time; 3290 3291 if (flag_syntax_only) 3292 goto finish_syntax; 3293 3294 globals = getdecls (); 3295 3296 /* Really define vars that have had only a tentative definition. 3297 Really output inline functions that must actually be callable 3298 and have not been output so far. */ 3299 3300 { 3301 int len = list_length (globals); 3302 tree *vec = (tree *) alloca (sizeof (tree) * len); 3303 int i; 3304 tree decl; 3305 3306 /* Process the decls in reverse order--earliest first. 3307 Put them into VEC from back to front, then take out from front. */ 3308 3309 for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl)) 3310 vec[len - i - 1] = decl; 3311 3312 wrapup_global_declarations (vec, len); 3313 3314 /* This must occur after the loop to output deferred functions. Else 3315 the profiler initializer would not be emitted if all the functions 3316 in this compilation unit were deferred. 3317 3318 output_func_start_profiler can not cause any additional functions or 3319 data to need to be output, so it need not be in the deferred function 3320 loop above. */ 3321 output_func_start_profiler (); 3322 3323 /* Now that all possible functions have been output, we can dump 3324 the exception table. */ 3325 3326 output_exception_table (); 3327 3328 check_global_declarations (vec, len); 3329 } 3330 3331 /* Write out any pending weak symbol declarations. */ 3332 3333 weak_finish (); 3334 3335 /* Do dbx symbols */ 3336#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 3337 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 3338 TIMEVAR (symout_time, 3339 { 3340 dbxout_finish (asm_out_file, main_input_filename); 3341 }); 3342#endif 3343 3344#ifdef DWARF_DEBUGGING_INFO 3345 if (write_symbols == DWARF_DEBUG) 3346 TIMEVAR (symout_time, 3347 { 3348 dwarfout_finish (); 3349 }); 3350#endif 3351 3352#ifdef DWARF2_UNWIND_INFO 3353 if (dwarf2out_do_frame ()) 3354 dwarf2out_frame_finish (); 3355#endif 3356 3357#ifdef DWARF2_DEBUGGING_INFO 3358 if (write_symbols == DWARF2_DEBUG) 3359 TIMEVAR (symout_time, 3360 { 3361 dwarf2out_finish (); 3362 }); 3363#endif 3364 3365 /* Output some stuff at end of file if nec. */ 3366 3367 end_final (dump_base_name); 3368 3369 if (branch_prob_dump) 3370 open_dump_file (".bp", NULL); 3371 3372 TIMEVAR (dump_time, end_branch_prob (rtl_dump_file)); 3373 3374 if (branch_prob_dump) 3375 close_dump_file (NULL, NULL_RTX); 3376 3377#ifdef ASM_FILE_END 3378 ASM_FILE_END (asm_out_file); 3379#endif 3380 3381 3382 /* Language-specific end of compilation actions. */ 3383 finish_syntax: 3384 lang_finish (); 3385 3386 /* Close the dump files. */ 3387 3388 if (flag_gen_aux_info) 3389 { 3390 fclose (aux_info_file); 3391 if (errorcount) 3392 unlink (aux_info_file_name); 3393 } 3394 3395 if (combine_dump) 3396 { 3397 open_dump_file (".combine", NULL); 3398 TIMEVAR (dump_time, dump_combine_total_stats (rtl_dump_file)); 3399 close_dump_file (NULL, NULL_RTX); 3400 } 3401 3402 /* Close non-debugging input and output files. Take special care to note 3403 whether fclose returns an error, since the pages might still be on the 3404 buffer chain while the file is open. */ 3405 3406 finish_parse (); 3407 3408 if (! flag_syntax_only 3409 && (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0)) 3410 fatal_io_error (asm_file_name); 3411 3412 /* Do whatever is necessary to finish printing the graphs. */ 3413 if (graph_dump_format != no_graph) 3414 { 3415 if (jump_opt_dump) 3416 finish_graph_dump_file (dump_base_name, ".jump"); 3417 if (addressof_dump) 3418 finish_graph_dump_file (dump_base_name, ".addressof"); 3419 if (cse_dump) 3420 finish_graph_dump_file (dump_base_name, ".cse"); 3421 if (loop_dump) 3422 finish_graph_dump_file (dump_base_name, ".loop"); 3423 if (cse2_dump) 3424 finish_graph_dump_file (dump_base_name, ".cse2"); 3425 if (branch_prob_dump) 3426 finish_graph_dump_file (dump_base_name, ".bp"); 3427 if (flow_dump) 3428 finish_graph_dump_file (dump_base_name, ".flow"); 3429 if (combine_dump) 3430 finish_graph_dump_file (dump_base_name, ".combine"); 3431 if (regmove_dump) 3432 finish_graph_dump_file (dump_base_name, ".regmove"); 3433 if (sched_dump) 3434 finish_graph_dump_file (dump_base_name, ".sched"); 3435 if (local_reg_dump) 3436 finish_graph_dump_file (dump_base_name, ".lreg"); 3437 if (global_reg_dump) 3438 finish_graph_dump_file (dump_base_name, ".greg"); 3439 if (flow2_dump) 3440 finish_graph_dump_file (dump_base_name, ".flow2"); 3441 if (sched2_dump) 3442 finish_graph_dump_file (dump_base_name, ".sched2"); 3443 if (jump2_opt_dump) 3444 finish_graph_dump_file (dump_base_name, ".jump2"); 3445#ifdef DELAY_SLOTS 3446 if (dbr_sched_dump) 3447 finish_graph_dump_file (dump_base_name, ".dbr"); 3448#endif 3449 if (gcse_dump) 3450 finish_graph_dump_file (dump_base_name, ".gcse"); 3451#ifdef STACK_REGS 3452 if (stack_reg_dump) 3453 finish_graph_dump_file (dump_base_name, ".stack"); 3454#endif 3455#ifdef MACHINE_DEPENDENT_REORG 3456 if (mach_dep_reorg_dump) 3457 finish_graph_dump_file (dump_base_name, ".mach"); 3458#endif 3459 } 3460 3461 /* Free up memory for the benefit of leak detectors. */ 3462 free_reg_info (); 3463 3464 /* Print the times. */ 3465 3466 if (! quiet_flag) 3467 { 3468 fprintf (stderr,"\n"); 3469 print_time ("parse", parse_time); 3470 3471 print_time ("integration", integration_time); 3472 print_time ("jump", jump_time); 3473 print_time ("cse", cse_time); 3474 print_time ("gcse", gcse_time); 3475 print_time ("loop", loop_time); 3476 print_time ("cse2", cse2_time); 3477 print_time ("branch-prob", branch_prob_time); 3478 print_time ("flow", flow_time); 3479 print_time ("combine", combine_time); 3480 print_time ("regmove", regmove_time); 3481 print_time ("sched", sched_time); 3482 print_time ("local-alloc", local_alloc_time); 3483 print_time ("global-alloc", global_alloc_time); 3484 print_time ("flow2", flow2_time); 3485 print_time ("sched2", sched2_time); 3486#ifdef DELAY_SLOTS 3487 print_time ("dbranch", dbr_sched_time); 3488#endif 3489 print_time ("shorten-branch", shorten_branch_time); 3490 print_time ("stack-reg", stack_reg_time); 3491 print_time ("final", final_time); 3492 print_time ("varconst", varconst_time); 3493 print_time ("symout", symout_time); 3494 print_time ("dump", dump_time); 3495 } 3496} 3497 3498/* This is called from various places for FUNCTION_DECL, VAR_DECL, 3499 and TYPE_DECL nodes. 3500 3501 This does nothing for local (non-static) variables. 3502 Otherwise, it sets up the RTL and outputs any assembler code 3503 (label definition, storage allocation and initialization). 3504 3505 DECL is the declaration. If ASMSPEC is nonzero, it specifies 3506 the assembler symbol name to be used. TOP_LEVEL is nonzero 3507 if this declaration is not within a function. */ 3508 3509void 3510rest_of_decl_compilation (decl, asmspec, top_level, at_end) 3511 tree decl; 3512 const char *asmspec; 3513 int top_level; 3514 int at_end; 3515{ 3516 /* Declarations of variables, and of functions defined elsewhere. */ 3517 3518/* The most obvious approach, to put an #ifndef around where 3519 this macro is used, doesn't work since it's inside a macro call. */ 3520#ifndef ASM_FINISH_DECLARE_OBJECT 3521#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END) 3522#endif 3523 3524 /* Forward declarations for nested functions are not "external", 3525 but we need to treat them as if they were. */ 3526 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl) 3527 || TREE_CODE (decl) == FUNCTION_DECL) 3528 TIMEVAR (varconst_time, 3529 { 3530 make_decl_rtl (decl, asmspec, top_level); 3531 /* Initialized extern variable exists to be replaced 3532 with its value, or represents something that will be 3533 output in another file. */ 3534 if (! (TREE_CODE (decl) == VAR_DECL 3535 && DECL_EXTERNAL (decl) && TREE_READONLY (decl) 3536 && DECL_INITIAL (decl) != 0 3537 && DECL_INITIAL (decl) != error_mark_node)) 3538 /* Don't output anything 3539 when a tentative file-scope definition is seen. 3540 But at end of compilation, do output code for them. */ 3541 if (! (! at_end && top_level 3542 && (DECL_INITIAL (decl) == 0 3543 || DECL_INITIAL (decl) == error_mark_node))) 3544 assemble_variable (decl, top_level, at_end, 0); 3545 if (decl == last_assemble_variable_decl) 3546 { 3547 ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl, 3548 top_level, at_end); 3549 } 3550 }); 3551 else if (DECL_REGISTER (decl) && asmspec != 0) 3552 { 3553 if (decode_reg_name (asmspec) >= 0) 3554 { 3555 DECL_RTL (decl) = 0; 3556 make_decl_rtl (decl, asmspec, top_level); 3557 } 3558 else 3559 error ("invalid register name `%s' for register variable", asmspec); 3560 } 3561#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 3562 else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 3563 && TREE_CODE (decl) == TYPE_DECL) 3564 TIMEVAR (symout_time, dbxout_symbol (decl, 0)); 3565#endif 3566#ifdef SDB_DEBUGGING_INFO 3567 else if (write_symbols == SDB_DEBUG && top_level 3568 && TREE_CODE (decl) == TYPE_DECL) 3569 TIMEVAR (symout_time, sdbout_symbol (decl, 0)); 3570#endif 3571} 3572 3573/* Called after finishing a record, union or enumeral type. */ 3574 3575void 3576rest_of_type_compilation (type, toplev) 3577#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO) 3578 tree type; 3579 int toplev; 3580#else 3581 tree type ATTRIBUTE_UNUSED; 3582 int toplev ATTRIBUTE_UNUSED; 3583#endif 3584{ 3585#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 3586 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 3587 TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev)); 3588#endif 3589#ifdef SDB_DEBUGGING_INFO 3590 if (write_symbols == SDB_DEBUG) 3591 TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev)); 3592#endif 3593} 3594 3595/* This is called from finish_function (within yyparse) 3596 after each top-level definition is parsed. 3597 It is supposed to compile that function or variable 3598 and output the assembler code for it. 3599 After we return, the tree storage is freed. */ 3600 3601void 3602rest_of_compilation (decl) 3603 tree decl; 3604{ 3605 register rtx insns; 3606 int start_time = get_run_time (); 3607 int tem; 3608 /* Nonzero if we have saved the original DECL_INITIAL of the function, 3609 to be restored after we finish compiling the function 3610 (for use when compiling inline calls to this function). */ 3611 tree saved_block_tree = 0; 3612 /* Likewise, for DECL_ARGUMENTS. */ 3613 tree saved_arguments = 0; 3614 int failure = 0; 3615 int rebuild_label_notes_after_reload; 3616 3617 /* If we are reconsidering an inline function 3618 at the end of compilation, skip the stuff for making it inline. */ 3619 3620 if (DECL_SAVED_INSNS (decl) == 0) 3621 { 3622 int inlinable = 0; 3623 const char *lose; 3624 3625 /* If requested, consider whether to make this function inline. */ 3626 if (DECL_INLINE (decl) || flag_inline_functions) 3627 TIMEVAR (integration_time, 3628 { 3629 lose = function_cannot_inline_p (decl); 3630 if (lose || ! optimize) 3631 { 3632 if (warn_inline && DECL_INLINE (decl)) 3633 warning_with_decl (decl, lose); 3634 DECL_ABSTRACT_ORIGIN (decl) = 0; 3635 /* Don't really compile an extern inline function. 3636 If we can't make it inline, pretend 3637 it was only declared. */ 3638 if (DECL_EXTERNAL (decl)) 3639 { 3640 DECL_INITIAL (decl) = 0; 3641 goto exit_rest_of_compilation; 3642 } 3643 } 3644 else 3645 /* ??? Note that this has the effect of making it look 3646 like "inline" was specified for a function if we choose 3647 to inline it. This isn't quite right, but it's 3648 probably not worth the trouble to fix. */ 3649 inlinable = DECL_INLINE (decl) = 1; 3650 }); 3651 3652 insns = get_insns (); 3653 3654 /* Dump the rtl code if we are dumping rtl. */ 3655 3656 if (rtl_dump) 3657 { 3658 open_dump_file (".rtl", decl_printable_name (decl, 2)); 3659 3660 if (DECL_SAVED_INSNS (decl)) 3661 fprintf (rtl_dump_file, ";; (integrable)\n\n"); 3662 3663 close_dump_file (print_rtl, insns); 3664 } 3665 3666 /* If we can, defer compiling inlines until EOF. 3667 save_for_inline_copying can be extremely expensive. */ 3668 if (inlinable && ! decl_function_context (decl)) 3669 DECL_DEFER_OUTPUT (decl) = 1; 3670 3671 /* If function is inline, and we don't yet know whether to 3672 compile it by itself, defer decision till end of compilation. 3673 finish_compilation will call rest_of_compilation again 3674 for those functions that need to be output. Also defer those 3675 functions that we are supposed to defer. We cannot defer 3676 functions containing nested functions since the nested function 3677 data is in our non-saved obstack. We cannot defer nested 3678 functions for the same reason. */ 3679 3680 /* If this is a nested inline, remove ADDRESSOF now so we can 3681 finish compiling ourselves. Otherwise, wait until EOF. 3682 We have to do this because the purge_addressof transformation 3683 changes the DECL_RTL for many variables, which confuses integrate. */ 3684 if (inlinable) 3685 { 3686 if (decl_function_context (decl)) 3687 purge_addressof (insns); 3688 else 3689 DECL_DEFER_OUTPUT (decl) = 1; 3690 } 3691 3692 if (! current_function_contains_functions 3693 && (DECL_DEFER_OUTPUT (decl) 3694 || (DECL_INLINE (decl) 3695 && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl) 3696 && ! flag_keep_inline_functions) 3697 || DECL_EXTERNAL (decl))))) 3698 { 3699 DECL_DEFER_OUTPUT (decl) = 1; 3700 3701 /* If -Wreturn-type, we have to do a bit of compilation. 3702 However, if we just fall through we will call 3703 save_for_inline_copying() which results in excessive 3704 memory use. Instead, we just want to call 3705 jump_optimize() to figure out whether or not we can fall 3706 off the end of the function; we do the minimum amount of 3707 work necessary to make that safe. And, we set optimize 3708 to zero to keep jump_optimize from working too hard. */ 3709 if (warn_return_type) 3710 { 3711 int saved_optimize = optimize; 3712 optimize = 0; 3713 find_exception_handler_labels (); 3714 jump_optimize (get_insns(), !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES, 3715 !JUMP_AFTER_REGSCAN); 3716 optimize = saved_optimize; 3717 } 3718 3719#ifdef DWARF_DEBUGGING_INFO 3720 /* Generate the DWARF info for the "abstract" instance 3721 of a function which we may later generate inlined and/or 3722 out-of-line instances of. */ 3723 if (write_symbols == DWARF_DEBUG) 3724 { 3725 set_decl_abstract_flags (decl, 1); 3726 TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); 3727 set_decl_abstract_flags (decl, 0); 3728 } 3729#endif 3730#ifdef DWARF2_DEBUGGING_INFO 3731 /* Generate the DWARF2 info for the "abstract" instance 3732 of a function which we may later generate inlined and/or 3733 out-of-line instances of. */ 3734 if (write_symbols == DWARF2_DEBUG) 3735 { 3736 set_decl_abstract_flags (decl, 1); 3737 TIMEVAR (symout_time, dwarf2out_decl (decl)); 3738 set_decl_abstract_flags (decl, 0); 3739 } 3740#endif 3741 TIMEVAR (integration_time, save_for_inline_nocopy (decl)); 3742 RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable; 3743 goto exit_rest_of_compilation; 3744 } 3745 3746 /* If we have to compile the function now, save its rtl and subdecls 3747 so that its compilation will not affect what others get. */ 3748 if (inlinable || DECL_DEFER_OUTPUT (decl)) 3749 { 3750#ifdef DWARF_DEBUGGING_INFO 3751 /* Generate the DWARF info for the "abstract" instance of 3752 a function which we will generate an out-of-line instance 3753 of almost immediately (and which we may also later generate 3754 various inlined instances of). */ 3755 if (write_symbols == DWARF_DEBUG) 3756 { 3757 set_decl_abstract_flags (decl, 1); 3758 TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); 3759 set_decl_abstract_flags (decl, 0); 3760 } 3761#endif 3762#ifdef DWARF2_DEBUGGING_INFO 3763 /* Generate the DWARF2 info for the "abstract" instance of 3764 a function which we will generate an out-of-line instance 3765 of almost immediately (and which we may also later generate 3766 various inlined instances of). */ 3767 if (write_symbols == DWARF2_DEBUG) 3768 { 3769 set_decl_abstract_flags (decl, 1); 3770 TIMEVAR (symout_time, dwarf2out_decl (decl)); 3771 set_decl_abstract_flags (decl, 0); 3772 } 3773#endif 3774 saved_block_tree = DECL_INITIAL (decl); 3775 saved_arguments = DECL_ARGUMENTS (decl); 3776 TIMEVAR (integration_time, save_for_inline_copying (decl)); 3777 RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable; 3778 } 3779 3780 /* If specified extern inline but we aren't inlining it, we are 3781 done. This goes for anything that gets here with DECL_EXTERNAL 3782 set, not just things with DECL_INLINE. */ 3783 if (DECL_EXTERNAL (decl)) 3784 goto exit_rest_of_compilation; 3785 } 3786 3787 if (! DECL_DEFER_OUTPUT (decl)) 3788 TREE_ASM_WRITTEN (decl) = 1; 3789 3790 /* Now that integrate will no longer see our rtl, we need not distinguish 3791 between the return value of this function and the return value of called 3792 functions. */ 3793 rtx_equal_function_value_matters = 0; 3794 3795 /* Don't return yet if -Wreturn-type; we need to do jump_optimize. */ 3796 if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type) 3797 { 3798 goto exit_rest_of_compilation; 3799 } 3800 3801 /* Emit code to get eh context, if needed. */ 3802 emit_eh_context (); 3803 3804#ifdef FINALIZE_PIC 3805 /* If we are doing position-independent code generation, now 3806 is the time to output special prologues and epilogues. 3807 We do not want to do this earlier, because it just clutters 3808 up inline functions with meaningless insns. */ 3809 if (flag_pic) 3810 FINALIZE_PIC; 3811#endif 3812 3813 /* From now on, allocate rtl in current_obstack, not in saveable_obstack. 3814 Note that that may have been done above, in save_for_inline_copying. 3815 The call to resume_temporary_allocation near the end of this function 3816 goes back to the usual state of affairs. This must be done after 3817 we've built up any unwinders for exception handling, and done 3818 the FINALIZE_PIC work, if necessary. */ 3819 3820 rtl_in_current_obstack (); 3821 3822 insns = get_insns (); 3823 3824 /* Copy any shared structure that should not be shared. */ 3825 3826 unshare_all_rtl (insns); 3827 3828#ifdef SETJMP_VIA_SAVE_AREA 3829 /* This must be performed before virutal register instantiation. */ 3830 if (current_function_calls_alloca) 3831 optimize_save_area_alloca (insns); 3832#endif 3833 3834 /* Instantiate all virtual registers. */ 3835 3836 instantiate_virtual_regs (current_function_decl, get_insns ()); 3837 3838 /* See if we have allocated stack slots that are not directly addressable. 3839 If so, scan all the insns and create explicit address computation 3840 for all references to such slots. */ 3841/* fixup_stack_slots (); */ 3842 3843 /* Find all the EH handlers. */ 3844 find_exception_handler_labels (); 3845 3846 /* Always do one jump optimization pass to ensure that JUMP_LABEL fields 3847 are initialized and to compute whether control can drop off the end 3848 of the function. */ 3849 TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0)); 3850 TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES, 3851 JUMP_AFTER_REGSCAN)); 3852 3853 /* Now is when we stop if -fsyntax-only and -Wreturn-type. */ 3854 if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl)) 3855 goto exit_rest_of_compilation; 3856 3857 /* Dump rtl code after jump, if we are doing that. */ 3858 3859 if (jump_opt_dump) 3860 dump_rtl (".jump", decl, print_rtl, insns); 3861 3862 /* Perform common subexpression elimination. 3863 Nonzero value from `cse_main' means that jumps were simplified 3864 and some code may now be unreachable, so do 3865 jump optimization again. */ 3866 3867 if (optimize > 0) 3868 { 3869 if (cse_dump) 3870 open_dump_file (".cse", decl_printable_name (decl, 2)); 3871 3872 TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1)); 3873 3874 if (flag_thread_jumps) 3875 /* Hacks by tiemann & kenner. */ 3876 TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 1)); 3877 3878 TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (), 3879 0, rtl_dump_file)); 3880 if (tem || optimize > 1) 3881 TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, 3882 !JUMP_NOOP_MOVES, 3883 !JUMP_AFTER_REGSCAN)); 3884 3885 /* Run this after jump optmizations remove all the unreachable code 3886 so that unreachable code will not keep values live. */ 3887 TIMEVAR (cse_time, delete_trivially_dead_insns (insns, max_reg_num ())); 3888 3889 /* Dump rtl code after cse, if we are doing that. */ 3890 3891 if (cse_dump) 3892 { 3893 close_dump_file (print_rtl, insns); 3894 if (graph_dump_format != no_graph) 3895 print_rtl_graph_with_bb (dump_base_name, ".cse", insns); 3896 } 3897 } 3898 3899 purge_addressof (insns); 3900 reg_scan (insns, max_reg_num (), 1); 3901 3902 if (addressof_dump) 3903 { 3904 dump_rtl (".addressof", decl, print_rtl, insns); 3905 if (graph_dump_format != no_graph) 3906 print_rtl_graph_with_bb (dump_base_name, ".addressof", insns); 3907 } 3908 3909 /* Perform global cse. */ 3910 3911 if (optimize > 0 && flag_gcse) 3912 { 3913 if (gcse_dump) 3914 open_dump_file (".gcse", IDENTIFIER_POINTER (DECL_NAME (decl))); 3915 3916 TIMEVAR (gcse_time, tem = gcse_main (insns, rtl_dump_file)); 3917 3918 /* If gcse altered any jumps, rerun jump optimizations to clean 3919 things up. */ 3920 if (tem) 3921 { 3922 TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, 3923 !JUMP_NOOP_MOVES, 3924 !JUMP_AFTER_REGSCAN)); 3925 } 3926 3927 if (gcse_dump) 3928 { 3929 close_dump_file (print_rtl, insns); 3930 if (graph_dump_format != no_graph) 3931 print_rtl_graph_with_bb (dump_base_name, ".gcse", insns); 3932 } 3933 } 3934 /* Move constant computations out of loops. */ 3935 3936 if (optimize > 0) 3937 { 3938 if (loop_dump) 3939 open_dump_file (".loop", decl_printable_name (decl, 2)); 3940 3941 TIMEVAR 3942 (loop_time, 3943 { 3944 if (flag_rerun_loop_opt) 3945 { 3946 /* We only want to perform unrolling once. */ 3947 3948 loop_optimize (insns, rtl_dump_file, 0, 0); 3949 3950 3951 /* The first call to loop_optimize makes some instructions 3952 trivially dead. We delete those instructions now in the 3953 hope that doing so will make the heuristics in loop work 3954 better and possibly speed up compilation. */ 3955 delete_trivially_dead_insns (insns, max_reg_num ()); 3956 3957 /* The regscan pass is currently necessary as the alias 3958 analysis code depends on this information. */ 3959 reg_scan (insns, max_reg_num (), 1); 3960 } 3961 loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1); 3962 }); 3963 3964 /* Dump rtl code after loop opt, if we are doing that. */ 3965 3966 if (loop_dump) 3967 { 3968 close_dump_file (print_rtl, insns); 3969 if (graph_dump_format != no_graph) 3970 print_rtl_graph_with_bb (dump_base_name, ".loop", insns); 3971 } 3972 } 3973 3974 if (optimize > 0) 3975 { 3976 if (cse2_dump) 3977 open_dump_file (".cse2", decl_printable_name (decl, 2)); 3978 3979 if (flag_rerun_cse_after_loop) 3980 { 3981 /* Running another jump optimization pass before the second 3982 cse pass sometimes simplifies the RTL enough to allow 3983 the second CSE pass to do a better job. Jump_optimize can change 3984 max_reg_num so we must rerun reg_scan afterwards. 3985 ??? Rework to not call reg_scan so often. */ 3986 TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0)); 3987 TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, 3988 !JUMP_NOOP_MOVES, 3989 JUMP_AFTER_REGSCAN)); 3990 3991 TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0)); 3992 TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (), 3993 1, rtl_dump_file)); 3994 if (tem) 3995 TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, 3996 !JUMP_NOOP_MOVES, 3997 !JUMP_AFTER_REGSCAN)); 3998 } 3999 4000 if (flag_thread_jumps) 4001 { 4002 /* This pass of jump threading straightens out code 4003 that was kinked by loop optimization. */ 4004 TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0)); 4005 TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0)); 4006 } 4007 4008 /* Dump rtl code after cse, if we are doing that. */ 4009 4010 if (cse2_dump) 4011 { 4012 close_dump_file (print_rtl, insns); 4013 if (graph_dump_format != no_graph) 4014 print_rtl_graph_with_bb (dump_base_name, ".cse2", insns); 4015 } 4016 } 4017 4018 if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) 4019 { 4020 if (branch_prob_dump) 4021 open_dump_file (".bp", decl_printable_name (decl, 2)); 4022 4023 TIMEVAR 4024 (branch_prob_time, 4025 { 4026 branch_prob (insns, rtl_dump_file); 4027 }); 4028 4029 if (branch_prob_dump) 4030 { 4031 close_dump_file (print_rtl, insns); 4032 if (graph_dump_format != no_graph) 4033 print_rtl_graph_with_bb (dump_base_name, ".bp", insns); 4034 } 4035 } 4036 4037 /* We are no longer anticipating cse in this function, at least. */ 4038 4039 cse_not_expected = 1; 4040 4041 /* Now we choose between stupid (pcc-like) register allocation 4042 (if we got the -noreg switch and not -opt) 4043 and smart register allocation. */ 4044 4045 if (optimize > 0) /* Stupid allocation probably won't work */ 4046 obey_regdecls = 0; /* if optimizations being done. */ 4047 4048 regclass_init (); 4049 4050 /* Print function header into flow dump now 4051 because doing the flow analysis makes some of the dump. */ 4052 4053 if (flow_dump) 4054 open_dump_file (".flow", decl_printable_name (decl, 2)); 4055 4056 if (obey_regdecls) 4057 { 4058 TIMEVAR (flow_time, 4059 { 4060 regclass (insns, max_reg_num ()); 4061 stupid_life_analysis (insns, max_reg_num (), 4062 rtl_dump_file); 4063 }); 4064 } 4065 else 4066 { 4067 /* Do control and data flow analysis, 4068 and write some of the results to dump file. */ 4069 4070 TIMEVAR 4071 (flow_time, 4072 { 4073 find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1); 4074 life_analysis (insns, max_reg_num (), rtl_dump_file, 1); 4075 }); 4076 4077 if (warn_uninitialized) 4078 { 4079 uninitialized_vars_warning (DECL_INITIAL (decl)); 4080 setjmp_args_warning (); 4081 } 4082 } 4083 4084 /* Dump rtl after flow analysis. */ 4085 4086 if (flow_dump) 4087 { 4088 close_dump_file (print_rtl_with_bb, insns); 4089 if (graph_dump_format != no_graph) 4090 print_rtl_graph_with_bb (dump_base_name, ".flow", insns); 4091 } 4092 4093 /* The first life analysis pass has finished. From now on we can not 4094 generate any new pseudos. */ 4095 no_new_pseudos = 1; 4096 4097 /* If -opt, try combining insns through substitution. */ 4098 4099 if (optimize > 0) 4100 { 4101 TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ())); 4102 4103 /* Dump rtl code after insn combination. */ 4104 4105 if (combine_dump) 4106 { 4107 dump_rtl (".combine", decl, print_rtl_with_bb, insns); 4108 if (graph_dump_format != no_graph) 4109 print_rtl_graph_with_bb (dump_base_name, ".combine", insns); 4110 } 4111 } 4112 4113 /* Register allocation pre-pass, to reduce number of moves 4114 necessary for two-address machines. */ 4115 if (optimize > 0 && (flag_regmove || flag_expensive_optimizations)) 4116 { 4117 if (regmove_dump) 4118 open_dump_file (".regmove", decl_printable_name (decl, 2)); 4119 4120 TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (), 4121 rtl_dump_file)); 4122 4123 if (regmove_dump) 4124 { 4125 close_dump_file (print_rtl_with_bb, insns); 4126 if (graph_dump_format != no_graph) 4127 print_rtl_graph_with_bb (dump_base_name, ".regmove", insns); 4128 } 4129 } 4130 4131 /* Print function header into sched dump now 4132 because doing the sched analysis makes some of the dump. */ 4133 4134 if (optimize > 0 && flag_schedule_insns) 4135 { 4136 if (sched_dump) 4137 open_dump_file (".sched", decl_printable_name (decl, 2)); 4138 4139 /* Do control and data sched analysis, 4140 and write some of the results to dump file. */ 4141 4142 TIMEVAR (sched_time, schedule_insns (rtl_dump_file)); 4143 4144 /* Dump rtl after instruction scheduling. */ 4145 4146 if (sched_dump) 4147 { 4148 close_dump_file (print_rtl_with_bb, insns); 4149 if (graph_dump_format != no_graph) 4150 print_rtl_graph_with_bb (dump_base_name, ".sched", insns); 4151 } 4152 } 4153 4154 /* Determine if the current function is a leaf before running reload 4155 since this can impact optimizations done by the prologue and 4156 epilogue thus changing register elimination offsets. */ 4157 current_function_is_leaf = leaf_function_p (); 4158 4159 /* Unless we did stupid register allocation, 4160 allocate pseudo-regs that are used only within 1 basic block. 4161 4162 RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the 4163 jump optimizer after register allocation and reloading are finished. */ 4164 4165 if (!obey_regdecls) 4166 TIMEVAR (local_alloc_time, 4167 { 4168 recompute_reg_usage (insns, ! optimize_size); 4169 regclass (insns, max_reg_num ()); 4170 rebuild_label_notes_after_reload = local_alloc (); 4171 }); 4172 else 4173 rebuild_label_notes_after_reload = 0; 4174 4175 /* Dump rtl code after allocating regs within basic blocks. */ 4176 4177 if (local_reg_dump) 4178 { 4179 open_dump_file (".lreg", decl_printable_name (decl, 2)); 4180 4181 TIMEVAR (dump_time, dump_flow_info (rtl_dump_file)); 4182 TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file)); 4183 4184 close_dump_file (print_rtl_with_bb, insns); 4185 if (graph_dump_format != no_graph) 4186 print_rtl_graph_with_bb (dump_base_name, ".lreg", insns); 4187 } 4188 4189 if (global_reg_dump) 4190 open_dump_file (".greg", decl_printable_name (decl, 2)); 4191 4192 /* Unless we did stupid register allocation, 4193 allocate remaining pseudo-regs, then do the reload pass 4194 fixing up any insns that are invalid. */ 4195 4196 TIMEVAR (global_alloc_time, 4197 { 4198 if (!obey_regdecls) 4199 failure = global_alloc (rtl_dump_file); 4200 else 4201 failure = reload (insns, 0, rtl_dump_file); 4202 }); 4203 4204 4205 if (failure) 4206 goto exit_rest_of_compilation; 4207 4208 /* Do a very simple CSE pass over just the hard registers. */ 4209 if (optimize > 0) 4210 reload_cse_regs (insns); 4211 4212 /* Register allocation and reloading may have turned an indirect jump into 4213 a direct jump. If so, we must rebuild the JUMP_LABEL fields of 4214 jumping instructions. */ 4215 if (rebuild_label_notes_after_reload) 4216 TIMEVAR (jump_time, rebuild_jump_labels (insns)); 4217 4218 /* If optimizing and we are performing instruction scheduling after 4219 reload, then go ahead and split insns now since we are about to 4220 recompute flow information anyway. 4221 4222 reload_cse_regs may expose more splitting opportunities, expecially 4223 for double-word operations. */ 4224 if (optimize > 0 && flag_schedule_insns_after_reload) 4225 { 4226 rtx insn; 4227 4228 for (insn = insns; insn; insn = NEXT_INSN (insn)) 4229 { 4230 rtx last; 4231 4232 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i') 4233 continue; 4234 4235 last = try_split (PATTERN (insn), insn, 1); 4236 4237 if (last != insn) 4238 { 4239 PUT_CODE (insn, NOTE); 4240 NOTE_SOURCE_FILE (insn) = 0; 4241 NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; 4242 } 4243 } 4244 } 4245 4246 if (global_reg_dump) 4247 { 4248 TIMEVAR (dump_time, dump_global_regs (rtl_dump_file)); 4249 close_dump_file (print_rtl_with_bb, insns); 4250 if (graph_dump_format != no_graph) 4251 print_rtl_graph_with_bb (dump_base_name, ".greg", insns); 4252 } 4253 4254 /* Re-create the death notes which were deleted during reload. */ 4255 if (flow2_dump) 4256 open_dump_file (".flow2", decl_printable_name (decl, 2)); 4257 4258 if (optimize) 4259 { 4260 TIMEVAR 4261 (flow2_time, 4262 { 4263 find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1); 4264 life_analysis (insns, max_reg_num (), rtl_dump_file, 1); 4265 }); 4266 } 4267 4268 flow2_completed = 1; 4269 4270 /* On some machines, the prologue and epilogue code, or parts thereof, 4271 can be represented as RTL. Doing so lets us schedule insns between 4272 it and the rest of the code and also allows delayed branch 4273 scheduling to operate in the epilogue. */ 4274 4275 thread_prologue_and_epilogue_insns (insns); 4276 4277 if (flow2_dump) 4278 { 4279 close_dump_file (print_rtl_with_bb, insns); 4280 if (graph_dump_format != no_graph) 4281 print_rtl_graph_with_bb (dump_base_name, ".flow2", insns); 4282 } 4283 4284 if (optimize > 0 && flag_schedule_insns_after_reload) 4285 { 4286 if (sched2_dump) 4287 open_dump_file (".sched2", decl_printable_name (decl, 2)); 4288 4289 /* Do control and data sched analysis again, 4290 and write some more of the results to dump file. */ 4291 4292 TIMEVAR (sched2_time, schedule_insns (rtl_dump_file)); 4293 4294 /* Dump rtl after post-reorder instruction scheduling. */ 4295 4296 if (sched2_dump) 4297 { 4298 close_dump_file (print_rtl_with_bb, insns); 4299 if (graph_dump_format != no_graph) 4300 print_rtl_graph_with_bb (dump_base_name, ".sched2", insns); 4301 } 4302 } 4303 4304#ifdef LEAF_REGISTERS 4305 current_function_uses_only_leaf_regs 4306 = optimize > 0 && only_leaf_regs_used () && leaf_function_p (); 4307#endif 4308 4309 /* One more attempt to remove jumps to .+1 4310 left by dead-store-elimination. 4311 Also do cross-jumping this time 4312 and delete no-op move insns. */ 4313 4314 if (optimize > 0) 4315 { 4316 TIMEVAR (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP, 4317 JUMP_NOOP_MOVES, 4318 !JUMP_AFTER_REGSCAN)); 4319 4320 /* Dump rtl code after jump, if we are doing that. */ 4321 4322 if (jump2_opt_dump) 4323 { 4324 dump_rtl (".jump2", decl, print_rtl_with_bb, insns); 4325 if (graph_dump_format != no_graph) 4326 print_rtl_graph_with_bb (dump_base_name, ".jump2", insns); 4327 } 4328 } 4329 4330 /* If a machine dependent reorganization is needed, call it. */ 4331#ifdef MACHINE_DEPENDENT_REORG 4332 MACHINE_DEPENDENT_REORG (insns); 4333 4334 if (mach_dep_reorg_dump) 4335 { 4336 dump_rtl (".mach", decl, print_rtl_with_bb, insns); 4337 if (graph_dump_format != no_graph) 4338 print_rtl_graph_with_bb (dump_base_name, ".mach", insns); 4339 } 4340#endif 4341 4342 /* If a scheduling pass for delayed branches is to be done, 4343 call the scheduling code. */ 4344 4345#ifdef DELAY_SLOTS 4346 if (optimize > 0 && flag_delayed_branch) 4347 { 4348 if (dbr_sched_dump) 4349 open_dump_file (".dbr", decl_printable_name (decl, 2)); 4350 4351 TIMEVAR (dbr_sched_time, dbr_schedule (insns, rtl_dump_file)); 4352 4353 if (dbr_sched_dump) 4354 { 4355 close_dump_file (print_rtl_with_bb, insns); 4356 if (graph_dump_format != no_graph) 4357 print_rtl_graph_with_bb (dump_base_name, ".dbr", insns); 4358 } 4359 } 4360#endif 4361 4362 /* Shorten branches. */ 4363 TIMEVAR (shorten_branch_time, 4364 { 4365 shorten_branches (get_insns ()); 4366 }); 4367 4368#ifdef STACK_REGS 4369 if (stack_reg_dump) 4370 open_dump_file (".stack", decl_printable_name (decl, 2)); 4371 4372 TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file)); 4373 4374 if (stack_reg_dump) 4375 { 4376 dump_rtl (".stack", decl, print_rtl_with_bb, insns); 4377 if (graph_dump_format != no_graph) 4378 print_rtl_graph_with_bb (dump_base_name, ".stack", insns); 4379 } 4380#endif 4381 4382 /* Now turn the rtl into assembler code. */ 4383 4384 TIMEVAR (final_time, 4385 { 4386 rtx x; 4387 char *fnname; 4388 4389 /* Get the function's name, as described by its RTL. 4390 This may be different from the DECL_NAME name used 4391 in the source file. */ 4392 4393 x = DECL_RTL (decl); 4394 if (GET_CODE (x) != MEM) 4395 abort (); 4396 x = XEXP (x, 0); 4397 if (GET_CODE (x) != SYMBOL_REF) 4398 abort (); 4399 fnname = XSTR (x, 0); 4400 4401 assemble_start_function (decl, fnname); 4402 final_start_function (insns, asm_out_file, optimize); 4403 final (insns, asm_out_file, optimize, 0); 4404 final_end_function (insns, asm_out_file, optimize); 4405 assemble_end_function (decl, fnname); 4406 if (! quiet_flag) 4407 fflush (asm_out_file); 4408 4409 /* Release all memory allocated by flow. */ 4410 free_basic_block_vars (0); 4411 4412 /* Release all memory held by regsets now */ 4413 regset_release_memory (); 4414 }); 4415 4416 /* Write DBX symbols if requested */ 4417 4418 /* Note that for those inline functions where we don't initially 4419 know for certain that we will be generating an out-of-line copy, 4420 the first invocation of this routine (rest_of_compilation) will 4421 skip over this code by doing a `goto exit_rest_of_compilation;'. 4422 Later on, finish_compilation will call rest_of_compilation again 4423 for those inline functions that need to have out-of-line copies 4424 generated. During that call, we *will* be routed past here. */ 4425 4426#ifdef DBX_DEBUGGING_INFO 4427 if (write_symbols == DBX_DEBUG) 4428 TIMEVAR (symout_time, dbxout_function (decl)); 4429#endif 4430 4431#ifdef DWARF_DEBUGGING_INFO 4432 if (write_symbols == DWARF_DEBUG) 4433 TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); 4434#endif 4435 4436#ifdef DWARF2_DEBUGGING_INFO 4437 if (write_symbols == DWARF2_DEBUG) 4438 TIMEVAR (symout_time, dwarf2out_decl (decl)); 4439#endif 4440 4441 exit_rest_of_compilation: 4442 4443 free_bb_mem (); 4444 4445 /* In case the function was not output, 4446 don't leave any temporary anonymous types 4447 queued up for sdb output. */ 4448#ifdef SDB_DEBUGGING_INFO 4449 if (write_symbols == SDB_DEBUG) 4450 sdbout_types (NULL_TREE); 4451#endif 4452 4453 /* Put back the tree of subblocks and list of arguments 4454 from before we copied them. 4455 Code generation and the output of debugging info may have modified 4456 the copy, but the original is unchanged. */ 4457 4458 if (saved_block_tree != 0) 4459 { 4460 DECL_INITIAL (decl) = saved_block_tree; 4461 DECL_ARGUMENTS (decl) = saved_arguments; 4462 DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE; 4463 } 4464 4465 reload_completed = 0; 4466 flow2_completed = 0; 4467 no_new_pseudos = 0; 4468 4469 TIMEVAR (final_time, 4470 { 4471 /* Clear out the insn_length contents now that they are no 4472 longer valid. */ 4473 init_insn_lengths (); 4474 4475 /* Clear out the real_constant_chain before some of the rtx's 4476 it runs through become garbage. */ 4477 clear_const_double_mem (); 4478 4479 /* Cancel the effect of rtl_in_current_obstack. */ 4480 resume_temporary_allocation (); 4481 4482 /* Show no temporary slots allocated. */ 4483 init_temp_slots (); 4484 }); 4485 4486 /* Make sure volatile mem refs aren't considered valid operands for 4487 arithmetic insns. We must call this here if this is a nested inline 4488 function, since the above code leaves us in the init_recog state 4489 (from final.c), and the function context push/pop code does not 4490 save/restore volatile_ok. 4491 4492 ??? Maybe it isn't necessary for expand_start_function to call this 4493 anymore if we do it here? */ 4494 4495 init_recog_no_volatile (); 4496 4497 /* The parsing time is all the time spent in yyparse 4498 *except* what is spent in this function. */ 4499 4500 parse_time -= get_run_time () - start_time; 4501 4502 /* Reset global variables. */ 4503 free_basic_block_vars (0); 4504} 4505 4506static void 4507display_help () 4508{ 4509 int undoc; 4510 unsigned long i; 4511 const char * lang; 4512 4513#ifndef USE_CPPLIB 4514 printf ("Usage: %s input [switches]\n", progname); 4515 printf ("Switches:\n"); 4516#endif 4517 printf (" -ffixed-<register> Mark <register> as being unavailable to the compiler\n"); 4518 printf (" -fcall-used-<register> Mark <register> as being corrupted by function calls\n"); 4519 printf (" -fcall-saved-<register> Mark <register> as being preserved across functions\n"); 4520 printf (" -finline-limit-<number> Limits the size of inlined functions to <number>\n"); 4521 4522 for (i = NUM_ELEM (f_options); i--;) 4523 { 4524 const char * description = f_options[i].description; 4525 4526 if (description != NULL && * description != 0) 4527 printf (" -f%-21s %s\n", 4528 f_options[i].string, description); 4529 } 4530 4531 printf (" -O[number] Set optimisation level to [number]\n"); 4532 printf (" -Os Optimise for space rather than speed\n"); 4533 printf (" -pedantic Issue warnings needed by strict compliance to ANSI C\n"); 4534 printf (" -pedantic-errors Like -pedantic except that errors are produced\n"); 4535 printf (" -w Suppress warnings\n"); 4536 printf (" -W Enable extra warnings\n"); 4537 4538 for (i = NUM_ELEM (W_options); i--;) 4539 { 4540 const char * description = W_options[i].description; 4541 4542 if (description != NULL && * description != 0) 4543 printf (" -W%-21s %s\n", 4544 W_options[i].string, description); 4545 } 4546 4547 printf (" -Wid-clash-<num> Warn if 2 identifiers have the same first <num> chars\n"); 4548 printf (" -Wlarger-than-<number> Warn if an object is larger than <number> bytes\n"); 4549 printf (" -p Enable function profiling\n"); 4550#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) 4551 printf (" -a Enable block profiling \n"); 4552#endif 4553#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) || defined FUNCTION_BLOCK_PROFILER_EXIT 4554 printf (" -ax Enable jump profiling \n"); 4555#endif 4556 printf (" -o <file> Place output into <file> \n"); 4557 printf (" -G <number> Put global and static data smaller than <number>\n"); 4558 printf (" bytes into a special section (on some targets)\n"); 4559 4560 for (i = NUM_ELEM (debug_args); i--;) 4561 { 4562 if (debug_args[i].description != NULL) 4563 printf (" -%-22s %s\n", debug_args[i].arg, debug_args[i].description); 4564 } 4565 4566 printf (" -aux-info <file> Emit declaration info into <file>.X\n"); 4567 printf (" -quiet Do not display functions compiled or elapsed time\n"); 4568 printf (" -version Display the compiler's version\n"); 4569 printf (" -d[letters] Enable dumps from specific passes of the compiler\n"); 4570 printf (" -dumpbase <file> Base name to be used for dumps from specific passes\n"); 4571#if defined HAIFA || defined INSN_SCHEDULING 4572 printf (" -sched-verbose-<number> Set the verbosity level of the scheduler\n"); 4573#endif 4574 printf (" --help Display this information\n"); 4575 4576 undoc = 0; 4577 lang = "language"; 4578 4579 /* Display descriptions of language specific options. 4580 If there is no description, note that there is an undocumented option. 4581 If the description is empty, do not display anything. (This allows 4582 options to be deliberately undocumented, for whatever reason). 4583 If the option string is missing, then this is a marker, indicating 4584 that the description string is in fact the name of a language, whose 4585 language specific options are to follow. */ 4586 4587 if (NUM_ELEM (documented_lang_options) > 1) 4588 { 4589 printf ("\nLanguage specific options:\n"); 4590 4591 for (i = 0; i < NUM_ELEM (documented_lang_options); i++) 4592 { 4593 const char * description = documented_lang_options[i].description; 4594 const char * option = documented_lang_options[i].option; 4595 4596 if (description == NULL) 4597 { 4598 undoc = 1; 4599 4600 if (extra_warnings) 4601 printf (" %-23.23s [undocumented]\n", option); 4602 } 4603 else if (* description == 0) 4604 continue; 4605 else if (option == NULL) 4606 { 4607 if (undoc) 4608 printf 4609 ("\nThere are undocumented %s specific options as well.\n", 4610 lang); 4611 undoc = 0; 4612 4613 printf ("\n Options for %s:\n", description); 4614 4615 lang = description; 4616 } 4617 else 4618 printf (" %-23.23s %s\n", option, description); 4619 } 4620 } 4621 4622 if (undoc) 4623 printf ("\nThere are undocumented %s specific options as well.\n", lang); 4624 4625 if (NUM_ELEM (target_switches) > 1 4626#ifdef TARGET_OPTIONS 4627 || NUM_ELEM (target_options) > 1 4628#endif 4629 ) 4630 { 4631 int doc = 0; 4632 4633 undoc = 0; 4634 4635 printf ("\nTarget specific options:\n"); 4636 4637 for (i = NUM_ELEM (target_switches); i--;) 4638 { 4639 const char * option = target_switches[i].name; 4640 const char * description = target_switches[i].description; 4641 4642 if (option == NULL || * option == 0) 4643 continue; 4644 else if (description == NULL) 4645 { 4646 undoc = 1; 4647 4648 if (extra_warnings) 4649 printf (" -m%-21.21s [undocumented]\n", option); 4650 } 4651 else if (* description != 0) 4652 doc += printf (" -m%-21.21s %s\n", option, description); 4653 } 4654 4655#ifdef TARGET_OPTIONS 4656 for (i = NUM_ELEM (target_options); i--;) 4657 { 4658 const char * option = target_options[i].prefix; 4659 const char * description = target_options[i].description; 4660 4661 if (option == NULL || * option == 0) 4662 continue; 4663 else if (description == NULL) 4664 { 4665 undoc = 1; 4666 4667 if (extra_warnings) 4668 printf (" -m%-21.21s [undocumented]\n", option); 4669 } 4670 else if (* description != 0) 4671 doc += printf (" -m%-21.21s %s\n", option, description); 4672 } 4673#endif 4674 if (undoc) 4675 { 4676 if (doc) 4677 printf ("\nThere are undocumented target specific options as well.\n"); 4678 else 4679 printf (" They exist, but they are not documented.\n"); 4680 } 4681 } 4682} 4683 4684/* Compare the user specified 'option' with the language 4685 specific 'lang_option'. Return true if they match, or 4686 if 'option' is a viable prefix of 'lang_option'. */ 4687 4688static int 4689check_lang_option (option, lang_option) 4690 char * option; 4691 char * lang_option; 4692{ 4693 lang_independent_options * indep_options; 4694 int len; 4695 long k; 4696 char * space; 4697 4698 /* Ignore NULL entries. */ 4699 if (option == NULL || lang_option == NULL) 4700 return 0; 4701 4702 if ((space = strchr (lang_option, ' ')) != NULL) 4703 len = space - lang_option; 4704 else 4705 len = strlen (lang_option); 4706 4707 /* If they do not match to the first n characters then fail. */ 4708 if (strncmp (option, lang_option, len) != 0) 4709 return 0; 4710 4711 /* Do not accept a lang option, if it matches a normal -f or -W 4712 option. Chill defines a -fpack, but we want to support 4713 -fpack-struct. */ 4714 4715 /* An exact match is OK */ 4716 if ((int) strlen (option) == len) 4717 return 1; 4718 4719 /* If it is not an -f or -W option allow the match */ 4720 if (option[0] != '-') 4721 return 1; 4722 4723 switch (option[1]) 4724 { 4725 case 'f': indep_options = f_options; break; 4726 case 'W': indep_options = W_options; break; 4727 default: return 1; 4728 } 4729 4730 /* The option is a -f or -W option. 4731 Skip past the prefix and search for the remainder in the 4732 appropriate table of options. */ 4733 option += 2; 4734 4735 if (option[0] == 'n' && option[1] == 'o' && option[2] == '-') 4736 option += 3; 4737 4738 for (k = NUM_ELEM (indep_options); k--;) 4739 { 4740 if (!strcmp (option, indep_options[k].string)) 4741 { 4742 /* The option matched a language independent option, 4743 do not allow the language specific match. */ 4744 4745 return 0; 4746 } 4747 } 4748 4749 /* The option matches the start of the langauge specific option 4750 and it is not an exact match for a language independent option. */ 4751 return 1; 4752} 4753 4754/* Entry point of cc1/c++. Decode command args, then call compile_file. 4755 Exit code is 35 if can't open files, 34 if fatal error, 4756 33 if had nonfatal errors, else success. */ 4757 4758int 4759main (argc, argv) 4760 int argc; 4761 char **argv; 4762{ 4763 register int i; 4764 char *filename = 0; 4765 int flag_print_mem = 0; 4766 int version_flag = 0; 4767 char *p; 4768 4769 /* save in case md file wants to emit args as a comment. */ 4770 save_argc = argc; 4771 save_argv = argv; 4772 4773 p = argv[0] + strlen (argv[0]); 4774 while (p != argv[0] && p[-1] != '/' 4775#ifdef DIR_SEPARATOR 4776 && p[-1] != DIR_SEPARATOR 4777#endif 4778 ) 4779 --p; 4780 progname = p; 4781 4782#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT) 4783 /* Get rid of any avoidable limit on stack size. */ 4784 { 4785 struct rlimit rlim; 4786 4787 /* Set the stack limit huge so that alloca does not fail. */ 4788 getrlimit (RLIMIT_STACK, &rlim); 4789 rlim.rlim_cur = rlim.rlim_max; 4790 setrlimit (RLIMIT_STACK, &rlim); 4791 } 4792#endif 4793 4794#ifdef HAVE_LC_MESSAGES 4795 setlocale (LC_MESSAGES, ""); 4796#endif 4797 (void) bindtextdomain (PACKAGE, localedir); 4798 (void) textdomain (PACKAGE); 4799 4800 signal (SIGFPE, float_signal); 4801 4802#ifdef SIGPIPE 4803 signal (SIGPIPE, pipe_closed); 4804#endif 4805 4806 decl_printable_name = decl_name; 4807 lang_expand_expr = (lang_expand_expr_t) do_abort; 4808 4809 /* Initialize whether `char' is signed. */ 4810 flag_signed_char = DEFAULT_SIGNED_CHAR; 4811#ifdef DEFAULT_SHORT_ENUMS 4812 /* Initialize how much space enums occupy, by default. */ 4813 flag_short_enums = DEFAULT_SHORT_ENUMS; 4814#endif 4815 4816 /* Perform language-specific options intialization. */ 4817 lang_init_options (); 4818 4819 /* Scan to see what optimization level has been specified. That will 4820 determine the default value of many flags. */ 4821 for (i = 1; i < argc; i++) 4822 { 4823 if (!strcmp (argv[i], "-O")) 4824 { 4825 optimize = 1; 4826 optimize_size = 0; 4827 } 4828 else if (argv[i][0] == '-' && argv[i][1] == 'O') 4829 { 4830 /* Handle -Os, -O2, -O3, -O69, ... */ 4831 char *p = &argv[i][2]; 4832 4833 if ((p[0] == 's') && (p[1] == 0)) 4834 { 4835 optimize_size = 1; 4836 4837 /* Optimizing for size forces optimize to be 2. */ 4838 optimize = 2; 4839 } 4840 else 4841 { 4842 const int optimize_val = read_integral_parameter (p, p - 2, -1); 4843 if (optimize_val != -1) 4844 { 4845 optimize = optimize_val; 4846#ifdef __alpha__ 4847 if (optimize > 1) 4848 { 4849 #ifdef FORCE_OPTIMIZATION_DOWNGRADE 4850 optimize = 1; 4851 warning ("\n***\n***\t-O%d converted to \"-O1\" due to optimizer bugs on this platform\n***\n", 4852 optimize_val); 4853 #else 4854 warning ("\n***\n***\tThe -O%d flag TRIGGERS KNOWN OPTIMIZER BUGS ON THIS PLATFORM\n***\n", 4855 optimize_val); 4856 #endif 4857 } 4858#endif /*__alpha__*/ 4859 optimize_size = 0; 4860 } 4861 } 4862 } 4863 } 4864 4865 obey_regdecls = (optimize == 0); 4866 4867 if (optimize >= 1) 4868 { 4869 flag_defer_pop = 1; 4870 flag_thread_jumps = 1; 4871#ifdef DELAY_SLOTS 4872 flag_delayed_branch = 1; 4873#endif 4874#ifdef CAN_DEBUG_WITHOUT_FP 4875 flag_omit_frame_pointer = 1; 4876#endif 4877 } 4878 4879 if (optimize >= 2) 4880 { 4881 flag_cse_follow_jumps = 1; 4882 flag_cse_skip_blocks = 1; 4883 flag_gcse = 1; 4884 flag_expensive_optimizations = 1; 4885 flag_strength_reduce = 1; 4886 flag_rerun_cse_after_loop = 1; 4887 flag_rerun_loop_opt = 1; 4888 flag_caller_saves = 1; 4889 flag_force_mem = 1; 4890#ifdef INSN_SCHEDULING 4891 flag_schedule_insns = 1; 4892 flag_schedule_insns_after_reload = 1; 4893#endif 4894 flag_regmove = 1; 4895 } 4896 4897 if (optimize >= 3) 4898 { 4899 flag_inline_functions = 1; 4900 } 4901 4902 /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can 4903 modify it. */ 4904 target_flags = 0; 4905 set_target_switch (""); 4906 4907#ifdef OPTIMIZATION_OPTIONS 4908 /* Allow default optimizations to be specified on a per-machine basis. */ 4909 OPTIMIZATION_OPTIONS (optimize, optimize_size); 4910#endif 4911 4912 /* Initialize register usage now so switches may override. */ 4913 init_reg_sets (); 4914 4915 for (i = 1; i < argc; i++) 4916 { 4917 size_t j; 4918 4919 /* If this is a language-specific option, 4920 decode it in a language-specific way. */ 4921 for (j = NUM_ELEM (documented_lang_options); j--;) 4922 if (check_lang_option (argv[i], documented_lang_options[j].option)) 4923 break; 4924 4925 if (j != (size_t)-1) 4926 { 4927 /* If the option is valid for *some* language, 4928 treat it as valid even if this language doesn't understand it. */ 4929 int strings_processed = lang_decode_option (argc - i, argv + i); 4930 4931 if (!strcmp (argv[i], "--help")) 4932 { 4933 display_help (); 4934 exit (0); 4935 } 4936 4937 if (strings_processed != 0) 4938 i += strings_processed - 1; 4939 } 4940 else if (argv[i][0] == '-' && argv[i][1] != 0) 4941 { 4942 register char *str = argv[i] + 1; 4943 if (str[0] == 'Y') 4944 str++; 4945 4946 if (str[0] == 'm') 4947 set_target_switch (&str[1]); 4948 else if (!strcmp (str, "dumpbase")) 4949 { 4950 dump_base_name = argv[++i]; 4951 } 4952 else if (str[0] == 'd') 4953 { 4954 register char *p = &str[1]; 4955 while (*p) 4956 switch (*p++) 4957 { 4958 case 'a': 4959 branch_prob_dump = 1; 4960 combine_dump = 1; 4961#ifdef DELAY_SLOTS 4962 dbr_sched_dump = 1; 4963#endif 4964 flow_dump = 1; 4965 flow2_dump = 1; 4966 global_reg_dump = 1; 4967 jump_opt_dump = 1; 4968 addressof_dump = 1; 4969 jump2_opt_dump = 1; 4970 local_reg_dump = 1; 4971 loop_dump = 1; 4972 regmove_dump = 1; 4973 rtl_dump = 1; 4974 cse_dump = 1, cse2_dump = 1; 4975 gcse_dump = 1; 4976 sched_dump = 1; 4977 sched2_dump = 1; 4978#ifdef STACK_REGS 4979 stack_reg_dump = 1; 4980#endif 4981#ifdef MACHINE_DEPENDENT_REORG 4982 mach_dep_reorg_dump = 1; 4983#endif 4984 break; 4985 case 'A': 4986 flag_debug_asm = 1; 4987 break; 4988 case 'b': 4989 branch_prob_dump = 1; 4990 break; 4991 case 'c': 4992 combine_dump = 1; 4993 break; 4994#ifdef DELAY_SLOTS 4995 case 'd': 4996 dbr_sched_dump = 1; 4997 break; 4998#endif 4999 case 'f': 5000 flow_dump = 1; 5001 break; 5002 case 'F': 5003 addressof_dump = 1; 5004 break; 5005 case 'g': 5006 global_reg_dump = 1; 5007 break; 5008 case 'G': 5009 gcse_dump = 1; 5010 break; 5011 case 'j': 5012 jump_opt_dump = 1; 5013 break; 5014 case 'J': 5015 jump2_opt_dump = 1; 5016 break; 5017#ifdef STACK_REGS 5018 case 'k': 5019 stack_reg_dump = 1; 5020 break; 5021#endif 5022 case 'l': 5023 local_reg_dump = 1; 5024 break; 5025 case 'L': 5026 loop_dump = 1; 5027 break; 5028 case 'm': 5029 flag_print_mem = 1; 5030 break; 5031#ifdef MACHINE_DEPENDENT_REORG 5032 case 'M': 5033 mach_dep_reorg_dump = 1; 5034 break; 5035#endif 5036 case 'p': 5037 flag_print_asm_name = 1; 5038 break; 5039 case 'r': 5040 rtl_dump = 1; 5041 break; 5042 case 'R': 5043 sched2_dump = 1; 5044 break; 5045 case 's': 5046 cse_dump = 1; 5047 break; 5048 case 'S': 5049 sched_dump = 1; 5050 break; 5051 case 't': 5052 cse2_dump = 1; 5053 break; 5054 case 'N': 5055 regmove_dump = 1; 5056 break; 5057 case 'v': 5058 graph_dump_format = vcg; 5059 break; 5060 case 'w': 5061 flow2_dump = 1; 5062 break; 5063 case 'y': 5064 set_yydebug (1); 5065 break; 5066 case 'x': 5067 rtl_dump_and_exit = 1; 5068 break; 5069 case 'D': /* these are handled by the preprocessor */ 5070 case 'I': 5071 break; 5072 default: 5073 warning ("unrecognised gcc debugging option: %c", p[-1]); 5074 break; 5075 } 5076 } 5077 else if (str[0] == 'f') 5078 { 5079 register char *p = &str[1]; 5080 int found = 0; 5081 5082 /* Some kind of -f option. 5083 P's value is the option sans `-f'. 5084 Search for it in the table of options. */ 5085 5086 for (j = 0; 5087 !found && j < sizeof (f_options) / sizeof (f_options[0]); 5088 j++) 5089 { 5090 if (!strcmp (p, f_options[j].string)) 5091 { 5092 *f_options[j].variable = f_options[j].on_value; 5093 /* A goto here would be cleaner, 5094 but breaks the vax pcc. */ 5095 found = 1; 5096 } 5097 if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' 5098 && ! strcmp (p+3, f_options[j].string)) 5099 { 5100 *f_options[j].variable = ! f_options[j].on_value; 5101 found = 1; 5102 } 5103 } 5104 5105 if (found) 5106 ; 5107 else if (!strncmp (p, "inline-limit-", 13)) 5108 inline_max_insns = 5109 read_integral_parameter (p + 13, p - 2, inline_max_insns); 5110#ifdef HAIFA 5111#ifdef INSN_SCHEDULING 5112 else if (!strncmp (p, "sched-verbose-",14)) 5113 fix_sched_param("verbose",&p[14]); 5114#endif 5115#endif /* HAIFA */ 5116 else if (!strncmp (p, "fixed-", 6)) 5117 fix_register (&p[6], 1, 1); 5118 else if (!strncmp (p, "call-used-", 10)) 5119 fix_register (&p[10], 0, 1); 5120 else if (!strncmp (p, "call-saved-", 11)) 5121 fix_register (&p[11], 0, 0); 5122 else 5123 error ("Invalid option `%s'", argv[i]); 5124 } 5125 else if (str[0] == 'O') 5126 { 5127 /* Already been treated above. Do nothing. */ 5128 } 5129 else if (!strcmp (str, "pedantic")) 5130 pedantic = 1; 5131 else if (!strcmp (str, "pedantic-errors")) 5132 flag_pedantic_errors = pedantic = 1; 5133 else if (!strcmp (str, "quiet")) 5134 quiet_flag = 1; 5135 else if (!strcmp (str, "version")) 5136 version_flag = 1; 5137 else if (!strcmp (str, "w")) 5138 inhibit_warnings = 1; 5139 else if (!strcmp (str, "W")) 5140 { 5141 extra_warnings = 1; 5142 /* We save the value of warn_uninitialized, since if they put 5143 -Wuninitialized on the command line, we need to generate a 5144 warning about not using it without also specifying -O. */ 5145 if (warn_uninitialized != 1) 5146 warn_uninitialized = 2; 5147 } 5148 else if (str[0] == 'W') 5149 { 5150 register char *p = &str[1]; 5151 int found = 0; 5152 5153 /* Some kind of -W option. 5154 P's value is the option sans `-W'. 5155 Search for it in the table of options. */ 5156 5157 for (j = 0; 5158 !found && j < sizeof (W_options) / sizeof (W_options[0]); 5159 j++) 5160 { 5161 if (!strcmp (p, W_options[j].string)) 5162 { 5163 *W_options[j].variable = W_options[j].on_value; 5164 /* A goto here would be cleaner, 5165 but breaks the vax pcc. */ 5166 found = 1; 5167 } 5168 if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' 5169 && ! strcmp (p+3, W_options[j].string)) 5170 { 5171 *W_options[j].variable = ! W_options[j].on_value; 5172 found = 1; 5173 } 5174 } 5175 5176 if (found) 5177 ; 5178 else if (!strncmp (p, "id-clash-", 9)) 5179 { 5180 const int id_clash_val 5181 = read_integral_parameter (p + 9, p - 2, -1); 5182 if (id_clash_val != -1) 5183 { 5184 id_clash_len = id_clash_val; 5185 warn_id_clash = 1; 5186 } 5187 } 5188 else if (!strncmp (p, "larger-than-", 12)) 5189 { 5190 const int larger_than_val 5191 = read_integral_parameter (p + 12, p - 2, -1); 5192 if (larger_than_val != -1) 5193 { 5194 larger_than_size = larger_than_val; 5195 warn_larger_than = 1; 5196 } 5197 } 5198 else 5199 error ("Invalid option `%s'", argv[i]); 5200 } 5201 else if (!strcmp (str, "p")) 5202 { 5203 profile_flag = 1; 5204 } 5205 else if (!strcmp (str, "a")) 5206 { 5207#if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER) 5208 warning ("`-a' option (basic block profile) not supported"); 5209#else 5210 profile_block_flag = (profile_block_flag < 2) ? 1 : 3; 5211#endif 5212 } 5213 else if (!strcmp (str, "ax")) 5214 { 5215#if !defined (FUNCTION_BLOCK_PROFILER_EXIT) || !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER) 5216 warning ("`-ax' option (jump profiling) not supported"); 5217#else 5218 profile_block_flag = (!profile_block_flag 5219 || profile_block_flag == 2) ? 2 : 3; 5220#endif 5221 } 5222 else if (str[0] == 'g') 5223 { 5224 unsigned level; 5225 /* A lot of code assumes write_symbols == NO_DEBUG if the 5226 debugging level is 0 (thus -gstabs1 -gstabs0 would lose track 5227 of what debugging type has been selected). This records the 5228 selected type. It is an error to specify more than one 5229 debugging type. */ 5230 static enum debug_info_type selected_debug_type = NO_DEBUG; 5231 /* Non-zero if debugging format has been explicitly set. 5232 -g and -ggdb don't explicitly set the debugging format so 5233 -gdwarf -g3 is equivalent to -gdwarf3. */ 5234 static int type_explicitly_set_p = 0; 5235 /* Indexed by enum debug_info_type. */ 5236 static const char *debug_type_names[] = 5237 { 5238 "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff" 5239 }; 5240 5241 /* The maximum admissible debug level value. */ 5242 static const unsigned max_debug_level = 3; 5243 5244 /* Look up STR in the table. */ 5245 for (da = debug_args; da->arg; da++) 5246 { 5247 const int da_len = strlen (da->arg); 5248 5249 if (! strncmp (str, da->arg, da_len)) 5250 { 5251 enum debug_info_type type = da->debug_type; 5252 const char *p = str + da_len; 5253 5254 if (*p && (*p < '0' || *p > '9')) 5255 continue; 5256 5257 /* A debug flag without a level defaults to level 2. 5258 Note we do not want to call read_integral_parameter 5259 for that case since it will call atoi which 5260 will return zero. 5261 5262 ??? We may want to generalize the interface to 5263 read_integral_parameter to better handle this case 5264 if this case shows up often. */ 5265 if (*p) 5266 level = read_integral_parameter (p, 0, 5267 max_debug_level + 1); 5268 else 5269 level = 2; 5270 5271 if (da_len > 1 && *p && !strncmp (str, "gdwarf", da_len)) 5272 { 5273 error ("use -gdwarf -g%d for DWARF v1, level %d", 5274 level, level); 5275 if (level == 2) 5276 error ("use -gdwarf-2 for DWARF v2"); 5277 } 5278 5279 if (level > max_debug_level) 5280 { 5281 warning ("ignoring option `%s' due to invalid debug level specification", 5282 str - 1); 5283 level = debug_info_level; 5284 } 5285 5286 if (type == NO_DEBUG) 5287 { 5288 type = PREFERRED_DEBUGGING_TYPE; 5289 if (da_len > 1 && strncmp (str, "ggdb", da_len) == 0) 5290 { 5291#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2) 5292 type = DWARF2_DEBUG; 5293#else 5294#ifdef DBX_DEBUGGING_INFO 5295 type = DBX_DEBUG; 5296#endif 5297#endif 5298 } 5299 } 5300 5301 if (type == NO_DEBUG) 5302 warning ("`-%s' not supported by this configuration of GCC", 5303 str); 5304 5305 /* Does it conflict with an already selected type? */ 5306 if (type_explicitly_set_p 5307 /* -g/-ggdb don't conflict with anything */ 5308 && da->debug_type != NO_DEBUG 5309 && type != selected_debug_type) 5310 warning ("`-%s' ignored, conflicts with `-g%s'", 5311 str, debug_type_names[(int) selected_debug_type]); 5312 else 5313 { 5314 /* If the format has already been set, -g/-ggdb 5315 only change the debug level. */ 5316 if (type_explicitly_set_p 5317 && da->debug_type == NO_DEBUG) 5318 ; /* don't change debugging type */ 5319 else 5320 { 5321 selected_debug_type = type; 5322 type_explicitly_set_p = da->debug_type != NO_DEBUG; 5323 } 5324 write_symbols = (level == 0 5325 ? NO_DEBUG 5326 : selected_debug_type); 5327 use_gnu_debug_info_extensions = da->use_extensions_p; 5328 debug_info_level = (enum debug_info_level) level; 5329 } 5330 break; 5331 } 5332 } 5333 if (! da->arg) 5334 warning ("`-%s' not supported by this configuration of GCC", 5335 str); 5336 } 5337 else if (!strcmp (str, "o")) 5338 { 5339 asm_file_name = argv[++i]; 5340 } 5341 else if (str[0] == 'G') 5342 { 5343 const int g_switch_val = (str[1] != '\0') ? 5344 read_integral_parameter(str + 1, 0, -1) : 5345 read_integral_parameter(argv[++i], 0, -1); 5346 5347 if (g_switch_val != -1) 5348 { 5349 g_switch_set = TRUE; 5350 g_switch_value = g_switch_val; 5351 } 5352 else 5353 { 5354 error("Invalid option `-%s'",str); 5355 } 5356 } 5357 else if (!strncmp (str, "aux-info", 8)) 5358 { 5359 flag_gen_aux_info = 1; 5360 aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]); 5361 } 5362 else if (!strcmp (str, "-help")) 5363 { 5364 display_help (); 5365 exit (0); 5366 } 5367 else 5368 error ("Invalid option `%s'", argv[i]); 5369 } 5370 else if (argv[i][0] == '+') 5371 error ("Invalid option `%s'", argv[i]); 5372 else 5373 filename = argv[i]; 5374 } 5375 5376 /* Checker uses the frame pointer. */ 5377 if (flag_check_memory_usage) 5378 flag_omit_frame_pointer = 0; 5379 5380 if (optimize == 0) 5381 { 5382 /* Inlining does not work if not optimizing, 5383 so force it not to be done. */ 5384 flag_no_inline = 1; 5385 warn_inline = 0; 5386 5387 /* The c_decode_option and lang_decode_option functions set 5388 this to `2' if -Wall is used, so we can avoid giving out 5389 lots of errors for people who don't realize what -Wall does. */ 5390 if (warn_uninitialized == 1) 5391 warning ("-Wuninitialized is not supported without -O"); 5392 } 5393 5394#ifdef OVERRIDE_OPTIONS 5395 /* Some machines may reject certain combinations of options. */ 5396 OVERRIDE_OPTIONS; 5397#endif 5398 5399 if (exceptions_via_longjmp == 2) 5400 { 5401#ifdef DWARF2_UNWIND_INFO 5402 exceptions_via_longjmp = ! DWARF2_UNWIND_INFO; 5403#else 5404 exceptions_via_longjmp = 1; 5405#endif 5406 } 5407 5408 if (profile_block_flag == 3) 5409 { 5410 warning ("`-ax' and `-a' are conflicting options. `-a' ignored."); 5411 profile_block_flag = 2; 5412 } 5413 5414 /* Unrolling all loops implies that standard loop unrolling must also 5415 be done. */ 5416 if (flag_unroll_all_loops) 5417 flag_unroll_loops = 1; 5418 /* Loop unrolling requires that strength_reduction be on also. Silently 5419 turn on strength reduction here if it isn't already on. Also, the loop 5420 unrolling code assumes that cse will be run after loop, so that must 5421 be turned on also. */ 5422 if (flag_unroll_loops) 5423 { 5424 flag_strength_reduce = 1; 5425 flag_rerun_cse_after_loop = 1; 5426 } 5427 5428 /* Warn about options that are not supported on this machine. */ 5429#ifndef INSN_SCHEDULING 5430 if (flag_schedule_insns || flag_schedule_insns_after_reload) 5431 warning ("instruction scheduling not supported on this target machine"); 5432#endif 5433#ifndef DELAY_SLOTS 5434 if (flag_delayed_branch) 5435 warning ("this target machine does not have delayed branches"); 5436#endif 5437 5438 user_label_prefix = USER_LABEL_PREFIX; 5439 if (flag_leading_underscore != -1) 5440 { 5441 /* If the default prefix is more complicated than "" or "_", 5442 issue a warning and ignore this option. */ 5443 if (user_label_prefix[0] == 0 || 5444 (user_label_prefix[0] == '_' && user_label_prefix[1] == 0)) 5445 { 5446 user_label_prefix = flag_leading_underscore ? "_" : ""; 5447 } 5448 else 5449 warning ("-f%sleading-underscore not supported on this target machine", 5450 flag_leading_underscore ? "" : "no-"); 5451 } 5452 5453 /* If we are in verbose mode, write out the version and maybe all the 5454 option flags in use. */ 5455 if (version_flag) 5456 { 5457 print_version (stderr, ""); 5458 if (! quiet_flag) 5459 print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n"); 5460 } 5461 5462 compile_file (filename); 5463 5464#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX) 5465 if (flag_print_mem) 5466 { 5467 char *lim = (char *) sbrk (0); 5468 5469 notice ("Data size %ld.\n", (long) (lim - (char *) &environ)); 5470 fflush (stderr); 5471 5472#ifndef __MSDOS__ 5473#ifdef USG 5474 system ("ps -l 1>&2"); 5475#else /* not USG */ 5476 system ("ps v"); 5477#endif /* not USG */ 5478#endif 5479 } 5480#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN) && ! __INTERIX */ 5481 5482 if (errorcount) 5483 exit (FATAL_EXIT_CODE); 5484 if (sorrycount) 5485 exit (FATAL_EXIT_CODE); 5486 exit (SUCCESS_EXIT_CODE); 5487 return 0; 5488} 5489 5490/* Decode -m switches. */ 5491/* Decode the switch -mNAME. */ 5492 5493static void 5494set_target_switch (name) 5495 const char *name; 5496{ 5497 register size_t j; 5498 int valid_target_option = 0; 5499 5500 for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++) 5501 if (!strcmp (target_switches[j].name, name)) 5502 { 5503 if (target_switches[j].value < 0) 5504 target_flags &= ~-target_switches[j].value; 5505 else 5506 target_flags |= target_switches[j].value; 5507 valid_target_option = 1; 5508 } 5509 5510#ifdef TARGET_OPTIONS 5511 if (!valid_target_option) 5512 for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++) 5513 { 5514 int len = strlen (target_options[j].prefix); 5515 if (!strncmp (target_options[j].prefix, name, len)) 5516 { 5517 *target_options[j].variable = name + len; 5518 valid_target_option = 1; 5519 } 5520 } 5521#endif 5522 5523 if (!valid_target_option) 5524 error ("Invalid option `%s'", name); 5525} 5526 5527/* Print version information to FILE. 5528 Each line begins with INDENT (for the case where FILE is the 5529 assembler output file). */ 5530 5531static void 5532print_version (file, indent) 5533 FILE *file; 5534 const char *indent; 5535{ 5536#ifndef __VERSION__ 5537#define __VERSION__ "[?]" 5538#endif 5539 fnotice (file, 5540#ifdef __GNUC__ 5541 "%s%s%s version %s (%s) compiled by GNU C version %s.\n" 5542#else 5543 "%s%s%s version %s (%s) compiled by CC.\n" 5544#endif 5545 , indent, *indent != 0 ? " " : "", 5546 language_string, version_string, TARGET_NAME, __VERSION__); 5547} 5548 5549/* Print an option value and return the adjusted position in the line. 5550 ??? We don't handle error returns from fprintf (disk full); presumably 5551 other code will catch a disk full though. */ 5552 5553static int 5554print_single_switch (file, pos, max, indent, sep, term, type, name) 5555 FILE *file; 5556 int pos, max; 5557 const char *indent, *sep, *term, *type, *name; 5558{ 5559 /* The ultrix fprintf returns 0 on success, so compute the result we want 5560 here since we need it for the following test. */ 5561 int len = strlen (sep) + strlen (type) + strlen (name); 5562 5563 if (pos != 0 5564 && pos + len > max) 5565 { 5566 fprintf (file, "%s", term); 5567 pos = 0; 5568 } 5569 if (pos == 0) 5570 { 5571 fprintf (file, "%s", indent); 5572 pos = strlen (indent); 5573 } 5574 fprintf (file, "%s%s%s", sep, type, name); 5575 pos += len; 5576 return pos; 5577} 5578 5579/* Print active target switches to FILE. 5580 POS is the current cursor position and MAX is the size of a "line". 5581 Each line begins with INDENT and ends with TERM. 5582 Each switch is separated from the next by SEP. */ 5583 5584static void 5585print_switch_values (file, pos, max, indent, sep, term) 5586 FILE *file; 5587 int pos, max; 5588 const char *indent, *sep, *term; 5589{ 5590 size_t j; 5591 char **p; 5592 5593 /* Print the options as passed. */ 5594 5595 pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term, 5596 _("options passed: "), ""); 5597 5598 for (p = &save_argv[1]; *p != NULL; p++) 5599 if (**p == '-') 5600 { 5601 /* Ignore these. */ 5602 if (strcmp (*p, "-o") == 0) 5603 { 5604 if (p[1] != NULL) 5605 p++; 5606 continue; 5607 } 5608 if (strcmp (*p, "-quiet") == 0) 5609 continue; 5610 if (strcmp (*p, "-version") == 0) 5611 continue; 5612 if ((*p)[1] == 'd') 5613 continue; 5614 5615 pos = print_single_switch (file, pos, max, indent, sep, term, *p, ""); 5616 } 5617 if (pos > 0) 5618 fprintf (file, "%s", term); 5619 5620 /* Print the -f and -m options that have been enabled. 5621 We don't handle language specific options but printing argv 5622 should suffice. */ 5623 5624 pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term, 5625 _("options enabled: "), ""); 5626 5627 for (j = 0; j < sizeof f_options / sizeof f_options[0]; j++) 5628 if (*f_options[j].variable == f_options[j].on_value) 5629 pos = print_single_switch (file, pos, max, indent, sep, term, 5630 "-f", f_options[j].string); 5631 5632 /* Print target specific options. */ 5633 5634 for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++) 5635 if (target_switches[j].name[0] != '\0' 5636 && target_switches[j].value > 0 5637 && ((target_switches[j].value & target_flags) 5638 == target_switches[j].value)) 5639 { 5640 pos = print_single_switch (file, pos, max, indent, sep, term, 5641 "-m", target_switches[j].name); 5642 } 5643 5644#ifdef TARGET_OPTIONS 5645 for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++) 5646 if (*target_options[j].variable != NULL) 5647 { 5648 char prefix[256]; 5649 sprintf (prefix, "-m%s", target_options[j].prefix); 5650 pos = print_single_switch (file, pos, max, indent, sep, term, 5651 prefix, *target_options[j].variable); 5652 } 5653#endif 5654 5655 fprintf (file, "%s", term); 5656} 5657 5658/* Record the beginning of a new source file, named FILENAME. */ 5659 5660void 5661debug_start_source_file (filename) 5662 register char *filename ATTRIBUTE_UNUSED; 5663{ 5664#ifdef DBX_DEBUGGING_INFO 5665 if (write_symbols == DBX_DEBUG) 5666 dbxout_start_new_source_file (filename); 5667#endif 5668#ifdef DWARF_DEBUGGING_INFO 5669 if (debug_info_level == DINFO_LEVEL_VERBOSE 5670 && write_symbols == DWARF_DEBUG) 5671 dwarfout_start_new_source_file (filename); 5672#endif /* DWARF_DEBUGGING_INFO */ 5673#ifdef DWARF2_DEBUGGING_INFO 5674 if (debug_info_level == DINFO_LEVEL_VERBOSE 5675 && write_symbols == DWARF2_DEBUG) 5676 dwarf2out_start_source_file (filename); 5677#endif /* DWARF2_DEBUGGING_INFO */ 5678#ifdef SDB_DEBUGGING_INFO 5679 if (write_symbols == SDB_DEBUG) 5680 sdbout_start_new_source_file (filename); 5681#endif 5682} 5683 5684/* Record the resumption of a source file. LINENO is the line number in 5685 the source file we are returning to. */ 5686 5687void 5688debug_end_source_file (lineno) 5689 register unsigned lineno ATTRIBUTE_UNUSED; 5690{ 5691#ifdef DBX_DEBUGGING_INFO 5692 if (write_symbols == DBX_DEBUG) 5693 dbxout_resume_previous_source_file (); 5694#endif 5695#ifdef DWARF_DEBUGGING_INFO 5696 if (debug_info_level == DINFO_LEVEL_VERBOSE 5697 && write_symbols == DWARF_DEBUG) 5698 dwarfout_resume_previous_source_file (lineno); 5699#endif /* DWARF_DEBUGGING_INFO */ 5700#ifdef DWARF2_DEBUGGING_INFO 5701 if (debug_info_level == DINFO_LEVEL_VERBOSE 5702 && write_symbols == DWARF2_DEBUG) 5703 dwarf2out_end_source_file (); 5704#endif /* DWARF2_DEBUGGING_INFO */ 5705#ifdef SDB_DEBUGGING_INFO 5706 if (write_symbols == SDB_DEBUG) 5707 sdbout_resume_previous_source_file (); 5708#endif 5709} 5710 5711/* Called from check_newline in c-parse.y. The `buffer' parameter contains 5712 the tail part of the directive line, i.e. the part which is past the 5713 initial whitespace, #, whitespace, directive-name, whitespace part. */ 5714 5715void 5716debug_define (lineno, buffer) 5717 register unsigned lineno ATTRIBUTE_UNUSED; 5718 register char *buffer ATTRIBUTE_UNUSED; 5719{ 5720#ifdef DWARF_DEBUGGING_INFO 5721 if (debug_info_level == DINFO_LEVEL_VERBOSE 5722 && write_symbols == DWARF_DEBUG) 5723 dwarfout_define (lineno, buffer); 5724#endif /* DWARF_DEBUGGING_INFO */ 5725#ifdef DWARF2_DEBUGGING_INFO 5726 if (debug_info_level == DINFO_LEVEL_VERBOSE 5727 && write_symbols == DWARF2_DEBUG) 5728 dwarf2out_define (lineno, buffer); 5729#endif /* DWARF2_DEBUGGING_INFO */ 5730} 5731 5732/* Called from check_newline in c-parse.y. The `buffer' parameter contains 5733 the tail part of the directive line, i.e. the part which is past the 5734 initial whitespace, #, whitespace, directive-name, whitespace part. */ 5735 5736void 5737debug_undef (lineno, buffer) 5738 register unsigned lineno ATTRIBUTE_UNUSED; 5739 register char *buffer ATTRIBUTE_UNUSED; 5740{ 5741#ifdef DWARF_DEBUGGING_INFO 5742 if (debug_info_level == DINFO_LEVEL_VERBOSE 5743 && write_symbols == DWARF_DEBUG) 5744 dwarfout_undef (lineno, buffer); 5745#endif /* DWARF_DEBUGGING_INFO */ 5746#ifdef DWARF2_DEBUGGING_INFO 5747 if (debug_info_level == DINFO_LEVEL_VERBOSE 5748 && write_symbols == DWARF2_DEBUG) 5749 dwarf2out_undef (lineno, buffer); 5750#endif /* DWARF2_DEBUGGING_INFO */ 5751} 5752