#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "c-common.h"
#include "c-pragma.h"
#include "flags.h"
#include "toplev.h"
#include "langhooks.h"
#include "tree-inline.h"
#include "diagnostic.h"
#include "intl.h"
#include "cppdefault.h"
#include "c-incpath.h"
#include "debug.h"
#include "opts.h"
#include "options.h"
#include "mkdeps.h"
#ifndef DOLLARS_IN_IDENTIFIERS
# define DOLLARS_IN_IDENTIFIERS true
#endif
#ifndef TARGET_SYSTEM_ROOT
# define TARGET_SYSTEM_ROOT NULL
#endif
#ifndef TARGET_OPTF
#define TARGET_OPTF(ARG)
#endif
static cpp_options *cpp_opts;
static const char *this_input_filename;
static const char *out_fname;
static FILE *out_stream;
static bool deps_append;
static bool deps_seen;
static bool verbose;
static const char *deps_file;
static const char *iprefix;
static const char *sysroot = TARGET_SYSTEM_ROOT;
static bool std_inc = true;
static bool std_cxx_inc = true;
static bool quote_chain_split;
static bool warn_unused_macros;
static bool warn_variadic_macros = true;
static size_t deferred_count;
static size_t include_cursor;
static void set_Wimplicit (int);
static void handle_OPT_d (const char *);
static void set_std_cxx98 (int);
static void set_std_c89 (int, int);
static void set_std_c99 (int);
static void check_deps_environment_vars (void);
static void handle_deferred_opts (void);
static void sanitize_cpp_opts (void);
static void add_prefixed_path (const char *, size_t);
static void push_command_line_include (void);
static void cb_file_change (cpp_reader *, const struct line_map *);
static void cb_dir_change (cpp_reader *, const char *);
static void finish_options (void);
#ifndef STDC_0_IN_SYSTEM_HEADERS
#define STDC_0_IN_SYSTEM_HEADERS 0
#endif
static void defer_opt (enum opt_code, const char *);
static struct deferred_opt
{
enum opt_code code;
const char *arg;
} *deferred_opts;
bool
c_common_missing_argument (const char *opt, size_t code)
{
switch (code)
{
default:
return false;
case OPT_fconstant_string_class_:
error ("no class name specified with %qs", opt);
break;
case OPT_A:
error ("assertion missing after %qs", opt);
break;
case OPT_D:
case OPT_U:
error ("macro name missing after %qs", opt);
break;
case OPT_F:
case OPT_I:
case OPT_idirafter:
case OPT_isysroot:
case OPT_isystem:
case OPT_iquote:
error ("missing path after %qs", opt);
break;
case OPT_MF:
case OPT_MD:
case OPT_MMD:
case OPT_include:
case OPT_imacros:
case OPT_o:
error ("missing filename after %qs", opt);
break;
case OPT_MQ:
case OPT_MT:
error ("missing makefile target after %qs", opt);
break;
}
return true;
}
static void
defer_opt (enum opt_code code, const char *arg)
{
deferred_opts[deferred_count].code = code;
deferred_opts[deferred_count].arg = arg;
deferred_count++;
}
unsigned int
c_common_init_options (unsigned int argc, const char **argv)
{
static const unsigned int lang_flags[] = {CL_C, CL_ObjC, CL_CXX, CL_ObjCXX};
unsigned int i, result;
if (c_dialect_cxx ())
{
diagnostic_line_cutoff (global_dc) = 80;
diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
}
parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89,
ident_hash, &line_table);
cpp_opts = cpp_get_options (parse_in);
cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
cpp_opts->objc = c_dialect_objc ();
cpp_opts->warn_dollars = 0;
#ifdef WARN_FOUR_CHAR_CONSTANTS
cpp_opts->warn_four_char_constants = WARN_FOUR_CHAR_CONSTANTS;
#endif
flag_const_strings = c_dialect_cxx ();
flag_exceptions = c_dialect_cxx ();
warn_pointer_arith = c_dialect_cxx ();
deferred_opts = XNEWVEC (struct deferred_opt, argc);
result = lang_flags[c_language];
if (c_language == clk_c)
{
for (i = 1; i < argc; i++)
if (! strcmp (argv[i], "-lang-asm"))
{
result |= CL_C | CL_ObjC | CL_CXX | CL_ObjCXX;
break;
}
}
return result;
}
int
c_common_handle_option (size_t scode, const char *arg, int value)
{
const struct cl_option *option = &cl_options[scode];
enum opt_code code = (enum opt_code) scode;
int result = 1;
switch (code)
{
default:
if (cl_options[code].flags & (CL_C | CL_CXX | CL_ObjC | CL_ObjCXX))
break;
result = 0;
break;
case OPT__output_pch_:
pch_file = arg;
break;
case OPT_A:
defer_opt (code, arg);
break;
case OPT_C:
cpp_opts->discard_comments = 0;
break;
case OPT_CC:
cpp_opts->discard_comments = 0;
cpp_opts->discard_comments_in_macro_exp = 0;
break;
case OPT_D:
defer_opt (code, arg);
break;
case OPT_E:
flag_preprocess_only = 1;
break;
case OPT_H:
cpp_opts->print_include_names = 1;
break;
case OPT_F:
TARGET_OPTF (xstrdup (arg));
break;
case OPT_I:
if (strcmp (arg, "-"))
add_path (xstrdup (arg), BRACKET, 0, true);
else
{
if (quote_chain_split)
error ("-I- specified twice");
quote_chain_split = true;
split_quote_chain ();
inform ("obsolete option -I- used, please use -iquote instead");
}
break;
case OPT_M:
case OPT_MM:
cpp_opts->deps.style = (code == OPT_M ? DEPS_SYSTEM: DEPS_USER);
flag_no_output = 1;
cpp_opts->inhibit_warnings = 1;
break;
case OPT_MD:
case OPT_MMD:
cpp_opts->deps.style = (code == OPT_MD ? DEPS_SYSTEM: DEPS_USER);
deps_file = arg;
break;
case OPT_MF:
deps_seen = true;
deps_file = arg;
break;
case OPT_MG:
deps_seen = true;
cpp_opts->deps.missing_files = true;
break;
case OPT_MP:
deps_seen = true;
cpp_opts->deps.phony_targets = true;
break;
case OPT_MQ:
case OPT_MT:
deps_seen = true;
defer_opt (code, arg);
break;
case OPT_P:
flag_no_line_commands = 1;
break;
case OPT_W_warnings:
cpp_opts->no_pound_warnings = !value;
break;
case OPT_fworking_directory:
flag_working_directory = value;
break;
case OPT_U:
defer_opt (code, arg);
break;
case OPT_Wall:
case OPT_Wmost:
set_Wunused (value);
set_Wformat (value);
set_Wimplicit (value);
warn_char_subscripts = value;
warn_missing_braces = value;
if (code != OPT_Wmost)
warn_parentheses = value;
warn_return_type = value;
warn_sequence_point = value;
if (c_dialect_cxx ())
warn_sign_compare = value;
warn_switch = value;
warn_strict_aliasing = value;
warn_unknown_pragmas = value;
if (warn_uninitialized != 1)
warn_uninitialized = (value ? 2 : 0);
if (!c_dialect_cxx ())
warn_main = value * 2;
else
{
warn_nonvdtor = value;
warn_reorder = value;
warn_nontemplate_friend = value;
}
cpp_opts->warn_trigraphs = value;
cpp_opts->warn_comments = value;
cpp_opts->warn_num_sign_change = value;
cpp_opts->warn_multichar = value;
break;
case OPT_Wcomment:
case OPT_Wcomments:
cpp_opts->warn_comments = value;
break;
case OPT_Wdeprecated:
cpp_opts->warn_deprecated = value;
break;
case OPT_Wdiv_by_zero:
warn_div_by_zero = value;
break;
case OPT_Wendif_labels:
cpp_opts->warn_endif_labels = value;
break;
case OPT_Werror:
cpp_opts->warnings_are_errors = value;
global_dc->warning_as_error_requested = value;
break;
case OPT_Wextra_tokens:
cpp_opts->warn_extra_tokens = value;
break;
case OPT_Werror_implicit_function_declaration:
mesg_implicit_function_declaration = 2;
break;
case OPT_Wformat:
set_Wformat (value);
break;
case OPT_Wformat_:
set_Wformat (atoi (arg));
break;
case OPT_Wfour_char_constants:
cpp_opts->warn_four_char_constants = value;
break;
case OPT_Wimplicit:
set_Wimplicit (value);
break;
case OPT_Wimport:
break;
case OPT_Winvalid_pch:
cpp_opts->warn_invalid_pch = value;
break;
case OPT_Wmain:
if (value)
warn_main = 1;
else
warn_main = -1;
break;
case OPT_Wmissing_include_dirs:
cpp_opts->warn_missing_include_dirs = value;
break;
case OPT_Wmultichar:
cpp_opts->warn_multichar = value;
break;
case OPT_Wnewline_eof:
cpp_opts->warn_newline_at_eof = value;
break;
case OPT_Wnormalized_:
if (!value || (arg && strcasecmp (arg, "none") == 0))
cpp_opts->warn_normalize = normalized_none;
else if (!arg || strcasecmp (arg, "nfkc") == 0)
cpp_opts->warn_normalize = normalized_KC;
else if (strcasecmp (arg, "id") == 0)
cpp_opts->warn_normalize = normalized_identifier_C;
else if (strcasecmp (arg, "nfc") == 0)
cpp_opts->warn_normalize = normalized_C;
else
error ("argument %qs to %<-Wnormalized%> not recognized", arg);
break;
case OPT_Wreturn_type:
warn_return_type = value;
break;
case OPT_Wsystem_headers:
cpp_opts->warn_system_headers = value;
break;
case OPT_Wtraditional:
cpp_opts->warn_traditional = value;
break;
case OPT_Wtrigraphs:
cpp_opts->warn_trigraphs = value;
break;
case OPT_Wundef:
cpp_opts->warn_undef = value;
break;
case OPT_Wunknown_pragmas:
warn_unknown_pragmas = value * 2;
break;
case OPT_Wunused_macros:
warn_unused_macros = value;
break;
case OPT_Wvariadic_macros:
warn_variadic_macros = value;
break;
case OPT_Wwrite_strings:
if (!c_dialect_cxx ())
flag_const_strings = value;
else
warn_write_strings = value;
break;
case OPT_ansi:
if (!c_dialect_cxx ())
set_std_c89 (false, true);
else
set_std_cxx98 (true);
break;
case OPT_arch:
break;
case OPT_d:
handle_OPT_d (arg);
break;
case OPT_fcond_mismatch:
if (!c_dialect_cxx ())
{
flag_cond_mismatch = value;
break;
}
case OPT_fall_virtual:
case OPT_falt_external_templates:
case OPT_fenum_int_equiv:
case OPT_fexternal_templates:
case OPT_fguiding_decls:
case OPT_fhonor_std:
case OPT_fhuge_objects:
case OPT_flabels_ok:
case OPT_fname_mangling_version_:
case OPT_fnew_abi:
case OPT_fnonnull_objects:
case OPT_fsquangle:
case OPT_fstrict_prototype:
case OPT_fthis_is_variable:
case OPT_fvtable_thunks:
case OPT_fxref:
case OPT_fvtable_gc:
warning ("switch %qs is no longer supported", option->opt_text);
break;
case OPT_faccess_control:
flag_access_control = value;
break;
case OPT_fasm:
flag_no_asm = !value;
break;
case OPT_fasm_blocks:
flag_cw_asm_blocks = value;
break;
case OPT_fbuiltin:
flag_no_builtin = !value;
break;
case OPT_fbuiltin_:
if (value)
result = 0;
else
disable_builtin_function (arg);
break;
case OPT_fdisable_typechecking_for_spec:
disable_typechecking_for_spec_flag = value;
break;
case OPT_fdollars_in_identifiers:
cpp_opts->dollars_in_ident = value;
break;
case OPT_ffreestanding:
value = !value;
case OPT_fhosted:
flag_hosted = value;
flag_no_builtin = !value;
if (!value && warn_main == 2)
warn_main = 0;
break;
case OPT_fshort_double:
flag_short_double = value;
break;
case OPT_fshort_enums:
flag_short_enums = value;
break;
case OPT_fshort_wchar:
flag_short_wchar = value;
break;
case OPT_fsigned_bitfields:
flag_signed_bitfields = value;
break;
case OPT_fsigned_char:
flag_signed_char = value;
break;
case OPT_funsigned_bitfields:
flag_signed_bitfields = !value;
break;
case OPT_funsigned_char:
flag_signed_char = !value;
break;
case OPT_fclone_structors:
flag_clone_structors = value;
break;
case OPT_fcheck_new:
flag_check_new = value;
break;
case OPT_fconserve_space:
flag_conserve_space = value;
break;
case OPT_fconst_strings:
flag_const_strings = value;
break;
case OPT_fconstant_string_class_:
constant_string_class_name = arg;
break;
case OPT_fdefault_inline:
flag_default_inline = value;
break;
case OPT_felide_constructors:
flag_elide_constructors = value;
break;
case OPT_fenforce_eh_specs:
flag_enforce_eh_specs = value;
break;
case OPT_ffixed_form:
case OPT_ffixed_line_length_:
if (!flag_preprocess_only)
result = 0;
break;
case OPT_ffor_scope:
flag_new_for_scope = value;
break;
case OPT_fgnu_keywords:
flag_no_gnu_keywords = !value;
break;
case OPT_fgnu_runtime:
flag_next_runtime = !value;
break;
case OPT_fhandle_exceptions:
warning ("-fhandle-exceptions has been renamed -fexceptions (and is now on by default)");
flag_exceptions = value;
break;
case OPT_fimplement_inlines:
flag_implement_inlines = value;
break;
case OPT_fimplicit_inline_templates:
flag_implicit_inline_templates = value;
break;
case OPT_fimplicit_templates:
flag_implicit_templates = value;
break;
case OPT_fms_extensions:
flag_ms_extensions = value;
break;
case OPT_fnext_runtime:
flag_next_runtime = value;
break;
case OPT_fnil_receivers:
flag_nil_receivers = value;
break;
case OPT_fnonansi_builtins:
flag_no_nonansi_builtin = !value;
break;
case OPT_fobjc_call_cxx_cdtors:
flag_objc_call_cxx_cdtors = value;
break;
case OPT_fobjc_exceptions:
flag_objc_exceptions = value;
break;
case OPT_fobjc_sjlj_exceptions:
flag_objc_sjlj_exceptions = value;
break;
case OPT_foperator_names:
cpp_opts->operator_names = value;
break;
case OPT_foptional_diags:
flag_optional_diags = value;
break;
case OPT_fpch_deps:
cpp_opts->restore_pch_deps = value;
break;
case OPT_fpch_preprocess:
flag_pch_preprocess = value;
break;
case OPT_fpermissive:
flag_permissive = value;
break;
case OPT_fpreprocessed:
cpp_opts->preprocessed = value;
flag_preprocessed = value;
break;
case OPT_freplace_objc_classes:
flag_replace_objc_classes = value;
break;
case OPT_frepo:
flag_use_repository = value;
if (value)
flag_implicit_templates = 0;
break;
case OPT_frtti:
flag_rtti = value;
break;
case OPT_fshow_column:
cpp_opts->show_column = value;
break;
case OPT_fstats:
flag_detailed_statistics = value;
break;
case OPT_ftabstop_:
if (value >= 1 && value <= 100)
cpp_opts->tabstop = value;
break;
case OPT_fexec_charset_:
cpp_opts->narrow_charset = arg;
break;
case OPT_fwide_exec_charset_:
cpp_opts->wide_charset = arg;
break;
case OPT_finput_charset_:
cpp_opts->input_charset = arg;
break;
case OPT_ftemplate_depth_:
max_tinst_depth = value;
break;
case OPT_fuse_cxa_atexit:
flag_use_cxa_atexit = value;
break;
case OPT_fvisibility_inlines_hidden:
visibility_options.inlines_hidden = value;
break;
case OPT_fweak:
flag_weak = value;
break;
case OPT_fthreadsafe_statics:
flag_threadsafe_statics = value;
break;
case OPT_fzero_link:
flag_zero_link = value;
break;
case OPT_gen_decls:
flag_gen_declaration = 1;
break;
case OPT_idirafter:
add_path (xstrdup (arg), AFTER, 0, true);
break;
case OPT_imacros:
case OPT_include:
defer_opt (code, arg);
break;
case OPT_iprefix:
iprefix = arg;
break;
case OPT_iquote:
add_path (xstrdup (arg), QUOTE, 0, true);
break;
case OPT_isysroot:
sysroot = arg;
break;
case OPT_isystem:
add_path (xstrdup (arg), SYSTEM, 0, true);
break;
case OPT_iwithprefix:
add_prefixed_path (arg, SYSTEM);
break;
case OPT_iwithprefixbefore:
add_prefixed_path (arg, BRACKET);
break;
case OPT_lang_asm:
cpp_set_lang (parse_in, CLK_ASM);
cpp_opts->dollars_in_ident = false;
break;
case OPT_lang_objc:
cpp_opts->objc = 1;
break;
case OPT_nostdinc:
std_inc = false;
break;
case OPT_nostdinc__:
std_cxx_inc = false;
break;
case OPT_o:
if (!out_fname)
out_fname = arg;
else
error ("output filename specified twice");
break;
case OPT_pedantic_errors:
cpp_opts->pedantic_errors = 1;
case OPT_pedantic:
cpp_opts->pedantic = 1;
cpp_opts->warn_endif_labels = 1;
break;
case OPT_print_objc_runtime_info:
print_struct_values = 1;
break;
case OPT_remap:
cpp_opts->remap = 1;
break;
case OPT_std_c__98:
case OPT_std_gnu__98:
set_std_cxx98 (code == OPT_std_c__98 );
break;
case OPT_std_c89:
case OPT_std_iso9899_1990:
case OPT_std_iso9899_199409:
set_std_c89 (code == OPT_std_iso9899_199409 , true );
break;
case OPT_std_gnu89:
set_std_c89 (false , false );
break;
case OPT_std_c99:
case OPT_std_c9x:
case OPT_std_iso9899_1999:
case OPT_std_iso9899_199x:
set_std_c99 (true );
break;
case OPT_std_gnu99:
case OPT_std_gnu9x:
set_std_c99 (false );
break;
case OPT_trigraphs:
cpp_opts->trigraphs = 1;
break;
case OPT_traditional_cpp:
cpp_opts->traditional = 1;
break;
case OPT_undef:
flag_undef = 1;
break;
case OPT_w:
cpp_opts->inhibit_warnings = 1;
break;
case OPT_v:
verbose = true;
break;
case OPT_fast:
case OPT_fastcp:
case OPT_fastf:
break;
}
return result;
}
bool
c_common_post_options (const char **pfilename)
{
struct cpp_callbacks *cb;
if (in_fnames == NULL)
{
in_fnames = XNEWVEC (const char *, 1);
in_fnames[0] = "";
}
else if (predictive_compilation >= 0)
{
set_stdin_option(parse_in, predictive_compilation);
}
else if (strcmp (in_fnames[0], "-") == 0)
in_fnames[0] = "";
if (out_fname == NULL || !strcmp (out_fname, "-"))
out_fname = "";
if (cpp_opts->deps.style == DEPS_NONE)
check_deps_environment_vars ();
handle_deferred_opts ();
sanitize_cpp_opts ();
register_include_chains (parse_in, sysroot, iprefix,
std_inc, std_cxx_inc && c_dialect_cxx (), verbose);
flag_inline_trees = 1;
if (!flag_no_inline)
flag_no_inline = 1;
if (flag_inline_functions)
flag_inline_trees = 2;
if (num_in_fnames > 1)
flag_unit_at_a_time = 1;
if (flag_objc_sjlj_exceptions < 0)
flag_objc_sjlj_exceptions = flag_next_runtime;
if (flag_objc_exceptions && !flag_objc_sjlj_exceptions)
flag_exceptions = 1;
if (warn_sign_compare == -1)
warn_sign_compare = extra_warnings;
if (warn_missing_field_initializers == -1)
warn_missing_field_initializers = extra_warnings;
if (warn_format_y2k && !warn_format)
warning ("-Wformat-y2k ignored without -Wformat");
if (warn_format_extra_args && !warn_format)
warning ("-Wformat-extra-args ignored without -Wformat");
if (warn_format_zero_length && !warn_format)
warning ("-Wformat-zero-length ignored without -Wformat");
if (warn_format_nonliteral && !warn_format)
warning ("-Wformat-nonliteral ignored without -Wformat");
if (warn_format_security && !warn_format)
warning ("-Wformat-security ignored without -Wformat");
if (warn_missing_format_attribute && !warn_format)
warning ("-Wmissing-format-attribute ignored without -Wformat");
if (flag_isoc99)
flag_complex_method = 2;
if (flag_preprocess_only)
{
if (out_fname[0] == '\0')
out_stream = stdout;
else
out_stream = fopen (out_fname, "w");
if (out_stream == NULL)
{
fatal_error ("opening output file %s: %m", out_fname);
return false;
}
if (num_in_fnames > 1)
error ("too many filenames given. Type %s --help for usage",
progname);
init_pp_output (out_stream);
}
else
{
init_c_lex ();
input_location = UNKNOWN_LOCATION;
}
cb = cpp_get_callbacks (parse_in);
cb->file_change = cb_file_change;
cb->dir_change = cb_dir_change;
cpp_post_options (parse_in);
input_location = UNKNOWN_LOCATION;
errorcount += cpp_errors (parse_in);
*pfilename = this_input_filename
= cpp_read_main_file (parse_in, in_fnames[0]);
if (this_input_filename == NULL)
{
errorcount++;
return false;
}
if (flag_working_directory
&& flag_preprocess_only && !flag_no_line_commands)
pp_dir_change (parse_in, get_src_pwd ());
return flag_preprocess_only;
}
bool
c_common_init (void)
{
cpp_opts->precision = TYPE_PRECISION (intmax_type_node);
cpp_opts->char_precision = TYPE_PRECISION (char_type_node);
cpp_opts->int_precision = TYPE_PRECISION (integer_type_node);
cpp_opts->wchar_precision = TYPE_PRECISION (wchar_type_node);
cpp_opts->unsigned_wchar = TYPE_UNSIGNED (wchar_type_node);
cpp_opts->bytes_big_endian = BYTES_BIG_ENDIAN;
cpp_init_iconv (parse_in);
if (flag_preprocess_only)
{
finish_options ();
preprocess_file (parse_in);
return false;
}
init_pragma ();
return true;
}
void
c_common_parse_file (int set_yydebug)
{
unsigned int i;
#if YYDEBUG != 0
yydebug = set_yydebug;
#else
if (set_yydebug)
warning ("YYDEBUG was not defined at build time, -dy ignored");
#endif
i = 0;
for (;;)
{
if (debug_hooks->start_end_main_source_file)
(*debug_hooks->start_source_file) (0, this_input_filename);
finish_options ();
pch_init ();
push_file_scope ();
c_parse_file ();
finish_file ();
pop_file_scope ();
if (debug_hooks->start_end_main_source_file)
(*debug_hooks->end_source_file) (0);
if (++i >= num_in_fnames)
break;
cpp_undef_all (parse_in);
this_input_filename
= cpp_read_main_file (parse_in, in_fnames[i]);
if (!this_input_filename)
break;
}
}
void
c_common_finish (void)
{
FILE *deps_stream = NULL;
if (cpp_opts->deps.style != DEPS_NONE)
{
if (!deps_file)
deps_stream = out_stream;
else
{
deps_stream = fopen (deps_file, deps_append ? "a": "w");
if (!deps_stream)
fatal_error ("opening dependency file %s: %m", deps_file);
}
}
errorcount += cpp_finish (parse_in, deps_stream);
if (deps_stream && deps_stream != out_stream
&& (ferror (deps_stream) || fclose (deps_stream)))
fatal_error ("closing dependency file %s: %m", deps_file);
if (out_stream && (ferror (out_stream) || fclose (out_stream)))
fatal_error ("when writing output to %s: %m", out_fname);
}
static void
check_deps_environment_vars (void)
{
char *spec;
GET_ENVIRONMENT (spec, "DEPENDENCIES_OUTPUT");
if (spec)
cpp_opts->deps.style = DEPS_USER;
else
{
GET_ENVIRONMENT (spec, "SUNPRO_DEPENDENCIES");
if (spec)
{
cpp_opts->deps.style = DEPS_SYSTEM;
cpp_opts->deps.ignore_main_file = true;
}
}
if (spec)
{
char *s = strchr (spec, ' ');
if (s)
{
defer_opt (OPT_MT, s + 1);
*s = '\0';
}
if (!deps_file)
deps_file = spec;
deps_append = 1;
deps_seen = true;
}
}
static void
handle_deferred_opts (void)
{
size_t i;
struct deps *deps;
if (!deps_seen)
return;
deps = cpp_get_deps (parse_in);
for (i = 0; i < deferred_count; i++)
{
struct deferred_opt *opt = &deferred_opts[i];
if (opt->code == OPT_MT || opt->code == OPT_MQ)
deps_add_target (deps, opt->arg, opt->code == OPT_MQ);
}
}
static void
sanitize_cpp_opts (void)
{
if (deps_seen && cpp_opts->deps.style == DEPS_NONE)
error ("to generate dependencies you must specify either -M or -MM");
if (flag_dump_macros == 'M')
flag_no_output = 1;
if (flag_no_output)
{
if (flag_dump_macros != 'M')
flag_dump_macros = 0;
flag_dump_includes = 0;
flag_no_line_commands = 1;
}
cpp_opts->unsigned_char = !flag_signed_char;
cpp_opts->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS;
cpp_opts->warn_long_long
= warn_long_long && ((!flag_isoc99 && pedantic) || warn_traditional);
cpp_opts->warn_variadic_macros
= warn_variadic_macros && (pedantic || warn_traditional);
if (flag_working_directory == -1)
flag_working_directory = (debug_info_level != DINFO_LEVEL_NONE);
}
static void
add_prefixed_path (const char *suffix, size_t chain)
{
char *path;
const char *prefix;
size_t prefix_len, suffix_len;
suffix_len = strlen (suffix);
prefix = iprefix ? iprefix : cpp_GCC_INCLUDE_DIR;
prefix_len = iprefix ? strlen (iprefix) : cpp_GCC_INCLUDE_DIR_len;
path = (char *) xmalloc (prefix_len + suffix_len + 1);
memcpy (path, prefix, prefix_len);
memcpy (path + prefix_len, suffix, suffix_len);
path[prefix_len + suffix_len] = '\0';
add_path (path, chain, 0, false);
}
static void
finish_options (void)
{
if (!cpp_opts->preprocessed)
{
size_t i;
cpp_change_file (parse_in, LC_RENAME, _("<built-in>"));
cpp_init_builtins (parse_in, flag_hosted);
c_cpp_builtins (parse_in);
cpp_opts->warn_dollars = (cpp_opts->pedantic && !cpp_opts->c99);
cpp_change_file (parse_in, LC_RENAME, _("<command line>"));
for (i = 0; i < deferred_count; i++)
{
struct deferred_opt *opt = &deferred_opts[i];
if (opt->code == OPT_D)
cpp_define (parse_in, opt->arg);
else if (opt->code == OPT_U)
cpp_undef (parse_in, opt->arg);
else if (opt->code == OPT_A)
{
if (opt->arg[0] == '-')
cpp_unassert (parse_in, opt->arg + 1);
else
cpp_assert (parse_in, opt->arg);
}
}
for (i = 0; i < deferred_count; i++)
{
struct deferred_opt *opt = &deferred_opts[i];
if (opt->code == OPT_imacros
&& cpp_push_include (parse_in, opt->arg))
{
include_cursor = deferred_count + 1;
cpp_scan_nooutput (parse_in);
}
}
}
include_cursor = 0;
push_command_line_include ();
}
static void
push_command_line_include (void)
{
while (include_cursor < deferred_count)
{
struct deferred_opt *opt = &deferred_opts[include_cursor++];
if (!cpp_opts->preprocessed && opt->code == OPT_include
&& cpp_push_include (parse_in, opt->arg))
return;
}
if (include_cursor == deferred_count)
{
include_cursor++;
cpp_opts->warn_unused_macros = warn_unused_macros;
if (!cpp_opts->preprocessed)
cpp_change_file (parse_in, LC_RENAME, this_input_filename);
line_table.trace_includes = cpp_opts->print_include_names;
}
}
static void
cb_file_change (cpp_reader * ARG_UNUSED (pfile),
const struct line_map *new_map)
{
if (flag_preprocess_only)
pp_file_change (new_map);
else
fe_file_change (new_map);
if (new_map == 0 || (new_map->reason == LC_LEAVE && MAIN_FILE_P (new_map)))
push_command_line_include ();
}
void
cb_dir_change (cpp_reader * ARG_UNUSED (pfile), const char *dir)
{
if (!set_src_pwd (dir))
warning ("too late for # directive to set debug directory");
}
static void
set_std_c89 (int c94, int iso)
{
if (cpp_opts->lang != CLK_ASM)
cpp_set_lang (parse_in, c94 ? CLK_STDC94: iso ? CLK_STDC89: CLK_GNUC89);
flag_iso = iso;
flag_no_asm = iso;
flag_no_gnu_keywords = iso;
flag_no_nonansi_builtin = iso;
flag_isoc94 = c94;
flag_isoc99 = 0;
flag_writable_strings = 0;
}
static void
set_std_c99 (int iso)
{
cpp_set_lang (parse_in, iso ? CLK_STDC99: CLK_GNUC99);
flag_no_asm = iso;
flag_no_nonansi_builtin = iso;
flag_iso = iso;
flag_isoc99 = 1;
flag_isoc94 = 1;
flag_writable_strings = 0;
}
static void
set_std_cxx98 (int iso)
{
cpp_set_lang (parse_in, iso ? CLK_CXX98: CLK_GNUCXX);
flag_no_gnu_keywords = iso;
flag_no_nonansi_builtin = iso;
flag_iso = iso;
}
static void
set_Wimplicit (int on)
{
warn_implicit = on;
warn_implicit_int = on;
if (on)
{
if (mesg_implicit_function_declaration != 2)
mesg_implicit_function_declaration = 1;
}
else
mesg_implicit_function_declaration = 0;
}
static void
handle_OPT_d (const char *arg)
{
char c;
while ((c = *arg++) != '\0')
switch (c)
{
case 'M':
case 'N':
case 'D':
flag_dump_macros = c;
break;
case 'I':
flag_dump_includes = 1;
break;
}
}