diff options
Diffstat (limited to 'gcc-4.8.1/gcc/c-family')
28 files changed, 0 insertions, 34643 deletions
diff --git a/gcc-4.8.1/gcc/c-family/ChangeLog b/gcc-4.8.1/gcc/c-family/ChangeLog deleted file mode 100644 index 3acbfe392..000000000 --- a/gcc-4.8.1/gcc/c-family/ChangeLog +++ /dev/null @@ -1,2433 +0,0 @@ -2013-05-31 Release Manager - - * GCC 4.8.1 released. - -2013-05-14 Jakub Jelinek <jakub@redhat.com> - - PR c++/57274 - * c-common.c (verify_tree): Don't recurse into SIZEOF_EXPR. - -2013-03-22 Release Manager - - * GCC 4.8.0 released. - -2013-03-09 Richard Sandiford <rdsandiford@googlemail.com> - - PR middle-end/56524 - * c-common.c (handle_optimize_attribute): Don't call - save_optabs_if_changed. - -2013-03-05 Jakub Jelinek <jakub@redhat.com> - - PR middle-end/56461 - * c-pch.c (pch_init): Free target_validity at the end. - -2013-03-04 Jakub Jelinek <jakub@redhat.com> - - * c-pretty-print.c (pp_c_pretty_printer_init): Clear pp->flags. - -2013-02-28 Konstantin Serebryany <konstantin.s.serebryany@gmail.com> - Jakub Jelinek <jakub@redhat.com> - - PR sanitizer/56454 - * c-common.c (handle_no_sanitize_address_attribute): New function. - (c_common_attribute_table): Add no_sanitize_address attribute. - (handle_no_address_safety_analysis_attribute): Add - no_sanitize_address attribute, not no_address_safety_analysis - attribute. - -2013-02-18 Aldy Hernandez <aldyh@redhat.com> - - PR target/52555 - * c-common.c (handle_optimize_attribute): Call - save_optabs_if_changed. - -2013-02-18 Jakub Jelinek <jakub@redhat.com> - Steven Bosscher <steven@gcc.gnu.org> - - PR pch/54117 - * c-opts.c (c_common_post_options): If debug info is enabled - and non-dwarf*, refuse to load PCH files and when writing PCH - file warn. - -2013-02-05 Jakub Jelinek <jakub@redhat.com> - - PR middle-end/56167 - * c-common.c (handle_error_attribute): Fix condition. - -2013-01-30 Jakub Jelinek <jakub@redhat.com> - - PR c++/55742 - * c-common.c (handle_target_attribute): Revert 2012-12-26 change. - -2013-01-18 Jason Merrill <jason@redhat.com> - - PR target/54908 - * c.opt (-fextern-tls-init): New. - * c-opts.c (c_common_post_options): Handle it. - -2013-01-09 Jakub Jelinek <jakub@redhat.com> - - PR c/48418 - * c-common.c (c_fully_fold_internal): Warn for LSHIFT_EXPR and - RSHIFT_EXPR, if orig_op1 isn't INTEGER_CST, op1 is INTEGER_CST - and is either negative or bigger or equal to type precision - of the first operand. - -2012-12-03 Marek Polacek <polacek@redhat.com> - - PR c/55570 - * c-common.c (check_user_alignment): Swap order of tests, - check TREE_CODE first. - -2012-11-29 Ed Smith-Rowland <3dw4rd@verizon.net> - - PR c++/52654 - * c-common.h (overflow_type): New enum. - (build_userdef_literal): Add overflow_type argument. - (tree_userdef_literal): Add overflow_type. - (USERDEF_LITERAL_OVERFLOW): New access macro. - * c-common.c (build_userdef_literal): Add overflow_type - argument. - * c-lex.c (c_lex_with_flags): Add overflow_type to - build_userdef_literal calls. - (interpret_integer, interpret_float): Add overflow_type argument. - -2012-11-28 Richard Biener <rguenther@suse.de> - - PR c/35634 - * c-gimplify.c (c_gimplify_expr): Gimplify self-modify expressions - here and use a type with proper overflow behavior for types that would - need to be promoted for the arithmetic. - -2012-11-23 Jakub Jelinek <jakub@redhat.com> - - PR sanitizer/55435 - * c-common.c (handle_no_address_safety_analysis_attribute): New - function. - (c_common_attribute_table): Add no_address_safety_analysis. - -2012-11-16 Simon Baldwin <simonb@google.com> - - * c.opt: Add f[no-]canonical-system-headers. - * c-opts.c (c_common_handle_option): Handle - OPT_fcanonical_system_headers. - -2012-11-09 Ed Smith-Rowland <3dw4rd@verizon.net> - - PR c++/54413 - * c-opts.c (c_common_handle_option): Set new flags. - * c.opt: Describe new flags. - -2012-11-09 Jason Merrill <jason@redhat.com> - - * c.opt (Wabi-tag): New. - -2012-11-09 Andi Kleen <ak@linux.intel.com> - - PR 55139 - * c-common.c (get_atomic_generic_size): Mask with - MEMMODEL_MASK - -2012-11-07 Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR c/53063 - * c.opt (Wformat): Make it Alias Wformat=1. - (Wformat-contains-nul,Wformat-extra-args,Wformat-nonliteral, - Wformat-security,Wformat-y2k,Wformat-zero-length): Use - LangEnabledBy. - (Wformat=): RejectNegative. Use LangEnabledBy. - (Wnonnull): Use LangEnabledBy. - * c-opts.c (c_common_handle_option): Do not handle Wformat here. - * c-format.c (set_Wformat): Delete. - (decode_format_attr): Replace OPT_Wformat with OPT_Wformat_. - (maybe_read_dollar_number): Likewise. - (avoid_dollar_number): Likewise. - (finish_dollar_format_checking): Likewise. - (check_format_info): Likewise. - (check_format_info_main): Likewise. - (check_format_types): Likewise. - (format_type_warning): Likewise. - * c-common.c (int): Likewise. - (check_function_sentinel): Likewise. - * c-common.h (warn_format,set_Wformat): Do not declare here. - -2012-11-07 Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR c/53063 - * c.opt(Warray-bounds,Wdelete-non-virtual-dtor,Wenum-compare, - Wmain,Woverlength-strings, Wunknown-pragmas,Wunused-macros): - Use LangEnabledBy. - (Wswitch,Wswitch-default,Wswitch-enum): Likewise. Move here from - common.opt. - (Wvariadic-macros): Init(1). - * c-opts.c (c_common_handle_option): Do not handle them - explicitly. - (c_common_post_options): Likewise. - (sanitize_cpp_opts): warn_unused_macros is now - cpp_warn_unused_macros. - (push_command_line_include): Likewise. - * c-common.c (warn_unknown_pragmas): Do not define. - * c-common.h (warn_unknown_pragmas): Do not declare. - -2012-11-07 Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR c/51294 - * c-common.c (conversion_warning): Handle conditional expressions. - -2012-10-29 Jonathan Wakely <jwakely.gcc@gmail.com> - - PR c++/54930 - * c.opt (Wreturn_local_addr): Define new option. - -2012-10-25 Jason Merrill <jason@redhat.com> - - * c.opt (Wvirtual-move-assign): New. - - * c.opt (Winherited-variadic-ctor): New. - -2012-10-25 Marc Glisse <marc.glisse@inria.fr> - - PR c++/54427 - * c-common.c (scalar_to_vector): Handle VEC_COND_EXPR. - -2012-10-23 Joseph Myers <joseph@codesourcery.com> - - * c-common.h (pch_cpp_save_state): Declare. - * c-target.def (c_preinclude): New hook. - * c-opts.c (done_preinclude): New. - (push_command_line_include): Handle default preincluded header. - (cb_file_change): Call pch_cpp_save_state when calling - push_command_line_include. - * c-pch.c (pch_ready_to_save_cpp_state, pch_cpp_state_saved) - (pch_cpp_save_state): New. - (pch_init): Call pch_cpp_save_state conditionally, instead of - calling cpp_save_state. - -2012-10-20 Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR c/53063 - PR c/40989 - * c.opt (Waddress,Wchar-subscripts,Wsign-conversion,Wimplicit, - Wimplicit-function-declaration,Wimplicit-int,Wsizeof-pointer-memaccess, - Wnarrowing,Wparentheses,Wpointer-sign,Wreturn-type,Wsequence-point, - Wsign-compare,Wuninitialized,Wmaybe-uninitialized,Wunused, - Wvolatile-register-var): Add LangEnabledBy or EnabledBy. - * c-opts.c (c_common_handle_option): Remove explicit handling from - here. - (c_common_post_options): Likewise. - -2012-10-18 Eric Botcazou <ebotcazou@adacore.com> - - * c-ada-spec.c (LOCATION_COL): Delete. - (compare_location): New function. - (compare_node): Use it. - (compare_comment): Likewise. - -2012-10-16 Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR c/53063 - PR c/40989 - * c.opt (Wstrict-aliasing=,Wstrict-overflow=): Use LangEnabledBy. - * c-opts.c (c_common_handle_option): Do not set them here. Add - comment. - (c_common_post_options): Likewise. - -2012-10-16 Eric Botcazou <ebotcazou@adacore.com> - - * c-ada-spec.c (ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX): Define. - (dump_generic_ada_node) <INTEGER_CST>: Deal with sizetype specially. - Remove POINTER_TYPE handling, add large unsigned handling and use - ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX for big numbers. - -2012-10-12 Jakub Jelinek <jakub@redhat.com> - - PR c/54381 - * c-common.h (sizeof_pointer_memaccess_warning): Adjust prototype. - * c-common.c (sizeof_pointer_memaccess_warning): Take array of 3 - locs and array of 3 trees instead of just single loc and single - sizeof_arg tree. Handle __builtin___*_chk builtins too, and - also stpncpy, bcopy, bcmp, bzero, snprintf and vsnprintf builtins. - For *cmp* builtins that take two sources strings report warnings - about first and second source, not about destination and source. - -2012-10-12 Marc Glisse <marc.glisse@inria.fr> - - PR c++/53055 - * c-common.h (enum ref_operator) [RO_ARROW_STAR]: New. - -2012-10-11 Eric Botcazou <ebotcazou@adacore.com> - - * c-ada-spec.c (dump_ada_template): Bail out for template declarations - declaring something coming from another file. - -2012-10-10 Arnaud Charlet <charlet@adacore.com> - - PR ada/54845 - * c-ada-spec.c (print_ada_struct_decl): Increase buf size. - -2012-10-09 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/54194 - * c-common.c (warn_about_parentheses): Add location_t parameter; - use EXPR_LOC_OR_LOC. - * c-common.h: Update declaration. - -2012-10-09 Marc Glisse <marc.glisse@inria.fr> - - PR c++/54427 - * c-common.c (scalar_to_vector): Moved from c-typeck.c. Support - more operations. Make error messages optional. - * c-common.h (enum stv_conv): Moved from c-typeck.c. - (scalar_to_vector): Declare. - -2012-10-08 Jason Merrill <jason@redhat.com> - - * c-common.c (c_common_reswords): Add thread_local. - -2012-10-08 Dodji Seketeli <dodji@redhat.com> - - PR c++/53528 C++11 attribute support - * c-common.h (bitfield_p, cxx_fundamental_alignment_p): Declare - new functions. - * c-common.c (check_cxx_fundamental_alignment_constraints): New - static function. - (handle_aligned_attribute): In choose strictest alignment - among many. Use new check_cxx_fundamental_alignment_constraints. - (handle_transparent_union_attribute): In c++11 attribute syntax, - don't look through typedefs. - -2012-10-04 Arnaud Charlet <charlet@adacore.com> - - * c-ada-spec.c (print_ada_declaration): Remove handling of TDF_RAW. - * c.opt (-fdump-ada-spec, -fdump-ada-spec-slim): Move switch definition - out of dumpfile.h. - -2012-09-25 Dehao Chen <dehao@google.com> - - PR middle-end/54645 - * c-pch.c (c_common_read_pch): Rebuild the location_adhoc_data - map when read in the pch. - -2012-09-18 Arnaud Charlet <charlet@adacore.com> - - * c-ada-spec.c: Style fixes. - -2012-09-18 Thomas Quinot <quinot@adacore.com> - - * c.opt (-fada-spec-parent): Define new command line switch. - * c-ada-spec.c (get_ada_package): When -fada-spec-parent - is specified, generate binding spec as a child of the specified unit. - -2012-09-13 Paolo Carlini <paolo.carlini@oracle.com> - Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR c++/53210 - * c.opt ([Winit-self]): Enabled by -Wall in C++. - -2012-08-23 Arnaud Charlet <charlet@adacore.com> - - * c-ada-spec.c (dump_generic_ada_node): Fix handling of name_only - for pointers, and add missing Convention C pragma. - (print_ada_struct_decl): Add missing aliased keyword. - (dump_ads): Add pragma Ada_2005 and Style_Checks (Off). - -2012-08-17 Jakub Jelinek <jakub@redhat.com> - - * c-common.c (sizeof_pointer_memaccess_warning): New function. - * c.opt (-Wsizeof-pointer-memaccess): Add new option. - * c-opts.c (c_common_handle_option): Enable it for -Wall. - * c-common.h (sizeof_pointer_memaccess_warning): Add prototype. - * c-common.def (SIZEOF_EXPR): Moved here from cp-tree.def. - -2012-08-10 Richard Guenther <rguenther@suse.de> - - * c-pretty-print.c (pp_c_expression): Handle anonymous SSA names. - -2012-08-07 Steven Bosscher <steven@gcc.gnu.org> - - * c-pretty-print.c (pp_c_function_definition): Use pp_newline_and_flush - instead of separate pp_newline and pp_flush. - (print_c_tree): Likewise. - -2012-07-26 Richard Henderson <rth@redhat.com> - - * c-common.c (handle_hot_attribute): Allow labels. - (handle_cold_attribute): Likewise. - -2012-07-20 Jakub Jelinek <jakub@redhat.com> - - PR c++/28656 - * c-common.c (check_function_nonnull): Handle multiple nonnull - attributes properly. - -2012-07-16 Steven Bosscher <steven@gcc.gnu.org> - - * c-gimplify.c: Include dumpfile.h instead of tree-dump.h. - * c-ada-spec.c: Likewise. - * c-dump.c (dump_stmt): Move to cp/dump.c, the only user. - -2012-07-14 Steven Bosscher <steven@gcc.gnu.org> - - * c-pch.c (CHECK_NO_ASM_OUT_DURING_PCH): Do not define. - Remove code conditional on it. - -2012-07-11 Steven Bosscher <steven@gcc.gnu.org> - - * c-gimplify.c: Do not include basic-block.h. - * c-common.c: Do not include linfuncs.h. - -2012-07-08 Steven Bosscher <steven@gcc.gnu.org> - - * c-common.h: Include tree.h. - -2012-07-02 Jason Merrill <jason@redhat.com> - - PR c++/53524 - * c-common.c (get_priority): Call default_conversion. - -2012-07-01 Uros Bizjak <ubizjak@gmail.com> - - * c-pch.c (c_common_write_pch): Remove unused variables. - -2012-06-29 Steven Bosscher <steven@gcc.gnu.org> - - * cppspec.c: Moved from gcc/ to here. - -2012-06-27 Kai Tietz <ktietz@redhat.com> - - PR preprocessor/37215 - * c-ppoutput.c (preprocess_file): Check for nonempty buffer. - -2012-06-21 Steven Bosscher <steven@gcc.gnu.org> - - * c-common.h (c_common_print_pch_checksum): Remove. - * c-pch.c: Do not include output.h. - (CHECK_NO_ASM_OUT_DURING_PCH): Define and add FIXME. - (asm_out_file): Define iff CHECK_NO_ASM_OUT_DURING_PCH isdefined. - (asm_file_startpos): Define iff CHECK_NO_ASM_OUT_DURING_PCH is defined. - (struct c_pch_header): Remove. - (get_ident): Update gpch version. - (pch_init): Do not print executable_checksum to asm_out_file. - Do not fail if there is no asm_out_file to read back from. Set - asm_file_startpos only if CHECK_NO_ASM_OUT_DURING_PCH is defined. - (c_common_write_pch): Verify that nothing was written to asm_out_file - since pch_init was called. Do not write a c_pch_header, and do not - copy from asm_out_file to the PCH. - (c_common_read_pch): Do not read a c_pch_header, and do not restore - the content of asm_out_file from the PCH. - (c_common_print_pch_checksum): Remove. - * c-opts.c (c_common_init): Print out executable_checksum directly. - -2012-06-19 Steven Bosscher <steven@gcc.gnu.org> - - * c-target.def (objc_declare_unresolved_class_reference, - objc_declare_class_definition): Add new hooks. - -2012-06-19 Steven Bosscher <steven@gcc.gnu.org> - - * c-lex.c: Do not include output.h. - (cb_ident): Try to put out .ident with targetm.asm_out.output_ident. - Remove uses of ASM_OUTPUT_IDENT. - -2012-06-15 Marc Glisse <marc.glisse@inria.fr> - - PR c++/51033 - * c-common.h (c_build_vec_perm_expr): Move decl here. - * c-common.c (c_build_vec_perm_expr): Move definition - here. - -2012-06-06 Steven Bosscher <steven@gcc.gnu.org> - - * c.opt (fconserve-space): Turn into a no-op. - -2012-06-04 Sterling Augustine <saugustine@google.com> - - * c-pretty-print.h (pp_c_flag_gnu_v3): New enumerator. - * c-pretty-print.c (pp_c_specifier_qualifier_list): Check it at - both the start and end of the function. - -2012-06-04 Steven Bosscher <steven@gcc.gnu.org> - - * c-common.c: Do not include output.h. - * c-pragma.c: Likewise. - -2012-06-04 Steven Bosscher <steven@gcc.gnu.org> - - * error.c (dump_decl): Check pp_c_flag_gnu_v3. - (decl_as_dwarf_string, lang_decl_dwarf_name): New functions. - (lang_decl_name): Handle namespace decls. - -2012-05-31 Steven Bosscher <steven@gcc.gnu.org> - - * c-ada-spec.c: Do not include output.h. - * c-semantics.c: Likewise. - -2012-05-29 Joseph Myers <joseph@codesourcery.com> - - * c-common.c: Fix typo. - -2012-05-29 Michael Matz <matz@suse.de> - - * c-common.h (c_expand_decl): Remove prototype. - -2012-05-29 Manuel López-Ibáñez <manu@gcc.gnu.org> - - * c.opt (Wmissing-braces): Use LangEnabledBy(C ObjC,Wall). - * c-opts.c (c_common_handle_option): Remove code handling - warn_missing_braces. - -2012-05-28 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/25137 - * c-opts.c (c_common_handle_option): For C++ -Wall doesn't enable - -Wmissing_braces. - -2012-05-22 Dodji Seketeli <dodji@redhat.com> - - PR c++/53322 - * c.opt (Wunused-local-typedefs): Use EnabledBy(Wunused). - -2012-05-17 Manuel López-Ibáñez <manu@gcc.gnu.org> - - * c.opt (--pedantic-errors,-pedantic-errors): Do not handle here. - * c-opts.c (c_common_handle_option): Do not handle explicitly - Wreturn-type, Wwrite-strings, warn_ecpp, and -pedantic-errors. - -2012-05-16 Dodji Seketeli <dodji@redhat.com> - - PR preprocessor/7263 - * c-lex.c (c_lex_with_flags): Pass a virtual location to the call - to cpp_classify_number. For diagnostics, use the precise location - instead of the global input_location. - -2012-05-15 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/11856 - * c-common.c (shorten_compare): Check c_inhibit_evaluation_warnings. - -2012-05-14 Bernd Schmidt <bernds@codesourcery.com> - - * c-common.c (DEF_ATTR_STRING): Define and undefine as necessary. - -2012-05-14 Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR 53063 - * c.opt (Wc++0X-compat,Wdelete-non-virtual-dtor,Wjump-misses-init, - Wreorder): Use LangEnabledBy. - * c-opts.c (c_common_handle_option): Do not enable them - explicitly. Call lang-specific generated functions. - (c_common_post_options): Do not set them here. - -2012-05-13 Manuel López-Ibáñez <manu@gcc.gnu.org> - - * c.opt (Wclobbered,Wempty-body,Wignored-qualifiers, - Wmissing-field-initializers,Wmissing-parameter-type, - Wold-style-declaration,Woverride-init): Use EnabledBy. - * c-opts.c (c_common_post_options): Do not set here explicitly. - -2012-05-11 Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR 53063 - * c-opts.c (c_common_handle_option): Use handle_generated_option - to enable sub-options. - -2012-05-10 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/53158 - * c-common.c (warnings_for_convert_and_check): Use warning_at. - -2012-05-10 Richard Guenther <rguenther@suse.de> - - * c-common.c (c_sizeof_or_alignof_type): Remove assert and - adjust commentary about TYPE_IS_SIZETYPE types. - -2012-05-09 Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR c++/53261 - * c-common.c (warn_logical_operator): Check that argument of - integer_zerop is not NULL. - -2012-05-05 Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR c/43772 - * c-common.c (warn_logical_operator): Do not warn if either side - is already true or false. - -2012-05-04 Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR c/51712 - * c-common.c (expr_original_type): New. - (shorten_compare): Do not warn for enumeration types. - -2012-05-03 Manuel López-Ibáñez <manu@gcc.gnu.org> - - * c.opt (fpermissive): Add Var(flag_permissive). - -2012-04-30 Marc Glisse <marc.glisse@inria.fr> - - PR c++/51033 - * c-common.c (convert_vector_to_pointer_for_subscript): New function. - * c-common.h (convert_vector_to_pointer_for_subscript): Declare it. - -2012-04-30 Dodji Seketeli <dodji@redhat.com> - - Add -Wvarargs option - * c.opt (Wvarargs): Define new option. - -2012-04-30 Manuel López-Ibáñez <manu@gcc.gnu.org> - - * c-common.c (check_function_arguments): Replace - Wmissing-format-attribute with Wsuggest-attribute=format. - -2012-04-30 Manuel López-Ibáñez <manu@gcc.gnu.org> - - * c.opt (Wsuggest-attribute=format): New. Alias of - Wmissing-format-attribute. - * c-format.c (decode_format_type): Replace - Wmissing-format-attribute with Wsuggest-attribute=format. - (check_function_format): Likewise. - -2012-04-27 Ollie Wild <aaw@google.com> - - * c-common.c: Add CPP_W_LITERAL_SUFFIX mapping. - * c-opts.c (c_common_handle_option): Handle OPT_Wliteral_suffix. - * c.opt: Add Wliteral-suffix. - -2012-04-22 Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR c/44774 - * c.opt (Wpedantic): New. - (pedantic): Alias Wpedantic. - * c-opts.c (c_common_handle_option): Replace -pedantic with -Wpedantic. - (c_common_post_options): Likewise. - (sanitize_cpp_opts): Likewise. - * c-lex.c (interpret_float): Likewise. - * c-format.c (check_format_types): Likewise. - * c-common.c (pointer_int_sum): Likewise. - (c_sizeof_or_alignof_type): Likewise. - (c_add_case_label): Likewise. - (c_do_switch_warnings): Likewise. - * c-pragma.c (handle_pragma_float_const_decimal64): Likewise. - -2012-04-15 Jason Merrill <jason@redhat.com> - - PR c++/52818 - * c-format.c (CPLUSPLUS_STD_VER): C++11 inherits from C99. - (C_STD_NAME): Distinguish between C++98 and C++11. - -2012-04-11 Eric Botcazou <ebotcazou@adacore.com> - - PR target/52624 - * c-common.h (uint16_type_node): Rename into... - (c_uint16_type_node): ...this. - * c-common.c (c_common_nodes_and_builtins): Adjust for above renaming. - * c-cppbuiltin.c (builtin_define_stdint_macros): Likewise. - -2012-04-10 Manuel López-Ibáñez <manu@gcc.gnu.org> - - * c-common.c (warn_if_unused_value): Move definition to here. - * c-common.h (warn_if_unused_value): Move declaration to here. - -2012-03-23 William Bader <williambader@hotmail.com> - - * c-lex.c (c_lex_with_flags): Avoid declarations after stmts. - -2012-03-20 Jason Merrill <jason@redhat.com> - - * c-common.h (enum cxx_dialect): Add cxx1y. - * c-common.c (c_common_nodes_and_builtins): Use >= for cxx_dialect - test. - * c-cppbuiltin.c (c_cpp_builtins): Likewise. - * c-opts.c (c_common_post_options): Likewise. - (set_std_cxx1y): New. - (c_common_handle_option): Call it. - * c.opt (-std=c++1y, -std=gnu++1y): New flags. - -2012-03-19 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/14710 - * c.opt ([Wuseless-cast]): Add. - -2012-03-16 Richard Guenther <rguenther@suse.de> - - * c-pretty-print.c (pp_c_initializer_list): Adjust. - -2012-03-15 Manuel López-Ibáñez <manu@gcc.gnu.org> - - PR c++/44783 - * c.opt (ftemplate-backtrace-limit) Add. - -2012-03-12 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> - - * c-cppbuiltin.c (c_cpp_builtins): Remove #pragma extern_prefix - handling. - * c-pragma.c (handle_pragma_extern_prefix): Remove. - (init_pragma): Don't register extern_prefix. - -2012-03-12 Richard Guenther <rguenther@suse.de> - - * c-common.c (c_common_get_narrower): Use c_common_type_for_size. - (builtin_type_for_size): Likewise. - -2012-02-13 Jakub Jelinek <jakub@redhat.com> - - PR c++/52215 - * c-common.c (sync_resolve_params): Don't decide whether to convert - or not based on TYPE_SIZE comparison, convert whenever arg_type - is unsigned INTEGER_TYPE. - -2012-02-06 Paolo Carlini <paolo.carlini@oracle.com> - - PR c/52118 - * c.opt ([Wunused-local-typedefs]): Fix description. - -2012-01-24 Mike Stump <mikestump@comcast.net> - - * c-common.c (c_common_type_for_mode): Match signed/unsigned types - exactly. - -2012-01-18 Richard Guenther <rguenther@suse.de> - - * c-opts.c (c_common_post_options): Reset LTO flags if - we are about to generate a PCH. - -2012-01-17 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/51777 - * c-pretty-print.c (pp_c_integer_constant): For unsigned constants - use pp_unsigned_wide_integer. - -2012-01-10 Richard Guenther <rguenther@suse.de> - - PR middle-end/51806 - * c-opts.c (c_common_handle_option): Move -Werror handling - to language independent code. - -2012-01-05 Richard Guenther <rguenther@suse.de> - - PR middle-end/51764 - * c.opt (Wmudflap, fmudflap, fmudflapth, fmudflapir): Move here - from common.opt. - -2011-12-30 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/51316 - * c-common.c (c_sizeof_or_alignof_type): In C++ allow for alignof - of array types with an unknown bound. - -2011-12-20 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (flag_isoc99): Update comment to refer to C11. - (flag_isoc1x): Change to flag_isoc11. - * c-common.h (flag_isoc99): Update comment to refer to C11. - (flag_isoc1x): Change to flag_isoc11. - * c-cppbuiltin.c (cpp_atomic_builtins): Change comment to refer to - C11. - * c-opts.c (set_std_c1x): Change to set_std_c11. - (c_common_handle_option): Handle OPT_std_c11 and OPT_std_gnu11. - Call set_std_c11. - (set_std_c89, set_std_c99, set_std_c11): Use flag_isoc11. - (set_std_c1): Use CLK_STDC11 and CLK_GNUC11. - * c.opt (std=c1x): Change to std=c11. Document as non-draft - standard. - (std=c1x, std=iso9899:2011): Add as aliases of std=c11. - (std=gnu1x): Change to std=gnu11. Refer to non-draft standard. - (std=gnu1x): Make alias of std=gnu11. - -2011-12-19 Jason Merrill <jason@redhat.com> - - PR c++/51228 - * c-common.c (handle_transparent_union_attribute): Check the first - field if the type is complete. - -2011-12-15 Jonathan Wakely <jwakely.gcc@gmail.com> - - PR libstdc++/51365 - * c-common.c (RID_IS_FINAL): Add. - * c-common.h (RID_IS_FINAL): Add. - -2011-11-30 Iain Sandoe <iains@gcc.gnu.org> - - * c.opt (fgnu-runtime): Provide full description. - (fnext-runtime): Likewise. - * c-opts.c (OPT_fgnu_runtime, OPT_fnext_runtime) Remove. - -2011-11-28 Andrew MacLeod <amacleod@redhat.com> - - * c-cpp-builtin.c (cpp_atomic_builtins):New. Emit all atomic - predefines in one place. Add LOCK_FREE predefines. - (c_cpp_builtins): Move Legacy HAVE_SYNC predefines to - new func. - -2011-11-24 Andrew MacLeod <amacleod@redhat.com> - - PR c/51256 - * c-common.c (get_atomic_generic_size): Check for various error - conditions - (resolve_overloaded_atomic_exchange, - resolve_overloaded_atomic_compare_exchange, - resolve_overloaded_atomic_load, resolve_overloaded_atomic_store): Return - error_mark_node for error conditions. - -2011-11-08 Richard Guenther <rguenther@suse.de> - - PR middle-end/51010 - c-family/ - -2011-11-07 Richard Henderson <rth@redhat.com> - Aldy Hernandez <aldyh@redhat.com> - Torvald Riegel <triegel@redhat.com> - - Merged from transactional-memory. - - * c-common.c (handle_tm_wrap_attribute, - handle_tm_attribute, ignore_attribute, parse_tm_stmt_attr): New. - (struct c_common_reswords): Added __transaction* keywords. - (struct c_common_attribute_table): Added transaction* and tm_regparm - attributes. - * c-common.h: Added RID_TRANSACTION*. Added TM_ATTR* and TM_STMT* - masks. - (parse_tm_stmt_attr, tm_attr_to_mask, tm_mask_to_attr, - find_tm_attribute): Declare. - -2011-11-07 Jason Merrill <jason@redhat.com> - - PR c++/35688 - * c-common.c, c-common.h: Revert yesterday's changes. - -2011-11-06 Jason Merrill <jason@redhat.com> - - PR c++/35688 - * c-common.c (decl_has_visibility_attr): Split out from... - (c_determine_visibility): ...here. - * c-common.h: Declare it. - -2011-11-06 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (c_common_reswords): Add _Alignas and _Alignof. - (c_sizeof_or_alignof_type): Diagnose alignof applied to a function - type. - (check_user_alignment): New. Split out of - handle_aligned_attribute. Disallow integer constants with - noninteger types. Conditionally allow zero. - (handle_aligned_attribute): Use check_user_alignment. - * c-common.h (RID_ALIGNAS, check_user_alignment): New. - -2011-11-06 Andrew MacLeod <amacleod@redhat.com> - Richard Henderson <rth@redhat.com> - - Merged from cxx-mem-model. - - * c-cppbuiltin.c (c_cpp_builtins): Test both atomic and sync patterns. - * c-common.c (sync_resolve_params, sync_resolve_return): Only tweak - parameters that are the same type size. - (get_atomic_generic_size): New. Find size of generic - atomic function parameters and do typechecking. - (add_atomic_size_parameter): New. Insert size into parameter list. - (resolve_overloaded_atomic_exchange): Restructure __atomic_exchange to - either __atomic_exchange_n or external library call. - (resolve_overloaded_atomic_compare_exchange): Restructure - __atomic_compare_exchange to either _n variant or external library call. - (resolve_overloaded_atomic_load): Restructure __atomic_load to either - __atomic_load_n or an external library call. - (resolve_overloaded_atomic_store): Restructure __atomic_store to either - __atomic_store_n or an external library call. - (resolve_overloaded_builtin): Handle new __atomic builtins. - -2011-11-04 Eric Botcazou <ebotcazou@adacore.com> - - PR c++/50608 - * c-common.c (c_fully_fold_internal) <ADDR_EXPR>: Call fold_offsetof_1. - (fold_offsetof_1): Make global. Remove STOP_REF argument and adjust. - <INDIRECT_REF>: Return the argument. - <ARRAY_REF>: Remove special code for negative offset. - Call fold_build_pointer_plus instead of size_binop. - (fold_offsetof): Remove STOP_REF argument and adjust. - * c-common.h (fold_offsetof_1): Declare. - (fold_offsetof): Remove STOP_REF argument. - -2011-11-02 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/50810 - * c-opts.c (c_common_handle_option): Enable -Wnarrowing as part - of -Wall; include -Wnarrowing in -Wc++0x-compat; adjust default - Wnarrowing for C++0x and C++98. - * c.opt ([Wnarrowing]): Update. - -2011-11-01 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/44277 - * c.opt: Add Wzero-as-null-pointer-constant. - -2011-10-31 Jason Merrill <jason@redhat.com> - - * c.opt (-fdeduce-init-list): Off by default. - - PR c++/50920 - * c-common.h (cxx_dialect): Add cxx11 and cxx03. - * c.opt: Add -std=c++11, -std=gnu++11, -std=gnu++03, - and -Wc++11-compat. - * c-opts.c (set_std_cxx11): Rename from set_std_cxx0x. - -2011-10-27 Roberto Agostino Vitillo <ravitillo@lbl.gov> - - PR c++/30066 - * c.opt (fvisibility-inlines-hidden): Description change. - -2011-10-26 Ed Smith-Rowland <3dw4rd@verizon.net> - - Implement C++11 user-defined literals. - * c-common.c (build_userdef_literal): New. - * c-common.def: New tree code. - * c-common.h (tree_userdef_literal): New tree struct and accessors. - * c-lex.c (interpret_float): Add suffix parm. - (c_lex_with_flags): Build literal tokens. - -2011-10-23 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/50841 - Revert: - 2011-10-23 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/50810 - * c-opts.c (c_common_handle_option): Enable -Wnarrowing as part - of -Wall; include -Wnarrowing in -Wc++0x-compat; adjust default - Wnarrowing for C++0x and C++98. - * c.opt ([Wnarrowing]): Update. - -2011-10-23 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/50810 - * c-opts.c (c_common_handle_option): Enable -Wnarrowing as part - of -Wall; include -Wnarrowing in -Wc++0x-compat; adjust default - Wnarrowing for C++0x and C++98. - * c.opt ([Wnarrowing]): Update. - -2011-10-21 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/45385 - * c-common.c (conversion_warning): Remove code looking for - artificial operands. - -2011-10-18 Dodji Seketeli <dodji@redhat.com> - - PR bootstrap/50760 - * c-lex.c (fe_file_change): Use LINEMAP_SYSP when - !NO_IMPLICIT_EXTERN_C. - -2011-10-17 Michael Spertus <mike_spertus@symantec.com> - - * c-common.c (c_common_reswords): Add __bases, - __direct_bases. - * c-common.h: Add RID_BASES and RID_DIRECT_BASES. - -2011-10-17 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/50757 - * c.opt ([Wnonnull]): Add C++ and Objective-C++. - -2011-10-15 Tom Tromey <tromey@redhat.com> - Dodji Seketeli <dodji@redhat.com> - - * c.opt (fdebug-cpp): New option. - * c-opts.c (c_common_handle_option): Handle the option. - * c-ppoutput.c (maybe_print_line_1): New static function. Takes an - output stream in parameter. Factorized from ... - (maybe_print_line): ... this. Dump location debug information when - -fdebug-cpp is in effect. - (print_line_1): New static function. Takes an output stream in - parameter. Factorized from ... - (print_line): ... here. Dump location information when -fdebug-cpp - is in effect. - (scan_translation_unit): Dump location information when - -fdebug-cpp is in effect. - -2011-10-15 Tom Tromey <tromey@redhat.com> - Dodji Seketeli <dodji@redhat.com> - - * c.opt (ftrack-macro-expansion): New option. Handle it with and - without argument. - * c-opts.c (c_common_handle_option)<case - OPT_ftrack_macro_expansion_, case OPT_ftrack_macro_expansion>: New - cases. Handle -ftrack-macro-expansion with and without argument. - -2011-10-15 Tom Tromey <tromey@redhat.com> - Dodji Seketeli <dodji@redhat.com> - - * c-ppoutput.c (scan_translation_unit, maybe_print_line) - (print_line, cb_define, do_line_change): Adjust to avoid touching - the internals of struct line_map. Use the public API instead. - * c-pch.c (c_common_read_pch): Likewise. - * c-lex.c (fe_file_change): Likewise. - -2011-10-14 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/17212 - * c.opt ([Wformat-zero-length]): Add C++ and Objective-C++. - -2011-10-11 Paolo Carlini <paolo.carlini@oracle.com> - - PR c++/33067 - * c-pretty-print.c (pp_c_floating_constant): Output - max_digits10 (in the ISO C++ WG N1822 sense) decimal digits. - -2011-10-11 Michael Meissner <meissner@linux.vnet.ibm.com> - - * c-common.c (def_builtin_1): Delete old interface with two - parallel arrays to hold standard builtin declarations, and replace - it with a function based interface that can support creating - builtins on the fly in the future. Change all uses, and poison - the old names. Make sure 0 is not a legitimate builtin index. - * c-omp.c (c_finish_omp_barrier): Ditto. - (c_finish_omp_taskwait): Ditto. - (c_finish_omp_flush): Ditto. - -2011-10-11 Tristan Gingold <gingold@adacore.com> - - * c.opt: (fallow-parameterless-variadic-functions): New. - -2011-09-08 Dodji Seketeli <dodji@redhat.com> - - PR c++/33255 - Support -Wunused-local-typedefs warning - * c-common.h (struct c_language_function::local_typedefs): New - field. - (record_locally_defined_typedef, maybe_record_typedef_use) - (maybe_warn_unused_local_typedefs): Declare new functions. - * c-common.c (record_locally_defined_typedef) - (maybe_record_typedef_use) - (maybe_warn_unused_local_typedefs): Define new functions. - * c.opt: Declare new -Wunused-local-typedefs flag. - -2011-09-06 Eric Botcazou <ebotcazou@adacore.com> - - PR middle-end/50266 - * c-common.c (c_fully_fold_internal) <ADDR_EXPR>: Fold offsetof-like - computations. - -2011-09-05 Richard Guenther <rguenther@suse.de> - - * c-common.c (complete_array_type): Use ssize_int (-1) instead - of integer_minus_one_node for empty array upper bounds. - -2011-08-28 Dodji Seketeli <dodji@redhat.com> - - * c-pch.c (c_common_read_pch): Call linemap_add with LC_ENTER as - it's the first time it's being called on this main TU. - -2011-08-24 Richard Guenther <rguenther@suse.de> - - PR c/49396 - * c-cppbuiltin.c (c_cpp_builtins_optimize_pragma): Fix conditional. - -2011-08-22 Gabriel Charette <gchare@google.com> - - * c-opts.c (c_finish_options): Force BUILTINS_LOCATION for tokens - defined in cpp_init_builtins and c_cpp_builtins. - -2011-08-19 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (c_common_reswords): Add __builtin_complex. - * c-common.h (RID_BUILTIN_COMPLEX): New. - -2011-08-18 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (c_common_reswords): Add _Noreturn. - (keyword_is_function_specifier): Handle RID_NORETURN. - * c-common.h (RID_NORETURN): New. - -2011-08-10 Artjoms Sinkarovs <artyom.shinakroff@gmail.com> - - * c-common.c (unsafe_conversion_p): New function. Check if it is - unsafe to convert an expression to the type. - (conversion_warning): Adjust, use unsafe_conversion_p. - * c-common.h (unsafe_conversion_p): New function declaration. - -2011-08-02 Jakub Jelinek <jakub@redhat.com> - - * c-common.h (c_finish_omp_atomic): Adjust prototype. - (c_finish_omp_taskyield): New prototype. - * c-omp.c (c_finish_omp_atomic): Add OPCODE, V, LHS1 and RHS1 - arguments. Handle OMP_ATOMIC_READ, OMP_ATOMIC_CAPTURE_OLD and - OMP_ATOMIC_CAPTURE_NEW in addition to OMP_ATOMIC. If LHS1 - or RHS1 have side-effects, evaluate those too in the right spot, - if it is a decl and LHS is also a decl, error out if they - aren't the same. - (c_finish_omp_taskyield): New function. - * c-cppbuiltin.c (c_cpp_builtins): Change _OPENMP to 201107. - * c-pragma.c (omp_pragmas): Add taskyield. - * c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_TASKYIELD. - (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_FINAL and - PRAGMA_OMP_CLAUSE_MERGEABLE. - -2011-07-25 Dodji Seketeli <dodji@redhat.com> - - * c-common.h (set_underlying_type): Remove parm name from - declaration. - -2011-07-25 Romain Geissler <romain.geissler@gmail.com> - - * c-pretty-print.h: Search c-common.h in c-family. - -2011-07-22 Jason Merrill <jason@redhat.com> - - PR c++/49793 - * c.opt (Wnarrowing): New. - - PR c++/30112 - * c-common.h: Declare c_linkage_bindings. - * c-pragma.c (handle_pragma_redefine_extname): Use it. - - PR c++/49813 - * c-opts.c (set_std_cxx0x): Set flag_isoc94 and flag_isoc99. - * c-pretty-print.c (pp_c_cv_qualifiers): Check c_dialect_cxx as well - as flag_isoc99 for 'restrict'. - (pp_c_specifier_qualifier_list): Likewise for _Complex. - -2011-07-21 Ian Lance Taylor <iant@google.com> - - PR middle-end/49705 - * c-common.c (c_disable_warnings): New static function. - (c_enable_warnings): New static function. - (c_fully_fold_internal): Change local unused_p to bool. Call - c_disable_warnings and c_enable_warnings rather than change - c_inhibit_evaluation_warnings. - -2011-07-20 Jason Merrill <jason@redhat.com> - - PR c++/6709 (DR 743) - PR c++/42603 (DR 950) - * c-common.h (CPP_KEYWORD, CPP_TEMPLATE_ID): Move from cp/parser.h. - (CPP_NESTED_NAME_SPECIFIER, N_CP_TTYPES): Likewise. - (CPP_DECLTYPE): New. - * c-common.c (c_parse_error): Handle CPP_DECLTYPE. - -2011-07-19 Richard Guenther <rguenther@suse.de> - - * c-common.c (pointer_int_sum): Use fold_build_pointer_plus. - * c-omp.c (c_finish_omp_for): Likewise. - -2011-07-12 Eric Botcazou <ebotcazou@adacore.com> - - * c-ada-spec.c (dump_nested_types): Put semi-colon after empty loop - body on the next line. - -2011-07-08 Jason Merrill <jason@redhat.com> - - PR c++/45437 - * c-omp.c (check_omp_for_incr_expr): Handle preevaluation. - - PR c++/49673 - * c-common.c (c_apply_type_quals_to_decl): Don't check - TYPE_NEEDS_CONSTRUCTING. - -2011-07-06 Richard Guenther <rguenther@suse.de> - - * c-common.c (c_common_nodes_and_builtins): - Merge calls to build_common_tree_nodes and build_common_tree_nodes_2. - -2011-07-05 Richard Guenther <rguenther@suse.de> - - * c-common.c (c_common_nodes_and_builtins): Build all common - tree nodes first. - -2011-06-27 Jakub Jelinek <jakub@redhat.com> - - * c-common.h (c_tree_chain_next): New static inline function. - - * c-common.c (check_builtin_function_arguments): Handle - BUILT_IN_ASSUME_ALIGNED. - -2011-06-21 Andrew MacLeod <amacleod@redhat.com> - - * c-common.c: Add sync_ or SYNC__ to builtin names. - * c-omp.c: Add sync_ or SYNC__ to builtin names. - -2011-06-20 Pierre Vittet <piervit@pvittet.com> - - * c-pragma.h (pragma_handler_1arg, pragma_handler_2arg): New - handler. - (gen_pragma_handler): New union. - (internal_pragma_handler): New type. - (c_register_pragma_with_data) - (c_register_pragma_with_expansion_and_data): New functions. - - * c-pragma.c (registered_pragmas, c_register_pragma_1) - (c_register_pragma, c_register_pragma_with_expansion) - (c_invoke_pragma_handler): Changed to work with - internal_pragma_handler. - (c_register_pragma_with_data) - (c_register_pragma_with_expansion_and_data): New functions. - -2011-06-14 Joseph Myers <joseph@codesourcery.com> - - * c-common.c: Include common/common-target.h. - (handle_section_attribute): Use - targetm_common.have_named_sections. - * c-cppbuiltin.c: Include common/common-target.h. - (c_cpp_builtins): Use targetm_common.except_unwind_info. - -2011-06-10 Richard Guenther <rguenther@suse.de> - - * c-pretty-print.c (pp_c_type_specifier): Use pp_c_identifier - to print a IDENTIFIER_NODE. - -2011-06-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> - Joseph Myers <joseph@codesourcery.com> - - * c.opt (fbuilding-libgcc): New option. - * c-cppbuiltin.c (c_cpp_builtins): Define - __LIBGCC_TRAMPOLINE_SIZE__ if flag_building_libgcc. - -2011-06-07 Jason Merrill <jason@redhat.com> - - * c-common.c (max_tinst_depth): Lower default to 900. - - * c-format.c (gcc_cxxdiag_char_table): Add 'S' format. - -2011-06-07 Richard Guenther <rguenther@suse.de> - - * c-common.c (c_common_nodes_and_builtins): Do not set - size_type_node or call set_sizetype. - -2011-06-07 Dodji Seketeli <dodji@redhat.com> - - PR debug/49130 - * c-pretty-print.c (pp_c_integer_constant): Consider the canonical - type when using pointer comparison to compare types. - -2011-06-02 Jonathan Wakely <jwakely.gcc@gmail.com> - - * c.opt: Add -Wdelete-non-virtual-dtor. - * c-opts.c (c_common_handle_option): Include it in -Wall. - -2011-05-30 Nathan Froyd <froydnj@gcc.gnu.org> - - PR bootstrap/49190 - - Revert: - 2011-05-26 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.h (struct c_common_identifier): Inherit from tree_typed, - not tree_common. - -2011-05-27 Jakub Jelinek <jakub@redhat.com> - - PR c++/49165 - * c-common.c (c_common_truthvalue_conversion) <case COND_EXPR>: For - C++ don't call c_common_truthvalue_conversion on void type arms. - -2011-05-27 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.h (struct stmt_tree_s) [x_cur_stmt_list]: Change to a VEC. - (stmt_list_stack): Define. - (cur_stmt_list): Adjust for new type of x_cur_stmt_list. - * c-semantics.c (push_stmt_list, pop_stmt_list): Likewise. - -2011-05-26 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.c (warning_candidate_p): Check for BLOCKs. - -2011-05-26 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.h (struct c_common_identifier): Inherit from tree_typed, - not tree_common. - -2011-05-25 Jakub Jelinek <jakub@redhat.com> - - * c-common.c (def_fn_type): Remove extra va_end. - -2011-05-23 Jason Merrill <jason@redhat.com> - - PR c++/48106 - * c-common.c (c_common_get_narrower): New. - (shorten_binary_op, shorten_compare, warn_for_sign_compare): Use it. - -2011-05-23 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.h (check_function_arguments): Tweak prototype of - check_function_arguments. - * c-common.c (check_function_arguments): Likewise. Adjust - calls to check_function_nonnull, check_function_format, and - check_function_sentinel. - (check_function_sentinel): Take a FUNCTION_TYPE rather than - separate attributes and typelist arguments. Use - FOREACH_FUNCTION_ARGS to iterate over argument types. - -2011-05-15 Paolo Carlini <paolo.carlini@oracle.com> - - * c-common.c (c_common_reswords): Reorder. - * c-common.h (rid): Likewise. - -2011-05-10 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.c (def_fn_type): Don't call build_function_type, call - build_function_type_array or build_varargs_function_type_array - instead. - (c_common_nodes_and_builtins): Likewise. - -2011-05-05 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.c (c_add_case_label): Omit the loc argument to - build_case_label. - * c-common.h (build_case_label): Remove. - * c-semantics.c (build_case_label): Remove. - -2011-05-05 Joseph Myers <joseph@codesourcery.com> - - * c-objc.h (objc_start_method_definition): Update prototype. - * stub-objc.c (objc_start_method_definition): Add extra parameter. - -2011-05-04 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.c (check_main_parameter_types): Reindent. Don't use - TYPE_ARG_TYPES directly. - (handle_nonnull_attribute): Likewise. - (sync_resolve_params): Likewise. - * c-format.c (handle_format_arg_attribute): Likewise. Adjust call - to check_format_string. - (handle_format_attribute): Likewise. - (check_format_string): Take a function type to examine instead of - a type list. Use a function_arg_iterator to step through argument - types. - -2011-05-04 Richard Guenther <rguenther@suse.de> - - * c-common.c (fix_string_type): Use size_int for index type bounds. - (start_fname_decls): Do not pass NULL to build_int_cst. - (c_init_attributes): Likewise. - * c-lex.c (c_lex_with_flags): Likewise. - -2011-04-27 Jason Merrill <jason@redhat.com> - - * c-common.c (make_tree_vector_from_list): New. - * c-common.h: Declare it. - -2011-04-26 Richard Guenther <rguenther@suse.de> - - PR preprocessor/48248 - * c-ppoutput.c (maybe_print_line): Always optimize newlines - for output size with -P. - -2011-04-25 Paolo Carlini <paolo.carlini@oracle.com> - - * c-common.c (struct c_common_resword): Add __underlying_type. - * c-common.h (enum rid): Add RID_UNDERLYING_TYPE. - -2011-04-20 Jim Meyering <meyering@redhat.com> - - * c-format.c (init_dollar_format_checking): Remove useless - if-before-free. - -2011-04-15 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-objc.h (objc_get_interface_ivars): Removed. - (objc_detect_field_duplicates): New. - * stub-objc.c: Likewise. - -2011-04-14 Nicola Pero <nicola.pero@meta-innovation.com> - - * stub-objc.c (objc_declare_protocols): Renamed to - objc_declare_protocol. - * c-objc.h: Likewise. - -2011-04-14 Nicola Pero <nicola.pero@meta-innovation.com> - - * stub-objc.c (objc_declare_class): Updated argument name. - -2011-04-12 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.h (c_common_init_ts): Declare. - * c-common.c (c_common_init_ts): Define. - -2011-04-12 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-objc.h (objc_build_message_expr): Updated prototype. - * stub-objc.c (objc_build_message_expr): Likewise. - -2011-04-12 Martin Jambor <mjambor@suse.cz> - - * c-gimplify.c (c_genericize): Call cgraph_get_create_node instead - of cgraph_node. - -2011-04-11 Richard Guenther <rguenther@suse.de> - - * c-common.c (complete_array_type): Build a range type of - proper type. - -2011-04-08 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.c (handle_sentinel_attribute): Don't use TYPE_ARG_TYPES. - (handle_type_generic_attribute): Likewise. - -2011-04-07 Jason Merrill <jason@redhat.com> - - PR c++/48450 - * c-common.c (c_common_truthvalue_conversion): Don't ignore - conversion from C++0x scoped enum. - -2011-04-06 Joseph Myers <joseph@codesourcery.com> - - * c-target-def.h: New file. - * c-target.def: New file. - * c-target.h: New file. - * c-common.c (targetcm): Don't define here. - * c-common.h (default_handle_c_option): Declare. - * c-format.c: Include c-target.h instead of target.h. - * c-opts.c: Include c-target.h instead of target.h. Explicitly - include tm.h. - (default_handle_c_option): Move from targhooks.c. - -2011-03-29 Jakub Jelinek <jakub@redhat.com> - - PR preprocessor/48248 - * c-ppoutput.c (print): Add src_file field. - (init_pp_output): Initialize it. - (maybe_print_line): Don't optimize by adding up to 8 newlines - if map->to_file and print.src_file are different file. - (print_line): Update print.src_file. - -2011-03-25 Kai Tietz <ktietz@redhat.com> - - * c-ada-spec.c (compare_comment): Use filename_cmp - instead of strcmp for filename. - -2011-03-25 Jeff Law <law@redhat.com> - - * c-family/c-common.c (def_fn_type): Add missing va_end. - -2011-03-25 Jason Merrill <jason@redhat.com> - - * c.opt: Add -std=c++03. - -2011-03-22 Eric Botcazou <ebotcazou@adacore.com> - - * c-ada-spec.c (dump_ada_template): Skip non-class instances. - -2011-03-17 Kai Tietz - - PR target/12171 - * c-pretty-print.c (pp_c_specifier_qualifier_list): - Display allowed attributes for function pointer types. - (pp_c_attributes_display): New function to display - attributes having affects_type_identity flag set to true. - * c-pretty-print.h (pp_c_attributes_display): New prototype. - - * c-common.c (c_common_attribute_table): - Add new element. - (c_common_format_attribute_table): Likewise. - -2011-03-18 Jason Merrill <jason@redhat.com> - - * c.opt (fconstexpr-depth): Add Var(max_constexpr_depth). - * c-common.h: Don't declare it here. - * c-common.c: Or define it here. - * c-opts.c (c_common_handle_option): Or set it here. - - PR c++/35315 - * c-common.c (handle_transparent_union_attribute): Don't - make a duplicate type in C++. - -2011-03-15 Jason Merrill <jason@redhat.com> - - * c-common.c (max_constexpr_depth): New. - * c-common.h: Declare it. - * c-opts.c (c_common_handle_option): Set it. - * c.opt (fconstexpr-depth): New option. - -2011-03-11 Jason Merrill <jason@redhat.com> - - * c-common.c (attribute_takes_identifier_p): Add missing const. - - PR c++/46803 - * c-common.c (attribute_takes_identifier_p): Assume that an - unknown attribute takes an identifier. - -2011-03-07 Nathan Froyd <froydnj@codesourcery.com> - - PR c/47786 - * c-common.c (c_type_hash): Call list_length instead of iterating - through DECL_CHAIN. Rename 'i' to 'n_elements'. - -2011-02-19 Jakub Jelinek <jakub@redhat.com> - - PR c/47809 - * c-common.c (c_fully_fold_internal): Handle VIEW_CONVERT_EXPR. - -2011-02-17 Iain Sandoe <iains@gcc.gnu.org> - - * c.opt (fobjc-abi-version=) New. - (fobjc-nilcheck): New. - -2011-02-03 Nathan Froyd <froydnj@codesourcery.com> - - PR c++/46890 - * c-common.h (keyword_is_decl_specifier): Declare. - * c-common.c (keyword_is_decl_specifier): Define. - (keyword_is_function_specifier): New function. - -2011-01-26 Jakub Jelinek <jakub@redhat.com> - - PR c/47473 - * c-lex.c (interpret_float): If CPP_N_IMAGINARY, ensure - EXCESS_PRECISION_EXPR is created with COMPLEX_TYPE instead of - REAL_TYPE. - -2011-01-26 Arnaud Charlet <charlet@adacore.com> - - * c-ada-spec.c (dump_generic_ada_node): Avoid dereferencing null type. - -2011-01-26 Jakub Jelinek <jakub@redhat.com> - - PR pch/47430 - * c-opts.c (c_common_post_options): Call c_common_no_more_pch - after init_c_lex if pch_file is set. - -2011-01-26 Dave Korn <dave.korn.cygwin@gmail.com> - - PR c++/43601 - * c.opt (-fkeep-inline-dllexport): New switch. - -2011-01-12 Richard Guenther <rguenther@suse.de> - - PR middle-end/32511 - * c-common.c (handle_weak_attribute): Warn instead of error - on declaring an inline function weak. - -2011-01-05 Tom Tromey <tromey@redhat.com> - - * c-common.h (lvalue_error): Update. - * c-common.c (lvalue_error): Add 'loc' argument. Call error_at, - not error. - -2010-12-29 Nicola Pero <nicola.pero@meta-innovation.com> - - PR objc/47075 - * c-objc.h (objc_finish_message_expr): Added argument to - prototype. - -2010-12-22 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.c (handle_nonnull_attribute, handle_sentinel_attribute): - Use prototype_p. - -2010-12-18 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-objc.h (objc_maybe_warn_exceptions): New. - * stub-objc.c (objc_maybe_warn_exceptions): New. - -2010-12-10 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.h (readonly_error): Declare. - * c-common.c (readonly_error): Define. - -2010-12-09 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.h (invalid_indirection_error): Declare. - * c-common.c (invalid_indirection_error): Define. - -2010-12-03 Richard Guenther <rguenther@suse.de> - - PR c/46745 - * c-pretty-print.c (pp_c_postfix_expression): Handle MEM_REF. - (pp_c_unary_expression): Likewise. - (pp_c_expression): Likewise. - -2010-11-30 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-common.h (objc_finish_function): New. - (objc_non_volatilized_type): Removed. - (objc_type_quals_match): Removed. - * stub-objc.c (objc_finish_function): New. - (objc_non_volatilized_type): Removed. - (objc_type_quals_match): Removed. - -2010-11-30 Joseph Myers <joseph@codesourcery.com> - - * c-common.h (parse_optimize_options): Declare. - * c-cppbuiltin.c, c-format.c, c-gimplify.c, c-lex.c, c-omp.c, - c-pch.c, c-pragma.c, c-semantics.c: Don't include toplev.h. - -2010-11-29 Joseph Myers <joseph@codesourcery.com> - - * c-opts.c (check_deps_environment_vars): Use getenv instead of - GET_ENVIRONMENT. - * c-pch.c (O_BINARY): Don't define here. - * c-pragma.h: Include "cpplib.h" instead of <cpplib.h>. - -2010-11-25 Joseph Myers <joseph@codesourcery.com> - - * c-cppbuiltin.c (c_cpp_builtins): Pass &global_options to - targetm.except_unwind_info. - -2010-11-23 Joseph Myers <joseph@codesourcery.com> - - * c-opts.c (c_common_handle_option): Pass location to - set_struct_debug_option. - -2010-11-23 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (visibility_options): Move from ../opts.c. - * c-common.h (struct visibility_flags, visibility_options): - Declare here. - * c-opts.c (finish_options): Rename to c_finish_options. - (c_common_init): Update call to finish_options. - -2010-11-22 Nicola Pero <nicola.pero@meta-innovation.com> - - PR objc/34033 - * c-lex.c (lex_string): Check that each string in an Objective-C - string concat sequence starts with either one or zero '@', and - that there are no spurious '@' signs at the end. - -2010-11-20 Joseph Myers <joseph@codesourcery.com> - - * c-pragma.c: Remove conditionals on HANDLE_PRAGMA_PACK, - HANDLE_PRAGMA_PACK_PUSH_POP, HANDLE_PRAGMA_WEAK and - HANDLE_PRAGMA_VISIBILITY. - * c-pragma.h (HANDLE_PRAGMA_WEAK, HANDLE_PRAGMA_PACK, - HANDLE_PRAGMA_VISIBILITY): Don't define. - (HANDLE_SYSV_PRAGMA, HANDLE_PRAGMA_PACK_PUSH_POP): Don't test. - -2010-11-20 Nathan Froyd <froydnj@codesourcery.com> - - PR c++/16189 - PR c++/36888 - PR c++/45331 - * c-common.h (keyword_begins_type_specifier): Declare. - (keyword_is_storage_class_specifier): Declare. - (keyword_is_type_qualifier): Declare. - * c-common.c (keyword_begins_type_specifier): New function. - (keyword_is_storage_class_specifier): New function. - (keyword_is_type_qualifier): Declare. - -2010-11-19 Joseph Myers <joseph@codesourcery.com> - - PR c/46547 - * c-common.c (in_late_binary_op): Define. - (c_common_truthvalue_conversion): Check in_late_binary_op before - calling c_save_expr. - * c-common.h (in_late_binary_op): Declare. - -2010-11-19 Joseph Myers <joseph@codesourcery.com> - - * c-opts.c (c_common_handle_option): Update calls to - set_struct_debug_option. - -2010-11-19 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-common.h (objc_declare_protocols): Added additional argument. - * stub-objc.c (objc_declare_protocol): Same change. - -2010-11-18 Nathan Froyd <froydnj@codesourcery.com> - - PR c/33193 - * c-common.h (build_real_imag_expr): Declare. - * c-semantics.c (build_real_imag_expr): Define. - -2010-11-17 Joseph Myers <joseph@codesourcery.com> - - * c-opts.c (c_common_parse_file): Take no arguments. - * c-common.h (c_common_parse_file): Update prototype. - -2010-11-16 Jakub Jelinek <jakub@redhat.com> - - PR c++/46401 - * c-common.c (warning_candidate_p): Don't track non-const calls - or STRING_CSTs. - -2010-11-15 Ian Lance Taylor <iant@google.com> - - * c-lex.c (init_c_lex): Set macro debug callbacks if - flag_dump_go_spec is set. - -2010-11-15 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-common.h (objc_build_incr_expr_for_property_ref): New. - * stub-objc.c (objc_build_incr_expr_for_property_ref): New. - -2010-11-15 Nathan Froyd <froydnj@codesourcery.com> - - PR preprocessor/45038 - * c-cppbuiltin.c (c_cpp_builtins): Use different format for C++ - dialects. - -2010-11-12 Joseph Myers <joseph@codesourcery.com> - - * c-common.h (c_family_lang_mask): Declare. - * c-opts.c (c_family_lang_mask): Make extern. - * c-pragma.c (handle_pragma_diagnostic): Use - control_warning_option. - -2010-11-12 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (parse_optimize_options): Update call to - decode_options. - * c-common.h (c_common_handle_option): Update prototype. - * c-opts.c (c_common_handle_option): Take location_t parameter and - pass it to other functions. - -2010-11-11 Joseph Myers <joseph@codesourcery.com> - - * c-opts.c (warning_as_error_callback): Remove. - (c_common_initialize_diagnostics): Don't call - register_warning_as_error_callback. - (c_common_handle_option): Handle -Werror=normalized= here. - -2010-11-10 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (handle_mode_attribute): Use %' and word "signedness" - in diagnostic. - * c-opts.c (c_common_parse_file): Start diagnostics with lowercase - letter. - * c-pragma.c (handle_pragma_target, handle_pragma_optimize): - Remove trailing '.' from diagnostics. - * c.opt (Wwrite-strings_: Avoid '`' in help text. - -2010-11-10 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (parse_optimize_options): Pass global_dc to - decode_options. - * c-opts.c (c_common_handle_option): Pass &global_options to - set_Wstrict_aliasing. - * c.opt (v): Don't mark Common or document here. - -2010-11-06 Iain Sandoe <iains@gcc.gnu.org> - - PR target/44981 - * c-format.c (format_type): New type gcc_objc_string_format_type. - (valid_stringptr_type_p): New. - (handle_format_arg_attribute): Use valid_stringptr_type_p (). - (check_format_string): Pass expected type, use - valid_stringptr_type_p (), check that the format string types are - consistent with the format specification. - (decode_format_attr): Warn if NSString is used outside objective-c. - (format_types_orig): Add NSString. - (format_name): New. - (format_flags): New. - (check_format_arg): Handle format strings requiring an external parser. - first_target_format_type: New variable. - (handle_format_attribute): Set up first_target_format_type, pass the - expected format arg string type to check_format_string(). - * c-common.h (FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL): New flag. - * stub-objc.c (objc_string_ref_type_p): New. - (objc_check_format_arg): New. - -2010-11-04 Nicola Pero <nicola.pero@meta-innovation.com> - - Fixed using the Objective-C 2.0 dot-syntax with class names. - * c-common.h (objc_build_class_component_ref): New. - * stub-objc.c (objc_build_class_component_ref): New. - -2010-11-03 Nicola Pero <nicola.pero@meta-innovation.com> - - * c.opt (Wproperty-assign-default): New option. - -2010-11-03 Nicola Pero <nicola.pero@meta-innovation.com> - - Implemented -fobjc-std=objc1 flag. - * c.opt (fobjc-std=objc1): New option. - -2010-11-01 Nicola Pero <nicola.pero@meta-innovation.com> - - Implemented format and noreturn attributes for Objective-C methods. - * c-common.c (handle_noreturn_attribute): Recognize 'noreturn' - attribute for Objective-C methods. - -2010-10-31 Jason Merrill <jason@redhat.com> - - * c-common.c (conversion_warning, warn_for_collisions_1): Use - EXPR_LOC_OR_HERE. - -2010-10-30 Nicola Pero <nicola.pero@meta-innovation.com> - - Implemented Objective-C 2.0 @property, @synthesize and @dynamic. - * c-common.h (enum rid): Removed RID_COPIES and RID_IVAR. - (objc_add_property_declaration): Removed arguments for copies and - ivar. - (objc_build_getter_call): Renamed to - objc_maybe_build_component_ref. - (objc_build_setter_call): Renamed to objc_maybe_build_modify_expr. - (objc_is_property_ref): New. - * c-common.c (c_common_reswords): Removed copies and ivar. - * stub-objc.c (objc_add_property_declaration): Removed arguments - for copies and ivar. - (objc_build_getter_call): Renamed to - objc_maybe_build_component_ref. - (objc_build_setter_call): Renamed to objc_maybe_build_modify_expr. - (objc_is_property_ref): New. - -2010-10-29 Arnaud Charlet <charlet@adacore.com> - Matthew Gingell <gingell@adacore.com> - - * c-ada-spec.c (separate_class_package): New function. - (pp_ada_tree_identifier): Prefix references to C++ classes with the - name of their enclosing package. - (print_ada_declaration): Use separate_class_package. - -2010-10-27 Jason Merrill <jason@redhat.com> - - * c-common.c (c_common_reswords): Add __is_literal_type. - * c-common.h (enum rid): Add RID_IS_LITERAL_TYPE. - - * c-common.c (check_case_value): Remove special C++ code. - -2010-10-27 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-common.h (enum rid): Added RID_READWRITE, RID_ASSIGN, - RID_RETAIN, RID_COPY and RID_NONATOMIC. Updated RID_FIRST_PATTR - and RID_LAST_PATTR. - (objc_add_property_declaration): Added additional arguments. - (objc_property_attribute_kind): Removed. - (objc_set_property_attr): Removed. - * c-common.c (c_common_reswords): Added readwrite, assign, retain, - copy and nonatomic. - * stub-objc.c (objc_add_property_declaration): Added additional - arguments. - (objc_set_property_attr): Removed. - -2010-10-27 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-common.h (objc_add_property_variable): Renamed to - objc_add_property_declaration. Added location argument. - * stub-objc.c (objc_add_property_variable): Same change. - -2010-10-23 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-common.h (objc_maybe_printable_name): New. - * stub-objc.c (objc_maybe_printable_name): New. - -2010-10-22 Artjoms Sinkarovs <artyom.shinakroff@gmail.com> - Andrew Pinski <pinskia@gmail.com> - - * c-common.h (c_common_mark_addressable_vec): Declare. - * c-common.c (c_common_mark_addressable_vec): New function. - -2010-10-20 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-common.h (objc_set_method_type): Removed. - (objc_add_method_declaration): Added boolean argument. - (objc_start_method_definition): Same change. - (objc_build_method_signature): Same change. - * stub-objc.c (objc_set_method_type): Removed. - (objc_add_method_declaration): Added boolean argument. - (objc_start_method_definition): Same change. - (objc_build_method_signature): Same change. - -2010-10-20 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-common.h (finish_file): Removed. - (objc_write_global_declarations): New. - * c-opts.c (c_common_parse_file): Do not call finish_file. - * stub-objc.c (objc_write_global_declarations): New. - -2010-10-18 Nicola Pero <nicola.pero@meta-innovation.com> - - Implemented parsing @synthesize and @dynamic for - Objective-C/Objective-C++. - * c-common.h (enum rid): Add RID_AT_SYNTHESIZE and RID_AT_DYNAMIC. - (objc_add_synthesize_declaration): New. - (objc_add_dynamic_declaration): New. - * c-common.c (c_common_reswords): Add synthesize and dynamic. - * stub-objc.c (objc_add_synthesize_declaration): New. - (objc_add_dynamic_declaration): New. - -2010-10-18 Michael Meissner <meissner@linux.vnet.ibm.com> - - PR target/46041 - * c-cppbuiltin.c (mode_has_fma): Move function here from - builtins.c. Don't use the fma optab, instead just use the - HAVE_fma* macros, so that __FP_FAST_FMA* will be defined when - using -save-temps. - -2010-10-18 Nicola Pero <nicola.pero@meta-innovation.com> - - Merge from 'apple/trunk' branch on FSF servers. - - 2005-11-08 Fariborz Jahanian <fjahanian@apple.com> - - Radar 4330422 - * c-common.h (objc_non_volatilized_type): New declaration - * stub-objc.c (objc_non_volatilized_type): New stub. - -2010-10-17 Nicola Pero <nicola.pero@meta-innovation.com> - - Merge from 'apple/trunk' branch on FSF servers. - - 2006-03-27 Fariborz Jahanian <fjahanian@apple.com> - - Radar 4133425 - * c-common.h (objc_diagnose_private_ivar): New decl. - * stub-objc.c (objc_diagnose_private_ivar): New stub. - -2010-10-17 Iain Sandoe <iains@gcc.gnu.org> - - * c-common.c (c_common_reswords): Add package, RID_AT_PACKAGE. - * c-common.h (enum rid): Add RID_AT_PACKAGE. - (objc_ivar_visibility_kind): New enum. - (objc_set_visibility): Adjust prototype to use visibility enum. - * stub-objc.c (objc_set_visibility): Adjust stub to use - visibility enum. - -2010-10-14 Michael Meissner <meissner@linux.vnet.ibm.com> - - * c-cppbuiltin.c (builtin_define_float_constants): Emit - __FP_FAST_FMA, __FP_FAST_FMAF, and __FP_FAST_FMAL if the machine - has the appropriate fma builtins. - (c_cpp_builtins): Adjust call to builtin_define_float_constants. - -2010-10-14 Iain Sandoe <iains@gcc.gnu.org> - - merge from FSF apple 'trunk' branch. - 2006 Fariborz Jahanian <fjahanian@apple.com> - - Radars 4436866, 4505126, 4506903, 4517826 - * c-common.c (c_common_resword): Define @property and its attributes. - * c-common.h: Define property attribute enum entries. - (OBJC_IS_PATTR_KEYWORD): New. - (objc_property_attribute_kind): New enum. - Declare objc_set_property_attr (), objc_add_property_variable (), - objc_build_getter_call () and objc_build_setter_call (). - * stub-objc.c (objc_set_property_attr): New stub. - (objc_add_property_variable): Likewise. - (objc_build_getter_call): Likewise. - (objc_build_setter_call) Likewise. - -2010-10-13 Iain Sandoe <iains@gcc.gnu.org> - - merge from FSF apple 'trunk' branch. - 2006-04-26 Fariborz Jahanian <fjahanian@apple.com> - - Radar 3803157 (method attributes) - * c-common.c (handle_deprecated_attribute): Recognize - objc methods as valid declarations. - * c-common.h: Declare objc_method_decl (). - * stub-objc.c (objc_method_decl): New stub. - -2010-10-08 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (parse_optimize_options): Call - decode_cmdline_options_to_array_default_mask before - decode_options. Update arguments to decode_options. - * c-common.h (c_common_init_options_struct): Declare. - * c-opts.c (c_common_init_options_struct): New. Split out from - c_common_init_options. - -2010-10-06 Nicola Pero <nicola.pero@meta-innovation.com> - - Implemented fast enumeration for Objective-C. - * c-common.h (objc_finish_foreach_loop): New. - * stub-objc.c (objc_finish_foreach_loop): New. - -2010-10-05 Joseph Myers <joseph@codesourcery.com> - - * c-common.h (struct diagnostic_context): Don't declare here. - (c_common_initialize_diagnostics): Declare using - diagnostic_context typedef. - * c-opts.c (c_common_handle_option): Pass global_dc to - handle_generated_option. - -2010-10-04 Joseph Myers <joseph@codesourcery.com> - - * c-opts.c (c_common_handle_option): Pass &global_options_set to - handle_generated_option. - -2010-10-03 Ian Lance Taylor <iant@google.com> - - * c.opt (-fplan9-extensions): New option. - -2010-10-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> - - * c-cppbuiltin.c (define__GNUC__, builtin_define_type_precision): - Remove. - (c_cpp_builtins): Call functions from cppbuiltin.c instead - of duplicating code. - -2010-09-30 Iain Sandoe <iains@gcc.gnu.org> - - * c-common.c: Add two new entries for @optional - and @required keywords. - - merge from FSF 'apple/trunk' branch. - 2006-01-30 Fariborz Jahanian <fjahanian@apple.com> - - Radar 4386773 - * c-common.h (RID_AT_OPTIONAL, RID_AT_REQUIRED): Two new - objective-c keywords. - (objc_set_method_opt): New declaration. - * stub-objc.c (objc_set_method_opt): New stub. - -2010-09-30 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (handle_optimize_attribute): Pass &global_options to - cl_optimization_save and cl_optimization_restore. - * c-opts.c (c_common_handle_option): Pass &global_options to - handle_generated_option. - * c-pragma.c (handle_pragma_diagnostic): Use option_flag_var. - (handle_pragma_pop_options, handle_pragma_reset_options): Pass - &global_options to cl_optimization_restore. - -2010-09-30 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-lex.c (c_lex_with_flags): Updated comments for CPP_AT_NAME - Objective-C/Objective-C++ keywords. - -2010-09-29 Nicola Pero <nicola.pero@meta-innovation.com> - - Merge from 'apple/trunk' branch on FSF servers. - - 2005-10-04 Fariborz Jahanian <fjahanian@apple.com> - - Radar 4281748 - * c-common.h (objc_check_global_decl): New declaration. - * stub-objc.c (objc_check_global_decl): New stub. - -2010-09-29 Joseph Myers <joseph@codesourcery.com> - - * c.opt: Don't use VarExists. - -2010-09-29 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (c_cpp_error): Update names of diagnostic_context - members. - * c-cppbuiltin.c (c_cpp_builtins_optimize_pragma): Update names of - cl_optimization members. - * c-opts.c (warning_as_error_callback, c_common_handle_option, - sanitize_cpp_opts, finish_options): Update names of cpp_options - members. - -2010-09-29 Nicola Pero <nicola.pero@meta-innovation.com> - - * c-common.h (OBJC_IS_CXX_KEYWORD): New macro. Updated comments. - (objc_is_reserved_word): Removed. - * c-common.c: Updated comments. - * c-lex.c (c_lex_with_flags): Use OBJC_IS_CXX_KEYWORD instead of - objc_is_reserved_word. - * stub-objc.c (objc_is_reserved_word): Removed. - -2010-09-28 Iain Sandoe <iains@gcc.gnu.org> - - * c-common.h (objc_add_method_declaration): Adjust prototype to - include attributes. - (objc_start_method_definition): Likewise. - (objc_build_keyword_decl): Likewise. - * stub-objc.c:(objc_add_method_declaration): Handle attributes. - (objc_start_method_definition): Likewise. - (objc_build_keyword_decl): Likewise. - -2010-09-28 Iain Sandoe <iains@gcc.gnu.org> - - * c-common.h (objc_start_class_interface): Adjust prototype. - (objc_start_category_interface): Likewise. - (objc_start_protocol): Likewise. - * stub-objc.c (objc_start_protocol): Adjust for extra argument. - (objc_start_class_interface): Likewise. - (objc_start_category_interface): Likewise. - -2010-09-27 Ian Lance Taylor <iant@google.com> - - * c-common.c (c_common_attribute_table): Add no_split_stack. - (handle_no_split_stack_attribute): New static function. - -2010-09-27 Nicola Pero <nicola.pero@meta-innovation.com> - - Merge from 'apple/trunk' branch on FSF servers. - - 2005-12-15 Fariborz Jahanian <fjahanian@apple.com> - - Radar 4229905 - * c-common.h (objc_have_common_type): New declaration. - * stub-objc.c (objc_have_common_type): New stub. - - 2005-06-22 Ziemowit Laski <zlaski@apple.com> - - Radar 4154928 - * c-common.h (objc_common_type): New prototype. - * stub-objc.c (objc_common_type): New stub. - -2010-09-24 Jan Hubicka <jh@suse.cz> - - * c-common.c (handle_leaf_attribute): New function. - (struct attribute_spec c_common_att): Add leaf. - -2010-09-22 Joseph Myers <joseph@codesourcery.com> - - * c.opt (-all-warnings, -ansi, -assert, -assert=, -comments, - -comments-in-macros, -define-macro, -define-macro=, -dependencies, - -dump, -dump=, -imacros, -imacros=, -include, -include=, - -include-barrier, -include-directory, -include-directory=, - -include-directory-after, -include-directory-after=, - -include-prefix, -include-prefix=, -include-with-prefix, - -include-with-prefix=, -include-with-prefix-after, - -include-with-prefix-after=, -include-with-prefix-before, - -include-with-prefix-before=, -no-integrated-cpp, - -no-line-commands, -no-standard-includes, -no-warnings, -output, - -output=, -pedantic, -pedantic-errors, -preprocess, - -print-missing-file-dependencies, -trace-includes, -traditional, - -traditional-cpp, -trigraphs, -undefine-macro, -undefine-macro=, - -user-dependencies, -verbose, -write-dependencies, - -write-user-dependencies, no-integrated-cpp, traditional): New. - -2010-09-21 Nicola Pero <nicola.pero@meta-innovation.com> - - PR objc/23710 - * c-common.h (objc_start_method_definition): Return bool instead - of void. - * stub-objc.c (objc_start_method_definition): Return bool instead - of void. - -2010-09-21 Nicola Pero <nicola.pero@meta-innovation.com> - - PR objc/25965 - * c-common.h (objc_get_interface_ivars): New declaration. - * stub-objc.c (objc_get_interface_ivars): New stub. - -2010-09-15 Ian Lance Taylor <iant@google.com> - - * c-common.c (parse_optimize_options): Do not capitalize warning - messages. Remove period at end of warning message. - -2010-09-09 Nathan Sidwell <nathan@codesourcery.com> - - * c-common.c (handle_alias_ifunc_attribute): New, broken out of ... - (handle_alias_attribute): ... here. - (handle_ifunc_attribute): New. - -2010-09-06 Mark Mitchell <mark@codesourcery.com> - - * c-common.h (do_warn_double_promotion): Declare. - * c-common.c (do_warn_double_promotion): Define. - -2010-09-05 Mark Mitchell <mark@codesourcery.com> - - * c.opt (Wdouble-promotion): New. - -2010-09-02 Joseph Myers <joseph@codesourcery.com> - - * c.opt (falt-external-templates, fhuge-objects, fvtable-gc, - fvtable-thunks, fxref): Mark no longer supported in help text. - -2010-09-02 Joseph Myers <joseph@codesourcery.com> - - * c.opt (Wimport, fall-virtual, falt-external-templates, - fdefault-inline, fenum-int-equiv, fexternal-templates, - fguiding-decls, fhonor-std, fhuge-objects, flabels-ok, - fname-mangling-version-, fnew-abi, fnonnull-objects, - foptional-diags, fsquangle, fstrict-prototype, fthis-is-variable, - fvtable-gc, fvtable-thunks, fxref): Mark with Ignore and Warn as - applicable. - (fhandle-exceptions): Mark with Alias and Warn. - * c-opts.c (c_common_handle_option): Don't handle options marked - as ignored. - -2010-09-02 Joseph Myers <joseph@codesourcery.com> - - * c.opt (Wcomments, Werror-implicit-function-declaration, - ftemplate-depth-, std=c89, std=c9x, std=gnu89, std=gnu9x, - std=iso9899:1990, std=iso9899:1999, std=iso9899:199x): Mark as - aliases. - * c-common.c (option_codes): Use OPT_Wcomment instead of - OPT_Wcomments. - * c-opts.c (warning_as_error_callback, c_common_handle_option): - Don't handle options marked as aliases. - -2010-08-25 Richard Guenther <rguenther@suse.de> - - * c-common.c (c_common_get_alias_set): Remove special - handling for pointers. - -2010-08-20 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.c: Use FOR_EACH_VEC_ELT. - * c-gimplify.c: Likewise. - * c-pragma.c: Likewise. - -2010-08-16 Joseph Myers <joseph@codesourcery.com> - - * c.opt (MDX): Change back to MD. Mark NoDriverArg instead of - RejectDriver. - (MMDX): Change back to MMD. Mark NoDriverArg instead of - RejectDriver. - * c-opts.c (c_common_handle_option): Use OPT_MD and OPT_MMD - instead of OPT_MDX and OPT_MMDX. - -2010-08-16 Joseph Myers <joseph@codesourcery.com> - - * c.opt (MDX, MMDX, lang-asm): Mark RejectDriver. - -2010-08-12 Joseph Myers <joseph@codesourcery.com> - - * c.opt (MD, MMD): Change to MDX and MMDX. - * c-opts.c (c_common_handle_option): Use OPT_MMD and OPT_MMDX. - -2010-08-11 Joseph Myers <joseph@codesourcery.com> - - * c-opts.c (c_common_handle_option): Call handle_generated_option - instead of handle_option. - -2010-08-08 Nathan Froyd <froydnj@codesourcery.com> - - * c-pragma.c (add_to_renaming_pragma_list): Fix call to VEC_safe_push. - (maybe_apply_renaming_pragma): Delete unneeded declarations. - -2010-08-08 Nathan Froyd <froydnj@codesourcery.com> - - * c-pragma.c (pending_redefinition): Declare. Declare a VEC of it. - (pending_redefine_extname): Change type to a VEC. - (add_to_renaming_pragma_list): Update for new type of - pending_redefine_extname. - (maybe_apply_renaming_pragma): Likewise. - -2010-08-04 Arnaud Charlet <charlet@adacore.com> - - * c-ada-spec.c (dump_ada_template): Mark underlying instance type as - visited. - (dump_generic_ada_node): Code clean up. Use TREE_VISITED flag to - decide whether a type has already been declared/seen. - Do not go to the original type. - (dump_nested_types): New parameter forward. - Generate forward declaration if needed and mark type as visited. - (print_ada_declaration): Call dump_nested_types if not already done. - Mark types as visited. - -2010-08-03 Joseph Myers <joseph@codesourcery.com> - - * c.opt (-print-pch-checksum): Remove option. - * c-opts.c (c_common_handle_option): Don't handle - OPT_print_pch_checksum. - -2010-07-27 Joseph Myers <joseph@codesourcery.com> - - * c-common.h (c_common_handle_option): Update prototype and return - value type. - * c-opts.c (c_common_handle_option): Update prototype and return - value type. Update calls to handle_option and - enable_warning_as_error. - -2010-07-27 Jakub Jelinek <jakub@redhat.com> - - PR c/45079 - * c-pretty-print.c (pp_c_expression): Handle C_MAYBE_CONST_EXPR. - -2010-07-27 Joseph Myers <joseph@codesourcery.com> - - * c-common.h (c_common_missing_argument): Remove. - * c-opts.c (c_common_missing_argument): Remove. - * c.opt (A, D, F, I, MD, MMD, MQ, MT, U, fconstant-string-class=, - idirafter, imacros, include, isysroot, isystem, iquote): Add - MissingArgError. - * c-objc-common.h (LANG_HOOKS_MISSING_ARGUMENT): Remove. - -2010-07-27 Joseph Myers <joseph@codesourcery.com> - - * c-common.h (c_common_option_lang_mask, - c_common_initialize_diagnostics, c_common_complain_wrong_lang_p): - New. - (c_common_init_options): Update prototype. - * c-opts.c (c_common_option_lang_mask): New. - (c_common_initialize_diagnostics): Split out of - c_common_init_options. - (accept_all_c_family_options, c_common_complain_wrong_lang_p): - New. - (c_common_init_options): Update prototype. Use decoded options in - search for -lang-asm. - -2010-07-15 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.c: Carefully replace TREE_CHAIN with DECL_CHAIN. - * c-format.c: Likewise. - -2010-07-08 Manuel López-Ibáñez <manu@gcc.gnu.org> - - * c-common.h: Include diagnostic-core.h. Error if already - included. - * c-semantics.c: Do not define GCC_DIAG_STYLE here. - -2010-07-03 Manuel López-Ibáñez <manu@gcc.gnu.org> - - * c-family/c-common.c (IN_GCC_FRONTEND): Do not undef. - Do not include expr.h - (vector_mode_valid_p): Move here. - -2010-06-21 DJ Delorie <dj@redhat.com> - - * c-pragma.c (handle_pragma_diagnostic): Add push/pop, - allow these pragmas anywhere. - -2010-06-14 Jakub Jelinek <jakub@redhat.com> - - PR bootstrap/44509 - * c-cppbuiltin.c: Include gt-c-family-c-cppbuiltin.h. - (lazy_hex_fp_values, lazy_hex_fp_value_count): Add GTY(()) markers. - (lazy_hex_fp_value, builtin_define_with_hex_fp_value): Use - ggc_strdup instead of xstrdup. - -2010-06-10 Jakub Jelinek <jakub@redhat.com> - - * c-cppbuiltin.c: Include cpp-id-data.h. - (lazy_hex_fp_values, lazy_hex_fp_value_count): New variables. - (lazy_hex_fp_value): New function. - (builtin_define_with_hex_fp_value): Provide definitions lazily. - -2010-06-30 Manuel López-Ibáñez <manu@gcc.gnu.org> - - * c-gimplify.c: Do not include tree-flow.h - -2010-06-29 Joern Rennecke <joern.rennecke@embecosm.com> - - PR other/44034 - * c-common.c: Rename targetm member: - targetm.enum_va_list -> targetm.enum_va_list_p - -2010-06-28 Anatoly Sokolov <aesok@post.ru> - - * c-common.c (shorten_compare): Adjust call to force_fit_type_double. - -2010-06-28 Steven Bosscher <steven@gcc.gnu.org> - - * c-cppbuiltin.c: Do not include except.h. - -2010-06-24 Andi Kleen <ak@linux.intel.com> - - * c-common.c (warn_for_omitted_condop): New. - * c-common.h (warn_for_omitted_condop): Add prototype. - -2010-06-21 Joseph Myers <joseph@codesourcery.com> - - * c.opt (lang-objc): Remove. - * c-opts.c (c_common_handle_option): Don't handle OPT_lang_objc. - -2010-06-21 Joern Rennecke <joern.rennecke@embecosm.com> - - * c-opts.c: Include "tm_p.h". - -2010-06-20 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (parse_optimize_options): Update call to - decode_options. - -2010-06-18 Nathan Froyd <froydnj@codesourcery.com> - - * c-common.c (record_types_used_by_current_var_decl): Adjust for - new type of types_used_by_cur_var_decl. - -2010-06-17 Joern Rennecke <joern.rennecke@embecosm.com> - - PR bootstrap/44512 - * c-cppbuiltin.c (builtin_define_with_hex_fp_value): Add cast - for C++ standard compliance. - -2010-06-16 Jason Merrill <jason@redhat.com> - - * c.opt: Add -Wnoexcept. - -2010-06-16 Richard Guenther <rguenther@suse.de> - - PR c/44555 - * c-common.c (c_common_truthvalue_conversion): Remove - premature and wrong optimization concering ADDR_EXPRs. - -2010-06-15 Arnaud Charlet <charlet@adacore.com> - - * c-ada-spec.c (dump_sloc): Remove column info. - (is_simple_enum): New function. - (dump_generic_ada_node, print_ada_declaration): Map C enum types to Ada - enum types when relevant. - -2010-06-11 Manuel López-Ibáñez <manu@gcc.gnu.org> - - * c-common.c (conversion_warning): Warn at expression - location. - -2010-06-10 Joseph Myers <joseph@codesourcery.com> - - * c-opts.c (c_common_handle_option): Don't handle - OPT_fshow_column. - -2010-06-08 Laurynas Biveinis <laurynas.biveinis@gmail.com> - - * c-pragma.c (push_alignment): Use typed GC allocation. - (handle_pragma_push_options): Likewise. - - * c-common.c (parse_optimize_options): Likewise. - - * c-common.h (struct sorted_fields_type): Add variable_size GTY - option. - -2010-06-07 Joseph Myers <joseph@codesourcery.com> - - * c-common.c (flag_preprocess_only, flag_undef, flag_no_builtin, - flag_no_nonansi_builtin, flag_short_double, flag_short_wchar, - flag_lax_vector_conversions, flag_ms_extensions, flag_no_asm, - flag_signed_bitfields, warn_strict_null_sentinel, - flag_nil_receivers, flag_zero_link, flag_replace_objc_classes, - flag_gen_declaration, flag_no_gnu_keywords, - flag_implement_inlines, flag_implicit_templates, - flag_implicit_inline_templates, flag_optional_diags, - flag_elide_constructors, flag_default_inline, flag_rtti, - flag_conserve_space, flag_access_control, flag_check_new, - flag_new_for_scope, flag_weak, flag_working_directory, - flag_use_cxa_atexit, flag_use_cxa_get_exception_ptr, - flag_enforce_eh_specs, flag_threadsafe_statics, - flag_pretty_templates): Remove. - * c-common.h (flag_preprocess_only, flag_nil_receivers, - flag_objc_exceptions, flag_objc_sjlj_exceptions, flag_zero_link, - flag_replace_objc_classes, flag_undef, flag_no_builtin, - flag_no_nonansi_builtin, flag_short_double, flag_short_wchar, - flag_lax_vector_conversions, flag_ms_extensions, flag_no_asm, - flag_const_strings, flag_signed_bitfields, flag_gen_declaration, - flag_no_gnu_keywords, flag_implement_inlines, - flag_implicit_templates, flag_implicit_inline_templates, - flag_optional_diags, flag_elide_constructors, flag_default_inline, - flag_rtti, flag_conserve_space, flag_access_control, - flag_check_new, flag_new_for_scope, flag_weak, - flag_working_directory, flag_use_cxa_atexit, - flag_use_cxa_get_exception_ptr, flag_enforce_eh_specs, - flag_threadsafe_statics, flag_pretty_templates, - warn_strict_null_sentinel): Remove. - * c.opt (E, Wstrict-null-sentinel, faccess-control, fasm, - fbuiltin, fcheck-new, fconserve-space, felide-constructors, - fenforce-eh-specs, ffor-scope, fgnu-keywords, fimplement-inlines, - fimplicit-inline-templates, fimplicit-templates, - flax-vector-conversions, fms-extensions, fnil-receivers, - fnonansi-builtins, fpretty-templates, freplace-objc-classes, - frtti, fshort-double, fshort-enums, fshort-wchar, - fsigned-bitfields, fsigned-char, fstats, fthreadsafe-statics, - funsigned-bitfields, funsigned-char, fuse-cxa-atexit, - fuse-cxa-get-exception-ptr, fweak, fworking-directory, fzero-link, - gen-decls, undef): Use Var. - (fdefault-inline, foptional-diags): Document as doing nothing. - * c-opts.c (c_common_handle_option): Remove cases for options now - using Var. Mark ignored options as such. - -2010-06-05 Steven Bosscher <steven@gcc.gnu.org> - - * c-common.c: Moved to here from parent directory. - * c-common.def: Likewise. - * c-common.h: Likewise. - * c-cppbuiltin.c: Likewise. - * c-dump.c: Likewise. - * c-format.c: Likewise. - * c-format.h : Likewise. - * c-gimplify.c: Likewise. - * c-lex.c: Likewise. - * c-omp.c: Likewise. - * c.opt: Likewise. - * c-opts.c: Likewise. - * c-pch.c: Likewise. - * c-ppoutput.c: Likewise. - * c-pragma.c: Likewise. - * c-pragma.h: Likewise. - * c-pretty-print.c: Likewise. - * c-pretty-print.h: Likewise. - * c-semantics.c: Likewise. - * stub-objc.c: Likewise. - - * c-common.c: Include gt-c-family-c-common.h. - * c-pragma.c: Include gt-c-family-c-pragma.h. - -Copyright (C) 2010-2013 Free Software Foundation, Inc. - -Copying and distribution of this file, with or without modification, -are permitted in any medium without royalty provided the copyright -notice and this notice are preserved. diff --git a/gcc-4.8.1/gcc/c-family/c-ada-spec.c b/gcc-4.8.1/gcc/c-family/c-ada-spec.c deleted file mode 100644 index 21cbfe94f..000000000 --- a/gcc-4.8.1/gcc/c-family/c-ada-spec.c +++ /dev/null @@ -1,3392 +0,0 @@ -/* Print GENERIC declaration (functions, variables, types) trees coming from - the C and C++ front-ends as well as macros in Ada syntax. - Copyright (C) 2010-2013 Free Software Foundation, Inc. - Adapted from tree-pretty-print.c by Arnaud Charlet <charlet@adacore.com> - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "tree.h" -#include "dumpfile.h" -#include "c-ada-spec.h" -#include "cpplib.h" -#include "c-pragma.h" -#include "cpp-id-data.h" - -/* Adapted from hwint.h to use the Ada prefix. */ -#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG -# if HOST_BITS_PER_WIDE_INT == 64 -# define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \ - "16#%" HOST_LONG_FORMAT "x%016" HOST_LONG_FORMAT "x#" -# else -# define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \ - "16#%" HOST_LONG_FORMAT "x%08" HOST_LONG_FORMAT "x#" -# endif -#else - /* We can assume that 'long long' is at least 64 bits. */ -# define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \ - "16#%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x#" -#endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */ - -/* Local functions, macros and variables. */ -static int dump_generic_ada_node (pretty_printer *, tree, tree, - int (*)(tree, cpp_operation), int, int, bool); -static int print_ada_declaration (pretty_printer *, tree, tree, - int (*cpp_check)(tree, cpp_operation), int); -static void print_ada_struct_decl (pretty_printer *, tree, tree, - int (*cpp_check)(tree, cpp_operation), int, - bool); -static void dump_sloc (pretty_printer *buffer, tree node); -static void print_comment (pretty_printer *, const char *); -static void print_generic_ada_decl (pretty_printer *, tree, - int (*)(tree, cpp_operation), const char *); -static char *get_ada_package (const char *); -static void dump_ada_nodes (pretty_printer *, const char *, - int (*)(tree, cpp_operation)); -static void reset_ada_withs (void); -static void dump_ada_withs (FILE *); -static void dump_ads (const char *, void (*)(const char *), - int (*)(tree, cpp_operation)); -static char *to_ada_name (const char *, int *); -static bool separate_class_package (tree); - -#define INDENT(SPACE) do { \ - int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0) - -#define INDENT_INCR 3 - -/* Given a cpp MACRO, compute the max length BUFFER_LEN of the macro, as well - as max length PARAM_LEN of arguments for fun_like macros, and also set - SUPPORTED to 0 if the macro cannot be mapped to an Ada construct. */ - -static void -macro_length (const cpp_macro *macro, int *supported, int *buffer_len, - int *param_len) -{ - int i; - unsigned j; - - *supported = 1; - *buffer_len = 0; - *param_len = 0; - - if (macro->fun_like) - { - param_len++; - for (i = 0; i < macro->paramc; i++) - { - cpp_hashnode *param = macro->params[i]; - - *param_len += NODE_LEN (param); - - if (i + 1 < macro->paramc) - { - *param_len += 2; /* ", " */ - } - else if (macro->variadic) - { - *supported = 0; - return; - } - } - *param_len += 2; /* ")\0" */ - } - - for (j = 0; j < macro->count; j++) - { - cpp_token *token = ¯o->exp.tokens[j]; - - if (token->flags & PREV_WHITE) - (*buffer_len)++; - - if (token->flags & STRINGIFY_ARG || token->flags & PASTE_LEFT) - { - *supported = 0; - return; - } - - if (token->type == CPP_MACRO_ARG) - *buffer_len += - NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]); - else - /* Include enough extra space to handle e.g. special characters. */ - *buffer_len += (cpp_token_len (token) + 1) * 8; - } - - (*buffer_len)++; -} - -/* Dump into PP a set of MAX_ADA_MACROS MACROS (C/C++) as Ada constants when - possible. */ - -static void -print_ada_macros (pretty_printer *pp, cpp_hashnode **macros, int max_ada_macros) -{ - int j, num_macros = 0, prev_line = -1; - - for (j = 0; j < max_ada_macros; j++) - { - cpp_hashnode *node = macros[j]; - const cpp_macro *macro = node->value.macro; - unsigned i; - int supported = 1, prev_is_one = 0, buffer_len, param_len; - int is_string = 0, is_char = 0; - char *ada_name; - unsigned char *s, *params, *buffer, *buf_param, *char_one = NULL; - - macro_length (macro, &supported, &buffer_len, ¶m_len); - s = buffer = XALLOCAVEC (unsigned char, buffer_len); - params = buf_param = XALLOCAVEC (unsigned char, param_len); - - if (supported) - { - if (macro->fun_like) - { - *buf_param++ = '('; - for (i = 0; i < macro->paramc; i++) - { - cpp_hashnode *param = macro->params[i]; - - memcpy (buf_param, NODE_NAME (param), NODE_LEN (param)); - buf_param += NODE_LEN (param); - - if (i + 1 < macro->paramc) - { - *buf_param++ = ','; - *buf_param++ = ' '; - } - else if (macro->variadic) - { - supported = 0; - break; - } - } - *buf_param++ = ')'; - *buf_param = '\0'; - } - - for (i = 0; supported && i < macro->count; i++) - { - cpp_token *token = ¯o->exp.tokens[i]; - int is_one = 0; - - if (token->flags & PREV_WHITE) - *buffer++ = ' '; - - if (token->flags & STRINGIFY_ARG || token->flags & PASTE_LEFT) - { - supported = 0; - break; - } - - switch (token->type) - { - case CPP_MACRO_ARG: - { - cpp_hashnode *param = - macro->params[token->val.macro_arg.arg_no - 1]; - memcpy (buffer, NODE_NAME (param), NODE_LEN (param)); - buffer += NODE_LEN (param); - } - break; - - case CPP_EQ_EQ: *buffer++ = '='; break; - case CPP_GREATER: *buffer++ = '>'; break; - case CPP_LESS: *buffer++ = '<'; break; - case CPP_PLUS: *buffer++ = '+'; break; - case CPP_MINUS: *buffer++ = '-'; break; - case CPP_MULT: *buffer++ = '*'; break; - case CPP_DIV: *buffer++ = '/'; break; - case CPP_COMMA: *buffer++ = ','; break; - case CPP_OPEN_SQUARE: - case CPP_OPEN_PAREN: *buffer++ = '('; break; - case CPP_CLOSE_SQUARE: /* fallthrough */ - case CPP_CLOSE_PAREN: *buffer++ = ')'; break; - case CPP_DEREF: /* fallthrough */ - case CPP_SCOPE: /* fallthrough */ - case CPP_DOT: *buffer++ = '.'; break; - - case CPP_EQ: *buffer++ = ':'; *buffer++ = '='; break; - case CPP_NOT_EQ: *buffer++ = '/'; *buffer++ = '='; break; - case CPP_GREATER_EQ: *buffer++ = '>'; *buffer++ = '='; break; - case CPP_LESS_EQ: *buffer++ = '<'; *buffer++ = '='; break; - - case CPP_NOT: - *buffer++ = 'n'; *buffer++ = 'o'; *buffer++ = 't'; break; - case CPP_MOD: - *buffer++ = 'm'; *buffer++ = 'o'; *buffer++ = 'd'; break; - case CPP_AND: - *buffer++ = 'a'; *buffer++ = 'n'; *buffer++ = 'd'; break; - case CPP_OR: - *buffer++ = 'o'; *buffer++ = 'r'; break; - case CPP_XOR: - *buffer++ = 'x'; *buffer++ = 'o'; *buffer++ = 'r'; break; - case CPP_AND_AND: - strcpy ((char *) buffer, " and then "); - buffer += 10; - break; - case CPP_OR_OR: - strcpy ((char *) buffer, " or else "); - buffer += 9; - break; - - case CPP_PADDING: - *buffer++ = ' '; - is_one = prev_is_one; - break; - - case CPP_COMMENT: break; - - case CPP_WSTRING: - case CPP_STRING16: - case CPP_STRING32: - case CPP_UTF8STRING: - case CPP_WCHAR: - case CPP_CHAR16: - case CPP_CHAR32: - case CPP_NAME: - case CPP_STRING: - case CPP_NUMBER: - if (!macro->fun_like) - supported = 0; - else - buffer = cpp_spell_token (parse_in, token, buffer, false); - break; - - case CPP_CHAR: - is_char = 1; - { - unsigned chars_seen; - int ignored; - cppchar_t c; - - c = cpp_interpret_charconst (parse_in, token, - &chars_seen, &ignored); - if (c >= 32 && c <= 126) - { - *buffer++ = '\''; - *buffer++ = (char) c; - *buffer++ = '\''; - } - else - { - chars_seen = sprintf - ((char *) buffer, "Character'Val (%d)", (int) c); - buffer += chars_seen; - } - } - break; - - case CPP_LSHIFT: - if (prev_is_one) - { - /* Replace "1 << N" by "2 ** N" */ - *char_one = '2'; - *buffer++ = '*'; - *buffer++ = '*'; - break; - } - /* fallthrough */ - - case CPP_RSHIFT: - case CPP_COMPL: - case CPP_QUERY: - case CPP_EOF: - case CPP_PLUS_EQ: - case CPP_MINUS_EQ: - case CPP_MULT_EQ: - case CPP_DIV_EQ: - case CPP_MOD_EQ: - case CPP_AND_EQ: - case CPP_OR_EQ: - case CPP_XOR_EQ: - case CPP_RSHIFT_EQ: - case CPP_LSHIFT_EQ: - case CPP_PRAGMA: - case CPP_PRAGMA_EOL: - case CPP_HASH: - case CPP_PASTE: - case CPP_OPEN_BRACE: - case CPP_CLOSE_BRACE: - case CPP_SEMICOLON: - case CPP_ELLIPSIS: - case CPP_PLUS_PLUS: - case CPP_MINUS_MINUS: - case CPP_DEREF_STAR: - case CPP_DOT_STAR: - case CPP_ATSIGN: - case CPP_HEADER_NAME: - case CPP_AT_NAME: - case CPP_OTHER: - case CPP_OBJC_STRING: - default: - if (!macro->fun_like) - supported = 0; - else - buffer = cpp_spell_token (parse_in, token, buffer, false); - break; - } - - prev_is_one = is_one; - } - - if (supported) - *buffer = '\0'; - } - - if (macro->fun_like && supported) - { - char *start = (char *) s; - int is_function = 0; - - pp_string (pp, " -- arg-macro: "); - - if (*start == '(' && buffer[-1] == ')') - { - start++; - buffer[-1] = '\0'; - is_function = 1; - pp_string (pp, "function "); - } - else - { - pp_string (pp, "procedure "); - } - - pp_string (pp, (const char *) NODE_NAME (node)); - pp_space (pp); - pp_string (pp, (char *) params); - pp_newline (pp); - pp_string (pp, " -- "); - - if (is_function) - { - pp_string (pp, "return "); - pp_string (pp, start); - pp_semicolon (pp); - } - else - pp_string (pp, start); - - pp_newline (pp); - } - else if (supported) - { - expanded_location sloc = expand_location (macro->line); - - if (sloc.line != prev_line + 1) - pp_newline (pp); - - num_macros++; - prev_line = sloc.line; - - pp_string (pp, " "); - ada_name = to_ada_name ((const char *) NODE_NAME (node), NULL); - pp_string (pp, ada_name); - free (ada_name); - pp_string (pp, " : "); - - if (is_string) - pp_string (pp, "aliased constant String"); - else if (is_char) - pp_string (pp, "aliased constant Character"); - else - pp_string (pp, "constant"); - - pp_string (pp, " := "); - pp_string (pp, (char *) s); - - if (is_string) - pp_string (pp, " & ASCII.NUL"); - - pp_string (pp, "; -- "); - pp_string (pp, sloc.file); - pp_character (pp, ':'); - pp_scalar (pp, "%d", sloc.line); - pp_newline (pp); - } - else - { - pp_string (pp, " -- unsupported macro: "); - pp_string (pp, (const char *) cpp_macro_definition (parse_in, node)); - pp_newline (pp); - } - } - - if (num_macros > 0) - pp_newline (pp); -} - -static const char *source_file; -static int max_ada_macros; - -/* Callback used to count the number of relevant macros from - cpp_forall_identifiers. PFILE and V are not used. NODE is the current macro - to consider. */ - -static int -count_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *node, - void *v ATTRIBUTE_UNUSED) -{ - const cpp_macro *macro = node->value.macro; - - if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN) - && macro->count - && *NODE_NAME (node) != '_' - && LOCATION_FILE (macro->line) == source_file) - max_ada_macros++; - - return 1; -} - -static int store_ada_macro_index; - -/* Callback used to store relevant macros from cpp_forall_identifiers. - PFILE is not used. NODE is the current macro to store if relevant. - MACROS is an array of cpp_hashnode* used to store NODE. */ - -static int -store_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED, - cpp_hashnode *node, void *macros) -{ - const cpp_macro *macro = node->value.macro; - - if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN) - && macro->count - && *NODE_NAME (node) != '_' - && LOCATION_FILE (macro->line) == source_file) - ((cpp_hashnode **) macros)[store_ada_macro_index++] = node; - - return 1; -} - -/* Callback used to compare (during qsort) macros. NODE1 and NODE2 are the - two macro nodes to compare. */ - -static int -compare_macro (const void *node1, const void *node2) -{ - typedef const cpp_hashnode *const_hnode; - - const_hnode n1 = *(const const_hnode *) node1; - const_hnode n2 = *(const const_hnode *) node2; - - return n1->value.macro->line - n2->value.macro->line; -} - -/* Dump in PP all relevant macros appearing in FILE. */ - -static void -dump_ada_macros (pretty_printer *pp, const char* file) -{ - cpp_hashnode **macros; - - /* Initialize file-scope variables. */ - max_ada_macros = 0; - store_ada_macro_index = 0; - source_file = file; - - /* Count all potentially relevant macros, and then sort them by sloc. */ - cpp_forall_identifiers (parse_in, count_ada_macro, NULL); - macros = XALLOCAVEC (cpp_hashnode *, max_ada_macros); - cpp_forall_identifiers (parse_in, store_ada_macro, macros); - qsort (macros, max_ada_macros, sizeof (cpp_hashnode *), compare_macro); - - print_ada_macros (pp, macros, max_ada_macros); -} - -/* Current source file being handled. */ - -static const char *source_file_base; - -/* Compare the declaration (DECL) of struct-like types based on the sloc of - their last field (if LAST is true), so that more nested types collate before - less nested ones. - If ORIG_TYPE is true, also consider struct with a DECL_ORIGINAL_TYPE. */ - -static location_t -decl_sloc_common (const_tree decl, bool last, bool orig_type) -{ - tree type = TREE_TYPE (decl); - - if (TREE_CODE (decl) == TYPE_DECL - && (orig_type || !DECL_ORIGINAL_TYPE (decl)) - && RECORD_OR_UNION_TYPE_P (type) - && TYPE_FIELDS (type)) - { - tree f = TYPE_FIELDS (type); - - if (last) - while (TREE_CHAIN (f)) - f = TREE_CHAIN (f); - - return DECL_SOURCE_LOCATION (f); - } - else - return DECL_SOURCE_LOCATION (decl); -} - -/* Return sloc of DECL, using sloc of last field if LAST is true. */ - -location_t -decl_sloc (const_tree decl, bool last) -{ - return decl_sloc_common (decl, last, false); -} - -/* Compare two locations LHS and RHS. */ - -static int -compare_location (location_t lhs, location_t rhs) -{ - expanded_location xlhs = expand_location (lhs); - expanded_location xrhs = expand_location (rhs); - - if (xlhs.file != xrhs.file) - return filename_cmp (xlhs.file, xrhs.file); - - if (xlhs.line != xrhs.line) - return xlhs.line - xrhs.line; - - if (xlhs.column != xrhs.column) - return xlhs.column - xrhs.column; - - return 0; -} - -/* Compare two declarations (LP and RP) by their source location. */ - -static int -compare_node (const void *lp, const void *rp) -{ - const_tree lhs = *((const tree *) lp); - const_tree rhs = *((const tree *) rp); - - return compare_location (decl_sloc (lhs, true), decl_sloc (rhs, true)); -} - -/* Compare two comments (LP and RP) by their source location. */ - -static int -compare_comment (const void *lp, const void *rp) -{ - const cpp_comment *lhs = (const cpp_comment *) lp; - const cpp_comment *rhs = (const cpp_comment *) rp; - - return compare_location (lhs->sloc, rhs->sloc); -} - -static tree *to_dump = NULL; -static int to_dump_count = 0; - -/* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped - by a subsequent call to dump_ada_nodes. */ - -void -collect_ada_nodes (tree t, const char *source_file) -{ - tree n; - int i = to_dump_count; - - /* Count the likely relevant nodes. */ - for (n = t; n; n = TREE_CHAIN (n)) - if (!DECL_IS_BUILTIN (n) - && LOCATION_FILE (decl_sloc (n, false)) == source_file) - to_dump_count++; - - /* Allocate sufficient storage for all nodes. */ - to_dump = XRESIZEVEC (tree, to_dump, to_dump_count); - - /* Store the relevant nodes. */ - for (n = t; n; n = TREE_CHAIN (n)) - if (!DECL_IS_BUILTIN (n) - && LOCATION_FILE (decl_sloc (n, false)) == source_file) - to_dump[i++] = n; -} - -/* Call back for walk_tree to clear the TREE_VISITED flag of TP. */ - -static tree -unmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, - void *data ATTRIBUTE_UNUSED) -{ - if (TREE_VISITED (*tp)) - TREE_VISITED (*tp) = 0; - else - *walk_subtrees = 0; - - return NULL_TREE; -} - -/* Dump nodes into PP relevant to SOURCE_FILE, as collected by previous calls - to collect_ada_nodes. CPP_CHECK is used to perform C++ queries on nodes. */ - -static void -dump_ada_nodes (pretty_printer *pp, const char *source_file, - int (*cpp_check)(tree, cpp_operation)) -{ - int i, j; - cpp_comment_table *comments; - - /* Sort the table of declarations to dump by sloc. */ - qsort (to_dump, to_dump_count, sizeof (tree), compare_node); - - /* Fetch the table of comments. */ - comments = cpp_get_comments (parse_in); - - /* Sort the comments table by sloc. */ - qsort (comments->entries, comments->count, sizeof (cpp_comment), - compare_comment); - - /* Interleave comments and declarations in line number order. */ - i = j = 0; - do - { - /* Advance j until comment j is in this file. */ - while (j != comments->count - && LOCATION_FILE (comments->entries[j].sloc) != source_file) - j++; - - /* Advance j until comment j is not a duplicate. */ - while (j < comments->count - 1 - && !compare_comment (&comments->entries[j], - &comments->entries[j + 1])) - j++; - - /* Write decls until decl i collates after comment j. */ - while (i != to_dump_count) - { - if (j == comments->count - || LOCATION_LINE (decl_sloc (to_dump[i], false)) - < LOCATION_LINE (comments->entries[j].sloc)) - print_generic_ada_decl (pp, to_dump[i++], cpp_check, source_file); - else - break; - } - - /* Write comment j, if there is one. */ - if (j != comments->count) - print_comment (pp, comments->entries[j++].comment); - - } while (i != to_dump_count || j != comments->count); - - /* Clear the TREE_VISITED flag over each subtree we've dumped. */ - for (i = 0; i < to_dump_count; i++) - walk_tree (&to_dump[i], unmark_visited_r, NULL, NULL); - - /* Finalize the to_dump table. */ - if (to_dump) - { - free (to_dump); - to_dump = NULL; - to_dump_count = 0; - } -} - -/* Print a COMMENT to the output stream PP. */ - -static void -print_comment (pretty_printer *pp, const char *comment) -{ - int len = strlen (comment); - char *str = XALLOCAVEC (char, len + 1); - char *tok; - bool extra_newline = false; - - memcpy (str, comment, len + 1); - - /* Trim C/C++ comment indicators. */ - if (str[len - 2] == '*' && str[len - 1] == '/') - { - str[len - 2] = ' '; - str[len - 1] = '\0'; - } - str += 2; - - tok = strtok (str, "\n"); - while (tok) { - pp_string (pp, " --"); - pp_string (pp, tok); - pp_newline (pp); - tok = strtok (NULL, "\n"); - - /* Leave a blank line after multi-line comments. */ - if (tok) - extra_newline = true; - } - - if (extra_newline) - pp_newline (pp); -} - -/* Prints declaration DECL to PP in Ada syntax. The current source file being - handled is SOURCE_FILE, and CPP_CHECK is used to perform C++ queries on - nodes. */ - -static void -print_generic_ada_decl (pretty_printer *pp, tree decl, - int (*cpp_check)(tree, cpp_operation), - const char* source_file) -{ - source_file_base = source_file; - - if (print_ada_declaration (pp, decl, 0, cpp_check, INDENT_INCR)) - { - pp_newline (pp); - pp_newline (pp); - } -} - -/* Dump a newline and indent BUFFER by SPC chars. */ - -static void -newline_and_indent (pretty_printer *buffer, int spc) -{ - pp_newline (buffer); - INDENT (spc); -} - -struct with { char *s; const char *in_file; int limited; }; -static struct with *withs = NULL; -static int withs_max = 4096; -static int with_len = 0; - -/* Record a "with" clause on package S (a limited with if LIMITED_ACCESS is - true), if not already done. */ - -static void -append_withs (const char *s, int limited_access) -{ - int i; - - if (withs == NULL) - withs = XNEWVEC (struct with, withs_max); - - if (with_len == withs_max) - { - withs_max *= 2; - withs = XRESIZEVEC (struct with, withs, withs_max); - } - - for (i = 0; i < with_len; i++) - if (!strcmp (s, withs[i].s) - && source_file_base == withs[i].in_file) - { - withs[i].limited &= limited_access; - return; - } - - withs[with_len].s = xstrdup (s); - withs[with_len].in_file = source_file_base; - withs[with_len].limited = limited_access; - with_len++; -} - -/* Reset "with" clauses. */ - -static void -reset_ada_withs (void) -{ - int i; - - if (!withs) - return; - - for (i = 0; i < with_len; i++) - free (withs[i].s); - free (withs); - withs = NULL; - withs_max = 4096; - with_len = 0; -} - -/* Dump "with" clauses in F. */ - -static void -dump_ada_withs (FILE *f) -{ - int i; - - fprintf (f, "with Interfaces.C; use Interfaces.C;\n"); - - for (i = 0; i < with_len; i++) - fprintf - (f, "%swith %s;\n", withs[i].limited ? "limited " : "", withs[i].s); -} - -/* Return suitable Ada package name from FILE. */ - -static char * -get_ada_package (const char *file) -{ - const char *base; - char *res; - const char *s; - int i; - size_t plen; - - s = strstr (file, "/include/"); - if (s) - base = s + 9; - else - base = lbasename (file); - - if (ada_specs_parent == NULL) - plen = 0; - else - plen = strlen (ada_specs_parent) + 1; - - res = XNEWVEC (char, plen + strlen (base) + 1); - if (ada_specs_parent != NULL) { - strcpy (res, ada_specs_parent); - res[plen - 1] = '.'; - } - - for (i = plen; *base; base++, i++) - switch (*base) - { - case '+': - res[i] = 'p'; - break; - - case '.': - case '-': - case '_': - case '/': - case '\\': - res[i] = (i == 0 || res[i - 1] == '.' || res[i - 1] == '_') ? 'u' : '_'; - break; - - default: - res[i] = *base; - break; - } - res[i] = '\0'; - - return res; -} - -static const char *ada_reserved[] = { - "abort", "abs", "abstract", "accept", "access", "aliased", "all", "and", - "array", "at", "begin", "body", "case", "constant", "declare", "delay", - "delta", "digits", "do", "else", "elsif", "end", "entry", "exception", - "exit", "for", "function", "generic", "goto", "if", "in", "interface", "is", - "limited", "loop", "mod", "new", "not", "null", "others", "out", "of", "or", - "overriding", "package", "pragma", "private", "procedure", "protected", - "raise", "range", "record", "rem", "renames", "requeue", "return", "reverse", - "select", "separate", "subtype", "synchronized", "tagged", "task", - "terminate", "then", "type", "until", "use", "when", "while", "with", "xor", - NULL}; - -/* ??? would be nice to specify this list via a config file, so that users - can create their own dictionary of conflicts. */ -static const char *c_duplicates[] = { - /* system will cause troubles with System.Address. */ - "system", - - /* The following values have other definitions with same name/other - casing. */ - "funmap", - "rl_vi_fWord", - "rl_vi_bWord", - "rl_vi_eWord", - "rl_readline_version", - "_Vx_ushort", - "USHORT", - "XLookupKeysym", - NULL}; - -/* Return a declaration tree corresponding to TYPE. */ - -static tree -get_underlying_decl (tree type) -{ - tree decl = NULL_TREE; - - if (type == NULL_TREE) - return NULL_TREE; - - /* type is a declaration. */ - if (DECL_P (type)) - decl = type; - - /* type is a typedef. */ - if (TYPE_P (type) && TYPE_NAME (type) && DECL_P (TYPE_NAME (type))) - decl = TYPE_NAME (type); - - /* TYPE_STUB_DECL has been set for type. */ - if (TYPE_P (type) && TYPE_STUB_DECL (type) && - DECL_P (TYPE_STUB_DECL (type))) - decl = TYPE_STUB_DECL (type); - - return decl; -} - -/* Return whether TYPE has static fields. */ - -static int -has_static_fields (const_tree type) -{ - tree tmp; - - for (tmp = TYPE_FIELDS (type); tmp; tmp = TREE_CHAIN (tmp)) - { - if (DECL_NAME (tmp) && TREE_STATIC (tmp)) - return true; - } - return false; -} - -/* Return whether TYPE corresponds to an Ada tagged type (has a dispatch - table). */ - -static int -is_tagged_type (const_tree type) -{ - tree tmp; - - if (!type || !RECORD_OR_UNION_TYPE_P (type)) - return false; - - for (tmp = TYPE_METHODS (type); tmp; tmp = TREE_CHAIN (tmp)) - if (DECL_VINDEX (tmp)) - return true; - - return false; -} - -/* Generate a legal Ada name from a C NAME, returning a malloc'd string. - SPACE_FOUND, if not NULL, is used to indicate whether a space was found in - NAME. */ - -static char * -to_ada_name (const char *name, int *space_found) -{ - const char **names; - int len = strlen (name); - int j, len2 = 0; - int found = false; - char *s = XNEWVEC (char, len * 2 + 5); - char c; - - if (space_found) - *space_found = false; - - /* Add trailing "c_" if name is an Ada reserved word. */ - for (names = ada_reserved; *names; names++) - if (!strcasecmp (name, *names)) - { - s[len2++] = 'c'; - s[len2++] = '_'; - found = true; - break; - } - - if (!found) - /* Add trailing "c_" if name is an potential case sensitive duplicate. */ - for (names = c_duplicates; *names; names++) - if (!strcmp (name, *names)) - { - s[len2++] = 'c'; - s[len2++] = '_'; - found = true; - break; - } - - for (j = 0; name[j] == '_'; j++) - s[len2++] = 'u'; - - if (j > 0) - s[len2++] = '_'; - else if (*name == '.' || *name == '$') - { - s[0] = 'a'; - s[1] = 'n'; - s[2] = 'o'; - s[3] = 'n'; - len2 = 4; - j++; - } - - /* Replace unsuitable characters for Ada identifiers. */ - - for (; j < len; j++) - switch (name[j]) - { - case ' ': - if (space_found) - *space_found = true; - s[len2++] = '_'; - break; - - /* ??? missing some C++ operators. */ - case '=': - s[len2++] = '_'; - - if (name[j + 1] == '=') - { - j++; - s[len2++] = 'e'; - s[len2++] = 'q'; - } - else - { - s[len2++] = 'a'; - s[len2++] = 's'; - } - break; - - case '!': - s[len2++] = '_'; - if (name[j + 1] == '=') - { - j++; - s[len2++] = 'n'; - s[len2++] = 'e'; - } - break; - - case '~': - s[len2++] = '_'; - s[len2++] = 't'; - s[len2++] = 'i'; - break; - - case '&': - case '|': - case '^': - s[len2++] = '_'; - s[len2++] = name[j] == '&' ? 'a' : name[j] == '|' ? 'o' : 'x'; - - if (name[j + 1] == '=') - { - j++; - s[len2++] = 'e'; - } - break; - - case '+': - case '-': - case '*': - case '/': - case '(': - case '[': - if (s[len2 - 1] != '_') - s[len2++] = '_'; - - switch (name[j + 1]) { - case '\0': - j++; - switch (name[j - 1]) { - case '+': s[len2++] = 'p'; break; /* + */ - case '-': s[len2++] = 'm'; break; /* - */ - case '*': s[len2++] = 't'; break; /* * */ - case '/': s[len2++] = 'd'; break; /* / */ - } - break; - - case '=': - j++; - switch (name[j - 1]) { - case '+': s[len2++] = 'p'; break; /* += */ - case '-': s[len2++] = 'm'; break; /* -= */ - case '*': s[len2++] = 't'; break; /* *= */ - case '/': s[len2++] = 'd'; break; /* /= */ - } - s[len2++] = 'a'; - break; - - case '-': /* -- */ - j++; - s[len2++] = 'm'; - s[len2++] = 'm'; - break; - - case '+': /* ++ */ - j++; - s[len2++] = 'p'; - s[len2++] = 'p'; - break; - - case ')': /* () */ - j++; - s[len2++] = 'o'; - s[len2++] = 'p'; - break; - - case ']': /* [] */ - j++; - s[len2++] = 'o'; - s[len2++] = 'b'; - break; - } - - break; - - case '<': - case '>': - c = name[j] == '<' ? 'l' : 'g'; - s[len2++] = '_'; - - switch (name[j + 1]) { - case '\0': - s[len2++] = c; - s[len2++] = 't'; - break; - case '=': - j++; - s[len2++] = c; - s[len2++] = 'e'; - break; - case '>': - j++; - s[len2++] = 's'; - s[len2++] = 'r'; - break; - case '<': - j++; - s[len2++] = 's'; - s[len2++] = 'l'; - break; - default: - break; - } - break; - - case '_': - if (len2 && s[len2 - 1] == '_') - s[len2++] = 'u'; - /* fall through */ - - default: - s[len2++] = name[j]; - } - - if (s[len2 - 1] == '_') - s[len2++] = 'u'; - - s[len2] = '\0'; - - return s; -} - -/* Return true if DECL refers to a C++ class type for which a - separate enclosing package has been or should be generated. */ - -static bool -separate_class_package (tree decl) -{ - if (decl) - { - tree type = TREE_TYPE (decl); - return type - && TREE_CODE (type) == RECORD_TYPE - && (TYPE_METHODS (type) || has_static_fields (type)); - } - else - return false; -} - -static bool package_prefix = true; - -/* Dump in BUFFER the name of an identifier NODE of type TYPE, following Ada - syntax. LIMITED_ACCESS indicates whether NODE can be accessed via a limited - 'with' clause rather than a regular 'with' clause. */ - -static void -pp_ada_tree_identifier (pretty_printer *buffer, tree node, tree type, - int limited_access) -{ - const char *name = IDENTIFIER_POINTER (node); - int space_found = false; - char *s = to_ada_name (name, &space_found); - tree decl; - - /* If the entity is a type and comes from another file, generate "package" - prefix. */ - - decl = get_underlying_decl (type); - - if (decl) - { - expanded_location xloc = expand_location (decl_sloc (decl, false)); - - if (xloc.file && xloc.line) - { - if (xloc.file != source_file_base) - { - switch (TREE_CODE (type)) - { - case ENUMERAL_TYPE: - case INTEGER_TYPE: - case REAL_TYPE: - case FIXED_POINT_TYPE: - case BOOLEAN_TYPE: - case REFERENCE_TYPE: - case POINTER_TYPE: - case ARRAY_TYPE: - case RECORD_TYPE: - case UNION_TYPE: - case QUAL_UNION_TYPE: - case TYPE_DECL: - { - char *s1 = get_ada_package (xloc.file); - - if (package_prefix) - { - append_withs (s1, limited_access); - pp_string (buffer, s1); - pp_character (buffer, '.'); - } - free (s1); - } - break; - default: - break; - } - - if (separate_class_package (decl)) - { - pp_string (buffer, "Class_"); - pp_string (buffer, s); - pp_string (buffer, "."); - } - - } - } - } - - if (space_found) - if (!strcmp (s, "short_int")) - pp_string (buffer, "short"); - else if (!strcmp (s, "short_unsigned_int")) - pp_string (buffer, "unsigned_short"); - else if (!strcmp (s, "unsigned_int")) - pp_string (buffer, "unsigned"); - else if (!strcmp (s, "long_int")) - pp_string (buffer, "long"); - else if (!strcmp (s, "long_unsigned_int")) - pp_string (buffer, "unsigned_long"); - else if (!strcmp (s, "long_long_int")) - pp_string (buffer, "Long_Long_Integer"); - else if (!strcmp (s, "long_long_unsigned_int")) - { - if (package_prefix) - { - append_withs ("Interfaces.C.Extensions", false); - pp_string (buffer, "Extensions.unsigned_long_long"); - } - else - pp_string (buffer, "unsigned_long_long"); - } - else - pp_string(buffer, s); - else - if (!strcmp (s, "bool")) - { - if (package_prefix) - { - append_withs ("Interfaces.C.Extensions", false); - pp_string (buffer, "Extensions.bool"); - } - else - pp_string (buffer, "bool"); - } - else - pp_string(buffer, s); - - free (s); -} - -/* Dump in BUFFER the assembly name of T. */ - -static void -pp_asm_name (pretty_printer *buffer, tree t) -{ - tree name = DECL_ASSEMBLER_NAME (t); - char *ada_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (name) + 1), *s; - const char *ident = IDENTIFIER_POINTER (name); - - for (s = ada_name; *ident; ident++) - { - if (*ident == ' ') - break; - else if (*ident != '*') - *s++ = *ident; - } - - *s = '\0'; - pp_string (buffer, ada_name); -} - -/* Dump in BUFFER the name of a DECL node if set, following Ada syntax. - LIMITED_ACCESS indicates whether NODE can be accessed via a limited - 'with' clause rather than a regular 'with' clause. */ - -static void -dump_ada_decl_name (pretty_printer *buffer, tree decl, int limited_access) -{ - if (DECL_NAME (decl)) - pp_ada_tree_identifier (buffer, DECL_NAME (decl), decl, limited_access); - else - { - tree type_name = TYPE_NAME (TREE_TYPE (decl)); - - if (!type_name) - { - pp_string (buffer, "anon"); - if (TREE_CODE (decl) == FIELD_DECL) - pp_scalar (buffer, "%d", DECL_UID (decl)); - else - pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (decl))); - } - else if (TREE_CODE (type_name) == IDENTIFIER_NODE) - pp_ada_tree_identifier (buffer, type_name, decl, limited_access); - } -} - -/* Dump in BUFFER a name based on both T1 and T2, followed by S. */ - -static void -dump_ada_double_name (pretty_printer *buffer, tree t1, tree t2, const char *s) -{ - if (DECL_NAME (t1)) - pp_ada_tree_identifier (buffer, DECL_NAME (t1), t1, false); - else - { - pp_string (buffer, "anon"); - pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t1))); - } - - pp_character (buffer, '_'); - - if (DECL_NAME (t1)) - pp_ada_tree_identifier (buffer, DECL_NAME (t2), t2, false); - else - { - pp_string (buffer, "anon"); - pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t2))); - } - - pp_string (buffer, s); -} - -/* Dump in BUFFER pragma Import C/CPP on a given node T. */ - -static void -dump_ada_import (pretty_printer *buffer, tree t) -{ - const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t)); - int is_stdcall = TREE_CODE (t) == FUNCTION_DECL && - lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (t))); - - if (is_stdcall) - pp_string (buffer, "pragma Import (Stdcall, "); - else if (name[0] == '_' && name[1] == 'Z') - pp_string (buffer, "pragma Import (CPP, "); - else - pp_string (buffer, "pragma Import (C, "); - - dump_ada_decl_name (buffer, t, false); - pp_string (buffer, ", \""); - - if (is_stdcall) - pp_string (buffer, IDENTIFIER_POINTER (DECL_NAME (t))); - else - pp_asm_name (buffer, t); - - pp_string (buffer, "\");"); -} - -/* Check whether T and its type have different names, and append "the_" - otherwise in BUFFER. */ - -static void -check_name (pretty_printer *buffer, tree t) -{ - const char *s; - tree tmp = TREE_TYPE (t); - - while (TREE_CODE (tmp) == POINTER_TYPE && !TYPE_NAME (tmp)) - tmp = TREE_TYPE (tmp); - - if (TREE_CODE (tmp) != FUNCTION_TYPE) - { - if (TREE_CODE (tmp) == IDENTIFIER_NODE) - s = IDENTIFIER_POINTER (tmp); - else if (!TYPE_NAME (tmp)) - s = ""; - else if (TREE_CODE (TYPE_NAME (tmp)) == IDENTIFIER_NODE) - s = IDENTIFIER_POINTER (TYPE_NAME (tmp)); - else - s = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp))); - - if (!strcasecmp (IDENTIFIER_POINTER (DECL_NAME (t)), s)) - pp_string (buffer, "the_"); - } -} - -/* Dump in BUFFER a function declaration FUNC with Ada syntax. - IS_METHOD indicates whether FUNC is a C++ method. - IS_CONSTRUCTOR whether FUNC is a C++ constructor. - IS_DESTRUCTOR whether FUNC is a C++ destructor. - SPC is the current indentation level. */ - -static int -dump_ada_function_declaration (pretty_printer *buffer, tree func, - int is_method, int is_constructor, - int is_destructor, int spc) -{ - tree arg; - const tree node = TREE_TYPE (func); - char buf[16]; - int num = 0, num_args = 0, have_args = true, have_ellipsis = false; - - /* Compute number of arguments. */ - arg = TYPE_ARG_TYPES (node); - - if (arg) - { - while (TREE_CHAIN (arg) && arg != error_mark_node) - { - num_args++; - arg = TREE_CHAIN (arg); - } - - if (TREE_CODE (TREE_VALUE (arg)) != VOID_TYPE) - { - num_args++; - have_ellipsis = true; - } - } - - if (is_constructor) - num_args--; - - if (is_destructor) - num_args = 1; - - if (num_args > 2) - newline_and_indent (buffer, spc + 1); - - if (num_args > 0) - { - pp_space (buffer); - pp_character (buffer, '('); - } - - if (TREE_CODE (func) == FUNCTION_DECL) - arg = DECL_ARGUMENTS (func); - else - arg = NULL_TREE; - - if (arg == NULL_TREE) - { - have_args = false; - arg = TYPE_ARG_TYPES (node); - - if (arg && TREE_CODE (TREE_VALUE (arg)) == VOID_TYPE) - arg = NULL_TREE; - } - - if (is_constructor) - arg = TREE_CHAIN (arg); - - /* Print the argument names (if available) & types. */ - - for (num = 1; num <= num_args; num++) - { - if (have_args) - { - if (DECL_NAME (arg)) - { - check_name (buffer, arg); - pp_ada_tree_identifier (buffer, DECL_NAME (arg), 0, false); - pp_string (buffer, " : "); - } - else - { - sprintf (buf, "arg%d : ", num); - pp_string (buffer, buf); - } - - dump_generic_ada_node - (buffer, TREE_TYPE (arg), node, NULL, spc, 0, true); - } - else - { - sprintf (buf, "arg%d : ", num); - pp_string (buffer, buf); - dump_generic_ada_node - (buffer, TREE_VALUE (arg), node, NULL, spc, 0, true); - } - - if (TREE_TYPE (arg) && TREE_TYPE (TREE_TYPE (arg)) - && is_tagged_type (TREE_TYPE (TREE_TYPE (arg)))) - { - if (!is_method - || (num != 1 || (!DECL_VINDEX (func) && !is_constructor))) - pp_string (buffer, "'Class"); - } - - arg = TREE_CHAIN (arg); - - if (num < num_args) - { - pp_character (buffer, ';'); - - if (num_args > 2) - newline_and_indent (buffer, spc + INDENT_INCR); - else - pp_space (buffer); - } - } - - if (have_ellipsis) - { - pp_string (buffer, " -- , ..."); - newline_and_indent (buffer, spc + INDENT_INCR); - } - - if (num_args > 0) - pp_character (buffer, ')'); - return num_args; -} - -/* Dump in BUFFER all the domains associated with an array NODE, - using Ada syntax. SPC is the current indentation level. */ - -static void -dump_ada_array_domains (pretty_printer *buffer, tree node, int spc) -{ - int first = 1; - pp_character (buffer, '('); - - for (; TREE_CODE (node) == ARRAY_TYPE; node = TREE_TYPE (node)) - { - tree domain = TYPE_DOMAIN (node); - - if (domain) - { - tree min = TYPE_MIN_VALUE (domain); - tree max = TYPE_MAX_VALUE (domain); - - if (!first) - pp_string (buffer, ", "); - first = 0; - - if (min) - dump_generic_ada_node (buffer, min, NULL_TREE, NULL, spc, 0, true); - pp_string (buffer, " .. "); - - /* If the upper bound is zero, gcc may generate a NULL_TREE - for TYPE_MAX_VALUE rather than an integer_cst. */ - if (max) - dump_generic_ada_node (buffer, max, NULL_TREE, NULL, spc, 0, true); - else - pp_string (buffer, "0"); - } - else - pp_string (buffer, "size_t"); - } - pp_character (buffer, ')'); -} - -/* Dump in BUFFER file:line information related to NODE. */ - -static void -dump_sloc (pretty_printer *buffer, tree node) -{ - expanded_location xloc; - - xloc.file = NULL; - - if (TREE_CODE_CLASS (TREE_CODE (node)) == tcc_declaration) - xloc = expand_location (DECL_SOURCE_LOCATION (node)); - else if (EXPR_HAS_LOCATION (node)) - xloc = expand_location (EXPR_LOCATION (node)); - - if (xloc.file) - { - pp_string (buffer, xloc.file); - pp_string (buffer, ":"); - pp_decimal_int (buffer, xloc.line); - } -} - -/* Return true if T designates a one dimension array of "char". */ - -static bool -is_char_array (tree t) -{ - tree tmp; - int num_dim = 0; - - /* Retrieve array's type. */ - tmp = t; - while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE) - { - num_dim++; - tmp = TREE_TYPE (tmp); - } - - tmp = TREE_TYPE (tmp); - return num_dim == 1 && TREE_CODE (tmp) == INTEGER_TYPE - && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp))), "char"); -} - -/* Dump in BUFFER an array type T in Ada syntax. Assume that the "type" - keyword and name have already been printed. SPC is the indentation - level. */ - -static void -dump_ada_array_type (pretty_printer *buffer, tree t, int spc) -{ - tree tmp; - bool char_array = is_char_array (t); - - /* Special case char arrays. */ - if (char_array) - { - pp_string (buffer, "Interfaces.C.char_array "); - } - else - pp_string (buffer, "array "); - - /* Print the dimensions. */ - dump_ada_array_domains (buffer, TREE_TYPE (t), spc); - - /* Retrieve array's type. */ - tmp = TREE_TYPE (t); - while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE) - tmp = TREE_TYPE (tmp); - - /* Print array's type. */ - if (!char_array) - { - pp_string (buffer, " of "); - - if (TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE) - pp_string (buffer, "aliased "); - - dump_generic_ada_node - (buffer, TREE_TYPE (tmp), TREE_TYPE (t), NULL, spc, false, true); - } -} - -/* Dump in BUFFER type names associated with a template, each prepended with - '_'. TYPES is the TREE_PURPOSE of a DECL_TEMPLATE_INSTANTIATIONS. - CPP_CHECK is used to perform C++ queries on nodes. - SPC is the indentation level. */ - -static void -dump_template_types (pretty_printer *buffer, tree types, - int (*cpp_check)(tree, cpp_operation), int spc) -{ - size_t i; - size_t len = TREE_VEC_LENGTH (types); - - for (i = 0; i < len; i++) - { - tree elem = TREE_VEC_ELT (types, i); - pp_character (buffer, '_'); - if (!dump_generic_ada_node (buffer, elem, 0, cpp_check, spc, false, true)) - { - pp_string (buffer, "unknown"); - pp_scalar (buffer, "%lu", (unsigned long) TREE_HASH (elem)); - } - } -} - -/* Dump in BUFFER the contents of all class instantiations associated with - a given template T. CPP_CHECK is used to perform C++ queries on nodes. - SPC is the indentation level. */ - -static int -dump_ada_template (pretty_printer *buffer, tree t, - int (*cpp_check)(tree, cpp_operation), int spc) -{ - /* DECL_VINDEX is DECL_TEMPLATE_INSTANTIATIONS in this context. */ - tree inst = DECL_VINDEX (t); - /* DECL_RESULT_FLD is DECL_TEMPLATE_RESULT in this context. */ - tree result = DECL_RESULT_FLD (t); - int num_inst = 0; - - /* Don't look at template declarations declaring something coming from - another file. This can occur for template friend declarations. */ - if (LOCATION_FILE (decl_sloc (result, false)) - != LOCATION_FILE (decl_sloc (t, false))) - return 0; - - while (inst && inst != error_mark_node) - { - tree types = TREE_PURPOSE (inst); - tree instance = TREE_VALUE (inst); - - if (TREE_VEC_LENGTH (types) == 0) - break; - - if (!TYPE_P (instance) || !TYPE_METHODS (instance)) - break; - - num_inst++; - INDENT (spc); - pp_string (buffer, "package "); - package_prefix = false; - dump_generic_ada_node (buffer, instance, t, cpp_check, spc, false, true); - dump_template_types (buffer, types, cpp_check, spc); - pp_string (buffer, " is"); - spc += INDENT_INCR; - newline_and_indent (buffer, spc); - - TREE_VISITED (get_underlying_decl (instance)) = 1; - pp_string (buffer, "type "); - dump_generic_ada_node (buffer, instance, t, cpp_check, spc, false, true); - package_prefix = true; - - if (is_tagged_type (instance)) - pp_string (buffer, " is tagged limited "); - else - pp_string (buffer, " is limited "); - - dump_generic_ada_node (buffer, instance, t, cpp_check, spc, false, false); - pp_newline (buffer); - spc -= INDENT_INCR; - newline_and_indent (buffer, spc); - - pp_string (buffer, "end;"); - newline_and_indent (buffer, spc); - pp_string (buffer, "use "); - package_prefix = false; - dump_generic_ada_node (buffer, instance, t, cpp_check, spc, false, true); - dump_template_types (buffer, types, cpp_check, spc); - package_prefix = true; - pp_semicolon (buffer); - pp_newline (buffer); - pp_newline (buffer); - - inst = TREE_CHAIN (inst); - } - - return num_inst > 0; -} - -/* Return true if NODE is a simple enum types, that can be mapped to an - Ada enum type directly. */ - -static bool -is_simple_enum (tree node) -{ - unsigned HOST_WIDE_INT count = 0; - tree value; - - for (value = TYPE_VALUES (node); value; value = TREE_CHAIN (value)) - { - tree int_val = TREE_VALUE (value); - - if (TREE_CODE (int_val) != INTEGER_CST) - int_val = DECL_INITIAL (int_val); - - if (!host_integerp (int_val, 0)) - return false; - else if (TREE_INT_CST_LOW (int_val) != count) - return false; - - count++; - } - - return true; -} - -static bool in_function = true; -static bool bitfield_used = false; - -/* Recursively dump in BUFFER Ada declarations corresponding to NODE of type - TYPE. CPP_CHECK is used to perform C++ queries on nodes. SPC is the - indentation level. LIMITED_ACCESS indicates whether NODE can be referenced - via a "limited with" clause. NAME_ONLY indicates whether we should only - dump the name of NODE, instead of its full declaration. */ - -static int -dump_generic_ada_node (pretty_printer *buffer, tree node, tree type, - int (*cpp_check)(tree, cpp_operation), int spc, - int limited_access, bool name_only) -{ - if (node == NULL_TREE) - return 0; - - switch (TREE_CODE (node)) - { - case ERROR_MARK: - pp_string (buffer, "<<< error >>>"); - return 0; - - case IDENTIFIER_NODE: - pp_ada_tree_identifier (buffer, node, type, limited_access); - break; - - case TREE_LIST: - pp_string (buffer, "--- unexpected node: TREE_LIST"); - return 0; - - case TREE_BINFO: - dump_generic_ada_node - (buffer, BINFO_TYPE (node), type, cpp_check, - spc, limited_access, name_only); - - case TREE_VEC: - pp_string (buffer, "--- unexpected node: TREE_VEC"); - return 0; - - case VOID_TYPE: - if (package_prefix) - { - append_withs ("System", false); - pp_string (buffer, "System.Address"); - } - else - pp_string (buffer, "address"); - break; - - case VECTOR_TYPE: - pp_string (buffer, "<vector>"); - break; - - case COMPLEX_TYPE: - pp_string (buffer, "<complex>"); - break; - - case ENUMERAL_TYPE: - if (name_only) - dump_generic_ada_node - (buffer, TYPE_NAME (node), node, cpp_check, spc, 0, true); - else - { - tree value = TYPE_VALUES (node); - - if (is_simple_enum (node)) - { - bool first = true; - spc += INDENT_INCR; - newline_and_indent (buffer, spc - 1); - pp_string (buffer, "("); - for (; value; value = TREE_CHAIN (value)) - { - if (first) - first = false; - else - { - pp_string (buffer, ","); - newline_and_indent (buffer, spc); - } - - pp_ada_tree_identifier - (buffer, TREE_PURPOSE (value), node, false); - } - pp_string (buffer, ");"); - spc -= INDENT_INCR; - newline_and_indent (buffer, spc); - pp_string (buffer, "pragma Convention (C, "); - dump_generic_ada_node - (buffer, DECL_NAME (type) ? type : TYPE_NAME (node), type, - cpp_check, spc, 0, true); - pp_string (buffer, ")"); - } - else - { - pp_string (buffer, "unsigned"); - for (; value; value = TREE_CHAIN (value)) - { - pp_semicolon (buffer); - newline_and_indent (buffer, spc); - - pp_ada_tree_identifier - (buffer, TREE_PURPOSE (value), node, false); - pp_string (buffer, " : constant "); - - dump_generic_ada_node - (buffer, DECL_NAME (type) ? type : TYPE_NAME (node), type, - cpp_check, spc, 0, true); - - pp_string (buffer, " := "); - dump_generic_ada_node - (buffer, - TREE_CODE (TREE_VALUE (value)) == INTEGER_CST ? - TREE_VALUE (value) : DECL_INITIAL (TREE_VALUE (value)), - node, cpp_check, spc, false, true); - } - } - } - break; - - case INTEGER_TYPE: - case REAL_TYPE: - case FIXED_POINT_TYPE: - case BOOLEAN_TYPE: - { - enum tree_code_class tclass; - - tclass = TREE_CODE_CLASS (TREE_CODE (node)); - - if (tclass == tcc_declaration) - { - if (DECL_NAME (node)) - pp_ada_tree_identifier - (buffer, DECL_NAME (node), 0, limited_access); - else - pp_string (buffer, "<unnamed type decl>"); - } - else if (tclass == tcc_type) - { - if (TYPE_NAME (node)) - { - if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE) - pp_ada_tree_identifier (buffer, TYPE_NAME (node), - node, limited_access); - else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (node))) - dump_ada_decl_name (buffer, TYPE_NAME (node), limited_access); - else - pp_string (buffer, "<unnamed type>"); - } - else if (TREE_CODE (node) == INTEGER_TYPE) - { - append_withs ("Interfaces.C.Extensions", false); - bitfield_used = true; - - if (TYPE_PRECISION (node) == 1) - pp_string (buffer, "Extensions.Unsigned_1"); - else - { - pp_string (buffer, (TYPE_UNSIGNED (node) - ? "Extensions.Unsigned_" - : "Extensions.Signed_")); - pp_decimal_int (buffer, TYPE_PRECISION (node)); - } - } - else - pp_string (buffer, "<unnamed type>"); - } - break; - } - - case POINTER_TYPE: - case REFERENCE_TYPE: - if (name_only && TYPE_NAME (node)) - dump_generic_ada_node - (buffer, TYPE_NAME (node), node, cpp_check, - spc, limited_access, true); - - else if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE) - { - tree fnode = TREE_TYPE (node); - bool is_function; - bool prev_in_function = in_function; - - if (VOID_TYPE_P (TREE_TYPE (fnode))) - { - is_function = false; - pp_string (buffer, "access procedure"); - } - else - { - is_function = true; - pp_string (buffer, "access function"); - } - - in_function = is_function; - dump_ada_function_declaration - (buffer, node, false, false, false, spc + INDENT_INCR); - in_function = prev_in_function; - - if (is_function) - { - pp_string (buffer, " return "); - dump_generic_ada_node - (buffer, TREE_TYPE (fnode), type, cpp_check, spc, 0, true); - } - - /* If we are dumping the full type, it means we are part of a - type definition and need also a Convention C pragma. */ - if (!name_only) - { - pp_semicolon (buffer); - newline_and_indent (buffer, spc); - pp_string (buffer, "pragma Convention (C, "); - dump_generic_ada_node - (buffer, type, 0, cpp_check, spc, false, true); - pp_string (buffer, ")"); - } - } - else - { - int is_access = false; - unsigned int quals = TYPE_QUALS (TREE_TYPE (node)); - - if (VOID_TYPE_P (TREE_TYPE (node))) - { - if (!name_only) - pp_string (buffer, "new "); - if (package_prefix) - { - append_withs ("System", false); - pp_string (buffer, "System.Address"); - } - else - pp_string (buffer, "address"); - } - else - { - if (TREE_CODE (node) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (node)) == INTEGER_TYPE - && !strcmp - (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME - (TREE_TYPE (node)))), "char")) - { - if (!name_only) - pp_string (buffer, "new "); - - if (package_prefix) - { - pp_string (buffer, "Interfaces.C.Strings.chars_ptr"); - append_withs ("Interfaces.C.Strings", false); - } - else - pp_string (buffer, "chars_ptr"); - } - else - { - /* For now, handle all access-to-access or - access-to-unknown-structs as opaque system.address. */ - - tree type_name = TYPE_NAME (TREE_TYPE (node)); - const_tree typ2 = !type || - DECL_P (type) ? type : TYPE_NAME (type); - const_tree underlying_type = - get_underlying_decl (TREE_TYPE (node)); - - if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE - /* Pointer to pointer. */ - - || (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node)) - && (!underlying_type - || !TYPE_FIELDS (TREE_TYPE (underlying_type)))) - /* Pointer to opaque structure. */ - - || underlying_type == NULL_TREE - || (!typ2 - && !TREE_VISITED (underlying_type) - && !TREE_VISITED (type_name) - && !is_tagged_type (TREE_TYPE (node)) - && DECL_SOURCE_FILE (underlying_type) - == source_file_base) - || (type_name && typ2 - && DECL_P (underlying_type) - && DECL_P (typ2) - && decl_sloc (underlying_type, true) - > decl_sloc (typ2, true) - && DECL_SOURCE_FILE (underlying_type) - == DECL_SOURCE_FILE (typ2))) - { - if (package_prefix) - { - append_withs ("System", false); - if (!name_only) - pp_string (buffer, "new "); - pp_string (buffer, "System.Address"); - } - else - pp_string (buffer, "address"); - return spc; - } - - if (!package_prefix) - pp_string (buffer, "access"); - else if (AGGREGATE_TYPE_P (TREE_TYPE (node))) - { - if (!type || TREE_CODE (type) != FUNCTION_DECL) - { - pp_string (buffer, "access "); - is_access = true; - - if (quals & TYPE_QUAL_CONST) - pp_string (buffer, "constant "); - else if (!name_only) - pp_string (buffer, "all "); - } - else if (quals & TYPE_QUAL_CONST) - pp_string (buffer, "in "); - else if (in_function) - { - is_access = true; - pp_string (buffer, "access "); - } - else - { - is_access = true; - pp_string (buffer, "access "); - /* ??? should be configurable: access or in out. */ - } - } - else - { - is_access = true; - pp_string (buffer, "access "); - - if (!name_only) - pp_string (buffer, "all "); - } - - if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node)) - && type_name != NULL_TREE) - dump_generic_ada_node - (buffer, type_name, - TREE_TYPE (node), cpp_check, spc, is_access, true); - else - dump_generic_ada_node - (buffer, TREE_TYPE (node), TREE_TYPE (node), - cpp_check, spc, 0, true); - } - } - } - break; - - case ARRAY_TYPE: - if (name_only) - dump_generic_ada_node - (buffer, TYPE_NAME (node), node, cpp_check, - spc, limited_access, true); - else - dump_ada_array_type (buffer, node, spc); - break; - - case RECORD_TYPE: - case UNION_TYPE: - case QUAL_UNION_TYPE: - if (name_only) - { - if (TYPE_NAME (node)) - dump_generic_ada_node - (buffer, TYPE_NAME (node), node, cpp_check, - spc, limited_access, true); - else - { - pp_string (buffer, "anon_"); - pp_scalar (buffer, "%d", TYPE_UID (node)); - } - } - else - print_ada_struct_decl - (buffer, node, type, cpp_check, spc, true); - break; - - case INTEGER_CST: - /* We treat the upper half of the sizetype range as negative. This - is consistent with the internal treatment and makes it possible - to generate the (0 .. -1) range for flexible array members. */ - if (TREE_TYPE (node) == sizetype) - node = fold_convert (ssizetype, node); - if (host_integerp (node, 0)) - pp_wide_integer (buffer, TREE_INT_CST_LOW (node)); - else if (host_integerp (node, 1)) - pp_unsigned_wide_integer (buffer, TREE_INT_CST_LOW (node)); - else - { - tree val = node; - unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (val); - HOST_WIDE_INT high = TREE_INT_CST_HIGH (val); - - if (tree_int_cst_sgn (val) < 0) - { - pp_character (buffer, '-'); - high = ~high + !low; - low = -low; - } - sprintf (pp_buffer (buffer)->digit_buffer, - ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX, - (unsigned HOST_WIDE_INT) high, low); - pp_string (buffer, pp_buffer (buffer)->digit_buffer); - } - break; - - case REAL_CST: - case FIXED_CST: - case COMPLEX_CST: - case STRING_CST: - case VECTOR_CST: - return 0; - - case FUNCTION_DECL: - case CONST_DECL: - dump_ada_decl_name (buffer, node, limited_access); - break; - - case TYPE_DECL: - if (DECL_IS_BUILTIN (node)) - { - /* Don't print the declaration of built-in types. */ - - if (name_only) - { - /* If we're in the middle of a declaration, defaults to - System.Address. */ - if (package_prefix) - { - append_withs ("System", false); - pp_string (buffer, "System.Address"); - } - else - pp_string (buffer, "address"); - } - break; - } - - if (name_only) - dump_ada_decl_name (buffer, node, limited_access); - else - { - if (is_tagged_type (TREE_TYPE (node))) - { - tree tmp = TYPE_FIELDS (TREE_TYPE (node)); - int first = 1; - - /* Look for ancestors. */ - for (; tmp; tmp = TREE_CHAIN (tmp)) - { - if (!DECL_NAME (tmp) && is_tagged_type (TREE_TYPE (tmp))) - { - if (first) - { - pp_string (buffer, "limited new "); - first = 0; - } - else - pp_string (buffer, " and "); - - dump_ada_decl_name - (buffer, TYPE_NAME (TREE_TYPE (tmp)), false); - } - } - - pp_string (buffer, first ? "tagged limited " : " with "); - } - else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node)) - && TYPE_METHODS (TREE_TYPE (node))) - pp_string (buffer, "limited "); - - dump_generic_ada_node - (buffer, TREE_TYPE (node), type, cpp_check, spc, false, false); - } - break; - - case VAR_DECL: - case PARM_DECL: - case FIELD_DECL: - case NAMESPACE_DECL: - dump_ada_decl_name (buffer, node, false); - break; - - default: - /* Ignore other nodes (e.g. expressions). */ - return 0; - } - - return 1; -} - -/* Dump in BUFFER NODE's methods. CPP_CHECK is used to perform C++ queries on - nodes. SPC is the indentation level. */ - -static void -print_ada_methods (pretty_printer *buffer, tree node, - int (*cpp_check)(tree, cpp_operation), int spc) -{ - tree tmp = TYPE_METHODS (node); - int res = 1; - - if (tmp) - { - pp_semicolon (buffer); - - for (; tmp; tmp = TREE_CHAIN (tmp)) - { - if (res) - { - pp_newline (buffer); - pp_newline (buffer); - } - res = print_ada_declaration (buffer, tmp, node, cpp_check, spc); - } - } -} - -/* Dump in BUFFER anonymous types nested inside T's definition. - PARENT is the parent node of T. - FORWARD indicates whether a forward declaration of T should be generated. - CPP_CHECK is used to perform C++ queries on - nodes. SPC is the indentation level. */ - -static void -dump_nested_types (pretty_printer *buffer, tree t, tree parent, bool forward, - int (*cpp_check)(tree, cpp_operation), int spc) -{ - tree field, outer, decl; - - /* Avoid recursing over the same tree. */ - if (TREE_VISITED (t)) - return; - - /* Find possible anonymous arrays/unions/structs recursively. */ - - outer = TREE_TYPE (t); - - if (outer == NULL_TREE) - return; - - if (forward) - { - pp_string (buffer, "type "); - dump_generic_ada_node - (buffer, t, t, cpp_check, spc, false, true); - pp_semicolon (buffer); - newline_and_indent (buffer, spc); - TREE_VISITED (t) = 1; - } - - field = TYPE_FIELDS (outer); - while (field) - { - if ((TREE_TYPE (field) != outer - || (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE - && TREE_TYPE (TREE_TYPE (field)) != outer)) - && (!TYPE_NAME (TREE_TYPE (field)) - || (TREE_CODE (field) == TYPE_DECL - && DECL_NAME (field) != DECL_NAME (t) - && TYPE_NAME (TREE_TYPE (field)) != TYPE_NAME (outer)))) - { - switch (TREE_CODE (TREE_TYPE (field))) - { - case POINTER_TYPE: - decl = TREE_TYPE (TREE_TYPE (field)); - - if (TREE_CODE (decl) == FUNCTION_TYPE) - for (decl = TREE_TYPE (decl); - decl && TREE_CODE (decl) == POINTER_TYPE; - decl = TREE_TYPE (decl)) - ; - - decl = get_underlying_decl (decl); - - if (decl - && DECL_P (decl) - && decl_sloc (decl, true) > decl_sloc (t, true) - && DECL_SOURCE_FILE (decl) == DECL_SOURCE_FILE (t) - && !TREE_VISITED (decl) - && !DECL_IS_BUILTIN (decl) - && (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)) - || TYPE_FIELDS (TREE_TYPE (decl)))) - { - /* Generate forward declaration. */ - - pp_string (buffer, "type "); - dump_generic_ada_node - (buffer, decl, 0, cpp_check, spc, false, true); - pp_semicolon (buffer); - newline_and_indent (buffer, spc); - - /* Ensure we do not generate duplicate forward - declarations for this type. */ - TREE_VISITED (decl) = 1; - } - break; - - case ARRAY_TYPE: - /* Special case char arrays. */ - if (is_char_array (field)) - pp_string (buffer, "sub"); - - pp_string (buffer, "type "); - dump_ada_double_name (buffer, parent, field, "_array is "); - dump_ada_array_type (buffer, field, spc); - pp_semicolon (buffer); - newline_and_indent (buffer, spc); - break; - - case UNION_TYPE: - TREE_VISITED (t) = 1; - dump_nested_types (buffer, field, t, false, cpp_check, spc); - - pp_string (buffer, "type "); - - if (TYPE_NAME (TREE_TYPE (field))) - { - dump_generic_ada_node - (buffer, TYPE_NAME (TREE_TYPE (field)), 0, cpp_check, - spc, false, true); - pp_string (buffer, " (discr : unsigned := 0) is "); - print_ada_struct_decl - (buffer, TREE_TYPE (field), t, cpp_check, spc, false); - - pp_string (buffer, "pragma Convention (C_Pass_By_Copy, "); - dump_generic_ada_node - (buffer, TREE_TYPE (field), 0, cpp_check, - spc, false, true); - pp_string (buffer, ");"); - newline_and_indent (buffer, spc); - - pp_string (buffer, "pragma Unchecked_Union ("); - dump_generic_ada_node - (buffer, TREE_TYPE (field), 0, cpp_check, - spc, false, true); - pp_string (buffer, ");"); - } - else - { - dump_ada_double_name - (buffer, parent, field, - "_union (discr : unsigned := 0) is "); - print_ada_struct_decl - (buffer, TREE_TYPE (field), t, cpp_check, spc, false); - pp_string (buffer, "pragma Convention (C_Pass_By_Copy, "); - dump_ada_double_name (buffer, parent, field, "_union);"); - newline_and_indent (buffer, spc); - - pp_string (buffer, "pragma Unchecked_Union ("); - dump_ada_double_name (buffer, parent, field, "_union);"); - } - - newline_and_indent (buffer, spc); - break; - - case RECORD_TYPE: - if (TYPE_NAME (TREE_TYPE (t)) && !TREE_VISITED (t)) - { - pp_string (buffer, "type "); - dump_generic_ada_node - (buffer, t, parent, 0, spc, false, true); - pp_semicolon (buffer); - newline_and_indent (buffer, spc); - } - - TREE_VISITED (t) = 1; - dump_nested_types (buffer, field, t, false, cpp_check, spc); - pp_string (buffer, "type "); - - if (TYPE_NAME (TREE_TYPE (field))) - { - dump_generic_ada_node - (buffer, TREE_TYPE (field), 0, cpp_check, - spc, false, true); - pp_string (buffer, " is "); - print_ada_struct_decl - (buffer, TREE_TYPE (field), t, cpp_check, spc, false); - pp_string (buffer, "pragma Convention (C_Pass_By_Copy, "); - dump_generic_ada_node - (buffer, TREE_TYPE (field), 0, cpp_check, - spc, false, true); - pp_string (buffer, ");"); - } - else - { - dump_ada_double_name - (buffer, parent, field, "_struct is "); - print_ada_struct_decl - (buffer, TREE_TYPE (field), t, cpp_check, spc, false); - pp_string (buffer, "pragma Convention (C_Pass_By_Copy, "); - dump_ada_double_name (buffer, parent, field, "_struct);"); - } - - newline_and_indent (buffer, spc); - break; - - default: - break; - } - } - field = TREE_CHAIN (field); - } - - TREE_VISITED (t) = 1; -} - -/* Dump in BUFFER destructor spec corresponding to T. */ - -static void -print_destructor (pretty_printer *buffer, tree t) -{ - const char *s = IDENTIFIER_POINTER (DECL_NAME (t)); - - if (*s == '_') - for (s += 2; *s != ' '; s++) - pp_character (buffer, *s); - else - { - pp_string (buffer, "Delete_"); - pp_ada_tree_identifier (buffer, DECL_NAME (t), t, false); - } -} - -/* Return the name of type T. */ - -static const char * -type_name (tree t) -{ - tree n = TYPE_NAME (t); - - if (TREE_CODE (n) == IDENTIFIER_NODE) - return IDENTIFIER_POINTER (n); - else - return IDENTIFIER_POINTER (DECL_NAME (n)); -} - -/* Print in BUFFER the declaration of a variable T of type TYPE in Ada syntax. - CPP_CHECK is used to perform C++ queries on nodes. SPC is the indentation - level. Return 1 if a declaration was printed, 0 otherwise. */ - -static int -print_ada_declaration (pretty_printer *buffer, tree t, tree type, - int (*cpp_check)(tree, cpp_operation), int spc) -{ - int is_var = 0, need_indent = 0; - int is_class = false; - tree name = TYPE_NAME (TREE_TYPE (t)); - tree decl_name = DECL_NAME (t); - tree orig = NULL_TREE; - - if (cpp_check && cpp_check (t, IS_TEMPLATE)) - return dump_ada_template (buffer, t, cpp_check, spc); - - if (TREE_CODE (t) == CONST_DECL && TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE) - /* Skip enumeral values: will be handled as part of the type itself. */ - return 0; - - if (TREE_CODE (t) == TYPE_DECL) - { - orig = DECL_ORIGINAL_TYPE (t); - - if (orig && TYPE_STUB_DECL (orig)) - { - tree stub = TYPE_STUB_DECL (orig); - tree typ = TREE_TYPE (stub); - - if (TYPE_NAME (typ)) - { - /* If types have same representation, and same name (ignoring - casing), then ignore the second type. */ - if (type_name (typ) == type_name (TREE_TYPE (t)) - || !strcasecmp (type_name (typ), type_name (TREE_TYPE (t)))) - return 0; - - INDENT (spc); - - if (RECORD_OR_UNION_TYPE_P (typ) && !TYPE_FIELDS (typ)) - { - pp_string (buffer, "-- skipped empty struct "); - dump_generic_ada_node (buffer, t, type, 0, spc, false, true); - } - else - { - if (!TREE_VISITED (stub) - && DECL_SOURCE_FILE (stub) == source_file_base) - dump_nested_types - (buffer, stub, stub, true, cpp_check, spc); - - pp_string (buffer, "subtype "); - dump_generic_ada_node (buffer, t, type, 0, spc, false, true); - pp_string (buffer, " is "); - dump_generic_ada_node - (buffer, typ, type, 0, spc, false, true); - pp_semicolon (buffer); - } - return 1; - } - } - - /* Skip unnamed or anonymous structs/unions/enum types. */ - if (!orig && !decl_name && !name) - { - tree tmp; - location_t sloc; - - if (cpp_check || TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE) - return 0; - - if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t))) - { - /* Search next items until finding a named type decl. */ - sloc = decl_sloc_common (t, true, true); - - for (tmp = TREE_CHAIN (t); tmp; tmp = TREE_CHAIN (tmp)) - { - if (TREE_CODE (tmp) == TYPE_DECL - && (DECL_NAME (tmp) || TYPE_NAME (TREE_TYPE (tmp)))) - { - /* If same sloc, it means we can ignore the anonymous - struct. */ - if (decl_sloc_common (tmp, true, true) == sloc) - return 0; - else - break; - } - } - if (tmp == NULL) - return 0; - } - } - - if (!orig - && TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE - && decl_name - && (*IDENTIFIER_POINTER (decl_name) == '.' - || *IDENTIFIER_POINTER (decl_name) == '$')) - /* Skip anonymous enum types (duplicates of real types). */ - return 0; - - INDENT (spc); - - switch (TREE_CODE (TREE_TYPE (t))) - { - case RECORD_TYPE: - case UNION_TYPE: - case QUAL_UNION_TYPE: - /* Skip empty structs (typically forward references to real - structs). */ - if (!TYPE_FIELDS (TREE_TYPE (t))) - { - pp_string (buffer, "-- skipped empty struct "); - dump_generic_ada_node (buffer, t, type, 0, spc, false, true); - return 1; - } - - if (decl_name - && (*IDENTIFIER_POINTER (decl_name) == '.' - || *IDENTIFIER_POINTER (decl_name) == '$')) - { - pp_string (buffer, "-- skipped anonymous struct "); - dump_generic_ada_node (buffer, t, type, 0, spc, false, true); - TREE_VISITED (t) = 1; - return 1; - } - - if (orig && TYPE_NAME (orig) && orig != TREE_TYPE (t)) - pp_string (buffer, "subtype "); - else - { - dump_nested_types (buffer, t, t, false, cpp_check, spc); - - if (separate_class_package (t)) - { - is_class = true; - pp_string (buffer, "package Class_"); - dump_generic_ada_node - (buffer, t, type, 0, spc, false, true); - pp_string (buffer, " is"); - spc += INDENT_INCR; - newline_and_indent (buffer, spc); - } - - pp_string (buffer, "type "); - } - break; - - case ARRAY_TYPE: - case POINTER_TYPE: - case REFERENCE_TYPE: - if ((orig && TYPE_NAME (orig) && orig != TREE_TYPE (t)) - || is_char_array (t)) - pp_string (buffer, "subtype "); - else - pp_string (buffer, "type "); - break; - - case FUNCTION_TYPE: - pp_string (buffer, "-- skipped function type "); - dump_generic_ada_node (buffer, t, type, 0, spc, false, true); - return 1; - break; - - case ENUMERAL_TYPE: - if ((orig && TYPE_NAME (orig) && orig != TREE_TYPE (t)) - || !is_simple_enum (TREE_TYPE (t))) - pp_string (buffer, "subtype "); - else - pp_string (buffer, "type "); - break; - - default: - pp_string (buffer, "subtype "); - } - TREE_VISITED (t) = 1; - } - else - { - if (TREE_CODE (t) == VAR_DECL - && decl_name - && *IDENTIFIER_POINTER (decl_name) == '_') - return 0; - - need_indent = 1; - } - - /* Print the type and name. */ - if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) - { - if (need_indent) - INDENT (spc); - - /* Print variable's name. */ - dump_generic_ada_node (buffer, t, type, cpp_check, spc, false, true); - - if (TREE_CODE (t) == TYPE_DECL) - { - pp_string (buffer, " is "); - - if (orig && TYPE_NAME (orig) && orig != TREE_TYPE (t)) - dump_generic_ada_node - (buffer, TYPE_NAME (orig), type, - cpp_check, spc, false, true); - else - dump_ada_array_type (buffer, t, spc); - } - else - { - tree tmp = TYPE_NAME (TREE_TYPE (t)); - - if (spc == INDENT_INCR || TREE_STATIC (t)) - is_var = 1; - - pp_string (buffer, " : "); - - if (tmp) - { - if (TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE - && TREE_CODE (tmp) != INTEGER_TYPE) - pp_string (buffer, "aliased "); - - dump_generic_ada_node (buffer, tmp, type, 0, spc, false, true); - } - else - { - pp_string (buffer, "aliased "); - - if (!type) - dump_ada_array_type (buffer, t, spc); - else - dump_ada_double_name (buffer, type, t, "_array"); - } - } - } - else if (TREE_CODE (t) == FUNCTION_DECL) - { - bool is_function = true, is_method, is_abstract_class = false; - tree decl_name = DECL_NAME (t); - int prev_in_function = in_function; - bool is_abstract = false; - bool is_constructor = false; - bool is_destructor = false; - bool is_copy_constructor = false; - - if (!decl_name) - return 0; - - if (cpp_check) - { - is_abstract = cpp_check (t, IS_ABSTRACT); - is_constructor = cpp_check (t, IS_CONSTRUCTOR); - is_destructor = cpp_check (t, IS_DESTRUCTOR); - is_copy_constructor = cpp_check (t, IS_COPY_CONSTRUCTOR); - } - - /* Skip __comp_dtor destructor which is redundant with the '~class()' - destructor. */ - if (is_destructor - && !strncmp (IDENTIFIER_POINTER (decl_name), "__comp", 6)) - return 0; - - /* Skip copy constructors: some are internal only, and those that are - not cannot be called easily from Ada anyway. */ - if (is_copy_constructor) - return 0; - - /* If this function has an entry in the dispatch table, we cannot - omit it. */ - if (!DECL_VINDEX (t) && *IDENTIFIER_POINTER (decl_name) == '_') - { - if (IDENTIFIER_POINTER (decl_name)[1] == '_') - return 0; - - INDENT (spc); - pp_string (buffer, "-- skipped func "); - pp_string (buffer, IDENTIFIER_POINTER (decl_name)); - return 1; - } - - if (need_indent) - INDENT (spc); - - if (is_constructor) - pp_string (buffer, "function New_"); - else if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t)))) - { - is_function = false; - pp_string (buffer, "procedure "); - } - else - pp_string (buffer, "function "); - - in_function = is_function; - is_method = TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE; - - if (is_destructor) - print_destructor (buffer, t); - else - dump_ada_decl_name (buffer, t, false); - - dump_ada_function_declaration - (buffer, t, is_method, is_constructor, is_destructor, spc); - in_function = prev_in_function; - - if (is_function) - { - pp_string (buffer, " return "); - - if (is_constructor) - { - dump_ada_decl_name (buffer, t, false); - } - else - { - dump_generic_ada_node - (buffer, TREE_TYPE (TREE_TYPE (t)), type, cpp_check, - spc, false, true); - } - } - - if (is_constructor && cpp_check && type - && AGGREGATE_TYPE_P (type) - && TYPE_METHODS (type)) - { - tree tmp = TYPE_METHODS (type); - - for (; tmp; tmp = TREE_CHAIN (tmp)) - if (cpp_check (tmp, IS_ABSTRACT)) - { - is_abstract_class = 1; - break; - } - } - - if (is_abstract || is_abstract_class) - pp_string (buffer, " is abstract"); - - pp_semicolon (buffer); - pp_string (buffer, " -- "); - dump_sloc (buffer, t); - - if (is_abstract) - return 1; - - newline_and_indent (buffer, spc); - - if (is_constructor) - { - pp_string (buffer, "pragma CPP_Constructor (New_"); - dump_ada_decl_name (buffer, t, false); - pp_string (buffer, ", \""); - pp_asm_name (buffer, t); - pp_string (buffer, "\");"); - } - else if (is_destructor) - { - pp_string (buffer, "pragma Import (CPP, "); - print_destructor (buffer, t); - pp_string (buffer, ", \""); - pp_asm_name (buffer, t); - pp_string (buffer, "\");"); - } - else - { - dump_ada_import (buffer, t); - } - - return 1; - } - else if (TREE_CODE (t) == TYPE_DECL && !DECL_ORIGINAL_TYPE (t)) - { - int is_interface = 0; - int is_abstract_record = 0; - - if (need_indent) - INDENT (spc); - - /* Anonymous structs/unions */ - dump_generic_ada_node - (buffer, TREE_TYPE (t), t, cpp_check, spc, false, true); - - if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE - || TREE_CODE (TREE_TYPE (t)) == QUAL_UNION_TYPE) - { - pp_string (buffer, " (discr : unsigned := 0)"); - } - - pp_string (buffer, " is "); - - /* Check whether we have an Ada interface compatible class. */ - if (cpp_check && AGGREGATE_TYPE_P (TREE_TYPE (t)) - && TYPE_METHODS (TREE_TYPE (t))) - { - int num_fields = 0; - tree tmp = TYPE_FIELDS (TREE_TYPE (t)); - - /* Check that there are no fields other than the virtual table. */ - for (; tmp; tmp = TREE_CHAIN (tmp)) - { - if (TREE_CODE (tmp) == TYPE_DECL) - continue; - num_fields++; - } - - if (num_fields == 1) - is_interface = 1; - - /* Also check that there are only virtual methods. */ - for (tmp = TYPE_METHODS (TREE_TYPE (t)); tmp; tmp = TREE_CHAIN (tmp)) - { - if (cpp_check (tmp, IS_ABSTRACT)) - is_abstract_record = 1; - else - is_interface = 0; - } - } - - TREE_VISITED (t) = 1; - if (is_interface) - { - pp_string (buffer, "limited interface; -- "); - dump_sloc (buffer, t); - newline_and_indent (buffer, spc); - pp_string (buffer, "pragma Import (CPP, "); - dump_generic_ada_node - (buffer, TYPE_NAME (TREE_TYPE (t)), type, cpp_check, - spc, false, true); - pp_character (buffer, ')'); - - print_ada_methods (buffer, TREE_TYPE (t), cpp_check, spc); - } - else - { - if (is_abstract_record) - pp_string (buffer, "abstract "); - dump_generic_ada_node (buffer, t, t, cpp_check, spc, false, false); - } - } - else - { - if (need_indent) - INDENT (spc); - - if (TREE_CODE (t) == FIELD_DECL && DECL_NAME (t)) - check_name (buffer, t); - - /* Print variable/type's name. */ - dump_generic_ada_node (buffer, t, t, cpp_check, spc, false, true); - - if (TREE_CODE (t) == TYPE_DECL) - { - tree orig = DECL_ORIGINAL_TYPE (t); - int is_subtype = orig && TYPE_NAME (orig) && orig != TREE_TYPE (t); - - if (!is_subtype - && (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE - || TREE_CODE (TREE_TYPE (t)) == QUAL_UNION_TYPE)) - pp_string (buffer, " (discr : unsigned := 0)"); - - pp_string (buffer, " is "); - - dump_generic_ada_node - (buffer, orig, t, cpp_check, spc, false, is_subtype); - } - else - { - if (spc == INDENT_INCR || TREE_STATIC (t)) - is_var = 1; - - pp_string (buffer, " : "); - - /* Print type declaration. */ - - if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE - && !TYPE_NAME (TREE_TYPE (t))) - { - dump_ada_double_name (buffer, type, t, "_union"); - } - else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t))) - { - if (TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE) - pp_string (buffer, "aliased "); - - dump_generic_ada_node - (buffer, TREE_TYPE (t), t, cpp_check, spc, false, true); - } - else - { - if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE - && (TYPE_NAME (TREE_TYPE (t)) - || TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE)) - pp_string (buffer, "aliased "); - - dump_generic_ada_node - (buffer, TREE_TYPE (t), TREE_TYPE (t), cpp_check, - spc, false, true); - } - } - } - - if (is_class) - { - spc -= 3; - newline_and_indent (buffer, spc); - pp_string (buffer, "end;"); - newline_and_indent (buffer, spc); - pp_string (buffer, "use Class_"); - dump_generic_ada_node (buffer, t, type, 0, spc, false, true); - pp_semicolon (buffer); - pp_newline (buffer); - - /* All needed indentation/newline performed already, so return 0. */ - return 0; - } - else - { - pp_string (buffer, "; -- "); - dump_sloc (buffer, t); - } - - if (is_var) - { - newline_and_indent (buffer, spc); - dump_ada_import (buffer, t); - } - - return 1; -} - -/* Prints in BUFFER a structure NODE of type TYPE: name, fields, and methods - with Ada syntax. CPP_CHECK is used to perform C++ queries on nodes. SPC - is the indentation level. If DISPLAY_CONVENTION is true, also print the - pragma Convention for NODE. */ - -static void -print_ada_struct_decl (pretty_printer *buffer, tree node, tree type, - int (*cpp_check)(tree, cpp_operation), int spc, - bool display_convention) -{ - tree tmp; - int is_union = - TREE_CODE (node) == UNION_TYPE || TREE_CODE (node) == QUAL_UNION_TYPE; - char buf[32]; - int field_num = 0; - int field_spc = spc + INDENT_INCR; - int need_semicolon; - - bitfield_used = false; - - if (!TYPE_FIELDS (node)) - pp_string (buffer, "null record;"); - else - { - pp_string (buffer, "record"); - - /* Print the contents of the structure. */ - - if (is_union) - { - newline_and_indent (buffer, spc + INDENT_INCR); - pp_string (buffer, "case discr is"); - field_spc = spc + INDENT_INCR * 3; - } - - pp_newline (buffer); - - /* Print the non-static fields of the structure. */ - for (tmp = TYPE_FIELDS (node); tmp; tmp = TREE_CHAIN (tmp)) - { - /* Add parent field if needed. */ - if (!DECL_NAME (tmp)) - { - if (!is_tagged_type (TREE_TYPE (tmp))) - { - if (!TYPE_NAME (TREE_TYPE (tmp))) - print_ada_declaration - (buffer, tmp, type, cpp_check, field_spc); - else - { - INDENT (field_spc); - - if (field_num == 0) - pp_string (buffer, "parent : aliased "); - else - { - sprintf (buf, "field_%d : aliased ", field_num + 1); - pp_string (buffer, buf); - } - dump_ada_decl_name - (buffer, TYPE_NAME (TREE_TYPE (tmp)), false); - pp_semicolon (buffer); - } - pp_newline (buffer); - field_num++; - } - } - /* Avoid printing the structure recursively. */ - else if ((TREE_TYPE (tmp) != node - || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE - && TREE_TYPE (TREE_TYPE (tmp)) != node)) - && TREE_CODE (tmp) != TYPE_DECL - && !TREE_STATIC (tmp)) - { - /* Skip internal virtual table field. */ - if (strncmp (IDENTIFIER_POINTER (DECL_NAME (tmp)), "_vptr", 5)) - { - if (is_union) - { - if (TREE_CHAIN (tmp) - && TREE_TYPE (TREE_CHAIN (tmp)) != node - && TREE_CODE (TREE_CHAIN (tmp)) != TYPE_DECL) - sprintf (buf, "when %d =>", field_num); - else - sprintf (buf, "when others =>"); - - INDENT (spc + INDENT_INCR * 2); - pp_string (buffer, buf); - pp_newline (buffer); - } - - if (print_ada_declaration (buffer, - tmp, type, cpp_check, field_spc)) - { - pp_newline (buffer); - field_num++; - } - } - } - } - - if (is_union) - { - INDENT (spc + INDENT_INCR); - pp_string (buffer, "end case;"); - pp_newline (buffer); - } - - if (field_num == 0) - { - INDENT (spc + INDENT_INCR); - pp_string (buffer, "null;"); - pp_newline (buffer); - } - - INDENT (spc); - pp_string (buffer, "end record;"); - } - - newline_and_indent (buffer, spc); - - if (!display_convention) - return; - - if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type))) - { - if (TYPE_METHODS (TREE_TYPE (type))) - pp_string (buffer, "pragma Import (CPP, "); - else - pp_string (buffer, "pragma Convention (C_Pass_By_Copy, "); - } - else - pp_string (buffer, "pragma Convention (C, "); - - package_prefix = false; - dump_generic_ada_node - (buffer, TREE_TYPE (type), type, cpp_check, spc, false, true); - package_prefix = true; - pp_character (buffer, ')'); - - if (is_union) - { - pp_semicolon (buffer); - newline_and_indent (buffer, spc); - pp_string (buffer, "pragma Unchecked_Union ("); - - dump_generic_ada_node - (buffer, TREE_TYPE (type), type, cpp_check, spc, false, true); - pp_character (buffer, ')'); - } - - if (bitfield_used) - { - pp_semicolon (buffer); - newline_and_indent (buffer, spc); - pp_string (buffer, "pragma Pack ("); - dump_generic_ada_node - (buffer, TREE_TYPE (type), type, cpp_check, spc, false, true); - pp_character (buffer, ')'); - bitfield_used = false; - } - - print_ada_methods (buffer, node, cpp_check, spc); - - /* Print the static fields of the structure, if any. */ - need_semicolon = TYPE_METHODS (node) == NULL_TREE; - for (tmp = TYPE_FIELDS (node); tmp; tmp = TREE_CHAIN (tmp)) - { - if (DECL_NAME (tmp) && TREE_STATIC (tmp)) - { - if (need_semicolon) - { - need_semicolon = false; - pp_semicolon (buffer); - } - pp_newline (buffer); - pp_newline (buffer); - print_ada_declaration (buffer, tmp, type, cpp_check, spc); - } - } -} - -/* Dump all the declarations in SOURCE_FILE to an Ada spec. - COLLECT_ALL_REFS is a front-end callback used to collect all relevant - nodes for SOURCE_FILE. CPP_CHECK is used to perform C++ queries on - nodes. */ - -static void -dump_ads (const char *source_file, - void (*collect_all_refs)(const char *), - int (*cpp_check)(tree, cpp_operation)) -{ - char *ads_name; - char *pkg_name; - char *s; - FILE *f; - - pkg_name = get_ada_package (source_file); - - /* Construct the .ads filename and package name. */ - ads_name = xstrdup (pkg_name); - - for (s = ads_name; *s; s++) - if (*s == '.') - *s = '-'; - else - *s = TOLOWER (*s); - - ads_name = reconcat (ads_name, ads_name, ".ads", NULL); - - /* Write out the .ads file. */ - f = fopen (ads_name, "w"); - if (f) - { - pretty_printer pp; - - pp_construct (&pp, NULL, 0); - pp_needs_newline (&pp) = true; - pp.buffer->stream = f; - - /* Dump all relevant macros. */ - dump_ada_macros (&pp, source_file); - - /* Reset the table of withs for this file. */ - reset_ada_withs (); - - (*collect_all_refs) (source_file); - - /* Dump all references. */ - dump_ada_nodes (&pp, source_file, cpp_check); - - /* Requires Ada 2005 syntax, so generate corresponding pragma. - Also, disable style checks since this file is auto-generated. */ - fprintf (f, "pragma Ada_2005;\npragma Style_Checks (Off);\n\n"); - - /* Dump withs. */ - dump_ada_withs (f); - - fprintf (f, "\npackage %s is\n\n", pkg_name); - pp_write_text_to_stream (&pp); - /* ??? need to free pp */ - fprintf (f, "end %s;\n", pkg_name); - fclose (f); - } - - free (ads_name); - free (pkg_name); -} - -static const char **source_refs = NULL; -static int source_refs_used = 0; -static int source_refs_allocd = 0; - -/* Add an entry for FILENAME to the table SOURCE_REFS. */ - -void -collect_source_ref (const char *filename) -{ - int i; - - if (!filename) - return; - - if (source_refs_allocd == 0) - { - source_refs_allocd = 1024; - source_refs = XNEWVEC (const char *, source_refs_allocd); - } - - for (i = 0; i < source_refs_used; i++) - if (filename == source_refs[i]) - return; - - if (source_refs_used == source_refs_allocd) - { - source_refs_allocd *= 2; - source_refs = XRESIZEVEC (const char *, source_refs, source_refs_allocd); - } - - source_refs[source_refs_used++] = filename; -} - -/* Main entry point: dump all Ada specs corresponding to SOURCE_REFS - using callbacks COLLECT_ALL_REFS and CPP_CHECK. - COLLECT_ALL_REFS is a front-end callback used to collect all relevant - nodes for a given source file. - CPP_CHECK is used to perform C++ queries on nodes, or NULL for the C - front-end. */ - -void -dump_ada_specs (void (*collect_all_refs)(const char *), - int (*cpp_check)(tree, cpp_operation)) -{ - int i; - - /* Iterate over the list of files to dump specs for */ - for (i = 0; i < source_refs_used; i++) - dump_ads (source_refs[i], collect_all_refs, cpp_check); - - /* Free files table. */ - free (source_refs); -} diff --git a/gcc-4.8.1/gcc/c-family/c-ada-spec.h b/gcc-4.8.1/gcc/c-family/c-ada-spec.h deleted file mode 100644 index 0bc249f8f..000000000 --- a/gcc-4.8.1/gcc/c-family/c-ada-spec.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Interface for -fdump-ada-spec capability. - Copyright (C) 2010-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#ifndef C_ADA_SPEC_H -#define C_ADA_SPEC_H - -#include "pretty-print.h" - -/* In c-ada-spec.c */ - -typedef enum { - IS_ABSTRACT, - IS_CONSTRUCTOR, - IS_DESTRUCTOR, - IS_COPY_CONSTRUCTOR, - IS_TEMPLATE -} cpp_operation; - -extern location_t decl_sloc (const_tree, bool); -extern void collect_ada_nodes (tree, const char *); -extern void collect_source_ref (const char *); -extern void dump_ada_specs (void (*)(const char *), - int (*)(tree, cpp_operation)); - -#endif /* ! C_ADA_SPEC_H */ diff --git a/gcc-4.8.1/gcc/c-family/c-common.c b/gcc-4.8.1/gcc/c-family/c-common.c deleted file mode 100644 index 0d91cc3cf..000000000 --- a/gcc-4.8.1/gcc/c-family/c-common.c +++ /dev/null @@ -1,11598 +0,0 @@ -/* Subroutines shared by all languages that are variants of C. - Copyright (C) 1992-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "intl.h" -#include "tree.h" -#include "flags.h" -#include "c-pragma.h" -#include "ggc.h" -#include "c-common.h" -#include "c-objc.h" -#include "tm_p.h" -#include "obstack.h" -#include "cpplib.h" -#include "target.h" -#include "common/common-target.h" -#include "langhooks.h" -#include "tree-inline.h" -#include "toplev.h" -#include "diagnostic.h" -#include "tree-iterator.h" -#include "hashtab.h" -#include "tree-mudflap.h" -#include "opts.h" -#include "cgraph.h" -#include "target-def.h" - -cpp_reader *parse_in; /* Declared in c-pragma.h. */ - -/* The following symbols are subsumed in the c_global_trees array, and - listed here individually for documentation purposes. - - INTEGER_TYPE and REAL_TYPE nodes for the standard data types. - - tree short_integer_type_node; - tree long_integer_type_node; - tree long_long_integer_type_node; - tree int128_integer_type_node; - - tree short_unsigned_type_node; - tree long_unsigned_type_node; - tree long_long_unsigned_type_node; - tree int128_unsigned_type_node; - - tree truthvalue_type_node; - tree truthvalue_false_node; - tree truthvalue_true_node; - - tree ptrdiff_type_node; - - tree unsigned_char_type_node; - tree signed_char_type_node; - tree wchar_type_node; - - tree char16_type_node; - tree char32_type_node; - - tree float_type_node; - tree double_type_node; - tree long_double_type_node; - - tree complex_integer_type_node; - tree complex_float_type_node; - tree complex_double_type_node; - tree complex_long_double_type_node; - - tree dfloat32_type_node; - tree dfloat64_type_node; - tree_dfloat128_type_node; - - tree intQI_type_node; - tree intHI_type_node; - tree intSI_type_node; - tree intDI_type_node; - tree intTI_type_node; - - tree unsigned_intQI_type_node; - tree unsigned_intHI_type_node; - tree unsigned_intSI_type_node; - tree unsigned_intDI_type_node; - tree unsigned_intTI_type_node; - - tree widest_integer_literal_type_node; - tree widest_unsigned_literal_type_node; - - Nodes for types `void *' and `const void *'. - - tree ptr_type_node, const_ptr_type_node; - - Nodes for types `char *' and `const char *'. - - tree string_type_node, const_string_type_node; - - Type `char[SOMENUMBER]'. - Used when an array of char is needed and the size is irrelevant. - - tree char_array_type_node; - - Type `int[SOMENUMBER]' or something like it. - Used when an array of int needed and the size is irrelevant. - - tree int_array_type_node; - - Type `wchar_t[SOMENUMBER]' or something like it. - Used when a wide string literal is created. - - tree wchar_array_type_node; - - Type `char16_t[SOMENUMBER]' or something like it. - Used when a UTF-16 string literal is created. - - tree char16_array_type_node; - - Type `char32_t[SOMENUMBER]' or something like it. - Used when a UTF-32 string literal is created. - - tree char32_array_type_node; - - Type `int ()' -- used for implicit declaration of functions. - - tree default_function_type; - - A VOID_TYPE node, packaged in a TREE_LIST. - - tree void_list_node; - - The lazily created VAR_DECLs for __FUNCTION__, __PRETTY_FUNCTION__, - and __func__. (C doesn't generate __FUNCTION__ and__PRETTY_FUNCTION__ - VAR_DECLS, but C++ does.) - - tree function_name_decl_node; - tree pretty_function_name_decl_node; - tree c99_function_name_decl_node; - - Stack of nested function name VAR_DECLs. - - tree saved_function_name_decls; - -*/ - -tree c_global_trees[CTI_MAX]; - -/* Switches common to the C front ends. */ - -/* Nonzero means don't output line number information. */ - -char flag_no_line_commands; - -/* Nonzero causes -E output not to be done, but directives such as - #define that have side effects are still obeyed. */ - -char flag_no_output; - -/* Nonzero means dump macros in some fashion. */ - -char flag_dump_macros; - -/* Nonzero means pass #include lines through to the output. */ - -char flag_dump_includes; - -/* Nonzero means process PCH files while preprocessing. */ - -bool flag_pch_preprocess; - -/* The file name to which we should write a precompiled header, or - NULL if no header will be written in this compile. */ - -const char *pch_file; - -/* Nonzero if an ISO standard was selected. It rejects macros in the - user's namespace. */ -int flag_iso; - -/* C/ObjC language option variables. */ - - -/* Nonzero means allow type mismatches in conditional expressions; - just make their values `void'. */ - -int flag_cond_mismatch; - -/* Nonzero means enable C89 Amendment 1 features. */ - -int flag_isoc94; - -/* Nonzero means use the ISO C99 (or C11) dialect of C. */ - -int flag_isoc99; - -/* Nonzero means use the ISO C11 dialect of C. */ - -int flag_isoc11; - -/* Nonzero means that we have builtin functions, and main is an int. */ - -int flag_hosted = 1; - - -/* ObjC language option variables. */ - - -/* Tells the compiler that this is a special run. Do not perform any - compiling, instead we are to test some platform dependent features - and output a C header file with appropriate definitions. */ - -int print_struct_values; - -/* Tells the compiler what is the constant string class for ObjC. */ - -const char *constant_string_class_name; - - -/* C++ language option variables. */ - - -/* Nonzero means generate separate instantiation control files and - juggle them at link time. */ - -int flag_use_repository; - -/* The C++ dialect being used. C++98 is the default. */ - -enum cxx_dialect cxx_dialect = cxx98; - -/* Maximum template instantiation depth. This limit exists to limit the - time it takes to notice excessively recursive template instantiations. - - The default is lower than the 1024 recommended by the C++0x standard - because G++ runs out of stack before 1024 with highly recursive template - argument deduction substitution (g++.dg/cpp0x/enum11.C). */ - -int max_tinst_depth = 900; - -/* The elements of `ridpointers' are identifier nodes for the reserved - type names and storage classes. It is indexed by a RID_... value. */ -tree *ridpointers; - -tree (*make_fname_decl) (location_t, tree, int); - -/* Nonzero means don't warn about problems that occur when the code is - executed. */ -int c_inhibit_evaluation_warnings; - -/* Whether we are building a boolean conversion inside - convert_for_assignment, or some other late binary operation. If - build_binary_op is called for C (from code shared by C and C++) in - this case, then the operands have already been folded and the - result will not be folded again, so C_MAYBE_CONST_EXPR should not - be generated. */ -bool in_late_binary_op; - -/* Whether lexing has been completed, so subsequent preprocessor - errors should use the compiler's input_location. */ -bool done_lexing = false; - -/* Information about how a function name is generated. */ -struct fname_var_t -{ - tree *const decl; /* pointer to the VAR_DECL. */ - const unsigned rid; /* RID number for the identifier. */ - const int pretty; /* How pretty is it? */ -}; - -/* The three ways of getting then name of the current function. */ - -const struct fname_var_t fname_vars[] = -{ - /* C99 compliant __func__, must be first. */ - {&c99_function_name_decl_node, RID_C99_FUNCTION_NAME, 0}, - /* GCC __FUNCTION__ compliant. */ - {&function_name_decl_node, RID_FUNCTION_NAME, 0}, - /* GCC __PRETTY_FUNCTION__ compliant. */ - {&pretty_function_name_decl_node, RID_PRETTY_FUNCTION_NAME, 1}, - {NULL, 0, 0}, -}; - -/* Global visibility options. */ -struct visibility_flags visibility_options; - -static tree c_fully_fold_internal (tree expr, bool, bool *, bool *); -static tree check_case_value (tree); -static bool check_case_bounds (tree, tree, tree *, tree *); - -static tree handle_packed_attribute (tree *, tree, tree, int, bool *); -static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *); -static tree handle_common_attribute (tree *, tree, tree, int, bool *); -static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *); -static tree handle_hot_attribute (tree *, tree, tree, int, bool *); -static tree handle_cold_attribute (tree *, tree, tree, int, bool *); -static tree handle_no_sanitize_address_attribute (tree *, tree, tree, - int, bool *); -static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree, - int, bool *); -static tree handle_noinline_attribute (tree *, tree, tree, int, bool *); -static tree handle_noclone_attribute (tree *, tree, tree, int, bool *); -static tree handle_leaf_attribute (tree *, tree, tree, int, bool *); -static tree handle_always_inline_attribute (tree *, tree, tree, int, - bool *); -static tree handle_gnu_inline_attribute (tree *, tree, tree, int, bool *); -static tree handle_artificial_attribute (tree *, tree, tree, int, bool *); -static tree handle_flatten_attribute (tree *, tree, tree, int, bool *); -static tree handle_error_attribute (tree *, tree, tree, int, bool *); -static tree handle_used_attribute (tree *, tree, tree, int, bool *); -static tree handle_unused_attribute (tree *, tree, tree, int, bool *); -static tree handle_externally_visible_attribute (tree *, tree, tree, int, - bool *); -static tree handle_const_attribute (tree *, tree, tree, int, bool *); -static tree handle_transparent_union_attribute (tree *, tree, tree, - int, bool *); -static tree handle_constructor_attribute (tree *, tree, tree, int, bool *); -static tree handle_destructor_attribute (tree *, tree, tree, int, bool *); -static tree handle_mode_attribute (tree *, tree, tree, int, bool *); -static tree handle_section_attribute (tree *, tree, tree, int, bool *); -static tree handle_aligned_attribute (tree *, tree, tree, int, bool *); -static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ; -static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *); -static tree handle_ifunc_attribute (tree *, tree, tree, int, bool *); -static tree handle_alias_attribute (tree *, tree, tree, int, bool *); -static tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ; -static tree handle_visibility_attribute (tree *, tree, tree, int, - bool *); -static tree handle_tls_model_attribute (tree *, tree, tree, int, - bool *); -static tree handle_no_instrument_function_attribute (tree *, tree, - tree, int, bool *); -static tree handle_malloc_attribute (tree *, tree, tree, int, bool *); -static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *); -static tree handle_no_limit_stack_attribute (tree *, tree, tree, int, - bool *); -static tree handle_pure_attribute (tree *, tree, tree, int, bool *); -static tree handle_tm_attribute (tree *, tree, tree, int, bool *); -static tree handle_tm_wrap_attribute (tree *, tree, tree, int, bool *); -static tree handle_novops_attribute (tree *, tree, tree, int, bool *); -static tree handle_deprecated_attribute (tree *, tree, tree, int, - bool *); -static tree handle_vector_size_attribute (tree *, tree, tree, int, - bool *); -static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *); -static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *); -static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *); -static tree handle_warn_unused_result_attribute (tree *, tree, tree, int, - bool *); -static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *); -static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *); -static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *); -static tree handle_target_attribute (tree *, tree, tree, int, bool *); -static tree handle_optimize_attribute (tree *, tree, tree, int, bool *); -static tree ignore_attribute (tree *, tree, tree, int, bool *); -static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *); -static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *); - -static void check_function_nonnull (tree, int, tree *); -static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT); -static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT); -static bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *); -static int resort_field_decl_cmp (const void *, const void *); - -/* Reserved words. The third field is a mask: keywords are disabled - if they match the mask. - - Masks for languages: - C --std=c89: D_C99 | D_CXXONLY | D_OBJC | D_CXX_OBJC - C --std=c99: D_CXXONLY | D_OBJC - ObjC is like C except that D_OBJC and D_CXX_OBJC are not set - C++ --std=c98: D_CONLY | D_CXXOX | D_OBJC - C++ --std=c0x: D_CONLY | D_OBJC - ObjC++ is like C++ except that D_OBJC is not set - - If -fno-asm is used, D_ASM is added to the mask. If - -fno-gnu-keywords is used, D_EXT is added. If -fno-asm and C in - C89 mode, D_EXT89 is added for both -fno-asm and -fno-gnu-keywords. - In C with -Wc++-compat, we warn if D_CXXWARN is set. - - Note the complication of the D_CXX_OBJC keywords. These are - reserved words such as 'class'. In C++, 'class' is a reserved - word. In Objective-C++ it is too. In Objective-C, it is a - reserved word too, but only if it follows an '@' sign. -*/ -const struct c_common_resword c_common_reswords[] = -{ - { "_Alignas", RID_ALIGNAS, D_CONLY }, - { "_Alignof", RID_ALIGNOF, D_CONLY }, - { "_Bool", RID_BOOL, D_CONLY }, - { "_Complex", RID_COMPLEX, 0 }, - { "_Imaginary", RID_IMAGINARY, D_CONLY }, - { "_Decimal32", RID_DFLOAT32, D_CONLY | D_EXT }, - { "_Decimal64", RID_DFLOAT64, D_CONLY | D_EXT }, - { "_Decimal128", RID_DFLOAT128, D_CONLY | D_EXT }, - { "_Fract", RID_FRACT, D_CONLY | D_EXT }, - { "_Accum", RID_ACCUM, D_CONLY | D_EXT }, - { "_Sat", RID_SAT, D_CONLY | D_EXT }, - { "_Static_assert", RID_STATIC_ASSERT, D_CONLY }, - { "_Noreturn", RID_NORETURN, D_CONLY }, - { "__FUNCTION__", RID_FUNCTION_NAME, 0 }, - { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 }, - { "__alignof", RID_ALIGNOF, 0 }, - { "__alignof__", RID_ALIGNOF, 0 }, - { "__asm", RID_ASM, 0 }, - { "__asm__", RID_ASM, 0 }, - { "__attribute", RID_ATTRIBUTE, 0 }, - { "__attribute__", RID_ATTRIBUTE, 0 }, - { "__bases", RID_BASES, D_CXXONLY }, - { "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY }, - { "__builtin_complex", RID_BUILTIN_COMPLEX, D_CONLY }, - { "__builtin_shuffle", RID_BUILTIN_SHUFFLE, 0 }, - { "__builtin_offsetof", RID_OFFSETOF, 0 }, - { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY }, - { "__builtin_va_arg", RID_VA_ARG, 0 }, - { "__complex", RID_COMPLEX, 0 }, - { "__complex__", RID_COMPLEX, 0 }, - { "__const", RID_CONST, 0 }, - { "__const__", RID_CONST, 0 }, - { "__decltype", RID_DECLTYPE, D_CXXONLY }, - { "__direct_bases", RID_DIRECT_BASES, D_CXXONLY }, - { "__extension__", RID_EXTENSION, 0 }, - { "__func__", RID_C99_FUNCTION_NAME, 0 }, - { "__has_nothrow_assign", RID_HAS_NOTHROW_ASSIGN, D_CXXONLY }, - { "__has_nothrow_constructor", RID_HAS_NOTHROW_CONSTRUCTOR, D_CXXONLY }, - { "__has_nothrow_copy", RID_HAS_NOTHROW_COPY, D_CXXONLY }, - { "__has_trivial_assign", RID_HAS_TRIVIAL_ASSIGN, D_CXXONLY }, - { "__has_trivial_constructor", RID_HAS_TRIVIAL_CONSTRUCTOR, D_CXXONLY }, - { "__has_trivial_copy", RID_HAS_TRIVIAL_COPY, D_CXXONLY }, - { "__has_trivial_destructor", RID_HAS_TRIVIAL_DESTRUCTOR, D_CXXONLY }, - { "__has_virtual_destructor", RID_HAS_VIRTUAL_DESTRUCTOR, D_CXXONLY }, - { "__imag", RID_IMAGPART, 0 }, - { "__imag__", RID_IMAGPART, 0 }, - { "__inline", RID_INLINE, 0 }, - { "__inline__", RID_INLINE, 0 }, - { "__int128", RID_INT128, 0 }, - { "__is_abstract", RID_IS_ABSTRACT, D_CXXONLY }, - { "__is_base_of", RID_IS_BASE_OF, D_CXXONLY }, - { "__is_class", RID_IS_CLASS, D_CXXONLY }, - { "__is_convertible_to", RID_IS_CONVERTIBLE_TO, D_CXXONLY }, - { "__is_empty", RID_IS_EMPTY, D_CXXONLY }, - { "__is_enum", RID_IS_ENUM, D_CXXONLY }, - { "__is_final", RID_IS_FINAL, D_CXXONLY }, - { "__is_literal_type", RID_IS_LITERAL_TYPE, D_CXXONLY }, - { "__is_pod", RID_IS_POD, D_CXXONLY }, - { "__is_polymorphic", RID_IS_POLYMORPHIC, D_CXXONLY }, - { "__is_standard_layout", RID_IS_STD_LAYOUT, D_CXXONLY }, - { "__is_trivial", RID_IS_TRIVIAL, D_CXXONLY }, - { "__is_union", RID_IS_UNION, D_CXXONLY }, - { "__label__", RID_LABEL, 0 }, - { "__null", RID_NULL, 0 }, - { "__real", RID_REALPART, 0 }, - { "__real__", RID_REALPART, 0 }, - { "__restrict", RID_RESTRICT, 0 }, - { "__restrict__", RID_RESTRICT, 0 }, - { "__signed", RID_SIGNED, 0 }, - { "__signed__", RID_SIGNED, 0 }, - { "__thread", RID_THREAD, 0 }, - { "__transaction_atomic", RID_TRANSACTION_ATOMIC, 0 }, - { "__transaction_relaxed", RID_TRANSACTION_RELAXED, 0 }, - { "__transaction_cancel", RID_TRANSACTION_CANCEL, 0 }, - { "__typeof", RID_TYPEOF, 0 }, - { "__typeof__", RID_TYPEOF, 0 }, - { "__underlying_type", RID_UNDERLYING_TYPE, D_CXXONLY }, - { "__volatile", RID_VOLATILE, 0 }, - { "__volatile__", RID_VOLATILE, 0 }, - { "alignas", RID_ALIGNAS, D_CXXONLY | D_CXX0X | D_CXXWARN }, - { "alignof", RID_ALIGNOF, D_CXXONLY | D_CXX0X | D_CXXWARN }, - { "asm", RID_ASM, D_ASM }, - { "auto", RID_AUTO, 0 }, - { "bool", RID_BOOL, D_CXXONLY | D_CXXWARN }, - { "break", RID_BREAK, 0 }, - { "case", RID_CASE, 0 }, - { "catch", RID_CATCH, D_CXX_OBJC | D_CXXWARN }, - { "char", RID_CHAR, 0 }, - { "char16_t", RID_CHAR16, D_CXXONLY | D_CXX0X | D_CXXWARN }, - { "char32_t", RID_CHAR32, D_CXXONLY | D_CXX0X | D_CXXWARN }, - { "class", RID_CLASS, D_CXX_OBJC | D_CXXWARN }, - { "const", RID_CONST, 0 }, - { "constexpr", RID_CONSTEXPR, D_CXXONLY | D_CXX0X | D_CXXWARN }, - { "const_cast", RID_CONSTCAST, D_CXXONLY | D_CXXWARN }, - { "continue", RID_CONTINUE, 0 }, - { "decltype", RID_DECLTYPE, D_CXXONLY | D_CXX0X | D_CXXWARN }, - { "default", RID_DEFAULT, 0 }, - { "delete", RID_DELETE, D_CXXONLY | D_CXXWARN }, - { "do", RID_DO, 0 }, - { "double", RID_DOUBLE, 0 }, - { "dynamic_cast", RID_DYNCAST, D_CXXONLY | D_CXXWARN }, - { "else", RID_ELSE, 0 }, - { "enum", RID_ENUM, 0 }, - { "explicit", RID_EXPLICIT, D_CXXONLY | D_CXXWARN }, - { "export", RID_EXPORT, D_CXXONLY | D_CXXWARN }, - { "extern", RID_EXTERN, 0 }, - { "false", RID_FALSE, D_CXXONLY | D_CXXWARN }, - { "float", RID_FLOAT, 0 }, - { "for", RID_FOR, 0 }, - { "friend", RID_FRIEND, D_CXXONLY | D_CXXWARN }, - { "goto", RID_GOTO, 0 }, - { "if", RID_IF, 0 }, - { "inline", RID_INLINE, D_EXT89 }, - { "int", RID_INT, 0 }, - { "long", RID_LONG, 0 }, - { "mutable", RID_MUTABLE, D_CXXONLY | D_CXXWARN }, - { "namespace", RID_NAMESPACE, D_CXXONLY | D_CXXWARN }, - { "new", RID_NEW, D_CXXONLY | D_CXXWARN }, - { "noexcept", RID_NOEXCEPT, D_CXXONLY | D_CXX0X | D_CXXWARN }, - { "nullptr", RID_NULLPTR, D_CXXONLY | D_CXX0X | D_CXXWARN }, - { "operator", RID_OPERATOR, D_CXXONLY | D_CXXWARN }, - { "private", RID_PRIVATE, D_CXX_OBJC | D_CXXWARN }, - { "protected", RID_PROTECTED, D_CXX_OBJC | D_CXXWARN }, - { "public", RID_PUBLIC, D_CXX_OBJC | D_CXXWARN }, - { "register", RID_REGISTER, 0 }, - { "reinterpret_cast", RID_REINTCAST, D_CXXONLY | D_CXXWARN }, - { "restrict", RID_RESTRICT, D_CONLY | D_C99 }, - { "return", RID_RETURN, 0 }, - { "short", RID_SHORT, 0 }, - { "signed", RID_SIGNED, 0 }, - { "sizeof", RID_SIZEOF, 0 }, - { "static", RID_STATIC, 0 }, - { "static_assert", RID_STATIC_ASSERT, D_CXXONLY | D_CXX0X | D_CXXWARN }, - { "static_cast", RID_STATCAST, D_CXXONLY | D_CXXWARN }, - { "struct", RID_STRUCT, 0 }, - { "switch", RID_SWITCH, 0 }, - { "template", RID_TEMPLATE, D_CXXONLY | D_CXXWARN }, - { "this", RID_THIS, D_CXXONLY | D_CXXWARN }, - { "thread_local", RID_THREAD, D_CXXONLY | D_CXX0X | D_CXXWARN }, - { "throw", RID_THROW, D_CXX_OBJC | D_CXXWARN }, - { "true", RID_TRUE, D_CXXONLY | D_CXXWARN }, - { "try", RID_TRY, D_CXX_OBJC | D_CXXWARN }, - { "typedef", RID_TYPEDEF, 0 }, - { "typename", RID_TYPENAME, D_CXXONLY | D_CXXWARN }, - { "typeid", RID_TYPEID, D_CXXONLY | D_CXXWARN }, - { "typeof", RID_TYPEOF, D_ASM | D_EXT }, - { "union", RID_UNION, 0 }, - { "unsigned", RID_UNSIGNED, 0 }, - { "using", RID_USING, D_CXXONLY | D_CXXWARN }, - { "virtual", RID_VIRTUAL, D_CXXONLY | D_CXXWARN }, - { "void", RID_VOID, 0 }, - { "volatile", RID_VOLATILE, 0 }, - { "wchar_t", RID_WCHAR, D_CXXONLY }, - { "while", RID_WHILE, 0 }, - /* These Objective-C keywords are recognized only immediately after - an '@'. */ - { "compatibility_alias", RID_AT_ALIAS, D_OBJC }, - { "defs", RID_AT_DEFS, D_OBJC }, - { "encode", RID_AT_ENCODE, D_OBJC }, - { "end", RID_AT_END, D_OBJC }, - { "implementation", RID_AT_IMPLEMENTATION, D_OBJC }, - { "interface", RID_AT_INTERFACE, D_OBJC }, - { "protocol", RID_AT_PROTOCOL, D_OBJC }, - { "selector", RID_AT_SELECTOR, D_OBJC }, - { "finally", RID_AT_FINALLY, D_OBJC }, - { "synchronized", RID_AT_SYNCHRONIZED, D_OBJC }, - { "optional", RID_AT_OPTIONAL, D_OBJC }, - { "required", RID_AT_REQUIRED, D_OBJC }, - { "property", RID_AT_PROPERTY, D_OBJC }, - { "package", RID_AT_PACKAGE, D_OBJC }, - { "synthesize", RID_AT_SYNTHESIZE, D_OBJC }, - { "dynamic", RID_AT_DYNAMIC, D_OBJC }, - /* These are recognized only in protocol-qualifier context - (see above) */ - { "bycopy", RID_BYCOPY, D_OBJC }, - { "byref", RID_BYREF, D_OBJC }, - { "in", RID_IN, D_OBJC }, - { "inout", RID_INOUT, D_OBJC }, - { "oneway", RID_ONEWAY, D_OBJC }, - { "out", RID_OUT, D_OBJC }, - /* These are recognized inside a property attribute list */ - { "assign", RID_ASSIGN, D_OBJC }, - { "copy", RID_COPY, D_OBJC }, - { "getter", RID_GETTER, D_OBJC }, - { "nonatomic", RID_NONATOMIC, D_OBJC }, - { "readonly", RID_READONLY, D_OBJC }, - { "readwrite", RID_READWRITE, D_OBJC }, - { "retain", RID_RETAIN, D_OBJC }, - { "setter", RID_SETTER, D_OBJC }, -}; - -const unsigned int num_c_common_reswords = - sizeof c_common_reswords / sizeof (struct c_common_resword); - -/* Table of machine-independent attributes common to all C-like languages. */ -const struct attribute_spec c_common_attribute_table[] = -{ - /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, - affects_type_identity } */ - { "packed", 0, 0, false, false, false, - handle_packed_attribute , false}, - { "nocommon", 0, 0, true, false, false, - handle_nocommon_attribute, false}, - { "common", 0, 0, true, false, false, - handle_common_attribute, false }, - /* FIXME: logically, noreturn attributes should be listed as - "false, true, true" and apply to function types. But implementing this - would require all the places in the compiler that use TREE_THIS_VOLATILE - on a decl to identify non-returning functions to be located and fixed - to check the function type instead. */ - { "noreturn", 0, 0, true, false, false, - handle_noreturn_attribute, false }, - { "volatile", 0, 0, true, false, false, - handle_noreturn_attribute, false }, - { "noinline", 0, 0, true, false, false, - handle_noinline_attribute, false }, - { "noclone", 0, 0, true, false, false, - handle_noclone_attribute, false }, - { "leaf", 0, 0, true, false, false, - handle_leaf_attribute, false }, - { "always_inline", 0, 0, true, false, false, - handle_always_inline_attribute, false }, - { "gnu_inline", 0, 0, true, false, false, - handle_gnu_inline_attribute, false }, - { "artificial", 0, 0, true, false, false, - handle_artificial_attribute, false }, - { "flatten", 0, 0, true, false, false, - handle_flatten_attribute, false }, - { "used", 0, 0, true, false, false, - handle_used_attribute, false }, - { "unused", 0, 0, false, false, false, - handle_unused_attribute, false }, - { "externally_visible", 0, 0, true, false, false, - handle_externally_visible_attribute, false }, - /* The same comments as for noreturn attributes apply to const ones. */ - { "const", 0, 0, true, false, false, - handle_const_attribute, false }, - { "transparent_union", 0, 0, false, false, false, - handle_transparent_union_attribute, false }, - { "constructor", 0, 1, true, false, false, - handle_constructor_attribute, false }, - { "destructor", 0, 1, true, false, false, - handle_destructor_attribute, false }, - { "mode", 1, 1, false, true, false, - handle_mode_attribute, false }, - { "section", 1, 1, true, false, false, - handle_section_attribute, false }, - { "aligned", 0, 1, false, false, false, - handle_aligned_attribute, false }, - { "weak", 0, 0, true, false, false, - handle_weak_attribute, false }, - { "ifunc", 1, 1, true, false, false, - handle_ifunc_attribute, false }, - { "alias", 1, 1, true, false, false, - handle_alias_attribute, false }, - { "weakref", 0, 1, true, false, false, - handle_weakref_attribute, false }, - { "no_instrument_function", 0, 0, true, false, false, - handle_no_instrument_function_attribute, - false }, - { "malloc", 0, 0, true, false, false, - handle_malloc_attribute, false }, - { "returns_twice", 0, 0, true, false, false, - handle_returns_twice_attribute, false }, - { "no_stack_limit", 0, 0, true, false, false, - handle_no_limit_stack_attribute, false }, - { "pure", 0, 0, true, false, false, - handle_pure_attribute, false }, - { "transaction_callable", 0, 0, false, true, false, - handle_tm_attribute, false }, - { "transaction_unsafe", 0, 0, false, true, false, - handle_tm_attribute, false }, - { "transaction_safe", 0, 0, false, true, false, - handle_tm_attribute, false }, - { "transaction_may_cancel_outer", 0, 0, false, true, false, - handle_tm_attribute, false }, - /* ??? These two attributes didn't make the transition from the - Intel language document to the multi-vendor language document. */ - { "transaction_pure", 0, 0, false, true, false, - handle_tm_attribute, false }, - { "transaction_wrap", 1, 1, true, false, false, - handle_tm_wrap_attribute, false }, - /* For internal use (marking of builtins) only. The name contains space - to prevent its usage in source code. */ - { "no vops", 0, 0, true, false, false, - handle_novops_attribute, false }, - { "deprecated", 0, 1, false, false, false, - handle_deprecated_attribute, false }, - { "vector_size", 1, 1, false, true, false, - handle_vector_size_attribute, false }, - { "visibility", 1, 1, false, false, false, - handle_visibility_attribute, false }, - { "tls_model", 1, 1, true, false, false, - handle_tls_model_attribute, false }, - { "nonnull", 0, -1, false, true, true, - handle_nonnull_attribute, false }, - { "nothrow", 0, 0, true, false, false, - handle_nothrow_attribute, false }, - { "may_alias", 0, 0, false, true, false, NULL, false }, - { "cleanup", 1, 1, true, false, false, - handle_cleanup_attribute, false }, - { "warn_unused_result", 0, 0, false, true, true, - handle_warn_unused_result_attribute, false }, - { "sentinel", 0, 1, false, true, true, - handle_sentinel_attribute, false }, - /* For internal use (marking of builtins) only. The name contains space - to prevent its usage in source code. */ - { "type generic", 0, 0, false, true, true, - handle_type_generic_attribute, false }, - { "alloc_size", 1, 2, false, true, true, - handle_alloc_size_attribute, false }, - { "cold", 0, 0, true, false, false, - handle_cold_attribute, false }, - { "hot", 0, 0, true, false, false, - handle_hot_attribute, false }, - { "no_address_safety_analysis", - 0, 0, true, false, false, - handle_no_address_safety_analysis_attribute, - false }, - { "no_sanitize_address", 0, 0, true, false, false, - handle_no_sanitize_address_attribute, - false }, - { "warning", 1, 1, true, false, false, - handle_error_attribute, false }, - { "error", 1, 1, true, false, false, - handle_error_attribute, false }, - { "target", 1, -1, true, false, false, - handle_target_attribute, false }, - { "optimize", 1, -1, true, false, false, - handle_optimize_attribute, false }, - /* For internal use only. The leading '*' both prevents its usage in - source code and signals that it may be overridden by machine tables. */ - { "*tm regparm", 0, 0, false, true, true, - ignore_attribute, false }, - { "no_split_stack", 0, 0, true, false, false, - handle_no_split_stack_attribute, false }, - /* For internal use (marking of builtins and runtime functions) only. - The name contains space to prevent its usage in source code. */ - { "fn spec", 1, 1, false, true, true, - handle_fnspec_attribute, false }, - { NULL, 0, 0, false, false, false, NULL, false } -}; - -/* Give the specifications for the format attributes, used by C and all - descendants. */ - -const struct attribute_spec c_common_format_attribute_table[] = -{ - /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, - affects_type_identity } */ - { "format", 3, 3, false, true, true, - handle_format_attribute, false }, - { "format_arg", 1, 1, false, true, true, - handle_format_arg_attribute, false }, - { NULL, 0, 0, false, false, false, NULL, false } -}; - -/* Return identifier for address space AS. */ - -const char * -c_addr_space_name (addr_space_t as) -{ - int rid = RID_FIRST_ADDR_SPACE + as; - gcc_assert (ridpointers [rid]); - return IDENTIFIER_POINTER (ridpointers [rid]); -} - -/* Push current bindings for the function name VAR_DECLS. */ - -void -start_fname_decls (void) -{ - unsigned ix; - tree saved = NULL_TREE; - - for (ix = 0; fname_vars[ix].decl; ix++) - { - tree decl = *fname_vars[ix].decl; - - if (decl) - { - saved = tree_cons (decl, build_int_cst (integer_type_node, ix), - saved); - *fname_vars[ix].decl = NULL_TREE; - } - } - if (saved || saved_function_name_decls) - /* Normally they'll have been NULL, so only push if we've got a - stack, or they are non-NULL. */ - saved_function_name_decls = tree_cons (saved, NULL_TREE, - saved_function_name_decls); -} - -/* Finish up the current bindings, adding them into the current function's - statement tree. This must be done _before_ finish_stmt_tree is called. - If there is no current function, we must be at file scope and no statements - are involved. Pop the previous bindings. */ - -void -finish_fname_decls (void) -{ - unsigned ix; - tree stmts = NULL_TREE; - tree stack = saved_function_name_decls; - - for (; stack && TREE_VALUE (stack); stack = TREE_CHAIN (stack)) - append_to_statement_list (TREE_VALUE (stack), &stmts); - - if (stmts) - { - tree *bodyp = &DECL_SAVED_TREE (current_function_decl); - - if (TREE_CODE (*bodyp) == BIND_EXPR) - bodyp = &BIND_EXPR_BODY (*bodyp); - - append_to_statement_list_force (*bodyp, &stmts); - *bodyp = stmts; - } - - for (ix = 0; fname_vars[ix].decl; ix++) - *fname_vars[ix].decl = NULL_TREE; - - if (stack) - { - /* We had saved values, restore them. */ - tree saved; - - for (saved = TREE_PURPOSE (stack); saved; saved = TREE_CHAIN (saved)) - { - tree decl = TREE_PURPOSE (saved); - unsigned ix = TREE_INT_CST_LOW (TREE_VALUE (saved)); - - *fname_vars[ix].decl = decl; - } - stack = TREE_CHAIN (stack); - } - saved_function_name_decls = stack; -} - -/* Return the text name of the current function, suitably prettified - by PRETTY_P. Return string must be freed by caller. */ - -const char * -fname_as_string (int pretty_p) -{ - const char *name = "top level"; - char *namep; - int vrb = 2, len; - cpp_string cstr = { 0, 0 }, strname; - - if (!pretty_p) - { - name = ""; - vrb = 0; - } - - if (current_function_decl) - name = lang_hooks.decl_printable_name (current_function_decl, vrb); - - len = strlen (name) + 3; /* Two for '"'s. One for NULL. */ - - namep = XNEWVEC (char, len); - snprintf (namep, len, "\"%s\"", name); - strname.text = (unsigned char *) namep; - strname.len = len - 1; - - if (cpp_interpret_string (parse_in, &strname, 1, &cstr, CPP_STRING)) - { - XDELETEVEC (namep); - return (const char *) cstr.text; - } - - return namep; -} - -/* Return the VAR_DECL for a const char array naming the current - function. If the VAR_DECL has not yet been created, create it - now. RID indicates how it should be formatted and IDENTIFIER_NODE - ID is its name (unfortunately C and C++ hold the RID values of - keywords in different places, so we can't derive RID from ID in - this language independent code. LOC is the location of the - function. */ - -tree -fname_decl (location_t loc, unsigned int rid, tree id) -{ - unsigned ix; - tree decl = NULL_TREE; - - for (ix = 0; fname_vars[ix].decl; ix++) - if (fname_vars[ix].rid == rid) - break; - - decl = *fname_vars[ix].decl; - if (!decl) - { - /* If a tree is built here, it would normally have the lineno of - the current statement. Later this tree will be moved to the - beginning of the function and this line number will be wrong. - To avoid this problem set the lineno to 0 here; that prevents - it from appearing in the RTL. */ - tree stmts; - location_t saved_location = input_location; - input_location = UNKNOWN_LOCATION; - - stmts = push_stmt_list (); - decl = (*make_fname_decl) (loc, id, fname_vars[ix].pretty); - stmts = pop_stmt_list (stmts); - if (!IS_EMPTY_STMT (stmts)) - saved_function_name_decls - = tree_cons (decl, stmts, saved_function_name_decls); - *fname_vars[ix].decl = decl; - input_location = saved_location; - } - if (!ix && !current_function_decl) - pedwarn (loc, 0, "%qD is not defined outside of function scope", decl); - - return decl; -} - -/* Given a STRING_CST, give it a suitable array-of-chars data type. */ - -tree -fix_string_type (tree value) -{ - int length = TREE_STRING_LENGTH (value); - int nchars; - tree e_type, i_type, a_type; - - /* Compute the number of elements, for the array type. */ - if (TREE_TYPE (value) == char_array_type_node || !TREE_TYPE (value)) - { - nchars = length; - e_type = char_type_node; - } - else if (TREE_TYPE (value) == char16_array_type_node) - { - nchars = length / (TYPE_PRECISION (char16_type_node) / BITS_PER_UNIT); - e_type = char16_type_node; - } - else if (TREE_TYPE (value) == char32_array_type_node) - { - nchars = length / (TYPE_PRECISION (char32_type_node) / BITS_PER_UNIT); - e_type = char32_type_node; - } - else - { - nchars = length / (TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT); - e_type = wchar_type_node; - } - - /* C89 2.2.4.1, C99 5.2.4.1 (Translation limits). The analogous - limit in C++98 Annex B is very large (65536) and is not normative, - so we do not diagnose it (warn_overlength_strings is forced off - in c_common_post_options). */ - if (warn_overlength_strings) - { - const int nchars_max = flag_isoc99 ? 4095 : 509; - const int relevant_std = flag_isoc99 ? 99 : 90; - if (nchars - 1 > nchars_max) - /* Translators: The %d after 'ISO C' will be 90 or 99. Do not - separate the %d from the 'C'. 'ISO' should not be - translated, but it may be moved after 'C%d' in languages - where modifiers follow nouns. */ - pedwarn (input_location, OPT_Woverlength_strings, - "string length %qd is greater than the length %qd " - "ISO C%d compilers are required to support", - nchars - 1, nchars_max, relevant_std); - } - - /* Create the array type for the string constant. The ISO C++ - standard says that a string literal has type `const char[N]' or - `const wchar_t[N]'. We use the same logic when invoked as a C - front-end with -Wwrite-strings. - ??? We should change the type of an expression depending on the - state of a warning flag. We should just be warning -- see how - this is handled in the C++ front-end for the deprecated implicit - conversion from string literals to `char*' or `wchar_t*'. - - The C++ front end relies on TYPE_MAIN_VARIANT of a cv-qualified - array type being the unqualified version of that type. - Therefore, if we are constructing an array of const char, we must - construct the matching unqualified array type first. The C front - end does not require this, but it does no harm, so we do it - unconditionally. */ - i_type = build_index_type (size_int (nchars - 1)); - a_type = build_array_type (e_type, i_type); - if (c_dialect_cxx() || warn_write_strings) - a_type = c_build_qualified_type (a_type, TYPE_QUAL_CONST); - - TREE_TYPE (value) = a_type; - TREE_CONSTANT (value) = 1; - TREE_READONLY (value) = 1; - TREE_STATIC (value) = 1; - return value; -} - -/* If DISABLE is true, stop issuing warnings. This is used when - parsing code that we know will not be executed. This function may - be called multiple times, and works as a stack. */ - -static void -c_disable_warnings (bool disable) -{ - if (disable) - { - ++c_inhibit_evaluation_warnings; - fold_defer_overflow_warnings (); - } -} - -/* If ENABLE is true, reenable issuing warnings. */ - -static void -c_enable_warnings (bool enable) -{ - if (enable) - { - --c_inhibit_evaluation_warnings; - fold_undefer_and_ignore_overflow_warnings (); - } -} - -/* Fully fold EXPR, an expression that was not folded (beyond integer - constant expressions and null pointer constants) when being built - up. If IN_INIT, this is in a static initializer and certain - changes are made to the folding done. Clear *MAYBE_CONST if - MAYBE_CONST is not NULL and EXPR is definitely not a constant - expression because it contains an evaluated operator (in C99) or an - operator outside of sizeof returning an integer constant (in C90) - not permitted in constant expressions, or because it contains an - evaluated arithmetic overflow. (*MAYBE_CONST should typically be - set to true by callers before calling this function.) Return the - folded expression. Function arguments have already been folded - before calling this function, as have the contents of SAVE_EXPR, - TARGET_EXPR, BIND_EXPR, VA_ARG_EXPR, OBJ_TYPE_REF and - C_MAYBE_CONST_EXPR. */ - -tree -c_fully_fold (tree expr, bool in_init, bool *maybe_const) -{ - tree ret; - tree eptype = NULL_TREE; - bool dummy = true; - bool maybe_const_itself = true; - location_t loc = EXPR_LOCATION (expr); - - /* This function is not relevant to C++ because C++ folds while - parsing, and may need changes to be correct for C++ when C++ - stops folding while parsing. */ - if (c_dialect_cxx ()) - gcc_unreachable (); - - if (!maybe_const) - maybe_const = &dummy; - if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR) - { - eptype = TREE_TYPE (expr); - expr = TREE_OPERAND (expr, 0); - } - ret = c_fully_fold_internal (expr, in_init, maybe_const, - &maybe_const_itself); - if (eptype) - ret = fold_convert_loc (loc, eptype, ret); - *maybe_const &= maybe_const_itself; - return ret; -} - -/* Internal helper for c_fully_fold. EXPR and IN_INIT are as for - c_fully_fold. *MAYBE_CONST_OPERANDS is cleared because of operands - not permitted, while *MAYBE_CONST_ITSELF is cleared because of - arithmetic overflow (for C90, *MAYBE_CONST_OPERANDS is carried from - both evaluated and unevaluated subexpressions while - *MAYBE_CONST_ITSELF is carried from only evaluated - subexpressions). */ - -static tree -c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, - bool *maybe_const_itself) -{ - tree ret = expr; - enum tree_code code = TREE_CODE (expr); - enum tree_code_class kind = TREE_CODE_CLASS (code); - location_t loc = EXPR_LOCATION (expr); - tree op0, op1, op2, op3; - tree orig_op0, orig_op1, orig_op2; - bool op0_const = true, op1_const = true, op2_const = true; - bool op0_const_self = true, op1_const_self = true, op2_const_self = true; - bool nowarning = TREE_NO_WARNING (expr); - bool unused_p; - - /* This function is not relevant to C++ because C++ folds while - parsing, and may need changes to be correct for C++ when C++ - stops folding while parsing. */ - if (c_dialect_cxx ()) - gcc_unreachable (); - - /* Constants, declarations, statements, errors, SAVE_EXPRs and - anything else not counted as an expression cannot usefully be - folded further at this point. */ - if (!IS_EXPR_CODE_CLASS (kind) - || kind == tcc_statement - || code == SAVE_EXPR) - return expr; - - /* Operands of variable-length expressions (function calls) have - already been folded, as have __builtin_* function calls, and such - expressions cannot occur in constant expressions. */ - if (kind == tcc_vl_exp) - { - *maybe_const_operands = false; - ret = fold (expr); - goto out; - } - - if (code == C_MAYBE_CONST_EXPR) - { - tree pre = C_MAYBE_CONST_EXPR_PRE (expr); - tree inner = C_MAYBE_CONST_EXPR_EXPR (expr); - if (C_MAYBE_CONST_EXPR_NON_CONST (expr)) - *maybe_const_operands = false; - if (C_MAYBE_CONST_EXPR_INT_OPERANDS (expr)) - *maybe_const_itself = false; - if (pre && !in_init) - ret = build2 (COMPOUND_EXPR, TREE_TYPE (expr), pre, inner); - else - ret = inner; - goto out; - } - - /* Assignment, increment, decrement, function call and comma - operators, and statement expressions, cannot occur in constant - expressions if evaluated / outside of sizeof. (Function calls - were handled above, though VA_ARG_EXPR is treated like a function - call here, and statement expressions are handled through - C_MAYBE_CONST_EXPR to avoid folding inside them.) */ - switch (code) - { - case MODIFY_EXPR: - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - case COMPOUND_EXPR: - *maybe_const_operands = false; - break; - - case VA_ARG_EXPR: - case TARGET_EXPR: - case BIND_EXPR: - case OBJ_TYPE_REF: - *maybe_const_operands = false; - ret = fold (expr); - goto out; - - default: - break; - } - - /* Fold individual tree codes as appropriate. */ - switch (code) - { - case COMPOUND_LITERAL_EXPR: - /* Any non-constancy will have been marked in a containing - C_MAYBE_CONST_EXPR; there is no more folding to do here. */ - goto out; - - case COMPONENT_REF: - orig_op0 = op0 = TREE_OPERAND (expr, 0); - op1 = TREE_OPERAND (expr, 1); - op2 = TREE_OPERAND (expr, 2); - op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, - maybe_const_itself); - STRIP_TYPE_NOPS (op0); - if (op0 != orig_op0) - ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2); - if (ret != expr) - { - TREE_READONLY (ret) = TREE_READONLY (expr); - TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr); - } - goto out; - - case ARRAY_REF: - orig_op0 = op0 = TREE_OPERAND (expr, 0); - orig_op1 = op1 = TREE_OPERAND (expr, 1); - op2 = TREE_OPERAND (expr, 2); - op3 = TREE_OPERAND (expr, 3); - op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, - maybe_const_itself); - STRIP_TYPE_NOPS (op0); - op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, - maybe_const_itself); - STRIP_TYPE_NOPS (op1); - op1 = decl_constant_value_for_optimization (op1); - if (op0 != orig_op0 || op1 != orig_op1) - ret = build4 (ARRAY_REF, TREE_TYPE (expr), op0, op1, op2, op3); - if (ret != expr) - { - TREE_READONLY (ret) = TREE_READONLY (expr); - TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr); - TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr); - } - ret = fold (ret); - goto out; - - case COMPOUND_EXPR: - case MODIFY_EXPR: - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - case PLUS_EXPR: - case MINUS_EXPR: - case MULT_EXPR: - case POINTER_PLUS_EXPR: - case TRUNC_DIV_EXPR: - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case TRUNC_MOD_EXPR: - case RDIV_EXPR: - case EXACT_DIV_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case BIT_AND_EXPR: - case LT_EXPR: - case LE_EXPR: - case GT_EXPR: - case GE_EXPR: - case EQ_EXPR: - case NE_EXPR: - case COMPLEX_EXPR: - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case TRUTH_XOR_EXPR: - case UNORDERED_EXPR: - case ORDERED_EXPR: - case UNLT_EXPR: - case UNLE_EXPR: - case UNGT_EXPR: - case UNGE_EXPR: - case UNEQ_EXPR: - /* Binary operations evaluating both arguments (increment and - decrement are binary internally in GCC). */ - orig_op0 = op0 = TREE_OPERAND (expr, 0); - orig_op1 = op1 = TREE_OPERAND (expr, 1); - op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, - maybe_const_itself); - STRIP_TYPE_NOPS (op0); - if (code != MODIFY_EXPR - && code != PREDECREMENT_EXPR - && code != PREINCREMENT_EXPR - && code != POSTDECREMENT_EXPR - && code != POSTINCREMENT_EXPR) - op0 = decl_constant_value_for_optimization (op0); - /* The RHS of a MODIFY_EXPR was fully folded when building that - expression for the sake of conversion warnings. */ - if (code != MODIFY_EXPR) - op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, - maybe_const_itself); - STRIP_TYPE_NOPS (op1); - op1 = decl_constant_value_for_optimization (op1); - if (op0 != orig_op0 || op1 != orig_op1 || in_init) - ret = in_init - ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1) - : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1); - else - ret = fold (expr); - if (TREE_OVERFLOW_P (ret) - && !TREE_OVERFLOW_P (op0) - && !TREE_OVERFLOW_P (op1)) - overflow_warning (EXPR_LOCATION (expr), ret); - if ((code == LSHIFT_EXPR || code == RSHIFT_EXPR) - && TREE_CODE (orig_op1) != INTEGER_CST - && TREE_CODE (op1) == INTEGER_CST - && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE - || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE) - && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE - && c_inhibit_evaluation_warnings == 0) - { - if (tree_int_cst_sgn (op1) < 0) - warning_at (loc, 0, (code == LSHIFT_EXPR - ? G_("left shift count is negative") - : G_("right shift count is negative"))); - else if (compare_tree_int (op1, - TYPE_PRECISION (TREE_TYPE (orig_op0))) - >= 0) - warning_at (loc, 0, (code == LSHIFT_EXPR - ? G_("left shift count >= width of type") - : G_("right shift count >= width of type"))); - } - goto out; - - case INDIRECT_REF: - case FIX_TRUNC_EXPR: - case FLOAT_EXPR: - CASE_CONVERT: - case VIEW_CONVERT_EXPR: - case NON_LVALUE_EXPR: - case NEGATE_EXPR: - case BIT_NOT_EXPR: - case TRUTH_NOT_EXPR: - case ADDR_EXPR: - case CONJ_EXPR: - case REALPART_EXPR: - case IMAGPART_EXPR: - /* Unary operations. */ - orig_op0 = op0 = TREE_OPERAND (expr, 0); - op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, - maybe_const_itself); - STRIP_TYPE_NOPS (op0); - if (code != ADDR_EXPR && code != REALPART_EXPR && code != IMAGPART_EXPR) - op0 = decl_constant_value_for_optimization (op0); - /* ??? Cope with user tricks that amount to offsetof. The middle-end is - not prepared to deal with them if they occur in initializers. */ - if (op0 != orig_op0 - && code == ADDR_EXPR - && (op1 = get_base_address (op0)) != NULL_TREE - && TREE_CODE (op1) == INDIRECT_REF - && TREE_CONSTANT (TREE_OPERAND (op1, 0))) - ret = fold_convert_loc (loc, TREE_TYPE (expr), fold_offsetof_1 (op0)); - else if (op0 != orig_op0 || in_init) - ret = in_init - ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0) - : fold_build1_loc (loc, code, TREE_TYPE (expr), op0); - else - ret = fold (expr); - if (code == INDIRECT_REF - && ret != expr - && TREE_CODE (ret) == INDIRECT_REF) - { - TREE_READONLY (ret) = TREE_READONLY (expr); - TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr); - TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr); - } - switch (code) - { - case FIX_TRUNC_EXPR: - case FLOAT_EXPR: - CASE_CONVERT: - /* Don't warn about explicit conversions. We will already - have warned about suspect implicit conversions. */ - break; - - default: - if (TREE_OVERFLOW_P (ret) && !TREE_OVERFLOW_P (op0)) - overflow_warning (EXPR_LOCATION (expr), ret); - break; - } - goto out; - - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - /* Binary operations not necessarily evaluating both - arguments. */ - orig_op0 = op0 = TREE_OPERAND (expr, 0); - orig_op1 = op1 = TREE_OPERAND (expr, 1); - op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self); - STRIP_TYPE_NOPS (op0); - - unused_p = (op0 == (code == TRUTH_ANDIF_EXPR - ? truthvalue_false_node - : truthvalue_true_node)); - c_disable_warnings (unused_p); - op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self); - STRIP_TYPE_NOPS (op1); - c_enable_warnings (unused_p); - - if (op0 != orig_op0 || op1 != orig_op1 || in_init) - ret = in_init - ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1) - : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1); - else - ret = fold (expr); - *maybe_const_operands &= op0_const; - *maybe_const_itself &= op0_const_self; - if (!(flag_isoc99 - && op0_const - && op0_const_self - && (code == TRUTH_ANDIF_EXPR - ? op0 == truthvalue_false_node - : op0 == truthvalue_true_node))) - *maybe_const_operands &= op1_const; - if (!(op0_const - && op0_const_self - && (code == TRUTH_ANDIF_EXPR - ? op0 == truthvalue_false_node - : op0 == truthvalue_true_node))) - *maybe_const_itself &= op1_const_self; - goto out; - - case COND_EXPR: - orig_op0 = op0 = TREE_OPERAND (expr, 0); - orig_op1 = op1 = TREE_OPERAND (expr, 1); - orig_op2 = op2 = TREE_OPERAND (expr, 2); - op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self); - - STRIP_TYPE_NOPS (op0); - c_disable_warnings (op0 == truthvalue_false_node); - op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self); - STRIP_TYPE_NOPS (op1); - c_enable_warnings (op0 == truthvalue_false_node); - - c_disable_warnings (op0 == truthvalue_true_node); - op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self); - STRIP_TYPE_NOPS (op2); - c_enable_warnings (op0 == truthvalue_true_node); - - if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2) - ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2); - else - ret = fold (expr); - *maybe_const_operands &= op0_const; - *maybe_const_itself &= op0_const_self; - if (!(flag_isoc99 - && op0_const - && op0_const_self - && op0 == truthvalue_false_node)) - *maybe_const_operands &= op1_const; - if (!(op0_const - && op0_const_self - && op0 == truthvalue_false_node)) - *maybe_const_itself &= op1_const_self; - if (!(flag_isoc99 - && op0_const - && op0_const_self - && op0 == truthvalue_true_node)) - *maybe_const_operands &= op2_const; - if (!(op0_const - && op0_const_self - && op0 == truthvalue_true_node)) - *maybe_const_itself &= op2_const_self; - goto out; - - case EXCESS_PRECISION_EXPR: - /* Each case where an operand with excess precision may be - encountered must remove the EXCESS_PRECISION_EXPR around - inner operands and possibly put one around the whole - expression or possibly convert to the semantic type (which - c_fully_fold does); we cannot tell at this stage which is - appropriate in any particular case. */ - gcc_unreachable (); - - default: - /* Various codes may appear through folding built-in functions - and their arguments. */ - goto out; - } - - out: - /* Some folding may introduce NON_LVALUE_EXPRs; all lvalue checks - have been done by this point, so remove them again. */ - nowarning |= TREE_NO_WARNING (ret); - STRIP_TYPE_NOPS (ret); - if (nowarning && !TREE_NO_WARNING (ret)) - { - if (!CAN_HAVE_LOCATION_P (ret)) - ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret); - TREE_NO_WARNING (ret) = 1; - } - if (ret != expr) - protected_set_expr_location (ret, loc); - return ret; -} - -/* If not optimizing, EXP is not a VAR_DECL, or EXP has array type, - return EXP. Otherwise, return either EXP or its known constant - value (if it has one), but return EXP if EXP has mode BLKmode. ??? - Is the BLKmode test appropriate? */ - -tree -decl_constant_value_for_optimization (tree exp) -{ - tree ret; - - /* This function is only used by C, for c_fully_fold and other - optimization, and may not be correct for C++. */ - if (c_dialect_cxx ()) - gcc_unreachable (); - - if (!optimize - || TREE_CODE (exp) != VAR_DECL - || TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE - || DECL_MODE (exp) == BLKmode) - return exp; - - ret = decl_constant_value (exp); - /* Avoid unwanted tree sharing between the initializer and current - function's body where the tree can be modified e.g. by the - gimplifier. */ - if (ret != exp && TREE_STATIC (exp)) - ret = unshare_expr (ret); - return ret; -} - -/* Print a warning if a constant expression had overflow in folding. - Invoke this function on every expression that the language - requires to be a constant expression. - Note the ANSI C standard says it is erroneous for a - constant expression to overflow. */ - -void -constant_expression_warning (tree value) -{ - if (warn_overflow && pedantic - && (TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST - || TREE_CODE (value) == FIXED_CST - || TREE_CODE (value) == VECTOR_CST - || TREE_CODE (value) == COMPLEX_CST) - && TREE_OVERFLOW (value)) - pedwarn (input_location, OPT_Woverflow, "overflow in constant expression"); -} - -/* The same as above but print an unconditional error. */ -void -constant_expression_error (tree value) -{ - if ((TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST - || TREE_CODE (value) == FIXED_CST - || TREE_CODE (value) == VECTOR_CST - || TREE_CODE (value) == COMPLEX_CST) - && TREE_OVERFLOW (value)) - error ("overflow in constant expression"); -} - -/* Print a warning if an expression had overflow in folding and its - operands hadn't. - - Invoke this function on every expression that - (1) appears in the source code, and - (2) is a constant expression that overflowed, and - (3) is not already checked by convert_and_check; - however, do not invoke this function on operands of explicit casts - or when the expression is the result of an operator and any operand - already overflowed. */ - -void -overflow_warning (location_t loc, tree value) -{ - if (c_inhibit_evaluation_warnings != 0) - return; - - switch (TREE_CODE (value)) - { - case INTEGER_CST: - warning_at (loc, OPT_Woverflow, "integer overflow in expression"); - break; - - case REAL_CST: - warning_at (loc, OPT_Woverflow, - "floating point overflow in expression"); - break; - - case FIXED_CST: - warning_at (loc, OPT_Woverflow, "fixed-point overflow in expression"); - break; - - case VECTOR_CST: - warning_at (loc, OPT_Woverflow, "vector overflow in expression"); - break; - - case COMPLEX_CST: - if (TREE_CODE (TREE_REALPART (value)) == INTEGER_CST) - warning_at (loc, OPT_Woverflow, - "complex integer overflow in expression"); - else if (TREE_CODE (TREE_REALPART (value)) == REAL_CST) - warning_at (loc, OPT_Woverflow, - "complex floating point overflow in expression"); - break; - - default: - break; - } -} - -/* Warn about uses of logical || / && operator in a context where it - is likely that the bitwise equivalent was intended by the - programmer. We have seen an expression in which CODE is a binary - operator used to combine expressions OP_LEFT and OP_RIGHT, which before folding - had CODE_LEFT and CODE_RIGHT, into an expression of type TYPE. */ -void -warn_logical_operator (location_t location, enum tree_code code, tree type, - enum tree_code code_left, tree op_left, - enum tree_code ARG_UNUSED (code_right), tree op_right) -{ - int or_op = (code == TRUTH_ORIF_EXPR || code == TRUTH_OR_EXPR); - int in0_p, in1_p, in_p; - tree low0, low1, low, high0, high1, high, lhs, rhs, tem; - bool strict_overflow_p = false; - - if (code != TRUTH_ANDIF_EXPR - && code != TRUTH_AND_EXPR - && code != TRUTH_ORIF_EXPR - && code != TRUTH_OR_EXPR) - return; - - /* Warn if &&/|| are being used in a context where it is - likely that the bitwise equivalent was intended by the - programmer. That is, an expression such as op && MASK - where op should not be any boolean expression, nor a - constant, and mask seems to be a non-boolean integer constant. */ - if (!truth_value_p (code_left) - && INTEGRAL_TYPE_P (TREE_TYPE (op_left)) - && !CONSTANT_CLASS_P (op_left) - && !TREE_NO_WARNING (op_left) - && TREE_CODE (op_right) == INTEGER_CST - && !integer_zerop (op_right) - && !integer_onep (op_right)) - { - if (or_op) - warning_at (location, OPT_Wlogical_op, "logical %<or%>" - " applied to non-boolean constant"); - else - warning_at (location, OPT_Wlogical_op, "logical %<and%>" - " applied to non-boolean constant"); - TREE_NO_WARNING (op_left) = true; - return; - } - - /* We do not warn for constants because they are typical of macro - expansions that test for features. */ - if (CONSTANT_CLASS_P (op_left) || CONSTANT_CLASS_P (op_right)) - return; - - /* This warning only makes sense with logical operands. */ - if (!(truth_value_p (TREE_CODE (op_left)) - || INTEGRAL_TYPE_P (TREE_TYPE (op_left))) - || !(truth_value_p (TREE_CODE (op_right)) - || INTEGRAL_TYPE_P (TREE_TYPE (op_right)))) - return; - - - /* We first test whether either side separately is trivially true - (with OR) or trivially false (with AND). If so, do not warn. - This is a common idiom for testing ranges of data types in - portable code. */ - lhs = make_range (op_left, &in0_p, &low0, &high0, &strict_overflow_p); - if (!lhs) - return; - if (TREE_CODE (lhs) == C_MAYBE_CONST_EXPR) - lhs = C_MAYBE_CONST_EXPR_EXPR (lhs); - - /* If this is an OR operation, invert both sides; now, the result - should be always false to get a warning. */ - if (or_op) - in0_p = !in0_p; - - tem = build_range_check (UNKNOWN_LOCATION, type, lhs, in0_p, low0, high0); - if (tem && integer_zerop (tem)) - return; - - rhs = make_range (op_right, &in1_p, &low1, &high1, &strict_overflow_p); - if (!rhs) - return; - if (TREE_CODE (rhs) == C_MAYBE_CONST_EXPR) - rhs = C_MAYBE_CONST_EXPR_EXPR (rhs); - - /* If this is an OR operation, invert both sides; now, the result - should be always false to get a warning. */ - if (or_op) - in1_p = !in1_p; - - tem = build_range_check (UNKNOWN_LOCATION, type, rhs, in1_p, low1, high1); - if (tem && integer_zerop (tem)) - return; - - /* If both expressions have the same operand, if we can merge the - ranges, and if the range test is always false, then warn. */ - if (operand_equal_p (lhs, rhs, 0) - && merge_ranges (&in_p, &low, &high, in0_p, low0, high0, - in1_p, low1, high1) - && 0 != (tem = build_range_check (UNKNOWN_LOCATION, - type, lhs, in_p, low, high)) - && integer_zerop (tem)) - { - if (or_op) - warning_at (location, OPT_Wlogical_op, - "logical %<or%> " - "of collectively exhaustive tests is always true"); - else - warning_at (location, OPT_Wlogical_op, - "logical %<and%> " - "of mutually exclusive tests is always false"); - } -} - - -/* Warn if EXP contains any computations whose results are not used. - Return true if a warning is printed; false otherwise. LOCUS is the - (potential) location of the expression. */ - -bool -warn_if_unused_value (const_tree exp, location_t locus) -{ - restart: - if (TREE_USED (exp) || TREE_NO_WARNING (exp)) - return false; - - /* Don't warn about void constructs. This includes casting to void, - void function calls, and statement expressions with a final cast - to void. */ - if (VOID_TYPE_P (TREE_TYPE (exp))) - return false; - - if (EXPR_HAS_LOCATION (exp)) - locus = EXPR_LOCATION (exp); - - switch (TREE_CODE (exp)) - { - case PREINCREMENT_EXPR: - case POSTINCREMENT_EXPR: - case PREDECREMENT_EXPR: - case POSTDECREMENT_EXPR: - case MODIFY_EXPR: - case INIT_EXPR: - case TARGET_EXPR: - case CALL_EXPR: - case TRY_CATCH_EXPR: - case WITH_CLEANUP_EXPR: - case EXIT_EXPR: - case VA_ARG_EXPR: - return false; - - case BIND_EXPR: - /* For a binding, warn if no side effect within it. */ - exp = BIND_EXPR_BODY (exp); - goto restart; - - case SAVE_EXPR: - case NON_LVALUE_EXPR: - case NOP_EXPR: - exp = TREE_OPERAND (exp, 0); - goto restart; - - case TRUTH_ORIF_EXPR: - case TRUTH_ANDIF_EXPR: - /* In && or ||, warn if 2nd operand has no side effect. */ - exp = TREE_OPERAND (exp, 1); - goto restart; - - case COMPOUND_EXPR: - if (warn_if_unused_value (TREE_OPERAND (exp, 0), locus)) - return true; - /* Let people do `(foo (), 0)' without a warning. */ - if (TREE_CONSTANT (TREE_OPERAND (exp, 1))) - return false; - exp = TREE_OPERAND (exp, 1); - goto restart; - - case COND_EXPR: - /* If this is an expression with side effects, don't warn; this - case commonly appears in macro expansions. */ - if (TREE_SIDE_EFFECTS (exp)) - return false; - goto warn; - - case INDIRECT_REF: - /* Don't warn about automatic dereferencing of references, since - the user cannot control it. */ - if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE) - { - exp = TREE_OPERAND (exp, 0); - goto restart; - } - /* Fall through. */ - - default: - /* Referencing a volatile value is a side effect, so don't warn. */ - if ((DECL_P (exp) || REFERENCE_CLASS_P (exp)) - && TREE_THIS_VOLATILE (exp)) - return false; - - /* If this is an expression which has no operands, there is no value - to be unused. There are no such language-independent codes, - but front ends may define such. */ - if (EXPRESSION_CLASS_P (exp) && TREE_OPERAND_LENGTH (exp) == 0) - return false; - - warn: - return warning_at (locus, OPT_Wunused_value, "value computed is not used"); - } -} - - -/* Print a warning about casts that might indicate violation - of strict aliasing rules if -Wstrict-aliasing is used and - strict aliasing mode is in effect. OTYPE is the original - TREE_TYPE of EXPR, and TYPE the type we're casting to. */ - -bool -strict_aliasing_warning (tree otype, tree type, tree expr) -{ - /* Strip pointer conversion chains and get to the correct original type. */ - STRIP_NOPS (expr); - otype = TREE_TYPE (expr); - - if (!(flag_strict_aliasing - && POINTER_TYPE_P (type) - && POINTER_TYPE_P (otype) - && !VOID_TYPE_P (TREE_TYPE (type))) - /* If the type we are casting to is a ref-all pointer - dereferencing it is always valid. */ - || TYPE_REF_CAN_ALIAS_ALL (type)) - return false; - - if ((warn_strict_aliasing > 1) && TREE_CODE (expr) == ADDR_EXPR - && (DECL_P (TREE_OPERAND (expr, 0)) - || handled_component_p (TREE_OPERAND (expr, 0)))) - { - /* Casting the address of an object to non void pointer. Warn - if the cast breaks type based aliasing. */ - if (!COMPLETE_TYPE_P (TREE_TYPE (type)) && warn_strict_aliasing == 2) - { - warning (OPT_Wstrict_aliasing, "type-punning to incomplete type " - "might break strict-aliasing rules"); - return true; - } - else - { - /* warn_strict_aliasing >= 3. This includes the default (3). - Only warn if the cast is dereferenced immediately. */ - alias_set_type set1 = - get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0))); - alias_set_type set2 = get_alias_set (TREE_TYPE (type)); - - if (set1 != set2 && set2 != 0 - && (set1 == 0 || !alias_sets_conflict_p (set1, set2))) - { - warning (OPT_Wstrict_aliasing, "dereferencing type-punned " - "pointer will break strict-aliasing rules"); - return true; - } - else if (warn_strict_aliasing == 2 - && !alias_sets_must_conflict_p (set1, set2)) - { - warning (OPT_Wstrict_aliasing, "dereferencing type-punned " - "pointer might break strict-aliasing rules"); - return true; - } - } - } - else - if ((warn_strict_aliasing == 1) && !VOID_TYPE_P (TREE_TYPE (otype))) - { - /* At this level, warn for any conversions, even if an address is - not taken in the same statement. This will likely produce many - false positives, but could be useful to pinpoint problems that - are not revealed at higher levels. */ - alias_set_type set1 = get_alias_set (TREE_TYPE (otype)); - alias_set_type set2 = get_alias_set (TREE_TYPE (type)); - if (!COMPLETE_TYPE_P (type) - || !alias_sets_must_conflict_p (set1, set2)) - { - warning (OPT_Wstrict_aliasing, "dereferencing type-punned " - "pointer might break strict-aliasing rules"); - return true; - } - } - - return false; -} - -/* Warn about memset (&a, 0, sizeof (&a)); and similar mistakes with - sizeof as last operand of certain builtins. */ - -void -sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee, - vec<tree, va_gc> *params, tree *sizeof_arg, - bool (*comp_types) (tree, tree)) -{ - tree type, dest = NULL_TREE, src = NULL_TREE, tem; - bool strop = false, cmp = false; - unsigned int idx = ~0; - location_t loc; - - if (TREE_CODE (callee) != FUNCTION_DECL - || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL - || vec_safe_length (params) <= 1) - return; - - switch (DECL_FUNCTION_CODE (callee)) - { - case BUILT_IN_STRNCMP: - case BUILT_IN_STRNCASECMP: - cmp = true; - /* FALLTHRU */ - case BUILT_IN_STRNCPY: - case BUILT_IN_STRNCPY_CHK: - case BUILT_IN_STRNCAT: - case BUILT_IN_STRNCAT_CHK: - case BUILT_IN_STPNCPY: - case BUILT_IN_STPNCPY_CHK: - strop = true; - /* FALLTHRU */ - case BUILT_IN_MEMCPY: - case BUILT_IN_MEMCPY_CHK: - case BUILT_IN_MEMMOVE: - case BUILT_IN_MEMMOVE_CHK: - if (params->length () < 3) - return; - src = (*params)[1]; - dest = (*params)[0]; - idx = 2; - break; - case BUILT_IN_BCOPY: - if (params->length () < 3) - return; - src = (*params)[0]; - dest = (*params)[1]; - idx = 2; - break; - case BUILT_IN_MEMCMP: - case BUILT_IN_BCMP: - if (params->length () < 3) - return; - src = (*params)[1]; - dest = (*params)[0]; - idx = 2; - cmp = true; - break; - case BUILT_IN_MEMSET: - case BUILT_IN_MEMSET_CHK: - if (params->length () < 3) - return; - dest = (*params)[0]; - idx = 2; - break; - case BUILT_IN_BZERO: - dest = (*params)[0]; - idx = 1; - break; - case BUILT_IN_STRNDUP: - src = (*params)[0]; - strop = true; - idx = 1; - break; - case BUILT_IN_MEMCHR: - if (params->length () < 3) - return; - src = (*params)[0]; - idx = 2; - break; - case BUILT_IN_SNPRINTF: - case BUILT_IN_SNPRINTF_CHK: - case BUILT_IN_VSNPRINTF: - case BUILT_IN_VSNPRINTF_CHK: - dest = (*params)[0]; - idx = 1; - strop = true; - break; - default: - break; - } - - if (idx >= 3) - return; - - if (sizeof_arg[idx] == NULL || sizeof_arg[idx] == error_mark_node) - return; - - type = TYPE_P (sizeof_arg[idx]) - ? sizeof_arg[idx] : TREE_TYPE (sizeof_arg[idx]); - if (!POINTER_TYPE_P (type)) - return; - - if (dest - && (tem = tree_strip_nop_conversions (dest)) - && POINTER_TYPE_P (TREE_TYPE (tem)) - && comp_types (TREE_TYPE (TREE_TYPE (tem)), type)) - return; - - if (src - && (tem = tree_strip_nop_conversions (src)) - && POINTER_TYPE_P (TREE_TYPE (tem)) - && comp_types (TREE_TYPE (TREE_TYPE (tem)), type)) - return; - - loc = sizeof_arg_loc[idx]; - - if (dest && !cmp) - { - if (!TYPE_P (sizeof_arg[idx]) - && operand_equal_p (dest, sizeof_arg[idx], 0) - && comp_types (TREE_TYPE (dest), type)) - { - if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop) - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "expression as the destination; did you mean to " - "remove the addressof?", callee); - else if ((TYPE_PRECISION (TREE_TYPE (type)) - == TYPE_PRECISION (char_type_node)) - || strop) - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "expression as the destination; did you mean to " - "provide an explicit length?", callee); - else - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "expression as the destination; did you mean to " - "dereference it?", callee); - return; - } - - if (POINTER_TYPE_P (TREE_TYPE (dest)) - && !strop - && comp_types (TREE_TYPE (dest), type) - && !VOID_TYPE_P (TREE_TYPE (type))) - { - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "pointer type %qT as the destination; expected %qT " - "or an explicit length", callee, TREE_TYPE (dest), - TREE_TYPE (TREE_TYPE (dest))); - return; - } - } - - if (src && !cmp) - { - if (!TYPE_P (sizeof_arg[idx]) - && operand_equal_p (src, sizeof_arg[idx], 0) - && comp_types (TREE_TYPE (src), type)) - { - if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop) - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "expression as the source; did you mean to " - "remove the addressof?", callee); - else if ((TYPE_PRECISION (TREE_TYPE (type)) - == TYPE_PRECISION (char_type_node)) - || strop) - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "expression as the source; did you mean to " - "provide an explicit length?", callee); - else - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "expression as the source; did you mean to " - "dereference it?", callee); - return; - } - - if (POINTER_TYPE_P (TREE_TYPE (src)) - && !strop - && comp_types (TREE_TYPE (src), type) - && !VOID_TYPE_P (TREE_TYPE (type))) - { - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "pointer type %qT as the source; expected %qT " - "or an explicit length", callee, TREE_TYPE (src), - TREE_TYPE (TREE_TYPE (src))); - return; - } - } - - if (dest) - { - if (!TYPE_P (sizeof_arg[idx]) - && operand_equal_p (dest, sizeof_arg[idx], 0) - && comp_types (TREE_TYPE (dest), type)) - { - if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop) - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "expression as the first source; did you mean to " - "remove the addressof?", callee); - else if ((TYPE_PRECISION (TREE_TYPE (type)) - == TYPE_PRECISION (char_type_node)) - || strop) - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "expression as the first source; did you mean to " - "provide an explicit length?", callee); - else - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "expression as the first source; did you mean to " - "dereference it?", callee); - return; - } - - if (POINTER_TYPE_P (TREE_TYPE (dest)) - && !strop - && comp_types (TREE_TYPE (dest), type) - && !VOID_TYPE_P (TREE_TYPE (type))) - { - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "pointer type %qT as the first source; expected %qT " - "or an explicit length", callee, TREE_TYPE (dest), - TREE_TYPE (TREE_TYPE (dest))); - return; - } - } - - if (src) - { - if (!TYPE_P (sizeof_arg[idx]) - && operand_equal_p (src, sizeof_arg[idx], 0) - && comp_types (TREE_TYPE (src), type)) - { - if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop) - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "expression as the second source; did you mean to " - "remove the addressof?", callee); - else if ((TYPE_PRECISION (TREE_TYPE (type)) - == TYPE_PRECISION (char_type_node)) - || strop) - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "expression as the second source; did you mean to " - "provide an explicit length?", callee); - else - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "expression as the second source; did you mean to " - "dereference it?", callee); - return; - } - - if (POINTER_TYPE_P (TREE_TYPE (src)) - && !strop - && comp_types (TREE_TYPE (src), type) - && !VOID_TYPE_P (TREE_TYPE (type))) - { - warning_at (loc, OPT_Wsizeof_pointer_memaccess, - "argument to %<sizeof%> in %qD call is the same " - "pointer type %qT as the second source; expected %qT " - "or an explicit length", callee, TREE_TYPE (src), - TREE_TYPE (TREE_TYPE (src))); - return; - } - } - -} - -/* Warn for unlikely, improbable, or stupid DECL declarations - of `main'. */ - -void -check_main_parameter_types (tree decl) -{ - function_args_iterator iter; - tree type; - int argct = 0; - - FOREACH_FUNCTION_ARGS (TREE_TYPE (decl), type, iter) - { - /* XXX void_type_node belies the abstraction. */ - if (type == void_type_node || type == error_mark_node ) - break; - - ++argct; - switch (argct) - { - case 1: - if (TYPE_MAIN_VARIANT (type) != integer_type_node) - pedwarn (input_location, OPT_Wmain, - "first argument of %q+D should be %<int%>", decl); - break; - - case 2: - if (TREE_CODE (type) != POINTER_TYPE - || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE - || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))) - != char_type_node)) - pedwarn (input_location, OPT_Wmain, - "second argument of %q+D should be %<char **%>", decl); - break; - - case 3: - if (TREE_CODE (type) != POINTER_TYPE - || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE - || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))) - != char_type_node)) - pedwarn (input_location, OPT_Wmain, - "third argument of %q+D should probably be " - "%<char **%>", decl); - break; - } - } - - /* It is intentional that this message does not mention the third - argument because it's only mentioned in an appendix of the - standard. */ - if (argct > 0 && (argct < 2 || argct > 3)) - pedwarn (input_location, OPT_Wmain, - "%q+D takes only zero or two arguments", decl); -} - -/* True if pointers to distinct types T1 and T2 can be converted to - each other without an explicit cast. Only returns true for opaque - vector types. */ -bool -vector_targets_convertible_p (const_tree t1, const_tree t2) -{ - if (TREE_CODE (t1) == VECTOR_TYPE && TREE_CODE (t2) == VECTOR_TYPE - && (TYPE_VECTOR_OPAQUE (t1) || TYPE_VECTOR_OPAQUE (t2)) - && tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2))) - return true; - - return false; -} - -/* True if vector types T1 and T2 can be converted to each other - without an explicit cast. If EMIT_LAX_NOTE is true, and T1 and T2 - can only be converted with -flax-vector-conversions yet that is not - in effect, emit a note telling the user about that option if such - a note has not previously been emitted. */ -bool -vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note) -{ - static bool emitted_lax_note = false; - bool convertible_lax; - - if ((TYPE_VECTOR_OPAQUE (t1) || TYPE_VECTOR_OPAQUE (t2)) - && tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2))) - return true; - - convertible_lax = - (tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2)) - && (TREE_CODE (TREE_TYPE (t1)) != REAL_TYPE || - TYPE_PRECISION (t1) == TYPE_PRECISION (t2)) - && (INTEGRAL_TYPE_P (TREE_TYPE (t1)) - == INTEGRAL_TYPE_P (TREE_TYPE (t2)))); - - if (!convertible_lax || flag_lax_vector_conversions) - return convertible_lax; - - if (TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2) - && lang_hooks.types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2))) - return true; - - if (emit_lax_note && !emitted_lax_note) - { - emitted_lax_note = true; - inform (input_location, "use -flax-vector-conversions to permit " - "conversions between vectors with differing " - "element types or numbers of subparts"); - } - - return false; -} - -/* Build a VEC_PERM_EXPR if V0, V1 and MASK are not error_mark_nodes - and have vector types, V0 has the same type as V1, and the number of - elements of V0, V1, MASK is the same. - - In case V1 is a NULL_TREE it is assumed that __builtin_shuffle was - called with two arguments. In this case implementation passes the - first argument twice in order to share the same tree code. This fact - could enable the mask-values being twice the vector length. This is - an implementation accident and this semantics is not guaranteed to - the user. */ -tree -c_build_vec_perm_expr (location_t loc, tree v0, tree v1, tree mask) -{ - tree ret; - bool wrap = true; - bool maybe_const = false; - bool two_arguments = false; - - if (v1 == NULL_TREE) - { - two_arguments = true; - v1 = v0; - } - - if (v0 == error_mark_node || v1 == error_mark_node - || mask == error_mark_node) - return error_mark_node; - - if (TREE_CODE (TREE_TYPE (mask)) != VECTOR_TYPE - || TREE_CODE (TREE_TYPE (TREE_TYPE (mask))) != INTEGER_TYPE) - { - error_at (loc, "__builtin_shuffle last argument must " - "be an integer vector"); - return error_mark_node; - } - - if (TREE_CODE (TREE_TYPE (v0)) != VECTOR_TYPE - || TREE_CODE (TREE_TYPE (v1)) != VECTOR_TYPE) - { - error_at (loc, "__builtin_shuffle arguments must be vectors"); - return error_mark_node; - } - - if (TYPE_MAIN_VARIANT (TREE_TYPE (v0)) != TYPE_MAIN_VARIANT (TREE_TYPE (v1))) - { - error_at (loc, "__builtin_shuffle argument vectors must be of " - "the same type"); - return error_mark_node; - } - - if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (v0)) - != TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask)) - && TYPE_VECTOR_SUBPARTS (TREE_TYPE (v1)) - != TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask))) - { - error_at (loc, "__builtin_shuffle number of elements of the " - "argument vector(s) and the mask vector should " - "be the same"); - return error_mark_node; - } - - if (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (v0)))) - != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (mask))))) - { - error_at (loc, "__builtin_shuffle argument vector(s) inner type " - "must have the same size as inner type of the mask"); - return error_mark_node; - } - - if (!c_dialect_cxx ()) - { - /* Avoid C_MAYBE_CONST_EXPRs inside VEC_PERM_EXPR. */ - v0 = c_fully_fold (v0, false, &maybe_const); - wrap &= maybe_const; - - if (two_arguments) - v1 = v0 = save_expr (v0); - else - { - v1 = c_fully_fold (v1, false, &maybe_const); - wrap &= maybe_const; - } - - mask = c_fully_fold (mask, false, &maybe_const); - wrap &= maybe_const; - } - - ret = build3_loc (loc, VEC_PERM_EXPR, TREE_TYPE (v0), v0, v1, mask); - - if (!c_dialect_cxx () && !wrap) - ret = c_wrap_maybe_const (ret, true); - - return ret; -} - -/* Like tree.c:get_narrower, but retain conversion from C++0x scoped enum - to integral type. */ - -static tree -c_common_get_narrower (tree op, int *unsignedp_ptr) -{ - op = get_narrower (op, unsignedp_ptr); - - if (TREE_CODE (TREE_TYPE (op)) == ENUMERAL_TYPE - && ENUM_IS_SCOPED (TREE_TYPE (op))) - { - /* C++0x scoped enumerations don't implicitly convert to integral - type; if we stripped an explicit conversion to a larger type we - need to replace it so common_type will still work. */ - tree type = c_common_type_for_size (TYPE_PRECISION (TREE_TYPE (op)), - TYPE_UNSIGNED (TREE_TYPE (op))); - op = fold_convert (type, op); - } - return op; -} - -/* This is a helper function of build_binary_op. - - For certain operations if both args were extended from the same - smaller type, do the arithmetic in that type and then extend. - - BITWISE indicates a bitwise operation. - For them, this optimization is safe only if - both args are zero-extended or both are sign-extended. - Otherwise, we might change the result. - Eg, (short)-1 | (unsigned short)-1 is (int)-1 - but calculated in (unsigned short) it would be (unsigned short)-1. -*/ -tree -shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise) -{ - int unsigned0, unsigned1; - tree arg0, arg1; - int uns; - tree type; - - /* Cast OP0 and OP1 to RESULT_TYPE. Doing so prevents - excessive narrowing when we call get_narrower below. For - example, suppose that OP0 is of unsigned int extended - from signed char and that RESULT_TYPE is long long int. - If we explicitly cast OP0 to RESULT_TYPE, OP0 would look - like - - (long long int) (unsigned int) signed_char - - which get_narrower would narrow down to - - (unsigned int) signed char - - If we do not cast OP0 first, get_narrower would return - signed_char, which is inconsistent with the case of the - explicit cast. */ - op0 = convert (result_type, op0); - op1 = convert (result_type, op1); - - arg0 = c_common_get_narrower (op0, &unsigned0); - arg1 = c_common_get_narrower (op1, &unsigned1); - - /* UNS is 1 if the operation to be done is an unsigned one. */ - uns = TYPE_UNSIGNED (result_type); - - /* Handle the case that OP0 (or OP1) does not *contain* a conversion - but it *requires* conversion to FINAL_TYPE. */ - - if ((TYPE_PRECISION (TREE_TYPE (op0)) - == TYPE_PRECISION (TREE_TYPE (arg0))) - && TREE_TYPE (op0) != result_type) - unsigned0 = TYPE_UNSIGNED (TREE_TYPE (op0)); - if ((TYPE_PRECISION (TREE_TYPE (op1)) - == TYPE_PRECISION (TREE_TYPE (arg1))) - && TREE_TYPE (op1) != result_type) - unsigned1 = TYPE_UNSIGNED (TREE_TYPE (op1)); - - /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE. */ - - /* For bitwise operations, signedness of nominal type - does not matter. Consider only how operands were extended. */ - if (bitwise) - uns = unsigned0; - - /* Note that in all three cases below we refrain from optimizing - an unsigned operation on sign-extended args. - That would not be valid. */ - - /* Both args variable: if both extended in same way - from same width, do it in that width. - Do it unsigned if args were zero-extended. */ - if ((TYPE_PRECISION (TREE_TYPE (arg0)) - < TYPE_PRECISION (result_type)) - && (TYPE_PRECISION (TREE_TYPE (arg1)) - == TYPE_PRECISION (TREE_TYPE (arg0))) - && unsigned0 == unsigned1 - && (unsigned0 || !uns)) - return c_common_signed_or_unsigned_type - (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1))); - - else if (TREE_CODE (arg0) == INTEGER_CST - && (unsigned1 || !uns) - && (TYPE_PRECISION (TREE_TYPE (arg1)) - < TYPE_PRECISION (result_type)) - && (type - = c_common_signed_or_unsigned_type (unsigned1, - TREE_TYPE (arg1))) - && !POINTER_TYPE_P (type) - && int_fits_type_p (arg0, type)) - return type; - - else if (TREE_CODE (arg1) == INTEGER_CST - && (unsigned0 || !uns) - && (TYPE_PRECISION (TREE_TYPE (arg0)) - < TYPE_PRECISION (result_type)) - && (type - = c_common_signed_or_unsigned_type (unsigned0, - TREE_TYPE (arg0))) - && !POINTER_TYPE_P (type) - && int_fits_type_p (arg1, type)) - return type; - - return result_type; -} - -/* Checks if expression EXPR of real/integer type cannot be converted - to the real/integer type TYPE. Function returns true when: - * EXPR is a constant which cannot be exactly converted to TYPE - * EXPR is not a constant and size of EXPR's type > than size of TYPE, - for EXPR type and TYPE being both integers or both real. - * EXPR is not a constant of real type and TYPE is an integer. - * EXPR is not a constant of integer type which cannot be - exactly converted to real type. - Function allows conversions between types of different signedness and - does not return true in that case. Function can produce signedness - warnings if PRODUCE_WARNS is true. */ -bool -unsafe_conversion_p (tree type, tree expr, bool produce_warns) -{ - bool give_warning = false; - tree expr_type = TREE_TYPE (expr); - location_t loc = EXPR_LOC_OR_HERE (expr); - - if (TREE_CODE (expr) == REAL_CST || TREE_CODE (expr) == INTEGER_CST) - { - /* Warn for real constant that is not an exact integer converted - to integer type. */ - if (TREE_CODE (expr_type) == REAL_TYPE - && TREE_CODE (type) == INTEGER_TYPE) - { - if (!real_isinteger (TREE_REAL_CST_PTR (expr), TYPE_MODE (expr_type))) - give_warning = true; - } - /* Warn for an integer constant that does not fit into integer type. */ - else if (TREE_CODE (expr_type) == INTEGER_TYPE - && TREE_CODE (type) == INTEGER_TYPE - && !int_fits_type_p (expr, type)) - { - if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (expr_type) - && tree_int_cst_sgn (expr) < 0) - { - if (produce_warns) - warning_at (loc, OPT_Wsign_conversion, "negative integer" - " implicitly converted to unsigned type"); - } - else if (!TYPE_UNSIGNED (type) && TYPE_UNSIGNED (expr_type)) - { - if (produce_warns) - warning_at (loc, OPT_Wsign_conversion, "conversion of unsigned" - " constant value to negative integer"); - } - else - give_warning = true; - } - else if (TREE_CODE (type) == REAL_TYPE) - { - /* Warn for an integer constant that does not fit into real type. */ - if (TREE_CODE (expr_type) == INTEGER_TYPE) - { - REAL_VALUE_TYPE a = real_value_from_int_cst (0, expr); - if (!exact_real_truncate (TYPE_MODE (type), &a)) - give_warning = true; - } - /* Warn for a real constant that does not fit into a smaller - real type. */ - else if (TREE_CODE (expr_type) == REAL_TYPE - && TYPE_PRECISION (type) < TYPE_PRECISION (expr_type)) - { - REAL_VALUE_TYPE a = TREE_REAL_CST (expr); - if (!exact_real_truncate (TYPE_MODE (type), &a)) - give_warning = true; - } - } - } - else - { - /* Warn for real types converted to integer types. */ - if (TREE_CODE (expr_type) == REAL_TYPE - && TREE_CODE (type) == INTEGER_TYPE) - give_warning = true; - - else if (TREE_CODE (expr_type) == INTEGER_TYPE - && TREE_CODE (type) == INTEGER_TYPE) - { - /* Don't warn about unsigned char y = 0xff, x = (int) y; */ - expr = get_unwidened (expr, 0); - expr_type = TREE_TYPE (expr); - - /* Don't warn for short y; short x = ((int)y & 0xff); */ - if (TREE_CODE (expr) == BIT_AND_EXPR - || TREE_CODE (expr) == BIT_IOR_EXPR - || TREE_CODE (expr) == BIT_XOR_EXPR) - { - /* If both args were extended from a shortest type, - use that type if that is safe. */ - expr_type = shorten_binary_op (expr_type, - TREE_OPERAND (expr, 0), - TREE_OPERAND (expr, 1), - /* bitwise */1); - - if (TREE_CODE (expr) == BIT_AND_EXPR) - { - tree op0 = TREE_OPERAND (expr, 0); - tree op1 = TREE_OPERAND (expr, 1); - bool unsigned0 = TYPE_UNSIGNED (TREE_TYPE (op0)); - bool unsigned1 = TYPE_UNSIGNED (TREE_TYPE (op1)); - - /* If one of the operands is a non-negative constant - that fits in the target type, then the type of the - other operand does not matter. */ - if ((TREE_CODE (op0) == INTEGER_CST - && int_fits_type_p (op0, c_common_signed_type (type)) - && int_fits_type_p (op0, c_common_unsigned_type (type))) - || (TREE_CODE (op1) == INTEGER_CST - && int_fits_type_p (op1, c_common_signed_type (type)) - && int_fits_type_p (op1, - c_common_unsigned_type (type)))) - return false; - /* If constant is unsigned and fits in the target - type, then the result will also fit. */ - else if ((TREE_CODE (op0) == INTEGER_CST - && unsigned0 - && int_fits_type_p (op0, type)) - || (TREE_CODE (op1) == INTEGER_CST - && unsigned1 - && int_fits_type_p (op1, type))) - return false; - } - } - /* Warn for integer types converted to smaller integer types. */ - if (TYPE_PRECISION (type) < TYPE_PRECISION (expr_type)) - give_warning = true; - - /* When they are the same width but different signedness, - then the value may change. */ - else if (((TYPE_PRECISION (type) == TYPE_PRECISION (expr_type) - && TYPE_UNSIGNED (expr_type) != TYPE_UNSIGNED (type)) - /* Even when converted to a bigger type, if the type is - unsigned but expr is signed, then negative values - will be changed. */ - || (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (expr_type))) - && produce_warns) - warning_at (loc, OPT_Wsign_conversion, "conversion to %qT from %qT " - "may change the sign of the result", - type, expr_type); - } - - /* Warn for integer types converted to real types if and only if - all the range of values of the integer type cannot be - represented by the real type. */ - else if (TREE_CODE (expr_type) == INTEGER_TYPE - && TREE_CODE (type) == REAL_TYPE) - { - tree type_low_bound, type_high_bound; - REAL_VALUE_TYPE real_low_bound, real_high_bound; - - /* Don't warn about char y = 0xff; float x = (int) y; */ - expr = get_unwidened (expr, 0); - expr_type = TREE_TYPE (expr); - - type_low_bound = TYPE_MIN_VALUE (expr_type); - type_high_bound = TYPE_MAX_VALUE (expr_type); - real_low_bound = real_value_from_int_cst (0, type_low_bound); - real_high_bound = real_value_from_int_cst (0, type_high_bound); - - if (!exact_real_truncate (TYPE_MODE (type), &real_low_bound) - || !exact_real_truncate (TYPE_MODE (type), &real_high_bound)) - give_warning = true; - } - - /* Warn for real types converted to smaller real types. */ - else if (TREE_CODE (expr_type) == REAL_TYPE - && TREE_CODE (type) == REAL_TYPE - && TYPE_PRECISION (type) < TYPE_PRECISION (expr_type)) - give_warning = true; - } - - return give_warning; -} - -/* Warns if the conversion of EXPR to TYPE may alter a value. - This is a helper function for warnings_for_convert_and_check. */ - -static void -conversion_warning (tree type, tree expr) -{ - tree expr_type = TREE_TYPE (expr); - location_t loc = EXPR_LOC_OR_HERE (expr); - - if (!warn_conversion && !warn_sign_conversion) - return; - - switch (TREE_CODE (expr)) - { - case EQ_EXPR: - case NE_EXPR: - case LE_EXPR: - case GE_EXPR: - case LT_EXPR: - case GT_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case TRUTH_XOR_EXPR: - case TRUTH_NOT_EXPR: - /* Conversion from boolean to a signed:1 bit-field (which only - can hold the values 0 and -1) doesn't lose information - but - it does change the value. */ - if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type)) - warning_at (loc, OPT_Wconversion, - "conversion to %qT from boolean expression", type); - return; - - case REAL_CST: - case INTEGER_CST: - if (unsafe_conversion_p (type, expr, true)) - warning_at (loc, OPT_Wconversion, - "conversion to %qT alters %qT constant value", - type, expr_type); - return; - - case COND_EXPR: - { - /* In case of COND_EXPR, we do not care about the type of - COND_EXPR, only about the conversion of each operand. */ - tree op1 = TREE_OPERAND (expr, 1); - tree op2 = TREE_OPERAND (expr, 2); - - conversion_warning (type, op1); - conversion_warning (type, op2); - return; - } - - default: /* 'expr' is not a constant. */ - if (unsafe_conversion_p (type, expr, true)) - warning_at (loc, OPT_Wconversion, - "conversion to %qT from %qT may alter its value", - type, expr_type); - } -} - -/* Produce warnings after a conversion. RESULT is the result of - converting EXPR to TYPE. This is a helper function for - convert_and_check and cp_convert_and_check. */ - -void -warnings_for_convert_and_check (tree type, tree expr, tree result) -{ - location_t loc = EXPR_LOC_OR_HERE (expr); - - if (TREE_CODE (expr) == INTEGER_CST - && (TREE_CODE (type) == INTEGER_TYPE - || TREE_CODE (type) == ENUMERAL_TYPE) - && !int_fits_type_p (expr, type)) - { - /* Do not diagnose overflow in a constant expression merely - because a conversion overflowed. */ - if (TREE_OVERFLOW (result)) - TREE_OVERFLOW (result) = TREE_OVERFLOW (expr); - - if (TYPE_UNSIGNED (type)) - { - /* This detects cases like converting -129 or 256 to - unsigned char. */ - if (!int_fits_type_p (expr, c_common_signed_type (type))) - warning_at (loc, OPT_Woverflow, - "large integer implicitly truncated to unsigned type"); - else - conversion_warning (type, expr); - } - else if (!int_fits_type_p (expr, c_common_unsigned_type (type))) - warning (OPT_Woverflow, - "overflow in implicit constant conversion"); - /* No warning for converting 0x80000000 to int. */ - else if (pedantic - && (TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE - || TYPE_PRECISION (TREE_TYPE (expr)) - != TYPE_PRECISION (type))) - warning_at (loc, OPT_Woverflow, - "overflow in implicit constant conversion"); - - else - conversion_warning (type, expr); - } - else if ((TREE_CODE (result) == INTEGER_CST - || TREE_CODE (result) == FIXED_CST) && TREE_OVERFLOW (result)) - warning_at (loc, OPT_Woverflow, - "overflow in implicit constant conversion"); - else - conversion_warning (type, expr); -} - - -/* Convert EXPR to TYPE, warning about conversion problems with constants. - Invoke this function on every expression that is converted implicitly, - i.e. because of language rules and not because of an explicit cast. */ - -tree -convert_and_check (tree type, tree expr) -{ - tree result; - tree expr_for_warning; - - /* Convert from a value with possible excess precision rather than - via the semantic type, but do not warn about values not fitting - exactly in the semantic type. */ - if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR) - { - tree orig_type = TREE_TYPE (expr); - expr = TREE_OPERAND (expr, 0); - expr_for_warning = convert (orig_type, expr); - if (orig_type == type) - return expr_for_warning; - } - else - expr_for_warning = expr; - - if (TREE_TYPE (expr) == type) - return expr; - - result = convert (type, expr); - - if (c_inhibit_evaluation_warnings == 0 - && !TREE_OVERFLOW_P (expr) - && result != error_mark_node) - warnings_for_convert_and_check (type, expr_for_warning, result); - - return result; -} - -/* A node in a list that describes references to variables (EXPR), which are - either read accesses if WRITER is zero, or write accesses, in which case - WRITER is the parent of EXPR. */ -struct tlist -{ - struct tlist *next; - tree expr, writer; -}; - -/* Used to implement a cache the results of a call to verify_tree. We only - use this for SAVE_EXPRs. */ -struct tlist_cache -{ - struct tlist_cache *next; - struct tlist *cache_before_sp; - struct tlist *cache_after_sp; - tree expr; -}; - -/* Obstack to use when allocating tlist structures, and corresponding - firstobj. */ -static struct obstack tlist_obstack; -static char *tlist_firstobj = 0; - -/* Keep track of the identifiers we've warned about, so we can avoid duplicate - warnings. */ -static struct tlist *warned_ids; -/* SAVE_EXPRs need special treatment. We process them only once and then - cache the results. */ -static struct tlist_cache *save_expr_cache; - -static void add_tlist (struct tlist **, struct tlist *, tree, int); -static void merge_tlist (struct tlist **, struct tlist *, int); -static void verify_tree (tree, struct tlist **, struct tlist **, tree); -static int warning_candidate_p (tree); -static bool candidate_equal_p (const_tree, const_tree); -static void warn_for_collisions (struct tlist *); -static void warn_for_collisions_1 (tree, tree, struct tlist *, int); -static struct tlist *new_tlist (struct tlist *, tree, tree); - -/* Create a new struct tlist and fill in its fields. */ -static struct tlist * -new_tlist (struct tlist *next, tree t, tree writer) -{ - struct tlist *l; - l = XOBNEW (&tlist_obstack, struct tlist); - l->next = next; - l->expr = t; - l->writer = writer; - return l; -} - -/* Add duplicates of the nodes found in ADD to the list *TO. If EXCLUDE_WRITER - is nonnull, we ignore any node we find which has a writer equal to it. */ - -static void -add_tlist (struct tlist **to, struct tlist *add, tree exclude_writer, int copy) -{ - while (add) - { - struct tlist *next = add->next; - if (!copy) - add->next = *to; - if (!exclude_writer || !candidate_equal_p (add->writer, exclude_writer)) - *to = copy ? new_tlist (*to, add->expr, add->writer) : add; - add = next; - } -} - -/* Merge the nodes of ADD into TO. This merging process is done so that for - each variable that already exists in TO, no new node is added; however if - there is a write access recorded in ADD, and an occurrence on TO is only - a read access, then the occurrence in TO will be modified to record the - write. */ - -static void -merge_tlist (struct tlist **to, struct tlist *add, int copy) -{ - struct tlist **end = to; - - while (*end) - end = &(*end)->next; - - while (add) - { - int found = 0; - struct tlist *tmp2; - struct tlist *next = add->next; - - for (tmp2 = *to; tmp2; tmp2 = tmp2->next) - if (candidate_equal_p (tmp2->expr, add->expr)) - { - found = 1; - if (!tmp2->writer) - tmp2->writer = add->writer; - } - if (!found) - { - *end = copy ? add : new_tlist (NULL, add->expr, add->writer); - end = &(*end)->next; - *end = 0; - } - add = next; - } -} - -/* WRITTEN is a variable, WRITER is its parent. Warn if any of the variable - references in list LIST conflict with it, excluding reads if ONLY writers - is nonzero. */ - -static void -warn_for_collisions_1 (tree written, tree writer, struct tlist *list, - int only_writes) -{ - struct tlist *tmp; - - /* Avoid duplicate warnings. */ - for (tmp = warned_ids; tmp; tmp = tmp->next) - if (candidate_equal_p (tmp->expr, written)) - return; - - while (list) - { - if (candidate_equal_p (list->expr, written) - && !candidate_equal_p (list->writer, writer) - && (!only_writes || list->writer)) - { - warned_ids = new_tlist (warned_ids, written, NULL_TREE); - warning_at (EXPR_LOC_OR_HERE (writer), - OPT_Wsequence_point, "operation on %qE may be undefined", - list->expr); - } - list = list->next; - } -} - -/* Given a list LIST of references to variables, find whether any of these - can cause conflicts due to missing sequence points. */ - -static void -warn_for_collisions (struct tlist *list) -{ - struct tlist *tmp; - - for (tmp = list; tmp; tmp = tmp->next) - { - if (tmp->writer) - warn_for_collisions_1 (tmp->expr, tmp->writer, list, 0); - } -} - -/* Return nonzero if X is a tree that can be verified by the sequence point - warnings. */ -static int -warning_candidate_p (tree x) -{ - if (DECL_P (x) && DECL_ARTIFICIAL (x)) - return 0; - - if (TREE_CODE (x) == BLOCK) - return 0; - - /* VOID_TYPE_P (TREE_TYPE (x)) is workaround for cp/tree.c - (lvalue_p) crash on TRY/CATCH. */ - if (TREE_TYPE (x) == NULL_TREE || VOID_TYPE_P (TREE_TYPE (x))) - return 0; - - if (!lvalue_p (x)) - return 0; - - /* No point to track non-const calls, they will never satisfy - operand_equal_p. */ - if (TREE_CODE (x) == CALL_EXPR && (call_expr_flags (x) & ECF_CONST) == 0) - return 0; - - if (TREE_CODE (x) == STRING_CST) - return 0; - - return 1; -} - -/* Return nonzero if X and Y appear to be the same candidate (or NULL) */ -static bool -candidate_equal_p (const_tree x, const_tree y) -{ - return (x == y) || (x && y && operand_equal_p (x, y, 0)); -} - -/* Walk the tree X, and record accesses to variables. If X is written by the - parent tree, WRITER is the parent. - We store accesses in one of the two lists: PBEFORE_SP, and PNO_SP. If this - expression or its only operand forces a sequence point, then everything up - to the sequence point is stored in PBEFORE_SP. Everything else gets stored - in PNO_SP. - Once we return, we will have emitted warnings if any subexpression before - such a sequence point could be undefined. On a higher level, however, the - sequence point may not be relevant, and we'll merge the two lists. - - Example: (b++, a) + b; - The call that processes the COMPOUND_EXPR will store the increment of B - in PBEFORE_SP, and the use of A in PNO_SP. The higher-level call that - processes the PLUS_EXPR will need to merge the two lists so that - eventually, all accesses end up on the same list (and we'll warn about the - unordered subexpressions b++ and b. - - A note on merging. If we modify the former example so that our expression - becomes - (b++, b) + a - care must be taken not simply to add all three expressions into the final - PNO_SP list. The function merge_tlist takes care of that by merging the - before-SP list of the COMPOUND_EXPR into its after-SP list in a special - way, so that no more than one access to B is recorded. */ - -static void -verify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp, - tree writer) -{ - struct tlist *tmp_before, *tmp_nosp, *tmp_list2, *tmp_list3; - enum tree_code code; - enum tree_code_class cl; - - /* X may be NULL if it is the operand of an empty statement expression - ({ }). */ - if (x == NULL) - return; - - restart: - code = TREE_CODE (x); - cl = TREE_CODE_CLASS (code); - - if (warning_candidate_p (x)) - *pno_sp = new_tlist (*pno_sp, x, writer); - - switch (code) - { - case CONSTRUCTOR: - case SIZEOF_EXPR: - return; - - case COMPOUND_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - tmp_before = tmp_nosp = tmp_list3 = 0; - verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_nosp, NULL_TREE); - warn_for_collisions (tmp_nosp); - merge_tlist (pbefore_sp, tmp_before, 0); - merge_tlist (pbefore_sp, tmp_nosp, 0); - verify_tree (TREE_OPERAND (x, 1), &tmp_list3, pno_sp, NULL_TREE); - merge_tlist (pbefore_sp, tmp_list3, 0); - return; - - case COND_EXPR: - tmp_before = tmp_list2 = 0; - verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_list2, NULL_TREE); - warn_for_collisions (tmp_list2); - merge_tlist (pbefore_sp, tmp_before, 0); - merge_tlist (pbefore_sp, tmp_list2, 1); - - tmp_list3 = tmp_nosp = 0; - verify_tree (TREE_OPERAND (x, 1), &tmp_list3, &tmp_nosp, NULL_TREE); - warn_for_collisions (tmp_nosp); - merge_tlist (pbefore_sp, tmp_list3, 0); - - tmp_list3 = tmp_list2 = 0; - verify_tree (TREE_OPERAND (x, 2), &tmp_list3, &tmp_list2, NULL_TREE); - warn_for_collisions (tmp_list2); - merge_tlist (pbefore_sp, tmp_list3, 0); - /* Rather than add both tmp_nosp and tmp_list2, we have to merge the - two first, to avoid warning for (a ? b++ : b++). */ - merge_tlist (&tmp_nosp, tmp_list2, 0); - add_tlist (pno_sp, tmp_nosp, NULL_TREE, 0); - return; - - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - verify_tree (TREE_OPERAND (x, 0), pno_sp, pno_sp, x); - return; - - case MODIFY_EXPR: - tmp_before = tmp_nosp = tmp_list3 = 0; - verify_tree (TREE_OPERAND (x, 1), &tmp_before, &tmp_nosp, NULL_TREE); - verify_tree (TREE_OPERAND (x, 0), &tmp_list3, &tmp_list3, x); - /* Expressions inside the LHS are not ordered wrt. the sequence points - in the RHS. Example: - *a = (a++, 2) - Despite the fact that the modification of "a" is in the before_sp - list (tmp_before), it conflicts with the use of "a" in the LHS. - We can handle this by adding the contents of tmp_list3 - to those of tmp_before, and redoing the collision warnings for that - list. */ - add_tlist (&tmp_before, tmp_list3, x, 1); - warn_for_collisions (tmp_before); - /* Exclude the LHS itself here; we first have to merge it into the - tmp_nosp list. This is done to avoid warning for "a = a"; if we - didn't exclude the LHS, we'd get it twice, once as a read and once - as a write. */ - add_tlist (pno_sp, tmp_list3, x, 0); - warn_for_collisions_1 (TREE_OPERAND (x, 0), x, tmp_nosp, 1); - - merge_tlist (pbefore_sp, tmp_before, 0); - if (warning_candidate_p (TREE_OPERAND (x, 0))) - merge_tlist (&tmp_nosp, new_tlist (NULL, TREE_OPERAND (x, 0), x), 0); - add_tlist (pno_sp, tmp_nosp, NULL_TREE, 1); - return; - - case CALL_EXPR: - /* We need to warn about conflicts among arguments and conflicts between - args and the function address. Side effects of the function address, - however, are not ordered by the sequence point of the call. */ - { - call_expr_arg_iterator iter; - tree arg; - tmp_before = tmp_nosp = 0; - verify_tree (CALL_EXPR_FN (x), &tmp_before, &tmp_nosp, NULL_TREE); - FOR_EACH_CALL_EXPR_ARG (arg, iter, x) - { - tmp_list2 = tmp_list3 = 0; - verify_tree (arg, &tmp_list2, &tmp_list3, NULL_TREE); - merge_tlist (&tmp_list3, tmp_list2, 0); - add_tlist (&tmp_before, tmp_list3, NULL_TREE, 0); - } - add_tlist (&tmp_before, tmp_nosp, NULL_TREE, 0); - warn_for_collisions (tmp_before); - add_tlist (pbefore_sp, tmp_before, NULL_TREE, 0); - return; - } - - case TREE_LIST: - /* Scan all the list, e.g. indices of multi dimensional array. */ - while (x) - { - tmp_before = tmp_nosp = 0; - verify_tree (TREE_VALUE (x), &tmp_before, &tmp_nosp, NULL_TREE); - merge_tlist (&tmp_nosp, tmp_before, 0); - add_tlist (pno_sp, tmp_nosp, NULL_TREE, 0); - x = TREE_CHAIN (x); - } - return; - - case SAVE_EXPR: - { - struct tlist_cache *t; - for (t = save_expr_cache; t; t = t->next) - if (candidate_equal_p (t->expr, x)) - break; - - if (!t) - { - t = XOBNEW (&tlist_obstack, struct tlist_cache); - t->next = save_expr_cache; - t->expr = x; - save_expr_cache = t; - - tmp_before = tmp_nosp = 0; - verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_nosp, NULL_TREE); - warn_for_collisions (tmp_nosp); - - tmp_list3 = 0; - while (tmp_nosp) - { - struct tlist *t = tmp_nosp; - tmp_nosp = t->next; - merge_tlist (&tmp_list3, t, 0); - } - t->cache_before_sp = tmp_before; - t->cache_after_sp = tmp_list3; - } - merge_tlist (pbefore_sp, t->cache_before_sp, 1); - add_tlist (pno_sp, t->cache_after_sp, NULL_TREE, 1); - return; - } - - case ADDR_EXPR: - x = TREE_OPERAND (x, 0); - if (DECL_P (x)) - return; - writer = 0; - goto restart; - - default: - /* For other expressions, simply recurse on their operands. - Manual tail recursion for unary expressions. - Other non-expressions need not be processed. */ - if (cl == tcc_unary) - { - x = TREE_OPERAND (x, 0); - writer = 0; - goto restart; - } - else if (IS_EXPR_CODE_CLASS (cl)) - { - int lp; - int max = TREE_OPERAND_LENGTH (x); - for (lp = 0; lp < max; lp++) - { - tmp_before = tmp_nosp = 0; - verify_tree (TREE_OPERAND (x, lp), &tmp_before, &tmp_nosp, 0); - merge_tlist (&tmp_nosp, tmp_before, 0); - add_tlist (pno_sp, tmp_nosp, NULL_TREE, 0); - } - } - return; - } -} - -/* Try to warn for undefined behavior in EXPR due to missing sequence - points. */ - -DEBUG_FUNCTION void -verify_sequence_points (tree expr) -{ - struct tlist *before_sp = 0, *after_sp = 0; - - warned_ids = 0; - save_expr_cache = 0; - if (tlist_firstobj == 0) - { - gcc_obstack_init (&tlist_obstack); - tlist_firstobj = (char *) obstack_alloc (&tlist_obstack, 0); - } - - verify_tree (expr, &before_sp, &after_sp, 0); - warn_for_collisions (after_sp); - obstack_free (&tlist_obstack, tlist_firstobj); -} - -/* Validate the expression after `case' and apply default promotions. */ - -static tree -check_case_value (tree value) -{ - if (value == NULL_TREE) - return value; - - if (TREE_CODE (value) == INTEGER_CST) - /* Promote char or short to int. */ - value = perform_integral_promotions (value); - else if (value != error_mark_node) - { - error ("case label does not reduce to an integer constant"); - value = error_mark_node; - } - - constant_expression_warning (value); - - return value; -} - -/* See if the case values LOW and HIGH are in the range of the original - type (i.e. before the default conversion to int) of the switch testing - expression. - TYPE is the promoted type of the testing expression, and ORIG_TYPE is - the type before promoting it. CASE_LOW_P is a pointer to the lower - bound of the case label, and CASE_HIGH_P is the upper bound or NULL - if the case is not a case range. - The caller has to make sure that we are not called with NULL for - CASE_LOW_P (i.e. the default case). - Returns true if the case label is in range of ORIG_TYPE (saturated or - untouched) or false if the label is out of range. */ - -static bool -check_case_bounds (tree type, tree orig_type, - tree *case_low_p, tree *case_high_p) -{ - tree min_value, max_value; - tree case_low = *case_low_p; - tree case_high = case_high_p ? *case_high_p : case_low; - - /* If there was a problem with the original type, do nothing. */ - if (orig_type == error_mark_node) - return true; - - min_value = TYPE_MIN_VALUE (orig_type); - max_value = TYPE_MAX_VALUE (orig_type); - - /* Case label is less than minimum for type. */ - if (tree_int_cst_compare (case_low, min_value) < 0 - && tree_int_cst_compare (case_high, min_value) < 0) - { - warning (0, "case label value is less than minimum value for type"); - return false; - } - - /* Case value is greater than maximum for type. */ - if (tree_int_cst_compare (case_low, max_value) > 0 - && tree_int_cst_compare (case_high, max_value) > 0) - { - warning (0, "case label value exceeds maximum value for type"); - return false; - } - - /* Saturate lower case label value to minimum. */ - if (tree_int_cst_compare (case_high, min_value) >= 0 - && tree_int_cst_compare (case_low, min_value) < 0) - { - warning (0, "lower value in case label range" - " less than minimum value for type"); - case_low = min_value; - } - - /* Saturate upper case label value to maximum. */ - if (tree_int_cst_compare (case_low, max_value) <= 0 - && tree_int_cst_compare (case_high, max_value) > 0) - { - warning (0, "upper value in case label range" - " exceeds maximum value for type"); - case_high = max_value; - } - - if (*case_low_p != case_low) - *case_low_p = convert (type, case_low); - if (case_high_p && *case_high_p != case_high) - *case_high_p = convert (type, case_high); - - return true; -} - -/* Return an integer type with BITS bits of precision, - that is unsigned if UNSIGNEDP is nonzero, otherwise signed. */ - -tree -c_common_type_for_size (unsigned int bits, int unsignedp) -{ - if (bits == TYPE_PRECISION (integer_type_node)) - return unsignedp ? unsigned_type_node : integer_type_node; - - if (bits == TYPE_PRECISION (signed_char_type_node)) - return unsignedp ? unsigned_char_type_node : signed_char_type_node; - - if (bits == TYPE_PRECISION (short_integer_type_node)) - return unsignedp ? short_unsigned_type_node : short_integer_type_node; - - if (bits == TYPE_PRECISION (long_integer_type_node)) - return unsignedp ? long_unsigned_type_node : long_integer_type_node; - - if (bits == TYPE_PRECISION (long_long_integer_type_node)) - return (unsignedp ? long_long_unsigned_type_node - : long_long_integer_type_node); - - if (int128_integer_type_node - && bits == TYPE_PRECISION (int128_integer_type_node)) - return (unsignedp ? int128_unsigned_type_node - : int128_integer_type_node); - - if (bits == TYPE_PRECISION (widest_integer_literal_type_node)) - return (unsignedp ? widest_unsigned_literal_type_node - : widest_integer_literal_type_node); - - if (bits <= TYPE_PRECISION (intQI_type_node)) - return unsignedp ? unsigned_intQI_type_node : intQI_type_node; - - if (bits <= TYPE_PRECISION (intHI_type_node)) - return unsignedp ? unsigned_intHI_type_node : intHI_type_node; - - if (bits <= TYPE_PRECISION (intSI_type_node)) - return unsignedp ? unsigned_intSI_type_node : intSI_type_node; - - if (bits <= TYPE_PRECISION (intDI_type_node)) - return unsignedp ? unsigned_intDI_type_node : intDI_type_node; - - return 0; -} - -/* Return a fixed-point type that has at least IBIT ibits and FBIT fbits - that is unsigned if UNSIGNEDP is nonzero, otherwise signed; - and saturating if SATP is nonzero, otherwise not saturating. */ - -tree -c_common_fixed_point_type_for_size (unsigned int ibit, unsigned int fbit, - int unsignedp, int satp) -{ - enum machine_mode mode; - if (ibit == 0) - mode = unsignedp ? UQQmode : QQmode; - else - mode = unsignedp ? UHAmode : HAmode; - - for (; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) - if (GET_MODE_IBIT (mode) >= ibit && GET_MODE_FBIT (mode) >= fbit) - break; - - if (mode == VOIDmode || !targetm.scalar_mode_supported_p (mode)) - { - sorry ("GCC cannot support operators with integer types and " - "fixed-point types that have too many integral and " - "fractional bits together"); - return 0; - } - - return c_common_type_for_mode (mode, satp); -} - -/* Used for communication between c_common_type_for_mode and - c_register_builtin_type. */ -static GTY(()) tree registered_builtin_types; - -/* Return a data type that has machine mode MODE. - If the mode is an integer, - then UNSIGNEDP selects between signed and unsigned types. - If the mode is a fixed-point mode, - then UNSIGNEDP selects between saturating and nonsaturating types. */ - -tree -c_common_type_for_mode (enum machine_mode mode, int unsignedp) -{ - tree t; - - if (mode == TYPE_MODE (integer_type_node)) - return unsignedp ? unsigned_type_node : integer_type_node; - - if (mode == TYPE_MODE (signed_char_type_node)) - return unsignedp ? unsigned_char_type_node : signed_char_type_node; - - if (mode == TYPE_MODE (short_integer_type_node)) - return unsignedp ? short_unsigned_type_node : short_integer_type_node; - - if (mode == TYPE_MODE (long_integer_type_node)) - return unsignedp ? long_unsigned_type_node : long_integer_type_node; - - if (mode == TYPE_MODE (long_long_integer_type_node)) - return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node; - - if (int128_integer_type_node - && mode == TYPE_MODE (int128_integer_type_node)) - return unsignedp ? int128_unsigned_type_node : int128_integer_type_node; - - if (mode == TYPE_MODE (widest_integer_literal_type_node)) - return unsignedp ? widest_unsigned_literal_type_node - : widest_integer_literal_type_node; - - if (mode == QImode) - return unsignedp ? unsigned_intQI_type_node : intQI_type_node; - - if (mode == HImode) - return unsignedp ? unsigned_intHI_type_node : intHI_type_node; - - if (mode == SImode) - return unsignedp ? unsigned_intSI_type_node : intSI_type_node; - - if (mode == DImode) - return unsignedp ? unsigned_intDI_type_node : intDI_type_node; - -#if HOST_BITS_PER_WIDE_INT >= 64 - if (mode == TYPE_MODE (intTI_type_node)) - return unsignedp ? unsigned_intTI_type_node : intTI_type_node; -#endif - - if (mode == TYPE_MODE (float_type_node)) - return float_type_node; - - if (mode == TYPE_MODE (double_type_node)) - return double_type_node; - - if (mode == TYPE_MODE (long_double_type_node)) - return long_double_type_node; - - if (mode == TYPE_MODE (void_type_node)) - return void_type_node; - - if (mode == TYPE_MODE (build_pointer_type (char_type_node))) - return (unsignedp - ? make_unsigned_type (GET_MODE_PRECISION (mode)) - : make_signed_type (GET_MODE_PRECISION (mode))); - - if (mode == TYPE_MODE (build_pointer_type (integer_type_node))) - return (unsignedp - ? make_unsigned_type (GET_MODE_PRECISION (mode)) - : make_signed_type (GET_MODE_PRECISION (mode))); - - if (COMPLEX_MODE_P (mode)) - { - enum machine_mode inner_mode; - tree inner_type; - - if (mode == TYPE_MODE (complex_float_type_node)) - return complex_float_type_node; - if (mode == TYPE_MODE (complex_double_type_node)) - return complex_double_type_node; - if (mode == TYPE_MODE (complex_long_double_type_node)) - return complex_long_double_type_node; - - if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp) - return complex_integer_type_node; - - inner_mode = GET_MODE_INNER (mode); - inner_type = c_common_type_for_mode (inner_mode, unsignedp); - if (inner_type != NULL_TREE) - return build_complex_type (inner_type); - } - else if (VECTOR_MODE_P (mode)) - { - enum machine_mode inner_mode = GET_MODE_INNER (mode); - tree inner_type = c_common_type_for_mode (inner_mode, unsignedp); - if (inner_type != NULL_TREE) - return build_vector_type_for_mode (inner_type, mode); - } - - if (mode == TYPE_MODE (dfloat32_type_node)) - return dfloat32_type_node; - if (mode == TYPE_MODE (dfloat64_type_node)) - return dfloat64_type_node; - if (mode == TYPE_MODE (dfloat128_type_node)) - return dfloat128_type_node; - - if (ALL_SCALAR_FIXED_POINT_MODE_P (mode)) - { - if (mode == TYPE_MODE (short_fract_type_node)) - return unsignedp ? sat_short_fract_type_node : short_fract_type_node; - if (mode == TYPE_MODE (fract_type_node)) - return unsignedp ? sat_fract_type_node : fract_type_node; - if (mode == TYPE_MODE (long_fract_type_node)) - return unsignedp ? sat_long_fract_type_node : long_fract_type_node; - if (mode == TYPE_MODE (long_long_fract_type_node)) - return unsignedp ? sat_long_long_fract_type_node - : long_long_fract_type_node; - - if (mode == TYPE_MODE (unsigned_short_fract_type_node)) - return unsignedp ? sat_unsigned_short_fract_type_node - : unsigned_short_fract_type_node; - if (mode == TYPE_MODE (unsigned_fract_type_node)) - return unsignedp ? sat_unsigned_fract_type_node - : unsigned_fract_type_node; - if (mode == TYPE_MODE (unsigned_long_fract_type_node)) - return unsignedp ? sat_unsigned_long_fract_type_node - : unsigned_long_fract_type_node; - if (mode == TYPE_MODE (unsigned_long_long_fract_type_node)) - return unsignedp ? sat_unsigned_long_long_fract_type_node - : unsigned_long_long_fract_type_node; - - if (mode == TYPE_MODE (short_accum_type_node)) - return unsignedp ? sat_short_accum_type_node : short_accum_type_node; - if (mode == TYPE_MODE (accum_type_node)) - return unsignedp ? sat_accum_type_node : accum_type_node; - if (mode == TYPE_MODE (long_accum_type_node)) - return unsignedp ? sat_long_accum_type_node : long_accum_type_node; - if (mode == TYPE_MODE (long_long_accum_type_node)) - return unsignedp ? sat_long_long_accum_type_node - : long_long_accum_type_node; - - if (mode == TYPE_MODE (unsigned_short_accum_type_node)) - return unsignedp ? sat_unsigned_short_accum_type_node - : unsigned_short_accum_type_node; - if (mode == TYPE_MODE (unsigned_accum_type_node)) - return unsignedp ? sat_unsigned_accum_type_node - : unsigned_accum_type_node; - if (mode == TYPE_MODE (unsigned_long_accum_type_node)) - return unsignedp ? sat_unsigned_long_accum_type_node - : unsigned_long_accum_type_node; - if (mode == TYPE_MODE (unsigned_long_long_accum_type_node)) - return unsignedp ? sat_unsigned_long_long_accum_type_node - : unsigned_long_long_accum_type_node; - - if (mode == QQmode) - return unsignedp ? sat_qq_type_node : qq_type_node; - if (mode == HQmode) - return unsignedp ? sat_hq_type_node : hq_type_node; - if (mode == SQmode) - return unsignedp ? sat_sq_type_node : sq_type_node; - if (mode == DQmode) - return unsignedp ? sat_dq_type_node : dq_type_node; - if (mode == TQmode) - return unsignedp ? sat_tq_type_node : tq_type_node; - - if (mode == UQQmode) - return unsignedp ? sat_uqq_type_node : uqq_type_node; - if (mode == UHQmode) - return unsignedp ? sat_uhq_type_node : uhq_type_node; - if (mode == USQmode) - return unsignedp ? sat_usq_type_node : usq_type_node; - if (mode == UDQmode) - return unsignedp ? sat_udq_type_node : udq_type_node; - if (mode == UTQmode) - return unsignedp ? sat_utq_type_node : utq_type_node; - - if (mode == HAmode) - return unsignedp ? sat_ha_type_node : ha_type_node; - if (mode == SAmode) - return unsignedp ? sat_sa_type_node : sa_type_node; - if (mode == DAmode) - return unsignedp ? sat_da_type_node : da_type_node; - if (mode == TAmode) - return unsignedp ? sat_ta_type_node : ta_type_node; - - if (mode == UHAmode) - return unsignedp ? sat_uha_type_node : uha_type_node; - if (mode == USAmode) - return unsignedp ? sat_usa_type_node : usa_type_node; - if (mode == UDAmode) - return unsignedp ? sat_uda_type_node : uda_type_node; - if (mode == UTAmode) - return unsignedp ? sat_uta_type_node : uta_type_node; - } - - for (t = registered_builtin_types; t; t = TREE_CHAIN (t)) - if (TYPE_MODE (TREE_VALUE (t)) == mode - && !!unsignedp == !!TYPE_UNSIGNED (TREE_VALUE (t))) - return TREE_VALUE (t); - - return 0; -} - -tree -c_common_unsigned_type (tree type) -{ - return c_common_signed_or_unsigned_type (1, type); -} - -/* Return a signed type the same as TYPE in other respects. */ - -tree -c_common_signed_type (tree type) -{ - return c_common_signed_or_unsigned_type (0, type); -} - -/* Return a type the same as TYPE except unsigned or - signed according to UNSIGNEDP. */ - -tree -c_common_signed_or_unsigned_type (int unsignedp, tree type) -{ - tree type1; - - /* This block of code emulates the behavior of the old - c_common_unsigned_type. In particular, it returns - long_unsigned_type_node if passed a long, even when a int would - have the same size. This is necessary for warnings to work - correctly in archs where sizeof(int) == sizeof(long) */ - - type1 = TYPE_MAIN_VARIANT (type); - if (type1 == signed_char_type_node || type1 == char_type_node || type1 == unsigned_char_type_node) - return unsignedp ? unsigned_char_type_node : signed_char_type_node; - if (type1 == integer_type_node || type1 == unsigned_type_node) - return unsignedp ? unsigned_type_node : integer_type_node; - if (type1 == short_integer_type_node || type1 == short_unsigned_type_node) - return unsignedp ? short_unsigned_type_node : short_integer_type_node; - if (type1 == long_integer_type_node || type1 == long_unsigned_type_node) - return unsignedp ? long_unsigned_type_node : long_integer_type_node; - if (type1 == long_long_integer_type_node || type1 == long_long_unsigned_type_node) - return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node; - if (int128_integer_type_node - && (type1 == int128_integer_type_node - || type1 == int128_unsigned_type_node)) - return unsignedp ? int128_unsigned_type_node : int128_integer_type_node; - if (type1 == widest_integer_literal_type_node || type1 == widest_unsigned_literal_type_node) - return unsignedp ? widest_unsigned_literal_type_node : widest_integer_literal_type_node; -#if HOST_BITS_PER_WIDE_INT >= 64 - if (type1 == intTI_type_node || type1 == unsigned_intTI_type_node) - return unsignedp ? unsigned_intTI_type_node : intTI_type_node; -#endif - if (type1 == intDI_type_node || type1 == unsigned_intDI_type_node) - return unsignedp ? unsigned_intDI_type_node : intDI_type_node; - if (type1 == intSI_type_node || type1 == unsigned_intSI_type_node) - return unsignedp ? unsigned_intSI_type_node : intSI_type_node; - if (type1 == intHI_type_node || type1 == unsigned_intHI_type_node) - return unsignedp ? unsigned_intHI_type_node : intHI_type_node; - if (type1 == intQI_type_node || type1 == unsigned_intQI_type_node) - return unsignedp ? unsigned_intQI_type_node : intQI_type_node; - -#define C_COMMON_FIXED_TYPES(NAME) \ - if (type1 == short_ ## NAME ## _type_node \ - || type1 == unsigned_short_ ## NAME ## _type_node) \ - return unsignedp ? unsigned_short_ ## NAME ## _type_node \ - : short_ ## NAME ## _type_node; \ - if (type1 == NAME ## _type_node \ - || type1 == unsigned_ ## NAME ## _type_node) \ - return unsignedp ? unsigned_ ## NAME ## _type_node \ - : NAME ## _type_node; \ - if (type1 == long_ ## NAME ## _type_node \ - || type1 == unsigned_long_ ## NAME ## _type_node) \ - return unsignedp ? unsigned_long_ ## NAME ## _type_node \ - : long_ ## NAME ## _type_node; \ - if (type1 == long_long_ ## NAME ## _type_node \ - || type1 == unsigned_long_long_ ## NAME ## _type_node) \ - return unsignedp ? unsigned_long_long_ ## NAME ## _type_node \ - : long_long_ ## NAME ## _type_node; - -#define C_COMMON_FIXED_MODE_TYPES(NAME) \ - if (type1 == NAME ## _type_node \ - || type1 == u ## NAME ## _type_node) \ - return unsignedp ? u ## NAME ## _type_node \ - : NAME ## _type_node; - -#define C_COMMON_FIXED_TYPES_SAT(NAME) \ - if (type1 == sat_ ## short_ ## NAME ## _type_node \ - || type1 == sat_ ## unsigned_short_ ## NAME ## _type_node) \ - return unsignedp ? sat_ ## unsigned_short_ ## NAME ## _type_node \ - : sat_ ## short_ ## NAME ## _type_node; \ - if (type1 == sat_ ## NAME ## _type_node \ - || type1 == sat_ ## unsigned_ ## NAME ## _type_node) \ - return unsignedp ? sat_ ## unsigned_ ## NAME ## _type_node \ - : sat_ ## NAME ## _type_node; \ - if (type1 == sat_ ## long_ ## NAME ## _type_node \ - || type1 == sat_ ## unsigned_long_ ## NAME ## _type_node) \ - return unsignedp ? sat_ ## unsigned_long_ ## NAME ## _type_node \ - : sat_ ## long_ ## NAME ## _type_node; \ - if (type1 == sat_ ## long_long_ ## NAME ## _type_node \ - || type1 == sat_ ## unsigned_long_long_ ## NAME ## _type_node) \ - return unsignedp ? sat_ ## unsigned_long_long_ ## NAME ## _type_node \ - : sat_ ## long_long_ ## NAME ## _type_node; - -#define C_COMMON_FIXED_MODE_TYPES_SAT(NAME) \ - if (type1 == sat_ ## NAME ## _type_node \ - || type1 == sat_ ## u ## NAME ## _type_node) \ - return unsignedp ? sat_ ## u ## NAME ## _type_node \ - : sat_ ## NAME ## _type_node; - - C_COMMON_FIXED_TYPES (fract); - C_COMMON_FIXED_TYPES_SAT (fract); - C_COMMON_FIXED_TYPES (accum); - C_COMMON_FIXED_TYPES_SAT (accum); - - C_COMMON_FIXED_MODE_TYPES (qq); - C_COMMON_FIXED_MODE_TYPES (hq); - C_COMMON_FIXED_MODE_TYPES (sq); - C_COMMON_FIXED_MODE_TYPES (dq); - C_COMMON_FIXED_MODE_TYPES (tq); - C_COMMON_FIXED_MODE_TYPES_SAT (qq); - C_COMMON_FIXED_MODE_TYPES_SAT (hq); - C_COMMON_FIXED_MODE_TYPES_SAT (sq); - C_COMMON_FIXED_MODE_TYPES_SAT (dq); - C_COMMON_FIXED_MODE_TYPES_SAT (tq); - C_COMMON_FIXED_MODE_TYPES (ha); - C_COMMON_FIXED_MODE_TYPES (sa); - C_COMMON_FIXED_MODE_TYPES (da); - C_COMMON_FIXED_MODE_TYPES (ta); - C_COMMON_FIXED_MODE_TYPES_SAT (ha); - C_COMMON_FIXED_MODE_TYPES_SAT (sa); - C_COMMON_FIXED_MODE_TYPES_SAT (da); - C_COMMON_FIXED_MODE_TYPES_SAT (ta); - - /* For ENUMERAL_TYPEs in C++, must check the mode of the types, not - the precision; they have precision set to match their range, but - may use a wider mode to match an ABI. If we change modes, we may - wind up with bad conversions. For INTEGER_TYPEs in C, must check - the precision as well, so as to yield correct results for - bit-field types. C++ does not have these separate bit-field - types, and producing a signed or unsigned variant of an - ENUMERAL_TYPE may cause other problems as well. */ - - if (!INTEGRAL_TYPE_P (type) - || TYPE_UNSIGNED (type) == unsignedp) - return type; - -#define TYPE_OK(node) \ - (TYPE_MODE (type) == TYPE_MODE (node) \ - && TYPE_PRECISION (type) == TYPE_PRECISION (node)) - if (TYPE_OK (signed_char_type_node)) - return unsignedp ? unsigned_char_type_node : signed_char_type_node; - if (TYPE_OK (integer_type_node)) - return unsignedp ? unsigned_type_node : integer_type_node; - if (TYPE_OK (short_integer_type_node)) - return unsignedp ? short_unsigned_type_node : short_integer_type_node; - if (TYPE_OK (long_integer_type_node)) - return unsignedp ? long_unsigned_type_node : long_integer_type_node; - if (TYPE_OK (long_long_integer_type_node)) - return (unsignedp ? long_long_unsigned_type_node - : long_long_integer_type_node); - if (int128_integer_type_node && TYPE_OK (int128_integer_type_node)) - return (unsignedp ? int128_unsigned_type_node - : int128_integer_type_node); - if (TYPE_OK (widest_integer_literal_type_node)) - return (unsignedp ? widest_unsigned_literal_type_node - : widest_integer_literal_type_node); - -#if HOST_BITS_PER_WIDE_INT >= 64 - if (TYPE_OK (intTI_type_node)) - return unsignedp ? unsigned_intTI_type_node : intTI_type_node; -#endif - if (TYPE_OK (intDI_type_node)) - return unsignedp ? unsigned_intDI_type_node : intDI_type_node; - if (TYPE_OK (intSI_type_node)) - return unsignedp ? unsigned_intSI_type_node : intSI_type_node; - if (TYPE_OK (intHI_type_node)) - return unsignedp ? unsigned_intHI_type_node : intHI_type_node; - if (TYPE_OK (intQI_type_node)) - return unsignedp ? unsigned_intQI_type_node : intQI_type_node; -#undef TYPE_OK - - return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp); -} - -/* Build a bit-field integer type for the given WIDTH and UNSIGNEDP. */ - -tree -c_build_bitfield_integer_type (unsigned HOST_WIDE_INT width, int unsignedp) -{ - /* Extended integer types of the same width as a standard type have - lesser rank, so those of the same width as int promote to int or - unsigned int and are valid for printf formats expecting int or - unsigned int. To avoid such special cases, avoid creating - extended integer types for bit-fields if a standard integer type - is available. */ - if (width == TYPE_PRECISION (integer_type_node)) - return unsignedp ? unsigned_type_node : integer_type_node; - if (width == TYPE_PRECISION (signed_char_type_node)) - return unsignedp ? unsigned_char_type_node : signed_char_type_node; - if (width == TYPE_PRECISION (short_integer_type_node)) - return unsignedp ? short_unsigned_type_node : short_integer_type_node; - if (width == TYPE_PRECISION (long_integer_type_node)) - return unsignedp ? long_unsigned_type_node : long_integer_type_node; - if (width == TYPE_PRECISION (long_long_integer_type_node)) - return (unsignedp ? long_long_unsigned_type_node - : long_long_integer_type_node); - if (int128_integer_type_node - && width == TYPE_PRECISION (int128_integer_type_node)) - return (unsignedp ? int128_unsigned_type_node - : int128_integer_type_node); - return build_nonstandard_integer_type (width, unsignedp); -} - -/* The C version of the register_builtin_type langhook. */ - -void -c_register_builtin_type (tree type, const char* name) -{ - tree decl; - - decl = build_decl (UNKNOWN_LOCATION, - TYPE_DECL, get_identifier (name), type); - DECL_ARTIFICIAL (decl) = 1; - if (!TYPE_NAME (type)) - TYPE_NAME (type) = decl; - pushdecl (decl); - - registered_builtin_types = tree_cons (0, type, registered_builtin_types); -} - -/* Print an error message for invalid operands to arith operation - CODE with TYPE0 for operand 0, and TYPE1 for operand 1. - LOCATION is the location of the message. */ - -void -binary_op_error (location_t location, enum tree_code code, - tree type0, tree type1) -{ - const char *opname; - - switch (code) - { - case PLUS_EXPR: - opname = "+"; break; - case MINUS_EXPR: - opname = "-"; break; - case MULT_EXPR: - opname = "*"; break; - case MAX_EXPR: - opname = "max"; break; - case MIN_EXPR: - opname = "min"; break; - case EQ_EXPR: - opname = "=="; break; - case NE_EXPR: - opname = "!="; break; - case LE_EXPR: - opname = "<="; break; - case GE_EXPR: - opname = ">="; break; - case LT_EXPR: - opname = "<"; break; - case GT_EXPR: - opname = ">"; break; - case LSHIFT_EXPR: - opname = "<<"; break; - case RSHIFT_EXPR: - opname = ">>"; break; - case TRUNC_MOD_EXPR: - case FLOOR_MOD_EXPR: - opname = "%"; break; - case TRUNC_DIV_EXPR: - case FLOOR_DIV_EXPR: - opname = "/"; break; - case BIT_AND_EXPR: - opname = "&"; break; - case BIT_IOR_EXPR: - opname = "|"; break; - case TRUTH_ANDIF_EXPR: - opname = "&&"; break; - case TRUTH_ORIF_EXPR: - opname = "||"; break; - case BIT_XOR_EXPR: - opname = "^"; break; - default: - gcc_unreachable (); - } - error_at (location, - "invalid operands to binary %s (have %qT and %qT)", opname, - type0, type1); -} - -/* Given an expression as a tree, return its original type. Do this - by stripping any conversion that preserves the sign and precision. */ -static tree -expr_original_type (tree expr) -{ - STRIP_SIGN_NOPS (expr); - return TREE_TYPE (expr); -} - -/* Subroutine of build_binary_op, used for comparison operations. - See if the operands have both been converted from subword integer types - and, if so, perhaps change them both back to their original type. - This function is also responsible for converting the two operands - to the proper common type for comparison. - - The arguments of this function are all pointers to local variables - of build_binary_op: OP0_PTR is &OP0, OP1_PTR is &OP1, - RESTYPE_PTR is &RESULT_TYPE and RESCODE_PTR is &RESULTCODE. - - If this function returns nonzero, it means that the comparison has - a constant value. What this function returns is an expression for - that value. */ - -tree -shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr, - enum tree_code *rescode_ptr) -{ - tree type; - tree op0 = *op0_ptr; - tree op1 = *op1_ptr; - int unsignedp0, unsignedp1; - int real1, real2; - tree primop0, primop1; - enum tree_code code = *rescode_ptr; - location_t loc = EXPR_LOC_OR_HERE (op0); - - /* Throw away any conversions to wider types - already present in the operands. */ - - primop0 = c_common_get_narrower (op0, &unsignedp0); - primop1 = c_common_get_narrower (op1, &unsignedp1); - - /* If primopN is first sign-extended from primopN's precision to opN's - precision, then zero-extended from opN's precision to - *restype_ptr precision, shortenings might be invalid. */ - if (TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (TREE_TYPE (op0)) - && TYPE_PRECISION (TREE_TYPE (op0)) < TYPE_PRECISION (*restype_ptr) - && !unsignedp0 - && TYPE_UNSIGNED (TREE_TYPE (op0))) - primop0 = op0; - if (TYPE_PRECISION (TREE_TYPE (primop1)) < TYPE_PRECISION (TREE_TYPE (op1)) - && TYPE_PRECISION (TREE_TYPE (op1)) < TYPE_PRECISION (*restype_ptr) - && !unsignedp1 - && TYPE_UNSIGNED (TREE_TYPE (op1))) - primop1 = op1; - - /* Handle the case that OP0 does not *contain* a conversion - but it *requires* conversion to FINAL_TYPE. */ - - if (op0 == primop0 && TREE_TYPE (op0) != *restype_ptr) - unsignedp0 = TYPE_UNSIGNED (TREE_TYPE (op0)); - if (op1 == primop1 && TREE_TYPE (op1) != *restype_ptr) - unsignedp1 = TYPE_UNSIGNED (TREE_TYPE (op1)); - - /* If one of the operands must be floated, we cannot optimize. */ - real1 = TREE_CODE (TREE_TYPE (primop0)) == REAL_TYPE; - real2 = TREE_CODE (TREE_TYPE (primop1)) == REAL_TYPE; - - /* If first arg is constant, swap the args (changing operation - so value is preserved), for canonicalization. Don't do this if - the second arg is 0. */ - - if (TREE_CONSTANT (primop0) - && !integer_zerop (primop1) && !real_zerop (primop1) - && !fixed_zerop (primop1)) - { - tree tem = primop0; - int temi = unsignedp0; - primop0 = primop1; - primop1 = tem; - tem = op0; - op0 = op1; - op1 = tem; - *op0_ptr = op0; - *op1_ptr = op1; - unsignedp0 = unsignedp1; - unsignedp1 = temi; - temi = real1; - real1 = real2; - real2 = temi; - - switch (code) - { - case LT_EXPR: - code = GT_EXPR; - break; - case GT_EXPR: - code = LT_EXPR; - break; - case LE_EXPR: - code = GE_EXPR; - break; - case GE_EXPR: - code = LE_EXPR; - break; - default: - break; - } - *rescode_ptr = code; - } - - /* If comparing an integer against a constant more bits wide, - maybe we can deduce a value of 1 or 0 independent of the data. - Or else truncate the constant now - rather than extend the variable at run time. - - This is only interesting if the constant is the wider arg. - Also, it is not safe if the constant is unsigned and the - variable arg is signed, since in this case the variable - would be sign-extended and then regarded as unsigned. - Our technique fails in this case because the lowest/highest - possible unsigned results don't follow naturally from the - lowest/highest possible values of the variable operand. - For just EQ_EXPR and NE_EXPR there is another technique that - could be used: see if the constant can be faithfully represented - in the other operand's type, by truncating it and reextending it - and see if that preserves the constant's value. */ - - if (!real1 && !real2 - && TREE_CODE (TREE_TYPE (primop0)) != FIXED_POINT_TYPE - && TREE_CODE (primop1) == INTEGER_CST - && TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (*restype_ptr)) - { - int min_gt, max_gt, min_lt, max_lt; - tree maxval, minval; - /* 1 if comparison is nominally unsigned. */ - int unsignedp = TYPE_UNSIGNED (*restype_ptr); - tree val; - - type = c_common_signed_or_unsigned_type (unsignedp0, - TREE_TYPE (primop0)); - - maxval = TYPE_MAX_VALUE (type); - minval = TYPE_MIN_VALUE (type); - - if (unsignedp && !unsignedp0) - *restype_ptr = c_common_signed_type (*restype_ptr); - - if (TREE_TYPE (primop1) != *restype_ptr) - { - /* Convert primop1 to target type, but do not introduce - additional overflow. We know primop1 is an int_cst. */ - primop1 = force_fit_type_double (*restype_ptr, - tree_to_double_int (primop1), - 0, TREE_OVERFLOW (primop1)); - } - if (type != *restype_ptr) - { - minval = convert (*restype_ptr, minval); - maxval = convert (*restype_ptr, maxval); - } - - if (unsignedp && unsignedp0) - { - min_gt = INT_CST_LT_UNSIGNED (primop1, minval); - max_gt = INT_CST_LT_UNSIGNED (primop1, maxval); - min_lt = INT_CST_LT_UNSIGNED (minval, primop1); - max_lt = INT_CST_LT_UNSIGNED (maxval, primop1); - } - else - { - min_gt = INT_CST_LT (primop1, minval); - max_gt = INT_CST_LT (primop1, maxval); - min_lt = INT_CST_LT (minval, primop1); - max_lt = INT_CST_LT (maxval, primop1); - } - - val = 0; - /* This used to be a switch, but Genix compiler can't handle that. */ - if (code == NE_EXPR) - { - if (max_lt || min_gt) - val = truthvalue_true_node; - } - else if (code == EQ_EXPR) - { - if (max_lt || min_gt) - val = truthvalue_false_node; - } - else if (code == LT_EXPR) - { - if (max_lt) - val = truthvalue_true_node; - if (!min_lt) - val = truthvalue_false_node; - } - else if (code == GT_EXPR) - { - if (min_gt) - val = truthvalue_true_node; - if (!max_gt) - val = truthvalue_false_node; - } - else if (code == LE_EXPR) - { - if (!max_gt) - val = truthvalue_true_node; - if (min_gt) - val = truthvalue_false_node; - } - else if (code == GE_EXPR) - { - if (!min_lt) - val = truthvalue_true_node; - if (max_lt) - val = truthvalue_false_node; - } - - /* If primop0 was sign-extended and unsigned comparison specd, - we did a signed comparison above using the signed type bounds. - But the comparison we output must be unsigned. - - Also, for inequalities, VAL is no good; but if the signed - comparison had *any* fixed result, it follows that the - unsigned comparison just tests the sign in reverse - (positive values are LE, negative ones GE). - So we can generate an unsigned comparison - against an extreme value of the signed type. */ - - if (unsignedp && !unsignedp0) - { - if (val != 0) - switch (code) - { - case LT_EXPR: - case GE_EXPR: - primop1 = TYPE_MIN_VALUE (type); - val = 0; - break; - - case LE_EXPR: - case GT_EXPR: - primop1 = TYPE_MAX_VALUE (type); - val = 0; - break; - - default: - break; - } - type = c_common_unsigned_type (type); - } - - if (TREE_CODE (primop0) != INTEGER_CST - && c_inhibit_evaluation_warnings == 0) - { - if (val == truthvalue_false_node) - warning_at (loc, OPT_Wtype_limits, - "comparison is always false due to limited range of data type"); - if (val == truthvalue_true_node) - warning_at (loc, OPT_Wtype_limits, - "comparison is always true due to limited range of data type"); - } - - if (val != 0) - { - /* Don't forget to evaluate PRIMOP0 if it has side effects. */ - if (TREE_SIDE_EFFECTS (primop0)) - return build2 (COMPOUND_EXPR, TREE_TYPE (val), primop0, val); - return val; - } - - /* Value is not predetermined, but do the comparison - in the type of the operand that is not constant. - TYPE is already properly set. */ - } - - /* If either arg is decimal float and the other is float, find the - proper common type to use for comparison. */ - else if (real1 && real2 - && (DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (primop0))) - || DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (primop1))))) - type = common_type (TREE_TYPE (primop0), TREE_TYPE (primop1)); - - else if (real1 && real2 - && (TYPE_PRECISION (TREE_TYPE (primop0)) - == TYPE_PRECISION (TREE_TYPE (primop1)))) - type = TREE_TYPE (primop0); - - /* If args' natural types are both narrower than nominal type - and both extend in the same manner, compare them - in the type of the wider arg. - Otherwise must actually extend both to the nominal - common type lest different ways of extending - alter the result. - (eg, (short)-1 == (unsigned short)-1 should be 0.) */ - - else if (unsignedp0 == unsignedp1 && real1 == real2 - && TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (*restype_ptr) - && TYPE_PRECISION (TREE_TYPE (primop1)) < TYPE_PRECISION (*restype_ptr)) - { - type = common_type (TREE_TYPE (primop0), TREE_TYPE (primop1)); - type = c_common_signed_or_unsigned_type (unsignedp0 - || TYPE_UNSIGNED (*restype_ptr), - type); - /* Make sure shorter operand is extended the right way - to match the longer operand. */ - primop0 - = convert (c_common_signed_or_unsigned_type (unsignedp0, - TREE_TYPE (primop0)), - primop0); - primop1 - = convert (c_common_signed_or_unsigned_type (unsignedp1, - TREE_TYPE (primop1)), - primop1); - } - else - { - /* Here we must do the comparison on the nominal type - using the args exactly as we received them. */ - type = *restype_ptr; - primop0 = op0; - primop1 = op1; - - if (!real1 && !real2 && integer_zerop (primop1) - && TYPE_UNSIGNED (*restype_ptr)) - { - tree value = 0; - /* All unsigned values are >= 0, so we warn. However, - if OP0 is a constant that is >= 0, the signedness of - the comparison isn't an issue, so suppress the - warning. */ - bool warn = - warn_type_limits && !in_system_header - && c_inhibit_evaluation_warnings == 0 - && !(TREE_CODE (primop0) == INTEGER_CST - && !TREE_OVERFLOW (convert (c_common_signed_type (type), - primop0))) - /* Do not warn for enumeration types. */ - && (TREE_CODE (expr_original_type (primop0)) != ENUMERAL_TYPE); - - switch (code) - { - case GE_EXPR: - if (warn) - warning_at (loc, OPT_Wtype_limits, - "comparison of unsigned expression >= 0 is always true"); - value = truthvalue_true_node; - break; - - case LT_EXPR: - if (warn) - warning_at (loc, OPT_Wtype_limits, - "comparison of unsigned expression < 0 is always false"); - value = truthvalue_false_node; - break; - - default: - break; - } - - if (value != 0) - { - /* Don't forget to evaluate PRIMOP0 if it has side effects. */ - if (TREE_SIDE_EFFECTS (primop0)) - return build2 (COMPOUND_EXPR, TREE_TYPE (value), - primop0, value); - return value; - } - } - } - - *op0_ptr = convert (type, primop0); - *op1_ptr = convert (type, primop1); - - *restype_ptr = truthvalue_type_node; - - return 0; -} - -/* Return a tree for the sum or difference (RESULTCODE says which) - of pointer PTROP and integer INTOP. */ - -tree -pointer_int_sum (location_t loc, enum tree_code resultcode, - tree ptrop, tree intop) -{ - tree size_exp, ret; - - /* The result is a pointer of the same type that is being added. */ - tree result_type = TREE_TYPE (ptrop); - - if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE) - { - pedwarn (loc, pedantic ? OPT_Wpedantic : OPT_Wpointer_arith, - "pointer of type %<void *%> used in arithmetic"); - size_exp = integer_one_node; - } - else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE) - { - pedwarn (loc, pedantic ? OPT_Wpedantic : OPT_Wpointer_arith, - "pointer to a function used in arithmetic"); - size_exp = integer_one_node; - } - else if (TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE) - { - pedwarn (loc, pedantic ? OPT_Wpedantic : OPT_Wpointer_arith, - "pointer to member function used in arithmetic"); - size_exp = integer_one_node; - } - else - size_exp = size_in_bytes (TREE_TYPE (result_type)); - - /* We are manipulating pointer values, so we don't need to warn - about relying on undefined signed overflow. We disable the - warning here because we use integer types so fold won't know that - they are really pointers. */ - fold_defer_overflow_warnings (); - - /* If what we are about to multiply by the size of the elements - contains a constant term, apply distributive law - and multiply that constant term separately. - This helps produce common subexpressions. */ - if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR) - && !TREE_CONSTANT (intop) - && TREE_CONSTANT (TREE_OPERAND (intop, 1)) - && TREE_CONSTANT (size_exp) - /* If the constant comes from pointer subtraction, - skip this optimization--it would cause an error. */ - && TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE - /* If the constant is unsigned, and smaller than the pointer size, - then we must skip this optimization. This is because it could cause - an overflow error if the constant is negative but INTOP is not. */ - && (!TYPE_UNSIGNED (TREE_TYPE (intop)) - || (TYPE_PRECISION (TREE_TYPE (intop)) - == TYPE_PRECISION (TREE_TYPE (ptrop))))) - { - enum tree_code subcode = resultcode; - tree int_type = TREE_TYPE (intop); - if (TREE_CODE (intop) == MINUS_EXPR) - subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR); - /* Convert both subexpression types to the type of intop, - because weird cases involving pointer arithmetic - can result in a sum or difference with different type args. */ - ptrop = build_binary_op (EXPR_LOCATION (TREE_OPERAND (intop, 1)), - subcode, ptrop, - convert (int_type, TREE_OPERAND (intop, 1)), 1); - intop = convert (int_type, TREE_OPERAND (intop, 0)); - } - - /* Convert the integer argument to a type the same size as sizetype - so the multiply won't overflow spuriously. */ - if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype) - || TYPE_UNSIGNED (TREE_TYPE (intop)) != TYPE_UNSIGNED (sizetype)) - intop = convert (c_common_type_for_size (TYPE_PRECISION (sizetype), - TYPE_UNSIGNED (sizetype)), intop); - - /* Replace the integer argument with a suitable product by the object size. - Do this multiplication as signed, then convert to the appropriate type - for the pointer operation and disregard an overflow that occurred only - because of the sign-extension change in the latter conversion. */ - { - tree t = build_binary_op (loc, - MULT_EXPR, intop, - convert (TREE_TYPE (intop), size_exp), 1); - intop = convert (sizetype, t); - if (TREE_OVERFLOW_P (intop) && !TREE_OVERFLOW (t)) - intop = build_int_cst_wide (TREE_TYPE (intop), TREE_INT_CST_LOW (intop), - TREE_INT_CST_HIGH (intop)); - } - - /* Create the sum or difference. */ - if (resultcode == MINUS_EXPR) - intop = fold_build1_loc (loc, NEGATE_EXPR, sizetype, intop); - - ret = fold_build_pointer_plus_loc (loc, ptrop, intop); - - fold_undefer_and_ignore_overflow_warnings (); - - return ret; -} - -/* Wrap a C_MAYBE_CONST_EXPR around an expression that is fully folded - and if NON_CONST is known not to be permitted in an evaluated part - of a constant expression. */ - -tree -c_wrap_maybe_const (tree expr, bool non_const) -{ - bool nowarning = TREE_NO_WARNING (expr); - location_t loc = EXPR_LOCATION (expr); - - /* This should never be called for C++. */ - if (c_dialect_cxx ()) - gcc_unreachable (); - - /* The result of folding may have a NOP_EXPR to set TREE_NO_WARNING. */ - STRIP_TYPE_NOPS (expr); - expr = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (expr), NULL, expr); - C_MAYBE_CONST_EXPR_NON_CONST (expr) = non_const; - if (nowarning) - TREE_NO_WARNING (expr) = 1; - protected_set_expr_location (expr, loc); - - return expr; -} - -/* Wrap a SAVE_EXPR around EXPR, if appropriate. Like save_expr, but - for C folds the inside expression and wraps a C_MAYBE_CONST_EXPR - around the SAVE_EXPR if needed so that c_fully_fold does not need - to look inside SAVE_EXPRs. */ - -tree -c_save_expr (tree expr) -{ - bool maybe_const = true; - if (c_dialect_cxx ()) - return save_expr (expr); - expr = c_fully_fold (expr, false, &maybe_const); - expr = save_expr (expr); - if (!maybe_const) - expr = c_wrap_maybe_const (expr, true); - return expr; -} - -/* Return whether EXPR is a declaration whose address can never be - NULL. */ - -bool -decl_with_nonnull_addr_p (const_tree expr) -{ - return (DECL_P (expr) - && (TREE_CODE (expr) == PARM_DECL - || TREE_CODE (expr) == LABEL_DECL - || !DECL_WEAK (expr))); -} - -/* Prepare expr to be an argument of a TRUTH_NOT_EXPR, - or for an `if' or `while' statement or ?..: exp. It should already - have been validated to be of suitable type; otherwise, a bad - diagnostic may result. - - The EXPR is located at LOCATION. - - This preparation consists of taking the ordinary - representation of an expression expr and producing a valid tree - boolean expression describing whether expr is nonzero. We could - simply always do build_binary_op (NE_EXPR, expr, truthvalue_false_node, 1), - but we optimize comparisons, &&, ||, and !. - - The resulting type should always be `truthvalue_type_node'. */ - -tree -c_common_truthvalue_conversion (location_t location, tree expr) -{ - switch (TREE_CODE (expr)) - { - case EQ_EXPR: case NE_EXPR: case UNEQ_EXPR: case LTGT_EXPR: - case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR: - case UNLE_EXPR: case UNGE_EXPR: case UNLT_EXPR: case UNGT_EXPR: - case ORDERED_EXPR: case UNORDERED_EXPR: - if (TREE_TYPE (expr) == truthvalue_type_node) - return expr; - expr = build2 (TREE_CODE (expr), truthvalue_type_node, - TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1)); - goto ret; - - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case TRUTH_XOR_EXPR: - if (TREE_TYPE (expr) == truthvalue_type_node) - return expr; - expr = build2 (TREE_CODE (expr), truthvalue_type_node, - c_common_truthvalue_conversion (location, - TREE_OPERAND (expr, 0)), - c_common_truthvalue_conversion (location, - TREE_OPERAND (expr, 1))); - goto ret; - - case TRUTH_NOT_EXPR: - if (TREE_TYPE (expr) == truthvalue_type_node) - return expr; - expr = build1 (TREE_CODE (expr), truthvalue_type_node, - c_common_truthvalue_conversion (location, - TREE_OPERAND (expr, 0))); - goto ret; - - case ERROR_MARK: - return expr; - - case INTEGER_CST: - return integer_zerop (expr) ? truthvalue_false_node - : truthvalue_true_node; - - case REAL_CST: - return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst0) - ? truthvalue_true_node - : truthvalue_false_node; - - case FIXED_CST: - return fixed_compare (NE_EXPR, &TREE_FIXED_CST (expr), - &FCONST0 (TYPE_MODE (TREE_TYPE (expr)))) - ? truthvalue_true_node - : truthvalue_false_node; - - case FUNCTION_DECL: - expr = build_unary_op (location, ADDR_EXPR, expr, 0); - /* Fall through. */ - - case ADDR_EXPR: - { - tree inner = TREE_OPERAND (expr, 0); - if (decl_with_nonnull_addr_p (inner)) - { - /* Common Ada/Pascal programmer's mistake. */ - warning_at (location, - OPT_Waddress, - "the address of %qD will always evaluate as %<true%>", - inner); - return truthvalue_true_node; - } - break; - } - - case COMPLEX_EXPR: - expr = build_binary_op (EXPR_LOCATION (expr), - (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)) - ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR), - c_common_truthvalue_conversion (location, - TREE_OPERAND (expr, 0)), - c_common_truthvalue_conversion (location, - TREE_OPERAND (expr, 1)), - 0); - goto ret; - - case NEGATE_EXPR: - case ABS_EXPR: - case FLOAT_EXPR: - case EXCESS_PRECISION_EXPR: - /* These don't change whether an object is nonzero or zero. */ - return c_common_truthvalue_conversion (location, TREE_OPERAND (expr, 0)); - - case LROTATE_EXPR: - case RROTATE_EXPR: - /* These don't change whether an object is zero or nonzero, but - we can't ignore them if their second arg has side-effects. */ - if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))) - { - expr = build2 (COMPOUND_EXPR, truthvalue_type_node, - TREE_OPERAND (expr, 1), - c_common_truthvalue_conversion - (location, TREE_OPERAND (expr, 0))); - goto ret; - } - else - return c_common_truthvalue_conversion (location, - TREE_OPERAND (expr, 0)); - - case COND_EXPR: - /* Distribute the conversion into the arms of a COND_EXPR. */ - if (c_dialect_cxx ()) - { - tree op1 = TREE_OPERAND (expr, 1); - tree op2 = TREE_OPERAND (expr, 2); - /* In C++ one of the arms might have void type if it is throw. */ - if (!VOID_TYPE_P (TREE_TYPE (op1))) - op1 = c_common_truthvalue_conversion (location, op1); - if (!VOID_TYPE_P (TREE_TYPE (op2))) - op2 = c_common_truthvalue_conversion (location, op2); - expr = fold_build3_loc (location, COND_EXPR, truthvalue_type_node, - TREE_OPERAND (expr, 0), op1, op2); - goto ret; - } - else - { - /* Folding will happen later for C. */ - expr = build3 (COND_EXPR, truthvalue_type_node, - TREE_OPERAND (expr, 0), - c_common_truthvalue_conversion (location, - TREE_OPERAND (expr, 1)), - c_common_truthvalue_conversion (location, - TREE_OPERAND (expr, 2))); - goto ret; - } - - CASE_CONVERT: - { - tree totype = TREE_TYPE (expr); - tree fromtype = TREE_TYPE (TREE_OPERAND (expr, 0)); - - /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE, - since that affects how `default_conversion' will behave. */ - if (TREE_CODE (totype) == REFERENCE_TYPE - || TREE_CODE (fromtype) == REFERENCE_TYPE) - break; - /* Don't strip a conversion from C++0x scoped enum, since they - don't implicitly convert to other types. */ - if (TREE_CODE (fromtype) == ENUMERAL_TYPE - && ENUM_IS_SCOPED (fromtype)) - break; - /* If this isn't narrowing the argument, we can ignore it. */ - if (TYPE_PRECISION (totype) >= TYPE_PRECISION (fromtype)) - return c_common_truthvalue_conversion (location, - TREE_OPERAND (expr, 0)); - } - break; - - case MODIFY_EXPR: - if (!TREE_NO_WARNING (expr) - && warn_parentheses) - { - warning (OPT_Wparentheses, - "suggest parentheses around assignment used as truth value"); - TREE_NO_WARNING (expr) = 1; - } - break; - - default: - break; - } - - if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE) - { - tree t = (in_late_binary_op ? save_expr (expr) : c_save_expr (expr)); - expr = (build_binary_op - (EXPR_LOCATION (expr), - (TREE_SIDE_EFFECTS (expr) - ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR), - c_common_truthvalue_conversion - (location, - build_unary_op (location, REALPART_EXPR, t, 0)), - c_common_truthvalue_conversion - (location, - build_unary_op (location, IMAGPART_EXPR, t, 0)), - 0)); - goto ret; - } - - if (TREE_CODE (TREE_TYPE (expr)) == FIXED_POINT_TYPE) - { - tree fixed_zero_node = build_fixed (TREE_TYPE (expr), - FCONST0 (TYPE_MODE - (TREE_TYPE (expr)))); - return build_binary_op (location, NE_EXPR, expr, fixed_zero_node, 1); - } - else - return build_binary_op (location, NE_EXPR, expr, integer_zero_node, 1); - - ret: - protected_set_expr_location (expr, location); - return expr; -} - -static void def_builtin_1 (enum built_in_function fncode, - const char *name, - enum built_in_class fnclass, - tree fntype, tree libtype, - bool both_p, bool fallback_p, bool nonansi_p, - tree fnattrs, bool implicit_p); - - -/* Apply the TYPE_QUALS to the new DECL. */ - -void -c_apply_type_quals_to_decl (int type_quals, tree decl) -{ - tree type = TREE_TYPE (decl); - - if (type == error_mark_node) - return; - - if ((type_quals & TYPE_QUAL_CONST) - || (type && TREE_CODE (type) == REFERENCE_TYPE)) - /* We used to check TYPE_NEEDS_CONSTRUCTING here, but now a constexpr - constructor can produce constant init, so rely on cp_finish_decl to - clear TREE_READONLY if the variable has non-constant init. */ - TREE_READONLY (decl) = 1; - if (type_quals & TYPE_QUAL_VOLATILE) - { - TREE_SIDE_EFFECTS (decl) = 1; - TREE_THIS_VOLATILE (decl) = 1; - } - if (type_quals & TYPE_QUAL_RESTRICT) - { - while (type && TREE_CODE (type) == ARRAY_TYPE) - /* Allow 'restrict' on arrays of pointers. - FIXME currently we just ignore it. */ - type = TREE_TYPE (type); - if (!type - || !POINTER_TYPE_P (type) - || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))) - error ("invalid use of %<restrict%>"); - } -} - -/* Hash function for the problem of multiple type definitions in - different files. This must hash all types that will compare - equal via comptypes to the same value. In practice it hashes - on some of the simple stuff and leaves the details to comptypes. */ - -static hashval_t -c_type_hash (const void *p) -{ - int n_elements; - int shift, size; - const_tree const t = (const_tree) p; - tree t2; - switch (TREE_CODE (t)) - { - /* For pointers, hash on pointee type plus some swizzling. */ - case POINTER_TYPE: - return c_type_hash (TREE_TYPE (t)) ^ 0x3003003; - /* Hash on number of elements and total size. */ - case ENUMERAL_TYPE: - shift = 3; - t2 = TYPE_VALUES (t); - break; - case RECORD_TYPE: - shift = 0; - t2 = TYPE_FIELDS (t); - break; - case QUAL_UNION_TYPE: - shift = 1; - t2 = TYPE_FIELDS (t); - break; - case UNION_TYPE: - shift = 2; - t2 = TYPE_FIELDS (t); - break; - default: - gcc_unreachable (); - } - /* FIXME: We want to use a DECL_CHAIN iteration method here, but - TYPE_VALUES of ENUMERAL_TYPEs is stored as a TREE_LIST. */ - n_elements = list_length (t2); - /* We might have a VLA here. */ - if (TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST) - size = 0; - else - size = TREE_INT_CST_LOW (TYPE_SIZE (t)); - return ((size << 24) | (n_elements << shift)); -} - -static GTY((param_is (union tree_node))) htab_t type_hash_table; - -/* Return the typed-based alias set for T, which may be an expression - or a type. Return -1 if we don't do anything special. */ - -alias_set_type -c_common_get_alias_set (tree t) -{ - tree u; - PTR *slot; - - /* For VLAs, use the alias set of the element type rather than the - default of alias set 0 for types compared structurally. */ - if (TYPE_P (t) && TYPE_STRUCTURAL_EQUALITY_P (t)) - { - if (TREE_CODE (t) == ARRAY_TYPE) - return get_alias_set (TREE_TYPE (t)); - return -1; - } - - /* Permit type-punning when accessing a union, provided the access - is directly through the union. For example, this code does not - permit taking the address of a union member and then storing - through it. Even the type-punning allowed here is a GCC - extension, albeit a common and useful one; the C standard says - that such accesses have implementation-defined behavior. */ - for (u = t; - TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF; - u = TREE_OPERAND (u, 0)) - if (TREE_CODE (u) == COMPONENT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) - return 0; - - /* That's all the expressions we handle specially. */ - if (!TYPE_P (t)) - return -1; - - /* The C standard guarantees that any object may be accessed via an - lvalue that has character type. */ - if (t == char_type_node - || t == signed_char_type_node - || t == unsigned_char_type_node) - return 0; - - /* The C standard specifically allows aliasing between signed and - unsigned variants of the same type. We treat the signed - variant as canonical. */ - if (TREE_CODE (t) == INTEGER_TYPE && TYPE_UNSIGNED (t)) - { - tree t1 = c_common_signed_type (t); - - /* t1 == t can happen for boolean nodes which are always unsigned. */ - if (t1 != t) - return get_alias_set (t1); - } - - /* Handle the case of multiple type nodes referring to "the same" type, - which occurs with IMA. These share an alias set. FIXME: Currently only - C90 is handled. (In C99 type compatibility is not transitive, which - complicates things mightily. The alias set splay trees can theoretically - represent this, but insertion is tricky when you consider all the - different orders things might arrive in.) */ - - if (c_language != clk_c || flag_isoc99) - return -1; - - /* Save time if there's only one input file. */ - if (num_in_fnames == 1) - return -1; - - /* Pointers need special handling if they point to any type that - needs special handling (below). */ - if (TREE_CODE (t) == POINTER_TYPE) - { - tree t2; - /* Find bottom type under any nested POINTERs. */ - for (t2 = TREE_TYPE (t); - TREE_CODE (t2) == POINTER_TYPE; - t2 = TREE_TYPE (t2)) - ; - if (TREE_CODE (t2) != RECORD_TYPE - && TREE_CODE (t2) != ENUMERAL_TYPE - && TREE_CODE (t2) != QUAL_UNION_TYPE - && TREE_CODE (t2) != UNION_TYPE) - return -1; - if (TYPE_SIZE (t2) == 0) - return -1; - } - /* These are the only cases that need special handling. */ - if (TREE_CODE (t) != RECORD_TYPE - && TREE_CODE (t) != ENUMERAL_TYPE - && TREE_CODE (t) != QUAL_UNION_TYPE - && TREE_CODE (t) != UNION_TYPE - && TREE_CODE (t) != POINTER_TYPE) - return -1; - /* Undefined? */ - if (TYPE_SIZE (t) == 0) - return -1; - - /* Look up t in hash table. Only one of the compatible types within each - alias set is recorded in the table. */ - if (!type_hash_table) - type_hash_table = htab_create_ggc (1021, c_type_hash, - (htab_eq) lang_hooks.types_compatible_p, - NULL); - slot = htab_find_slot (type_hash_table, t, INSERT); - if (*slot != NULL) - { - TYPE_ALIAS_SET (t) = TYPE_ALIAS_SET ((tree)*slot); - return TYPE_ALIAS_SET ((tree)*slot); - } - else - /* Our caller will assign and record (in t) a new alias set; all we need - to do is remember t in the hash table. */ - *slot = t; - - return -1; -} - -/* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where - the second parameter indicates which OPERATOR is being applied. - The COMPLAIN flag controls whether we should diagnose possibly - ill-formed constructs or not. LOC is the location of the SIZEOF or - TYPEOF operator. */ - -tree -c_sizeof_or_alignof_type (location_t loc, - tree type, bool is_sizeof, int complain) -{ - const char *op_name; - tree value = NULL; - enum tree_code type_code = TREE_CODE (type); - - op_name = is_sizeof ? "sizeof" : "__alignof__"; - - if (type_code == FUNCTION_TYPE) - { - if (is_sizeof) - { - if (complain && (pedantic || warn_pointer_arith)) - pedwarn (loc, pedantic ? OPT_Wpedantic : OPT_Wpointer_arith, - "invalid application of %<sizeof%> to a function type"); - else if (!complain) - return error_mark_node; - value = size_one_node; - } - else - { - if (complain) - { - if (c_dialect_cxx ()) - pedwarn (loc, OPT_Wpedantic, "ISO C++ does not permit " - "%<alignof%> applied to a function type"); - else - pedwarn (loc, OPT_Wpedantic, "ISO C does not permit " - "%<_Alignof%> applied to a function type"); - } - value = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT); - } - } - else if (type_code == VOID_TYPE || type_code == ERROR_MARK) - { - if (type_code == VOID_TYPE - && complain && (pedantic || warn_pointer_arith)) - pedwarn (loc, pedantic ? OPT_Wpedantic : OPT_Wpointer_arith, - "invalid application of %qs to a void type", op_name); - else if (!complain) - return error_mark_node; - value = size_one_node; - } - else if (!COMPLETE_TYPE_P (type) - && (!c_dialect_cxx () || is_sizeof || type_code != ARRAY_TYPE)) - { - if (complain) - error_at (loc, "invalid application of %qs to incomplete type %qT", - op_name, type); - return error_mark_node; - } - else if (c_dialect_cxx () && type_code == ARRAY_TYPE - && !COMPLETE_TYPE_P (TREE_TYPE (type))) - { - if (complain) - error_at (loc, "invalid application of %qs to array type %qT of " - "incomplete element type", op_name, type); - return error_mark_node; - } - else - { - if (is_sizeof) - /* Convert in case a char is more than one unit. */ - value = size_binop_loc (loc, CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), - size_int (TYPE_PRECISION (char_type_node) - / BITS_PER_UNIT)); - else - value = size_int (TYPE_ALIGN_UNIT (type)); - } - - /* VALUE will have the middle-end integer type sizetype. - However, we should really return a value of type `size_t', - which is just a typedef for an ordinary integer type. */ - value = fold_convert_loc (loc, size_type_node, value); - - return value; -} - -/* Implement the __alignof keyword: Return the minimum required - alignment of EXPR, measured in bytes. For VAR_DECLs, - FUNCTION_DECLs and FIELD_DECLs return DECL_ALIGN (which can be set - from an "aligned" __attribute__ specification). LOC is the - location of the ALIGNOF operator. */ - -tree -c_alignof_expr (location_t loc, tree expr) -{ - tree t; - - if (VAR_OR_FUNCTION_DECL_P (expr)) - t = size_int (DECL_ALIGN_UNIT (expr)); - - else if (TREE_CODE (expr) == COMPONENT_REF - && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1))) - { - error_at (loc, "%<__alignof%> applied to a bit-field"); - t = size_one_node; - } - else if (TREE_CODE (expr) == COMPONENT_REF - && TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL) - t = size_int (DECL_ALIGN_UNIT (TREE_OPERAND (expr, 1))); - - else if (TREE_CODE (expr) == INDIRECT_REF) - { - tree t = TREE_OPERAND (expr, 0); - tree best = t; - int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); - - while (CONVERT_EXPR_P (t) - && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE) - { - int thisalign; - - t = TREE_OPERAND (t, 0); - thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); - if (thisalign > bestalign) - best = t, bestalign = thisalign; - } - return c_alignof (loc, TREE_TYPE (TREE_TYPE (best))); - } - else - return c_alignof (loc, TREE_TYPE (expr)); - - return fold_convert_loc (loc, size_type_node, t); -} - -/* Handle C and C++ default attributes. */ - -enum built_in_attribute -{ -#define DEF_ATTR_NULL_TREE(ENUM) ENUM, -#define DEF_ATTR_INT(ENUM, VALUE) ENUM, -#define DEF_ATTR_STRING(ENUM, VALUE) ENUM, -#define DEF_ATTR_IDENT(ENUM, STRING) ENUM, -#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM, -#include "builtin-attrs.def" -#undef DEF_ATTR_NULL_TREE -#undef DEF_ATTR_INT -#undef DEF_ATTR_STRING -#undef DEF_ATTR_IDENT -#undef DEF_ATTR_TREE_LIST - ATTR_LAST -}; - -static GTY(()) tree built_in_attributes[(int) ATTR_LAST]; - -static void c_init_attributes (void); - -enum c_builtin_type -{ -#define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME, -#define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME, -#define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME, -#define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME, -#define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME, -#define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME, -#define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME, -#define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) NAME, -#define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) NAME, -#define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME, -#define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME, -#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME, -#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME, -#define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME, -#define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) \ - NAME, -#define DEF_POINTER_TYPE(NAME, TYPE) NAME, -#include "builtin-types.def" -#undef DEF_PRIMITIVE_TYPE -#undef DEF_FUNCTION_TYPE_0 -#undef DEF_FUNCTION_TYPE_1 -#undef DEF_FUNCTION_TYPE_2 -#undef DEF_FUNCTION_TYPE_3 -#undef DEF_FUNCTION_TYPE_4 -#undef DEF_FUNCTION_TYPE_5 -#undef DEF_FUNCTION_TYPE_6 -#undef DEF_FUNCTION_TYPE_7 -#undef DEF_FUNCTION_TYPE_VAR_0 -#undef DEF_FUNCTION_TYPE_VAR_1 -#undef DEF_FUNCTION_TYPE_VAR_2 -#undef DEF_FUNCTION_TYPE_VAR_3 -#undef DEF_FUNCTION_TYPE_VAR_4 -#undef DEF_FUNCTION_TYPE_VAR_5 -#undef DEF_POINTER_TYPE - BT_LAST -}; - -typedef enum c_builtin_type builtin_type; - -/* A temporary array for c_common_nodes_and_builtins. Used in - communication with def_fn_type. */ -static tree builtin_types[(int) BT_LAST + 1]; - -/* A helper function for c_common_nodes_and_builtins. Build function type - for DEF with return type RET and N arguments. If VAR is true, then the - function should be variadic after those N arguments. - - Takes special care not to ICE if any of the types involved are - error_mark_node, which indicates that said type is not in fact available - (see builtin_type_for_size). In which case the function type as a whole - should be error_mark_node. */ - -static void -def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...) -{ - tree t; - tree *args = XALLOCAVEC (tree, n); - va_list list; - int i; - - va_start (list, n); - for (i = 0; i < n; ++i) - { - builtin_type a = (builtin_type) va_arg (list, int); - t = builtin_types[a]; - if (t == error_mark_node) - goto egress; - args[i] = t; - } - - t = builtin_types[ret]; - if (t == error_mark_node) - goto egress; - if (var) - t = build_varargs_function_type_array (t, n, args); - else - t = build_function_type_array (t, n, args); - - egress: - builtin_types[def] = t; - va_end (list); -} - -/* Build builtin functions common to both C and C++ language - frontends. */ - -static void -c_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node) -{ -#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \ - builtin_types[ENUM] = VALUE; -#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \ - def_fn_type (ENUM, RETURN, 0, 0); -#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \ - def_fn_type (ENUM, RETURN, 0, 1, ARG1); -#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \ - def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2); -#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \ - def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3); -#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \ - def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4); -#define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ - def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5); -#define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6) \ - def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); -#define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7) \ - def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); -#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \ - def_fn_type (ENUM, RETURN, 1, 0); -#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \ - def_fn_type (ENUM, RETURN, 1, 1, ARG1); -#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \ - def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2); -#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \ - def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3); -#define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \ - def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4); -#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ - def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5); -#define DEF_POINTER_TYPE(ENUM, TYPE) \ - builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]); - -#include "builtin-types.def" - -#undef DEF_PRIMITIVE_TYPE -#undef DEF_FUNCTION_TYPE_1 -#undef DEF_FUNCTION_TYPE_2 -#undef DEF_FUNCTION_TYPE_3 -#undef DEF_FUNCTION_TYPE_4 -#undef DEF_FUNCTION_TYPE_5 -#undef DEF_FUNCTION_TYPE_6 -#undef DEF_FUNCTION_TYPE_VAR_0 -#undef DEF_FUNCTION_TYPE_VAR_1 -#undef DEF_FUNCTION_TYPE_VAR_2 -#undef DEF_FUNCTION_TYPE_VAR_3 -#undef DEF_FUNCTION_TYPE_VAR_4 -#undef DEF_FUNCTION_TYPE_VAR_5 -#undef DEF_POINTER_TYPE - builtin_types[(int) BT_LAST] = NULL_TREE; - - c_init_attributes (); - -#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \ - NONANSI_P, ATTRS, IMPLICIT, COND) \ - if (NAME && COND) \ - def_builtin_1 (ENUM, NAME, CLASS, \ - builtin_types[(int) TYPE], \ - builtin_types[(int) LIBTYPE], \ - BOTH_P, FALLBACK_P, NONANSI_P, \ - built_in_attributes[(int) ATTRS], IMPLICIT); -#include "builtins.def" -#undef DEF_BUILTIN - - targetm.init_builtins (); - - build_common_builtin_nodes (); - - if (flag_mudflap) - mudflap_init (); -} - -/* Like get_identifier, but avoid warnings about null arguments when - the argument may be NULL for targets where GCC lacks stdint.h type - information. */ - -static inline tree -c_get_ident (const char *id) -{ - return get_identifier (id); -} - -/* Build tree nodes and builtin functions common to both C and C++ language - frontends. */ - -void -c_common_nodes_and_builtins (void) -{ - int char16_type_size; - int char32_type_size; - int wchar_type_size; - tree array_domain_type; - tree va_list_ref_type_node; - tree va_list_arg_type_node; - - build_common_tree_nodes (flag_signed_char, flag_short_double); - - /* Define `int' and `char' first so that dbx will output them first. */ - record_builtin_type (RID_INT, NULL, integer_type_node); - record_builtin_type (RID_CHAR, "char", char_type_node); - - /* `signed' is the same as `int'. FIXME: the declarations of "signed", - "unsigned long", "long long unsigned" and "unsigned short" were in C++ - but not C. Are the conditionals here needed? */ - if (c_dialect_cxx ()) - record_builtin_type (RID_SIGNED, NULL, integer_type_node); - record_builtin_type (RID_LONG, "long int", long_integer_type_node); - record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node); - record_builtin_type (RID_MAX, "long unsigned int", - long_unsigned_type_node); - if (int128_integer_type_node != NULL_TREE) - { - record_builtin_type (RID_INT128, "__int128", - int128_integer_type_node); - record_builtin_type (RID_MAX, "__int128 unsigned", - int128_unsigned_type_node); - } - if (c_dialect_cxx ()) - record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node); - record_builtin_type (RID_MAX, "long long int", - long_long_integer_type_node); - record_builtin_type (RID_MAX, "long long unsigned int", - long_long_unsigned_type_node); - if (c_dialect_cxx ()) - record_builtin_type (RID_MAX, "long long unsigned", - long_long_unsigned_type_node); - record_builtin_type (RID_SHORT, "short int", short_integer_type_node); - record_builtin_type (RID_MAX, "short unsigned int", - short_unsigned_type_node); - if (c_dialect_cxx ()) - record_builtin_type (RID_MAX, "unsigned short", - short_unsigned_type_node); - - /* Define both `signed char' and `unsigned char'. */ - record_builtin_type (RID_MAX, "signed char", signed_char_type_node); - record_builtin_type (RID_MAX, "unsigned char", unsigned_char_type_node); - - /* These are types that c_common_type_for_size and - c_common_type_for_mode use. */ - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, NULL_TREE, - intQI_type_node)); - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, NULL_TREE, - intHI_type_node)); - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, NULL_TREE, - intSI_type_node)); - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, NULL_TREE, - intDI_type_node)); -#if HOST_BITS_PER_WIDE_INT >= 64 - if (targetm.scalar_mode_supported_p (TImode)) - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, - get_identifier ("__int128_t"), - intTI_type_node)); -#endif - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, NULL_TREE, - unsigned_intQI_type_node)); - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, NULL_TREE, - unsigned_intHI_type_node)); - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, NULL_TREE, - unsigned_intSI_type_node)); - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, NULL_TREE, - unsigned_intDI_type_node)); -#if HOST_BITS_PER_WIDE_INT >= 64 - if (targetm.scalar_mode_supported_p (TImode)) - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, - get_identifier ("__uint128_t"), - unsigned_intTI_type_node)); -#endif - - /* Create the widest literal types. */ - widest_integer_literal_type_node - = make_signed_type (HOST_BITS_PER_WIDE_INT * 2); - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, NULL_TREE, - widest_integer_literal_type_node)); - - widest_unsigned_literal_type_node - = make_unsigned_type (HOST_BITS_PER_WIDE_INT * 2); - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, NULL_TREE, - widest_unsigned_literal_type_node)); - - signed_size_type_node = c_common_signed_type (size_type_node); - - pid_type_node = - TREE_TYPE (identifier_global_value (get_identifier (PID_TYPE))); - - record_builtin_type (RID_FLOAT, NULL, float_type_node); - record_builtin_type (RID_DOUBLE, NULL, double_type_node); - record_builtin_type (RID_MAX, "long double", long_double_type_node); - - /* Only supported decimal floating point extension if the target - actually supports underlying modes. */ - if (targetm.scalar_mode_supported_p (SDmode) - && targetm.scalar_mode_supported_p (DDmode) - && targetm.scalar_mode_supported_p (TDmode)) - { - record_builtin_type (RID_DFLOAT32, NULL, dfloat32_type_node); - record_builtin_type (RID_DFLOAT64, NULL, dfloat64_type_node); - record_builtin_type (RID_DFLOAT128, NULL, dfloat128_type_node); - } - - if (targetm.fixed_point_supported_p ()) - { - record_builtin_type (RID_MAX, "short _Fract", short_fract_type_node); - record_builtin_type (RID_FRACT, NULL, fract_type_node); - record_builtin_type (RID_MAX, "long _Fract", long_fract_type_node); - record_builtin_type (RID_MAX, "long long _Fract", - long_long_fract_type_node); - record_builtin_type (RID_MAX, "unsigned short _Fract", - unsigned_short_fract_type_node); - record_builtin_type (RID_MAX, "unsigned _Fract", - unsigned_fract_type_node); - record_builtin_type (RID_MAX, "unsigned long _Fract", - unsigned_long_fract_type_node); - record_builtin_type (RID_MAX, "unsigned long long _Fract", - unsigned_long_long_fract_type_node); - record_builtin_type (RID_MAX, "_Sat short _Fract", - sat_short_fract_type_node); - record_builtin_type (RID_MAX, "_Sat _Fract", sat_fract_type_node); - record_builtin_type (RID_MAX, "_Sat long _Fract", - sat_long_fract_type_node); - record_builtin_type (RID_MAX, "_Sat long long _Fract", - sat_long_long_fract_type_node); - record_builtin_type (RID_MAX, "_Sat unsigned short _Fract", - sat_unsigned_short_fract_type_node); - record_builtin_type (RID_MAX, "_Sat unsigned _Fract", - sat_unsigned_fract_type_node); - record_builtin_type (RID_MAX, "_Sat unsigned long _Fract", - sat_unsigned_long_fract_type_node); - record_builtin_type (RID_MAX, "_Sat unsigned long long _Fract", - sat_unsigned_long_long_fract_type_node); - record_builtin_type (RID_MAX, "short _Accum", short_accum_type_node); - record_builtin_type (RID_ACCUM, NULL, accum_type_node); - record_builtin_type (RID_MAX, "long _Accum", long_accum_type_node); - record_builtin_type (RID_MAX, "long long _Accum", - long_long_accum_type_node); - record_builtin_type (RID_MAX, "unsigned short _Accum", - unsigned_short_accum_type_node); - record_builtin_type (RID_MAX, "unsigned _Accum", - unsigned_accum_type_node); - record_builtin_type (RID_MAX, "unsigned long _Accum", - unsigned_long_accum_type_node); - record_builtin_type (RID_MAX, "unsigned long long _Accum", - unsigned_long_long_accum_type_node); - record_builtin_type (RID_MAX, "_Sat short _Accum", - sat_short_accum_type_node); - record_builtin_type (RID_MAX, "_Sat _Accum", sat_accum_type_node); - record_builtin_type (RID_MAX, "_Sat long _Accum", - sat_long_accum_type_node); - record_builtin_type (RID_MAX, "_Sat long long _Accum", - sat_long_long_accum_type_node); - record_builtin_type (RID_MAX, "_Sat unsigned short _Accum", - sat_unsigned_short_accum_type_node); - record_builtin_type (RID_MAX, "_Sat unsigned _Accum", - sat_unsigned_accum_type_node); - record_builtin_type (RID_MAX, "_Sat unsigned long _Accum", - sat_unsigned_long_accum_type_node); - record_builtin_type (RID_MAX, "_Sat unsigned long long _Accum", - sat_unsigned_long_long_accum_type_node); - - } - - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, - get_identifier ("complex int"), - complex_integer_type_node)); - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, - get_identifier ("complex float"), - complex_float_type_node)); - lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, - get_identifier ("complex double"), - complex_double_type_node)); - lang_hooks.decls.pushdecl - (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, get_identifier ("complex long double"), - complex_long_double_type_node)); - - if (c_dialect_cxx ()) - /* For C++, make fileptr_type_node a distinct void * type until - FILE type is defined. */ - fileptr_type_node = build_variant_type_copy (ptr_type_node); - - record_builtin_type (RID_VOID, NULL, void_type_node); - - /* Set the TYPE_NAME for any variants that were built before - record_builtin_type gave names to the built-in types. */ - { - tree void_name = TYPE_NAME (void_type_node); - TYPE_NAME (void_type_node) = NULL_TREE; - TYPE_NAME (build_qualified_type (void_type_node, TYPE_QUAL_CONST)) - = void_name; - TYPE_NAME (void_type_node) = void_name; - } - - /* This node must not be shared. */ - void_zero_node = make_node (INTEGER_CST); - TREE_TYPE (void_zero_node) = void_type_node; - - void_list_node = build_void_list_node (); - - /* Make a type to be the domain of a few array types - whose domains don't really matter. - 200 is small enough that it always fits in size_t - and large enough that it can hold most function names for the - initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */ - array_domain_type = build_index_type (size_int (200)); - - /* Make a type for arrays of characters. - With luck nothing will ever really depend on the length of this - array type. */ - char_array_type_node - = build_array_type (char_type_node, array_domain_type); - - /* Likewise for arrays of ints. */ - int_array_type_node - = build_array_type (integer_type_node, array_domain_type); - - string_type_node = build_pointer_type (char_type_node); - const_string_type_node - = build_pointer_type (build_qualified_type - (char_type_node, TYPE_QUAL_CONST)); - - /* This is special for C++ so functions can be overloaded. */ - wchar_type_node = get_identifier (MODIFIED_WCHAR_TYPE); - wchar_type_node = TREE_TYPE (identifier_global_value (wchar_type_node)); - wchar_type_size = TYPE_PRECISION (wchar_type_node); - underlying_wchar_type_node = wchar_type_node; - if (c_dialect_cxx ()) - { - if (TYPE_UNSIGNED (wchar_type_node)) - wchar_type_node = make_unsigned_type (wchar_type_size); - else - wchar_type_node = make_signed_type (wchar_type_size); - record_builtin_type (RID_WCHAR, "wchar_t", wchar_type_node); - } - - /* This is for wide string constants. */ - wchar_array_type_node - = build_array_type (wchar_type_node, array_domain_type); - - /* Define 'char16_t'. */ - char16_type_node = get_identifier (CHAR16_TYPE); - char16_type_node = TREE_TYPE (identifier_global_value (char16_type_node)); - char16_type_size = TYPE_PRECISION (char16_type_node); - if (c_dialect_cxx ()) - { - char16_type_node = make_unsigned_type (char16_type_size); - - if (cxx_dialect >= cxx0x) - record_builtin_type (RID_CHAR16, "char16_t", char16_type_node); - } - - /* This is for UTF-16 string constants. */ - char16_array_type_node - = build_array_type (char16_type_node, array_domain_type); - - /* Define 'char32_t'. */ - char32_type_node = get_identifier (CHAR32_TYPE); - char32_type_node = TREE_TYPE (identifier_global_value (char32_type_node)); - char32_type_size = TYPE_PRECISION (char32_type_node); - if (c_dialect_cxx ()) - { - char32_type_node = make_unsigned_type (char32_type_size); - - if (cxx_dialect >= cxx0x) - record_builtin_type (RID_CHAR32, "char32_t", char32_type_node); - } - - /* This is for UTF-32 string constants. */ - char32_array_type_node - = build_array_type (char32_type_node, array_domain_type); - - wint_type_node = - TREE_TYPE (identifier_global_value (get_identifier (WINT_TYPE))); - - intmax_type_node = - TREE_TYPE (identifier_global_value (get_identifier (INTMAX_TYPE))); - uintmax_type_node = - TREE_TYPE (identifier_global_value (get_identifier (UINTMAX_TYPE))); - - if (SIG_ATOMIC_TYPE) - sig_atomic_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (SIG_ATOMIC_TYPE))); - if (INT8_TYPE) - int8_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INT8_TYPE))); - if (INT16_TYPE) - int16_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INT16_TYPE))); - if (INT32_TYPE) - int32_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INT32_TYPE))); - if (INT64_TYPE) - int64_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INT64_TYPE))); - if (UINT8_TYPE) - uint8_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINT8_TYPE))); - if (UINT16_TYPE) - c_uint16_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINT16_TYPE))); - if (UINT32_TYPE) - c_uint32_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINT32_TYPE))); - if (UINT64_TYPE) - c_uint64_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINT64_TYPE))); - if (INT_LEAST8_TYPE) - int_least8_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INT_LEAST8_TYPE))); - if (INT_LEAST16_TYPE) - int_least16_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INT_LEAST16_TYPE))); - if (INT_LEAST32_TYPE) - int_least32_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INT_LEAST32_TYPE))); - if (INT_LEAST64_TYPE) - int_least64_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INT_LEAST64_TYPE))); - if (UINT_LEAST8_TYPE) - uint_least8_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINT_LEAST8_TYPE))); - if (UINT_LEAST16_TYPE) - uint_least16_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINT_LEAST16_TYPE))); - if (UINT_LEAST32_TYPE) - uint_least32_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINT_LEAST32_TYPE))); - if (UINT_LEAST64_TYPE) - uint_least64_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINT_LEAST64_TYPE))); - if (INT_FAST8_TYPE) - int_fast8_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INT_FAST8_TYPE))); - if (INT_FAST16_TYPE) - int_fast16_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INT_FAST16_TYPE))); - if (INT_FAST32_TYPE) - int_fast32_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INT_FAST32_TYPE))); - if (INT_FAST64_TYPE) - int_fast64_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INT_FAST64_TYPE))); - if (UINT_FAST8_TYPE) - uint_fast8_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINT_FAST8_TYPE))); - if (UINT_FAST16_TYPE) - uint_fast16_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINT_FAST16_TYPE))); - if (UINT_FAST32_TYPE) - uint_fast32_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINT_FAST32_TYPE))); - if (UINT_FAST64_TYPE) - uint_fast64_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINT_FAST64_TYPE))); - if (INTPTR_TYPE) - intptr_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (INTPTR_TYPE))); - if (UINTPTR_TYPE) - uintptr_type_node = - TREE_TYPE (identifier_global_value (c_get_ident (UINTPTR_TYPE))); - - default_function_type - = build_varargs_function_type_list (integer_type_node, NULL_TREE); - ptrdiff_type_node - = TREE_TYPE (identifier_global_value (get_identifier (PTRDIFF_TYPE))); - unsigned_ptrdiff_type_node = c_common_unsigned_type (ptrdiff_type_node); - - lang_hooks.decls.pushdecl - (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, get_identifier ("__builtin_va_list"), - va_list_type_node)); - if (targetm.enum_va_list_p) - { - int l; - const char *pname; - tree ptype; - - for (l = 0; targetm.enum_va_list_p (l, &pname, &ptype); ++l) - { - lang_hooks.decls.pushdecl - (build_decl (UNKNOWN_LOCATION, - TYPE_DECL, get_identifier (pname), - ptype)); - - } - } - - if (TREE_CODE (va_list_type_node) == ARRAY_TYPE) - { - va_list_arg_type_node = va_list_ref_type_node = - build_pointer_type (TREE_TYPE (va_list_type_node)); - } - else - { - va_list_arg_type_node = va_list_type_node; - va_list_ref_type_node = build_reference_type (va_list_type_node); - } - - if (!flag_preprocess_only) - c_define_builtins (va_list_ref_type_node, va_list_arg_type_node); - - main_identifier_node = get_identifier ("main"); - - /* Create the built-in __null node. It is important that this is - not shared. */ - null_node = make_node (INTEGER_CST); - TREE_TYPE (null_node) = c_common_type_for_size (POINTER_SIZE, 0); - - /* Since builtin_types isn't gc'ed, don't export these nodes. */ - memset (builtin_types, 0, sizeof (builtin_types)); -} - -/* The number of named compound-literals generated thus far. */ -static GTY(()) int compound_literal_number; - -/* Set DECL_NAME for DECL, a VAR_DECL for a compound-literal. */ - -void -set_compound_literal_name (tree decl) -{ - char *name; - ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal", - compound_literal_number); - compound_literal_number++; - DECL_NAME (decl) = get_identifier (name); -} - -tree -build_va_arg (location_t loc, tree expr, tree type) -{ - expr = build1 (VA_ARG_EXPR, type, expr); - SET_EXPR_LOCATION (expr, loc); - return expr; -} - - -/* Linked list of disabled built-in functions. */ - -typedef struct disabled_builtin -{ - const char *name; - struct disabled_builtin *next; -} disabled_builtin; -static disabled_builtin *disabled_builtins = NULL; - -static bool builtin_function_disabled_p (const char *); - -/* Disable a built-in function specified by -fno-builtin-NAME. If NAME - begins with "__builtin_", give an error. */ - -void -disable_builtin_function (const char *name) -{ - if (strncmp (name, "__builtin_", strlen ("__builtin_")) == 0) - error ("cannot disable built-in function %qs", name); - else - { - disabled_builtin *new_disabled_builtin = XNEW (disabled_builtin); - new_disabled_builtin->name = name; - new_disabled_builtin->next = disabled_builtins; - disabled_builtins = new_disabled_builtin; - } -} - - -/* Return true if the built-in function NAME has been disabled, false - otherwise. */ - -static bool -builtin_function_disabled_p (const char *name) -{ - disabled_builtin *p; - for (p = disabled_builtins; p != NULL; p = p->next) - { - if (strcmp (name, p->name) == 0) - return true; - } - return false; -} - - -/* Worker for DEF_BUILTIN. - Possibly define a builtin function with one or two names. - Does not declare a non-__builtin_ function if flag_no_builtin, or if - nonansi_p and flag_no_nonansi_builtin. */ - -static void -def_builtin_1 (enum built_in_function fncode, - const char *name, - enum built_in_class fnclass, - tree fntype, tree libtype, - bool both_p, bool fallback_p, bool nonansi_p, - tree fnattrs, bool implicit_p) -{ - tree decl; - const char *libname; - - if (fntype == error_mark_node) - return; - - gcc_assert ((!both_p && !fallback_p) - || !strncmp (name, "__builtin_", - strlen ("__builtin_"))); - - libname = name + strlen ("__builtin_"); - decl = add_builtin_function (name, fntype, fncode, fnclass, - (fallback_p ? libname : NULL), - fnattrs); - - set_builtin_decl (fncode, decl, implicit_p); - - if (both_p - && !flag_no_builtin && !builtin_function_disabled_p (libname) - && !(nonansi_p && flag_no_nonansi_builtin)) - add_builtin_function (libname, libtype, fncode, fnclass, - NULL, fnattrs); -} - -/* Nonzero if the type T promotes to int. This is (nearly) the - integral promotions defined in ISO C99 6.3.1.1/2. */ - -bool -c_promoting_integer_type_p (const_tree t) -{ - switch (TREE_CODE (t)) - { - case INTEGER_TYPE: - return (TYPE_MAIN_VARIANT (t) == char_type_node - || TYPE_MAIN_VARIANT (t) == signed_char_type_node - || TYPE_MAIN_VARIANT (t) == unsigned_char_type_node - || TYPE_MAIN_VARIANT (t) == short_integer_type_node - || TYPE_MAIN_VARIANT (t) == short_unsigned_type_node - || TYPE_PRECISION (t) < TYPE_PRECISION (integer_type_node)); - - case ENUMERAL_TYPE: - /* ??? Technically all enumerations not larger than an int - promote to an int. But this is used along code paths - that only want to notice a size change. */ - return TYPE_PRECISION (t) < TYPE_PRECISION (integer_type_node); - - case BOOLEAN_TYPE: - return 1; - - default: - return 0; - } -} - -/* Return 1 if PARMS specifies a fixed number of parameters - and none of their types is affected by default promotions. */ - -int -self_promoting_args_p (const_tree parms) -{ - const_tree t; - for (t = parms; t; t = TREE_CHAIN (t)) - { - tree type = TREE_VALUE (t); - - if (type == error_mark_node) - continue; - - if (TREE_CHAIN (t) == 0 && type != void_type_node) - return 0; - - if (type == 0) - return 0; - - if (TYPE_MAIN_VARIANT (type) == float_type_node) - return 0; - - if (c_promoting_integer_type_p (type)) - return 0; - } - return 1; -} - -/* Recursively remove any '*' or '&' operator from TYPE. */ -tree -strip_pointer_operator (tree t) -{ - while (POINTER_TYPE_P (t)) - t = TREE_TYPE (t); - return t; -} - -/* Recursively remove pointer or array type from TYPE. */ -tree -strip_pointer_or_array_types (tree t) -{ - while (TREE_CODE (t) == ARRAY_TYPE || POINTER_TYPE_P (t)) - t = TREE_TYPE (t); - return t; -} - -/* Used to compare case labels. K1 and K2 are actually tree nodes - representing case labels, or NULL_TREE for a `default' label. - Returns -1 if K1 is ordered before K2, -1 if K1 is ordered after - K2, and 0 if K1 and K2 are equal. */ - -int -case_compare (splay_tree_key k1, splay_tree_key k2) -{ - /* Consider a NULL key (such as arises with a `default' label) to be - smaller than anything else. */ - if (!k1) - return k2 ? -1 : 0; - else if (!k2) - return k1 ? 1 : 0; - - return tree_int_cst_compare ((tree) k1, (tree) k2); -} - -/* Process a case label, located at LOC, for the range LOW_VALUE - ... HIGH_VALUE. If LOW_VALUE and HIGH_VALUE are both NULL_TREE - then this case label is actually a `default' label. If only - HIGH_VALUE is NULL_TREE, then case label was declared using the - usual C/C++ syntax, rather than the GNU case range extension. - CASES is a tree containing all the case ranges processed so far; - COND is the condition for the switch-statement itself. Returns the - CASE_LABEL_EXPR created, or ERROR_MARK_NODE if no CASE_LABEL_EXPR - is created. */ - -tree -c_add_case_label (location_t loc, splay_tree cases, tree cond, tree orig_type, - tree low_value, tree high_value) -{ - tree type; - tree label; - tree case_label; - splay_tree_node node; - - /* Create the LABEL_DECL itself. */ - label = create_artificial_label (loc); - - /* If there was an error processing the switch condition, bail now - before we get more confused. */ - if (!cond || cond == error_mark_node) - goto error_out; - - if ((low_value && TREE_TYPE (low_value) - && POINTER_TYPE_P (TREE_TYPE (low_value))) - || (high_value && TREE_TYPE (high_value) - && POINTER_TYPE_P (TREE_TYPE (high_value)))) - { - error_at (loc, "pointers are not permitted as case values"); - goto error_out; - } - - /* Case ranges are a GNU extension. */ - if (high_value) - pedwarn (loc, OPT_Wpedantic, - "range expressions in switch statements are non-standard"); - - type = TREE_TYPE (cond); - if (low_value) - { - low_value = check_case_value (low_value); - low_value = convert_and_check (type, low_value); - if (low_value == error_mark_node) - goto error_out; - } - if (high_value) - { - high_value = check_case_value (high_value); - high_value = convert_and_check (type, high_value); - if (high_value == error_mark_node) - goto error_out; - } - - if (low_value && high_value) - { - /* If the LOW_VALUE and HIGH_VALUE are the same, then this isn't - really a case range, even though it was written that way. - Remove the HIGH_VALUE to simplify later processing. */ - if (tree_int_cst_equal (low_value, high_value)) - high_value = NULL_TREE; - else if (!tree_int_cst_lt (low_value, high_value)) - warning_at (loc, 0, "empty range specified"); - } - - /* See if the case is in range of the type of the original testing - expression. If both low_value and high_value are out of range, - don't insert the case label and return NULL_TREE. */ - if (low_value - && !check_case_bounds (type, orig_type, - &low_value, high_value ? &high_value : NULL)) - return NULL_TREE; - - /* Look up the LOW_VALUE in the table of case labels we already - have. */ - node = splay_tree_lookup (cases, (splay_tree_key) low_value); - /* If there was not an exact match, check for overlapping ranges. - There's no need to do this if there's no LOW_VALUE or HIGH_VALUE; - that's a `default' label and the only overlap is an exact match. */ - if (!node && (low_value || high_value)) - { - splay_tree_node low_bound; - splay_tree_node high_bound; - - /* Even though there wasn't an exact match, there might be an - overlap between this case range and another case range. - Since we've (inductively) not allowed any overlapping case - ranges, we simply need to find the greatest low case label - that is smaller that LOW_VALUE, and the smallest low case - label that is greater than LOW_VALUE. If there is an overlap - it will occur in one of these two ranges. */ - low_bound = splay_tree_predecessor (cases, - (splay_tree_key) low_value); - high_bound = splay_tree_successor (cases, - (splay_tree_key) low_value); - - /* Check to see if the LOW_BOUND overlaps. It is smaller than - the LOW_VALUE, so there is no need to check unless the - LOW_BOUND is in fact itself a case range. */ - if (low_bound - && CASE_HIGH ((tree) low_bound->value) - && tree_int_cst_compare (CASE_HIGH ((tree) low_bound->value), - low_value) >= 0) - node = low_bound; - /* Check to see if the HIGH_BOUND overlaps. The low end of that - range is bigger than the low end of the current range, so we - are only interested if the current range is a real range, and - not an ordinary case label. */ - else if (high_bound - && high_value - && (tree_int_cst_compare ((tree) high_bound->key, - high_value) - <= 0)) - node = high_bound; - } - /* If there was an overlap, issue an error. */ - if (node) - { - tree duplicate = CASE_LABEL ((tree) node->value); - - if (high_value) - { - error_at (loc, "duplicate (or overlapping) case value"); - error_at (DECL_SOURCE_LOCATION (duplicate), - "this is the first entry overlapping that value"); - } - else if (low_value) - { - error_at (loc, "duplicate case value") ; - error_at (DECL_SOURCE_LOCATION (duplicate), "previously used here"); - } - else - { - error_at (loc, "multiple default labels in one switch"); - error_at (DECL_SOURCE_LOCATION (duplicate), - "this is the first default label"); - } - goto error_out; - } - - /* Add a CASE_LABEL to the statement-tree. */ - case_label = add_stmt (build_case_label (low_value, high_value, label)); - /* Register this case label in the splay tree. */ - splay_tree_insert (cases, - (splay_tree_key) low_value, - (splay_tree_value) case_label); - - return case_label; - - error_out: - /* Add a label so that the back-end doesn't think that the beginning of - the switch is unreachable. Note that we do not add a case label, as - that just leads to duplicates and thence to failure later on. */ - if (!cases->root) - { - tree t = create_artificial_label (loc); - add_stmt (build_stmt (loc, LABEL_EXPR, t)); - } - return error_mark_node; -} - -/* Subroutines of c_do_switch_warnings, called via splay_tree_foreach. - Used to verify that case values match up with enumerator values. */ - -static void -match_case_to_enum_1 (tree key, tree type, tree label) -{ - char buf[2 + 2*HOST_BITS_PER_WIDE_INT/4 + 1]; - - /* ??? Not working too hard to print the double-word value. - Should perhaps be done with %lwd in the diagnostic routines? */ - if (TREE_INT_CST_HIGH (key) == 0) - snprintf (buf, sizeof (buf), HOST_WIDE_INT_PRINT_UNSIGNED, - TREE_INT_CST_LOW (key)); - else if (!TYPE_UNSIGNED (type) - && TREE_INT_CST_HIGH (key) == -1 - && TREE_INT_CST_LOW (key) != 0) - snprintf (buf, sizeof (buf), "-" HOST_WIDE_INT_PRINT_UNSIGNED, - -TREE_INT_CST_LOW (key)); - else - snprintf (buf, sizeof (buf), HOST_WIDE_INT_PRINT_DOUBLE_HEX, - (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (key), - (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (key)); - - if (TYPE_NAME (type) == 0) - warning_at (DECL_SOURCE_LOCATION (CASE_LABEL (label)), - warn_switch ? OPT_Wswitch : OPT_Wswitch_enum, - "case value %qs not in enumerated type", - buf); - else - warning_at (DECL_SOURCE_LOCATION (CASE_LABEL (label)), - warn_switch ? OPT_Wswitch : OPT_Wswitch_enum, - "case value %qs not in enumerated type %qT", - buf, type); -} - -/* Subroutine of c_do_switch_warnings, called via splay_tree_foreach. - Used to verify that case values match up with enumerator values. */ - -static int -match_case_to_enum (splay_tree_node node, void *data) -{ - tree label = (tree) node->value; - tree type = (tree) data; - - /* Skip default case. */ - if (!CASE_LOW (label)) - return 0; - - /* If CASE_LOW_SEEN is not set, that means CASE_LOW did not appear - when we did our enum->case scan. Reset our scratch bit after. */ - if (!CASE_LOW_SEEN (label)) - match_case_to_enum_1 (CASE_LOW (label), type, label); - else - CASE_LOW_SEEN (label) = 0; - - /* If CASE_HIGH is non-null, we have a range. If CASE_HIGH_SEEN is - not set, that means that CASE_HIGH did not appear when we did our - enum->case scan. Reset our scratch bit after. */ - if (CASE_HIGH (label)) - { - if (!CASE_HIGH_SEEN (label)) - match_case_to_enum_1 (CASE_HIGH (label), type, label); - else - CASE_HIGH_SEEN (label) = 0; - } - - return 0; -} - -/* Handle -Wswitch*. Called from the front end after parsing the - switch construct. */ -/* ??? Should probably be somewhere generic, since other languages - besides C and C++ would want this. At the moment, however, C/C++ - are the only tree-ssa languages that support enumerations at all, - so the point is moot. */ - -void -c_do_switch_warnings (splay_tree cases, location_t switch_location, - tree type, tree cond) -{ - splay_tree_node default_node; - splay_tree_node node; - tree chain; - - if (!warn_switch && !warn_switch_enum && !warn_switch_default) - return; - - default_node = splay_tree_lookup (cases, (splay_tree_key) NULL); - if (!default_node) - warning_at (switch_location, OPT_Wswitch_default, - "switch missing default case"); - - /* From here on, we only care about about enumerated types. */ - if (!type || TREE_CODE (type) != ENUMERAL_TYPE) - return; - - /* From here on, we only care about -Wswitch and -Wswitch-enum. */ - if (!warn_switch_enum && !warn_switch) - return; - - /* Check the cases. Warn about case values which are not members of - the enumerated type. For -Wswitch-enum, or for -Wswitch when - there is no default case, check that exactly all enumeration - literals are covered by the cases. */ - - /* Clearing COND if it is not an integer constant simplifies - the tests inside the loop below. */ - if (TREE_CODE (cond) != INTEGER_CST) - cond = NULL_TREE; - - /* The time complexity here is O(N*lg(N)) worst case, but for the - common case of monotonically increasing enumerators, it is - O(N), since the nature of the splay tree will keep the next - element adjacent to the root at all times. */ - - for (chain = TYPE_VALUES (type); chain; chain = TREE_CHAIN (chain)) - { - tree value = TREE_VALUE (chain); - if (TREE_CODE (value) == CONST_DECL) - value = DECL_INITIAL (value); - node = splay_tree_lookup (cases, (splay_tree_key) value); - if (node) - { - /* Mark the CASE_LOW part of the case entry as seen. */ - tree label = (tree) node->value; - CASE_LOW_SEEN (label) = 1; - continue; - } - - /* Even though there wasn't an exact match, there might be a - case range which includes the enumerator's value. */ - node = splay_tree_predecessor (cases, (splay_tree_key) value); - if (node && CASE_HIGH ((tree) node->value)) - { - tree label = (tree) node->value; - int cmp = tree_int_cst_compare (CASE_HIGH (label), value); - if (cmp >= 0) - { - /* If we match the upper bound exactly, mark the CASE_HIGH - part of the case entry as seen. */ - if (cmp == 0) - CASE_HIGH_SEEN (label) = 1; - continue; - } - } - - /* We've now determined that this enumerated literal isn't - handled by the case labels of the switch statement. */ - - /* If the switch expression is a constant, we only really care - about whether that constant is handled by the switch. */ - if (cond && tree_int_cst_compare (cond, value)) - continue; - - /* If there is a default_node, the only relevant option is - Wswitch-enum. Otherwise, if both are enabled then we prefer - to warn using -Wswitch because -Wswitch is enabled by -Wall - while -Wswitch-enum is explicit. */ - warning_at (switch_location, - (default_node || !warn_switch - ? OPT_Wswitch_enum - : OPT_Wswitch), - "enumeration value %qE not handled in switch", - TREE_PURPOSE (chain)); - } - - /* Warn if there are case expressions that don't correspond to - enumerators. This can occur since C and C++ don't enforce - type-checking of assignments to enumeration variables. - - The time complexity here is now always O(N) worst case, since - we should have marked both the lower bound and upper bound of - every disjoint case label, with CASE_LOW_SEEN and CASE_HIGH_SEEN - above. This scan also resets those fields. */ - - splay_tree_foreach (cases, match_case_to_enum, type); -} - -/* Finish an expression taking the address of LABEL (an - IDENTIFIER_NODE). Returns an expression for the address. - - LOC is the location for the expression returned. */ - -tree -finish_label_address_expr (tree label, location_t loc) -{ - tree result; - - pedwarn (input_location, OPT_Wpedantic, "taking the address of a label is non-standard"); - - if (label == error_mark_node) - return error_mark_node; - - label = lookup_label (label); - if (label == NULL_TREE) - result = null_pointer_node; - else - { - TREE_USED (label) = 1; - result = build1 (ADDR_EXPR, ptr_type_node, label); - /* The current function is not necessarily uninlinable. - Computed gotos are incompatible with inlining, but the value - here could be used only in a diagnostic, for example. */ - protected_set_expr_location (result, loc); - } - - return result; -} - - -/* Given a boolean expression ARG, return a tree representing an increment - or decrement (as indicated by CODE) of ARG. The front end must check for - invalid cases (e.g., decrement in C++). */ -tree -boolean_increment (enum tree_code code, tree arg) -{ - tree val; - tree true_res = build_int_cst (TREE_TYPE (arg), 1); - - arg = stabilize_reference (arg); - switch (code) - { - case PREINCREMENT_EXPR: - val = build2 (MODIFY_EXPR, TREE_TYPE (arg), arg, true_res); - break; - case POSTINCREMENT_EXPR: - val = build2 (MODIFY_EXPR, TREE_TYPE (arg), arg, true_res); - arg = save_expr (arg); - val = build2 (COMPOUND_EXPR, TREE_TYPE (arg), val, arg); - val = build2 (COMPOUND_EXPR, TREE_TYPE (arg), arg, val); - break; - case PREDECREMENT_EXPR: - val = build2 (MODIFY_EXPR, TREE_TYPE (arg), arg, - invert_truthvalue_loc (input_location, arg)); - break; - case POSTDECREMENT_EXPR: - val = build2 (MODIFY_EXPR, TREE_TYPE (arg), arg, - invert_truthvalue_loc (input_location, arg)); - arg = save_expr (arg); - val = build2 (COMPOUND_EXPR, TREE_TYPE (arg), val, arg); - val = build2 (COMPOUND_EXPR, TREE_TYPE (arg), arg, val); - break; - default: - gcc_unreachable (); - } - TREE_SIDE_EFFECTS (val) = 1; - return val; -} - -/* Built-in macros for stddef.h and stdint.h, that require macros - defined in this file. */ -void -c_stddef_cpp_builtins(void) -{ - builtin_define_with_value ("__SIZE_TYPE__", SIZE_TYPE, 0); - builtin_define_with_value ("__PTRDIFF_TYPE__", PTRDIFF_TYPE, 0); - builtin_define_with_value ("__WCHAR_TYPE__", MODIFIED_WCHAR_TYPE, 0); - builtin_define_with_value ("__WINT_TYPE__", WINT_TYPE, 0); - builtin_define_with_value ("__INTMAX_TYPE__", INTMAX_TYPE, 0); - builtin_define_with_value ("__UINTMAX_TYPE__", UINTMAX_TYPE, 0); - builtin_define_with_value ("__CHAR16_TYPE__", CHAR16_TYPE, 0); - builtin_define_with_value ("__CHAR32_TYPE__", CHAR32_TYPE, 0); - if (SIG_ATOMIC_TYPE) - builtin_define_with_value ("__SIG_ATOMIC_TYPE__", SIG_ATOMIC_TYPE, 0); - if (INT8_TYPE) - builtin_define_with_value ("__INT8_TYPE__", INT8_TYPE, 0); - if (INT16_TYPE) - builtin_define_with_value ("__INT16_TYPE__", INT16_TYPE, 0); - if (INT32_TYPE) - builtin_define_with_value ("__INT32_TYPE__", INT32_TYPE, 0); - if (INT64_TYPE) - builtin_define_with_value ("__INT64_TYPE__", INT64_TYPE, 0); - if (UINT8_TYPE) - builtin_define_with_value ("__UINT8_TYPE__", UINT8_TYPE, 0); - if (UINT16_TYPE) - builtin_define_with_value ("__UINT16_TYPE__", UINT16_TYPE, 0); - if (UINT32_TYPE) - builtin_define_with_value ("__UINT32_TYPE__", UINT32_TYPE, 0); - if (UINT64_TYPE) - builtin_define_with_value ("__UINT64_TYPE__", UINT64_TYPE, 0); - if (INT_LEAST8_TYPE) - builtin_define_with_value ("__INT_LEAST8_TYPE__", INT_LEAST8_TYPE, 0); - if (INT_LEAST16_TYPE) - builtin_define_with_value ("__INT_LEAST16_TYPE__", INT_LEAST16_TYPE, 0); - if (INT_LEAST32_TYPE) - builtin_define_with_value ("__INT_LEAST32_TYPE__", INT_LEAST32_TYPE, 0); - if (INT_LEAST64_TYPE) - builtin_define_with_value ("__INT_LEAST64_TYPE__", INT_LEAST64_TYPE, 0); - if (UINT_LEAST8_TYPE) - builtin_define_with_value ("__UINT_LEAST8_TYPE__", UINT_LEAST8_TYPE, 0); - if (UINT_LEAST16_TYPE) - builtin_define_with_value ("__UINT_LEAST16_TYPE__", UINT_LEAST16_TYPE, 0); - if (UINT_LEAST32_TYPE) - builtin_define_with_value ("__UINT_LEAST32_TYPE__", UINT_LEAST32_TYPE, 0); - if (UINT_LEAST64_TYPE) - builtin_define_with_value ("__UINT_LEAST64_TYPE__", UINT_LEAST64_TYPE, 0); - if (INT_FAST8_TYPE) - builtin_define_with_value ("__INT_FAST8_TYPE__", INT_FAST8_TYPE, 0); - if (INT_FAST16_TYPE) - builtin_define_with_value ("__INT_FAST16_TYPE__", INT_FAST16_TYPE, 0); - if (INT_FAST32_TYPE) - builtin_define_with_value ("__INT_FAST32_TYPE__", INT_FAST32_TYPE, 0); - if (INT_FAST64_TYPE) - builtin_define_with_value ("__INT_FAST64_TYPE__", INT_FAST64_TYPE, 0); - if (UINT_FAST8_TYPE) - builtin_define_with_value ("__UINT_FAST8_TYPE__", UINT_FAST8_TYPE, 0); - if (UINT_FAST16_TYPE) - builtin_define_with_value ("__UINT_FAST16_TYPE__", UINT_FAST16_TYPE, 0); - if (UINT_FAST32_TYPE) - builtin_define_with_value ("__UINT_FAST32_TYPE__", UINT_FAST32_TYPE, 0); - if (UINT_FAST64_TYPE) - builtin_define_with_value ("__UINT_FAST64_TYPE__", UINT_FAST64_TYPE, 0); - if (INTPTR_TYPE) - builtin_define_with_value ("__INTPTR_TYPE__", INTPTR_TYPE, 0); - if (UINTPTR_TYPE) - builtin_define_with_value ("__UINTPTR_TYPE__", UINTPTR_TYPE, 0); -} - -static void -c_init_attributes (void) -{ - /* Fill in the built_in_attributes array. */ -#define DEF_ATTR_NULL_TREE(ENUM) \ - built_in_attributes[(int) ENUM] = NULL_TREE; -#define DEF_ATTR_INT(ENUM, VALUE) \ - built_in_attributes[(int) ENUM] = build_int_cst (integer_type_node, VALUE); -#define DEF_ATTR_STRING(ENUM, VALUE) \ - built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE); -#define DEF_ATTR_IDENT(ENUM, STRING) \ - built_in_attributes[(int) ENUM] = get_identifier (STRING); -#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \ - built_in_attributes[(int) ENUM] \ - = tree_cons (built_in_attributes[(int) PURPOSE], \ - built_in_attributes[(int) VALUE], \ - built_in_attributes[(int) CHAIN]); -#include "builtin-attrs.def" -#undef DEF_ATTR_NULL_TREE -#undef DEF_ATTR_INT -#undef DEF_ATTR_IDENT -#undef DEF_ATTR_TREE_LIST -} - -/* Returns TRUE iff the attribute indicated by ATTR_ID takes a plain - identifier as an argument, so the front end shouldn't look it up. */ - -bool -attribute_takes_identifier_p (const_tree attr_id) -{ - const struct attribute_spec *spec = lookup_attribute_spec (attr_id); - if (spec == NULL) - /* Unknown attribute that we'll end up ignoring, return true so we - don't complain about an identifier argument. */ - return true; - else if (!strcmp ("mode", spec->name) - || !strcmp ("format", spec->name) - || !strcmp ("cleanup", spec->name)) - return true; - else - return targetm.attribute_takes_identifier_p (attr_id); -} - -/* Attribute handlers common to C front ends. */ - -/* Handle a "packed" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int flags, bool *no_add_attrs) -{ - if (TYPE_P (*node)) - { - if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) - *node = build_variant_type_copy (*node); - TYPE_PACKED (*node) = 1; - } - else if (TREE_CODE (*node) == FIELD_DECL) - { - if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT - /* Still pack bitfields. */ - && ! DECL_INITIAL (*node)) - warning (OPT_Wattributes, - "%qE attribute ignored for field of type %qT", - name, TREE_TYPE (*node)); - else - DECL_PACKED (*node) = 1; - } - /* We can't set DECL_PACKED for a VAR_DECL, because the bit is - used for DECL_REGISTER. It wouldn't mean anything anyway. - We can't set DECL_PACKED on the type of a TYPE_DECL, because - that changes what the typedef is typing. */ - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "nocommon" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_nocommon_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) == VAR_DECL) - DECL_COMMON (*node) = 0; - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "common" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_common_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) == VAR_DECL) - DECL_COMMON (*node) = 1; - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "noreturn" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - tree type = TREE_TYPE (*node); - - /* See FIXME comment in c_common_attribute_table. */ - if (TREE_CODE (*node) == FUNCTION_DECL - || objc_method_decl (TREE_CODE (*node))) - TREE_THIS_VOLATILE (*node) = 1; - else if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) - TREE_TYPE (*node) - = build_pointer_type - (build_type_variant (TREE_TYPE (type), - TYPE_READONLY (TREE_TYPE (type)), 1)); - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "hot" and attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL - || TREE_CODE (*node) == LABEL_DECL) - { - if (lookup_attribute ("cold", DECL_ATTRIBUTES (*node)) != NULL) - { - warning (OPT_Wattributes, "%qE attribute conflicts with attribute %s", - name, "cold"); - *no_add_attrs = true; - } - /* Most of the rest of the hot processing is done later with - lookup_attribute. */ - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "cold" and attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL - || TREE_CODE (*node) == LABEL_DECL) - { - if (lookup_attribute ("hot", DECL_ATTRIBUTES (*node)) != NULL) - { - warning (OPT_Wattributes, "%qE attribute conflicts with attribute %s", - name, "hot"); - *no_add_attrs = true; - } - /* Most of the rest of the cold processing is done later with - lookup_attribute. */ - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "no_sanitize_address" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_no_sanitize_address_attribute (tree *node, tree name, tree, int, - bool *no_add_attrs) -{ - if (TREE_CODE (*node) != FUNCTION_DECL) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "no_address_safety_analysis" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_no_address_safety_analysis_attribute (tree *node, tree name, tree, int, - bool *no_add_attrs) -{ - if (TREE_CODE (*node) != FUNCTION_DECL) - warning (OPT_Wattributes, "%qE attribute ignored", name); - else if (!lookup_attribute ("no_sanitize_address", DECL_ATTRIBUTES (*node))) - DECL_ATTRIBUTES (*node) - = tree_cons (get_identifier ("no_sanitize_address"), - NULL_TREE, DECL_ATTRIBUTES (*node)); - *no_add_attrs = true; - return NULL_TREE; -} - -/* Handle a "noinline" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_noinline_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - DECL_UNINLINABLE (*node) = 1; - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "noclone" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_noclone_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) != FUNCTION_DECL) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "always_inline" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_always_inline_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - { - /* Set the attribute and mark it for disregarding inline - limits. */ - DECL_DISREGARD_INLINE_LIMITS (*node) = 1; - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "gnu_inline" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_gnu_inline_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node)) - { - /* Do nothing else, just set the attribute. We'll get at - it later with lookup_attribute. */ - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "leaf" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_leaf_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) != FUNCTION_DECL) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - if (!TREE_PUBLIC (*node)) - { - warning (OPT_Wattributes, "%qE attribute has no effect on unit local functions", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle an "artificial" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_artificial_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node)) - { - /* Do nothing else, just set the attribute. We'll get at - it later with lookup_attribute. */ - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "flatten" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_flatten_attribute (tree *node, tree name, - tree args ATTRIBUTE_UNUSED, - int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - /* Do nothing else, just set the attribute. We'll get at - it later with lookup_attribute. */ - ; - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "warning" or "error" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_error_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL - && TREE_CODE (TREE_VALUE (args)) == STRING_CST) - /* Do nothing else, just set the attribute. We'll get at - it later with lookup_attribute. */ - ; - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "used" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - tree node = *pnode; - - if (TREE_CODE (node) == FUNCTION_DECL - || (TREE_CODE (node) == VAR_DECL && TREE_STATIC (node)) - || (TREE_CODE (node) == TYPE_DECL)) - { - TREE_USED (node) = 1; - DECL_PRESERVE_P (node) = 1; - if (TREE_CODE (node) == VAR_DECL) - DECL_READ_P (node) = 1; - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "unused" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int flags, bool *no_add_attrs) -{ - if (DECL_P (*node)) - { - tree decl = *node; - - if (TREE_CODE (decl) == PARM_DECL - || TREE_CODE (decl) == VAR_DECL - || TREE_CODE (decl) == FUNCTION_DECL - || TREE_CODE (decl) == LABEL_DECL - || TREE_CODE (decl) == TYPE_DECL) - { - TREE_USED (decl) = 1; - if (TREE_CODE (decl) == VAR_DECL - || TREE_CODE (decl) == PARM_DECL) - DECL_READ_P (decl) = 1; - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - } - else - { - if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) - *node = build_variant_type_copy (*node); - TREE_USED (*node) = 1; - } - - return NULL_TREE; -} - -/* Handle a "externally_visible" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_externally_visible_attribute (tree *pnode, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - tree node = *pnode; - - if (TREE_CODE (node) == FUNCTION_DECL || TREE_CODE (node) == VAR_DECL) - { - if ((!TREE_STATIC (node) && TREE_CODE (node) != FUNCTION_DECL - && !DECL_EXTERNAL (node)) || !TREE_PUBLIC (node)) - { - warning (OPT_Wattributes, - "%qE attribute have effect only on public objects", name); - *no_add_attrs = true; - } - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "const" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - tree type = TREE_TYPE (*node); - - /* See FIXME comment on noreturn in c_common_attribute_table. */ - if (TREE_CODE (*node) == FUNCTION_DECL) - TREE_READONLY (*node) = 1; - else if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) - TREE_TYPE (*node) - = build_pointer_type - (build_type_variant (TREE_TYPE (type), 1, - TREE_THIS_VOLATILE (TREE_TYPE (type)))); - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "transparent_union" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_transparent_union_attribute (tree *node, tree name, - tree ARG_UNUSED (args), int flags, - bool *no_add_attrs) -{ - tree type; - - *no_add_attrs = true; - - - if (TREE_CODE (*node) == TYPE_DECL - && ! (flags & ATTR_FLAG_CXX11)) - node = &TREE_TYPE (*node); - type = *node; - - if (TREE_CODE (type) == UNION_TYPE) - { - /* Make sure that the first field will work for a transparent union. - If the type isn't complete yet, leave the check to the code in - finish_struct. */ - if (TYPE_SIZE (type)) - { - tree first = first_field (type); - if (first == NULL_TREE - || DECL_ARTIFICIAL (first) - || TYPE_MODE (type) != DECL_MODE (first)) - goto ignored; - } - - if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) - { - /* If the type isn't complete yet, setting the flag - on a variant wouldn't ever be checked. */ - if (!TYPE_SIZE (type)) - goto ignored; - - /* build_duplicate_type doesn't work for C++. */ - if (c_dialect_cxx ()) - goto ignored; - - /* A type variant isn't good enough, since we don't a cast - to such a type removed as a no-op. */ - *node = type = build_duplicate_type (type); - } - - TYPE_TRANSPARENT_AGGR (type) = 1; - return NULL_TREE; - } - - ignored: - warning (OPT_Wattributes, "%qE attribute ignored", name); - return NULL_TREE; -} - -/* Subroutine of handle_{con,de}structor_attribute. Evaluate ARGS to - get the requested priority for a constructor or destructor, - possibly issuing diagnostics for invalid or reserved - priorities. */ - -static priority_type -get_priority (tree args, bool is_destructor) -{ - HOST_WIDE_INT pri; - tree arg; - - if (!args) - return DEFAULT_INIT_PRIORITY; - - if (!SUPPORTS_INIT_PRIORITY) - { - if (is_destructor) - error ("destructor priorities are not supported"); - else - error ("constructor priorities are not supported"); - return DEFAULT_INIT_PRIORITY; - } - - arg = TREE_VALUE (args); - arg = default_conversion (arg); - if (!host_integerp (arg, /*pos=*/0) - || !INTEGRAL_TYPE_P (TREE_TYPE (arg))) - goto invalid; - - pri = tree_low_cst (arg, /*pos=*/0); - if (pri < 0 || pri > MAX_INIT_PRIORITY) - goto invalid; - - if (pri <= MAX_RESERVED_INIT_PRIORITY) - { - if (is_destructor) - warning (0, - "destructor priorities from 0 to %d are reserved " - "for the implementation", - MAX_RESERVED_INIT_PRIORITY); - else - warning (0, - "constructor priorities from 0 to %d are reserved " - "for the implementation", - MAX_RESERVED_INIT_PRIORITY); - } - return pri; - - invalid: - if (is_destructor) - error ("destructor priorities must be integers from 0 to %d inclusive", - MAX_INIT_PRIORITY); - else - error ("constructor priorities must be integers from 0 to %d inclusive", - MAX_INIT_PRIORITY); - return DEFAULT_INIT_PRIORITY; -} - -/* Handle a "constructor" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_constructor_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - tree decl = *node; - tree type = TREE_TYPE (decl); - - if (TREE_CODE (decl) == FUNCTION_DECL - && TREE_CODE (type) == FUNCTION_TYPE - && decl_function_context (decl) == 0) - { - priority_type priority; - DECL_STATIC_CONSTRUCTOR (decl) = 1; - priority = get_priority (args, /*is_destructor=*/false); - SET_DECL_INIT_PRIORITY (decl, priority); - TREE_USED (decl) = 1; - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "destructor" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_destructor_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - tree decl = *node; - tree type = TREE_TYPE (decl); - - if (TREE_CODE (decl) == FUNCTION_DECL - && TREE_CODE (type) == FUNCTION_TYPE - && decl_function_context (decl) == 0) - { - priority_type priority; - DECL_STATIC_DESTRUCTOR (decl) = 1; - priority = get_priority (args, /*is_destructor=*/true); - SET_DECL_FINI_PRIORITY (decl, priority); - TREE_USED (decl) = 1; - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Nonzero if the mode is a valid vector mode for this architecture. - This returns nonzero even if there is no hardware support for the - vector mode, but we can emulate with narrower modes. */ - -static int -vector_mode_valid_p (enum machine_mode mode) -{ - enum mode_class mclass = GET_MODE_CLASS (mode); - enum machine_mode innermode; - - /* Doh! What's going on? */ - if (mclass != MODE_VECTOR_INT - && mclass != MODE_VECTOR_FLOAT - && mclass != MODE_VECTOR_FRACT - && mclass != MODE_VECTOR_UFRACT - && mclass != MODE_VECTOR_ACCUM - && mclass != MODE_VECTOR_UACCUM) - return 0; - - /* Hardware support. Woo hoo! */ - if (targetm.vector_mode_supported_p (mode)) - return 1; - - innermode = GET_MODE_INNER (mode); - - /* We should probably return 1 if requesting V4DI and we have no DI, - but we have V2DI, but this is probably very unlikely. */ - - /* If we have support for the inner mode, we can safely emulate it. - We may not have V2DI, but me can emulate with a pair of DIs. */ - return targetm.scalar_mode_supported_p (innermode); -} - - -/* Handle a "mode" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_mode_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - tree type = *node; - tree ident = TREE_VALUE (args); - - *no_add_attrs = true; - - if (TREE_CODE (ident) != IDENTIFIER_NODE) - warning (OPT_Wattributes, "%qE attribute ignored", name); - else - { - int j; - const char *p = IDENTIFIER_POINTER (ident); - int len = strlen (p); - enum machine_mode mode = VOIDmode; - tree typefm; - bool valid_mode; - - if (len > 4 && p[0] == '_' && p[1] == '_' - && p[len - 1] == '_' && p[len - 2] == '_') - { - char *newp = (char *) alloca (len - 1); - - strcpy (newp, &p[2]); - newp[len - 4] = '\0'; - p = newp; - } - - /* Change this type to have a type with the specified mode. - First check for the special modes. */ - if (!strcmp (p, "byte")) - mode = byte_mode; - else if (!strcmp (p, "word")) - mode = word_mode; - else if (!strcmp (p, "pointer")) - mode = ptr_mode; - else if (!strcmp (p, "libgcc_cmp_return")) - mode = targetm.libgcc_cmp_return_mode (); - else if (!strcmp (p, "libgcc_shift_count")) - mode = targetm.libgcc_shift_count_mode (); - else if (!strcmp (p, "unwind_word")) - mode = targetm.unwind_word_mode (); - else - for (j = 0; j < NUM_MACHINE_MODES; j++) - if (!strcmp (p, GET_MODE_NAME (j))) - { - mode = (enum machine_mode) j; - break; - } - - if (mode == VOIDmode) - { - error ("unknown machine mode %qE", ident); - return NULL_TREE; - } - - valid_mode = false; - switch (GET_MODE_CLASS (mode)) - { - case MODE_INT: - case MODE_PARTIAL_INT: - case MODE_FLOAT: - case MODE_DECIMAL_FLOAT: - case MODE_FRACT: - case MODE_UFRACT: - case MODE_ACCUM: - case MODE_UACCUM: - valid_mode = targetm.scalar_mode_supported_p (mode); - break; - - case MODE_COMPLEX_INT: - case MODE_COMPLEX_FLOAT: - valid_mode = targetm.scalar_mode_supported_p (GET_MODE_INNER (mode)); - break; - - case MODE_VECTOR_INT: - case MODE_VECTOR_FLOAT: - case MODE_VECTOR_FRACT: - case MODE_VECTOR_UFRACT: - case MODE_VECTOR_ACCUM: - case MODE_VECTOR_UACCUM: - warning (OPT_Wattributes, "specifying vector types with " - "__attribute__ ((mode)) is deprecated"); - warning (OPT_Wattributes, - "use __attribute__ ((vector_size)) instead"); - valid_mode = vector_mode_valid_p (mode); - break; - - default: - break; - } - if (!valid_mode) - { - error ("unable to emulate %qs", p); - return NULL_TREE; - } - - if (POINTER_TYPE_P (type)) - { - addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type)); - tree (*fn)(tree, enum machine_mode, bool); - - if (!targetm.addr_space.valid_pointer_mode (mode, as)) - { - error ("invalid pointer mode %qs", p); - return NULL_TREE; - } - - if (TREE_CODE (type) == POINTER_TYPE) - fn = build_pointer_type_for_mode; - else - fn = build_reference_type_for_mode; - typefm = fn (TREE_TYPE (type), mode, false); - } - else - { - /* For fixed-point modes, we need to test if the signness of type - and the machine mode are consistent. */ - if (ALL_FIXED_POINT_MODE_P (mode) - && TYPE_UNSIGNED (type) != UNSIGNED_FIXED_POINT_MODE_P (mode)) - { - error ("signedness of type and machine mode %qs don%'t match", p); - return NULL_TREE; - } - /* For fixed-point modes, we need to pass saturating info. */ - typefm = lang_hooks.types.type_for_mode (mode, - ALL_FIXED_POINT_MODE_P (mode) ? TYPE_SATURATING (type) - : TYPE_UNSIGNED (type)); - } - - if (typefm == NULL_TREE) - { - error ("no data type for mode %qs", p); - return NULL_TREE; - } - else if (TREE_CODE (type) == ENUMERAL_TYPE) - { - /* For enumeral types, copy the precision from the integer - type returned above. If not an INTEGER_TYPE, we can't use - this mode for this type. */ - if (TREE_CODE (typefm) != INTEGER_TYPE) - { - error ("cannot use mode %qs for enumeral types", p); - return NULL_TREE; - } - - if (flags & ATTR_FLAG_TYPE_IN_PLACE) - { - TYPE_PRECISION (type) = TYPE_PRECISION (typefm); - typefm = type; - } - else - { - /* We cannot build a type variant, as there's code that assumes - that TYPE_MAIN_VARIANT has the same mode. This includes the - debug generators. Instead, create a subrange type. This - results in all of the enumeral values being emitted only once - in the original, and the subtype gets them by reference. */ - if (TYPE_UNSIGNED (type)) - typefm = make_unsigned_type (TYPE_PRECISION (typefm)); - else - typefm = make_signed_type (TYPE_PRECISION (typefm)); - TREE_TYPE (typefm) = type; - } - } - else if (VECTOR_MODE_P (mode) - ? TREE_CODE (type) != TREE_CODE (TREE_TYPE (typefm)) - : TREE_CODE (type) != TREE_CODE (typefm)) - { - error ("mode %qs applied to inappropriate type", p); - return NULL_TREE; - } - - *node = typefm; - } - - return NULL_TREE; -} - -/* Handle a "section" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args, - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - tree decl = *node; - - if (targetm_common.have_named_sections) - { - user_defined_section_attribute = true; - - if ((TREE_CODE (decl) == FUNCTION_DECL - || TREE_CODE (decl) == VAR_DECL) - && TREE_CODE (TREE_VALUE (args)) == STRING_CST) - { - if (TREE_CODE (decl) == VAR_DECL - && current_function_decl != NULL_TREE - && !TREE_STATIC (decl)) - { - error_at (DECL_SOURCE_LOCATION (decl), - "section attribute cannot be specified for " - "local variables"); - *no_add_attrs = true; - } - - /* The decl may have already been given a section attribute - from a previous declaration. Ensure they match. */ - else if (DECL_SECTION_NAME (decl) != NULL_TREE - && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), - TREE_STRING_POINTER (TREE_VALUE (args))) != 0) - { - error ("section of %q+D conflicts with previous declaration", - *node); - *no_add_attrs = true; - } - else if (TREE_CODE (decl) == VAR_DECL - && !targetm.have_tls && targetm.emutls.tmpl_section - && DECL_THREAD_LOCAL_P (decl)) - { - error ("section of %q+D cannot be overridden", *node); - *no_add_attrs = true; - } - else - DECL_SECTION_NAME (decl) = TREE_VALUE (args); - } - else - { - error ("section attribute not allowed for %q+D", *node); - *no_add_attrs = true; - } - } - else - { - error_at (DECL_SOURCE_LOCATION (*node), - "section attributes are not supported for this target"); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Check whether ALIGN is a valid user-specified alignment. If so, - return its base-2 log; if not, output an error and return -1. If - ALLOW_ZERO then 0 is valid and should result in a return of -1 with - no error. */ -int -check_user_alignment (const_tree align, bool allow_zero) -{ - int i; - - if (TREE_CODE (align) != INTEGER_CST - || !INTEGRAL_TYPE_P (TREE_TYPE (align))) - { - error ("requested alignment is not an integer constant"); - return -1; - } - else if (allow_zero && integer_zerop (align)) - return -1; - else if ((i = tree_log2 (align)) == -1) - { - error ("requested alignment is not a power of 2"); - return -1; - } - else if (i >= HOST_BITS_PER_INT - BITS_PER_UNIT_LOG) - { - error ("requested alignment is too large"); - return -1; - } - return i; -} - -/* - If in c++-11, check if the c++-11 alignment constraint with respect - to fundamental alignment (in [dcl.align]) are satisfied. If not in - c++-11 mode, does nothing. - - [dcl.align]2/ says: - - [* if the constant expression evaluates to a fundamental alignment, - the alignment requirement of the declared entity shall be the - specified fundamental alignment. - - * if the constant expression evaluates to an extended alignment - and the implementation supports that alignment in the context - of the declaration, the alignment of the declared entity shall - be that alignment - - * if the constant expression evaluates to an extended alignment - and the implementation does not support that alignment in the - context of the declaration, the program is ill-formed]. */ - -static bool -check_cxx_fundamental_alignment_constraints (tree node, - unsigned align_log, - int flags) -{ - bool alignment_too_large_p = false; - unsigned requested_alignment = 1U << align_log; - unsigned max_align = 0; - - if ((!(flags & ATTR_FLAG_CXX11) && !warn_cxx_compat) - || (node == NULL_TREE || node == error_mark_node)) - return true; - - if (cxx_fundamental_alignment_p (requested_alignment)) - return true; - - if (DECL_P (node)) - { - if (TREE_STATIC (node)) - { - /* For file scope variables and static members, the target - supports alignments that are at most - MAX_OFILE_ALIGNMENT. */ - if (requested_alignment > (max_align = MAX_OFILE_ALIGNMENT)) - alignment_too_large_p = true; - } - else - { -#ifdef BIGGEST_FIELD_ALIGNMENT -#define MAX_TARGET_FIELD_ALIGNMENT BIGGEST_FIELD_ALIGNMENT -#else -#define MAX_TARGET_FIELD_ALIGNMENT BIGGEST_ALIGNMENT -#endif - /* For non-static members, the target supports either - alignments that at most either BIGGEST_FIELD_ALIGNMENT - if it is defined or BIGGEST_ALIGNMENT. */ - max_align = MAX_TARGET_FIELD_ALIGNMENT; - if (TREE_CODE (node) == FIELD_DECL - && requested_alignment > (max_align = MAX_TARGET_FIELD_ALIGNMENT)) - alignment_too_large_p = true; -#undef MAX_TARGET_FIELD_ALIGNMENT - /* For stack variables, the target supports at most - MAX_STACK_ALIGNMENT. */ - else if (decl_function_context (node) != NULL - && requested_alignment > (max_align = MAX_STACK_ALIGNMENT)) - alignment_too_large_p = true; - } - } - else if (TYPE_P (node)) - { - /* Let's be liberal for types. */ - if (requested_alignment > (max_align = BIGGEST_ALIGNMENT)) - alignment_too_large_p = true; - } - - if (alignment_too_large_p) - pedwarn (input_location, OPT_Wattributes, - "requested alignment %d is larger than %d", - requested_alignment, max_align); - - return !alignment_too_large_p; -} - -/* Handle a "aligned" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args, - int flags, bool *no_add_attrs) -{ - tree decl = NULL_TREE; - tree *type = NULL; - int is_type = 0; - tree align_expr = (args ? TREE_VALUE (args) - : size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT)); - int i; - - if (DECL_P (*node)) - { - decl = *node; - type = &TREE_TYPE (decl); - is_type = TREE_CODE (*node) == TYPE_DECL; - } - else if (TYPE_P (*node)) - type = node, is_type = 1; - - if ((i = check_user_alignment (align_expr, false)) == -1 - || !check_cxx_fundamental_alignment_constraints (*node, i, flags)) - *no_add_attrs = true; - else if (is_type) - { - if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) - /* OK, modify the type in place. */; - /* If we have a TYPE_DECL, then copy the type, so that we - don't accidentally modify a builtin type. See pushdecl. */ - else if (decl && TREE_TYPE (decl) != error_mark_node - && DECL_ORIGINAL_TYPE (decl) == NULL_TREE) - { - tree tt = TREE_TYPE (decl); - *type = build_variant_type_copy (*type); - DECL_ORIGINAL_TYPE (decl) = tt; - TYPE_NAME (*type) = decl; - TREE_USED (*type) = TREE_USED (decl); - TREE_TYPE (decl) = *type; - } - else - *type = build_variant_type_copy (*type); - - TYPE_ALIGN (*type) = (1U << i) * BITS_PER_UNIT; - TYPE_USER_ALIGN (*type) = 1; - } - else if (! VAR_OR_FUNCTION_DECL_P (decl) - && TREE_CODE (decl) != FIELD_DECL) - { - error ("alignment may not be specified for %q+D", decl); - *no_add_attrs = true; - } - else if (DECL_USER_ALIGN (decl) - && DECL_ALIGN (decl) > (1U << i) * BITS_PER_UNIT) - /* C++-11 [dcl.align/4]: - - When multiple alignment-specifiers are specified for an - entity, the alignment requirement shall be set to the - strictest specified alignment. - - This formally comes from the c++11 specification but we are - doing it for the GNU attribute syntax as well. */ - *no_add_attrs = true; - else if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_ALIGN (decl) > (1U << i) * BITS_PER_UNIT) - { - if (DECL_USER_ALIGN (decl)) - error ("alignment for %q+D was previously specified as %d " - "and may not be decreased", decl, - DECL_ALIGN (decl) / BITS_PER_UNIT); - else - error ("alignment for %q+D must be at least %d", decl, - DECL_ALIGN (decl) / BITS_PER_UNIT); - *no_add_attrs = true; - } - else - { - DECL_ALIGN (decl) = (1U << i) * BITS_PER_UNIT; - DECL_USER_ALIGN (decl) = 1; - } - - return NULL_TREE; -} - -/* Handle a "weak" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_weak_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - if (TREE_CODE (*node) == FUNCTION_DECL - && DECL_DECLARED_INLINE_P (*node)) - { - warning (OPT_Wattributes, "inline function %q+D declared weak", *node); - *no_add_attrs = true; - } - else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node))) - { - error ("indirect function %q+D cannot be declared weak", *node); - *no_add_attrs = true; - return NULL_TREE; - } - else if (TREE_CODE (*node) == FUNCTION_DECL - || TREE_CODE (*node) == VAR_DECL) - declare_weak (*node); - else - warning (OPT_Wattributes, "%qE attribute ignored", name); - - return NULL_TREE; -} - -/* Handle an "alias" or "ifunc" attribute; arguments as in - struct attribute_spec.handler, except that IS_ALIAS tells us - whether this is an alias as opposed to ifunc attribute. */ - -static tree -handle_alias_ifunc_attribute (bool is_alias, tree *node, tree name, tree args, - bool *no_add_attrs) -{ - tree decl = *node; - - if (TREE_CODE (decl) != FUNCTION_DECL - && (!is_alias || TREE_CODE (decl) != VAR_DECL)) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)) - || (TREE_CODE (decl) != FUNCTION_DECL - && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) - /* A static variable declaration is always a tentative definition, - but the alias is a non-tentative definition which overrides. */ - || (TREE_CODE (decl) != FUNCTION_DECL - && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl))) - { - error ("%q+D defined both normally and as %qE attribute", decl, name); - *no_add_attrs = true; - return NULL_TREE; - } - else if (!is_alias - && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl)) - || lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))) - { - error ("weak %q+D cannot be defined %qE", decl, name); - *no_add_attrs = true; - return NULL_TREE; - } - - /* Note that the very first time we process a nested declaration, - decl_function_context will not be set. Indeed, *would* never - be set except for the DECL_INITIAL/DECL_EXTERNAL frobbery that - we do below. After such frobbery, pushdecl would set the context. - In any case, this is never what we want. */ - else if (decl_function_context (decl) == 0 && current_function_decl == NULL) - { - tree id; - - id = TREE_VALUE (args); - if (TREE_CODE (id) != STRING_CST) - { - error ("attribute %qE argument not a string", name); - *no_add_attrs = true; - return NULL_TREE; - } - id = get_identifier (TREE_STRING_POINTER (id)); - /* This counts as a use of the object pointed to. */ - TREE_USED (id) = 1; - - if (TREE_CODE (decl) == FUNCTION_DECL) - DECL_INITIAL (decl) = error_mark_node; - else - { - if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) - DECL_EXTERNAL (decl) = 1; - else - DECL_EXTERNAL (decl) = 0; - TREE_STATIC (decl) = 1; - } - - if (!is_alias) - /* ifuncs are also aliases, so set that attribute too. */ - DECL_ATTRIBUTES (decl) - = tree_cons (get_identifier ("alias"), args, DECL_ATTRIBUTES (decl)); - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle an "alias" or "ifunc" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_ifunc_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - return handle_alias_ifunc_attribute (false, node, name, args, no_add_attrs); -} - -/* Handle an "alias" or "ifunc" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_alias_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - return handle_alias_ifunc_attribute (true, node, name, args, no_add_attrs); -} - -/* Handle a "weakref" attribute; arguments as in struct - attribute_spec.handler. */ - -static tree -handle_weakref_attribute (tree *node, tree ARG_UNUSED (name), tree args, - int flags, bool *no_add_attrs) -{ - tree attr = NULL_TREE; - - /* We must ignore the attribute when it is associated with - local-scoped decls, since attribute alias is ignored and many - such symbols do not even have a DECL_WEAK field. */ - if (decl_function_context (*node) - || current_function_decl - || (TREE_CODE (*node) != VAR_DECL && TREE_CODE (*node) != FUNCTION_DECL)) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - return NULL_TREE; - } - - if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node))) - { - error ("indirect function %q+D cannot be declared weakref", *node); - *no_add_attrs = true; - return NULL_TREE; - } - - /* The idea here is that `weakref("name")' mutates into `weakref, - alias("name")', and weakref without arguments, in turn, - implicitly adds weak. */ - - if (args) - { - attr = tree_cons (get_identifier ("alias"), args, attr); - attr = tree_cons (get_identifier ("weakref"), NULL_TREE, attr); - - *no_add_attrs = true; - - decl_attributes (node, attr, flags); - } - else - { - if (lookup_attribute ("alias", DECL_ATTRIBUTES (*node))) - error_at (DECL_SOURCE_LOCATION (*node), - "weakref attribute must appear before alias attribute"); - - /* Can't call declare_weak because it wants this to be TREE_PUBLIC, - and that isn't supported; and because it wants to add it to - the list of weak decls, which isn't helpful. */ - DECL_WEAK (*node) = 1; - } - - return NULL_TREE; -} - -/* Handle an "visibility" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_visibility_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), - bool *ARG_UNUSED (no_add_attrs)) -{ - tree decl = *node; - tree id = TREE_VALUE (args); - enum symbol_visibility vis; - - if (TYPE_P (*node)) - { - if (TREE_CODE (*node) == ENUMERAL_TYPE) - /* OK */; - else if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE) - { - warning (OPT_Wattributes, "%qE attribute ignored on non-class types", - name); - return NULL_TREE; - } - else if (TYPE_FIELDS (*node)) - { - error ("%qE attribute ignored because %qT is already defined", - name, *node); - return NULL_TREE; - } - } - else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl)) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - return NULL_TREE; - } - - if (TREE_CODE (id) != STRING_CST) - { - error ("visibility argument not a string"); - return NULL_TREE; - } - - /* If this is a type, set the visibility on the type decl. */ - if (TYPE_P (decl)) - { - decl = TYPE_NAME (decl); - if (!decl) - return NULL_TREE; - if (TREE_CODE (decl) == IDENTIFIER_NODE) - { - warning (OPT_Wattributes, "%qE attribute ignored on types", - name); - return NULL_TREE; - } - } - - if (strcmp (TREE_STRING_POINTER (id), "default") == 0) - vis = VISIBILITY_DEFAULT; - else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0) - vis = VISIBILITY_INTERNAL; - else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0) - vis = VISIBILITY_HIDDEN; - else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0) - vis = VISIBILITY_PROTECTED; - else - { - error ("visibility argument must be one of \"default\", \"hidden\", \"protected\" or \"internal\""); - vis = VISIBILITY_DEFAULT; - } - - if (DECL_VISIBILITY_SPECIFIED (decl) - && vis != DECL_VISIBILITY (decl)) - { - tree attributes = (TYPE_P (*node) - ? TYPE_ATTRIBUTES (*node) - : DECL_ATTRIBUTES (decl)); - if (lookup_attribute ("visibility", attributes)) - error ("%qD redeclared with different visibility", decl); - else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES - && lookup_attribute ("dllimport", attributes)) - error ("%qD was declared %qs which implies default visibility", - decl, "dllimport"); - else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES - && lookup_attribute ("dllexport", attributes)) - error ("%qD was declared %qs which implies default visibility", - decl, "dllexport"); - } - - DECL_VISIBILITY (decl) = vis; - DECL_VISIBILITY_SPECIFIED (decl) = 1; - - /* Go ahead and attach the attribute to the node as well. This is needed - so we can determine whether we have VISIBILITY_DEFAULT because the - visibility was not specified, or because it was explicitly overridden - from the containing scope. */ - - return NULL_TREE; -} - -/* Determine the ELF symbol visibility for DECL, which is either a - variable or a function. It is an error to use this function if a - definition of DECL is not available in this translation unit. - Returns true if the final visibility has been determined by this - function; false if the caller is free to make additional - modifications. */ - -bool -c_determine_visibility (tree decl) -{ - gcc_assert (TREE_CODE (decl) == VAR_DECL - || TREE_CODE (decl) == FUNCTION_DECL); - - /* If the user explicitly specified the visibility with an - attribute, honor that. DECL_VISIBILITY will have been set during - the processing of the attribute. We check for an explicit - attribute, rather than just checking DECL_VISIBILITY_SPECIFIED, - to distinguish the use of an attribute from the use of a "#pragma - GCC visibility push(...)"; in the latter case we still want other - considerations to be able to overrule the #pragma. */ - if (lookup_attribute ("visibility", DECL_ATTRIBUTES (decl)) - || (TARGET_DLLIMPORT_DECL_ATTRIBUTES - && (lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)) - || lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))))) - return true; - - /* Set default visibility to whatever the user supplied with - visibility_specified depending on #pragma GCC visibility. */ - if (!DECL_VISIBILITY_SPECIFIED (decl)) - { - if (visibility_options.inpragma - || DECL_VISIBILITY (decl) != default_visibility) - { - DECL_VISIBILITY (decl) = default_visibility; - DECL_VISIBILITY_SPECIFIED (decl) = visibility_options.inpragma; - /* If visibility changed and DECL already has DECL_RTL, ensure - symbol flags are updated. */ - if (((TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)) - || TREE_CODE (decl) == FUNCTION_DECL) - && DECL_RTL_SET_P (decl)) - make_decl_rtl (decl); - } - } - return false; -} - -/* Handle an "tls_model" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_tls_model_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - tree id; - tree decl = *node; - enum tls_model kind; - - *no_add_attrs = true; - - if (TREE_CODE (decl) != VAR_DECL || !DECL_THREAD_LOCAL_P (decl)) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - return NULL_TREE; - } - - kind = DECL_TLS_MODEL (decl); - id = TREE_VALUE (args); - if (TREE_CODE (id) != STRING_CST) - { - error ("tls_model argument not a string"); - return NULL_TREE; - } - - if (!strcmp (TREE_STRING_POINTER (id), "local-exec")) - kind = TLS_MODEL_LOCAL_EXEC; - else if (!strcmp (TREE_STRING_POINTER (id), "initial-exec")) - kind = TLS_MODEL_INITIAL_EXEC; - else if (!strcmp (TREE_STRING_POINTER (id), "local-dynamic")) - kind = optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC; - else if (!strcmp (TREE_STRING_POINTER (id), "global-dynamic")) - kind = TLS_MODEL_GLOBAL_DYNAMIC; - else - error ("tls_model argument must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\""); - - DECL_TLS_MODEL (decl) = kind; - return NULL_TREE; -} - -/* Handle a "no_instrument_function" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_no_instrument_function_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - tree decl = *node; - - if (TREE_CODE (decl) != FUNCTION_DECL) - { - error_at (DECL_SOURCE_LOCATION (decl), - "%qE attribute applies only to functions", name); - *no_add_attrs = true; - } - else if (DECL_INITIAL (decl)) - { - error_at (DECL_SOURCE_LOCATION (decl), - "can%'t set %qE attribute after definition", name); - *no_add_attrs = true; - } - else - DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1; - - return NULL_TREE; -} - -/* Handle a "malloc" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_malloc_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL - && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node)))) - DECL_IS_MALLOC (*node) = 1; - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "alloc_size" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args, - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - unsigned arg_count = type_num_arguments (*node); - for (; args; args = TREE_CHAIN (args)) - { - tree position = TREE_VALUE (args); - - if (TREE_CODE (position) != INTEGER_CST - || TREE_INT_CST_HIGH (position) - || TREE_INT_CST_LOW (position) < 1 - || TREE_INT_CST_LOW (position) > arg_count ) - { - warning (OPT_Wattributes, - "alloc_size parameter outside range"); - *no_add_attrs = true; - return NULL_TREE; - } - } - return NULL_TREE; -} - -/* Handle a "fn spec" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name), - tree args, int ARG_UNUSED (flags), - bool *no_add_attrs ATTRIBUTE_UNUSED) -{ - gcc_assert (args - && TREE_CODE (TREE_VALUE (args)) == STRING_CST - && !TREE_CHAIN (args)); - return NULL_TREE; -} - -/* Handle a "returns_twice" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_returns_twice_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - DECL_IS_RETURNS_TWICE (*node) = 1; - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "no_limit_stack" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_no_limit_stack_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - tree decl = *node; - - if (TREE_CODE (decl) != FUNCTION_DECL) - { - error_at (DECL_SOURCE_LOCATION (decl), - "%qE attribute applies only to functions", name); - *no_add_attrs = true; - } - else if (DECL_INITIAL (decl)) - { - error_at (DECL_SOURCE_LOCATION (decl), - "can%'t set %qE attribute after definition", name); - *no_add_attrs = true; - } - else - DECL_NO_LIMIT_STACK (decl) = 1; - - return NULL_TREE; -} - -/* Handle a "pure" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - DECL_PURE_P (*node) = 1; - /* ??? TODO: Support types. */ - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Digest an attribute list destined for a transactional memory statement. - ALLOWED is the set of attributes that are allowed for this statement; - return the attribute we parsed. Multiple attributes are never allowed. */ - -int -parse_tm_stmt_attr (tree attrs, int allowed) -{ - tree a_seen = NULL; - int m_seen = 0; - - for ( ; attrs ; attrs = TREE_CHAIN (attrs)) - { - tree a = TREE_PURPOSE (attrs); - int m = 0; - - if (is_attribute_p ("outer", a)) - m = TM_STMT_ATTR_OUTER; - - if ((m & allowed) == 0) - { - warning (OPT_Wattributes, "%qE attribute directive ignored", a); - continue; - } - - if (m_seen == 0) - { - a_seen = a; - m_seen = m; - } - else if (m_seen == m) - warning (OPT_Wattributes, "%qE attribute duplicated", a); - else - warning (OPT_Wattributes, "%qE attribute follows %qE", a, a_seen); - } - - return m_seen; -} - -/* Transform a TM attribute name into a maskable integer and back. - Note that NULL (i.e. no attribute) is mapped to UNKNOWN, corresponding - to how the lack of an attribute is treated. */ - -int -tm_attr_to_mask (tree attr) -{ - if (attr == NULL) - return 0; - if (is_attribute_p ("transaction_safe", attr)) - return TM_ATTR_SAFE; - if (is_attribute_p ("transaction_callable", attr)) - return TM_ATTR_CALLABLE; - if (is_attribute_p ("transaction_pure", attr)) - return TM_ATTR_PURE; - if (is_attribute_p ("transaction_unsafe", attr)) - return TM_ATTR_IRREVOCABLE; - if (is_attribute_p ("transaction_may_cancel_outer", attr)) - return TM_ATTR_MAY_CANCEL_OUTER; - return 0; -} - -tree -tm_mask_to_attr (int mask) -{ - const char *str; - switch (mask) - { - case TM_ATTR_SAFE: - str = "transaction_safe"; - break; - case TM_ATTR_CALLABLE: - str = "transaction_callable"; - break; - case TM_ATTR_PURE: - str = "transaction_pure"; - break; - case TM_ATTR_IRREVOCABLE: - str = "transaction_unsafe"; - break; - case TM_ATTR_MAY_CANCEL_OUTER: - str = "transaction_may_cancel_outer"; - break; - default: - gcc_unreachable (); - } - return get_identifier (str); -} - -/* Return the first TM attribute seen in LIST. */ - -tree -find_tm_attribute (tree list) -{ - for (; list ; list = TREE_CHAIN (list)) - { - tree name = TREE_PURPOSE (list); - if (tm_attr_to_mask (name) != 0) - return name; - } - return NULL_TREE; -} - -/* Handle the TM attributes; arguments as in struct attribute_spec.handler. - Here we accept only function types, and verify that none of the other - function TM attributes are also applied. */ -/* ??? We need to accept class types for C++, but not C. This greatly - complicates this function, since we can no longer rely on the extra - processing given by function_type_required. */ - -static tree -handle_tm_attribute (tree *node, tree name, tree args, - int flags, bool *no_add_attrs) -{ - /* Only one path adds the attribute; others don't. */ - *no_add_attrs = true; - - switch (TREE_CODE (*node)) - { - case RECORD_TYPE: - case UNION_TYPE: - /* Only tm_callable and tm_safe apply to classes. */ - if (tm_attr_to_mask (name) & ~(TM_ATTR_SAFE | TM_ATTR_CALLABLE)) - goto ignored; - /* FALLTHRU */ - - case FUNCTION_TYPE: - case METHOD_TYPE: - { - tree old_name = find_tm_attribute (TYPE_ATTRIBUTES (*node)); - if (old_name == name) - ; - else if (old_name != NULL_TREE) - error ("type was previously declared %qE", old_name); - else - *no_add_attrs = false; - } - break; - - case POINTER_TYPE: - { - enum tree_code subcode = TREE_CODE (TREE_TYPE (*node)); - if (subcode == FUNCTION_TYPE || subcode == METHOD_TYPE) - { - tree fn_tmp = TREE_TYPE (*node); - decl_attributes (&fn_tmp, tree_cons (name, args, NULL), 0); - *node = build_pointer_type (fn_tmp); - break; - } - } - /* FALLTHRU */ - - default: - /* If a function is next, pass it on to be tried next. */ - if (flags & (int) ATTR_FLAG_FUNCTION_NEXT) - return tree_cons (name, args, NULL); - - ignored: - warning (OPT_Wattributes, "%qE attribute ignored", name); - break; - } - - return NULL_TREE; -} - -/* Handle the TM_WRAP attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_tm_wrap_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - tree decl = *node; - - /* We don't need the attribute even on success, since we - record the entry in an external table. */ - *no_add_attrs = true; - - if (TREE_CODE (decl) != FUNCTION_DECL) - warning (OPT_Wattributes, "%qE attribute ignored", name); - else - { - tree wrap_decl = TREE_VALUE (args); - if (TREE_CODE (wrap_decl) != IDENTIFIER_NODE - && TREE_CODE (wrap_decl) != VAR_DECL - && TREE_CODE (wrap_decl) != FUNCTION_DECL) - error ("%qE argument not an identifier", name); - else - { - if (TREE_CODE (wrap_decl) == IDENTIFIER_NODE) - wrap_decl = lookup_name (wrap_decl); - if (wrap_decl && TREE_CODE (wrap_decl) == FUNCTION_DECL) - { - if (lang_hooks.types_compatible_p (TREE_TYPE (decl), - TREE_TYPE (wrap_decl))) - record_tm_replacement (wrap_decl, decl); - else - error ("%qD is not compatible with %qD", wrap_decl, decl); - } - else - error ("transaction_wrap argument is not a function"); - } - } - - return NULL_TREE; -} - -/* Ignore the given attribute. Used when this attribute may be usefully - overridden by the target, but is not used generically. */ - -static tree -ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - *no_add_attrs = true; - return NULL_TREE; -} - -/* Handle a "no vops" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_novops_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool *ARG_UNUSED (no_add_attrs)) -{ - gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); - DECL_IS_NOVOPS (*node) = 1; - return NULL_TREE; -} - -/* Handle a "deprecated" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_deprecated_attribute (tree *node, tree name, - tree args, int flags, - bool *no_add_attrs) -{ - tree type = NULL_TREE; - int warn = 0; - tree what = NULL_TREE; - - if (!args) - *no_add_attrs = true; - else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST) - { - error ("deprecated message is not a string"); - *no_add_attrs = true; - } - - if (DECL_P (*node)) - { - tree decl = *node; - type = TREE_TYPE (decl); - - if (TREE_CODE (decl) == TYPE_DECL - || TREE_CODE (decl) == PARM_DECL - || TREE_CODE (decl) == VAR_DECL - || TREE_CODE (decl) == FUNCTION_DECL - || TREE_CODE (decl) == FIELD_DECL - || objc_method_decl (TREE_CODE (decl))) - TREE_DEPRECATED (decl) = 1; - else - warn = 1; - } - else if (TYPE_P (*node)) - { - if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) - *node = build_variant_type_copy (*node); - TREE_DEPRECATED (*node) = 1; - type = *node; - } - else - warn = 1; - - if (warn) - { - *no_add_attrs = true; - if (type && TYPE_NAME (type)) - { - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - what = TYPE_NAME (*node); - else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (type))) - what = DECL_NAME (TYPE_NAME (type)); - } - if (what) - warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what); - else - warning (OPT_Wattributes, "%qE attribute ignored", name); - } - - return NULL_TREE; -} - -/* Handle a "vector_size" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_vector_size_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - unsigned HOST_WIDE_INT vecsize, nunits; - enum machine_mode orig_mode; - tree type = *node, new_type, size; - - *no_add_attrs = true; - - size = TREE_VALUE (args); - - if (!host_integerp (size, 1)) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - return NULL_TREE; - } - - /* Get the vector size (in bytes). */ - vecsize = tree_low_cst (size, 1); - - /* We need to provide for vector pointers, vector arrays, and - functions returning vectors. For example: - - __attribute__((vector_size(16))) short *foo; - - In this case, the mode is SI, but the type being modified is - HI, so we need to look further. */ - - while (POINTER_TYPE_P (type) - || TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE - || TREE_CODE (type) == ARRAY_TYPE - || TREE_CODE (type) == OFFSET_TYPE) - type = TREE_TYPE (type); - - /* Get the mode of the type being modified. */ - orig_mode = TYPE_MODE (type); - - if ((!INTEGRAL_TYPE_P (type) - && !SCALAR_FLOAT_TYPE_P (type) - && !FIXED_POINT_TYPE_P (type)) - || (!SCALAR_FLOAT_MODE_P (orig_mode) - && GET_MODE_CLASS (orig_mode) != MODE_INT - && !ALL_SCALAR_FIXED_POINT_MODE_P (orig_mode)) - || !host_integerp (TYPE_SIZE_UNIT (type), 1) - || TREE_CODE (type) == BOOLEAN_TYPE) - { - error ("invalid vector type for attribute %qE", name); - return NULL_TREE; - } - - if (vecsize % tree_low_cst (TYPE_SIZE_UNIT (type), 1)) - { - error ("vector size not an integral multiple of component size"); - return NULL; - } - - if (vecsize == 0) - { - error ("zero vector size"); - return NULL; - } - - /* Calculate how many units fit in the vector. */ - nunits = vecsize / tree_low_cst (TYPE_SIZE_UNIT (type), 1); - if (nunits & (nunits - 1)) - { - error ("number of components of the vector not a power of two"); - return NULL_TREE; - } - - new_type = build_vector_type (type, nunits); - - /* Build back pointers if needed. */ - *node = lang_hooks.types.reconstruct_complex_type (*node, new_type); - - return NULL_TREE; -} - -/* Handle the "nonnull" attribute. */ -static tree -handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name), - tree args, int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - tree type = *node; - unsigned HOST_WIDE_INT attr_arg_num; - - /* If no arguments are specified, all pointer arguments should be - non-null. Verify a full prototype is given so that the arguments - will have the correct types when we actually check them later. */ - if (!args) - { - if (!prototype_p (type)) - { - error ("nonnull attribute without arguments on a non-prototype"); - *no_add_attrs = true; - } - return NULL_TREE; - } - - /* Argument list specified. Verify that each argument number references - a pointer argument. */ - for (attr_arg_num = 1; args; args = TREE_CHAIN (args)) - { - unsigned HOST_WIDE_INT arg_num = 0, ck_num; - - if (!get_nonnull_operand (TREE_VALUE (args), &arg_num)) - { - error ("nonnull argument has invalid operand number (argument %lu)", - (unsigned long) attr_arg_num); - *no_add_attrs = true; - return NULL_TREE; - } - - if (prototype_p (type)) - { - function_args_iterator iter; - tree argument; - - function_args_iter_init (&iter, type); - for (ck_num = 1; ; ck_num++, function_args_iter_next (&iter)) - { - argument = function_args_iter_cond (&iter); - if (argument == NULL_TREE || ck_num == arg_num) - break; - } - - if (!argument - || TREE_CODE (argument) == VOID_TYPE) - { - error ("nonnull argument with out-of-range operand number (argument %lu, operand %lu)", - (unsigned long) attr_arg_num, (unsigned long) arg_num); - *no_add_attrs = true; - return NULL_TREE; - } - - if (TREE_CODE (argument) != POINTER_TYPE) - { - error ("nonnull argument references non-pointer operand (argument %lu, operand %lu)", - (unsigned long) attr_arg_num, (unsigned long) arg_num); - *no_add_attrs = true; - return NULL_TREE; - } - } - } - - return NULL_TREE; -} - -/* Check the argument list of a function call for null in argument slots - that are marked as requiring a non-null pointer argument. The NARGS - arguments are passed in the array ARGARRAY. -*/ - -static void -check_function_nonnull (tree attrs, int nargs, tree *argarray) -{ - tree a; - int i; - - attrs = lookup_attribute ("nonnull", attrs); - if (attrs == NULL_TREE) - return; - - a = attrs; - /* See if any of the nonnull attributes has no arguments. If so, - then every pointer argument is checked (in which case the check - for pointer type is done in check_nonnull_arg). */ - if (TREE_VALUE (a) != NULL_TREE) - do - a = lookup_attribute ("nonnull", TREE_CHAIN (a)); - while (a != NULL_TREE && TREE_VALUE (a) != NULL_TREE); - - if (a != NULL_TREE) - for (i = 0; i < nargs; i++) - check_function_arguments_recurse (check_nonnull_arg, NULL, argarray[i], - i + 1); - else - { - /* Walk the argument list. If we encounter an argument number we - should check for non-null, do it. */ - for (i = 0; i < nargs; i++) - { - for (a = attrs; ; a = TREE_CHAIN (a)) - { - a = lookup_attribute ("nonnull", a); - if (a == NULL_TREE || nonnull_check_p (TREE_VALUE (a), i + 1)) - break; - } - - if (a != NULL_TREE) - check_function_arguments_recurse (check_nonnull_arg, NULL, - argarray[i], i + 1); - } - } -} - -/* Check that the Nth argument of a function call (counting backwards - from the end) is a (pointer)0. The NARGS arguments are passed in the - array ARGARRAY. */ - -static void -check_function_sentinel (const_tree fntype, int nargs, tree *argarray) -{ - tree attr = lookup_attribute ("sentinel", TYPE_ATTRIBUTES (fntype)); - - if (attr) - { - int len = 0; - int pos = 0; - tree sentinel; - function_args_iterator iter; - tree t; - - /* Skip over the named arguments. */ - FOREACH_FUNCTION_ARGS (fntype, t, iter) - { - if (len == nargs) - break; - len++; - } - - if (TREE_VALUE (attr)) - { - tree p = TREE_VALUE (TREE_VALUE (attr)); - pos = TREE_INT_CST_LOW (p); - } - - /* The sentinel must be one of the varargs, i.e. - in position >= the number of fixed arguments. */ - if ((nargs - 1 - pos) < len) - { - warning (OPT_Wformat_, - "not enough variable arguments to fit a sentinel"); - return; - } - - /* Validate the sentinel. */ - sentinel = argarray[nargs - 1 - pos]; - if ((!POINTER_TYPE_P (TREE_TYPE (sentinel)) - || !integer_zerop (sentinel)) - /* Although __null (in C++) is only an integer we allow it - nevertheless, as we are guaranteed that it's exactly - as wide as a pointer, and we don't want to force - users to cast the NULL they have written there. - We warn with -Wstrict-null-sentinel, though. */ - && (warn_strict_null_sentinel || null_node != sentinel)) - warning (OPT_Wformat_, "missing sentinel in function call"); - } -} - -/* Helper for check_function_nonnull; given a list of operands which - must be non-null in ARGS, determine if operand PARAM_NUM should be - checked. */ - -static bool -nonnull_check_p (tree args, unsigned HOST_WIDE_INT param_num) -{ - unsigned HOST_WIDE_INT arg_num = 0; - - for (; args; args = TREE_CHAIN (args)) - { - bool found = get_nonnull_operand (TREE_VALUE (args), &arg_num); - - gcc_assert (found); - - if (arg_num == param_num) - return true; - } - return false; -} - -/* Check that the function argument PARAM (which is operand number - PARAM_NUM) is non-null. This is called by check_function_nonnull - via check_function_arguments_recurse. */ - -static void -check_nonnull_arg (void * ARG_UNUSED (ctx), tree param, - unsigned HOST_WIDE_INT param_num) -{ - /* Just skip checking the argument if it's not a pointer. This can - happen if the "nonnull" attribute was given without an operand - list (which means to check every pointer argument). */ - - if (TREE_CODE (TREE_TYPE (param)) != POINTER_TYPE) - return; - - if (integer_zerop (param)) - warning (OPT_Wnonnull, "null argument where non-null required " - "(argument %lu)", (unsigned long) param_num); -} - -/* Helper for nonnull attribute handling; fetch the operand number - from the attribute argument list. */ - -static bool -get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp) -{ - /* Verify the arg number is a constant. */ - if (TREE_CODE (arg_num_expr) != INTEGER_CST - || TREE_INT_CST_HIGH (arg_num_expr) != 0) - return false; - - *valp = TREE_INT_CST_LOW (arg_num_expr); - return true; -} - -/* Handle a "nothrow" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_nothrow_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - TREE_NOTHROW (*node) = 1; - /* ??? TODO: Support types. */ - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "cleanup" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_cleanup_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - tree decl = *node; - tree cleanup_id, cleanup_decl; - - /* ??? Could perhaps support cleanups on TREE_STATIC, much like we do - for global destructors in C++. This requires infrastructure that - we don't have generically at the moment. It's also not a feature - we'd be missing too much, since we do have attribute constructor. */ - if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - return NULL_TREE; - } - - /* Verify that the argument is a function in scope. */ - /* ??? We could support pointers to functions here as well, if - that was considered desirable. */ - cleanup_id = TREE_VALUE (args); - if (TREE_CODE (cleanup_id) != IDENTIFIER_NODE) - { - error ("cleanup argument not an identifier"); - *no_add_attrs = true; - return NULL_TREE; - } - cleanup_decl = lookup_name (cleanup_id); - if (!cleanup_decl || TREE_CODE (cleanup_decl) != FUNCTION_DECL) - { - error ("cleanup argument not a function"); - *no_add_attrs = true; - return NULL_TREE; - } - - /* That the function has proper type is checked with the - eventual call to build_function_call. */ - - return NULL_TREE; -} - -/* Handle a "warn_unused_result" attribute. No special handling. */ - -static tree -handle_warn_unused_result_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - /* Ignore the attribute for functions not returning any value. */ - if (VOID_TYPE_P (TREE_TYPE (*node))) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "sentinel" attribute. */ - -static tree -handle_sentinel_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (!prototype_p (*node)) - { - warning (OPT_Wattributes, - "%qE attribute requires prototypes with named arguments", name); - *no_add_attrs = true; - } - else - { - if (!stdarg_p (*node)) - { - warning (OPT_Wattributes, - "%qE attribute only applies to variadic functions", name); - *no_add_attrs = true; - } - } - - if (args) - { - tree position = TREE_VALUE (args); - - if (TREE_CODE (position) != INTEGER_CST) - { - warning (OPT_Wattributes, - "requested position is not an integer constant"); - *no_add_attrs = true; - } - else - { - if (tree_int_cst_lt (position, integer_zero_node)) - { - warning (OPT_Wattributes, - "requested position is less than zero"); - *no_add_attrs = true; - } - } - } - - return NULL_TREE; -} - -/* Handle a "type_generic" attribute. */ - -static tree -handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - /* Ensure we have a function type. */ - gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE); - - /* Ensure we have a variadic function. */ - gcc_assert (!prototype_p (*node) || stdarg_p (*node)); - - return NULL_TREE; -} - -/* Handle a "target" attribute. */ - -static tree -handle_target_attribute (tree *node, tree name, tree args, int flags, - bool *no_add_attrs) -{ - /* Ensure we have a function type. */ - if (TREE_CODE (*node) != FUNCTION_DECL) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - else if (! targetm.target_option.valid_attribute_p (*node, name, args, - flags)) - *no_add_attrs = true; - - return NULL_TREE; -} - -/* Arguments being collected for optimization. */ -typedef const char *const_char_p; /* For DEF_VEC_P. */ -static GTY(()) vec<const_char_p, va_gc> *optimize_args; - - -/* Inner function to convert a TREE_LIST to argv string to parse the optimize - options in ARGS. ATTR_P is true if this is for attribute(optimize), and - false for #pragma GCC optimize. */ - -bool -parse_optimize_options (tree args, bool attr_p) -{ - bool ret = true; - unsigned opt_argc; - unsigned i; - int saved_flag_strict_aliasing; - const char **opt_argv; - struct cl_decoded_option *decoded_options; - unsigned int decoded_options_count; - tree ap; - - /* Build up argv vector. Just in case the string is stored away, use garbage - collected strings. */ - vec_safe_truncate (optimize_args, 0); - vec_safe_push (optimize_args, (const char *) NULL); - - for (ap = args; ap != NULL_TREE; ap = TREE_CHAIN (ap)) - { - tree value = TREE_VALUE (ap); - - if (TREE_CODE (value) == INTEGER_CST) - { - char buffer[20]; - sprintf (buffer, "-O%ld", (long) TREE_INT_CST_LOW (value)); - vec_safe_push (optimize_args, ggc_strdup (buffer)); - } - - else if (TREE_CODE (value) == STRING_CST) - { - /* Split string into multiple substrings. */ - size_t len = TREE_STRING_LENGTH (value); - char *p = ASTRDUP (TREE_STRING_POINTER (value)); - char *end = p + len; - char *comma; - char *next_p = p; - - while (next_p != NULL) - { - size_t len2; - char *q, *r; - - p = next_p; - comma = strchr (p, ','); - if (comma) - { - len2 = comma - p; - *comma = '\0'; - next_p = comma+1; - } - else - { - len2 = end - p; - next_p = NULL; - } - - r = q = (char *) ggc_alloc_atomic (len2 + 3); - - /* If the user supplied -Oxxx or -fxxx, only allow -Oxxx or -fxxx - options. */ - if (*p == '-' && p[1] != 'O' && p[1] != 'f') - { - ret = false; - if (attr_p) - warning (OPT_Wattributes, - "bad option %s to optimize attribute", p); - else - warning (OPT_Wpragmas, - "bad option %s to pragma attribute", p); - continue; - } - - if (*p != '-') - { - *r++ = '-'; - - /* Assume that Ox is -Ox, a numeric value is -Ox, a s by - itself is -Os, and any other switch begins with a -f. */ - if ((*p >= '0' && *p <= '9') - || (p[0] == 's' && p[1] == '\0')) - *r++ = 'O'; - else if (*p != 'O') - *r++ = 'f'; - } - - memcpy (r, p, len2); - r[len2] = '\0'; - vec_safe_push (optimize_args, (const char *) q); - } - - } - } - - opt_argc = optimize_args->length (); - opt_argv = (const char **) alloca (sizeof (char *) * (opt_argc + 1)); - - for (i = 1; i < opt_argc; i++) - opt_argv[i] = (*optimize_args)[i]; - - saved_flag_strict_aliasing = flag_strict_aliasing; - - /* Now parse the options. */ - decode_cmdline_options_to_array_default_mask (opt_argc, opt_argv, - &decoded_options, - &decoded_options_count); - decode_options (&global_options, &global_options_set, - decoded_options, decoded_options_count, - input_location, global_dc); - - targetm.override_options_after_change(); - - /* Don't allow changing -fstrict-aliasing. */ - flag_strict_aliasing = saved_flag_strict_aliasing; - - optimize_args->truncate (0); - return ret; -} - -/* For handling "optimize" attribute. arguments as in - struct attribute_spec.handler. */ - -static tree -handle_optimize_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - /* Ensure we have a function type. */ - if (TREE_CODE (*node) != FUNCTION_DECL) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - else - { - struct cl_optimization cur_opts; - tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node); - - /* Save current options. */ - cl_optimization_save (&cur_opts, &global_options); - - /* If we previously had some optimization options, use them as the - default. */ - if (old_opts) - cl_optimization_restore (&global_options, - TREE_OPTIMIZATION (old_opts)); - - /* Parse options, and update the vector. */ - parse_optimize_options (args, true); - DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) - = build_optimization_node (); - - /* Restore current options. */ - cl_optimization_restore (&global_options, &cur_opts); - } - - return NULL_TREE; -} - -/* Handle a "no_split_stack" attribute. */ - -static tree -handle_no_split_stack_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - tree decl = *node; - - if (TREE_CODE (decl) != FUNCTION_DECL) - { - error_at (DECL_SOURCE_LOCATION (decl), - "%qE attribute applies only to functions", name); - *no_add_attrs = true; - } - else if (DECL_INITIAL (decl)) - { - error_at (DECL_SOURCE_LOCATION (decl), - "can%'t set %qE attribute after definition", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Check for valid arguments being passed to a function with FNTYPE. - There are NARGS arguments in the array ARGARRAY. */ -void -check_function_arguments (const_tree fntype, int nargs, tree *argarray) -{ - /* Check for null being passed in a pointer argument that must be - non-null. We also need to do this if format checking is enabled. */ - - if (warn_nonnull) - check_function_nonnull (TYPE_ATTRIBUTES (fntype), nargs, argarray); - - /* Check for errors in format strings. */ - - if (warn_format || warn_suggest_attribute_format) - check_function_format (TYPE_ATTRIBUTES (fntype), nargs, argarray); - - if (warn_format) - check_function_sentinel (fntype, nargs, argarray); -} - -/* Generic argument checking recursion routine. PARAM is the argument to - be checked. PARAM_NUM is the number of the argument. CALLBACK is invoked - once the argument is resolved. CTX is context for the callback. */ -void -check_function_arguments_recurse (void (*callback) - (void *, tree, unsigned HOST_WIDE_INT), - void *ctx, tree param, - unsigned HOST_WIDE_INT param_num) -{ - if (CONVERT_EXPR_P (param) - && (TYPE_PRECISION (TREE_TYPE (param)) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (param, 0))))) - { - /* Strip coercion. */ - check_function_arguments_recurse (callback, ctx, - TREE_OPERAND (param, 0), param_num); - return; - } - - if (TREE_CODE (param) == CALL_EXPR) - { - tree type = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (param))); - tree attrs; - bool found_format_arg = false; - - /* See if this is a call to a known internationalization function - that modifies a format arg. Such a function may have multiple - format_arg attributes (for example, ngettext). */ - - for (attrs = TYPE_ATTRIBUTES (type); - attrs; - attrs = TREE_CHAIN (attrs)) - if (is_attribute_p ("format_arg", TREE_PURPOSE (attrs))) - { - tree inner_arg; - tree format_num_expr; - int format_num; - int i; - call_expr_arg_iterator iter; - - /* Extract the argument number, which was previously checked - to be valid. */ - format_num_expr = TREE_VALUE (TREE_VALUE (attrs)); - - gcc_assert (TREE_CODE (format_num_expr) == INTEGER_CST - && !TREE_INT_CST_HIGH (format_num_expr)); - - format_num = TREE_INT_CST_LOW (format_num_expr); - - for (inner_arg = first_call_expr_arg (param, &iter), i = 1; - inner_arg != 0; - inner_arg = next_call_expr_arg (&iter), i++) - if (i == format_num) - { - check_function_arguments_recurse (callback, ctx, - inner_arg, param_num); - found_format_arg = true; - break; - } - } - - /* If we found a format_arg attribute and did a recursive check, - we are done with checking this argument. Otherwise, we continue - and this will be considered a non-literal. */ - if (found_format_arg) - return; - } - - if (TREE_CODE (param) == COND_EXPR) - { - /* Check both halves of the conditional expression. */ - check_function_arguments_recurse (callback, ctx, - TREE_OPERAND (param, 1), param_num); - check_function_arguments_recurse (callback, ctx, - TREE_OPERAND (param, 2), param_num); - return; - } - - (*callback) (ctx, param, param_num); -} - -/* Checks for a builtin function FNDECL that the number of arguments - NARGS against the required number REQUIRED and issues an error if - there is a mismatch. Returns true if the number of arguments is - correct, otherwise false. */ - -static bool -builtin_function_validate_nargs (tree fndecl, int nargs, int required) -{ - if (nargs < required) - { - error_at (input_location, - "not enough arguments to function %qE", fndecl); - return false; - } - else if (nargs > required) - { - error_at (input_location, - "too many arguments to function %qE", fndecl); - return false; - } - return true; -} - -/* Verifies the NARGS arguments ARGS to the builtin function FNDECL. - Returns false if there was an error, otherwise true. */ - -bool -check_builtin_function_arguments (tree fndecl, int nargs, tree *args) -{ - if (!DECL_BUILT_IN (fndecl) - || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL) - return true; - - switch (DECL_FUNCTION_CODE (fndecl)) - { - case BUILT_IN_CONSTANT_P: - return builtin_function_validate_nargs (fndecl, nargs, 1); - - case BUILT_IN_ISFINITE: - case BUILT_IN_ISINF: - case BUILT_IN_ISINF_SIGN: - case BUILT_IN_ISNAN: - case BUILT_IN_ISNORMAL: - if (builtin_function_validate_nargs (fndecl, nargs, 1)) - { - if (TREE_CODE (TREE_TYPE (args[0])) != REAL_TYPE) - { - error ("non-floating-point argument in call to " - "function %qE", fndecl); - return false; - } - return true; - } - return false; - - case BUILT_IN_ISGREATER: - case BUILT_IN_ISGREATEREQUAL: - case BUILT_IN_ISLESS: - case BUILT_IN_ISLESSEQUAL: - case BUILT_IN_ISLESSGREATER: - case BUILT_IN_ISUNORDERED: - if (builtin_function_validate_nargs (fndecl, nargs, 2)) - { - enum tree_code code0, code1; - code0 = TREE_CODE (TREE_TYPE (args[0])); - code1 = TREE_CODE (TREE_TYPE (args[1])); - if (!((code0 == REAL_TYPE && code1 == REAL_TYPE) - || (code0 == REAL_TYPE && code1 == INTEGER_TYPE) - || (code0 == INTEGER_TYPE && code1 == REAL_TYPE))) - { - error ("non-floating-point arguments in call to " - "function %qE", fndecl); - return false; - } - return true; - } - return false; - - case BUILT_IN_FPCLASSIFY: - if (builtin_function_validate_nargs (fndecl, nargs, 6)) - { - unsigned i; - - for (i=0; i<5; i++) - if (TREE_CODE (args[i]) != INTEGER_CST) - { - error ("non-const integer argument %u in call to function %qE", - i+1, fndecl); - return false; - } - - if (TREE_CODE (TREE_TYPE (args[5])) != REAL_TYPE) - { - error ("non-floating-point argument in call to function %qE", - fndecl); - return false; - } - return true; - } - return false; - - case BUILT_IN_ASSUME_ALIGNED: - if (builtin_function_validate_nargs (fndecl, nargs, 2 + (nargs > 2))) - { - if (nargs >= 3 && TREE_CODE (TREE_TYPE (args[2])) != INTEGER_TYPE) - { - error ("non-integer argument 3 in call to function %qE", fndecl); - return false; - } - return true; - } - return false; - - default: - return true; - } -} - -/* Function to help qsort sort FIELD_DECLs by name order. */ - -int -field_decl_cmp (const void *x_p, const void *y_p) -{ - const tree *const x = (const tree *const) x_p; - const tree *const y = (const tree *const) y_p; - - if (DECL_NAME (*x) == DECL_NAME (*y)) - /* A nontype is "greater" than a type. */ - return (TREE_CODE (*y) == TYPE_DECL) - (TREE_CODE (*x) == TYPE_DECL); - if (DECL_NAME (*x) == NULL_TREE) - return -1; - if (DECL_NAME (*y) == NULL_TREE) - return 1; - if (DECL_NAME (*x) < DECL_NAME (*y)) - return -1; - return 1; -} - -static struct { - gt_pointer_operator new_value; - void *cookie; -} resort_data; - -/* This routine compares two fields like field_decl_cmp but using the -pointer operator in resort_data. */ - -static int -resort_field_decl_cmp (const void *x_p, const void *y_p) -{ - const tree *const x = (const tree *const) x_p; - const tree *const y = (const tree *const) y_p; - - if (DECL_NAME (*x) == DECL_NAME (*y)) - /* A nontype is "greater" than a type. */ - return (TREE_CODE (*y) == TYPE_DECL) - (TREE_CODE (*x) == TYPE_DECL); - if (DECL_NAME (*x) == NULL_TREE) - return -1; - if (DECL_NAME (*y) == NULL_TREE) - return 1; - { - tree d1 = DECL_NAME (*x); - tree d2 = DECL_NAME (*y); - resort_data.new_value (&d1, resort_data.cookie); - resort_data.new_value (&d2, resort_data.cookie); - if (d1 < d2) - return -1; - } - return 1; -} - -/* Resort DECL_SORTED_FIELDS because pointers have been reordered. */ - -void -resort_sorted_fields (void *obj, - void * ARG_UNUSED (orig_obj), - gt_pointer_operator new_value, - void *cookie) -{ - struct sorted_fields_type *sf = (struct sorted_fields_type *) obj; - resort_data.new_value = new_value; - resort_data.cookie = cookie; - qsort (&sf->elts[0], sf->len, sizeof (tree), - resort_field_decl_cmp); -} - -/* Subroutine of c_parse_error. - Return the result of concatenating LHS and RHS. RHS is really - a string literal, its first character is indicated by RHS_START and - RHS_SIZE is its length (including the terminating NUL character). - - The caller is responsible for deleting the returned pointer. */ - -static char * -catenate_strings (const char *lhs, const char *rhs_start, int rhs_size) -{ - const int lhs_size = strlen (lhs); - char *result = XNEWVEC (char, lhs_size + rhs_size); - strncpy (result, lhs, lhs_size); - strncpy (result + lhs_size, rhs_start, rhs_size); - return result; -} - -/* Issue the error given by GMSGID, indicating that it occurred before - TOKEN, which had the associated VALUE. */ - -void -c_parse_error (const char *gmsgid, enum cpp_ttype token_type, - tree value, unsigned char token_flags) -{ -#define catenate_messages(M1, M2) catenate_strings ((M1), (M2), sizeof (M2)) - - char *message = NULL; - - if (token_type == CPP_EOF) - message = catenate_messages (gmsgid, " at end of input"); - else if (token_type == CPP_CHAR - || token_type == CPP_WCHAR - || token_type == CPP_CHAR16 - || token_type == CPP_CHAR32) - { - unsigned int val = TREE_INT_CST_LOW (value); - const char *prefix; - - switch (token_type) - { - default: - prefix = ""; - break; - case CPP_WCHAR: - prefix = "L"; - break; - case CPP_CHAR16: - prefix = "u"; - break; - case CPP_CHAR32: - prefix = "U"; - break; - } - - if (val <= UCHAR_MAX && ISGRAPH (val)) - message = catenate_messages (gmsgid, " before %s'%c'"); - else - message = catenate_messages (gmsgid, " before %s'\\x%x'"); - - error (message, prefix, val); - free (message); - message = NULL; - } - else if (token_type == CPP_STRING - || token_type == CPP_WSTRING - || token_type == CPP_STRING16 - || token_type == CPP_STRING32 - || token_type == CPP_UTF8STRING) - message = catenate_messages (gmsgid, " before string constant"); - else if (token_type == CPP_NUMBER) - message = catenate_messages (gmsgid, " before numeric constant"); - else if (token_type == CPP_NAME) - { - message = catenate_messages (gmsgid, " before %qE"); - error (message, value); - free (message); - message = NULL; - } - else if (token_type == CPP_PRAGMA) - message = catenate_messages (gmsgid, " before %<#pragma%>"); - else if (token_type == CPP_PRAGMA_EOL) - message = catenate_messages (gmsgid, " before end of line"); - else if (token_type == CPP_DECLTYPE) - message = catenate_messages (gmsgid, " before %<decltype%>"); - else if (token_type < N_TTYPES) - { - message = catenate_messages (gmsgid, " before %qs token"); - error (message, cpp_type2name (token_type, token_flags)); - free (message); - message = NULL; - } - else - error (gmsgid); - - if (message) - { - error (message); - free (message); - } -#undef catenate_messages -} - -/* Mapping for cpp message reasons to the options that enable them. */ - -struct reason_option_codes_t -{ - const int reason; /* cpplib message reason. */ - const int option_code; /* gcc option that controls this message. */ -}; - -static const struct reason_option_codes_t option_codes[] = { - {CPP_W_DEPRECATED, OPT_Wdeprecated}, - {CPP_W_COMMENTS, OPT_Wcomment}, - {CPP_W_TRIGRAPHS, OPT_Wtrigraphs}, - {CPP_W_MULTICHAR, OPT_Wmultichar}, - {CPP_W_TRADITIONAL, OPT_Wtraditional}, - {CPP_W_LONG_LONG, OPT_Wlong_long}, - {CPP_W_ENDIF_LABELS, OPT_Wendif_labels}, - {CPP_W_VARIADIC_MACROS, OPT_Wvariadic_macros}, - {CPP_W_BUILTIN_MACRO_REDEFINED, OPT_Wbuiltin_macro_redefined}, - {CPP_W_UNDEF, OPT_Wundef}, - {CPP_W_UNUSED_MACROS, OPT_Wunused_macros}, - {CPP_W_CXX_OPERATOR_NAMES, OPT_Wc___compat}, - {CPP_W_NORMALIZE, OPT_Wnormalized_}, - {CPP_W_INVALID_PCH, OPT_Winvalid_pch}, - {CPP_W_WARNING_DIRECTIVE, OPT_Wcpp}, - {CPP_W_LITERAL_SUFFIX, OPT_Wliteral_suffix}, - {CPP_W_NONE, 0} -}; - -/* Return the gcc option code associated with the reason for a cpp - message, or 0 if none. */ - -static int -c_option_controlling_cpp_error (int reason) -{ - const struct reason_option_codes_t *entry; - - for (entry = option_codes; entry->reason != CPP_W_NONE; entry++) - { - if (entry->reason == reason) - return entry->option_code; - } - return 0; -} - -/* Callback from cpp_error for PFILE to print diagnostics from the - preprocessor. The diagnostic is of type LEVEL, with REASON set - to the reason code if LEVEL is represents a warning, at location - LOCATION unless this is after lexing and the compiler's location - should be used instead, with column number possibly overridden by - COLUMN_OVERRIDE if not zero; MSG is the translated message and AP - the arguments. Returns true if a diagnostic was emitted, false - otherwise. */ - -bool -c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason, - location_t location, unsigned int column_override, - const char *msg, va_list *ap) -{ - diagnostic_info diagnostic; - diagnostic_t dlevel; - bool save_warn_system_headers = global_dc->dc_warn_system_headers; - bool ret; - - switch (level) - { - case CPP_DL_WARNING_SYSHDR: - if (flag_no_output) - return false; - global_dc->dc_warn_system_headers = 1; - /* Fall through. */ - case CPP_DL_WARNING: - if (flag_no_output) - return false; - dlevel = DK_WARNING; - break; - case CPP_DL_PEDWARN: - if (flag_no_output && !flag_pedantic_errors) - return false; - dlevel = DK_PEDWARN; - break; - case CPP_DL_ERROR: - dlevel = DK_ERROR; - break; - case CPP_DL_ICE: - dlevel = DK_ICE; - break; - case CPP_DL_NOTE: - dlevel = DK_NOTE; - break; - case CPP_DL_FATAL: - dlevel = DK_FATAL; - break; - default: - gcc_unreachable (); - } - if (done_lexing) - location = input_location; - diagnostic_set_info_translated (&diagnostic, msg, ap, - location, dlevel); - if (column_override) - diagnostic_override_column (&diagnostic, column_override); - diagnostic_override_option_index (&diagnostic, - c_option_controlling_cpp_error (reason)); - ret = report_diagnostic (&diagnostic); - if (level == CPP_DL_WARNING_SYSHDR) - global_dc->dc_warn_system_headers = save_warn_system_headers; - return ret; -} - -/* Convert a character from the host to the target execution character - set. cpplib handles this, mostly. */ - -HOST_WIDE_INT -c_common_to_target_charset (HOST_WIDE_INT c) -{ - /* Character constants in GCC proper are sign-extended under -fsigned-char, - zero-extended under -fno-signed-char. cpplib insists that characters - and character constants are always unsigned. Hence we must convert - back and forth. */ - cppchar_t uc = ((cppchar_t)c) & ((((cppchar_t)1) << CHAR_BIT)-1); - - uc = cpp_host_to_exec_charset (parse_in, uc); - - if (flag_signed_char) - return ((HOST_WIDE_INT)uc) << (HOST_BITS_PER_WIDE_INT - CHAR_TYPE_SIZE) - >> (HOST_BITS_PER_WIDE_INT - CHAR_TYPE_SIZE); - else - return uc; -} - -/* Fold an offsetof-like expression. EXPR is a nested sequence of component - references with an INDIRECT_REF of a constant at the bottom; much like the - traditional rendering of offsetof as a macro. Return the folded result. */ - -tree -fold_offsetof_1 (tree expr) -{ - tree base, off, t; - - switch (TREE_CODE (expr)) - { - case ERROR_MARK: - return expr; - - case VAR_DECL: - error ("cannot apply %<offsetof%> to static data member %qD", expr); - return error_mark_node; - - case CALL_EXPR: - case TARGET_EXPR: - error ("cannot apply %<offsetof%> when %<operator[]%> is overloaded"); - return error_mark_node; - - case NOP_EXPR: - case INDIRECT_REF: - if (!TREE_CONSTANT (TREE_OPERAND (expr, 0))) - { - error ("cannot apply %<offsetof%> to a non constant address"); - return error_mark_node; - } - return TREE_OPERAND (expr, 0); - - case COMPONENT_REF: - base = fold_offsetof_1 (TREE_OPERAND (expr, 0)); - if (base == error_mark_node) - return base; - - t = TREE_OPERAND (expr, 1); - if (DECL_C_BIT_FIELD (t)) - { - error ("attempt to take address of bit-field structure " - "member %qD", t); - return error_mark_node; - } - off = size_binop_loc (input_location, PLUS_EXPR, DECL_FIELD_OFFSET (t), - size_int (tree_low_cst (DECL_FIELD_BIT_OFFSET (t), - 1) - / BITS_PER_UNIT)); - break; - - case ARRAY_REF: - base = fold_offsetof_1 (TREE_OPERAND (expr, 0)); - if (base == error_mark_node) - return base; - - t = TREE_OPERAND (expr, 1); - - /* Check if the offset goes beyond the upper bound of the array. */ - if (TREE_CODE (t) == INTEGER_CST && tree_int_cst_sgn (t) >= 0) - { - tree upbound = array_ref_up_bound (expr); - if (upbound != NULL_TREE - && TREE_CODE (upbound) == INTEGER_CST - && !tree_int_cst_equal (upbound, - TYPE_MAX_VALUE (TREE_TYPE (upbound)))) - { - upbound = size_binop (PLUS_EXPR, upbound, - build_int_cst (TREE_TYPE (upbound), 1)); - if (tree_int_cst_lt (upbound, t)) - { - tree v; - - for (v = TREE_OPERAND (expr, 0); - TREE_CODE (v) == COMPONENT_REF; - v = TREE_OPERAND (v, 0)) - if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) - == RECORD_TYPE) - { - tree fld_chain = DECL_CHAIN (TREE_OPERAND (v, 1)); - for (; fld_chain; fld_chain = DECL_CHAIN (fld_chain)) - if (TREE_CODE (fld_chain) == FIELD_DECL) - break; - - if (fld_chain) - break; - } - /* Don't warn if the array might be considered a poor - man's flexible array member with a very permissive - definition thereof. */ - if (TREE_CODE (v) == ARRAY_REF - || TREE_CODE (v) == COMPONENT_REF) - warning (OPT_Warray_bounds, - "index %E denotes an offset " - "greater than size of %qT", - t, TREE_TYPE (TREE_OPERAND (expr, 0))); - } - } - } - - t = convert (sizetype, t); - off = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (TREE_TYPE (expr)), t); - break; - - case COMPOUND_EXPR: - /* Handle static members of volatile structs. */ - t = TREE_OPERAND (expr, 1); - gcc_assert (TREE_CODE (t) == VAR_DECL); - return fold_offsetof_1 (t); - - default: - gcc_unreachable (); - } - - return fold_build_pointer_plus (base, off); -} - -/* Likewise, but convert it to the return type of offsetof. */ - -tree -fold_offsetof (tree expr) -{ - return convert (size_type_node, fold_offsetof_1 (expr)); -} - -/* Warn for A ?: C expressions (with B omitted) where A is a boolean - expression, because B will always be true. */ - -void -warn_for_omitted_condop (location_t location, tree cond) -{ - if (truth_value_p (TREE_CODE (cond))) - warning_at (location, OPT_Wparentheses, - "the omitted middle operand in ?: will always be %<true%>, " - "suggest explicit middle operand"); -} - -/* Give an error for storing into ARG, which is 'const'. USE indicates - how ARG was being used. */ - -void -readonly_error (tree arg, enum lvalue_use use) -{ - gcc_assert (use == lv_assign || use == lv_increment || use == lv_decrement - || use == lv_asm); - /* Using this macro rather than (for example) arrays of messages - ensures that all the format strings are checked at compile - time. */ -#define READONLY_MSG(A, I, D, AS) (use == lv_assign ? (A) \ - : (use == lv_increment ? (I) \ - : (use == lv_decrement ? (D) : (AS)))) - if (TREE_CODE (arg) == COMPONENT_REF) - { - if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0)))) - error (READONLY_MSG (G_("assignment of member " - "%qD in read-only object"), - G_("increment of member " - "%qD in read-only object"), - G_("decrement of member " - "%qD in read-only object"), - G_("member %qD in read-only object " - "used as %<asm%> output")), - TREE_OPERAND (arg, 1)); - else - error (READONLY_MSG (G_("assignment of read-only member %qD"), - G_("increment of read-only member %qD"), - G_("decrement of read-only member %qD"), - G_("read-only member %qD used as %<asm%> output")), - TREE_OPERAND (arg, 1)); - } - else if (TREE_CODE (arg) == VAR_DECL) - error (READONLY_MSG (G_("assignment of read-only variable %qD"), - G_("increment of read-only variable %qD"), - G_("decrement of read-only variable %qD"), - G_("read-only variable %qD used as %<asm%> output")), - arg); - else if (TREE_CODE (arg) == PARM_DECL) - error (READONLY_MSG (G_("assignment of read-only parameter %qD"), - G_("increment of read-only parameter %qD"), - G_("decrement of read-only parameter %qD"), - G_("read-only parameter %qD use as %<asm%> output")), - arg); - else if (TREE_CODE (arg) == RESULT_DECL) - { - gcc_assert (c_dialect_cxx ()); - error (READONLY_MSG (G_("assignment of " - "read-only named return value %qD"), - G_("increment of " - "read-only named return value %qD"), - G_("decrement of " - "read-only named return value %qD"), - G_("read-only named return value %qD " - "used as %<asm%>output")), - arg); - } - else if (TREE_CODE (arg) == FUNCTION_DECL) - error (READONLY_MSG (G_("assignment of function %qD"), - G_("increment of function %qD"), - G_("decrement of function %qD"), - G_("function %qD used as %<asm%> output")), - arg); - else - error (READONLY_MSG (G_("assignment of read-only location %qE"), - G_("increment of read-only location %qE"), - G_("decrement of read-only location %qE"), - G_("read-only location %qE used as %<asm%> output")), - arg); -} - -/* Print an error message for an invalid lvalue. USE says - how the lvalue is being used and so selects the error message. LOC - is the location for the error. */ - -void -lvalue_error (location_t loc, enum lvalue_use use) -{ - switch (use) - { - case lv_assign: - error_at (loc, "lvalue required as left operand of assignment"); - break; - case lv_increment: - error_at (loc, "lvalue required as increment operand"); - break; - case lv_decrement: - error_at (loc, "lvalue required as decrement operand"); - break; - case lv_addressof: - error_at (loc, "lvalue required as unary %<&%> operand"); - break; - case lv_asm: - error_at (loc, "lvalue required in asm statement"); - break; - default: - gcc_unreachable (); - } -} - -/* Print an error message for an invalid indirection of type TYPE. - ERRSTRING is the name of the operator for the indirection. */ - -void -invalid_indirection_error (location_t loc, tree type, ref_operator errstring) -{ - switch (errstring) - { - case RO_NULL: - gcc_assert (c_dialect_cxx ()); - error_at (loc, "invalid type argument (have %qT)", type); - break; - case RO_ARRAY_INDEXING: - error_at (loc, - "invalid type argument of array indexing (have %qT)", - type); - break; - case RO_UNARY_STAR: - error_at (loc, - "invalid type argument of unary %<*%> (have %qT)", - type); - break; - case RO_ARROW: - error_at (loc, - "invalid type argument of %<->%> (have %qT)", - type); - break; - case RO_IMPLICIT_CONVERSION: - error_at (loc, - "invalid type argument of implicit conversion (have %qT)", - type); - break; - default: - gcc_unreachable (); - } -} - -/* *PTYPE is an incomplete array. Complete it with a domain based on - INITIAL_VALUE. If INITIAL_VALUE is not present, use 1 if DO_DEFAULT - is true. Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered, - 2 if INITIAL_VALUE was NULL, and 3 if INITIAL_VALUE was empty. */ - -int -complete_array_type (tree *ptype, tree initial_value, bool do_default) -{ - tree maxindex, type, main_type, elt, unqual_elt; - int failure = 0, quals; - hashval_t hashcode = 0; - - maxindex = size_zero_node; - if (initial_value) - { - if (TREE_CODE (initial_value) == STRING_CST) - { - int eltsize - = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value))); - maxindex = size_int (TREE_STRING_LENGTH (initial_value)/eltsize - 1); - } - else if (TREE_CODE (initial_value) == CONSTRUCTOR) - { - vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (initial_value); - - if (vec_safe_is_empty (v)) - { - if (pedantic) - failure = 3; - maxindex = ssize_int (-1); - } - else - { - tree curindex; - unsigned HOST_WIDE_INT cnt; - constructor_elt *ce; - bool fold_p = false; - - if ((*v)[0].index) - maxindex = fold_convert_loc (input_location, sizetype, - (*v)[0].index); - curindex = maxindex; - - for (cnt = 1; vec_safe_iterate (v, cnt, &ce); cnt++) - { - bool curfold_p = false; - if (ce->index) - curindex = ce->index, curfold_p = true; - else - { - if (fold_p) - curindex = fold_convert (sizetype, curindex); - curindex = size_binop (PLUS_EXPR, curindex, - size_one_node); - } - if (tree_int_cst_lt (maxindex, curindex)) - maxindex = curindex, fold_p = curfold_p; - } - if (fold_p) - maxindex = fold_convert (sizetype, maxindex); - } - } - else - { - /* Make an error message unless that happened already. */ - if (initial_value != error_mark_node) - failure = 1; - } - } - else - { - failure = 2; - if (!do_default) - return failure; - } - - type = *ptype; - elt = TREE_TYPE (type); - quals = TYPE_QUALS (strip_array_types (elt)); - if (quals == 0) - unqual_elt = elt; - else - unqual_elt = c_build_qualified_type (elt, KEEP_QUAL_ADDR_SPACE (quals)); - - /* Using build_distinct_type_copy and modifying things afterward instead - of using build_array_type to create a new type preserves all of the - TYPE_LANG_FLAG_? bits that the front end may have set. */ - main_type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type)); - TREE_TYPE (main_type) = unqual_elt; - TYPE_DOMAIN (main_type) - = build_range_type (TREE_TYPE (maxindex), - build_int_cst (TREE_TYPE (maxindex), 0), maxindex); - layout_type (main_type); - - /* Make sure we have the canonical MAIN_TYPE. */ - hashcode = iterative_hash_object (TYPE_HASH (unqual_elt), hashcode); - hashcode = iterative_hash_object (TYPE_HASH (TYPE_DOMAIN (main_type)), - hashcode); - main_type = type_hash_canon (hashcode, main_type); - - /* Fix the canonical type. */ - if (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (main_type)) - || TYPE_STRUCTURAL_EQUALITY_P (TYPE_DOMAIN (main_type))) - SET_TYPE_STRUCTURAL_EQUALITY (main_type); - else if (TYPE_CANONICAL (TREE_TYPE (main_type)) != TREE_TYPE (main_type) - || (TYPE_CANONICAL (TYPE_DOMAIN (main_type)) - != TYPE_DOMAIN (main_type))) - TYPE_CANONICAL (main_type) - = build_array_type (TYPE_CANONICAL (TREE_TYPE (main_type)), - TYPE_CANONICAL (TYPE_DOMAIN (main_type))); - else - TYPE_CANONICAL (main_type) = main_type; - - if (quals == 0) - type = main_type; - else - type = c_build_qualified_type (main_type, quals); - - if (COMPLETE_TYPE_P (type) - && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST - && TREE_OVERFLOW (TYPE_SIZE_UNIT (type))) - { - error ("size of array is too large"); - /* If we proceed with the array type as it is, we'll eventually - crash in tree_low_cst(). */ - type = error_mark_node; - } - - *ptype = type; - return failure; -} - -/* Like c_mark_addressable but don't check register qualifier. */ -void -c_common_mark_addressable_vec (tree t) -{ - while (handled_component_p (t)) - t = TREE_OPERAND (t, 0); - if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) - return; - TREE_ADDRESSABLE (t) = 1; -} - - - -/* Used to help initialize the builtin-types.def table. When a type of - the correct size doesn't exist, use error_mark_node instead of NULL. - The later results in segfaults even when a decl using the type doesn't - get invoked. */ - -tree -builtin_type_for_size (int size, bool unsignedp) -{ - tree type = c_common_type_for_size (size, unsignedp); - return type ? type : error_mark_node; -} - -/* A helper function for resolve_overloaded_builtin in resolving the - overloaded __sync_ builtins. Returns a positive power of 2 if the - first operand of PARAMS is a pointer to a supported data type. - Returns 0 if an error is encountered. */ - -static int -sync_resolve_size (tree function, vec<tree, va_gc> *params) -{ - tree type; - int size; - - if (!params) - { - error ("too few arguments to function %qE", function); - return 0; - } - - type = TREE_TYPE ((*params)[0]); - if (TREE_CODE (type) != POINTER_TYPE) - goto incompatible; - - type = TREE_TYPE (type); - if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type)) - goto incompatible; - - size = tree_low_cst (TYPE_SIZE_UNIT (type), 1); - if (size == 1 || size == 2 || size == 4 || size == 8 || size == 16) - return size; - - incompatible: - error ("incompatible type for argument %d of %qE", 1, function); - return 0; -} - -/* A helper function for resolve_overloaded_builtin. Adds casts to - PARAMS to make arguments match up with those of FUNCTION. Drops - the variadic arguments at the end. Returns false if some error - was encountered; true on success. */ - -static bool -sync_resolve_params (location_t loc, tree orig_function, tree function, - vec<tree, va_gc> *params, bool orig_format) -{ - function_args_iterator iter; - tree ptype; - unsigned int parmnum; - - function_args_iter_init (&iter, TREE_TYPE (function)); - /* We've declared the implementation functions to use "volatile void *" - as the pointer parameter, so we shouldn't get any complaints from the - call to check_function_arguments what ever type the user used. */ - function_args_iter_next (&iter); - ptype = TREE_TYPE (TREE_TYPE ((*params)[0])); - - /* For the rest of the values, we need to cast these to FTYPE, so that we - don't get warnings for passing pointer types, etc. */ - parmnum = 0; - while (1) - { - tree val, arg_type; - - arg_type = function_args_iter_cond (&iter); - /* XXX void_type_node belies the abstraction. */ - if (arg_type == void_type_node) - break; - - ++parmnum; - if (params->length () <= parmnum) - { - error_at (loc, "too few arguments to function %qE", orig_function); - return false; - } - - /* Only convert parameters if arg_type is unsigned integer type with - new format sync routines, i.e. don't attempt to convert pointer - arguments (e.g. EXPECTED argument of __atomic_compare_exchange_n), - bool arguments (e.g. WEAK argument) or signed int arguments (memmodel - kinds). */ - if (TREE_CODE (arg_type) == INTEGER_TYPE && TYPE_UNSIGNED (arg_type)) - { - /* Ideally for the first conversion we'd use convert_for_assignment - so that we get warnings for anything that doesn't match the pointer - type. This isn't portable across the C and C++ front ends atm. */ - val = (*params)[parmnum]; - val = convert (ptype, val); - val = convert (arg_type, val); - (*params)[parmnum] = val; - } - - function_args_iter_next (&iter); - } - - /* __atomic routines are not variadic. */ - if (!orig_format && params->length () != parmnum + 1) - { - error_at (loc, "too many arguments to function %qE", orig_function); - return false; - } - - /* The definition of these primitives is variadic, with the remaining - being "an optional list of variables protected by the memory barrier". - No clue what that's supposed to mean, precisely, but we consider all - call-clobbered variables to be protected so we're safe. */ - params->truncate (parmnum + 1); - - return true; -} - -/* A helper function for resolve_overloaded_builtin. Adds a cast to - RESULT to make it match the type of the first pointer argument in - PARAMS. */ - -static tree -sync_resolve_return (tree first_param, tree result, bool orig_format) -{ - tree ptype = TREE_TYPE (TREE_TYPE (first_param)); - tree rtype = TREE_TYPE (result); - ptype = TYPE_MAIN_VARIANT (ptype); - - /* New format doesn't require casting unless the types are the same size. */ - if (orig_format || tree_int_cst_equal (TYPE_SIZE (ptype), TYPE_SIZE (rtype))) - return convert (ptype, result); - else - return result; -} - -/* This function verifies the PARAMS to generic atomic FUNCTION. - It returns the size if all the parameters are the same size, otherwise - 0 is returned if the parameters are invalid. */ - -static int -get_atomic_generic_size (location_t loc, tree function, - vec<tree, va_gc> *params) -{ - unsigned int n_param; - unsigned int n_model; - unsigned int x; - int size_0; - tree type_0; - - /* Determine the parameter makeup. */ - switch (DECL_FUNCTION_CODE (function)) - { - case BUILT_IN_ATOMIC_EXCHANGE: - n_param = 4; - n_model = 1; - break; - case BUILT_IN_ATOMIC_LOAD: - case BUILT_IN_ATOMIC_STORE: - n_param = 3; - n_model = 1; - break; - case BUILT_IN_ATOMIC_COMPARE_EXCHANGE: - n_param = 6; - n_model = 2; - break; - default: - gcc_unreachable (); - } - - if (vec_safe_length (params) != n_param) - { - error_at (loc, "incorrect number of arguments to function %qE", function); - return 0; - } - - /* Get type of first parameter, and determine its size. */ - type_0 = TREE_TYPE ((*params)[0]); - if (TREE_CODE (type_0) != POINTER_TYPE || VOID_TYPE_P (TREE_TYPE (type_0))) - { - error_at (loc, "argument 1 of %qE must be a non-void pointer type", - function); - return 0; - } - - /* Types must be compile time constant sizes. */ - if (TREE_CODE ((TYPE_SIZE_UNIT (TREE_TYPE (type_0)))) != INTEGER_CST) - { - error_at (loc, - "argument 1 of %qE must be a pointer to a constant size type", - function); - return 0; - } - - size_0 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (type_0)), 1); - - /* Zero size objects are not allowed. */ - if (size_0 == 0) - { - error_at (loc, - "argument 1 of %qE must be a pointer to a nonzero size object", - function); - return 0; - } - - /* Check each other parameter is a pointer and the same size. */ - for (x = 0; x < n_param - n_model; x++) - { - int size; - tree type = TREE_TYPE ((*params)[x]); - /* __atomic_compare_exchange has a bool in the 4th postion, skip it. */ - if (n_param == 6 && x == 3) - continue; - if (!POINTER_TYPE_P (type)) - { - error_at (loc, "argument %d of %qE must be a pointer type", x + 1, - function); - return 0; - } - size = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (type)), 1); - if (size != size_0) - { - error_at (loc, "size mismatch in argument %d of %qE", x + 1, - function); - return 0; - } - } - - /* Check memory model parameters for validity. */ - for (x = n_param - n_model ; x < n_param; x++) - { - tree p = (*params)[x]; - if (TREE_CODE (p) == INTEGER_CST) - { - int i = tree_low_cst (p, 1); - if (i < 0 || (i & MEMMODEL_MASK) >= MEMMODEL_LAST) - { - warning_at (loc, OPT_Winvalid_memory_model, - "invalid memory model argument %d of %qE", x + 1, - function); - } - } - else - if (!INTEGRAL_TYPE_P (TREE_TYPE (p))) - { - error_at (loc, "non-integer memory model argument %d of %qE", x + 1, - function); - return 0; - } - } - - return size_0; -} - - -/* This will take an __atomic_ generic FUNCTION call, and add a size parameter N - at the beginning of the parameter list PARAMS representing the size of the - objects. This is to match the library ABI requirement. LOC is the location - of the function call. - The new function is returned if it needed rebuilding, otherwise NULL_TREE is - returned to allow the external call to be constructed. */ - -static tree -add_atomic_size_parameter (unsigned n, location_t loc, tree function, - vec<tree, va_gc> *params) -{ - tree size_node; - - /* Insert a SIZE_T parameter as the first param. If there isn't - enough space, allocate a new vector and recursively re-build with that. */ - if (!params->space (1)) - { - unsigned int z, len; - vec<tree, va_gc> *v; - tree f; - - len = params->length (); - vec_alloc (v, len + 1); - for (z = 0; z < len; z++) - v->quick_push ((*params)[z]); - f = build_function_call_vec (loc, function, v, NULL); - vec_free (v); - return f; - } - - /* Add the size parameter and leave as a function call for processing. */ - size_node = build_int_cst (size_type_node, n); - params->quick_insert (0, size_node); - return NULL_TREE; -} - - -/* This will process an __atomic_exchange function call, determine whether it - needs to be mapped to the _N variation, or turned into a library call. - LOC is the location of the builtin call. - FUNCTION is the DECL that has been invoked; - PARAMS is the argument list for the call. The return value is non-null - TRUE is returned if it is translated into the proper format for a call to the - external library, and NEW_RETURN is set the tree for that function. - FALSE is returned if processing for the _N variation is required, and - NEW_RETURN is set to the the return value the result is copied into. */ -static bool -resolve_overloaded_atomic_exchange (location_t loc, tree function, - vec<tree, va_gc> *params, tree *new_return) -{ - tree p0, p1, p2, p3; - tree I_type, I_type_ptr; - int n = get_atomic_generic_size (loc, function, params); - - /* Size of 0 is an error condition. */ - if (n == 0) - { - *new_return = error_mark_node; - return true; - } - - /* If not a lock-free size, change to the library generic format. */ - if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16) - { - *new_return = add_atomic_size_parameter (n, loc, function, params); - return true; - } - - /* Otherwise there is a lockfree match, transform the call from: - void fn(T* mem, T* desired, T* return, model) - into - *return = (T) (fn (In* mem, (In) *desired, model)) */ - - p0 = (*params)[0]; - p1 = (*params)[1]; - p2 = (*params)[2]; - p3 = (*params)[3]; - - /* Create pointer to appropriate size. */ - I_type = builtin_type_for_size (BITS_PER_UNIT * n, 1); - I_type_ptr = build_pointer_type (I_type); - - /* Convert object pointer to required type. */ - p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0); - (*params)[0] = p0; - /* Convert new value to required type, and dereference it. */ - p1 = build_indirect_ref (loc, p1, RO_UNARY_STAR); - p1 = build1 (VIEW_CONVERT_EXPR, I_type, p1); - (*params)[1] = p1; - - /* Move memory model to the 3rd position, and end param list. */ - (*params)[2] = p3; - params->truncate (3); - - /* Convert return pointer and dereference it for later assignment. */ - *new_return = build_indirect_ref (loc, p2, RO_UNARY_STAR); - - return false; -} - - -/* This will process an __atomic_compare_exchange function call, determine - whether it needs to be mapped to the _N variation, or turned into a lib call. - LOC is the location of the builtin call. - FUNCTION is the DECL that has been invoked; - PARAMS is the argument list for the call. The return value is non-null - TRUE is returned if it is translated into the proper format for a call to the - external library, and NEW_RETURN is set the tree for that function. - FALSE is returned if processing for the _N variation is required. */ - -static bool -resolve_overloaded_atomic_compare_exchange (location_t loc, tree function, - vec<tree, va_gc> *params, - tree *new_return) -{ - tree p0, p1, p2; - tree I_type, I_type_ptr; - int n = get_atomic_generic_size (loc, function, params); - - /* Size of 0 is an error condition. */ - if (n == 0) - { - *new_return = error_mark_node; - return true; - } - - /* If not a lock-free size, change to the library generic format. */ - if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16) - { - /* The library generic format does not have the weak parameter, so - remove it from the param list. Since a parameter has been removed, - we can be sure that there is room for the SIZE_T parameter, meaning - there will not be a recursive rebuilding of the parameter list, so - there is no danger this will be done twice. */ - if (n > 0) - { - (*params)[3] = (*params)[4]; - (*params)[4] = (*params)[5]; - params->truncate (5); - } - *new_return = add_atomic_size_parameter (n, loc, function, params); - return true; - } - - /* Otherwise, there is a match, so the call needs to be transformed from: - bool fn(T* mem, T* desired, T* return, weak, success, failure) - into - bool fn ((In *)mem, (In *)expected, (In) *desired, weak, succ, fail) */ - - p0 = (*params)[0]; - p1 = (*params)[1]; - p2 = (*params)[2]; - - /* Create pointer to appropriate size. */ - I_type = builtin_type_for_size (BITS_PER_UNIT * n, 1); - I_type_ptr = build_pointer_type (I_type); - - /* Convert object pointer to required type. */ - p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0); - (*params)[0] = p0; - - /* Convert expected pointer to required type. */ - p1 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p1); - (*params)[1] = p1; - - /* Convert desired value to required type, and dereference it. */ - p2 = build_indirect_ref (loc, p2, RO_UNARY_STAR); - p2 = build1 (VIEW_CONVERT_EXPR, I_type, p2); - (*params)[2] = p2; - - /* The rest of the parameters are fine. NULL means no special return value - processing.*/ - *new_return = NULL; - return false; -} - - -/* This will process an __atomic_load function call, determine whether it - needs to be mapped to the _N variation, or turned into a library call. - LOC is the location of the builtin call. - FUNCTION is the DECL that has been invoked; - PARAMS is the argument list for the call. The return value is non-null - TRUE is returned if it is translated into the proper format for a call to the - external library, and NEW_RETURN is set the tree for that function. - FALSE is returned if processing for the _N variation is required, and - NEW_RETURN is set to the the return value the result is copied into. */ - -static bool -resolve_overloaded_atomic_load (location_t loc, tree function, - vec<tree, va_gc> *params, tree *new_return) -{ - tree p0, p1, p2; - tree I_type, I_type_ptr; - int n = get_atomic_generic_size (loc, function, params); - - /* Size of 0 is an error condition. */ - if (n == 0) - { - *new_return = error_mark_node; - return true; - } - - /* If not a lock-free size, change to the library generic format. */ - if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16) - { - *new_return = add_atomic_size_parameter (n, loc, function, params); - return true; - } - - /* Otherwise, there is a match, so the call needs to be transformed from: - void fn(T* mem, T* return, model) - into - *return = (T) (fn ((In *) mem, model)) */ - - p0 = (*params)[0]; - p1 = (*params)[1]; - p2 = (*params)[2]; - - /* Create pointer to appropriate size. */ - I_type = builtin_type_for_size (BITS_PER_UNIT * n, 1); - I_type_ptr = build_pointer_type (I_type); - - /* Convert object pointer to required type. */ - p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0); - (*params)[0] = p0; - - /* Move memory model to the 2nd position, and end param list. */ - (*params)[1] = p2; - params->truncate (2); - - /* Convert return pointer and dereference it for later assignment. */ - *new_return = build_indirect_ref (loc, p1, RO_UNARY_STAR); - - return false; -} - - -/* This will process an __atomic_store function call, determine whether it - needs to be mapped to the _N variation, or turned into a library call. - LOC is the location of the builtin call. - FUNCTION is the DECL that has been invoked; - PARAMS is the argument list for the call. The return value is non-null - TRUE is returned if it is translated into the proper format for a call to the - external library, and NEW_RETURN is set the tree for that function. - FALSE is returned if processing for the _N variation is required, and - NEW_RETURN is set to the the return value the result is copied into. */ - -static bool -resolve_overloaded_atomic_store (location_t loc, tree function, - vec<tree, va_gc> *params, tree *new_return) -{ - tree p0, p1; - tree I_type, I_type_ptr; - int n = get_atomic_generic_size (loc, function, params); - - /* Size of 0 is an error condition. */ - if (n == 0) - { - *new_return = error_mark_node; - return true; - } - - /* If not a lock-free size, change to the library generic format. */ - if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16) - { - *new_return = add_atomic_size_parameter (n, loc, function, params); - return true; - } - - /* Otherwise, there is a match, so the call needs to be transformed from: - void fn(T* mem, T* value, model) - into - fn ((In *) mem, (In) *value, model) */ - - p0 = (*params)[0]; - p1 = (*params)[1]; - - /* Create pointer to appropriate size. */ - I_type = builtin_type_for_size (BITS_PER_UNIT * n, 1); - I_type_ptr = build_pointer_type (I_type); - - /* Convert object pointer to required type. */ - p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0); - (*params)[0] = p0; - - /* Convert new value to required type, and dereference it. */ - p1 = build_indirect_ref (loc, p1, RO_UNARY_STAR); - p1 = build1 (VIEW_CONVERT_EXPR, I_type, p1); - (*params)[1] = p1; - - /* The memory model is in the right spot already. Return is void. */ - *new_return = NULL_TREE; - - return false; -} - - -/* Some builtin functions are placeholders for other expressions. This - function should be called immediately after parsing the call expression - before surrounding code has committed to the type of the expression. - - LOC is the location of the builtin call. - - FUNCTION is the DECL that has been invoked; it is known to be a builtin. - PARAMS is the argument list for the call. The return value is non-null - when expansion is complete, and null if normal processing should - continue. */ - -tree -resolve_overloaded_builtin (location_t loc, tree function, - vec<tree, va_gc> *params) -{ - enum built_in_function orig_code = DECL_FUNCTION_CODE (function); - bool orig_format = true; - tree new_return = NULL_TREE; - - switch (DECL_BUILT_IN_CLASS (function)) - { - case BUILT_IN_NORMAL: - break; - case BUILT_IN_MD: - if (targetm.resolve_overloaded_builtin) - return targetm.resolve_overloaded_builtin (loc, function, params); - else - return NULL_TREE; - default: - return NULL_TREE; - } - - /* Handle BUILT_IN_NORMAL here. */ - switch (orig_code) - { - case BUILT_IN_ATOMIC_EXCHANGE: - case BUILT_IN_ATOMIC_COMPARE_EXCHANGE: - case BUILT_IN_ATOMIC_LOAD: - case BUILT_IN_ATOMIC_STORE: - { - /* Handle these 4 together so that they can fall through to the next - case if the call is transformed to an _N variant. */ - switch (orig_code) - { - case BUILT_IN_ATOMIC_EXCHANGE: - { - if (resolve_overloaded_atomic_exchange (loc, function, params, - &new_return)) - return new_return; - /* Change to the _N variant. */ - orig_code = BUILT_IN_ATOMIC_EXCHANGE_N; - break; - } - - case BUILT_IN_ATOMIC_COMPARE_EXCHANGE: - { - if (resolve_overloaded_atomic_compare_exchange (loc, function, - params, - &new_return)) - return new_return; - /* Change to the _N variant. */ - orig_code = BUILT_IN_ATOMIC_COMPARE_EXCHANGE_N; - break; - } - case BUILT_IN_ATOMIC_LOAD: - { - if (resolve_overloaded_atomic_load (loc, function, params, - &new_return)) - return new_return; - /* Change to the _N variant. */ - orig_code = BUILT_IN_ATOMIC_LOAD_N; - break; - } - case BUILT_IN_ATOMIC_STORE: - { - if (resolve_overloaded_atomic_store (loc, function, params, - &new_return)) - return new_return; - /* Change to the _N variant. */ - orig_code = BUILT_IN_ATOMIC_STORE_N; - break; - } - default: - gcc_unreachable (); - } - /* Fallthrough to the normal processing. */ - } - case BUILT_IN_ATOMIC_EXCHANGE_N: - case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_N: - case BUILT_IN_ATOMIC_LOAD_N: - case BUILT_IN_ATOMIC_STORE_N: - case BUILT_IN_ATOMIC_ADD_FETCH_N: - case BUILT_IN_ATOMIC_SUB_FETCH_N: - case BUILT_IN_ATOMIC_AND_FETCH_N: - case BUILT_IN_ATOMIC_NAND_FETCH_N: - case BUILT_IN_ATOMIC_XOR_FETCH_N: - case BUILT_IN_ATOMIC_OR_FETCH_N: - case BUILT_IN_ATOMIC_FETCH_ADD_N: - case BUILT_IN_ATOMIC_FETCH_SUB_N: - case BUILT_IN_ATOMIC_FETCH_AND_N: - case BUILT_IN_ATOMIC_FETCH_NAND_N: - case BUILT_IN_ATOMIC_FETCH_XOR_N: - case BUILT_IN_ATOMIC_FETCH_OR_N: - { - orig_format = false; - /* Fallthru for parameter processing. */ - } - case BUILT_IN_SYNC_FETCH_AND_ADD_N: - case BUILT_IN_SYNC_FETCH_AND_SUB_N: - case BUILT_IN_SYNC_FETCH_AND_OR_N: - case BUILT_IN_SYNC_FETCH_AND_AND_N: - case BUILT_IN_SYNC_FETCH_AND_XOR_N: - case BUILT_IN_SYNC_FETCH_AND_NAND_N: - case BUILT_IN_SYNC_ADD_AND_FETCH_N: - case BUILT_IN_SYNC_SUB_AND_FETCH_N: - case BUILT_IN_SYNC_OR_AND_FETCH_N: - case BUILT_IN_SYNC_AND_AND_FETCH_N: - case BUILT_IN_SYNC_XOR_AND_FETCH_N: - case BUILT_IN_SYNC_NAND_AND_FETCH_N: - case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_N: - case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N: - case BUILT_IN_SYNC_LOCK_TEST_AND_SET_N: - case BUILT_IN_SYNC_LOCK_RELEASE_N: - { - int n = sync_resolve_size (function, params); - tree new_function, first_param, result; - enum built_in_function fncode; - - if (n == 0) - return error_mark_node; - - fncode = (enum built_in_function)((int)orig_code + exact_log2 (n) + 1); - new_function = builtin_decl_explicit (fncode); - if (!sync_resolve_params (loc, function, new_function, params, - orig_format)) - return error_mark_node; - - first_param = (*params)[0]; - result = build_function_call_vec (loc, new_function, params, NULL); - if (result == error_mark_node) - return result; - if (orig_code != BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_N - && orig_code != BUILT_IN_SYNC_LOCK_RELEASE_N - && orig_code != BUILT_IN_ATOMIC_STORE_N) - result = sync_resolve_return (first_param, result, orig_format); - - /* If new_return is set, assign function to that expr and cast the - result to void since the generic interface returned void. */ - if (new_return) - { - /* Cast function result from I{1,2,4,8,16} to the required type. */ - result = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (new_return), result); - result = build2 (MODIFY_EXPR, TREE_TYPE (new_return), new_return, - result); - TREE_SIDE_EFFECTS (result) = 1; - protected_set_expr_location (result, loc); - result = convert (void_type_node, result); - } - return result; - } - - default: - return NULL_TREE; - } -} - -/* Ignoring their sign, return true if two scalar types are the same. */ -bool -same_scalar_type_ignoring_signedness (tree t1, tree t2) -{ - enum tree_code c1 = TREE_CODE (t1), c2 = TREE_CODE (t2); - - gcc_assert ((c1 == INTEGER_TYPE || c1 == REAL_TYPE || c1 == FIXED_POINT_TYPE) - && (c2 == INTEGER_TYPE || c2 == REAL_TYPE - || c2 == FIXED_POINT_TYPE)); - - /* Equality works here because c_common_signed_type uses - TYPE_MAIN_VARIANT. */ - return c_common_signed_type (t1) - == c_common_signed_type (t2); -} - -/* Check for missing format attributes on function pointers. LTYPE is - the new type or left-hand side type. RTYPE is the old type or - right-hand side type. Returns TRUE if LTYPE is missing the desired - attribute. */ - -bool -check_missing_format_attribute (tree ltype, tree rtype) -{ - tree const ttr = TREE_TYPE (rtype), ttl = TREE_TYPE (ltype); - tree ra; - - for (ra = TYPE_ATTRIBUTES (ttr); ra; ra = TREE_CHAIN (ra)) - if (is_attribute_p ("format", TREE_PURPOSE (ra))) - break; - if (ra) - { - tree la; - for (la = TYPE_ATTRIBUTES (ttl); la; la = TREE_CHAIN (la)) - if (is_attribute_p ("format", TREE_PURPOSE (la))) - break; - return !la; - } - else - return false; -} - -/* Subscripting with type char is likely to lose on a machine where - chars are signed. So warn on any machine, but optionally. Don't - warn for unsigned char since that type is safe. Don't warn for - signed char because anyone who uses that must have done so - deliberately. Furthermore, we reduce the false positive load by - warning only for non-constant value of type char. */ - -void -warn_array_subscript_with_type_char (tree index) -{ - if (TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node - && TREE_CODE (index) != INTEGER_CST) - warning (OPT_Wchar_subscripts, "array subscript has type %<char%>"); -} - -/* Implement -Wparentheses for the unexpected C precedence rules, to - cover cases like x + y << z which readers are likely to - misinterpret. We have seen an expression in which CODE is a binary - operator used to combine expressions ARG_LEFT and ARG_RIGHT, which - before folding had CODE_LEFT and CODE_RIGHT. CODE_LEFT and - CODE_RIGHT may be ERROR_MARK, which means that that side of the - expression was not formed using a binary or unary operator, or it - was enclosed in parentheses. */ - -void -warn_about_parentheses (location_t loc, enum tree_code code, - enum tree_code code_left, tree arg_left, - enum tree_code code_right, tree arg_right) -{ - if (!warn_parentheses) - return; - - /* This macro tests that the expression ARG with original tree code - CODE appears to be a boolean expression. or the result of folding a - boolean expression. */ -#define APPEARS_TO_BE_BOOLEAN_EXPR_P(CODE, ARG) \ - (truth_value_p (TREE_CODE (ARG)) \ - || TREE_CODE (TREE_TYPE (ARG)) == BOOLEAN_TYPE \ - /* Folding may create 0 or 1 integers from other expressions. */ \ - || ((CODE) != INTEGER_CST \ - && (integer_onep (ARG) || integer_zerop (ARG)))) - - switch (code) - { - case LSHIFT_EXPR: - if (code_left == PLUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around %<+%> inside %<<<%>"); - else if (code_right == PLUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around %<+%> inside %<<<%>"); - else if (code_left == MINUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around %<-%> inside %<<<%>"); - else if (code_right == MINUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around %<-%> inside %<<<%>"); - return; - - case RSHIFT_EXPR: - if (code_left == PLUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around %<+%> inside %<>>%>"); - else if (code_right == PLUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around %<+%> inside %<>>%>"); - else if (code_left == MINUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around %<-%> inside %<>>%>"); - else if (code_right == MINUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around %<-%> inside %<>>%>"); - return; - - case TRUTH_ORIF_EXPR: - if (code_left == TRUTH_ANDIF_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around %<&&%> within %<||%>"); - else if (code_right == TRUTH_ANDIF_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around %<&&%> within %<||%>"); - return; - - case BIT_IOR_EXPR: - if (code_left == BIT_AND_EXPR || code_left == BIT_XOR_EXPR - || code_left == PLUS_EXPR || code_left == MINUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around arithmetic in operand of %<|%>"); - else if (code_right == BIT_AND_EXPR || code_right == BIT_XOR_EXPR - || code_right == PLUS_EXPR || code_right == MINUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around arithmetic in operand of %<|%>"); - /* Check cases like x|y==z */ - else if (TREE_CODE_CLASS (code_left) == tcc_comparison) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around comparison in operand of %<|%>"); - else if (TREE_CODE_CLASS (code_right) == tcc_comparison) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around comparison in operand of %<|%>"); - /* Check cases like !x | y */ - else if (code_left == TRUTH_NOT_EXPR - && !APPEARS_TO_BE_BOOLEAN_EXPR_P (code_right, arg_right)) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around operand of " - "%<!%> or change %<|%> to %<||%> or %<!%> to %<~%>"); - return; - - case BIT_XOR_EXPR: - if (code_left == BIT_AND_EXPR - || code_left == PLUS_EXPR || code_left == MINUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around arithmetic in operand of %<^%>"); - else if (code_right == BIT_AND_EXPR - || code_right == PLUS_EXPR || code_right == MINUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around arithmetic in operand of %<^%>"); - /* Check cases like x^y==z */ - else if (TREE_CODE_CLASS (code_left) == tcc_comparison) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around comparison in operand of %<^%>"); - else if (TREE_CODE_CLASS (code_right) == tcc_comparison) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around comparison in operand of %<^%>"); - return; - - case BIT_AND_EXPR: - if (code_left == PLUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around %<+%> in operand of %<&%>"); - else if (code_right == PLUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around %<+%> in operand of %<&%>"); - else if (code_left == MINUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around %<-%> in operand of %<&%>"); - else if (code_right == MINUS_EXPR) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around %<-%> in operand of %<&%>"); - /* Check cases like x&y==z */ - else if (TREE_CODE_CLASS (code_left) == tcc_comparison) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around comparison in operand of %<&%>"); - else if (TREE_CODE_CLASS (code_right) == tcc_comparison) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around comparison in operand of %<&%>"); - /* Check cases like !x & y */ - else if (code_left == TRUTH_NOT_EXPR - && !APPEARS_TO_BE_BOOLEAN_EXPR_P (code_right, arg_right)) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around operand of " - "%<!%> or change %<&%> to %<&&%> or %<!%> to %<~%>"); - return; - - case EQ_EXPR: - if (TREE_CODE_CLASS (code_left) == tcc_comparison) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around comparison in operand of %<==%>"); - else if (TREE_CODE_CLASS (code_right) == tcc_comparison) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around comparison in operand of %<==%>"); - return; - case NE_EXPR: - if (TREE_CODE_CLASS (code_left) == tcc_comparison) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "suggest parentheses around comparison in operand of %<!=%>"); - else if (TREE_CODE_CLASS (code_right) == tcc_comparison) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "suggest parentheses around comparison in operand of %<!=%>"); - return; - - default: - if (TREE_CODE_CLASS (code) == tcc_comparison) - { - if (TREE_CODE_CLASS (code_left) == tcc_comparison - && code_left != NE_EXPR && code_left != EQ_EXPR - && INTEGRAL_TYPE_P (TREE_TYPE (arg_left))) - warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses, - "comparisons like %<X<=Y<=Z%> do not " - "have their mathematical meaning"); - else if (TREE_CODE_CLASS (code_right) == tcc_comparison - && code_right != NE_EXPR && code_right != EQ_EXPR - && INTEGRAL_TYPE_P (TREE_TYPE (arg_right))) - warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses, - "comparisons like %<X<=Y<=Z%> do not " - "have their mathematical meaning"); - } - return; - } -#undef NOT_A_BOOLEAN_EXPR_P -} - -/* If LABEL (a LABEL_DECL) has not been used, issue a warning. */ - -void -warn_for_unused_label (tree label) -{ - if (!TREE_USED (label)) - { - if (DECL_INITIAL (label)) - warning (OPT_Wunused_label, "label %q+D defined but not used", label); - else - warning (OPT_Wunused_label, "label %q+D declared but not defined", label); - } -} - -/* Warn for division by zero according to the value of DIVISOR. LOC - is the location of the division operator. */ - -void -warn_for_div_by_zero (location_t loc, tree divisor) -{ - /* If DIVISOR is zero, and has integral or fixed-point type, issue a warning - about division by zero. Do not issue a warning if DIVISOR has a - floating-point type, since we consider 0.0/0.0 a valid way of - generating a NaN. */ - if (c_inhibit_evaluation_warnings == 0 - && (integer_zerop (divisor) || fixed_zerop (divisor))) - warning_at (loc, OPT_Wdiv_by_zero, "division by zero"); -} - -/* Subroutine of build_binary_op. Give warnings for comparisons - between signed and unsigned quantities that may fail. Do the - checking based on the original operand trees ORIG_OP0 and ORIG_OP1, - so that casts will be considered, but default promotions won't - be. - - LOCATION is the location of the comparison operator. - - The arguments of this function map directly to local variables - of build_binary_op. */ - -void -warn_for_sign_compare (location_t location, - tree orig_op0, tree orig_op1, - tree op0, tree op1, - tree result_type, enum tree_code resultcode) -{ - int op0_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op0)); - int op1_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op1)); - int unsignedp0, unsignedp1; - - /* In C++, check for comparison of different enum types. */ - if (c_dialect_cxx() - && TREE_CODE (TREE_TYPE (orig_op0)) == ENUMERAL_TYPE - && TREE_CODE (TREE_TYPE (orig_op1)) == ENUMERAL_TYPE - && TYPE_MAIN_VARIANT (TREE_TYPE (orig_op0)) - != TYPE_MAIN_VARIANT (TREE_TYPE (orig_op1))) - { - warning_at (location, - OPT_Wsign_compare, "comparison between types %qT and %qT", - TREE_TYPE (orig_op0), TREE_TYPE (orig_op1)); - } - - /* Do not warn if the comparison is being done in a signed type, - since the signed type will only be chosen if it can represent - all the values of the unsigned type. */ - if (!TYPE_UNSIGNED (result_type)) - /* OK */; - /* Do not warn if both operands are unsigned. */ - else if (op0_signed == op1_signed) - /* OK */; - else - { - tree sop, uop, base_type; - bool ovf; - - if (op0_signed) - sop = orig_op0, uop = orig_op1; - else - sop = orig_op1, uop = orig_op0; - - STRIP_TYPE_NOPS (sop); - STRIP_TYPE_NOPS (uop); - base_type = (TREE_CODE (result_type) == COMPLEX_TYPE - ? TREE_TYPE (result_type) : result_type); - - /* Do not warn if the signed quantity is an unsuffixed integer - literal (or some static constant expression involving such - literals or a conditional expression involving such literals) - and it is non-negative. */ - if (tree_expr_nonnegative_warnv_p (sop, &ovf)) - /* OK */; - /* Do not warn if the comparison is an equality operation, the - unsigned quantity is an integral constant, and it would fit - in the result if the result were signed. */ - else if (TREE_CODE (uop) == INTEGER_CST - && (resultcode == EQ_EXPR || resultcode == NE_EXPR) - && int_fits_type_p (uop, c_common_signed_type (base_type))) - /* OK */; - /* In C, do not warn if the unsigned quantity is an enumeration - constant and its maximum value would fit in the result if the - result were signed. */ - else if (!c_dialect_cxx() && TREE_CODE (uop) == INTEGER_CST - && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE - && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (uop)), - c_common_signed_type (base_type))) - /* OK */; - else - warning_at (location, - OPT_Wsign_compare, - "comparison between signed and unsigned integer expressions"); - } - - /* Warn if two unsigned values are being compared in a size larger - than their original size, and one (and only one) is the result of - a `~' operator. This comparison will always fail. - - Also warn if one operand is a constant, and the constant does not - have all bits set that are set in the ~ operand when it is - extended. */ - - op0 = c_common_get_narrower (op0, &unsignedp0); - op1 = c_common_get_narrower (op1, &unsignedp1); - - if ((TREE_CODE (op0) == BIT_NOT_EXPR) - ^ (TREE_CODE (op1) == BIT_NOT_EXPR)) - { - if (TREE_CODE (op0) == BIT_NOT_EXPR) - op0 = c_common_get_narrower (TREE_OPERAND (op0, 0), &unsignedp0); - if (TREE_CODE (op1) == BIT_NOT_EXPR) - op1 = c_common_get_narrower (TREE_OPERAND (op1, 0), &unsignedp1); - - if (host_integerp (op0, 0) || host_integerp (op1, 0)) - { - tree primop; - HOST_WIDE_INT constant, mask; - int unsignedp; - unsigned int bits; - - if (host_integerp (op0, 0)) - { - primop = op1; - unsignedp = unsignedp1; - constant = tree_low_cst (op0, 0); - } - else - { - primop = op0; - unsignedp = unsignedp0; - constant = tree_low_cst (op1, 0); - } - - bits = TYPE_PRECISION (TREE_TYPE (primop)); - if (bits < TYPE_PRECISION (result_type) - && bits < HOST_BITS_PER_LONG && unsignedp) - { - mask = (~ (HOST_WIDE_INT) 0) << bits; - if ((mask & constant) != mask) - { - if (constant == 0) - warning (OPT_Wsign_compare, - "promoted ~unsigned is always non-zero"); - else - warning_at (location, OPT_Wsign_compare, - "comparison of promoted ~unsigned with constant"); - } - } - } - else if (unsignedp0 && unsignedp1 - && (TYPE_PRECISION (TREE_TYPE (op0)) - < TYPE_PRECISION (result_type)) - && (TYPE_PRECISION (TREE_TYPE (op1)) - < TYPE_PRECISION (result_type))) - warning_at (location, OPT_Wsign_compare, - "comparison of promoted ~unsigned with unsigned"); - } -} - -/* RESULT_TYPE is the result of converting TYPE1 and TYPE2 to a common - type via c_common_type. If -Wdouble-promotion is in use, and the - conditions for warning have been met, issue a warning. GMSGID is - the warning message. It must have two %T specifiers for the type - that was converted (generally "float") and the type to which it was - converted (generally "double), respectively. LOC is the location - to which the awrning should refer. */ - -void -do_warn_double_promotion (tree result_type, tree type1, tree type2, - const char *gmsgid, location_t loc) -{ - tree source_type; - - if (!warn_double_promotion) - return; - /* If the conversion will not occur at run-time, there is no need to - warn about it. */ - if (c_inhibit_evaluation_warnings) - return; - if (TYPE_MAIN_VARIANT (result_type) != double_type_node - && TYPE_MAIN_VARIANT (result_type) != complex_double_type_node) - return; - if (TYPE_MAIN_VARIANT (type1) == float_type_node - || TYPE_MAIN_VARIANT (type1) == complex_float_type_node) - source_type = type1; - else if (TYPE_MAIN_VARIANT (type2) == float_type_node - || TYPE_MAIN_VARIANT (type2) == complex_float_type_node) - source_type = type2; - else - return; - warning_at (loc, OPT_Wdouble_promotion, gmsgid, source_type, result_type); -} - -/* Setup a TYPE_DECL node as a typedef representation. - - X is a TYPE_DECL for a typedef statement. Create a brand new - ..._TYPE node (which will be just a variant of the existing - ..._TYPE node with identical properties) and then install X - as the TYPE_NAME of this brand new (duplicate) ..._TYPE node. - - The whole point here is to end up with a situation where each - and every ..._TYPE node the compiler creates will be uniquely - associated with AT MOST one node representing a typedef name. - This way, even though the compiler substitutes corresponding - ..._TYPE nodes for TYPE_DECL (i.e. "typedef name") nodes very - early on, later parts of the compiler can always do the reverse - translation and get back the corresponding typedef name. For - example, given: - - typedef struct S MY_TYPE; - MY_TYPE object; - - Later parts of the compiler might only know that `object' was of - type `struct S' if it were not for code just below. With this - code however, later parts of the compiler see something like: - - struct S' == struct S - typedef struct S' MY_TYPE; - struct S' object; - - And they can then deduce (from the node for type struct S') that - the original object declaration was: - - MY_TYPE object; - - Being able to do this is important for proper support of protoize, - and also for generating precise symbolic debugging information - which takes full account of the programmer's (typedef) vocabulary. - - Obviously, we don't want to generate a duplicate ..._TYPE node if - the TYPE_DECL node that we are now processing really represents a - standard built-in type. */ - -void -set_underlying_type (tree x) -{ - if (x == error_mark_node) - return; - if (DECL_IS_BUILTIN (x)) - { - if (TYPE_NAME (TREE_TYPE (x)) == 0) - TYPE_NAME (TREE_TYPE (x)) = x; - } - else if (TREE_TYPE (x) != error_mark_node - && DECL_ORIGINAL_TYPE (x) == NULL_TREE) - { - tree tt = TREE_TYPE (x); - DECL_ORIGINAL_TYPE (x) = tt; - tt = build_variant_type_copy (tt); - TYPE_STUB_DECL (tt) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x)); - TYPE_NAME (tt) = x; - TREE_USED (tt) = TREE_USED (x); - TREE_TYPE (x) = tt; - } -} - -/* Record the types used by the current global variable declaration - being parsed, so that we can decide later to emit their debug info. - Those types are in types_used_by_cur_var_decl, and we are going to - store them in the types_used_by_vars_hash hash table. - DECL is the declaration of the global variable that has been parsed. */ - -void -record_types_used_by_current_var_decl (tree decl) -{ - gcc_assert (decl && DECL_P (decl) && TREE_STATIC (decl)); - - while (types_used_by_cur_var_decl && !types_used_by_cur_var_decl->is_empty ()) - { - tree type = types_used_by_cur_var_decl->pop (); - types_used_by_var_decl_insert (type, decl); - } -} - -/* If DECL is a typedef that is declared in the current function, - record it for the purpose of -Wunused-local-typedefs. */ - -void -record_locally_defined_typedef (tree decl) -{ - struct c_language_function *l; - - if (!warn_unused_local_typedefs - || cfun == NULL - /* if this is not a locally defined typedef then we are not - interested. */ - || !is_typedef_decl (decl) - || !decl_function_context (decl)) - return; - - l = (struct c_language_function *) cfun->language; - vec_safe_push (l->local_typedefs, decl); -} - -/* If T is a TYPE_DECL declared locally, mark it as used. */ - -void -maybe_record_typedef_use (tree t) -{ - if (!is_typedef_decl (t)) - return; - - TREE_USED (t) = true; -} - -/* Warn if there are some unused locally defined typedefs in the - current function. */ - -void -maybe_warn_unused_local_typedefs (void) -{ - int i; - tree decl; - /* The number of times we have emitted -Wunused-local-typedefs - warnings. If this is different from errorcount, that means some - unrelated errors have been issued. In which case, we'll avoid - emitting "unused-local-typedefs" warnings. */ - static int unused_local_typedefs_warn_count; - struct c_language_function *l; - - if (cfun == NULL) - return; - - if ((l = (struct c_language_function *) cfun->language) == NULL) - return; - - if (warn_unused_local_typedefs - && errorcount == unused_local_typedefs_warn_count) - { - FOR_EACH_VEC_SAFE_ELT (l->local_typedefs, i, decl) - if (!TREE_USED (decl)) - warning_at (DECL_SOURCE_LOCATION (decl), - OPT_Wunused_local_typedefs, - "typedef %qD locally defined but not used", decl); - unused_local_typedefs_warn_count = errorcount; - } - - vec_free (l->local_typedefs); -} - -/* The C and C++ parsers both use vectors to hold function arguments. - For efficiency, we keep a cache of unused vectors. This is the - cache. */ - -typedef vec<tree, va_gc> *tree_gc_vec; -static GTY((deletable)) vec<tree_gc_vec, va_gc> *tree_vector_cache; - -/* Return a new vector from the cache. If the cache is empty, - allocate a new vector. These vectors are GC'ed, so it is OK if the - pointer is not released.. */ - -vec<tree, va_gc> * -make_tree_vector (void) -{ - if (tree_vector_cache && !tree_vector_cache->is_empty ()) - return tree_vector_cache->pop (); - else - { - /* Passing 0 to vec::alloc returns NULL, and our callers require - that we always return a non-NULL value. The vector code uses - 4 when growing a NULL vector, so we do too. */ - vec<tree, va_gc> *v; - vec_alloc (v, 4); - return v; - } -} - -/* Release a vector of trees back to the cache. */ - -void -release_tree_vector (vec<tree, va_gc> *vec) -{ - if (vec != NULL) - { - vec->truncate (0); - vec_safe_push (tree_vector_cache, vec); - } -} - -/* Get a new tree vector holding a single tree. */ - -vec<tree, va_gc> * -make_tree_vector_single (tree t) -{ - vec<tree, va_gc> *ret = make_tree_vector (); - ret->quick_push (t); - return ret; -} - -/* Get a new tree vector of the TREE_VALUEs of a TREE_LIST chain. */ - -vec<tree, va_gc> * -make_tree_vector_from_list (tree list) -{ - vec<tree, va_gc> *ret = make_tree_vector (); - for (; list; list = TREE_CHAIN (list)) - vec_safe_push (ret, TREE_VALUE (list)); - return ret; -} - -/* Get a new tree vector which is a copy of an existing one. */ - -vec<tree, va_gc> * -make_tree_vector_copy (const vec<tree, va_gc> *orig) -{ - vec<tree, va_gc> *ret; - unsigned int ix; - tree t; - - ret = make_tree_vector (); - vec_safe_reserve (ret, vec_safe_length (orig)); - FOR_EACH_VEC_SAFE_ELT (orig, ix, t) - ret->quick_push (t); - return ret; -} - -/* Return true if KEYWORD starts a type specifier. */ - -bool -keyword_begins_type_specifier (enum rid keyword) -{ - switch (keyword) - { - case RID_INT: - case RID_CHAR: - case RID_FLOAT: - case RID_DOUBLE: - case RID_VOID: - case RID_INT128: - case RID_UNSIGNED: - case RID_LONG: - case RID_SHORT: - case RID_SIGNED: - case RID_DFLOAT32: - case RID_DFLOAT64: - case RID_DFLOAT128: - case RID_FRACT: - case RID_ACCUM: - case RID_BOOL: - case RID_WCHAR: - case RID_CHAR16: - case RID_CHAR32: - case RID_SAT: - case RID_COMPLEX: - case RID_TYPEOF: - case RID_STRUCT: - case RID_CLASS: - case RID_UNION: - case RID_ENUM: - return true; - default: - return false; - } -} - -/* Return true if KEYWORD names a type qualifier. */ - -bool -keyword_is_type_qualifier (enum rid keyword) -{ - switch (keyword) - { - case RID_CONST: - case RID_VOLATILE: - case RID_RESTRICT: - return true; - default: - return false; - } -} - -/* Return true if KEYWORD names a storage class specifier. - - RID_TYPEDEF is not included in this list despite `typedef' being - listed in C99 6.7.1.1. 6.7.1.3 indicates that `typedef' is listed as - such for syntactic convenience only. */ - -bool -keyword_is_storage_class_specifier (enum rid keyword) -{ - switch (keyword) - { - case RID_STATIC: - case RID_EXTERN: - case RID_REGISTER: - case RID_AUTO: - case RID_MUTABLE: - case RID_THREAD: - return true; - default: - return false; - } -} - -/* Return true if KEYWORD names a function-specifier [dcl.fct.spec]. */ - -static bool -keyword_is_function_specifier (enum rid keyword) -{ - switch (keyword) - { - case RID_INLINE: - case RID_NORETURN: - case RID_VIRTUAL: - case RID_EXPLICIT: - return true; - default: - return false; - } -} - -/* Return true if KEYWORD names a decl-specifier [dcl.spec] or a - declaration-specifier (C99 6.7). */ - -bool -keyword_is_decl_specifier (enum rid keyword) -{ - if (keyword_is_storage_class_specifier (keyword) - || keyword_is_type_qualifier (keyword) - || keyword_is_function_specifier (keyword)) - return true; - - switch (keyword) - { - case RID_TYPEDEF: - case RID_FRIEND: - case RID_CONSTEXPR: - return true; - default: - return false; - } -} - -/* Initialize language-specific-bits of tree_contains_struct. */ - -void -c_common_init_ts (void) -{ - MARK_TS_TYPED (C_MAYBE_CONST_EXPR); - MARK_TS_TYPED (EXCESS_PRECISION_EXPR); -} - -/* Build a user-defined numeric literal out of an integer constant type VALUE - with identifier SUFFIX. */ - -tree -build_userdef_literal (tree suffix_id, tree value, - enum overflow_type overflow, tree num_string) -{ - tree literal = make_node (USERDEF_LITERAL); - USERDEF_LITERAL_SUFFIX_ID (literal) = suffix_id; - USERDEF_LITERAL_VALUE (literal) = value; - USERDEF_LITERAL_OVERFLOW (literal) = overflow; - USERDEF_LITERAL_NUM_STRING (literal) = num_string; - return literal; -} - -/* For vector[index], convert the vector to a - pointer of the underlying type. */ -void -convert_vector_to_pointer_for_subscript (location_t loc, - tree* vecp, tree index) -{ - if (TREE_CODE (TREE_TYPE (*vecp)) == VECTOR_TYPE) - { - tree type = TREE_TYPE (*vecp); - tree type1; - - if (TREE_CODE (index) == INTEGER_CST) - if (!host_integerp (index, 1) - || ((unsigned HOST_WIDE_INT) tree_low_cst (index, 1) - >= TYPE_VECTOR_SUBPARTS (type))) - warning_at (loc, OPT_Warray_bounds, "index value is out of bound"); - - c_common_mark_addressable_vec (*vecp); - type = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type)); - type = build_pointer_type (type); - type1 = build_pointer_type (TREE_TYPE (*vecp)); - *vecp = build1 (ADDR_EXPR, type1, *vecp); - *vecp = convert (type, *vecp); - } -} - -/* Determine which of the operands, if any, is a scalar that needs to be - converted to a vector, for the range of operations. */ -enum stv_conv -scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1, - bool complain) -{ - tree type0 = TREE_TYPE (op0); - tree type1 = TREE_TYPE (op1); - bool integer_only_op = false; - enum stv_conv ret = stv_firstarg; - - gcc_assert (TREE_CODE (type0) == VECTOR_TYPE - || TREE_CODE (type1) == VECTOR_TYPE); - switch (code) - { - /* Most GENERIC binary expressions require homogeneous arguments. - LSHIFT_EXPR and RSHIFT_EXPR are exceptions and accept a first - argument that is a vector and a second one that is a scalar, so - we never return stv_secondarg for them. */ - case RSHIFT_EXPR: - case LSHIFT_EXPR: - if (TREE_CODE (type0) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE) - { - if (unsafe_conversion_p (TREE_TYPE (type1), op0, false)) - { - if (complain) - error_at (loc, "conversion of scalar %qT to vector %qT " - "involves truncation", type0, type1); - return stv_error; - } - else - return stv_firstarg; - } - break; - - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case BIT_AND_EXPR: - integer_only_op = true; - /* ... fall through ... */ - - case VEC_COND_EXPR: - - case PLUS_EXPR: - case MINUS_EXPR: - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case ROUND_DIV_EXPR: - case EXACT_DIV_EXPR: - case TRUNC_MOD_EXPR: - case FLOOR_MOD_EXPR: - case RDIV_EXPR: - case EQ_EXPR: - case NE_EXPR: - case LE_EXPR: - case GE_EXPR: - case LT_EXPR: - case GT_EXPR: - /* What about UNLT_EXPR? */ - if (TREE_CODE (type0) == VECTOR_TYPE) - { - tree tmp; - ret = stv_secondarg; - /* Swap TYPE0 with TYPE1 and OP0 with OP1 */ - tmp = type0; type0 = type1; type1 = tmp; - tmp = op0; op0 = op1; op1 = tmp; - } - - if (TREE_CODE (type0) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE) - { - if (unsafe_conversion_p (TREE_TYPE (type1), op0, false)) - { - if (complain) - error_at (loc, "conversion of scalar %qT to vector %qT " - "involves truncation", type0, type1); - return stv_error; - } - return ret; - } - else if (!integer_only_op - /* Allow integer --> real conversion if safe. */ - && (TREE_CODE (type0) == REAL_TYPE - || TREE_CODE (type0) == INTEGER_TYPE) - && SCALAR_FLOAT_TYPE_P (TREE_TYPE (type1))) - { - if (unsafe_conversion_p (TREE_TYPE (type1), op0, false)) - { - if (complain) - error_at (loc, "conversion of scalar %qT to vector %qT " - "involves truncation", type0, type1); - return stv_error; - } - return ret; - } - default: - break; - } - - return stv_nothing; -} - -/* Return true iff ALIGN is an integral constant that is a fundamental - alignment, as defined by [basic.align] in the c++-11 - specifications. - - That is: - - [A fundamental alignment is represented by an alignment less than or - equal to the greatest alignment supported by the implementation - in all contexts, which is equal to - alignof(max_align_t)]. */ - -bool -cxx_fundamental_alignment_p (unsigned align) -{ - return (align <= MAX (TYPE_ALIGN (long_long_integer_type_node), - TYPE_ALIGN (long_double_type_node))); -} - -#include "gt-c-family-c-common.h" diff --git a/gcc-4.8.1/gcc/c-family/c-common.def b/gcc-4.8.1/gcc/c-family/c-common.def deleted file mode 100644 index 13113afe5..000000000 --- a/gcc-4.8.1/gcc/c-family/c-common.def +++ /dev/null @@ -1,62 +0,0 @@ -/* This file contains the definitions and documentation for the - additional tree codes used in the GNU C compiler (see tree.def - for the standard codes). - Copyright (C) 1987-2013 Free Software Foundation, Inc. - Written by Benjamin Chelf <chelf@codesourcery.com> - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -/* Tree nodes used in the C frontend. These are also shared with the - C++ and Objective C frontends. */ - -/* A C_MAYBE_CONST_EXPR, currently only used for C and Objective C, - tracks information about constancy of an expression and VLA type - sizes or VM expressions from typeof that need to be evaluated - before the main expression. It is used during parsing and removed - in c_fully_fold. C_MAYBE_CONST_EXPR_PRE is the expression to - evaluate first, if not NULL; C_MAYBE_CONST_EXPR_EXPR is the main - expression. If C_MAYBE_CONST_EXPR_INT_OPERANDS is set then the - expression may be used in an unevaluated part of an integer - constant expression, but not in an evaluated part. If - C_MAYBE_CONST_EXPR_NON_CONST is set then the expression contains - something that cannot occur in an evaluated part of a constant - expression (or outside of sizeof in C90 mode); otherwise it does - not. */ -DEFTREECODE (C_MAYBE_CONST_EXPR, "c_maybe_const_expr", tcc_expression, 2) - -/* An EXCESS_PRECISION_EXPR, currently only used for C and Objective - C, represents an expression evaluated in greater range or precision - than its type. The type of the EXCESS_PRECISION_EXPR is the - semantic type while the operand represents what is actually being - evaluated. */ -DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", tcc_expression, 1) - -/* Used to represent a user-defined literal. - The operands are an IDENTIFIER for the suffix, the VALUE of the literal, - and for numeric literals the original string representation of the - number. */ -DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3) - -/* Represents a 'sizeof' expression during C++ template expansion, - or for the purpose of -Wsizeof-pointer-memaccess warning. */ -DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1) - -/* -Local variables: -mode:c -End: -*/ diff --git a/gcc-4.8.1/gcc/c-family/c-common.h b/gcc-4.8.1/gcc/c-family/c-common.h deleted file mode 100644 index 4014651b8..000000000 --- a/gcc-4.8.1/gcc/c-family/c-common.h +++ /dev/null @@ -1,1136 +0,0 @@ -/* Definitions for c-common.c. - Copyright (C) 1987-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#ifndef GCC_C_COMMON_H -#define GCC_C_COMMON_H - -#include "splay-tree.h" -#include "cpplib.h" -#include "ggc.h" -#include "tree.h" - -/* In order for the format checking to accept the C frontend - diagnostic framework extensions, you must include this file before - diagnostic-core.h, not after. The C front end formats are a subset of those - for C++, so they are the appropriate set to use in common code; - cp-tree.h overrides this for C++. */ -#if defined(GCC_DIAGNOSTIC_CORE_H) -#error \ -In order for the format checking to accept the C front end diagnostic \ -framework extensions, you must include this file before diagnostic-core.h \ -never after. -#endif -#ifndef GCC_DIAG_STYLE -#define GCC_DIAG_STYLE __gcc_cdiag__ -#endif -#include "diagnostic-core.h" - -/* Usage of TREE_LANG_FLAG_?: - 0: IDENTIFIER_MARKED (used by search routines). - C_MAYBE_CONST_EXPR_INT_OPERANDS (in C_MAYBE_CONST_EXPR, for C) - 1: C_DECLARED_LABEL_FLAG (in LABEL_DECL) - STATEMENT_LIST_STMT_EXPR (in STATEMENT_LIST) - C_MAYBE_CONST_EXPR_NON_CONST (in C_MAYBE_CONST_EXPR, for C) - 2: unused - 3: STATEMENT_LIST_HAS_LABEL (in STATEMENT_LIST) - 4: unused -*/ - -/* Reserved identifiers. This is the union of all the keywords for C, - C++, and Objective-C. All the type modifiers have to be in one - block at the beginning, because they are used as mask bits. There - are 28 type modifiers; if we add many more we will have to redesign - the mask mechanism. */ - -enum rid -{ - /* Modifiers: */ - /* C, in empirical order of frequency. */ - RID_STATIC = 0, - RID_UNSIGNED, RID_LONG, RID_CONST, RID_EXTERN, - RID_REGISTER, RID_TYPEDEF, RID_SHORT, RID_INLINE, - RID_VOLATILE, RID_SIGNED, RID_AUTO, RID_RESTRICT, - RID_NORETURN, - - /* C extensions */ - RID_COMPLEX, RID_THREAD, RID_SAT, - - /* C++ */ - RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE, - - /* ObjC ("PQ" reserved words - they do not appear after a '@' and - are keywords only in specific contexts) */ - RID_IN, RID_OUT, RID_INOUT, RID_BYCOPY, RID_BYREF, RID_ONEWAY, - - /* ObjC ("PATTR" reserved words - they do not appear after a '@' - and are keywords only as property attributes) */ - RID_GETTER, RID_SETTER, - RID_READONLY, RID_READWRITE, - RID_ASSIGN, RID_RETAIN, RID_COPY, - RID_NONATOMIC, - - /* C (reserved and imaginary types not implemented, so any use is a - syntax error) */ - RID_IMAGINARY, - - /* C */ - RID_INT, RID_CHAR, RID_FLOAT, RID_DOUBLE, RID_VOID, - RID_INT128, - RID_ENUM, RID_STRUCT, RID_UNION, RID_IF, RID_ELSE, - RID_WHILE, RID_DO, RID_FOR, RID_SWITCH, RID_CASE, - RID_DEFAULT, RID_BREAK, RID_CONTINUE, RID_RETURN, RID_GOTO, - RID_SIZEOF, - - /* C extensions */ - RID_ASM, RID_TYPEOF, RID_ALIGNOF, RID_ATTRIBUTE, RID_VA_ARG, - RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR, - RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE, - RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128, - RID_FRACT, RID_ACCUM, - - /* C11 */ - RID_ALIGNAS, - - /* This means to warn that this is a C++ keyword, and then treat it - as a normal identifier. */ - RID_CXX_COMPAT_WARN, - - /* GNU transactional memory extension */ - RID_TRANSACTION_ATOMIC, RID_TRANSACTION_RELAXED, RID_TRANSACTION_CANCEL, - - /* Too many ways of getting the name of a function as a string */ - RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME, - - /* C++ (some of these are keywords in Objective-C as well, but only - if they appear after a '@') */ - RID_BOOL, RID_WCHAR, RID_CLASS, - RID_PUBLIC, RID_PRIVATE, RID_PROTECTED, - RID_TEMPLATE, RID_NULL, RID_CATCH, - RID_DELETE, RID_FALSE, RID_NAMESPACE, - RID_NEW, RID_OFFSETOF, RID_OPERATOR, - RID_THIS, RID_THROW, RID_TRUE, - RID_TRY, RID_TYPENAME, RID_TYPEID, - RID_USING, RID_CHAR16, RID_CHAR32, - - /* casts */ - RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST, - - /* C++ extensions */ - RID_BASES, RID_DIRECT_BASES, - RID_HAS_NOTHROW_ASSIGN, RID_HAS_NOTHROW_CONSTRUCTOR, - RID_HAS_NOTHROW_COPY, RID_HAS_TRIVIAL_ASSIGN, - RID_HAS_TRIVIAL_CONSTRUCTOR, RID_HAS_TRIVIAL_COPY, - RID_HAS_TRIVIAL_DESTRUCTOR, RID_HAS_VIRTUAL_DESTRUCTOR, - RID_IS_ABSTRACT, RID_IS_BASE_OF, - RID_IS_CLASS, RID_IS_CONVERTIBLE_TO, - RID_IS_EMPTY, RID_IS_ENUM, - RID_IS_FINAL, RID_IS_LITERAL_TYPE, - RID_IS_POD, RID_IS_POLYMORPHIC, - RID_IS_STD_LAYOUT, RID_IS_TRIVIAL, - RID_IS_UNION, RID_UNDERLYING_TYPE, - - /* C++11 */ - RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT, - - /* Objective-C ("AT" reserved words - they are only keywords when - they follow '@') */ - RID_AT_ENCODE, RID_AT_END, - RID_AT_CLASS, RID_AT_ALIAS, RID_AT_DEFS, - RID_AT_PRIVATE, RID_AT_PROTECTED, RID_AT_PUBLIC, RID_AT_PACKAGE, - RID_AT_PROTOCOL, RID_AT_SELECTOR, - RID_AT_THROW, RID_AT_TRY, RID_AT_CATCH, - RID_AT_FINALLY, RID_AT_SYNCHRONIZED, - RID_AT_OPTIONAL, RID_AT_REQUIRED, RID_AT_PROPERTY, - RID_AT_SYNTHESIZE, RID_AT_DYNAMIC, - RID_AT_INTERFACE, - RID_AT_IMPLEMENTATION, - - /* Named address support, mapping the keyword to a particular named address - number. Named address space 0 is reserved for the generic address. If - there are more than 254 named addresses, the addr_space_t type will need - to be grown from an unsigned char to unsigned short. */ - RID_ADDR_SPACE_0, /* generic address */ - RID_ADDR_SPACE_1, - RID_ADDR_SPACE_2, - RID_ADDR_SPACE_3, - RID_ADDR_SPACE_4, - RID_ADDR_SPACE_5, - RID_ADDR_SPACE_6, - RID_ADDR_SPACE_7, - RID_ADDR_SPACE_8, - RID_ADDR_SPACE_9, - RID_ADDR_SPACE_10, - RID_ADDR_SPACE_11, - RID_ADDR_SPACE_12, - RID_ADDR_SPACE_13, - RID_ADDR_SPACE_14, - RID_ADDR_SPACE_15, - - RID_FIRST_ADDR_SPACE = RID_ADDR_SPACE_0, - RID_LAST_ADDR_SPACE = RID_ADDR_SPACE_15, - - RID_MAX, - - RID_FIRST_MODIFIER = RID_STATIC, - RID_LAST_MODIFIER = RID_ONEWAY, - - RID_FIRST_CXX0X = RID_CONSTEXPR, - RID_LAST_CXX0X = RID_STATIC_ASSERT, - RID_FIRST_AT = RID_AT_ENCODE, - RID_LAST_AT = RID_AT_IMPLEMENTATION, - RID_FIRST_PQ = RID_IN, - RID_LAST_PQ = RID_ONEWAY, - RID_FIRST_PATTR = RID_GETTER, - RID_LAST_PATTR = RID_NONATOMIC -}; - -#define OBJC_IS_AT_KEYWORD(rid) \ - ((unsigned int) (rid) >= (unsigned int) RID_FIRST_AT && \ - (unsigned int) (rid) <= (unsigned int) RID_LAST_AT) - -#define OBJC_IS_PQ_KEYWORD(rid) \ - ((unsigned int) (rid) >= (unsigned int) RID_FIRST_PQ && \ - (unsigned int) (rid) <= (unsigned int) RID_LAST_PQ) - -#define OBJC_IS_PATTR_KEYWORD(rid) \ - ((unsigned int) (rid) >= (unsigned int) RID_FIRST_PATTR && \ - (unsigned int) (rid) <= (unsigned int) RID_LAST_PATTR) - -/* OBJC_IS_CXX_KEYWORD recognizes the 'CXX_OBJC' keywords (such as - 'class') which are shared in a subtle way between Objective-C and - C++. When the lexer is lexing in Objective-C/Objective-C++, if it - finds '@' followed by one of these identifiers (eg, '@class'), it - recognizes the whole as an Objective-C keyword. If the identifier - is found elsewhere, it follows the rules of the C/C++ language. - */ -#define OBJC_IS_CXX_KEYWORD(rid) \ - (rid == RID_CLASS \ - || rid == RID_PUBLIC || rid == RID_PROTECTED || rid == RID_PRIVATE \ - || rid == RID_TRY || rid == RID_THROW || rid == RID_CATCH) - -/* The elements of `ridpointers' are identifier nodes for the reserved - type names and storage classes. It is indexed by a RID_... value. */ -extern GTY ((length ("(int) RID_MAX"))) tree *ridpointers; - -/* Standard named or nameless data types of the C compiler. */ - -enum c_tree_index -{ - CTI_CHAR16_TYPE, - CTI_CHAR32_TYPE, - CTI_WCHAR_TYPE, - CTI_UNDERLYING_WCHAR_TYPE, - CTI_WINT_TYPE, - CTI_SIGNED_SIZE_TYPE, /* For format checking only. */ - CTI_UNSIGNED_PTRDIFF_TYPE, /* For format checking only. */ - CTI_INTMAX_TYPE, - CTI_UINTMAX_TYPE, - CTI_WIDEST_INT_LIT_TYPE, - CTI_WIDEST_UINT_LIT_TYPE, - - /* Types for <stdint.h>, that may not be defined on all - targets. */ - CTI_SIG_ATOMIC_TYPE, - CTI_INT8_TYPE, - CTI_INT16_TYPE, - CTI_INT32_TYPE, - CTI_INT64_TYPE, - CTI_UINT8_TYPE, - CTI_UINT16_TYPE, - CTI_UINT32_TYPE, - CTI_UINT64_TYPE, - CTI_INT_LEAST8_TYPE, - CTI_INT_LEAST16_TYPE, - CTI_INT_LEAST32_TYPE, - CTI_INT_LEAST64_TYPE, - CTI_UINT_LEAST8_TYPE, - CTI_UINT_LEAST16_TYPE, - CTI_UINT_LEAST32_TYPE, - CTI_UINT_LEAST64_TYPE, - CTI_INT_FAST8_TYPE, - CTI_INT_FAST16_TYPE, - CTI_INT_FAST32_TYPE, - CTI_INT_FAST64_TYPE, - CTI_UINT_FAST8_TYPE, - CTI_UINT_FAST16_TYPE, - CTI_UINT_FAST32_TYPE, - CTI_UINT_FAST64_TYPE, - CTI_INTPTR_TYPE, - CTI_UINTPTR_TYPE, - - CTI_CHAR_ARRAY_TYPE, - CTI_CHAR16_ARRAY_TYPE, - CTI_CHAR32_ARRAY_TYPE, - CTI_WCHAR_ARRAY_TYPE, - CTI_INT_ARRAY_TYPE, - CTI_STRING_TYPE, - CTI_CONST_STRING_TYPE, - - /* Type for boolean expressions (bool in C++, int in C). */ - CTI_TRUTHVALUE_TYPE, - CTI_TRUTHVALUE_TRUE, - CTI_TRUTHVALUE_FALSE, - - CTI_DEFAULT_FUNCTION_TYPE, - - /* These are not types, but we have to look them up all the time. */ - CTI_FUNCTION_NAME_DECL, - CTI_PRETTY_FUNCTION_NAME_DECL, - CTI_C99_FUNCTION_NAME_DECL, - CTI_SAVED_FUNCTION_NAME_DECLS, - - CTI_VOID_ZERO, - - CTI_NULL, - - CTI_MAX -}; - -#define C_CPP_HASHNODE(id) \ - (&(((struct c_common_identifier *) (id))->node)) -#define C_RID_CODE(id) \ - ((enum rid) (((struct c_common_identifier *) (id))->node.rid_code)) -#define C_SET_RID_CODE(id, code) \ - (((struct c_common_identifier *) (id))->node.rid_code = (unsigned char) code) - -/* Identifier part common to the C front ends. Inherits from - tree_identifier, despite appearances. */ -struct GTY(()) c_common_identifier { - struct tree_common common; - struct cpp_hashnode node; -}; - -/* An entry in the reserved keyword table. */ - -struct c_common_resword -{ - const char *const word; - ENUM_BITFIELD(rid) const rid : 16; - const unsigned int disable : 16; -}; - -/* Extra cpp_ttype values for C++. */ - -/* A token type for keywords, as opposed to ordinary identifiers. */ -#define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1)) - -/* A token type for template-ids. If a template-id is processed while - parsing tentatively, it is replaced with a CPP_TEMPLATE_ID token; - the value of the CPP_TEMPLATE_ID is whatever was returned by - cp_parser_template_id. */ -#define CPP_TEMPLATE_ID ((enum cpp_ttype) (CPP_KEYWORD + 1)) - -/* A token type for nested-name-specifiers. If a - nested-name-specifier is processed while parsing tentatively, it is - replaced with a CPP_NESTED_NAME_SPECIFIER token; the value of the - CPP_NESTED_NAME_SPECIFIER is whatever was returned by - cp_parser_nested_name_specifier_opt. */ -#define CPP_NESTED_NAME_SPECIFIER ((enum cpp_ttype) (CPP_TEMPLATE_ID + 1)) - -/* A token type for pre-parsed C++0x decltype. */ -#define CPP_DECLTYPE ((enum cpp_ttype) (CPP_NESTED_NAME_SPECIFIER + 1)) - -/* The number of token types, including C++-specific ones. */ -#define N_CP_TTYPES ((int) (CPP_DECLTYPE + 1)) - -/* Disable mask. Keywords are disabled if (reswords[i].disable & - mask) is _true_. Thus for keywords which are present in all - languages the disable field is zero. */ - -#define D_CONLY 0x001 /* C only (not in C++). */ -#define D_CXXONLY 0x002 /* C++ only (not in C). */ -#define D_C99 0x004 /* In C, C99 only. */ -#define D_CXX0X 0x008 /* In C++, C++0X only. */ -#define D_EXT 0x010 /* GCC extension. */ -#define D_EXT89 0x020 /* GCC extension incorporated in C99. */ -#define D_ASM 0x040 /* Disabled by -fno-asm. */ -#define D_OBJC 0x080 /* In Objective C and neither C nor C++. */ -#define D_CXX_OBJC 0x100 /* In Objective C, and C++, but not C. */ -#define D_CXXWARN 0x200 /* In C warn with -Wcxx-compat. */ - -/* The reserved keyword table. */ -extern const struct c_common_resword c_common_reswords[]; - -/* The number of items in the reserved keyword table. */ -extern const unsigned int num_c_common_reswords; - -#define char16_type_node c_global_trees[CTI_CHAR16_TYPE] -#define char32_type_node c_global_trees[CTI_CHAR32_TYPE] -#define wchar_type_node c_global_trees[CTI_WCHAR_TYPE] -#define underlying_wchar_type_node c_global_trees[CTI_UNDERLYING_WCHAR_TYPE] -#define wint_type_node c_global_trees[CTI_WINT_TYPE] -#define signed_size_type_node c_global_trees[CTI_SIGNED_SIZE_TYPE] -#define unsigned_ptrdiff_type_node c_global_trees[CTI_UNSIGNED_PTRDIFF_TYPE] -#define intmax_type_node c_global_trees[CTI_INTMAX_TYPE] -#define uintmax_type_node c_global_trees[CTI_UINTMAX_TYPE] -#define widest_integer_literal_type_node c_global_trees[CTI_WIDEST_INT_LIT_TYPE] -#define widest_unsigned_literal_type_node c_global_trees[CTI_WIDEST_UINT_LIT_TYPE] - -#define sig_atomic_type_node c_global_trees[CTI_SIG_ATOMIC_TYPE] -#define int8_type_node c_global_trees[CTI_INT8_TYPE] -#define int16_type_node c_global_trees[CTI_INT16_TYPE] -#define int32_type_node c_global_trees[CTI_INT32_TYPE] -#define int64_type_node c_global_trees[CTI_INT64_TYPE] -#define uint8_type_node c_global_trees[CTI_UINT8_TYPE] -#define c_uint16_type_node c_global_trees[CTI_UINT16_TYPE] -#define c_uint32_type_node c_global_trees[CTI_UINT32_TYPE] -#define c_uint64_type_node c_global_trees[CTI_UINT64_TYPE] -#define int_least8_type_node c_global_trees[CTI_INT_LEAST8_TYPE] -#define int_least16_type_node c_global_trees[CTI_INT_LEAST16_TYPE] -#define int_least32_type_node c_global_trees[CTI_INT_LEAST32_TYPE] -#define int_least64_type_node c_global_trees[CTI_INT_LEAST64_TYPE] -#define uint_least8_type_node c_global_trees[CTI_UINT_LEAST8_TYPE] -#define uint_least16_type_node c_global_trees[CTI_UINT_LEAST16_TYPE] -#define uint_least32_type_node c_global_trees[CTI_UINT_LEAST32_TYPE] -#define uint_least64_type_node c_global_trees[CTI_UINT_LEAST64_TYPE] -#define int_fast8_type_node c_global_trees[CTI_INT_FAST8_TYPE] -#define int_fast16_type_node c_global_trees[CTI_INT_FAST16_TYPE] -#define int_fast32_type_node c_global_trees[CTI_INT_FAST32_TYPE] -#define int_fast64_type_node c_global_trees[CTI_INT_FAST64_TYPE] -#define uint_fast8_type_node c_global_trees[CTI_UINT_FAST8_TYPE] -#define uint_fast16_type_node c_global_trees[CTI_UINT_FAST16_TYPE] -#define uint_fast32_type_node c_global_trees[CTI_UINT_FAST32_TYPE] -#define uint_fast64_type_node c_global_trees[CTI_UINT_FAST64_TYPE] -#define intptr_type_node c_global_trees[CTI_INTPTR_TYPE] -#define uintptr_type_node c_global_trees[CTI_UINTPTR_TYPE] - -#define truthvalue_type_node c_global_trees[CTI_TRUTHVALUE_TYPE] -#define truthvalue_true_node c_global_trees[CTI_TRUTHVALUE_TRUE] -#define truthvalue_false_node c_global_trees[CTI_TRUTHVALUE_FALSE] - -#define char_array_type_node c_global_trees[CTI_CHAR_ARRAY_TYPE] -#define char16_array_type_node c_global_trees[CTI_CHAR16_ARRAY_TYPE] -#define char32_array_type_node c_global_trees[CTI_CHAR32_ARRAY_TYPE] -#define wchar_array_type_node c_global_trees[CTI_WCHAR_ARRAY_TYPE] -#define int_array_type_node c_global_trees[CTI_INT_ARRAY_TYPE] -#define string_type_node c_global_trees[CTI_STRING_TYPE] -#define const_string_type_node c_global_trees[CTI_CONST_STRING_TYPE] - -#define default_function_type c_global_trees[CTI_DEFAULT_FUNCTION_TYPE] - -#define function_name_decl_node c_global_trees[CTI_FUNCTION_NAME_DECL] -#define pretty_function_name_decl_node c_global_trees[CTI_PRETTY_FUNCTION_NAME_DECL] -#define c99_function_name_decl_node c_global_trees[CTI_C99_FUNCTION_NAME_DECL] -#define saved_function_name_decls c_global_trees[CTI_SAVED_FUNCTION_NAME_DECLS] - -/* A node for `((void) 0)'. */ -#define void_zero_node c_global_trees[CTI_VOID_ZERO] - -/* The node for C++ `__null'. */ -#define null_node c_global_trees[CTI_NULL] - -extern GTY(()) tree c_global_trees[CTI_MAX]; - -/* In a RECORD_TYPE, a sorted array of the fields of the type, not a - tree for size reasons. */ -struct GTY((variable_size)) sorted_fields_type { - int len; - tree GTY((length ("%h.len"))) elts[1]; -}; - -/* Mark which labels are explicitly declared. - These may be shadowed, and may be referenced from nested functions. */ -#define C_DECLARED_LABEL_FLAG(label) TREE_LANG_FLAG_1 (label) - -typedef enum c_language_kind -{ - clk_c = 0, /* C90, C94 or C99 */ - clk_objc = 1, /* clk_c with ObjC features. */ - clk_cxx = 2, /* ANSI/ISO C++ */ - clk_objcxx = 3 /* clk_cxx with ObjC features. */ -} -c_language_kind; - -/* To test for a specific language use c_language, defined by each - front end. For "ObjC features" or "not C++" use the macros. */ -extern c_language_kind c_language; - -#define c_dialect_cxx() ((c_language & clk_cxx) != 0) -#define c_dialect_objc() ((c_language & clk_objc) != 0) - -/* The various name of operator that appears in error messages. */ -typedef enum ref_operator { - /* NULL */ - RO_NULL, - /* array indexing */ - RO_ARRAY_INDEXING, - /* unary * */ - RO_UNARY_STAR, - /* -> */ - RO_ARROW, - /* implicit conversion */ - RO_IMPLICIT_CONVERSION, - /* ->* */ - RO_ARROW_STAR -} ref_operator; - -/* Information about a statement tree. */ - -struct GTY(()) stmt_tree_s { - /* A stack of statement lists being collected. */ - vec<tree, va_gc> *x_cur_stmt_list; - - /* In C++, Nonzero if we should treat statements as full - expressions. In particular, this variable is non-zero if at the - end of a statement we should destroy any temporaries created - during that statement. Similarly, if, at the end of a block, we - should destroy any local variables in this block. Normally, this - variable is nonzero, since those are the normal semantics of - C++. - - This flag has no effect in C. */ - int stmts_are_full_exprs_p; -}; - -typedef struct stmt_tree_s *stmt_tree; - -/* Global state pertinent to the current function. Some C dialects - extend this structure with additional fields. */ - -struct GTY(()) c_language_function { - /* While we are parsing the function, this contains information - about the statement-tree that we are building. */ - struct stmt_tree_s x_stmt_tree; - - /* Vector of locally defined typedefs, for - -Wunused-local-typedefs. */ - vec<tree, va_gc> *local_typedefs; -}; - -#define stmt_list_stack (current_stmt_tree ()->x_cur_stmt_list) - -/* When building a statement-tree, this is the current statement list - being collected. */ -#define cur_stmt_list (stmt_list_stack->last ()) - -#define building_stmt_list_p() (stmt_list_stack && !stmt_list_stack->is_empty()) - -/* Language-specific hooks. */ - -/* If non-NULL, this function is called after a precompile header file - is loaded. */ -extern void (*lang_post_pch_load) (void); - -extern void push_file_scope (void); -extern void pop_file_scope (void); -extern stmt_tree current_stmt_tree (void); -extern tree push_stmt_list (void); -extern tree pop_stmt_list (tree); -extern tree add_stmt (tree); -extern void push_cleanup (tree, tree, bool); -extern tree pushdecl_top_level (tree); -extern tree pushdecl (tree); -extern tree build_modify_expr (location_t, tree, tree, enum tree_code, - location_t, tree, tree); -extern tree build_indirect_ref (location_t, tree, ref_operator); - -extern int field_decl_cmp (const void *, const void *); -extern void resort_sorted_fields (void *, void *, gt_pointer_operator, - void *); -extern bool has_c_linkage (const_tree decl); - -/* Switches common to the C front ends. */ - -/* Nonzero means don't output line number information. */ - -extern char flag_no_line_commands; - -/* Nonzero causes -E output not to be done, but directives such as - #define that have side effects are still obeyed. */ - -extern char flag_no_output; - -/* Nonzero means dump macros in some fashion; contains the 'D', 'M', - 'N' or 'U' of the command line switch. */ - -extern char flag_dump_macros; - -/* Nonzero means pass #include lines through to the output. */ - -extern char flag_dump_includes; - -/* Nonzero means process PCH files while preprocessing. */ - -extern bool flag_pch_preprocess; - -/* The file name to which we should write a precompiled header, or - NULL if no header will be written in this compile. */ - -extern const char *pch_file; - -/* Nonzero if an ISO standard was selected. It rejects macros in the - user's namespace. */ - -extern int flag_iso; - -/* C/ObjC language option variables. */ - - -/* Nonzero means allow type mismatches in conditional expressions; - just make their values `void'. */ - -extern int flag_cond_mismatch; - -/* Nonzero means enable C89 Amendment 1 features. */ - -extern int flag_isoc94; - -/* Nonzero means use the ISO C99 (or C11) dialect of C. */ - -extern int flag_isoc99; - -/* Nonzero means use the ISO C11 dialect of C. */ - -extern int flag_isoc11; - -/* Nonzero means that we have builtin functions, and main is an int. */ - -extern int flag_hosted; - -/* ObjC language option variables. */ - - -/* Tells the compiler that this is a special run. Do not perform any - compiling, instead we are to test some platform dependent features - and output a C header file with appropriate definitions. */ - -extern int print_struct_values; - -/* Tells the compiler what is the constant string class for ObjC. */ - -extern const char *constant_string_class_name; - - -/* C++ language option variables. */ - - -/* Nonzero means generate separate instantiation control files and - juggle them at link time. */ - -extern int flag_use_repository; - -/* The supported C++ dialects. */ - -enum cxx_dialect { - /* C++98 with TC1 */ - cxx98, - cxx03 = cxx98, - /* C++11 */ - cxx0x, - cxx11 = cxx0x, - /* C++1y (C++17?) */ - cxx1y -}; - -/* The C++ dialect being used. C++98 is the default. */ -extern enum cxx_dialect cxx_dialect; - -/* Maximum template instantiation depth. This limit is rather - arbitrary, but it exists to limit the time it takes to notice - excessively recursive template instantiations. */ - -extern int max_tinst_depth; - -/* Nonzero means that we should not issue warnings about problems that - occur when the code is executed, because the code being processed - is not expected to be executed. This is set during parsing. This - is used for cases like sizeof() and "0 ? a : b". This is a count, - not a bool, because unexecuted expressions can nest. */ - -extern int c_inhibit_evaluation_warnings; - -/* Whether lexing has been completed, so subsequent preprocessor - errors should use the compiler's input_location. */ - -extern bool done_lexing; - -/* C types are partitioned into three subsets: object, function, and - incomplete types. */ -#define C_TYPE_OBJECT_P(type) \ - (TREE_CODE (type) != FUNCTION_TYPE && TYPE_SIZE (type)) - -#define C_TYPE_INCOMPLETE_P(type) \ - (TREE_CODE (type) != FUNCTION_TYPE && TYPE_SIZE (type) == 0) - -#define C_TYPE_FUNCTION_P(type) \ - (TREE_CODE (type) == FUNCTION_TYPE) - -/* For convenience we define a single macro to identify the class of - object or incomplete types. */ -#define C_TYPE_OBJECT_OR_INCOMPLETE_P(type) \ - (!C_TYPE_FUNCTION_P (type)) - -struct visibility_flags -{ - unsigned inpragma : 1; /* True when in #pragma GCC visibility. */ - unsigned inlines_hidden : 1; /* True when -finlineshidden in effect. */ -}; - -/* Global visibility options. */ -extern struct visibility_flags visibility_options; - -/* Attribute table common to the C front ends. */ -extern const struct attribute_spec c_common_attribute_table[]; -extern const struct attribute_spec c_common_format_attribute_table[]; - -/* Pointer to function to lazily generate the VAR_DECL for __FUNCTION__ etc. - ID is the identifier to use, NAME is the string. - TYPE_DEP indicates whether it depends on type of the function or not - (i.e. __PRETTY_FUNCTION__). */ - -extern tree (*make_fname_decl) (location_t, tree, int); - -/* In c-decl.c and cp/tree.c. FIXME. */ -extern void c_register_addr_space (const char *str, addr_space_t as); - -/* In c-common.c. */ -extern bool in_late_binary_op; -extern const char *c_addr_space_name (addr_space_t as); -extern tree identifier_global_value (tree); -extern tree c_linkage_bindings (tree); -extern void record_builtin_type (enum rid, const char *, tree); -extern tree build_void_list_node (void); -extern void start_fname_decls (void); -extern void finish_fname_decls (void); -extern const char *fname_as_string (int); -extern tree fname_decl (location_t, unsigned, tree); - -extern int check_user_alignment (const_tree, bool); -extern void check_function_arguments (const_tree, int, tree *); -extern void check_function_arguments_recurse (void (*) - (void *, tree, - unsigned HOST_WIDE_INT), - void *, tree, - unsigned HOST_WIDE_INT); -extern bool check_builtin_function_arguments (tree, int, tree *); -extern void check_function_format (tree, int, tree *); -extern tree handle_format_attribute (tree *, tree, tree, int, bool *); -extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *); -extern bool attribute_takes_identifier_p (const_tree); -extern bool c_common_handle_option (size_t, const char *, int, int, location_t, - const struct cl_option_handlers *); -extern bool default_handle_c_option (size_t, const char *, int); -extern tree c_common_type_for_mode (enum machine_mode, int); -extern tree c_common_type_for_size (unsigned int, int); -extern tree c_common_fixed_point_type_for_size (unsigned int, unsigned int, - int, int); -extern tree c_common_unsigned_type (tree); -extern tree c_common_signed_type (tree); -extern tree c_common_signed_or_unsigned_type (int, tree); -extern void c_common_init_ts (void); -extern tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT, int); -extern bool unsafe_conversion_p (tree, tree, bool); -extern bool decl_with_nonnull_addr_p (const_tree); -extern tree c_fully_fold (tree, bool, bool *); -extern tree decl_constant_value_for_optimization (tree); -extern tree c_wrap_maybe_const (tree, bool); -extern tree c_save_expr (tree); -extern tree c_common_truthvalue_conversion (location_t, tree); -extern void c_apply_type_quals_to_decl (int, tree); -extern tree c_sizeof_or_alignof_type (location_t, tree, bool, int); -extern tree c_alignof_expr (location_t, tree); -/* Print an error message for invalid operands to arith operation CODE. - NOP_EXPR is used as a special case (see truthvalue_conversion). */ -extern void binary_op_error (location_t, enum tree_code, tree, tree); -extern tree fix_string_type (tree); -extern void constant_expression_warning (tree); -extern void constant_expression_error (tree); -extern bool strict_aliasing_warning (tree, tree, tree); -extern void sizeof_pointer_memaccess_warning (location_t *, tree, - vec<tree, va_gc> *, tree *, - bool (*) (tree, tree)); -extern void warnings_for_convert_and_check (tree, tree, tree); -extern tree convert_and_check (tree, tree); -extern void overflow_warning (location_t, tree); -extern bool warn_if_unused_value (const_tree, location_t); -extern void warn_logical_operator (location_t, enum tree_code, tree, - enum tree_code, tree, enum tree_code, tree); -extern void check_main_parameter_types (tree decl); -extern bool c_determine_visibility (tree); -extern bool same_scalar_type_ignoring_signedness (tree, tree); -extern void mark_valid_location_for_stdc_pragma (bool); -extern bool valid_location_for_stdc_pragma_p (void); -extern void set_float_const_decimal64 (void); -extern void clear_float_const_decimal64 (void); -extern bool float_const_decimal64_p (void); - -extern bool keyword_begins_type_specifier (enum rid); -extern bool keyword_is_storage_class_specifier (enum rid); -extern bool keyword_is_type_qualifier (enum rid); -extern bool keyword_is_decl_specifier (enum rid); -extern bool cxx_fundamental_alignment_p (unsigned); - -#define c_sizeof(LOC, T) c_sizeof_or_alignof_type (LOC, T, true, 1) -#define c_alignof(LOC, T) c_sizeof_or_alignof_type (LOC, T, false, 1) - -/* Subroutine of build_binary_op, used for certain operations. */ -extern tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise); - -/* Subroutine of build_binary_op, used for comparison operations. - See if the operands have both been converted from subword integer types - and, if so, perhaps change them both back to their original type. */ -extern tree shorten_compare (tree *, tree *, tree *, enum tree_code *); - -extern tree pointer_int_sum (location_t, enum tree_code, tree, tree); - -/* Add qualifiers to a type, in the fashion for C. */ -extern tree c_build_qualified_type (tree, int); - -/* Build tree nodes and builtin functions common to both C and C++ language - frontends. */ -extern void c_common_nodes_and_builtins (void); - -extern void disable_builtin_function (const char *); - -extern void set_compound_literal_name (tree decl); - -extern tree build_va_arg (location_t, tree, tree); - -extern const unsigned int c_family_lang_mask; -extern unsigned int c_common_option_lang_mask (void); -extern void c_common_initialize_diagnostics (diagnostic_context *); -extern bool c_common_complain_wrong_lang_p (const struct cl_option *); -extern void c_common_init_options_struct (struct gcc_options *); -extern void c_common_init_options (unsigned int, struct cl_decoded_option *); -extern bool c_common_post_options (const char **); -extern bool c_common_init (void); -extern void c_common_finish (void); -extern void c_common_parse_file (void); -extern alias_set_type c_common_get_alias_set (tree); -extern void c_register_builtin_type (tree, const char*); -extern bool c_promoting_integer_type_p (const_tree); -extern int self_promoting_args_p (const_tree); -extern tree strip_pointer_operator (tree); -extern tree strip_pointer_or_array_types (tree); -extern HOST_WIDE_INT c_common_to_target_charset (HOST_WIDE_INT); - -/* This is the basic parsing function. */ -extern void c_parse_file (void); - -extern void warn_for_omitted_condop (location_t, tree); - -/* These macros provide convenient access to the various _STMT nodes. */ - -/* Nonzero if a given STATEMENT_LIST represents the outermost binding - if a statement expression. */ -#define STATEMENT_LIST_STMT_EXPR(NODE) \ - TREE_LANG_FLAG_1 (STATEMENT_LIST_CHECK (NODE)) - -/* Nonzero if a label has been added to the statement list. */ -#define STATEMENT_LIST_HAS_LABEL(NODE) \ - TREE_LANG_FLAG_3 (STATEMENT_LIST_CHECK (NODE)) - -/* C_MAYBE_CONST_EXPR accessors. */ -#define C_MAYBE_CONST_EXPR_PRE(NODE) \ - TREE_OPERAND (C_MAYBE_CONST_EXPR_CHECK (NODE), 0) -#define C_MAYBE_CONST_EXPR_EXPR(NODE) \ - TREE_OPERAND (C_MAYBE_CONST_EXPR_CHECK (NODE), 1) -#define C_MAYBE_CONST_EXPR_INT_OPERANDS(NODE) \ - TREE_LANG_FLAG_0 (C_MAYBE_CONST_EXPR_CHECK (NODE)) -#define C_MAYBE_CONST_EXPR_NON_CONST(NODE) \ - TREE_LANG_FLAG_1 (C_MAYBE_CONST_EXPR_CHECK (NODE)) -#define EXPR_INT_CONST_OPERANDS(EXPR) \ - (INTEGRAL_TYPE_P (TREE_TYPE (EXPR)) \ - && (TREE_CODE (EXPR) == INTEGER_CST \ - || (TREE_CODE (EXPR) == C_MAYBE_CONST_EXPR \ - && C_MAYBE_CONST_EXPR_INT_OPERANDS (EXPR)))) - -/* In a FIELD_DECL, nonzero if the decl was originally a bitfield. */ -#define DECL_C_BIT_FIELD(NODE) \ - (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) == 1) -#define SET_DECL_C_BIT_FIELD(NODE) \ - (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 1) -#define CLEAR_DECL_C_BIT_FIELD(NODE) \ - (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 0) - -extern tree do_case (location_t, tree, tree); -extern tree build_stmt (location_t, enum tree_code, ...); -extern tree build_real_imag_expr (location_t, enum tree_code, tree); - -/* These functions must be defined by each front-end which implements - a variant of the C language. They are used in c-common.c. */ - -extern tree build_unary_op (location_t, enum tree_code, tree, int); -extern tree build_binary_op (location_t, enum tree_code, tree, tree, int); -extern tree perform_integral_promotions (tree); - -/* These functions must be defined by each front-end which implements - a variant of the C language. They are used by port files. */ - -extern tree default_conversion (tree); - -/* Given two integer or real types, return the type for their sum. - Given two compatible ANSI C types, returns the merged type. */ - -extern tree common_type (tree, tree); - -extern tree decl_constant_value (tree); - -/* Handle increment and decrement of boolean types. */ -extern tree boolean_increment (enum tree_code, tree); - -extern int case_compare (splay_tree_key, splay_tree_key); - -extern tree c_add_case_label (location_t, splay_tree, tree, tree, tree, tree); - -extern void c_do_switch_warnings (splay_tree, location_t, tree, tree); - -extern tree build_function_call (location_t, tree, tree); - -extern tree build_function_call_vec (location_t, tree, vec<tree, va_gc> *, - vec<tree, va_gc> *); - -extern tree resolve_overloaded_builtin (location_t, tree, vec<tree, va_gc> *); - -extern tree finish_label_address_expr (tree, location_t); - -/* Same function prototype, but the C and C++ front ends have - different implementations. Used in c-common.c. */ -extern tree lookup_label (tree); -extern tree lookup_name (tree); -extern bool lvalue_p (const_tree); - -extern bool vector_targets_convertible_p (const_tree t1, const_tree t2); -extern bool vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note); -extern tree c_build_vec_perm_expr (location_t, tree, tree, tree); - -extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *); - -extern void init_c_lex (void); - -extern void c_cpp_builtins (cpp_reader *); -extern void c_cpp_builtins_optimize_pragma (cpp_reader *, tree, tree); -extern bool c_cpp_error (cpp_reader *, int, int, location_t, unsigned int, - const char *, va_list *) - ATTRIBUTE_GCC_DIAG(6,0); - -extern bool parse_optimize_options (tree, bool); - -/* Positive if an implicit `extern "C"' scope has just been entered; - negative if such a scope has just been exited. */ -extern GTY(()) int pending_lang_change; - -/* Information recorded about each file examined during compilation. */ - -struct c_fileinfo -{ - int time; /* Time spent in the file. */ - - /* Flags used only by C++. - INTERFACE_ONLY nonzero means that we are in an "interface" section - of the compiler. INTERFACE_UNKNOWN nonzero means we cannot trust - the value of INTERFACE_ONLY. If INTERFACE_UNKNOWN is zero and - INTERFACE_ONLY is zero, it means that we are responsible for - exporting definitions that others might need. */ - short interface_only; - short interface_unknown; -}; - -struct c_fileinfo *get_fileinfo (const char *); -extern void dump_time_statistics (void); - -extern bool c_dump_tree (void *, tree); - -extern void verify_sequence_points (tree); - -extern tree fold_offsetof_1 (tree); -extern tree fold_offsetof (tree); - -/* Places where an lvalue, or modifiable lvalue, may be required. - Used to select diagnostic messages in lvalue_error and - readonly_error. */ -enum lvalue_use { - lv_assign, - lv_increment, - lv_decrement, - lv_addressof, - lv_asm -}; - -extern void readonly_error (tree, enum lvalue_use); -extern void lvalue_error (location_t, enum lvalue_use); -extern void invalid_indirection_error (location_t, tree, ref_operator); - -extern int complete_array_type (tree *, tree, bool); - -extern tree builtin_type_for_size (int, bool); - -extern void c_common_mark_addressable_vec (tree); - -extern void warn_array_subscript_with_type_char (tree); -extern void warn_about_parentheses (location_t, - enum tree_code, - enum tree_code, tree, - enum tree_code, tree); -extern void warn_for_unused_label (tree label); -extern void warn_for_div_by_zero (location_t, tree divisor); -extern void warn_for_sign_compare (location_t, - tree orig_op0, tree orig_op1, - tree op0, tree op1, - tree result_type, - enum tree_code resultcode); -extern void do_warn_double_promotion (tree, tree, tree, const char *, - location_t); -extern void set_underlying_type (tree); -extern void record_locally_defined_typedef (tree); -extern void maybe_record_typedef_use (tree); -extern void maybe_warn_unused_local_typedefs (void); -extern vec<tree, va_gc> *make_tree_vector (void); -extern void release_tree_vector (vec<tree, va_gc> *); -extern vec<tree, va_gc> *make_tree_vector_single (tree); -extern vec<tree, va_gc> *make_tree_vector_from_list (tree); -extern vec<tree, va_gc> *make_tree_vector_copy (const vec<tree, va_gc> *); - -/* In c-gimplify.c */ -extern void c_genericize (tree); -extern int c_gimplify_expr (tree *, gimple_seq *, gimple_seq *); -extern tree c_build_bind_expr (location_t, tree, tree); - -/* In c-pch.c */ -extern void pch_init (void); -extern void pch_cpp_save_state (void); -extern int c_common_valid_pch (cpp_reader *pfile, const char *name, int fd); -extern void c_common_read_pch (cpp_reader *pfile, const char *name, int fd, - const char *orig); -extern void c_common_write_pch (void); -extern void c_common_no_more_pch (void); -extern void c_common_pch_pragma (cpp_reader *pfile, const char *); - -/* In *-checksum.c */ -extern const unsigned char executable_checksum[16]; - -/* In c-cppbuiltin.c */ -extern void builtin_define_std (const char *macro); -extern void builtin_define_with_value (const char *, const char *, int); -extern void c_stddef_cpp_builtins (void); -extern void fe_file_change (const struct line_map *); -extern void c_parse_error (const char *, enum cpp_ttype, tree, unsigned char); - -/* In c-ppoutput.c */ -extern void init_pp_output (FILE *); -extern void preprocess_file (cpp_reader *); -extern void pp_file_change (const struct line_map *); -extern void pp_dir_change (cpp_reader *, const char *); -extern bool check_missing_format_attribute (tree, tree); - -/* In c-omp.c */ -extern tree c_finish_omp_master (location_t, tree); -extern tree c_finish_omp_critical (location_t, tree, tree); -extern tree c_finish_omp_ordered (location_t, tree); -extern void c_finish_omp_barrier (location_t); -extern tree c_finish_omp_atomic (location_t, enum tree_code, enum tree_code, - tree, tree, tree, tree, tree); -extern void c_finish_omp_flush (location_t); -extern void c_finish_omp_taskwait (location_t); -extern void c_finish_omp_taskyield (location_t); -extern tree c_finish_omp_for (location_t, tree, tree, tree, tree, tree, tree); -extern void c_split_parallel_clauses (location_t, tree, tree *, tree *); -extern enum omp_clause_default_kind c_omp_predetermined_sharing (tree); - -/* Not in c-omp.c; provided by the front end. */ -extern bool c_omp_sharing_predetermined (tree); -extern tree c_omp_remap_decl (tree, bool); -extern void record_types_used_by_current_var_decl (tree); - -/* Return next tree in the chain for chain_next walking of tree nodes. */ -static inline tree -c_tree_chain_next (tree t) -{ - /* TREE_CHAIN of a type is TYPE_STUB_DECL, which is different - kind of object, never a long chain of nodes. Prefer - TYPE_NEXT_VARIANT for types. */ - if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPE_COMMON)) - return TYPE_NEXT_VARIANT (t); - /* Otherwise, if there is TREE_CHAIN, return it. */ - if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_COMMON)) - return TREE_CHAIN (t); - return NULL; -} - -/* Mask used by tm_stmt_attr. */ -#define TM_STMT_ATTR_OUTER 2 -#define TM_STMT_ATTR_ATOMIC 4 -#define TM_STMT_ATTR_RELAXED 8 - -extern int parse_tm_stmt_attr (tree, int); - -/* Mask used by tm_attr_to_mask and tm_mask_to_attr. Note that these - are ordered specifically such that more restrictive attributes are - at lower bit positions. This fact is known by the C++ tm attribute - inheritance code such that least bit extraction (mask & -mask) results - in the most restrictive attribute. */ -#define TM_ATTR_SAFE 1 -#define TM_ATTR_CALLABLE 2 -#define TM_ATTR_PURE 4 -#define TM_ATTR_IRREVOCABLE 8 -#define TM_ATTR_MAY_CANCEL_OUTER 16 - -extern int tm_attr_to_mask (tree); -extern tree tm_mask_to_attr (int); -extern tree find_tm_attribute (tree); - -/* A suffix-identifier value doublet that represents user-defined literals - for C++-0x. */ -enum overflow_type { - OT_UNDERFLOW = -1, - OT_NONE, - OT_OVERFLOW -}; - -struct GTY(()) tree_userdef_literal { - struct tree_base base; - tree suffix_id; - tree value; - tree num_string; - enum overflow_type overflow; -}; - -#define USERDEF_LITERAL_SUFFIX_ID(NODE) \ - (((struct tree_userdef_literal *)USERDEF_LITERAL_CHECK (NODE))->suffix_id) - -#define USERDEF_LITERAL_VALUE(NODE) \ - (((struct tree_userdef_literal *)USERDEF_LITERAL_CHECK (NODE))->value) - -#define USERDEF_LITERAL_OVERFLOW(NODE) \ - (((struct tree_userdef_literal *)USERDEF_LITERAL_CHECK (NODE))->overflow) - -#define USERDEF_LITERAL_NUM_STRING(NODE) \ - (((struct tree_userdef_literal *)USERDEF_LITERAL_CHECK (NODE))->num_string) - -#define USERDEF_LITERAL_TYPE(NODE) \ - (TREE_TYPE (USERDEF_LITERAL_VALUE (NODE))) - -extern tree build_userdef_literal (tree suffix_id, tree value, - enum overflow_type overflow, - tree num_string); - -extern void convert_vector_to_pointer_for_subscript (location_t, tree*, tree); - -/* Possibe cases of scalar_to_vector conversion. */ -enum stv_conv { - stv_error, /* Error occured. */ - stv_nothing, /* Nothing happened. */ - stv_firstarg, /* First argument must be expanded. */ - stv_secondarg /* Second argument must be expanded. */ -}; - -extern enum stv_conv scalar_to_vector (location_t loc, enum tree_code code, - tree op0, tree op1, bool); - -#endif /* ! GCC_C_COMMON_H */ diff --git a/gcc-4.8.1/gcc/c-family/c-cppbuiltin.c b/gcc-4.8.1/gcc/c-family/c-cppbuiltin.c deleted file mode 100644 index 3e210d90e..000000000 --- a/gcc-4.8.1/gcc/c-family/c-cppbuiltin.c +++ /dev/null @@ -1,1249 +0,0 @@ -/* Define builtin-in macros for the C family front ends. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "tree.h" -#include "version.h" -#include "flags.h" -#include "c-common.h" -#include "c-pragma.h" -#include "output.h" /* For user_label_prefix. */ -#include "debug.h" /* For dwarf2out_do_cfi_asm. */ -#include "tm_p.h" /* For TARGET_CPU_CPP_BUILTINS & friends. */ -#include "target.h" -#include "common/common-target.h" -#include "cpp-id-data.h" -#include "cppbuiltin.h" - -#ifndef TARGET_OS_CPP_BUILTINS -# define TARGET_OS_CPP_BUILTINS() -#endif - -#ifndef TARGET_OBJFMT_CPP_BUILTINS -# define TARGET_OBJFMT_CPP_BUILTINS() -#endif - -#ifndef REGISTER_PREFIX -#define REGISTER_PREFIX "" -#endif - -/* Non-static as some targets don't use it. */ -void builtin_define_std (const char *) ATTRIBUTE_UNUSED; -static void builtin_define_with_int_value (const char *, HOST_WIDE_INT); -static void builtin_define_with_hex_fp_value (const char *, tree, - int, const char *, - const char *, - const char *); -static void builtin_define_stdint_macros (void); -static void builtin_define_constants (const char *, tree); -static void builtin_define_type_max (const char *, tree); -static void builtin_define_type_minmax (const char *, const char *, tree); -static void builtin_define_type_sizeof (const char *, tree); -static void builtin_define_float_constants (const char *, - const char *, - const char *, - const char *, - tree); - -/* Return true if MODE provides a fast multiply/add (FMA) builtin function. - Originally this function used the fma optab, but that doesn't work with - -save-temps, so just rely on the HAVE_fma macros for the standard floating - point types. */ - -static bool -mode_has_fma (enum machine_mode mode) -{ - switch (mode) - { -#ifdef HAVE_fmasf4 - case SFmode: - return !!HAVE_fmasf4; -#endif - -#ifdef HAVE_fmadf4 - case DFmode: - return !!HAVE_fmadf4; -#endif - -#ifdef HAVE_fmaxf4 - case XFmode: - return !!HAVE_fmaxf4; -#endif - -#ifdef HAVE_fmatf4 - case TFmode: - return !!HAVE_fmatf4; -#endif - - default: - break; - } - - return false; -} - -/* Define NAME with value TYPE size_unit. */ -static void -builtin_define_type_sizeof (const char *name, tree type) -{ - builtin_define_with_int_value (name, - tree_low_cst (TYPE_SIZE_UNIT (type), 1)); -} - -/* Define the float.h constants for TYPE using NAME_PREFIX, FP_SUFFIX, - and FP_CAST. */ -static void -builtin_define_float_constants (const char *name_prefix, - const char *fp_suffix, - const char *fp_cast, - const char *fma_suffix, - tree type) -{ - /* Used to convert radix-based values to base 10 values in several cases. - - In the max_exp -> max_10_exp conversion for 128-bit IEEE, we need at - least 6 significant digits for correct results. Using the fraction - formed by (log(2)*1e6)/(log(10)*1e6) overflows a 32-bit integer as an - intermediate; perhaps someone can find a better approximation, in the - mean time, I suspect using doubles won't harm the bootstrap here. */ - - const double log10_2 = .30102999566398119521; - double log10_b; - const struct real_format *fmt; - const struct real_format *ldfmt; - - char name[64], buf[128]; - int dig, min_10_exp, max_10_exp; - int decimal_dig; - int type_decimal_dig; - - fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); - gcc_assert (fmt->b != 10); - ldfmt = REAL_MODE_FORMAT (TYPE_MODE (long_double_type_node)); - gcc_assert (ldfmt->b != 10); - - /* The radix of the exponent representation. */ - if (type == float_type_node) - builtin_define_with_int_value ("__FLT_RADIX__", fmt->b); - log10_b = log10_2; - - /* The number of radix digits, p, in the floating-point significand. */ - sprintf (name, "__%s_MANT_DIG__", name_prefix); - builtin_define_with_int_value (name, fmt->p); - - /* The number of decimal digits, q, such that any floating-point number - with q decimal digits can be rounded into a floating-point number with - p radix b digits and back again without change to the q decimal digits, - - p log10 b if b is a power of 10 - floor((p - 1) log10 b) otherwise - */ - dig = (fmt->p - 1) * log10_b; - sprintf (name, "__%s_DIG__", name_prefix); - builtin_define_with_int_value (name, dig); - - /* The minimum negative int x such that b**(x-1) is a normalized float. */ - sprintf (name, "__%s_MIN_EXP__", name_prefix); - sprintf (buf, "(%d)", fmt->emin); - builtin_define_with_value (name, buf, 0); - - /* The minimum negative int x such that 10**x is a normalized float, - - ceil (log10 (b ** (emin - 1))) - = ceil (log10 (b) * (emin - 1)) - - Recall that emin is negative, so the integer truncation calculates - the ceiling, not the floor, in this case. */ - min_10_exp = (fmt->emin - 1) * log10_b; - sprintf (name, "__%s_MIN_10_EXP__", name_prefix); - sprintf (buf, "(%d)", min_10_exp); - builtin_define_with_value (name, buf, 0); - - /* The maximum int x such that b**(x-1) is a representable float. */ - sprintf (name, "__%s_MAX_EXP__", name_prefix); - builtin_define_with_int_value (name, fmt->emax); - - /* The maximum int x such that 10**x is in the range of representable - finite floating-point numbers, - - floor (log10((1 - b**-p) * b**emax)) - = floor (log10(1 - b**-p) + log10(b**emax)) - = floor (log10(1 - b**-p) + log10(b)*emax) - - The safest thing to do here is to just compute this number. But since - we don't link cc1 with libm, we cannot. We could implement log10 here - a series expansion, but that seems too much effort because: - - Note that the first term, for all extant p, is a number exceedingly close - to zero, but slightly negative. Note that the second term is an integer - scaling an irrational number, and that because of the floor we are only - interested in its integral portion. - - In order for the first term to have any effect on the integral portion - of the second term, the second term has to be exceedingly close to an - integer itself (e.g. 123.000000000001 or something). Getting a result - that close to an integer requires that the irrational multiplicand have - a long series of zeros in its expansion, which doesn't occur in the - first 20 digits or so of log10(b). - - Hand-waving aside, crunching all of the sets of constants above by hand - does not yield a case for which the first term is significant, which - in the end is all that matters. */ - max_10_exp = fmt->emax * log10_b; - sprintf (name, "__%s_MAX_10_EXP__", name_prefix); - builtin_define_with_int_value (name, max_10_exp); - - /* The number of decimal digits, n, such that any floating-point number - can be rounded to n decimal digits and back again without change to - the value. - - p * log10(b) if b is a power of 10 - ceil(1 + p * log10(b)) otherwise - - The only macro we care about is this number for the widest supported - floating type, but we want this value for rendering constants below. */ - { - double d_decimal_dig - = 1 + (fmt->p < ldfmt->p ? ldfmt->p : fmt->p) * log10_b; - decimal_dig = d_decimal_dig; - if (decimal_dig < d_decimal_dig) - decimal_dig++; - } - /* Similar, for this type rather than long double. */ - { - double type_d_decimal_dig = 1 + fmt->p * log10_b; - type_decimal_dig = type_d_decimal_dig; - if (type_decimal_dig < type_d_decimal_dig) - type_decimal_dig++; - } - if (type == long_double_type_node) - builtin_define_with_int_value ("__DECIMAL_DIG__", decimal_dig); - else - { - sprintf (name, "__%s_DECIMAL_DIG__", name_prefix); - builtin_define_with_int_value (name, type_decimal_dig); - } - - /* Since, for the supported formats, B is always a power of 2, we - construct the following numbers directly as a hexadecimal - constants. */ - get_max_float (fmt, buf, sizeof (buf)); - - sprintf (name, "__%s_MAX__", name_prefix); - builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast); - - /* The minimum normalized positive floating-point number, - b**(emin-1). */ - sprintf (name, "__%s_MIN__", name_prefix); - sprintf (buf, "0x1p%d", fmt->emin - 1); - builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast); - - /* The difference between 1 and the least value greater than 1 that is - representable in the given floating point type, b**(1-p). */ - sprintf (name, "__%s_EPSILON__", name_prefix); - if (fmt->pnan < fmt->p) - /* This is an IBM extended double format, so 1.0 + any double is - representable precisely. */ - sprintf (buf, "0x1p%d", fmt->emin - fmt->p); - else - sprintf (buf, "0x1p%d", 1 - fmt->p); - builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast); - - /* For C++ std::numeric_limits<T>::denorm_min. The minimum denormalized - positive floating-point number, b**(emin-p). Zero for formats that - don't support denormals. */ - sprintf (name, "__%s_DENORM_MIN__", name_prefix); - if (fmt->has_denorm) - { - sprintf (buf, "0x1p%d", fmt->emin - fmt->p); - builtin_define_with_hex_fp_value (name, type, decimal_dig, - buf, fp_suffix, fp_cast); - } - else - { - sprintf (buf, "0.0%s", fp_suffix); - builtin_define_with_value (name, buf, 0); - } - - sprintf (name, "__%s_HAS_DENORM__", name_prefix); - builtin_define_with_value (name, fmt->has_denorm ? "1" : "0", 0); - - /* For C++ std::numeric_limits<T>::has_infinity. */ - sprintf (name, "__%s_HAS_INFINITY__", name_prefix); - builtin_define_with_int_value (name, - MODE_HAS_INFINITIES (TYPE_MODE (type))); - /* For C++ std::numeric_limits<T>::has_quiet_NaN. We do not have a - predicate to distinguish a target that has both quiet and - signalling NaNs from a target that has only quiet NaNs or only - signalling NaNs, so we assume that a target that has any kind of - NaN has quiet NaNs. */ - sprintf (name, "__%s_HAS_QUIET_NAN__", name_prefix); - builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type))); - - /* Note whether we have fast FMA. */ - if (mode_has_fma (TYPE_MODE (type))) - { - sprintf (name, "__FP_FAST_FMA%s", fma_suffix); - builtin_define_with_int_value (name, 1); - } -} - -/* Define __DECx__ constants for TYPE using NAME_PREFIX and SUFFIX. */ -static void -builtin_define_decimal_float_constants (const char *name_prefix, - const char *suffix, - tree type) -{ - const struct real_format *fmt; - char name[64], buf[128], *p; - int digits; - - fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); - - /* The number of radix digits, p, in the significand. */ - sprintf (name, "__%s_MANT_DIG__", name_prefix); - builtin_define_with_int_value (name, fmt->p); - - /* The minimum negative int x such that b**(x-1) is a normalized float. */ - sprintf (name, "__%s_MIN_EXP__", name_prefix); - sprintf (buf, "(%d)", fmt->emin); - builtin_define_with_value (name, buf, 0); - - /* The maximum int x such that b**(x-1) is a representable float. */ - sprintf (name, "__%s_MAX_EXP__", name_prefix); - builtin_define_with_int_value (name, fmt->emax); - - /* Compute the minimum representable value. */ - sprintf (name, "__%s_MIN__", name_prefix); - sprintf (buf, "1E%d%s", fmt->emin - 1, suffix); - builtin_define_with_value (name, buf, 0); - - /* Compute the maximum representable value. */ - sprintf (name, "__%s_MAX__", name_prefix); - p = buf; - for (digits = fmt->p; digits; digits--) - { - *p++ = '9'; - if (digits == fmt->p) - *p++ = '.'; - } - *p = 0; - /* fmt->p plus 1, to account for the decimal point and fmt->emax - minus 1 because the digits are nines, not 1.0. */ - sprintf (&buf[fmt->p + 1], "E%d%s", fmt->emax - 1, suffix); - builtin_define_with_value (name, buf, 0); - - /* Compute epsilon (the difference between 1 and least value greater - than 1 representable). */ - sprintf (name, "__%s_EPSILON__", name_prefix); - sprintf (buf, "1E-%d%s", fmt->p - 1, suffix); - builtin_define_with_value (name, buf, 0); - - /* Minimum subnormal positive decimal value. */ - sprintf (name, "__%s_SUBNORMAL_MIN__", name_prefix); - p = buf; - for (digits = fmt->p; digits > 1; digits--) - { - *p++ = '0'; - if (digits == fmt->p) - *p++ = '.'; - } - *p = 0; - sprintf (&buf[fmt->p], "1E%d%s", fmt->emin - 1, suffix); - builtin_define_with_value (name, buf, 0); -} - -/* Define fixed-point constants for TYPE using NAME_PREFIX and SUFFIX. */ - -static void -builtin_define_fixed_point_constants (const char *name_prefix, - const char *suffix, - tree type) -{ - char name[64], buf[256], *new_buf; - int i, mod; - - sprintf (name, "__%s_FBIT__", name_prefix); - builtin_define_with_int_value (name, TYPE_FBIT (type)); - - sprintf (name, "__%s_IBIT__", name_prefix); - builtin_define_with_int_value (name, TYPE_IBIT (type)); - - /* If there is no suffix, defines are for fixed-point modes. - We just return. */ - if (strcmp (suffix, "") == 0) - return; - - if (TYPE_UNSIGNED (type)) - { - sprintf (name, "__%s_MIN__", name_prefix); - sprintf (buf, "0.0%s", suffix); - builtin_define_with_value (name, buf, 0); - } - else - { - sprintf (name, "__%s_MIN__", name_prefix); - if (ALL_ACCUM_MODE_P (TYPE_MODE (type))) - sprintf (buf, "(-0X1P%d%s-0X1P%d%s)", TYPE_IBIT (type) - 1, suffix, - TYPE_IBIT (type) - 1, suffix); - else - sprintf (buf, "(-0.5%s-0.5%s)", suffix, suffix); - builtin_define_with_value (name, buf, 0); - } - - sprintf (name, "__%s_MAX__", name_prefix); - sprintf (buf, "0X"); - new_buf = buf + 2; - mod = (TYPE_FBIT (type) + TYPE_IBIT (type)) % 4; - if (mod) - sprintf (new_buf++, "%x", (1 << mod) - 1); - for (i = 0; i < (TYPE_FBIT (type) + TYPE_IBIT (type)) / 4; i++) - sprintf (new_buf++, "F"); - sprintf (new_buf, "P-%d%s", TYPE_FBIT (type), suffix); - builtin_define_with_value (name, buf, 0); - - sprintf (name, "__%s_EPSILON__", name_prefix); - sprintf (buf, "0x1P-%d%s", TYPE_FBIT (type), suffix); - builtin_define_with_value (name, buf, 0); -} - -/* Define macros used by <stdint.h>. */ -static void -builtin_define_stdint_macros (void) -{ - builtin_define_type_max ("__INTMAX_MAX__", intmax_type_node); - builtin_define_constants ("__INTMAX_C", intmax_type_node); - builtin_define_type_max ("__UINTMAX_MAX__", uintmax_type_node); - builtin_define_constants ("__UINTMAX_C", uintmax_type_node); - if (sig_atomic_type_node) - builtin_define_type_minmax ("__SIG_ATOMIC_MIN__", "__SIG_ATOMIC_MAX__", - sig_atomic_type_node); - if (int8_type_node) - builtin_define_type_max ("__INT8_MAX__", int8_type_node); - if (int16_type_node) - builtin_define_type_max ("__INT16_MAX__", int16_type_node); - if (int32_type_node) - builtin_define_type_max ("__INT32_MAX__", int32_type_node); - if (int64_type_node) - builtin_define_type_max ("__INT64_MAX__", int64_type_node); - if (uint8_type_node) - builtin_define_type_max ("__UINT8_MAX__", uint8_type_node); - if (c_uint16_type_node) - builtin_define_type_max ("__UINT16_MAX__", c_uint16_type_node); - if (c_uint32_type_node) - builtin_define_type_max ("__UINT32_MAX__", c_uint32_type_node); - if (c_uint64_type_node) - builtin_define_type_max ("__UINT64_MAX__", c_uint64_type_node); - if (int_least8_type_node) - { - builtin_define_type_max ("__INT_LEAST8_MAX__", int_least8_type_node); - builtin_define_constants ("__INT8_C", int_least8_type_node); - } - if (int_least16_type_node) - { - builtin_define_type_max ("__INT_LEAST16_MAX__", int_least16_type_node); - builtin_define_constants ("__INT16_C", int_least16_type_node); - } - if (int_least32_type_node) - { - builtin_define_type_max ("__INT_LEAST32_MAX__", int_least32_type_node); - builtin_define_constants ("__INT32_C", int_least32_type_node); - } - if (int_least64_type_node) - { - builtin_define_type_max ("__INT_LEAST64_MAX__", int_least64_type_node); - builtin_define_constants ("__INT64_C", int_least64_type_node); - } - if (uint_least8_type_node) - { - builtin_define_type_max ("__UINT_LEAST8_MAX__", uint_least8_type_node); - builtin_define_constants ("__UINT8_C", uint_least8_type_node); - } - if (uint_least16_type_node) - { - builtin_define_type_max ("__UINT_LEAST16_MAX__", uint_least16_type_node); - builtin_define_constants ("__UINT16_C", uint_least16_type_node); - } - if (uint_least32_type_node) - { - builtin_define_type_max ("__UINT_LEAST32_MAX__", uint_least32_type_node); - builtin_define_constants ("__UINT32_C", uint_least32_type_node); - } - if (uint_least64_type_node) - { - builtin_define_type_max ("__UINT_LEAST64_MAX__", uint_least64_type_node); - builtin_define_constants ("__UINT64_C", uint_least64_type_node); - } - if (int_fast8_type_node) - builtin_define_type_max ("__INT_FAST8_MAX__", int_fast8_type_node); - if (int_fast16_type_node) - builtin_define_type_max ("__INT_FAST16_MAX__", int_fast16_type_node); - if (int_fast32_type_node) - builtin_define_type_max ("__INT_FAST32_MAX__", int_fast32_type_node); - if (int_fast64_type_node) - builtin_define_type_max ("__INT_FAST64_MAX__", int_fast64_type_node); - if (uint_fast8_type_node) - builtin_define_type_max ("__UINT_FAST8_MAX__", uint_fast8_type_node); - if (uint_fast16_type_node) - builtin_define_type_max ("__UINT_FAST16_MAX__", uint_fast16_type_node); - if (uint_fast32_type_node) - builtin_define_type_max ("__UINT_FAST32_MAX__", uint_fast32_type_node); - if (uint_fast64_type_node) - builtin_define_type_max ("__UINT_FAST64_MAX__", uint_fast64_type_node); - if (intptr_type_node) - builtin_define_type_max ("__INTPTR_MAX__", intptr_type_node); - if (uintptr_type_node) - builtin_define_type_max ("__UINTPTR_MAX__", uintptr_type_node); -} - -/* Adjust the optimization macros when a #pragma GCC optimization is done to - reflect the current level. */ -void -c_cpp_builtins_optimize_pragma (cpp_reader *pfile, tree prev_tree, - tree cur_tree) -{ - struct cl_optimization *prev = TREE_OPTIMIZATION (prev_tree); - struct cl_optimization *cur = TREE_OPTIMIZATION (cur_tree); - bool prev_fast_math; - bool cur_fast_math; - - /* -undef turns off target-specific built-ins. */ - if (flag_undef) - return; - - /* Other target-independent built-ins determined by command-line - options. */ - if (!prev->x_optimize_size && cur->x_optimize_size) - cpp_define (pfile, "__OPTIMIZE_SIZE__"); - else if (prev->x_optimize_size && !cur->x_optimize_size) - cpp_undef (pfile, "__OPTIMIZE_SIZE__"); - - if (!prev->x_optimize && cur->x_optimize) - cpp_define (pfile, "__OPTIMIZE__"); - else if (prev->x_optimize && !cur->x_optimize) - cpp_undef (pfile, "__OPTIMIZE__"); - - prev_fast_math = fast_math_flags_struct_set_p (prev); - cur_fast_math = fast_math_flags_struct_set_p (cur); - if (!prev_fast_math && cur_fast_math) - cpp_define (pfile, "__FAST_MATH__"); - else if (prev_fast_math && !cur_fast_math) - cpp_undef (pfile, "__FAST_MATH__"); - - if (!prev->x_flag_signaling_nans && cur->x_flag_signaling_nans) - cpp_define (pfile, "__SUPPORT_SNAN__"); - else if (prev->x_flag_signaling_nans && !cur->x_flag_signaling_nans) - cpp_undef (pfile, "__SUPPORT_SNAN__"); - - if (!prev->x_flag_finite_math_only && cur->x_flag_finite_math_only) - { - cpp_undef (pfile, "__FINITE_MATH_ONLY__"); - cpp_define (pfile, "__FINITE_MATH_ONLY__=1"); - } - else if (prev->x_flag_finite_math_only && !cur->x_flag_finite_math_only) - { - cpp_undef (pfile, "__FINITE_MATH_ONLY__"); - cpp_define (pfile, "__FINITE_MATH_ONLY__=0"); - } -} - - -/* This function will emit cpp macros to indicate the presence of various lock - free atomic operations. */ - -static void -cpp_atomic_builtins (cpp_reader *pfile) -{ - /* Set a flag for each size of object that compare and swap exists for up to - a 16 byte object. */ -#define SWAP_LIMIT 17 - bool have_swap[SWAP_LIMIT]; - unsigned int psize; - - /* Clear the map of sizes compare_and swap exists for. */ - memset (have_swap, 0, sizeof (have_swap)); - - /* Tell source code if the compiler makes sync_compare_and_swap - builtins available. */ -#ifndef HAVE_sync_compare_and_swapqi -#define HAVE_sync_compare_and_swapqi 0 -#endif -#ifndef HAVE_atomic_compare_and_swapqi -#define HAVE_atomic_compare_and_swapqi 0 -#endif - - if (HAVE_sync_compare_and_swapqi || HAVE_atomic_compare_and_swapqi) - { - cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); - have_swap[1] = true; - } - -#ifndef HAVE_sync_compare_and_swaphi -#define HAVE_sync_compare_and_swaphi 0 -#endif -#ifndef HAVE_atomic_compare_and_swaphi -#define HAVE_atomic_compare_and_swaphi 0 -#endif - if (HAVE_sync_compare_and_swaphi || HAVE_atomic_compare_and_swaphi) - { - cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); - have_swap[2] = true; - } - -#ifndef HAVE_sync_compare_and_swapsi -#define HAVE_sync_compare_and_swapsi 0 -#endif -#ifndef HAVE_atomic_compare_and_swapsi -#define HAVE_atomic_compare_and_swapsi 0 -#endif - if (HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi) - { - cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); - have_swap[4] = true; - } - -#ifndef HAVE_sync_compare_and_swapdi -#define HAVE_sync_compare_and_swapdi 0 -#endif -#ifndef HAVE_atomic_compare_and_swapdi -#define HAVE_atomic_compare_and_swapdi 0 -#endif - if (HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi) - { - cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); - have_swap[8] = true; - } - -#ifndef HAVE_sync_compare_and_swapti -#define HAVE_sync_compare_and_swapti 0 -#endif -#ifndef HAVE_atomic_compare_and_swapti -#define HAVE_atomic_compare_and_swapti 0 -#endif - if (HAVE_sync_compare_and_swapti || HAVE_atomic_compare_and_swapti) - { - cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16"); - have_swap[16] = true; - } - - /* Tell the source code about various types. These map to the C++11 and C11 - macros where 2 indicates lock-free always, and 1 indicates sometimes - lock free. */ -#define SIZEOF_NODE(T) (tree_low_cst (TYPE_SIZE_UNIT (T), 1)) -#define SWAP_INDEX(T) ((SIZEOF_NODE (T) < SWAP_LIMIT) ? SIZEOF_NODE (T) : 0) - builtin_define_with_int_value ("__GCC_ATOMIC_BOOL_LOCK_FREE", - (have_swap[SWAP_INDEX (boolean_type_node)]? 2 : 1)); - builtin_define_with_int_value ("__GCC_ATOMIC_CHAR_LOCK_FREE", - (have_swap[SWAP_INDEX (signed_char_type_node)]? 2 : 1)); - builtin_define_with_int_value ("__GCC_ATOMIC_CHAR16_T_LOCK_FREE", - (have_swap[SWAP_INDEX (char16_type_node)]? 2 : 1)); - builtin_define_with_int_value ("__GCC_ATOMIC_CHAR32_T_LOCK_FREE", - (have_swap[SWAP_INDEX (char32_type_node)]? 2 : 1)); - builtin_define_with_int_value ("__GCC_ATOMIC_WCHAR_T_LOCK_FREE", - (have_swap[SWAP_INDEX (wchar_type_node)]? 2 : 1)); - builtin_define_with_int_value ("__GCC_ATOMIC_SHORT_LOCK_FREE", - (have_swap[SWAP_INDEX (short_integer_type_node)]? 2 : 1)); - builtin_define_with_int_value ("__GCC_ATOMIC_INT_LOCK_FREE", - (have_swap[SWAP_INDEX (integer_type_node)]? 2 : 1)); - builtin_define_with_int_value ("__GCC_ATOMIC_LONG_LOCK_FREE", - (have_swap[SWAP_INDEX (long_integer_type_node)]? 2 : 1)); - builtin_define_with_int_value ("__GCC_ATOMIC_LLONG_LOCK_FREE", - (have_swap[SWAP_INDEX (long_long_integer_type_node)]? 2 : 1)); - - /* If we're dealing with a "set" value that doesn't exactly correspond - to a boolean truth value, let the library work around that. */ - builtin_define_with_int_value ("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL", - targetm.atomic_test_and_set_trueval); - - /* ptr_type_node can't be used here since ptr_mode is only set when - toplev calls backend_init which is not done with -E or pch. */ - psize = POINTER_SIZE / BITS_PER_UNIT; - if (psize >= SWAP_LIMIT) - psize = 0; - builtin_define_with_int_value ("__GCC_ATOMIC_POINTER_LOCK_FREE", - (have_swap[psize]? 2 : 1)); -} - -/* Hook that registers front end and target-specific built-ins. */ -void -c_cpp_builtins (cpp_reader *pfile) -{ - /* -undef turns off target-specific built-ins. */ - if (flag_undef) - return; - - define_language_independent_builtin_macros (pfile); - - if (c_dialect_cxx ()) - { - int major; - parse_basever (&major, NULL, NULL); - cpp_define_formatted (pfile, "__GNUG__=%d", major); - } - - /* For stddef.h. They require macros defined in c-common.c. */ - c_stddef_cpp_builtins (); - - if (c_dialect_cxx ()) - { - if (flag_weak && SUPPORTS_ONE_ONLY) - cpp_define (pfile, "__GXX_WEAK__=1"); - else - cpp_define (pfile, "__GXX_WEAK__=0"); - if (warn_deprecated) - cpp_define (pfile, "__DEPRECATED"); - if (flag_rtti) - cpp_define (pfile, "__GXX_RTTI"); - if (cxx_dialect >= cxx0x) - cpp_define (pfile, "__GXX_EXPERIMENTAL_CXX0X__"); - } - /* Note that we define this for C as well, so that we know if - __attribute__((cleanup)) will interface with EH. */ - if (flag_exceptions) - cpp_define (pfile, "__EXCEPTIONS"); - - /* Represents the C++ ABI version, always defined so it can be used while - preprocessing C and assembler. */ - if (flag_abi_version == 0) - /* Use a very large value so that: - - #if __GXX_ABI_VERSION >= <value for version X> - - will work whether the user explicitly says "-fabi-version=x" or - "-fabi-version=0". Do not use INT_MAX because that will be - different from system to system. */ - builtin_define_with_int_value ("__GXX_ABI_VERSION", 999999); - else if (flag_abi_version == 1) - /* Due to a historical accident, this version had the value - "102". */ - builtin_define_with_int_value ("__GXX_ABI_VERSION", 102); - else - /* Newer versions have values 1002, 1003, .... */ - builtin_define_with_int_value ("__GXX_ABI_VERSION", - 1000 + flag_abi_version); - - /* libgcc needs to know this. */ - if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) - cpp_define (pfile, "__USING_SJLJ_EXCEPTIONS__"); - - /* limits.h and stdint.h need to know these. */ - builtin_define_type_max ("__SCHAR_MAX__", signed_char_type_node); - builtin_define_type_max ("__SHRT_MAX__", short_integer_type_node); - builtin_define_type_max ("__INT_MAX__", integer_type_node); - builtin_define_type_max ("__LONG_MAX__", long_integer_type_node); - builtin_define_type_max ("__LONG_LONG_MAX__", long_long_integer_type_node); - builtin_define_type_minmax ("__WCHAR_MIN__", "__WCHAR_MAX__", - underlying_wchar_type_node); - builtin_define_type_minmax ("__WINT_MIN__", "__WINT_MAX__", wint_type_node); - builtin_define_type_max ("__PTRDIFF_MAX__", ptrdiff_type_node); - builtin_define_type_max ("__SIZE_MAX__", size_type_node); - - /* stdint.h and the testsuite need to know these. */ - builtin_define_stdint_macros (); - - /* float.h needs to know this. */ - builtin_define_with_int_value ("__FLT_EVAL_METHOD__", - TARGET_FLT_EVAL_METHOD); - - /* And decfloat.h needs this. */ - builtin_define_with_int_value ("__DEC_EVAL_METHOD__", - TARGET_DEC_EVAL_METHOD); - - builtin_define_float_constants ("FLT", "F", "%s", "F", float_type_node); - /* Cast the double precision constants. This is needed when single - precision constants are specified or when pragma FLOAT_CONST_DECIMAL64 - is used. The correct result is computed by the compiler when using - macros that include a cast. We use a different cast for C++ to avoid - problems with -Wold-style-cast. */ - builtin_define_float_constants ("DBL", "L", - (c_dialect_cxx () - ? "double(%s)" - : "((double)%s)"), - "", double_type_node); - builtin_define_float_constants ("LDBL", "L", "%s", "L", - long_double_type_node); - - /* For decfloat.h. */ - builtin_define_decimal_float_constants ("DEC32", "DF", dfloat32_type_node); - builtin_define_decimal_float_constants ("DEC64", "DD", dfloat64_type_node); - builtin_define_decimal_float_constants ("DEC128", "DL", dfloat128_type_node); - - /* For fixed-point fibt, ibit, max, min, and epsilon. */ - if (targetm.fixed_point_supported_p ()) - { - builtin_define_fixed_point_constants ("SFRACT", "HR", - short_fract_type_node); - builtin_define_fixed_point_constants ("USFRACT", "UHR", - unsigned_short_fract_type_node); - builtin_define_fixed_point_constants ("FRACT", "R", - fract_type_node); - builtin_define_fixed_point_constants ("UFRACT", "UR", - unsigned_fract_type_node); - builtin_define_fixed_point_constants ("LFRACT", "LR", - long_fract_type_node); - builtin_define_fixed_point_constants ("ULFRACT", "ULR", - unsigned_long_fract_type_node); - builtin_define_fixed_point_constants ("LLFRACT", "LLR", - long_long_fract_type_node); - builtin_define_fixed_point_constants ("ULLFRACT", "ULLR", - unsigned_long_long_fract_type_node); - builtin_define_fixed_point_constants ("SACCUM", "HK", - short_accum_type_node); - builtin_define_fixed_point_constants ("USACCUM", "UHK", - unsigned_short_accum_type_node); - builtin_define_fixed_point_constants ("ACCUM", "K", - accum_type_node); - builtin_define_fixed_point_constants ("UACCUM", "UK", - unsigned_accum_type_node); - builtin_define_fixed_point_constants ("LACCUM", "LK", - long_accum_type_node); - builtin_define_fixed_point_constants ("ULACCUM", "ULK", - unsigned_long_accum_type_node); - builtin_define_fixed_point_constants ("LLACCUM", "LLK", - long_long_accum_type_node); - builtin_define_fixed_point_constants ("ULLACCUM", "ULLK", - unsigned_long_long_accum_type_node); - - builtin_define_fixed_point_constants ("QQ", "", qq_type_node); - builtin_define_fixed_point_constants ("HQ", "", hq_type_node); - builtin_define_fixed_point_constants ("SQ", "", sq_type_node); - builtin_define_fixed_point_constants ("DQ", "", dq_type_node); - builtin_define_fixed_point_constants ("TQ", "", tq_type_node); - builtin_define_fixed_point_constants ("UQQ", "", uqq_type_node); - builtin_define_fixed_point_constants ("UHQ", "", uhq_type_node); - builtin_define_fixed_point_constants ("USQ", "", usq_type_node); - builtin_define_fixed_point_constants ("UDQ", "", udq_type_node); - builtin_define_fixed_point_constants ("UTQ", "", utq_type_node); - builtin_define_fixed_point_constants ("HA", "", ha_type_node); - builtin_define_fixed_point_constants ("SA", "", sa_type_node); - builtin_define_fixed_point_constants ("DA", "", da_type_node); - builtin_define_fixed_point_constants ("TA", "", ta_type_node); - builtin_define_fixed_point_constants ("UHA", "", uha_type_node); - builtin_define_fixed_point_constants ("USA", "", usa_type_node); - builtin_define_fixed_point_constants ("UDA", "", uda_type_node); - builtin_define_fixed_point_constants ("UTA", "", uta_type_node); - } - - /* For libgcc-internal use only. */ - if (flag_building_libgcc) - /* For libgcc enable-execute-stack.c. */ - builtin_define_with_int_value ("__LIBGCC_TRAMPOLINE_SIZE__", - TRAMPOLINE_SIZE); - - /* For use in assembly language. */ - builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0); - builtin_define_with_value ("__USER_LABEL_PREFIX__", user_label_prefix, 0); - - /* Misc. */ - if (flag_gnu89_inline) - cpp_define (pfile, "__GNUC_GNU_INLINE__"); - else - cpp_define (pfile, "__GNUC_STDC_INLINE__"); - - if (flag_no_inline) - cpp_define (pfile, "__NO_INLINE__"); - - if (flag_iso) - cpp_define (pfile, "__STRICT_ANSI__"); - - if (!flag_signed_char) - cpp_define (pfile, "__CHAR_UNSIGNED__"); - - if (c_dialect_cxx () && TYPE_UNSIGNED (wchar_type_node)) - cpp_define (pfile, "__WCHAR_UNSIGNED__"); - - cpp_atomic_builtins (pfile); - -#ifdef DWARF2_UNWIND_INFO - if (dwarf2out_do_cfi_asm ()) - cpp_define (pfile, "__GCC_HAVE_DWARF2_CFI_ASM"); -#endif - - /* Make the choice of ObjC runtime visible to source code. */ - if (c_dialect_objc () && flag_next_runtime) - cpp_define (pfile, "__NEXT_RUNTIME__"); - - /* Show the availability of some target pragmas. */ - cpp_define (pfile, "__PRAGMA_REDEFINE_EXTNAME"); - - /* Make the choice of the stack protector runtime visible to source code. - The macro names and values here were chosen for compatibility with an - earlier implementation, i.e. ProPolice. */ - if (flag_stack_protect == 2) - cpp_define (pfile, "__SSP_ALL__=2"); - else if (flag_stack_protect == 1) - cpp_define (pfile, "__SSP__=1"); - - if (flag_openmp) - cpp_define (pfile, "_OPENMP=201107"); - - if (int128_integer_type_node != NULL_TREE) - builtin_define_type_sizeof ("__SIZEOF_INT128__", - int128_integer_type_node); - builtin_define_type_sizeof ("__SIZEOF_WCHAR_T__", wchar_type_node); - builtin_define_type_sizeof ("__SIZEOF_WINT_T__", wint_type_node); - builtin_define_type_sizeof ("__SIZEOF_PTRDIFF_T__", - unsigned_ptrdiff_type_node); - - /* A straightforward target hook doesn't work, because of problems - linking that hook's body when part of non-C front ends. */ -# define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM) -# define preprocessing_trad_p() (cpp_get_options (pfile)->traditional) -# define builtin_define(TXT) cpp_define (pfile, TXT) -# define builtin_assert(TXT) cpp_assert (pfile, TXT) - TARGET_CPU_CPP_BUILTINS (); - TARGET_OS_CPP_BUILTINS (); - TARGET_OBJFMT_CPP_BUILTINS (); - - /* Support the __declspec keyword by turning them into attributes. - Note that the current way we do this may result in a collision - with predefined attributes later on. This can be solved by using - one attribute, say __declspec__, and passing args to it. The - problem with that approach is that args are not accumulated: each - new appearance would clobber any existing args. */ - if (TARGET_DECLSPEC) - builtin_define ("__declspec(x)=__attribute__((x))"); - - /* If decimal floating point is supported, tell the user if the - alternate format (BID) is used instead of the standard (DPD) - format. */ - if (ENABLE_DECIMAL_FLOAT && ENABLE_DECIMAL_BID_FORMAT) - cpp_define (pfile, "__DECIMAL_BID_FORMAT__"); -} - -/* Pass an object-like macro. If it doesn't lie in the user's - namespace, defines it unconditionally. Otherwise define a version - with two leading underscores, and another version with two leading - and trailing underscores, and define the original only if an ISO - standard was not nominated. - - e.g. passing "unix" defines "__unix", "__unix__" and possibly - "unix". Passing "_mips" defines "__mips", "__mips__" and possibly - "_mips". */ -void -builtin_define_std (const char *macro) -{ - size_t len = strlen (macro); - char *buff = (char *) alloca (len + 5); - char *p = buff + 2; - char *q = p + len; - - /* prepend __ (or maybe just _) if in user's namespace. */ - memcpy (p, macro, len + 1); - if (!( *p == '_' && (p[1] == '_' || ISUPPER (p[1])))) - { - if (*p != '_') - *--p = '_'; - if (p[1] != '_') - *--p = '_'; - } - cpp_define (parse_in, p); - - /* If it was in user's namespace... */ - if (p != buff + 2) - { - /* Define the macro with leading and following __. */ - if (q[-1] != '_') - *q++ = '_'; - if (q[-2] != '_') - *q++ = '_'; - *q = '\0'; - cpp_define (parse_in, p); - - /* Finally, define the original macro if permitted. */ - if (!flag_iso) - cpp_define (parse_in, macro); - } -} - -/* Pass an object-like macro and a value to define it to. The third - parameter says whether or not to turn the value into a string - constant. */ -void -builtin_define_with_value (const char *macro, const char *expansion, int is_str) -{ - char *buf; - size_t mlen = strlen (macro); - size_t elen = strlen (expansion); - size_t extra = 2; /* space for an = and a NUL */ - - if (is_str) - extra += 2; /* space for two quote marks */ - - buf = (char *) alloca (mlen + elen + extra); - if (is_str) - sprintf (buf, "%s=\"%s\"", macro, expansion); - else - sprintf (buf, "%s=%s", macro, expansion); - - cpp_define (parse_in, buf); -} - - -/* Pass an object-like macro and an integer value to define it to. */ -static void -builtin_define_with_int_value (const char *macro, HOST_WIDE_INT value) -{ - char *buf; - size_t mlen = strlen (macro); - size_t vlen = 18; - size_t extra = 2; /* space for = and NUL. */ - - buf = (char *) alloca (mlen + vlen + extra); - memcpy (buf, macro, mlen); - buf[mlen] = '='; - sprintf (buf + mlen + 1, HOST_WIDE_INT_PRINT_DEC, value); - - cpp_define (parse_in, buf); -} - -/* builtin_define_with_hex_fp_value is very expensive, so the following - array and function allows it to be done lazily when __DBL_MAX__ - etc. is first used. */ - -struct GTY(()) lazy_hex_fp_value_struct -{ - const char *hex_str; - cpp_macro *macro; - enum machine_mode mode; - int digits; - const char *fp_suffix; -}; -static GTY(()) struct lazy_hex_fp_value_struct lazy_hex_fp_values[12]; -static GTY(()) int lazy_hex_fp_value_count; - -static bool -lazy_hex_fp_value (cpp_reader *pfile ATTRIBUTE_UNUSED, - cpp_hashnode *node) -{ - REAL_VALUE_TYPE real; - char dec_str[64], buf1[256]; - unsigned int idx; - if (node->value.builtin < BT_FIRST_USER - || (int) node->value.builtin >= BT_FIRST_USER + lazy_hex_fp_value_count) - return false; - - idx = node->value.builtin - BT_FIRST_USER; - real_from_string (&real, lazy_hex_fp_values[idx].hex_str); - real_to_decimal_for_mode (dec_str, &real, sizeof (dec_str), - lazy_hex_fp_values[idx].digits, 0, - lazy_hex_fp_values[idx].mode); - - sprintf (buf1, "%s%s", dec_str, lazy_hex_fp_values[idx].fp_suffix); - node->flags &= ~(NODE_BUILTIN | NODE_USED); - node->value.macro = lazy_hex_fp_values[idx].macro; - for (idx = 0; idx < node->value.macro->count; idx++) - if (node->value.macro->exp.tokens[idx].type == CPP_NUMBER) - break; - gcc_assert (idx < node->value.macro->count); - node->value.macro->exp.tokens[idx].val.str.len = strlen (buf1); - node->value.macro->exp.tokens[idx].val.str.text - = (const unsigned char *) ggc_strdup (buf1); - return true; -} - -/* Pass an object-like macro a hexadecimal floating-point value. */ -static void -builtin_define_with_hex_fp_value (const char *macro, - tree type, int digits, - const char *hex_str, - const char *fp_suffix, - const char *fp_cast) -{ - REAL_VALUE_TYPE real; - char dec_str[64], buf1[256], buf2[256]; - - /* This is very expensive, so if possible expand them lazily. */ - if (lazy_hex_fp_value_count < 12 - && flag_dump_macros == 0 - && !cpp_get_options (parse_in)->traditional) - { - struct cpp_hashnode *node; - if (lazy_hex_fp_value_count == 0) - cpp_get_callbacks (parse_in)->user_builtin_macro = lazy_hex_fp_value; - sprintf (buf2, fp_cast, "1.1"); - sprintf (buf1, "%s=%s", macro, buf2); - cpp_define (parse_in, buf1); - node = C_CPP_HASHNODE (get_identifier (macro)); - lazy_hex_fp_values[lazy_hex_fp_value_count].hex_str - = ggc_strdup (hex_str); - lazy_hex_fp_values[lazy_hex_fp_value_count].mode = TYPE_MODE (type); - lazy_hex_fp_values[lazy_hex_fp_value_count].digits = digits; - lazy_hex_fp_values[lazy_hex_fp_value_count].fp_suffix = fp_suffix; - lazy_hex_fp_values[lazy_hex_fp_value_count].macro = node->value.macro; - node->flags |= NODE_BUILTIN; - node->value.builtin - = (enum cpp_builtin_type) (BT_FIRST_USER + lazy_hex_fp_value_count); - lazy_hex_fp_value_count++; - return; - } - - /* Hex values are really cool and convenient, except that they're - not supported in strict ISO C90 mode. First, the "p-" sequence - is not valid as part of a preprocessor number. Second, we get a - pedwarn from the preprocessor, which has no context, so we can't - suppress the warning with __extension__. - - So instead what we do is construct the number in hex (because - it's easy to get the exact correct value), parse it as a real, - then print it back out as decimal. */ - - real_from_string (&real, hex_str); - real_to_decimal_for_mode (dec_str, &real, sizeof (dec_str), digits, 0, - TYPE_MODE (type)); - - /* Assemble the macro in the following fashion - macro = fp_cast [dec_str fp_suffix] */ - sprintf (buf1, "%s%s", dec_str, fp_suffix); - sprintf (buf2, fp_cast, buf1); - sprintf (buf1, "%s=%s", macro, buf2); - - cpp_define (parse_in, buf1); -} - -/* Return a string constant for the suffix for a value of type TYPE - promoted according to the integer promotions. The type must be one - of the standard integer type nodes. */ - -static const char * -type_suffix (tree type) -{ - static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" }; - int unsigned_suffix; - int is_long; - - if (type == long_long_integer_type_node - || type == long_long_unsigned_type_node) - is_long = 2; - else if (type == long_integer_type_node - || type == long_unsigned_type_node) - is_long = 1; - else if (type == integer_type_node - || type == unsigned_type_node - || type == short_integer_type_node - || type == short_unsigned_type_node - || type == signed_char_type_node - || type == unsigned_char_type_node - /* ??? "char" is not a signed or unsigned integer type and - so is not permitted for the standard typedefs, but some - systems use it anyway. */ - || type == char_type_node) - is_long = 0; - else - gcc_unreachable (); - - unsigned_suffix = TYPE_UNSIGNED (type); - if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) - unsigned_suffix = 0; - return suffixes[is_long * 2 + unsigned_suffix]; -} - -/* Define MACRO as a <stdint.h> constant-suffix macro for TYPE. */ -static void -builtin_define_constants (const char *macro, tree type) -{ - const char *suffix; - char *buf; - - suffix = type_suffix (type); - - if (suffix[0] == 0) - { - buf = (char *) alloca (strlen (macro) + 6); - sprintf (buf, "%s(c)=c", macro); - } - else - { - buf = (char *) alloca (strlen (macro) + 9 + strlen (suffix) + 1); - sprintf (buf, "%s(c)=c ## %s", macro, suffix); - } - - cpp_define (parse_in, buf); -} - -/* Define MAX for TYPE based on the precision of the type. */ - -static void -builtin_define_type_max (const char *macro, tree type) -{ - builtin_define_type_minmax (NULL, macro, type); -} - -/* Define MIN_MACRO (if not NULL) and MAX_MACRO for TYPE based on the - precision of the type. */ - -static void -builtin_define_type_minmax (const char *min_macro, const char *max_macro, - tree type) -{ - static const char *const values[] - = { "127", "255", - "32767", "65535", - "2147483647", "4294967295", - "9223372036854775807", "18446744073709551615", - "170141183460469231731687303715884105727", - "340282366920938463463374607431768211455" }; - - const char *value, *suffix; - char *buf; - size_t idx; - - /* Pre-rendering the values mean we don't have to futz with printing a - multi-word decimal value. There are also a very limited number of - precisions that we support, so it's really a waste of time. */ - switch (TYPE_PRECISION (type)) - { - case 8: idx = 0; break; - case 16: idx = 2; break; - case 32: idx = 4; break; - case 64: idx = 6; break; - case 128: idx = 8; break; - default: gcc_unreachable (); - } - - value = values[idx + TYPE_UNSIGNED (type)]; - suffix = type_suffix (type); - - buf = (char *) alloca (strlen (max_macro) + 1 + strlen (value) - + strlen (suffix) + 1); - sprintf (buf, "%s=%s%s", max_macro, value, suffix); - - cpp_define (parse_in, buf); - - if (min_macro) - { - if (TYPE_UNSIGNED (type)) - { - buf = (char *) alloca (strlen (min_macro) + 2 + strlen (suffix) + 1); - sprintf (buf, "%s=0%s", min_macro, suffix); - } - else - { - buf = (char *) alloca (strlen (min_macro) + 3 - + strlen (max_macro) + 6); - sprintf (buf, "%s=(-%s - 1)", min_macro, max_macro); - } - cpp_define (parse_in, buf); - } -} - -#include "gt-c-family-c-cppbuiltin.h" diff --git a/gcc-4.8.1/gcc/c-family/c-dump.c b/gcc-4.8.1/gcc/c-family/c-dump.c deleted file mode 100644 index 3954331b1..000000000 --- a/gcc-4.8.1/gcc/c-family/c-dump.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Tree-dumping functionality for C-family languages. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Written by Mark Mitchell <mark@codesourcery.com> - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "tree.h" -#include "tree-dump.h" -#include "c-common.h" - -/* Dump any C-specific tree codes and attributes of common codes. */ - -bool -c_dump_tree (void *dump_info, tree t) -{ - enum tree_code code; - dump_info_p di = (dump_info_p) dump_info; - - /* Figure out what kind of node this is. */ - code = TREE_CODE (t); - - switch (code) - { - case FIELD_DECL: - if (DECL_C_BIT_FIELD (t)) - dump_string (di, "bitfield"); - break; - - default: - break; - } - - return false; -} diff --git a/gcc-4.8.1/gcc/c-family/c-format.c b/gcc-4.8.1/gcc/c-family/c-format.c deleted file mode 100644 index 8f1ffedba..000000000 --- a/gcc-4.8.1/gcc/c-family/c-format.c +++ /dev/null @@ -1,3036 +0,0 @@ -/* Check calls to formatted I/O functions (-Wformat). - Copyright (C) 1992-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "tree.h" -#include "flags.h" -#include "c-common.h" -#include "c-objc.h" -#include "intl.h" -#include "diagnostic-core.h" -#include "langhooks.h" -#include "c-format.h" -#include "alloc-pool.h" -#include "c-target.h" - -/* Handle attributes associated with format checking. */ - -/* This must be in the same order as format_types, except for - format_type_error. Target-specific format types do not have - matching enum values. */ -enum format_type { printf_format_type, asm_fprintf_format_type, - gcc_diag_format_type, gcc_tdiag_format_type, - gcc_cdiag_format_type, - gcc_cxxdiag_format_type, gcc_gfc_format_type, - gcc_objc_string_format_type, - format_type_error = -1}; - -typedef struct function_format_info -{ - int format_type; /* type of format (printf, scanf, etc.) */ - unsigned HOST_WIDE_INT format_num; /* number of format argument */ - unsigned HOST_WIDE_INT first_arg_num; /* number of first arg (zero for varargs) */ -} function_format_info; - -static bool decode_format_attr (tree, function_format_info *, int); -static int decode_format_type (const char *); - -static bool check_format_string (tree argument, - unsigned HOST_WIDE_INT format_num, - int flags, bool *no_add_attrs, - int expected_format_type); -static bool get_constant (tree expr, unsigned HOST_WIDE_INT *value, - int validated_p); -static const char *convert_format_name_to_system_name (const char *attr_name); -static bool cmp_attribs (const char *tattr_name, const char *attr_name); - -static int first_target_format_type; -static const char *format_name (int format_num); -static int format_flags (int format_num); - -/* Check that we have a pointer to a string suitable for use as a format. - The default is to check for a char type. - For objective-c dialects, this is extended to include references to string - objects validated by objc_string_ref_type_p (). - Targets may also provide a string object type that can be used within c and - c++ and shared with their respective objective-c dialects. In this case the - reference to a format string is checked for validity via a hook. - - The function returns true if strref points to any string type valid for the - language dialect and target. */ - -static bool -valid_stringptr_type_p (tree strref) -{ - return (strref != NULL - && TREE_CODE (strref) == POINTER_TYPE - && (TYPE_MAIN_VARIANT (TREE_TYPE (strref)) == char_type_node - || objc_string_ref_type_p (strref) - || (*targetcm.string_object_ref_type_p) ((const_tree) strref))); -} - -/* Handle a "format_arg" attribute; arguments as in - struct attribute_spec.handler. */ -tree -handle_format_arg_attribute (tree *node, tree ARG_UNUSED (name), - tree args, int flags, bool *no_add_attrs) -{ - tree type = *node; - tree format_num_expr = TREE_VALUE (args); - unsigned HOST_WIDE_INT format_num = 0; - - if (!get_constant (format_num_expr, &format_num, 0)) - { - error ("format string has invalid operand number"); - *no_add_attrs = true; - return NULL_TREE; - } - - if (prototype_p (type)) - { - /* The format arg can be any string reference valid for the language and - target. We cannot be more specific in this case. */ - if (!check_format_string (type, format_num, flags, no_add_attrs, -1)) - return NULL_TREE; - } - - if (!valid_stringptr_type_p (TREE_TYPE (type))) - { - if (!(flags & (int) ATTR_FLAG_BUILT_IN)) - error ("function does not return string type"); - *no_add_attrs = true; - return NULL_TREE; - } - - return NULL_TREE; -} - -/* Verify that the format_num argument is actually a string reference suitable, - for the language dialect and target (in case the format attribute is in - error). When we know the specific reference type expected, this is also - checked. */ -static bool -check_format_string (tree fntype, unsigned HOST_WIDE_INT format_num, - int flags, bool *no_add_attrs, int expected_format_type) -{ - unsigned HOST_WIDE_INT i; - bool is_objc_sref, is_target_sref, is_char_ref; - tree ref; - int fmt_flags; - function_args_iterator iter; - - i = 1; - FOREACH_FUNCTION_ARGS (fntype, ref, iter) - { - if (i == format_num) - break; - i++; - } - - if (!ref - || !valid_stringptr_type_p (ref)) - { - if (!(flags & (int) ATTR_FLAG_BUILT_IN)) - error ("format string argument is not a string type"); - *no_add_attrs = true; - return false; - } - - /* We only know that we want a suitable string reference. */ - if (expected_format_type < 0) - return true; - - /* Now check that the arg matches the expected type. */ - is_char_ref = - (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) == char_type_node); - - fmt_flags = format_flags (expected_format_type); - is_objc_sref = is_target_sref = false; - if (!is_char_ref) - is_objc_sref = objc_string_ref_type_p (ref); - - if (!(fmt_flags & FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL)) - { - if (is_char_ref) - return true; /* OK, we expected a char and found one. */ - else - { - /* We expected a char but found an extended string type. */ - if (is_objc_sref) - error ("found a %<%s%> reference but the format argument should" - " be a string", format_name (gcc_objc_string_format_type)); - else - error ("found a %qT but the format argument should be a string", - ref); - *no_add_attrs = true; - return false; - } - } - - /* We expect a string object type as the format arg. */ - if (is_char_ref) - { - error ("format argument should be a %<%s%> reference but" - " a string was found", format_name (expected_format_type)); - *no_add_attrs = true; - return false; - } - - /* We will assert that objective-c will support either its own string type - or the target-supplied variant. */ - if (!is_objc_sref) - is_target_sref = (*targetcm.string_object_ref_type_p) ((const_tree) ref); - - if (expected_format_type == (int) gcc_objc_string_format_type - && (is_objc_sref || is_target_sref)) - return true; - - /* We will allow a target string ref to match only itself. */ - if (first_target_format_type - && expected_format_type >= first_target_format_type - && is_target_sref) - return true; - else - { - error ("format argument should be a %<%s%> reference", - format_name (expected_format_type)); - *no_add_attrs = true; - return false; - } - - gcc_unreachable (); -} - -/* Verify EXPR is a constant, and store its value. - If validated_p is true there should be no errors. - Returns true on success, false otherwise. */ -static bool -get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p) -{ - if (TREE_CODE (expr) != INTEGER_CST || TREE_INT_CST_HIGH (expr) != 0) - { - gcc_assert (!validated_p); - return false; - } - - *value = TREE_INT_CST_LOW (expr); - - return true; -} - -/* Decode the arguments to a "format" attribute into a - function_format_info structure. It is already known that the list - is of the right length. If VALIDATED_P is true, then these - attributes have already been validated and must not be erroneous; - if false, it will give an error message. Returns true if the - attributes are successfully decoded, false otherwise. */ - -static bool -decode_format_attr (tree args, function_format_info *info, int validated_p) -{ - tree format_type_id = TREE_VALUE (args); - tree format_num_expr = TREE_VALUE (TREE_CHAIN (args)); - tree first_arg_num_expr - = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args))); - - if (TREE_CODE (format_type_id) != IDENTIFIER_NODE) - { - gcc_assert (!validated_p); - error ("unrecognized format specifier"); - return false; - } - else - { - const char *p = IDENTIFIER_POINTER (format_type_id); - - p = convert_format_name_to_system_name (p); - - info->format_type = decode_format_type (p); - - if (!c_dialect_objc () - && info->format_type == gcc_objc_string_format_type) - { - gcc_assert (!validated_p); - warning (OPT_Wformat_, "%qE is only allowed in Objective-C dialects", - format_type_id); - info->format_type = format_type_error; - return false; - } - - if (info->format_type == format_type_error) - { - gcc_assert (!validated_p); - warning (OPT_Wformat_, "%qE is an unrecognized format function type", - format_type_id); - return false; - } - } - - if (!get_constant (format_num_expr, &info->format_num, validated_p)) - { - error ("format string has invalid operand number"); - return false; - } - - if (!get_constant (first_arg_num_expr, &info->first_arg_num, validated_p)) - { - error ("%<...%> has invalid operand number"); - return false; - } - - if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num) - { - gcc_assert (!validated_p); - error ("format string argument follows the args to be formatted"); - return false; - } - - return true; -} - -/* Check a call to a format function against a parameter list. */ - -/* The C standard version C++ is treated as equivalent to - or inheriting from, for the purpose of format features supported. */ -#define CPLUSPLUS_STD_VER (cxx_dialect < cxx11 ? STD_C94 : STD_C99) -/* The C standard version we are checking formats against when pedantic. */ -#define C_STD_VER ((int) (c_dialect_cxx () \ - ? CPLUSPLUS_STD_VER \ - : (flag_isoc99 \ - ? STD_C99 \ - : (flag_isoc94 ? STD_C94 : STD_C89)))) -/* The name to give to the standard version we are warning about when - pedantic. FEATURE_VER is the version in which the feature warned out - appeared, which is higher than C_STD_VER. */ -#define C_STD_NAME(FEATURE_VER) (c_dialect_cxx () \ - ? (cxx_dialect < cxx11 ? "ISO C++98" \ - : "ISO C++11") \ - : ((FEATURE_VER) == STD_EXT \ - ? "ISO C" \ - : "ISO C90")) -/* Adjust a C standard version, which may be STD_C9L, to account for - -Wno-long-long. Returns other standard versions unchanged. */ -#define ADJ_STD(VER) ((int) ((VER) == STD_C9L \ - ? (warn_long_long ? STD_C99 : STD_C89) \ - : (VER))) - -/* Enum describing the kind of specifiers present in the format and - requiring an argument. */ -enum format_specifier_kind { - CF_KIND_FORMAT, - CF_KIND_FIELD_WIDTH, - CF_KIND_FIELD_PRECISION -}; - -static const char *kind_descriptions[] = { - N_("format"), - N_("field width specifier"), - N_("field precision specifier") -}; - -/* Structure describing details of a type expected in format checking, - and the type to check against it. */ -typedef struct format_wanted_type -{ - /* The type wanted. */ - tree wanted_type; - /* The name of this type to use in diagnostics. */ - const char *wanted_type_name; - /* Should be type checked just for scalar width identity. */ - int scalar_identity_flag; - /* The level of indirection through pointers at which this type occurs. */ - int pointer_count; - /* Whether, when pointer_count is 1, to allow any character type when - pedantic, rather than just the character or void type specified. */ - int char_lenient_flag; - /* Whether the argument, dereferenced once, is written into and so the - argument must not be a pointer to a const-qualified type. */ - int writing_in_flag; - /* Whether the argument, dereferenced once, is read from and so - must not be a NULL pointer. */ - int reading_from_flag; - /* The kind of specifier that this type is used for. */ - enum format_specifier_kind kind; - /* The starting character of the specifier. This never includes the - initial percent sign. */ - const char *format_start; - /* The length of the specifier. */ - int format_length; - /* The actual parameter to check against the wanted type. */ - tree param; - /* The argument number of that parameter. */ - int arg_num; - /* The next type to check for this format conversion, or NULL if none. */ - struct format_wanted_type *next; -} format_wanted_type; - -/* Convenience macro for format_length_info meaning unused. */ -#define NO_FMT NULL, FMT_LEN_none, STD_C89 - -static const format_length_info printf_length_specs[] = -{ - { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 }, - { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 }, - { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 }, - { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 }, - { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 }, - { "Z", FMT_LEN_z, STD_EXT, NO_FMT, 0 }, - { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 }, - { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 }, - { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 }, - { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 }, - { NO_FMT, NO_FMT, 0 } -}; - -/* Length specifiers valid for asm_fprintf. */ -static const format_length_info asm_fprintf_length_specs[] = -{ - { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 }, - { "w", FMT_LEN_none, STD_C89, NO_FMT, 0 }, - { NO_FMT, NO_FMT, 0 } -}; - -/* Length specifiers valid for GCC diagnostics. */ -static const format_length_info gcc_diag_length_specs[] = -{ - { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 }, - { "w", FMT_LEN_none, STD_C89, NO_FMT, 0 }, - { NO_FMT, NO_FMT, 0 } -}; - -/* The custom diagnostics all accept the same length specifiers. */ -#define gcc_tdiag_length_specs gcc_diag_length_specs -#define gcc_cdiag_length_specs gcc_diag_length_specs -#define gcc_cxxdiag_length_specs gcc_diag_length_specs - -/* This differs from printf_length_specs only in that "Z" is not accepted. */ -static const format_length_info scanf_length_specs[] = -{ - { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 }, - { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 }, - { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 }, - { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 }, - { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 }, - { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 }, - { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 }, - { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 }, - { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 }, - { NO_FMT, NO_FMT, 0 } -}; - - -/* All tables for strfmon use STD_C89 everywhere, since -pedantic warnings - make no sense for a format type not part of any C standard version. */ -static const format_length_info strfmon_length_specs[] = -{ - /* A GNU extension. */ - { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 }, - { NO_FMT, NO_FMT, 0 } -}; - - -/* For now, the Fortran front-end routines only use l as length modifier. */ -static const format_length_info gcc_gfc_length_specs[] = -{ - { "l", FMT_LEN_l, STD_C89, NO_FMT, 0 }, - { NO_FMT, NO_FMT, 0 } -}; - - -static const format_flag_spec printf_flag_specs[] = -{ - { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 }, - { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 }, - { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 }, - { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 }, - { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 }, - { '\'', 0, 0, N_("''' flag"), N_("the ''' printf flag"), STD_EXT }, - { 'I', 0, 0, N_("'I' flag"), N_("the 'I' printf flag"), STD_EXT }, - { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 }, - { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, - { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, - { 0, 0, 0, NULL, NULL, STD_C89 } -}; - - -static const format_flag_pair printf_flag_pairs[] = -{ - { ' ', '+', 1, 0 }, - { '0', '-', 1, 0 }, - { '0', 'p', 1, 'i' }, - { 0, 0, 0, 0 } -}; - -static const format_flag_spec asm_fprintf_flag_specs[] = -{ - { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 }, - { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 }, - { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 }, - { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 }, - { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 }, - { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 }, - { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, - { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, - { 0, 0, 0, NULL, NULL, STD_C89 } -}; - -static const format_flag_pair asm_fprintf_flag_pairs[] = -{ - { ' ', '+', 1, 0 }, - { '0', '-', 1, 0 }, - { '0', 'p', 1, 'i' }, - { 0, 0, 0, 0 } -}; - -static const format_flag_pair gcc_diag_flag_pairs[] = -{ - { 0, 0, 0, 0 } -}; - -#define gcc_tdiag_flag_pairs gcc_diag_flag_pairs -#define gcc_cdiag_flag_pairs gcc_diag_flag_pairs -#define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs - -static const format_flag_pair gcc_gfc_flag_pairs[] = -{ - { 0, 0, 0, 0 } -}; - -static const format_flag_spec gcc_diag_flag_specs[] = -{ - { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 }, - { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 }, - { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 }, - { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, - { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, - { 0, 0, 0, NULL, NULL, STD_C89 } -}; - -#define gcc_tdiag_flag_specs gcc_diag_flag_specs -#define gcc_cdiag_flag_specs gcc_diag_flag_specs -#define gcc_cxxdiag_flag_specs gcc_diag_flag_specs - -static const format_flag_spec scanf_flag_specs[] = -{ - { '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 }, - { 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT }, - { 'm', 0, 0, N_("'m' flag"), N_("the 'm' scanf flag"), STD_EXT }, - { 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 }, - { 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 }, - { '\'', 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT }, - { 'I', 0, 0, N_("'I' flag"), N_("the 'I' scanf flag"), STD_EXT }, - { 0, 0, 0, NULL, NULL, STD_C89 } -}; - - -static const format_flag_pair scanf_flag_pairs[] = -{ - { '*', 'L', 0, 0 }, - { 'a', 'm', 0, 0 }, - { 0, 0, 0, 0 } -}; - - -static const format_flag_spec strftime_flag_specs[] = -{ - { '_', 0, 0, N_("'_' flag"), N_("the '_' strftime flag"), STD_EXT }, - { '-', 0, 0, N_("'-' flag"), N_("the '-' strftime flag"), STD_EXT }, - { '0', 0, 0, N_("'0' flag"), N_("the '0' strftime flag"), STD_EXT }, - { '^', 0, 0, N_("'^' flag"), N_("the '^' strftime flag"), STD_EXT }, - { '#', 0, 0, N_("'#' flag"), N_("the '#' strftime flag"), STD_EXT }, - { 'w', 0, 0, N_("field width"), N_("field width in strftime format"), STD_EXT }, - { 'E', 0, 0, N_("'E' modifier"), N_("the 'E' strftime modifier"), STD_C99 }, - { 'O', 0, 0, N_("'O' modifier"), N_("the 'O' strftime modifier"), STD_C99 }, - { 'O', 'o', 0, NULL, N_("the 'O' modifier"), STD_EXT }, - { 0, 0, 0, NULL, NULL, STD_C89 } -}; - - -static const format_flag_pair strftime_flag_pairs[] = -{ - { 'E', 'O', 0, 0 }, - { '_', '-', 0, 0 }, - { '_', '0', 0, 0 }, - { '-', '0', 0, 0 }, - { '^', '#', 0, 0 }, - { 0, 0, 0, 0 } -}; - - -static const format_flag_spec strfmon_flag_specs[] = -{ - { '=', 0, 1, N_("fill character"), N_("fill character in strfmon format"), STD_C89 }, - { '^', 0, 0, N_("'^' flag"), N_("the '^' strfmon flag"), STD_C89 }, - { '+', 0, 0, N_("'+' flag"), N_("the '+' strfmon flag"), STD_C89 }, - { '(', 0, 0, N_("'(' flag"), N_("the '(' strfmon flag"), STD_C89 }, - { '!', 0, 0, N_("'!' flag"), N_("the '!' strfmon flag"), STD_C89 }, - { '-', 0, 0, N_("'-' flag"), N_("the '-' strfmon flag"), STD_C89 }, - { 'w', 0, 0, N_("field width"), N_("field width in strfmon format"), STD_C89 }, - { '#', 0, 0, N_("left precision"), N_("left precision in strfmon format"), STD_C89 }, - { 'p', 0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 }, - { 'L', 0, 0, N_("length modifier"), N_("length modifier in strfmon format"), STD_C89 }, - { 0, 0, 0, NULL, NULL, STD_C89 } -}; - -static const format_flag_pair strfmon_flag_pairs[] = -{ - { '+', '(', 0, 0 }, - { 0, 0, 0, 0 } -}; - - -static const format_char_info print_char_table[] = -{ - /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "-wp0 +'I", "i", NULL }, - { "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, - { "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "-wp0'I", "i", NULL }, - { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#'I", "", NULL }, - { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#I", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, - { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, - /* C99 conversion specifiers. */ - { "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#'I", "", NULL }, - { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL }, - /* X/Open conversion specifiers. */ - { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL }, - /* GNU conversion specifiers. */ - { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL }, - { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } -}; - -static const format_char_info asm_fprintf_char_table[] = -{ - /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL }, - { "oxX", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0", "i", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, - - /* asm_fprintf conversion specifiers. */ - { "O", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - { "R", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - { "I", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - { "L", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - { "U", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - { "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL }, - { "@", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } -}; - -static const format_char_info gcc_diag_char_table[] = -{ - /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, - - /* Custom conversion specifiers. */ - - /* These will require a "tree" at runtime. */ - { "K", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - - { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL }, - { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } -}; - -static const format_char_info gcc_tdiag_char_table[] = -{ - /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, - - /* Custom conversion specifiers. */ - - /* These will require a "tree" at runtime. */ - { "DFKTEV", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL }, - - { "v", 0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL }, - - { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL }, - { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } -}; - -static const format_char_info gcc_cdiag_char_table[] = -{ - /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, - - /* Custom conversion specifiers. */ - - /* These will require a "tree" at runtime. */ - { "DEFKTV", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL }, - - { "v", 0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL }, - - { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL }, - { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } -}; - -static const format_char_info gcc_cxxdiag_char_table[] = -{ - /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, - - /* Custom conversion specifiers. */ - - /* These will require a "tree" at runtime. */ - { "ADEFKSTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL }, - - { "v", 0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL }, - - /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */ - { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - - { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL }, - { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } -}; - -static const format_char_info gcc_gfc_char_table[] = -{ - /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL }, - - /* gfc conversion specifiers. */ - - { "C", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - - /* This will require a "locus" at runtime. */ - { "L", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "R", NULL }, - - { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } -}; - -static const format_char_info scan_char_table[] = -{ - /* C89 conversion specifiers. */ - { "di", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "*w'I", "W", NULL }, - { "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w'I", "W", NULL }, - { "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL }, - { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "cW", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW", NULL }, - { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW[", NULL }, - { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, - /* C99 conversion specifiers. */ - { "F", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL }, - { "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - /* X/Open conversion specifiers. */ - { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "W", NULL }, - { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "W", NULL }, - { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } -}; - -static const format_char_info time_char_table[] = -{ - /* C89 conversion specifiers. */ - { "ABZab", 0, STD_C89, NOLENGTHS, "^#", "", NULL }, - { "cx", 0, STD_C89, NOLENGTHS, "E", "3", NULL }, - { "HIMSUWdmw", 0, STD_C89, NOLENGTHS, "-_0Ow", "", NULL }, - { "j", 0, STD_C89, NOLENGTHS, "-_0Ow", "o", NULL }, - { "p", 0, STD_C89, NOLENGTHS, "#", "", NULL }, - { "X", 0, STD_C89, NOLENGTHS, "E", "", NULL }, - { "y", 0, STD_C89, NOLENGTHS, "EO-_0w", "4", NULL }, - { "Y", 0, STD_C89, NOLENGTHS, "-_0EOw", "o", NULL }, - { "%", 0, STD_C89, NOLENGTHS, "", "", NULL }, - /* C99 conversion specifiers. */ - { "C", 0, STD_C99, NOLENGTHS, "-_0EOw", "o", NULL }, - { "D", 0, STD_C99, NOLENGTHS, "", "2", NULL }, - { "eVu", 0, STD_C99, NOLENGTHS, "-_0Ow", "", NULL }, - { "FRTnrt", 0, STD_C99, NOLENGTHS, "", "", NULL }, - { "g", 0, STD_C99, NOLENGTHS, "O-_0w", "2o", NULL }, - { "G", 0, STD_C99, NOLENGTHS, "-_0Ow", "o", NULL }, - { "h", 0, STD_C99, NOLENGTHS, "^#", "", NULL }, - { "z", 0, STD_C99, NOLENGTHS, "O", "o", NULL }, - /* GNU conversion specifiers. */ - { "kls", 0, STD_EXT, NOLENGTHS, "-_0Ow", "", NULL }, - { "P", 0, STD_EXT, NOLENGTHS, "", "", NULL }, - { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } -}; - -static const format_char_info monetary_char_table[] = -{ - { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "", NULL }, - { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } -}; - -/* This must be in the same order as enum format_type. */ -static const format_kind_info format_types_orig[] = -{ - { "gnu_printf", printf_length_specs, print_char_table, " +#0-'I", NULL, - printf_flag_specs, printf_flag_pairs, - FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK, - 'w', 0, 'p', 0, 'L', 0, - &integer_type_node, &integer_type_node - }, - { "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL, - asm_fprintf_flag_specs, asm_fprintf_flag_pairs, - FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, - 'w', 0, 'p', 0, 'L', 0, - NULL, NULL - }, - { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+#", NULL, - gcc_diag_flag_specs, gcc_diag_flag_pairs, - FMT_FLAG_ARG_CONVERT, - 0, 0, 'p', 0, 'L', 0, - NULL, &integer_type_node - }, - { "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+#", NULL, - gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs, - FMT_FLAG_ARG_CONVERT, - 0, 0, 'p', 0, 'L', 0, - NULL, &integer_type_node - }, - { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+#", NULL, - gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs, - FMT_FLAG_ARG_CONVERT, - 0, 0, 'p', 0, 'L', 0, - NULL, &integer_type_node - }, - { "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "q+#", NULL, - gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs, - FMT_FLAG_ARG_CONVERT, - 0, 0, 'p', 0, 'L', 0, - NULL, &integer_type_node - }, - { "gcc_gfc", gcc_gfc_length_specs, gcc_gfc_char_table, "", NULL, - NULL, gcc_gfc_flag_pairs, - FMT_FLAG_ARG_CONVERT, - 0, 0, 0, 0, 0, 0, - NULL, NULL - }, - { "NSString", NULL, NULL, NULL, NULL, - NULL, NULL, - FMT_FLAG_ARG_CONVERT|FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL, 0, 0, 0, 0, 0, 0, - NULL, NULL - }, - { "gnu_scanf", scanf_length_specs, scan_char_table, "*'I", NULL, - scanf_flag_specs, scanf_flag_pairs, - FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK, - 'w', 0, 0, '*', 'L', 'm', - NULL, NULL - }, - { "gnu_strftime", NULL, time_char_table, "_-0^#", "EO", - strftime_flag_specs, strftime_flag_pairs, - FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0, 0, - NULL, NULL - }, - { "gnu_strfmon", strfmon_length_specs, monetary_char_table, "=^+(!-", NULL, - strfmon_flag_specs, strfmon_flag_pairs, - FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L', 0, - NULL, NULL - } -}; - -/* This layer of indirection allows GCC to reassign format_types with - new data if necessary, while still allowing the original data to be - const. */ -static const format_kind_info *format_types = format_types_orig; -/* We can modify this one. We also add target-specific format types - to the end of the array. */ -static format_kind_info *dynamic_format_types; - -static int n_format_types = ARRAY_SIZE (format_types_orig); - -/* Structure detailing the results of checking a format function call - where the format expression may be a conditional expression with - many leaves resulting from nested conditional expressions. */ -typedef struct -{ - /* Number of leaves of the format argument that could not be checked - as they were not string literals. */ - int number_non_literal; - /* Number of leaves of the format argument that were null pointers or - string literals, but had extra format arguments. */ - int number_extra_args; - /* Number of leaves of the format argument that were null pointers or - string literals, but had extra format arguments and used $ operand - numbers. */ - int number_dollar_extra_args; - /* Number of leaves of the format argument that were wide string - literals. */ - int number_wide; - /* Number of leaves of the format argument that were empty strings. */ - int number_empty; - /* Number of leaves of the format argument that were unterminated - strings. */ - int number_unterminated; - /* Number of leaves of the format argument that were not counted above. */ - int number_other; -} format_check_results; - -typedef struct -{ - format_check_results *res; - function_format_info *info; - tree params; -} format_check_context; - -/* Return the format name (as specified in the original table) for the format - type indicated by format_num. */ -static const char * -format_name (int format_num) -{ - if (format_num >= 0 && format_num < n_format_types) - return format_types[format_num].name; - gcc_unreachable (); -} - -/* Return the format flags (as specified in the original table) for the format - type indicated by format_num. */ -static int -format_flags (int format_num) -{ - if (format_num >= 0 && format_num < n_format_types) - return format_types[format_num].flags; - gcc_unreachable (); -} - -static void check_format_info (function_format_info *, tree); -static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT); -static void check_format_info_main (format_check_results *, - function_format_info *, - const char *, int, tree, - unsigned HOST_WIDE_INT, alloc_pool); - -static void init_dollar_format_checking (int, tree); -static int maybe_read_dollar_number (const char **, int, - tree, tree *, const format_kind_info *); -static bool avoid_dollar_number (const char *); -static void finish_dollar_format_checking (format_check_results *, int); - -static const format_flag_spec *get_flag_spec (const format_flag_spec *, - int, const char *); - -static void check_format_types (format_wanted_type *); -static void format_type_warning (format_wanted_type *, tree, tree); - -/* Decode a format type from a string, returning the type, or - format_type_error if not valid, in which case the caller should print an - error message. */ -static int -decode_format_type (const char *s) -{ - int i; - int slen; - - s = convert_format_name_to_system_name (s); - slen = strlen (s); - for (i = 0; i < n_format_types; i++) - { - int alen; - if (!strcmp (s, format_types[i].name)) - return i; - alen = strlen (format_types[i].name); - if (slen == alen + 4 && s[0] == '_' && s[1] == '_' - && s[slen - 1] == '_' && s[slen - 2] == '_' - && !strncmp (s + 2, format_types[i].name, alen)) - return i; - } - return format_type_error; -} - - -/* Check the argument list of a call to printf, scanf, etc. - ATTRS are the attributes on the function type. There are NARGS argument - values in the array ARGARRAY. - Also, if -Wsuggest-attribute=format, - warn for calls to vprintf or vscanf in functions with no such format - attribute themselves. */ - -void -check_function_format (tree attrs, int nargs, tree *argarray) -{ - tree a; - - /* See if this function has any format attributes. */ - for (a = attrs; a; a = TREE_CHAIN (a)) - { - if (is_attribute_p ("format", TREE_PURPOSE (a))) - { - /* Yup; check it. */ - function_format_info info; - decode_format_attr (TREE_VALUE (a), &info, 1); - if (warn_format) - { - /* FIXME: Rewrite all the internal functions in this file - to use the ARGARRAY directly instead of constructing this - temporary list. */ - tree params = NULL_TREE; - int i; - for (i = nargs - 1; i >= 0; i--) - params = tree_cons (NULL_TREE, argarray[i], params); - check_format_info (&info, params); - } - if (warn_suggest_attribute_format && info.first_arg_num == 0 - && (format_types[info.format_type].flags - & (int) FMT_FLAG_ARG_CONVERT)) - { - tree c; - for (c = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)); - c; - c = TREE_CHAIN (c)) - if (is_attribute_p ("format", TREE_PURPOSE (c)) - && (decode_format_type (IDENTIFIER_POINTER - (TREE_VALUE (TREE_VALUE (c)))) - == info.format_type)) - break; - if (c == NULL_TREE) - { - /* Check if the current function has a parameter to which - the format attribute could be attached; if not, it - can't be a candidate for a format attribute, despite - the vprintf-like or vscanf-like call. */ - tree args; - for (args = DECL_ARGUMENTS (current_function_decl); - args != 0; - args = DECL_CHAIN (args)) - { - if (TREE_CODE (TREE_TYPE (args)) == POINTER_TYPE - && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args))) - == char_type_node)) - break; - } - if (args != 0) - warning (OPT_Wsuggest_attribute_format, "function might " - "be possible candidate for %qs format attribute", - format_types[info.format_type].name); - } - } - } - } -} - - -/* Variables used by the checking of $ operand number formats. */ -static char *dollar_arguments_used = NULL; -static char *dollar_arguments_pointer_p = NULL; -static int dollar_arguments_alloc = 0; -static int dollar_arguments_count; -static int dollar_first_arg_num; -static int dollar_max_arg_used; -static int dollar_format_warned; - -/* Initialize the checking for a format string that may contain $ - parameter number specifications; we will need to keep track of whether - each parameter has been used. FIRST_ARG_NUM is the number of the first - argument that is a parameter to the format, or 0 for a vprintf-style - function; PARAMS is the list of arguments starting at this argument. */ - -static void -init_dollar_format_checking (int first_arg_num, tree params) -{ - tree oparams = params; - - dollar_first_arg_num = first_arg_num; - dollar_arguments_count = 0; - dollar_max_arg_used = 0; - dollar_format_warned = 0; - if (first_arg_num > 0) - { - while (params) - { - dollar_arguments_count++; - params = TREE_CHAIN (params); - } - } - if (dollar_arguments_alloc < dollar_arguments_count) - { - free (dollar_arguments_used); - free (dollar_arguments_pointer_p); - dollar_arguments_alloc = dollar_arguments_count; - dollar_arguments_used = XNEWVEC (char, dollar_arguments_alloc); - dollar_arguments_pointer_p = XNEWVEC (char, dollar_arguments_alloc); - } - if (dollar_arguments_alloc) - { - memset (dollar_arguments_used, 0, dollar_arguments_alloc); - if (first_arg_num > 0) - { - int i = 0; - params = oparams; - while (params) - { - dollar_arguments_pointer_p[i] = (TREE_CODE (TREE_TYPE (TREE_VALUE (params))) - == POINTER_TYPE); - params = TREE_CHAIN (params); - i++; - } - } - } -} - - -/* Look for a decimal number followed by a $ in *FORMAT. If DOLLAR_NEEDED - is set, it is an error if one is not found; otherwise, it is OK. If - such a number is found, check whether it is within range and mark that - numbered operand as being used for later checking. Returns the operand - number if found and within range, zero if no such number was found and - this is OK, or -1 on error. PARAMS points to the first operand of the - format; PARAM_PTR is made to point to the parameter referred to. If - a $ format is found, *FORMAT is updated to point just after it. */ - -static int -maybe_read_dollar_number (const char **format, - int dollar_needed, tree params, tree *param_ptr, - const format_kind_info *fki) -{ - int argnum; - int overflow_flag; - const char *fcp = *format; - if (!ISDIGIT (*fcp)) - { - if (dollar_needed) - { - warning (OPT_Wformat_, "missing $ operand number in format"); - return -1; - } - else - return 0; - } - argnum = 0; - overflow_flag = 0; - while (ISDIGIT (*fcp)) - { - int nargnum; - nargnum = 10 * argnum + (*fcp - '0'); - if (nargnum < 0 || nargnum / 10 != argnum) - overflow_flag = 1; - argnum = nargnum; - fcp++; - } - if (*fcp != '$') - { - if (dollar_needed) - { - warning (OPT_Wformat_, "missing $ operand number in format"); - return -1; - } - else - return 0; - } - *format = fcp + 1; - if (pedantic && !dollar_format_warned) - { - warning (OPT_Wformat_, "%s does not support %%n$ operand number formats", - C_STD_NAME (STD_EXT)); - dollar_format_warned = 1; - } - if (overflow_flag || argnum == 0 - || (dollar_first_arg_num && argnum > dollar_arguments_count)) - { - warning (OPT_Wformat_, "operand number out of range in format"); - return -1; - } - if (argnum > dollar_max_arg_used) - dollar_max_arg_used = argnum; - /* For vprintf-style functions we may need to allocate more memory to - track which arguments are used. */ - while (dollar_arguments_alloc < dollar_max_arg_used) - { - int nalloc; - nalloc = 2 * dollar_arguments_alloc + 16; - dollar_arguments_used = XRESIZEVEC (char, dollar_arguments_used, - nalloc); - dollar_arguments_pointer_p = XRESIZEVEC (char, dollar_arguments_pointer_p, - nalloc); - memset (dollar_arguments_used + dollar_arguments_alloc, 0, - nalloc - dollar_arguments_alloc); - dollar_arguments_alloc = nalloc; - } - if (!(fki->flags & (int) FMT_FLAG_DOLLAR_MULTIPLE) - && dollar_arguments_used[argnum - 1] == 1) - { - dollar_arguments_used[argnum - 1] = 2; - warning (OPT_Wformat_, "format argument %d used more than once in %s format", - argnum, fki->name); - } - else - dollar_arguments_used[argnum - 1] = 1; - if (dollar_first_arg_num) - { - int i; - *param_ptr = params; - for (i = 1; i < argnum && *param_ptr != 0; i++) - *param_ptr = TREE_CHAIN (*param_ptr); - - /* This case shouldn't be caught here. */ - gcc_assert (*param_ptr); - } - else - *param_ptr = 0; - return argnum; -} - -/* Ensure that FORMAT does not start with a decimal number followed by - a $; give a diagnostic and return true if it does, false otherwise. */ - -static bool -avoid_dollar_number (const char *format) -{ - if (!ISDIGIT (*format)) - return false; - while (ISDIGIT (*format)) - format++; - if (*format == '$') - { - warning (OPT_Wformat_, "$ operand number used after format without operand number"); - return true; - } - return false; -} - - -/* Finish the checking for a format string that used $ operand number formats - instead of non-$ formats. We check for unused operands before used ones - (a serious error, since the implementation of the format function - can't know what types to pass to va_arg to find the later arguments). - and for unused operands at the end of the format (if we know how many - arguments the format had, so not for vprintf). If there were operand - numbers out of range on a non-vprintf-style format, we won't have reached - here. If POINTER_GAP_OK, unused arguments are OK if all arguments are - pointers. */ - -static void -finish_dollar_format_checking (format_check_results *res, int pointer_gap_ok) -{ - int i; - bool found_pointer_gap = false; - for (i = 0; i < dollar_max_arg_used; i++) - { - if (!dollar_arguments_used[i]) - { - if (pointer_gap_ok && (dollar_first_arg_num == 0 - || dollar_arguments_pointer_p[i])) - found_pointer_gap = true; - else - warning (OPT_Wformat_, - "format argument %d unused before used argument %d in $-style format", - i + 1, dollar_max_arg_used); - } - } - if (found_pointer_gap - || (dollar_first_arg_num - && dollar_max_arg_used < dollar_arguments_count)) - { - res->number_other--; - res->number_dollar_extra_args++; - } -} - - -/* Retrieve the specification for a format flag. SPEC contains the - specifications for format flags for the applicable kind of format. - FLAG is the flag in question. If PREDICATES is NULL, the basic - spec for that flag must be retrieved and must exist. If - PREDICATES is not NULL, it is a string listing possible predicates - for the spec entry; if an entry predicated on any of these is - found, it is returned, otherwise NULL is returned. */ - -static const format_flag_spec * -get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates) -{ - int i; - for (i = 0; spec[i].flag_char != 0; i++) - { - if (spec[i].flag_char != flag) - continue; - if (predicates != NULL) - { - if (spec[i].predicate != 0 - && strchr (predicates, spec[i].predicate) != 0) - return &spec[i]; - } - else if (spec[i].predicate == 0) - return &spec[i]; - } - gcc_assert (predicates); - return NULL; -} - - -/* Check the argument list of a call to printf, scanf, etc. - INFO points to the function_format_info structure. - PARAMS is the list of argument values. */ - -static void -check_format_info (function_format_info *info, tree params) -{ - format_check_context format_ctx; - unsigned HOST_WIDE_INT arg_num; - tree format_tree; - format_check_results res; - /* Skip to format argument. If the argument isn't available, there's - no work for us to do; prototype checking will catch the problem. */ - for (arg_num = 1; ; ++arg_num) - { - if (params == 0) - return; - if (arg_num == info->format_num) - break; - params = TREE_CHAIN (params); - } - format_tree = TREE_VALUE (params); - params = TREE_CHAIN (params); - if (format_tree == 0) - return; - - res.number_non_literal = 0; - res.number_extra_args = 0; - res.number_dollar_extra_args = 0; - res.number_wide = 0; - res.number_empty = 0; - res.number_unterminated = 0; - res.number_other = 0; - - format_ctx.res = &res; - format_ctx.info = info; - format_ctx.params = params; - - check_function_arguments_recurse (check_format_arg, &format_ctx, - format_tree, arg_num); - - if (res.number_non_literal > 0) - { - /* Functions taking a va_list normally pass a non-literal format - string. These functions typically are declared with - first_arg_num == 0, so avoid warning in those cases. */ - if (!(format_types[info->format_type].flags & (int) FMT_FLAG_ARG_CONVERT)) - { - /* For strftime-like formats, warn for not checking the format - string; but there are no arguments to check. */ - warning (OPT_Wformat_nonliteral, - "format not a string literal, format string not checked"); - } - else if (info->first_arg_num != 0) - { - /* If there are no arguments for the format at all, we may have - printf (foo) which is likely to be a security hole. */ - while (arg_num + 1 < info->first_arg_num) - { - if (params == 0) - break; - params = TREE_CHAIN (params); - ++arg_num; - } - if (params == 0 && warn_format_security) - warning (OPT_Wformat_security, - "format not a string literal and no format arguments"); - else if (params == 0 && warn_format_nonliteral) - warning (OPT_Wformat_nonliteral, - "format not a string literal and no format arguments"); - else - warning (OPT_Wformat_nonliteral, - "format not a string literal, argument types not checked"); - } - } - - /* If there were extra arguments to the format, normally warn. However, - the standard does say extra arguments are ignored, so in the specific - case where we have multiple leaves (conditional expressions or - ngettext) allow extra arguments if at least one leaf didn't have extra - arguments, but was otherwise OK (either non-literal or checked OK). - If the format is an empty string, this should be counted similarly to the - case of extra format arguments. */ - if (res.number_extra_args > 0 && res.number_non_literal == 0 - && res.number_other == 0) - warning (OPT_Wformat_extra_args, "too many arguments for format"); - if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0 - && res.number_other == 0) - warning (OPT_Wformat_extra_args, "unused arguments in $-style format"); - if (res.number_empty > 0 && res.number_non_literal == 0 - && res.number_other == 0) - warning (OPT_Wformat_zero_length, "zero-length %s format string", - format_types[info->format_type].name); - - if (res.number_wide > 0) - warning (OPT_Wformat_, "format is a wide character string"); - - if (res.number_unterminated > 0) - warning (OPT_Wformat_, "unterminated format string"); -} - -/* Callback from check_function_arguments_recurse to check a - format string. FORMAT_TREE is the format parameter. ARG_NUM - is the number of the format argument. CTX points to a - format_check_context. */ - -static void -check_format_arg (void *ctx, tree format_tree, - unsigned HOST_WIDE_INT arg_num) -{ - format_check_context *format_ctx = (format_check_context *) ctx; - format_check_results *res = format_ctx->res; - function_format_info *info = format_ctx->info; - tree params = format_ctx->params; - - int format_length; - HOST_WIDE_INT offset; - const char *format_chars; - tree array_size = 0; - tree array_init; - alloc_pool fwt_pool; - - if (integer_zerop (format_tree)) - { - /* Skip to first argument to check, so we can see if this format - has any arguments (it shouldn't). */ - while (arg_num + 1 < info->first_arg_num) - { - if (params == 0) - return; - params = TREE_CHAIN (params); - ++arg_num; - } - - if (params == 0) - res->number_other++; - else - res->number_extra_args++; - - return; - } - - offset = 0; - if (TREE_CODE (format_tree) == POINTER_PLUS_EXPR) - { - tree arg0, arg1; - - arg0 = TREE_OPERAND (format_tree, 0); - arg1 = TREE_OPERAND (format_tree, 1); - STRIP_NOPS (arg0); - STRIP_NOPS (arg1); - if (TREE_CODE (arg1) == INTEGER_CST) - format_tree = arg0; - else - { - res->number_non_literal++; - return; - } - if (!host_integerp (arg1, 0) - || (offset = tree_low_cst (arg1, 0)) < 0) - { - res->number_non_literal++; - return; - } - } - if (TREE_CODE (format_tree) != ADDR_EXPR) - { - res->number_non_literal++; - return; - } - format_tree = TREE_OPERAND (format_tree, 0); - if (format_types[info->format_type].flags - & (int) FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL) - { - bool objc_str = (info->format_type == gcc_objc_string_format_type); - /* We cannot examine this string here - but we can check that it is - a valid type. */ - if (TREE_CODE (format_tree) != CONST_DECL - || !((objc_str && objc_string_ref_type_p (TREE_TYPE (format_tree))) - || (*targetcm.string_object_ref_type_p) - ((const_tree) TREE_TYPE (format_tree)))) - { - res->number_non_literal++; - return; - } - /* Skip to first argument to check. */ - while (arg_num + 1 < info->first_arg_num) - { - if (params == 0) - return; - params = TREE_CHAIN (params); - ++arg_num; - } - /* So, we have a valid literal string object and one or more params. - We need to use an external helper to parse the string into format - info. For Objective-C variants we provide the resource within the - objc tree, for target variants, via a hook. */ - if (objc_str) - objc_check_format_arg (format_tree, params); - else if (targetcm.check_string_object_format_arg) - (*targetcm.check_string_object_format_arg) (format_tree, params); - /* Else we can't handle it and retire quietly. */ - return; - } - if (TREE_CODE (format_tree) == ARRAY_REF - && host_integerp (TREE_OPERAND (format_tree, 1), 0) - && (offset += tree_low_cst (TREE_OPERAND (format_tree, 1), 0)) >= 0) - format_tree = TREE_OPERAND (format_tree, 0); - if (TREE_CODE (format_tree) == VAR_DECL - && TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE - && (array_init = decl_constant_value (format_tree)) != format_tree - && TREE_CODE (array_init) == STRING_CST) - { - /* Extract the string constant initializer. Note that this may include - a trailing NUL character that is not in the array (e.g. - const char a[3] = "foo";). */ - array_size = DECL_SIZE_UNIT (format_tree); - format_tree = array_init; - } - if (TREE_CODE (format_tree) != STRING_CST) - { - res->number_non_literal++; - return; - } - if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node) - { - res->number_wide++; - return; - } - format_chars = TREE_STRING_POINTER (format_tree); - format_length = TREE_STRING_LENGTH (format_tree); - if (array_size != 0) - { - /* Variable length arrays can't be initialized. */ - gcc_assert (TREE_CODE (array_size) == INTEGER_CST); - - if (host_integerp (array_size, 0)) - { - HOST_WIDE_INT array_size_value = TREE_INT_CST_LOW (array_size); - if (array_size_value > 0 - && array_size_value == (int) array_size_value - && format_length > array_size_value) - format_length = array_size_value; - } - } - if (offset) - { - if (offset >= format_length) - { - res->number_non_literal++; - return; - } - format_chars += offset; - format_length -= offset; - } - if (format_length < 1 || format_chars[--format_length] != 0) - { - res->number_unterminated++; - return; - } - if (format_length == 0) - { - res->number_empty++; - return; - } - - /* Skip to first argument to check. */ - while (arg_num + 1 < info->first_arg_num) - { - if (params == 0) - return; - params = TREE_CHAIN (params); - ++arg_num; - } - /* Provisionally increment res->number_other; check_format_info_main - will decrement it if it finds there are extra arguments, but this way - need not adjust it for every return. */ - res->number_other++; - fwt_pool = create_alloc_pool ("format_wanted_type pool", - sizeof (format_wanted_type), 10); - check_format_info_main (res, info, format_chars, format_length, - params, arg_num, fwt_pool); - free_alloc_pool (fwt_pool); -} - - -/* Do the main part of checking a call to a format function. FORMAT_CHARS - is the NUL-terminated format string (which at this point may contain - internal NUL characters); FORMAT_LENGTH is its length (excluding the - terminating NUL character). ARG_NUM is one less than the number of - the first format argument to check; PARAMS points to that format - argument in the list of arguments. */ - -static void -check_format_info_main (format_check_results *res, - function_format_info *info, const char *format_chars, - int format_length, tree params, - unsigned HOST_WIDE_INT arg_num, alloc_pool fwt_pool) -{ - const char *orig_format_chars = format_chars; - tree first_fillin_param = params; - - const format_kind_info *fki = &format_types[info->format_type]; - const format_flag_spec *flag_specs = fki->flag_specs; - const format_flag_pair *bad_flag_pairs = fki->bad_flag_pairs; - - /* -1 if no conversions taking an operand have been found; 0 if one has - and it didn't use $; 1 if $ formats are in use. */ - int has_operand_number = -1; - - init_dollar_format_checking (info->first_arg_num, first_fillin_param); - - while (*format_chars != 0) - { - int i; - int suppressed = FALSE; - const char *length_chars = NULL; - enum format_lengths length_chars_val = FMT_LEN_none; - enum format_std_version length_chars_std = STD_C89; - int format_char; - tree cur_param; - tree wanted_type; - int main_arg_num = 0; - tree main_arg_params = 0; - enum format_std_version wanted_type_std; - const char *wanted_type_name; - format_wanted_type width_wanted_type; - format_wanted_type precision_wanted_type; - format_wanted_type main_wanted_type; - format_wanted_type *first_wanted_type = NULL; - format_wanted_type *last_wanted_type = NULL; - const format_length_info *fli = NULL; - const format_char_info *fci = NULL; - char flag_chars[256]; - int alloc_flag = 0; - int scalar_identity_flag = 0; - const char *format_start; - - if (*format_chars++ != '%') - continue; - if (*format_chars == 0) - { - warning (OPT_Wformat_, "spurious trailing %<%%%> in format"); - continue; - } - if (*format_chars == '%') - { - ++format_chars; - continue; - } - flag_chars[0] = 0; - - if ((fki->flags & (int) FMT_FLAG_USE_DOLLAR) && has_operand_number != 0) - { - /* Possibly read a $ operand number at the start of the format. - If one was previously used, one is required here. If one - is not used here, we can't immediately conclude this is a - format without them, since it could be printf %m or scanf %*. */ - int opnum; - opnum = maybe_read_dollar_number (&format_chars, 0, - first_fillin_param, - &main_arg_params, fki); - if (opnum == -1) - return; - else if (opnum > 0) - { - has_operand_number = 1; - main_arg_num = opnum + info->first_arg_num - 1; - } - } - else if (fki->flags & FMT_FLAG_USE_DOLLAR) - { - if (avoid_dollar_number (format_chars)) - return; - } - - /* Read any format flags, but do not yet validate them beyond removing - duplicates, since in general validation depends on the rest of - the format. */ - while (*format_chars != 0 - && strchr (fki->flag_chars, *format_chars) != 0) - { - const format_flag_spec *s = get_flag_spec (flag_specs, - *format_chars, NULL); - if (strchr (flag_chars, *format_chars) != 0) - { - warning (OPT_Wformat_, "repeated %s in format", _(s->name)); - } - else - { - i = strlen (flag_chars); - flag_chars[i++] = *format_chars; - flag_chars[i] = 0; - } - if (s->skip_next_char) - { - ++format_chars; - if (*format_chars == 0) - { - warning (OPT_Wformat_, "missing fill character at end of strfmon format"); - return; - } - } - ++format_chars; - } - - /* Read any format width, possibly * or *m$. */ - if (fki->width_char != 0) - { - if (fki->width_type != NULL && *format_chars == '*') - { - i = strlen (flag_chars); - flag_chars[i++] = fki->width_char; - flag_chars[i] = 0; - /* "...a field width...may be indicated by an asterisk. - In this case, an int argument supplies the field width..." */ - ++format_chars; - if (has_operand_number != 0) - { - int opnum; - opnum = maybe_read_dollar_number (&format_chars, - has_operand_number == 1, - first_fillin_param, - ¶ms, fki); - if (opnum == -1) - return; - else if (opnum > 0) - { - has_operand_number = 1; - arg_num = opnum + info->first_arg_num - 1; - } - else - has_operand_number = 0; - } - else - { - if (avoid_dollar_number (format_chars)) - return; - } - if (info->first_arg_num != 0) - { - if (params == 0) - cur_param = NULL; - else - { - cur_param = TREE_VALUE (params); - if (has_operand_number <= 0) - { - params = TREE_CHAIN (params); - ++arg_num; - } - } - width_wanted_type.wanted_type = *fki->width_type; - width_wanted_type.wanted_type_name = NULL; - width_wanted_type.pointer_count = 0; - width_wanted_type.char_lenient_flag = 0; - width_wanted_type.scalar_identity_flag = 0; - width_wanted_type.writing_in_flag = 0; - width_wanted_type.reading_from_flag = 0; - width_wanted_type.kind = CF_KIND_FIELD_WIDTH; - width_wanted_type.format_start = format_chars - 1; - width_wanted_type.format_length = 1; - width_wanted_type.param = cur_param; - width_wanted_type.arg_num = arg_num; - width_wanted_type.next = NULL; - if (last_wanted_type != 0) - last_wanted_type->next = &width_wanted_type; - if (first_wanted_type == 0) - first_wanted_type = &width_wanted_type; - last_wanted_type = &width_wanted_type; - } - } - else - { - /* Possibly read a numeric width. If the width is zero, - we complain if appropriate. */ - int non_zero_width_char = FALSE; - int found_width = FALSE; - while (ISDIGIT (*format_chars)) - { - found_width = TRUE; - if (*format_chars != '0') - non_zero_width_char = TRUE; - ++format_chars; - } - if (found_width && !non_zero_width_char && - (fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD)) - warning (OPT_Wformat_, "zero width in %s format", fki->name); - if (found_width) - { - i = strlen (flag_chars); - flag_chars[i++] = fki->width_char; - flag_chars[i] = 0; - } - } - } - - /* Read any format left precision (must be a number, not *). */ - if (fki->left_precision_char != 0 && *format_chars == '#') - { - ++format_chars; - i = strlen (flag_chars); - flag_chars[i++] = fki->left_precision_char; - flag_chars[i] = 0; - if (!ISDIGIT (*format_chars)) - warning (OPT_Wformat_, "empty left precision in %s format", fki->name); - while (ISDIGIT (*format_chars)) - ++format_chars; - } - - /* Read any format precision, possibly * or *m$. */ - if (fki->precision_char != 0 && *format_chars == '.') - { - ++format_chars; - i = strlen (flag_chars); - flag_chars[i++] = fki->precision_char; - flag_chars[i] = 0; - if (fki->precision_type != NULL && *format_chars == '*') - { - /* "...a...precision...may be indicated by an asterisk. - In this case, an int argument supplies the...precision." */ - ++format_chars; - if (has_operand_number != 0) - { - int opnum; - opnum = maybe_read_dollar_number (&format_chars, - has_operand_number == 1, - first_fillin_param, - ¶ms, fki); - if (opnum == -1) - return; - else if (opnum > 0) - { - has_operand_number = 1; - arg_num = opnum + info->first_arg_num - 1; - } - else - has_operand_number = 0; - } - else - { - if (avoid_dollar_number (format_chars)) - return; - } - if (info->first_arg_num != 0) - { - if (params == 0) - cur_param = NULL; - else - { - cur_param = TREE_VALUE (params); - if (has_operand_number <= 0) - { - params = TREE_CHAIN (params); - ++arg_num; - } - } - precision_wanted_type.wanted_type = *fki->precision_type; - precision_wanted_type.wanted_type_name = NULL; - precision_wanted_type.pointer_count = 0; - precision_wanted_type.char_lenient_flag = 0; - precision_wanted_type.scalar_identity_flag = 0; - precision_wanted_type.writing_in_flag = 0; - precision_wanted_type.reading_from_flag = 0; - precision_wanted_type.kind = CF_KIND_FIELD_PRECISION; - precision_wanted_type.param = cur_param; - precision_wanted_type.format_start = format_chars - 2; - precision_wanted_type.format_length = 2; - precision_wanted_type.arg_num = arg_num; - precision_wanted_type.next = NULL; - if (last_wanted_type != 0) - last_wanted_type->next = &precision_wanted_type; - if (first_wanted_type == 0) - first_wanted_type = &precision_wanted_type; - last_wanted_type = &precision_wanted_type; - } - } - else - { - if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK) - && !ISDIGIT (*format_chars)) - warning (OPT_Wformat_, "empty precision in %s format", fki->name); - while (ISDIGIT (*format_chars)) - ++format_chars; - } - } - - format_start = format_chars; - if (fki->alloc_char && fki->alloc_char == *format_chars) - { - i = strlen (flag_chars); - flag_chars[i++] = fki->alloc_char; - flag_chars[i] = 0; - format_chars++; - } - - /* Handle the scanf allocation kludge. */ - if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE) - { - if (*format_chars == 'a' && !flag_isoc99) - { - if (format_chars[1] == 's' || format_chars[1] == 'S' - || format_chars[1] == '[') - { - /* 'a' is used as a flag. */ - i = strlen (flag_chars); - flag_chars[i++] = 'a'; - flag_chars[i] = 0; - format_chars++; - } - } - } - - /* Read any length modifier, if this kind of format has them. */ - fli = fki->length_char_specs; - length_chars = NULL; - length_chars_val = FMT_LEN_none; - length_chars_std = STD_C89; - scalar_identity_flag = 0; - if (fli) - { - while (fli->name != 0 - && strncmp (fli->name, format_chars, strlen (fli->name))) - fli++; - if (fli->name != 0) - { - format_chars += strlen (fli->name); - if (fli->double_name != 0 && fli->name[0] == *format_chars) - { - format_chars++; - length_chars = fli->double_name; - length_chars_val = fli->double_index; - length_chars_std = fli->double_std; - } - else - { - length_chars = fli->name; - length_chars_val = fli->index; - length_chars_std = fli->std; - scalar_identity_flag = fli->scalar_identity_flag; - } - i = strlen (flag_chars); - flag_chars[i++] = fki->length_code_char; - flag_chars[i] = 0; - } - if (pedantic) - { - /* Warn if the length modifier is non-standard. */ - if (ADJ_STD (length_chars_std) > C_STD_VER) - warning (OPT_Wformat_, - "%s does not support the %qs %s length modifier", - C_STD_NAME (length_chars_std), length_chars, - fki->name); - } - } - - /* Read any modifier (strftime E/O). */ - if (fki->modifier_chars != NULL) - { - while (*format_chars != 0 - && strchr (fki->modifier_chars, *format_chars) != 0) - { - if (strchr (flag_chars, *format_chars) != 0) - { - const format_flag_spec *s = get_flag_spec (flag_specs, - *format_chars, NULL); - warning (OPT_Wformat_, "repeated %s in format", _(s->name)); - } - else - { - i = strlen (flag_chars); - flag_chars[i++] = *format_chars; - flag_chars[i] = 0; - } - ++format_chars; - } - } - - format_char = *format_chars; - if (format_char == 0 - || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK) - && format_char == '%')) - { - warning (OPT_Wformat_, "conversion lacks type at end of format"); - continue; - } - format_chars++; - fci = fki->conversion_specs; - while (fci->format_chars != 0 - && strchr (fci->format_chars, format_char) == 0) - ++fci; - if (fci->format_chars == 0) - { - if (ISGRAPH (format_char)) - warning (OPT_Wformat_, "unknown conversion type character %qc in format", - format_char); - else - warning (OPT_Wformat_, "unknown conversion type character 0x%x in format", - format_char); - continue; - } - if (pedantic) - { - if (ADJ_STD (fci->std) > C_STD_VER) - warning (OPT_Wformat_, "%s does not support the %<%%%c%> %s format", - C_STD_NAME (fci->std), format_char, fki->name); - } - - /* Validate the individual flags used, removing any that are invalid. */ - { - int d = 0; - for (i = 0; flag_chars[i] != 0; i++) - { - const format_flag_spec *s = get_flag_spec (flag_specs, - flag_chars[i], NULL); - flag_chars[i - d] = flag_chars[i]; - if (flag_chars[i] == fki->length_code_char) - continue; - if (strchr (fci->flag_chars, flag_chars[i]) == 0) - { - warning (OPT_Wformat_, "%s used with %<%%%c%> %s format", - _(s->name), format_char, fki->name); - d++; - continue; - } - if (pedantic) - { - const format_flag_spec *t; - if (ADJ_STD (s->std) > C_STD_VER) - warning (OPT_Wformat_, "%s does not support %s", - C_STD_NAME (s->std), _(s->long_name)); - t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2); - if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std)) - { - const char *long_name = (t->long_name != NULL - ? t->long_name - : s->long_name); - if (ADJ_STD (t->std) > C_STD_VER) - warning (OPT_Wformat_, - "%s does not support %s with the %<%%%c%> %s format", - C_STD_NAME (t->std), _(long_name), - format_char, fki->name); - } - } - } - flag_chars[i - d] = 0; - } - - if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE) - && strchr (flag_chars, 'a') != 0) - alloc_flag = 1; - if (fki->alloc_char && strchr (flag_chars, fki->alloc_char) != 0) - alloc_flag = 1; - - if (fki->suppression_char - && strchr (flag_chars, fki->suppression_char) != 0) - suppressed = 1; - - /* Validate the pairs of flags used. */ - for (i = 0; bad_flag_pairs[i].flag_char1 != 0; i++) - { - const format_flag_spec *s, *t; - if (strchr (flag_chars, bad_flag_pairs[i].flag_char1) == 0) - continue; - if (strchr (flag_chars, bad_flag_pairs[i].flag_char2) == 0) - continue; - if (bad_flag_pairs[i].predicate != 0 - && strchr (fci->flags2, bad_flag_pairs[i].predicate) == 0) - continue; - s = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char1, NULL); - t = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char2, NULL); - if (bad_flag_pairs[i].ignored) - { - if (bad_flag_pairs[i].predicate != 0) - warning (OPT_Wformat_, - "%s ignored with %s and %<%%%c%> %s format", - _(s->name), _(t->name), format_char, - fki->name); - else - warning (OPT_Wformat_, "%s ignored with %s in %s format", - _(s->name), _(t->name), fki->name); - } - else - { - if (bad_flag_pairs[i].predicate != 0) - warning (OPT_Wformat_, - "use of %s and %s together with %<%%%c%> %s format", - _(s->name), _(t->name), format_char, - fki->name); - else - warning (OPT_Wformat_, "use of %s and %s together in %s format", - _(s->name), _(t->name), fki->name); - } - } - - /* Give Y2K warnings. */ - if (warn_format_y2k) - { - int y2k_level = 0; - if (strchr (fci->flags2, '4') != 0) - if (strchr (flag_chars, 'E') != 0) - y2k_level = 3; - else - y2k_level = 2; - else if (strchr (fci->flags2, '3') != 0) - y2k_level = 3; - else if (strchr (fci->flags2, '2') != 0) - y2k_level = 2; - if (y2k_level == 3) - warning (OPT_Wformat_y2k, "%<%%%c%> yields only last 2 digits of " - "year in some locales", format_char); - else if (y2k_level == 2) - warning (OPT_Wformat_y2k, "%<%%%c%> yields only last 2 digits of " - "year", format_char); - } - - if (strchr (fci->flags2, '[') != 0) - { - /* Skip over scan set, in case it happens to have '%' in it. */ - if (*format_chars == '^') - ++format_chars; - /* Find closing bracket; if one is hit immediately, then - it's part of the scan set rather than a terminator. */ - if (*format_chars == ']') - ++format_chars; - while (*format_chars && *format_chars != ']') - ++format_chars; - if (*format_chars != ']') - /* The end of the format string was reached. */ - warning (OPT_Wformat_, "no closing %<]%> for %<%%[%> format"); - } - - wanted_type = 0; - wanted_type_name = 0; - if (fki->flags & (int) FMT_FLAG_ARG_CONVERT) - { - wanted_type = (fci->types[length_chars_val].type - ? *fci->types[length_chars_val].type : 0); - wanted_type_name = fci->types[length_chars_val].name; - wanted_type_std = fci->types[length_chars_val].std; - if (wanted_type == 0) - { - warning (OPT_Wformat_, - "use of %qs length modifier with %qc type character", - length_chars, format_char); - /* Heuristic: skip one argument when an invalid length/type - combination is encountered. */ - arg_num++; - if (params != 0) - params = TREE_CHAIN (params); - continue; - } - else if (pedantic - /* Warn if non-standard, provided it is more non-standard - than the length and type characters that may already - have been warned for. */ - && ADJ_STD (wanted_type_std) > ADJ_STD (length_chars_std) - && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std)) - { - if (ADJ_STD (wanted_type_std) > C_STD_VER) - warning (OPT_Wformat_, - "%s does not support the %<%%%s%c%> %s format", - C_STD_NAME (wanted_type_std), length_chars, - format_char, fki->name); - } - } - - main_wanted_type.next = NULL; - - /* Finally. . .check type of argument against desired type! */ - if (info->first_arg_num == 0) - continue; - if ((fci->pointer_count == 0 && wanted_type == void_type_node) - || suppressed) - { - if (main_arg_num != 0) - { - if (suppressed) - warning (OPT_Wformat_, "operand number specified with " - "suppressed assignment"); - else - warning (OPT_Wformat_, "operand number specified for format " - "taking no argument"); - } - } - else - { - format_wanted_type *wanted_type_ptr; - - if (main_arg_num != 0) - { - arg_num = main_arg_num; - params = main_arg_params; - } - else - { - ++arg_num; - if (has_operand_number > 0) - { - warning (OPT_Wformat_, "missing $ operand number in format"); - return; - } - else - has_operand_number = 0; - } - - wanted_type_ptr = &main_wanted_type; - while (fci) - { - if (params == 0) - cur_param = NULL; - else - { - cur_param = TREE_VALUE (params); - params = TREE_CHAIN (params); - } - - wanted_type_ptr->wanted_type = wanted_type; - wanted_type_ptr->wanted_type_name = wanted_type_name; - wanted_type_ptr->pointer_count = fci->pointer_count + alloc_flag; - wanted_type_ptr->char_lenient_flag = 0; - if (strchr (fci->flags2, 'c') != 0) - wanted_type_ptr->char_lenient_flag = 1; - wanted_type_ptr->scalar_identity_flag = 0; - if (scalar_identity_flag) - wanted_type_ptr->scalar_identity_flag = 1; - wanted_type_ptr->writing_in_flag = 0; - wanted_type_ptr->reading_from_flag = 0; - if (alloc_flag) - wanted_type_ptr->writing_in_flag = 1; - else - { - if (strchr (fci->flags2, 'W') != 0) - wanted_type_ptr->writing_in_flag = 1; - if (strchr (fci->flags2, 'R') != 0) - wanted_type_ptr->reading_from_flag = 1; - } - wanted_type_ptr->kind = CF_KIND_FORMAT; - wanted_type_ptr->param = cur_param; - wanted_type_ptr->arg_num = arg_num; - wanted_type_ptr->format_start = format_start; - wanted_type_ptr->format_length = format_chars - format_start; - wanted_type_ptr->next = NULL; - if (last_wanted_type != 0) - last_wanted_type->next = wanted_type_ptr; - if (first_wanted_type == 0) - first_wanted_type = wanted_type_ptr; - last_wanted_type = wanted_type_ptr; - - fci = fci->chain; - if (fci) - { - wanted_type_ptr = (format_wanted_type *) - pool_alloc (fwt_pool); - arg_num++; - wanted_type = *fci->types[length_chars_val].type; - wanted_type_name = fci->types[length_chars_val].name; - } - } - } - - if (first_wanted_type != 0) - check_format_types (first_wanted_type); - } - - if (format_chars - orig_format_chars != format_length) - warning (OPT_Wformat_contains_nul, "embedded %<\\0%> in format"); - if (info->first_arg_num != 0 && params != 0 - && has_operand_number <= 0) - { - res->number_other--; - res->number_extra_args++; - } - if (has_operand_number > 0) - finish_dollar_format_checking (res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK); -} - - -/* Check the argument types from a single format conversion (possibly - including width and precision arguments). */ -static void -check_format_types (format_wanted_type *types) -{ - for (; types != 0; types = types->next) - { - tree cur_param; - tree cur_type; - tree orig_cur_type; - tree wanted_type; - int arg_num; - int i; - int char_type_flag; - - wanted_type = types->wanted_type; - arg_num = types->arg_num; - - /* The following should not occur here. */ - gcc_assert (wanted_type); - gcc_assert (wanted_type != void_type_node || types->pointer_count); - - if (types->pointer_count == 0) - wanted_type = lang_hooks.types.type_promotes_to (wanted_type); - - wanted_type = TYPE_MAIN_VARIANT (wanted_type); - - cur_param = types->param; - if (!cur_param) - { - format_type_warning (types, wanted_type, NULL); - continue; - } - - cur_type = TREE_TYPE (cur_param); - if (cur_type == error_mark_node) - continue; - orig_cur_type = cur_type; - char_type_flag = 0; - - STRIP_NOPS (cur_param); - - /* Check the types of any additional pointer arguments - that precede the "real" argument. */ - for (i = 0; i < types->pointer_count; ++i) - { - if (TREE_CODE (cur_type) == POINTER_TYPE) - { - cur_type = TREE_TYPE (cur_type); - if (cur_type == error_mark_node) - break; - - /* Check for writing through a NULL pointer. */ - if (types->writing_in_flag - && i == 0 - && cur_param != 0 - && integer_zerop (cur_param)) - warning (OPT_Wformat_, "writing through null pointer " - "(argument %d)", arg_num); - - /* Check for reading through a NULL pointer. */ - if (types->reading_from_flag - && i == 0 - && cur_param != 0 - && integer_zerop (cur_param)) - warning (OPT_Wformat_, "reading through null pointer " - "(argument %d)", arg_num); - - if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR) - cur_param = TREE_OPERAND (cur_param, 0); - else - cur_param = 0; - - /* See if this is an attempt to write into a const type with - scanf or with printf "%n". Note: the writing in happens - at the first indirection only, if for example - void * const * is passed to scanf %p; passing - const void ** is simply passing an incompatible type. */ - if (types->writing_in_flag - && i == 0 - && (TYPE_READONLY (cur_type) - || (cur_param != 0 - && (CONSTANT_CLASS_P (cur_param) - || (DECL_P (cur_param) - && TREE_READONLY (cur_param)))))) - warning (OPT_Wformat_, "writing into constant object " - "(argument %d)", arg_num); - - /* If there are extra type qualifiers beyond the first - indirection, then this makes the types technically - incompatible. */ - if (i > 0 - && pedantic - && (TYPE_READONLY (cur_type) - || TYPE_VOLATILE (cur_type) - || TYPE_RESTRICT (cur_type))) - warning (OPT_Wformat_, "extra type qualifiers in format " - "argument (argument %d)", - arg_num); - - } - else - { - format_type_warning (types, wanted_type, orig_cur_type); - break; - } - } - - if (i < types->pointer_count) - continue; - - cur_type = TYPE_MAIN_VARIANT (cur_type); - - /* Check whether the argument type is a character type. This leniency - only applies to certain formats, flagged with 'c'. - */ - if (types->char_lenient_flag) - char_type_flag = (cur_type == char_type_node - || cur_type == signed_char_type_node - || cur_type == unsigned_char_type_node); - - /* Check the type of the "real" argument, if there's a type we want. */ - if (lang_hooks.types_compatible_p (wanted_type, cur_type)) - continue; - /* If we want 'void *', allow any pointer type. - (Anything else would already have got a warning.) - With -Wpedantic, only allow pointers to void and to character - types. */ - if (wanted_type == void_type_node - && (!pedantic || (i == 1 && char_type_flag))) - continue; - /* Don't warn about differences merely in signedness, unless - -Wpedantic. With -Wpedantic, warn if the type is a pointer - target and not a character type, and for character types at - a second level of indirection. */ - if (TREE_CODE (wanted_type) == INTEGER_TYPE - && TREE_CODE (cur_type) == INTEGER_TYPE - && (!pedantic || i == 0 || (i == 1 && char_type_flag)) - && (TYPE_UNSIGNED (wanted_type) - ? wanted_type == c_common_unsigned_type (cur_type) - : wanted_type == c_common_signed_type (cur_type))) - continue; - /* Likewise, "signed char", "unsigned char" and "char" are - equivalent but the above test won't consider them equivalent. */ - if (wanted_type == char_type_node - && (!pedantic || i < 2) - && char_type_flag) - continue; - if (types->scalar_identity_flag - && (TREE_CODE (cur_type) == TREE_CODE (wanted_type) - || (INTEGRAL_TYPE_P (cur_type) - && INTEGRAL_TYPE_P (wanted_type))) - && TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type)) - continue; - /* Now we have a type mismatch. */ - format_type_warning (types, wanted_type, orig_cur_type); - } -} - - -/* Give a warning about a format argument of different type from that - expected. WANTED_TYPE is the type the argument should have, possibly - stripped of pointer dereferences. The description (such as "field - precision"), the placement in the format string, a possibly more - friendly name of WANTED_TYPE, and the number of pointer dereferences - are taken from TYPE. ARG_TYPE is the type of the actual argument, - or NULL if it is missing. */ -static void -format_type_warning (format_wanted_type *type, tree wanted_type, tree arg_type) -{ - int kind = type->kind; - const char *wanted_type_name = type->wanted_type_name; - const char *format_start = type->format_start; - int format_length = type->format_length; - int pointer_count = type->pointer_count; - int arg_num = type->arg_num; - - char *p; - /* If ARG_TYPE is a typedef with a misleading name (for example, - size_t but not the standard size_t expected by printf %zu), avoid - printing the typedef name. */ - if (wanted_type_name - && arg_type - && TYPE_NAME (arg_type) - && TREE_CODE (TYPE_NAME (arg_type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (arg_type)) - && !strcmp (wanted_type_name, - lang_hooks.decl_printable_name (TYPE_NAME (arg_type), 2))) - arg_type = TYPE_MAIN_VARIANT (arg_type); - /* The format type and name exclude any '*' for pointers, so those - must be formatted manually. For all the types we currently have, - this is adequate, but formats taking pointers to functions or - arrays would require the full type to be built up in order to - print it with %T. */ - p = (char *) alloca (pointer_count + 2); - if (pointer_count == 0) - p[0] = 0; - else if (c_dialect_cxx ()) - { - memset (p, '*', pointer_count); - p[pointer_count] = 0; - } - else - { - p[0] = ' '; - memset (p + 1, '*', pointer_count); - p[pointer_count + 1] = 0; - } - - if (wanted_type_name) - { - if (arg_type) - warning (OPT_Wformat_, "%s %<%s%.*s%> expects argument of type %<%s%s%>, " - "but argument %d has type %qT", - gettext (kind_descriptions[kind]), - (kind == CF_KIND_FORMAT ? "%" : ""), - format_length, format_start, - wanted_type_name, p, arg_num, arg_type); - else - warning (OPT_Wformat_, "%s %<%s%.*s%> expects a matching %<%s%s%> argument", - gettext (kind_descriptions[kind]), - (kind == CF_KIND_FORMAT ? "%" : ""), - format_length, format_start, wanted_type_name, p); - } - else - { - if (arg_type) - warning (OPT_Wformat_, "%s %<%s%.*s%> expects argument of type %<%T%s%>, " - "but argument %d has type %qT", - gettext (kind_descriptions[kind]), - (kind == CF_KIND_FORMAT ? "%" : ""), - format_length, format_start, - wanted_type, p, arg_num, arg_type); - else - warning (OPT_Wformat_, "%s %<%s%.*s%> expects a matching %<%T%s%> argument", - gettext (kind_descriptions[kind]), - (kind == CF_KIND_FORMAT ? "%" : ""), - format_length, format_start, wanted_type, p); - } -} - - -/* Given a format_char_info array FCI, and a character C, this function - returns the index into the conversion_specs where that specifier's - data is located. The character must exist. */ -static unsigned int -find_char_info_specifier_index (const format_char_info *fci, int c) -{ - unsigned i; - - for (i = 0; fci->format_chars; i++, fci++) - if (strchr (fci->format_chars, c)) - return i; - - /* We shouldn't be looking for a non-existent specifier. */ - gcc_unreachable (); -} - -/* Given a format_length_info array FLI, and a character C, this - function returns the index into the conversion_specs where that - modifier's data is located. The character must exist. */ -static unsigned int -find_length_info_modifier_index (const format_length_info *fli, int c) -{ - unsigned i; - - for (i = 0; fli->name; i++, fli++) - if (strchr (fli->name, c)) - return i; - - /* We shouldn't be looking for a non-existent modifier. */ - gcc_unreachable (); -} - -/* Determine the type of HOST_WIDE_INT in the code being compiled for - use in GCC's __asm_fprintf__ custom format attribute. You must - have set dynamic_format_types before calling this function. */ -static void -init_dynamic_asm_fprintf_info (void) -{ - static tree hwi; - - if (!hwi) - { - format_length_info *new_asm_fprintf_length_specs; - unsigned int i; - - /* Find the underlying type for HOST_WIDE_INT. For the %w - length modifier to work, one must have issued: "typedef - HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code - prior to using that modifier. */ - hwi = maybe_get_identifier ("__gcc_host_wide_int__"); - if (!hwi) - { - error ("%<__gcc_host_wide_int__%> is not defined as a type"); - return; - } - hwi = identifier_global_value (hwi); - if (!hwi || TREE_CODE (hwi) != TYPE_DECL) - { - error ("%<__gcc_host_wide_int__%> is not defined as a type"); - return; - } - hwi = DECL_ORIGINAL_TYPE (hwi); - gcc_assert (hwi); - if (hwi != long_integer_type_node && hwi != long_long_integer_type_node) - { - error ("%<__gcc_host_wide_int__%> is not defined as %<long%>" - " or %<long long%>"); - return; - } - - /* Create a new (writable) copy of asm_fprintf_length_specs. */ - new_asm_fprintf_length_specs = (format_length_info *) - xmemdup (asm_fprintf_length_specs, - sizeof (asm_fprintf_length_specs), - sizeof (asm_fprintf_length_specs)); - - /* HOST_WIDE_INT must be one of 'long' or 'long long'. */ - i = find_length_info_modifier_index (new_asm_fprintf_length_specs, 'w'); - if (hwi == long_integer_type_node) - new_asm_fprintf_length_specs[i].index = FMT_LEN_l; - else if (hwi == long_long_integer_type_node) - new_asm_fprintf_length_specs[i].index = FMT_LEN_ll; - else - gcc_unreachable (); - - /* Assign the new data for use. */ - dynamic_format_types[asm_fprintf_format_type].length_char_specs = - new_asm_fprintf_length_specs; - } -} - -/* Determine the type of a "locus" in the code being compiled for use - in GCC's __gcc_gfc__ custom format attribute. You must have set - dynamic_format_types before calling this function. */ -static void -init_dynamic_gfc_info (void) -{ - static tree locus; - - if (!locus) - { - static format_char_info *gfc_fci; - - /* For the GCC __gcc_gfc__ custom format specifier to work, one - must have declared 'locus' prior to using this attribute. If - we haven't seen this declarations then you shouldn't use the - specifier requiring that type. */ - if ((locus = maybe_get_identifier ("locus"))) - { - locus = identifier_global_value (locus); - if (locus) - { - if (TREE_CODE (locus) != TYPE_DECL - || TREE_TYPE (locus) == error_mark_node) - { - error ("%<locus%> is not defined as a type"); - locus = 0; - } - else - locus = TREE_TYPE (locus); - } - } - - /* Assign the new data for use. */ - - /* Handle the __gcc_gfc__ format specifics. */ - if (!gfc_fci) - dynamic_format_types[gcc_gfc_format_type].conversion_specs = - gfc_fci = (format_char_info *) - xmemdup (gcc_gfc_char_table, - sizeof (gcc_gfc_char_table), - sizeof (gcc_gfc_char_table)); - if (locus) - { - const unsigned i = find_char_info_specifier_index (gfc_fci, 'L'); - gfc_fci[i].types[0].type = &locus; - gfc_fci[i].pointer_count = 1; - } - } -} - -/* Determine the types of "tree" and "location_t" in the code being - compiled for use in GCC's diagnostic custom format attributes. You - must have set dynamic_format_types before calling this function. */ -static void -init_dynamic_diag_info (void) -{ - static tree t, loc, hwi; - - if (!loc || !t || !hwi) - { - static format_char_info *diag_fci, *tdiag_fci, *cdiag_fci, *cxxdiag_fci; - static format_length_info *diag_ls; - unsigned int i; - - /* For the GCC-diagnostics custom format specifiers to work, one - must have declared 'tree' and/or 'location_t' prior to using - those attributes. If we haven't seen these declarations then - you shouldn't use the specifiers requiring these types. - However we don't force a hard ICE because we may see only one - or the other type. */ - if ((loc = maybe_get_identifier ("location_t"))) - { - loc = identifier_global_value (loc); - if (loc) - { - if (TREE_CODE (loc) != TYPE_DECL) - { - error ("%<location_t%> is not defined as a type"); - loc = 0; - } - else - loc = TREE_TYPE (loc); - } - } - - /* We need to grab the underlying 'union tree_node' so peek into - an extra type level. */ - if ((t = maybe_get_identifier ("tree"))) - { - t = identifier_global_value (t); - if (t) - { - if (TREE_CODE (t) != TYPE_DECL) - { - error ("%<tree%> is not defined as a type"); - t = 0; - } - else if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE) - { - error ("%<tree%> is not defined as a pointer type"); - t = 0; - } - else - t = TREE_TYPE (TREE_TYPE (t)); - } - } - - /* Find the underlying type for HOST_WIDE_INT. For the %w - length modifier to work, one must have issued: "typedef - HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code - prior to using that modifier. */ - if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__"))) - { - hwi = identifier_global_value (hwi); - if (hwi) - { - if (TREE_CODE (hwi) != TYPE_DECL) - { - error ("%<__gcc_host_wide_int__%> is not defined as a type"); - hwi = 0; - } - else - { - hwi = DECL_ORIGINAL_TYPE (hwi); - gcc_assert (hwi); - if (hwi != long_integer_type_node - && hwi != long_long_integer_type_node) - { - error ("%<__gcc_host_wide_int__%> is not defined" - " as %<long%> or %<long long%>"); - hwi = 0; - } - } - } - } - - /* Assign the new data for use. */ - - /* All the GCC diag formats use the same length specs. */ - if (!diag_ls) - dynamic_format_types[gcc_diag_format_type].length_char_specs = - dynamic_format_types[gcc_tdiag_format_type].length_char_specs = - dynamic_format_types[gcc_cdiag_format_type].length_char_specs = - dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs = - diag_ls = (format_length_info *) - xmemdup (gcc_diag_length_specs, - sizeof (gcc_diag_length_specs), - sizeof (gcc_diag_length_specs)); - if (hwi) - { - /* HOST_WIDE_INT must be one of 'long' or 'long long'. */ - i = find_length_info_modifier_index (diag_ls, 'w'); - if (hwi == long_integer_type_node) - diag_ls[i].index = FMT_LEN_l; - else if (hwi == long_long_integer_type_node) - diag_ls[i].index = FMT_LEN_ll; - else - gcc_unreachable (); - } - - /* Handle the __gcc_diag__ format specifics. */ - if (!diag_fci) - dynamic_format_types[gcc_diag_format_type].conversion_specs = - diag_fci = (format_char_info *) - xmemdup (gcc_diag_char_table, - sizeof (gcc_diag_char_table), - sizeof (gcc_diag_char_table)); - if (t) - { - i = find_char_info_specifier_index (diag_fci, 'K'); - diag_fci[i].types[0].type = &t; - diag_fci[i].pointer_count = 1; - } - - /* Handle the __gcc_tdiag__ format specifics. */ - if (!tdiag_fci) - dynamic_format_types[gcc_tdiag_format_type].conversion_specs = - tdiag_fci = (format_char_info *) - xmemdup (gcc_tdiag_char_table, - sizeof (gcc_tdiag_char_table), - sizeof (gcc_tdiag_char_table)); - if (t) - { - /* All specifiers taking a tree share the same struct. */ - i = find_char_info_specifier_index (tdiag_fci, 'D'); - tdiag_fci[i].types[0].type = &t; - tdiag_fci[i].pointer_count = 1; - i = find_char_info_specifier_index (tdiag_fci, 'K'); - tdiag_fci[i].types[0].type = &t; - tdiag_fci[i].pointer_count = 1; - } - - /* Handle the __gcc_cdiag__ format specifics. */ - if (!cdiag_fci) - dynamic_format_types[gcc_cdiag_format_type].conversion_specs = - cdiag_fci = (format_char_info *) - xmemdup (gcc_cdiag_char_table, - sizeof (gcc_cdiag_char_table), - sizeof (gcc_cdiag_char_table)); - if (t) - { - /* All specifiers taking a tree share the same struct. */ - i = find_char_info_specifier_index (cdiag_fci, 'D'); - cdiag_fci[i].types[0].type = &t; - cdiag_fci[i].pointer_count = 1; - i = find_char_info_specifier_index (cdiag_fci, 'K'); - cdiag_fci[i].types[0].type = &t; - cdiag_fci[i].pointer_count = 1; - } - - /* Handle the __gcc_cxxdiag__ format specifics. */ - if (!cxxdiag_fci) - dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs = - cxxdiag_fci = (format_char_info *) - xmemdup (gcc_cxxdiag_char_table, - sizeof (gcc_cxxdiag_char_table), - sizeof (gcc_cxxdiag_char_table)); - if (t) - { - /* All specifiers taking a tree share the same struct. */ - i = find_char_info_specifier_index (cxxdiag_fci, 'D'); - cxxdiag_fci[i].types[0].type = &t; - cxxdiag_fci[i].pointer_count = 1; - i = find_char_info_specifier_index (cxxdiag_fci, 'K'); - cxxdiag_fci[i].types[0].type = &t; - cxxdiag_fci[i].pointer_count = 1; - } - } -} - -#ifdef TARGET_FORMAT_TYPES -extern const format_kind_info TARGET_FORMAT_TYPES[]; -#endif - -#ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES -extern const target_ovr_attr TARGET_OVERRIDES_FORMAT_ATTRIBUTES[]; -#endif -#ifdef TARGET_OVERRIDES_FORMAT_INIT - extern void TARGET_OVERRIDES_FORMAT_INIT (void); -#endif - -/* Attributes such as "printf" are equivalent to those such as - "gnu_printf" unless this is overridden by a target. */ -static const target_ovr_attr gnu_target_overrides_format_attributes[] = -{ - { "gnu_printf", "printf" }, - { "gnu_scanf", "scanf" }, - { "gnu_strftime", "strftime" }, - { "gnu_strfmon", "strfmon" }, - { NULL, NULL } -}; - -/* Translate to unified attribute name. This is used in decode_format_type and - decode_format_attr. In attr_name the user specified argument is passed. It - returns the unified format name from TARGET_OVERRIDES_FORMAT_ATTRIBUTES - or the attr_name passed to this function, if there is no matching entry. */ -static const char * -convert_format_name_to_system_name (const char *attr_name) -{ - int i; - - if (attr_name == NULL || *attr_name == 0 - || strncmp (attr_name, "gcc_", 4) == 0) - return attr_name; -#ifdef TARGET_OVERRIDES_FORMAT_INIT - TARGET_OVERRIDES_FORMAT_INIT (); -#endif - -#ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES - /* Check if format attribute is overridden by target. */ - if (TARGET_OVERRIDES_FORMAT_ATTRIBUTES != NULL - && TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT > 0) - { - for (i = 0; i < TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT; ++i) - { - if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src, - attr_name)) - return attr_name; - if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_dst, - attr_name)) - return TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src; - } - } -#endif - /* Otherwise default to gnu format. */ - for (i = 0; - gnu_target_overrides_format_attributes[i].named_attr_src != NULL; - ++i) - { - if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_src, - attr_name)) - return attr_name; - if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_dst, - attr_name)) - return gnu_target_overrides_format_attributes[i].named_attr_src; - } - - return attr_name; -} - -/* Return true if TATTR_NAME and ATTR_NAME are the same format attribute, - counting "name" and "__name__" as the same, false otherwise. */ -static bool -cmp_attribs (const char *tattr_name, const char *attr_name) -{ - int alen = strlen (attr_name); - int slen = (tattr_name ? strlen (tattr_name) : 0); - if (alen > 4 && attr_name[0] == '_' && attr_name[1] == '_' - && attr_name[alen - 1] == '_' && attr_name[alen - 2] == '_') - { - attr_name += 2; - alen -= 4; - } - if (alen != slen || strncmp (tattr_name, attr_name, alen) != 0) - return false; - return true; -} - -/* Handle a "format" attribute; arguments as in - struct attribute_spec.handler. */ -tree -handle_format_attribute (tree *node, tree ARG_UNUSED (name), tree args, - int flags, bool *no_add_attrs) -{ - tree type = *node; - function_format_info info; - -#ifdef TARGET_FORMAT_TYPES - /* If the target provides additional format types, we need to - add them to FORMAT_TYPES at first use. */ - if (TARGET_FORMAT_TYPES != NULL && !dynamic_format_types) - { - dynamic_format_types = XNEWVEC (format_kind_info, - n_format_types + TARGET_N_FORMAT_TYPES); - memcpy (dynamic_format_types, format_types_orig, - sizeof (format_types_orig)); - memcpy (&dynamic_format_types[n_format_types], TARGET_FORMAT_TYPES, - TARGET_N_FORMAT_TYPES * sizeof (dynamic_format_types[0])); - - format_types = dynamic_format_types; - /* Provide a reference for the first potential external type. */ - first_target_format_type = n_format_types; - n_format_types += TARGET_N_FORMAT_TYPES; - } -#endif - - if (!decode_format_attr (args, &info, 0)) - { - *no_add_attrs = true; - return NULL_TREE; - } - - if (prototype_p (type)) - { - if (!check_format_string (type, info.format_num, flags, - no_add_attrs, info.format_type)) - return NULL_TREE; - - if (info.first_arg_num != 0) - { - unsigned HOST_WIDE_INT arg_num = 1; - function_args_iterator iter; - tree arg_type; - - /* Verify that first_arg_num points to the last arg, - the ... */ - FOREACH_FUNCTION_ARGS (type, arg_type, iter) - arg_num++; - - if (arg_num != info.first_arg_num) - { - if (!(flags & (int) ATTR_FLAG_BUILT_IN)) - error ("args to be formatted is not %<...%>"); - *no_add_attrs = true; - return NULL_TREE; - } - } - } - - /* Check if this is a strftime variant. Just for this variant - FMT_FLAG_ARG_CONVERT is not set. */ - if ((format_types[info.format_type].flags & (int) FMT_FLAG_ARG_CONVERT) == 0 - && info.first_arg_num != 0) - { - error ("strftime formats cannot format arguments"); - *no_add_attrs = true; - return NULL_TREE; - } - - /* If this is a custom GCC-internal format type, we have to - initialize certain bits at runtime. */ - if (info.format_type == asm_fprintf_format_type - || info.format_type == gcc_gfc_format_type - || info.format_type == gcc_diag_format_type - || info.format_type == gcc_tdiag_format_type - || info.format_type == gcc_cdiag_format_type - || info.format_type == gcc_cxxdiag_format_type) - { - /* Our first time through, we have to make sure that our - format_type data is allocated dynamically and is modifiable. */ - if (!dynamic_format_types) - format_types = dynamic_format_types = (format_kind_info *) - xmemdup (format_types_orig, sizeof (format_types_orig), - sizeof (format_types_orig)); - - /* If this is format __asm_fprintf__, we have to initialize - GCC's notion of HOST_WIDE_INT for checking %wd. */ - if (info.format_type == asm_fprintf_format_type) - init_dynamic_asm_fprintf_info (); - /* If this is format __gcc_gfc__, we have to initialize GCC's - notion of 'locus' at runtime for %L. */ - else if (info.format_type == gcc_gfc_format_type) - init_dynamic_gfc_info (); - /* If this is one of the diagnostic attributes, then we have to - initialize 'location_t' and 'tree' at runtime. */ - else if (info.format_type == gcc_diag_format_type - || info.format_type == gcc_tdiag_format_type - || info.format_type == gcc_cdiag_format_type - || info.format_type == gcc_cxxdiag_format_type) - init_dynamic_diag_info (); - else - gcc_unreachable (); - } - - return NULL_TREE; -} diff --git a/gcc-4.8.1/gcc/c-family/c-format.h b/gcc-4.8.1/gcc/c-family/c-format.h deleted file mode 100644 index f1cf71e8c..000000000 --- a/gcc-4.8.1/gcc/c-family/c-format.h +++ /dev/null @@ -1,328 +0,0 @@ -/* Check calls to formatted I/O functions (-Wformat). - Copyright (C) 1992-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#ifndef GCC_C_FORMAT_H -#define GCC_C_FORMAT_H - -/* The meaningfully distinct length modifiers for format checking recognized - by GCC. */ -enum format_lengths -{ - FMT_LEN_none, - FMT_LEN_hh, - FMT_LEN_h, - FMT_LEN_l, - FMT_LEN_ll, - FMT_LEN_L, - FMT_LEN_z, - FMT_LEN_t, - FMT_LEN_j, - FMT_LEN_H, - FMT_LEN_D, - FMT_LEN_DD, - FMT_LEN_MAX -}; - - -/* The standard versions in which various format features appeared. */ -enum format_std_version -{ - STD_C89, - STD_C94, - STD_C9L, /* C99, but treat as C89 if -Wno-long-long. */ - STD_C99, - STD_EXT -}; - -/* Flags that may apply to a particular kind of format checked by GCC. */ -enum -{ - /* This format converts arguments of types determined by the - format string. */ - FMT_FLAG_ARG_CONVERT = 1, - /* The scanf allocation 'a' kludge applies to this format kind. */ - FMT_FLAG_SCANF_A_KLUDGE = 2, - /* A % during parsing a specifier is allowed to be a modified % rather - that indicating the format is broken and we are out-of-sync. */ - FMT_FLAG_FANCY_PERCENT_OK = 4, - /* With $ operand numbers, it is OK to reference the same argument more - than once. */ - FMT_FLAG_DOLLAR_MULTIPLE = 8, - /* This format type uses $ operand numbers (strfmon doesn't). */ - FMT_FLAG_USE_DOLLAR = 16, - /* Zero width is bad in this type of format (scanf). */ - FMT_FLAG_ZERO_WIDTH_BAD = 32, - /* Empty precision specification is OK in this type of format (printf). */ - FMT_FLAG_EMPTY_PREC_OK = 64, - /* Gaps are allowed in the arguments with $ operand numbers if all - arguments are pointers (scanf). */ - FMT_FLAG_DOLLAR_GAP_POINTER_OK = 128, - /* The format arg is an opaque object that will be parsed by an external - facility. */ - FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL = 256 - /* Not included here: details of whether width or precision may occur - (controlled by width_char and precision_char); details of whether - '*' can be used for these (width_type and precision_type); details - of whether length modifiers can occur (length_char_specs). */ -}; - -/* Structure describing a length modifier supported in format checking, and - possibly a doubled version such as "hh". */ -typedef struct -{ - /* Name of the single-character length modifier. If prefixed by - a zero character, it describes a multi character length - modifier, like I64, I32, etc. */ - const char *name; - /* Index into a format_char_info.types array. */ - enum format_lengths index; - /* Standard version this length appears in. */ - enum format_std_version std; - /* Same, if the modifier can be repeated, or NULL if it can't. */ - const char *double_name; - enum format_lengths double_index; - enum format_std_version double_std; - - /* If this flag is set, just scalar width identity is checked, and - not the type identity itself. */ - int scalar_identity_flag; -} format_length_info; - - -/* Structure describing the combination of a conversion specifier - (or a set of specifiers which act identically) and a length modifier. */ -typedef struct -{ - /* The standard version this combination of length and type appeared in. - This is only relevant if greater than those for length and type - individually; otherwise it is ignored. */ - enum format_std_version std; - /* The name to use for the type, if different from that generated internally - (e.g., "signed size_t"). */ - const char *name; - /* The type itself. */ - tree *type; -} format_type_detail; - - -/* Macros to fill out tables of these. */ -#define NOARGUMENTS { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN } -#define BADLEN { STD_C89, NULL, NULL } -#define NOLENGTHS { BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN } - - -/* Structure describing a format conversion specifier (or a set of specifiers - which act identically), and the length modifiers used with it. */ -typedef struct format_char_info -{ - const char *format_chars; - int pointer_count; - enum format_std_version std; - /* Types accepted for each length modifier. */ - format_type_detail types[FMT_LEN_MAX]; - /* List of other modifier characters allowed with these specifiers. - This lists flags, and additionally "w" for width, "p" for precision - (right precision, for strfmon), "#" for left precision (strfmon), - "a" for scanf "a" allocation extension (not applicable in C99 mode), - "*" for scanf suppression, and "E" and "O" for those strftime - modifiers. */ - const char *flag_chars; - /* List of additional flags describing these conversion specifiers. - "c" for generic character pointers being allowed, "2" for strftime - two digit year formats, "3" for strftime formats giving two digit - years in some locales, "4" for "2" which becomes "3" with an "E" modifier, - "o" if use of strftime "O" is a GNU extension beyond C99, - "W" if the argument is a pointer which is dereferenced and written into, - "R" if the argument is a pointer which is dereferenced and read from, - "i" for printf integer formats where the '0' flag is ignored with - precision, and "[" for the starting character of a scanf scanset. */ - const char *flags2; - /* If this format conversion character consumes more than one argument, - CHAIN points to information about the next argument. For later - arguments, only POINTER_COUNT, TYPES, and the "c", "R", and "W" flags - in FLAGS2 are used. */ - const struct format_char_info *chain; -} format_char_info; - - -/* Structure describing a flag accepted by some kind of format. */ -typedef struct -{ - /* The flag character in question (0 for end of array). */ - int flag_char; - /* Zero if this entry describes the flag character in general, or a - nonzero character that may be found in flags2 if it describes the - flag when used with certain formats only. If the latter, only - the first such entry found that applies to the current conversion - specifier is used; the values of 'name' and 'long_name' it supplies - will be used, if non-NULL and the standard version is higher than - the unpredicated one, for any pedantic warning. For example, 'o' - for strftime formats (meaning 'O' is an extension over C99). */ - int predicate; - /* Nonzero if the next character after this flag in the format should - be skipped ('=' in strfmon), zero otherwise. */ - int skip_next_char; - /* The name to use for this flag in diagnostic messages. For example, - N_("'0' flag"), N_("field width"). */ - const char *name; - /* Long name for this flag in diagnostic messages; currently only used for - "ISO C does not support ...". For example, N_("the 'I' printf flag"). */ - const char *long_name; - /* The standard version in which it appeared. */ - enum format_std_version std; -} format_flag_spec; - - -/* Structure describing a combination of flags that is bad for some kind - of format. */ -typedef struct -{ - /* The first flag character in question (0 for end of array). */ - int flag_char1; - /* The second flag character. */ - int flag_char2; - /* Nonzero if the message should say that the first flag is ignored with - the second, zero if the combination should simply be objected to. */ - int ignored; - /* Zero if this entry applies whenever this flag combination occurs, - a nonzero character from flags2 if it only applies in some - circumstances (e.g. 'i' for printf formats ignoring 0 with precision). */ - int predicate; -} format_flag_pair; - - -/* Structure describing a particular kind of format processed by GCC. */ -typedef struct -{ - /* The name of this kind of format, for use in diagnostics. Also - the name of the attribute (without preceding and following __). */ - const char *name; - /* Specifications of the length modifiers accepted; possibly NULL. */ - const format_length_info *length_char_specs; - /* Details of the conversion specification characters accepted. */ - const format_char_info *conversion_specs; - /* String listing the flag characters that are accepted. */ - const char *flag_chars; - /* String listing modifier characters (strftime) accepted. May be NULL. */ - const char *modifier_chars; - /* Details of the flag characters, including pseudo-flags. */ - const format_flag_spec *flag_specs; - /* Details of bad combinations of flags. */ - const format_flag_pair *bad_flag_pairs; - /* Flags applicable to this kind of format. */ - int flags; - /* Flag character to treat a width as, or 0 if width not used. */ - int width_char; - /* Flag character to treat a left precision (strfmon) as, - or 0 if left precision not used. */ - int left_precision_char; - /* Flag character to treat a precision (for strfmon, right precision) as, - or 0 if precision not used. */ - int precision_char; - /* If a flag character has the effect of suppressing the conversion of - an argument ('*' in scanf), that flag character, otherwise 0. */ - int suppression_char; - /* Flag character to treat a length modifier as (ignored if length - modifiers not used). Need not be placed in flag_chars for conversion - specifiers, but is used to check for bad combinations such as length - modifier with assignment suppression in scanf. */ - int length_code_char; - /* Assignment-allocation flag character ('m' in scanf), otherwise 0. */ - int alloc_char; - /* Pointer to type of argument expected if '*' is used for a width, - or NULL if '*' not used for widths. */ - tree *width_type; - /* Pointer to type of argument expected if '*' is used for a precision, - or NULL if '*' not used for precisions. */ - tree *precision_type; -} format_kind_info; - -#define T_I &integer_type_node -#define T89_I { STD_C89, NULL, T_I } -#define T_L &long_integer_type_node -#define T89_L { STD_C89, NULL, T_L } -#define T_LL &long_long_integer_type_node -#define T9L_LL { STD_C9L, NULL, T_LL } -#define TEX_LL { STD_EXT, NULL, T_LL } -#define T_S &short_integer_type_node -#define T89_S { STD_C89, NULL, T_S } -#define T_UI &unsigned_type_node -#define T89_UI { STD_C89, NULL, T_UI } -#define T_UL &long_unsigned_type_node -#define T89_UL { STD_C89, NULL, T_UL } -#define T_ULL &long_long_unsigned_type_node -#define T9L_ULL { STD_C9L, NULL, T_ULL } -#define TEX_ULL { STD_EXT, NULL, T_ULL } -#define T_US &short_unsigned_type_node -#define T89_US { STD_C89, NULL, T_US } -#define T_F &float_type_node -#define T89_F { STD_C89, NULL, T_F } -#define T99_F { STD_C99, NULL, T_F } -#define T_D &double_type_node -#define T89_D { STD_C89, NULL, T_D } -#define T99_D { STD_C99, NULL, T_D } -#define T_LD &long_double_type_node -#define T89_LD { STD_C89, NULL, T_LD } -#define T99_LD { STD_C99, NULL, T_LD } -#define T_C &char_type_node -#define T89_C { STD_C89, NULL, T_C } -#define T_SC &signed_char_type_node -#define T99_SC { STD_C99, NULL, T_SC } -#define T_UC &unsigned_char_type_node -#define T99_UC { STD_C99, NULL, T_UC } -#define T_V &void_type_node -#define T89_V { STD_C89, NULL, T_V } -#define T_W &wchar_type_node -#define T94_W { STD_C94, "wchar_t", T_W } -#define TEX_W { STD_EXT, "wchar_t", T_W } -#define T_WI &wint_type_node -#define T94_WI { STD_C94, "wint_t", T_WI } -#define TEX_WI { STD_EXT, "wint_t", T_WI } -#define T_ST &size_type_node -#define T99_ST { STD_C99, "size_t", T_ST } -#define T_SST &signed_size_type_node -#define T99_SST { STD_C99, "signed size_t", T_SST } -#define T_PD &ptrdiff_type_node -#define T99_PD { STD_C99, "ptrdiff_t", T_PD } -#define T_UPD &unsigned_ptrdiff_type_node -#define T99_UPD { STD_C99, "unsigned ptrdiff_t", T_UPD } -#define T_IM &intmax_type_node -#define T99_IM { STD_C99, "intmax_t", T_IM } -#define T_UIM &uintmax_type_node -#define T99_UIM { STD_C99, "uintmax_t", T_UIM } -#define T_D32 &dfloat32_type_node -#define TEX_D32 { STD_EXT, "_Decimal32", T_D32 } -#define T_D64 &dfloat64_type_node -#define TEX_D64 { STD_EXT, "_Decimal64", T_D64 } -#define T_D128 &dfloat128_type_node -#define TEX_D128 { STD_EXT, "_Decimal128", T_D128 } - -/* Structure describing how format attributes such as "printf" are - interpreted as "gnu_printf" or "ms_printf" on a particular system. - TARGET_OVERRIDES_FORMAT_ATTRIBUTES is used to specify target-specific - defaults. */ -typedef struct -{ - /* The name of the to be copied format attribute. */ - const char *named_attr_src; - /* The name of the to be overridden format attribute. */ - const char *named_attr_dst; -} target_ovr_attr; - -#endif /* GCC_C_FORMAT_H */ diff --git a/gcc-4.8.1/gcc/c-family/c-gimplify.c b/gcc-4.8.1/gcc/c-family/c-gimplify.c deleted file mode 100644 index 3ff0a31cb..000000000 --- a/gcc-4.8.1/gcc/c-family/c-gimplify.c +++ /dev/null @@ -1,207 +0,0 @@ -/* Tree lowering pass. This pass gimplifies the tree representation built - by the C-based front ends. The structure of gimplified, or - language-independent, trees is dictated by the grammar described in this - file. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net> - Re-written to support lowering of whole function trees, documentation - and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com> - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "tree.h" -#include "c-common.h" -#include "gimple.h" -#include "tree-inline.h" -#include "diagnostic-core.h" -#include "langhooks.h" -#include "langhooks-def.h" -#include "flags.h" -#include "dumpfile.h" -#include "c-pretty-print.h" -#include "cgraph.h" - - -/* The gimplification pass converts the language-dependent trees - (ld-trees) emitted by the parser into language-independent trees - (li-trees) that are the target of SSA analysis and transformations. - - Language-independent trees are based on the SIMPLE intermediate - representation used in the McCAT compiler framework: - - "Designing the McCAT Compiler Based on a Family of Structured - Intermediate Representations," - L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan, - Proceedings of the 5th International Workshop on Languages and - Compilers for Parallel Computing, no. 757 in Lecture Notes in - Computer Science, New Haven, Connecticut, pp. 406-420, - Springer-Verlag, August 3-5, 1992. - - http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html - - Basically, we walk down gimplifying the nodes that we encounter. As we - walk back up, we check that they fit our constraints, and copy them - into temporaries if not. */ - -/* Gimplification of statement trees. */ - -/* Convert the tree representation of FNDECL from C frontend trees to - GENERIC. */ - -void -c_genericize (tree fndecl) -{ - FILE *dump_orig; - int local_dump_flags; - struct cgraph_node *cgn; - - /* Dump the C-specific tree IR. */ - dump_orig = dump_begin (TDI_original, &local_dump_flags); - if (dump_orig) - { - fprintf (dump_orig, "\n;; Function %s", - lang_hooks.decl_printable_name (fndecl, 2)); - fprintf (dump_orig, " (%s)\n", - (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null" - : IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)))); - fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original)); - fprintf (dump_orig, "\n"); - - if (local_dump_flags & TDF_RAW) - dump_node (DECL_SAVED_TREE (fndecl), - TDF_SLIM | local_dump_flags, dump_orig); - else - print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl)); - fprintf (dump_orig, "\n"); - - dump_end (TDI_original, dump_orig); - } - - /* Dump all nested functions now. */ - cgn = cgraph_get_create_node (fndecl); - for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) - c_genericize (cgn->symbol.decl); -} - -static void -add_block_to_enclosing (tree block) -{ - unsigned i; - tree enclosing; - gimple bind; - vec<gimple> stack = gimple_bind_expr_stack (); - - FOR_EACH_VEC_ELT (stack, i, bind) - if (gimple_bind_block (bind)) - break; - - enclosing = gimple_bind_block (bind); - BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block); -} - -/* Genericize a scope by creating a new BIND_EXPR. - BLOCK is either a BLOCK representing the scope or a chain of _DECLs. - In the latter case, we need to create a new BLOCK and add it to the - BLOCK_SUBBLOCKS of the enclosing block. - BODY is a chain of C _STMT nodes for the contents of the scope, to be - genericized. */ - -tree -c_build_bind_expr (location_t loc, tree block, tree body) -{ - tree decls, bind; - - if (block == NULL_TREE) - decls = NULL_TREE; - else if (TREE_CODE (block) == BLOCK) - decls = BLOCK_VARS (block); - else - { - decls = block; - if (DECL_ARTIFICIAL (decls)) - block = NULL_TREE; - else - { - block = make_node (BLOCK); - BLOCK_VARS (block) = decls; - add_block_to_enclosing (block); - } - } - - if (!body) - body = build_empty_stmt (loc); - if (decls || block) - { - bind = build3 (BIND_EXPR, void_type_node, decls, body, block); - TREE_SIDE_EFFECTS (bind) = 1; - SET_EXPR_LOCATION (bind, loc); - } - else - bind = body; - - return bind; -} - -/* Gimplification of expression trees. */ - -/* Do C-specific gimplification on *EXPR_P. PRE_P and POST_P are as in - gimplify_expr. */ - -int -c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED, - gimple_seq *post_p ATTRIBUTE_UNUSED) -{ - enum tree_code code = TREE_CODE (*expr_p); - - switch (code) - { - case DECL_EXPR: - /* This is handled mostly by gimplify.c, but we have to deal with - not warning about int x = x; as it is a GCC extension to turn off - this warning but only if warn_init_self is zero. */ - if (TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL - && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p)) - && !TREE_STATIC (DECL_EXPR_DECL (*expr_p)) - && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p)) - && !warn_init_self) - TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1; - break; - - case PREINCREMENT_EXPR: - case PREDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - { - tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0)); - if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type)) - { - if (TYPE_OVERFLOW_UNDEFINED (type)) - type = unsigned_type_for (type); - return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type); - } - break; - } - - default:; - } - - return GS_UNHANDLED; -} diff --git a/gcc-4.8.1/gcc/c-family/c-lex.c b/gcc-4.8.1/gcc/c-family/c-lex.c deleted file mode 100644 index 819e9d51e..000000000 --- a/gcc-4.8.1/gcc/c-family/c-lex.c +++ /dev/null @@ -1,1162 +0,0 @@ -/* Mainly the interface between cpplib and the C front ends. - Copyright (C) 1987-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" - -#include "tree.h" -#include "input.h" -#include "c-common.h" -#include "flags.h" -#include "timevar.h" -#include "cpplib.h" -#include "c-pragma.h" -#include "intl.h" -#include "splay-tree.h" -#include "debug.h" -#include "target.h" - -/* We may keep statistics about how long which files took to compile. */ -static int header_time, body_time; -static splay_tree file_info_tree; - -int pending_lang_change; /* If we need to switch languages - C++ only */ -int c_header_level; /* depth in C headers - C++ only */ - -static tree interpret_integer (const cpp_token *, unsigned int, - enum overflow_type *); -static tree interpret_float (const cpp_token *, unsigned int, const char *, - enum overflow_type *); -static tree interpret_fixed (const cpp_token *, unsigned int); -static enum integer_type_kind narrowest_unsigned_type - (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int); -static enum integer_type_kind narrowest_signed_type - (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int); -static enum cpp_ttype lex_string (const cpp_token *, tree *, bool, bool); -static tree lex_charconst (const cpp_token *); -static void update_header_times (const char *); -static int dump_one_header (splay_tree_node, void *); -static void cb_line_change (cpp_reader *, const cpp_token *, int); -static void cb_ident (cpp_reader *, unsigned int, const cpp_string *); -static void cb_def_pragma (cpp_reader *, unsigned int); -static void cb_define (cpp_reader *, unsigned int, cpp_hashnode *); -static void cb_undef (cpp_reader *, unsigned int, cpp_hashnode *); - -void -init_c_lex (void) -{ - struct cpp_callbacks *cb; - struct c_fileinfo *toplevel; - - /* The get_fileinfo data structure must be initialized before - cpp_read_main_file is called. */ - toplevel = get_fileinfo ("<top level>"); - if (flag_detailed_statistics) - { - header_time = 0; - body_time = get_run_time (); - toplevel->time = body_time; - } - - cb = cpp_get_callbacks (parse_in); - - cb->line_change = cb_line_change; - cb->ident = cb_ident; - cb->def_pragma = cb_def_pragma; - cb->valid_pch = c_common_valid_pch; - cb->read_pch = c_common_read_pch; - - /* Set the debug callbacks if we can use them. */ - if ((debug_info_level == DINFO_LEVEL_VERBOSE - && (write_symbols == DWARF2_DEBUG - || write_symbols == VMS_AND_DWARF2_DEBUG)) - || flag_dump_go_spec != NULL) - { - cb->define = cb_define; - cb->undef = cb_undef; - } -} - -struct c_fileinfo * -get_fileinfo (const char *name) -{ - splay_tree_node n; - struct c_fileinfo *fi; - - if (!file_info_tree) - file_info_tree = splay_tree_new ((splay_tree_compare_fn) strcmp, - 0, - (splay_tree_delete_value_fn) free); - - n = splay_tree_lookup (file_info_tree, (splay_tree_key) name); - if (n) - return (struct c_fileinfo *) n->value; - - fi = XNEW (struct c_fileinfo); - fi->time = 0; - fi->interface_only = 0; - fi->interface_unknown = 1; - splay_tree_insert (file_info_tree, (splay_tree_key) name, - (splay_tree_value) fi); - return fi; -} - -static void -update_header_times (const char *name) -{ - /* Changing files again. This means currently collected time - is charged against header time, and body time starts back at 0. */ - if (flag_detailed_statistics) - { - int this_time = get_run_time (); - struct c_fileinfo *file = get_fileinfo (name); - header_time += this_time - body_time; - file->time += this_time - body_time; - body_time = this_time; - } -} - -static int -dump_one_header (splay_tree_node n, void * ARG_UNUSED (dummy)) -{ - print_time ((const char *) n->key, - ((struct c_fileinfo *) n->value)->time); - return 0; -} - -void -dump_time_statistics (void) -{ - struct c_fileinfo *file = get_fileinfo (input_filename); - int this_time = get_run_time (); - file->time += this_time - body_time; - - fprintf (stderr, "\n******\n"); - print_time ("header files (total)", header_time); - print_time ("main file (total)", this_time - body_time); - fprintf (stderr, "ratio = %g : 1\n", - (double) header_time / (double) (this_time - body_time)); - fprintf (stderr, "\n******\n"); - - splay_tree_foreach (file_info_tree, dump_one_header, 0); -} - -static void -cb_ident (cpp_reader * ARG_UNUSED (pfile), - unsigned int ARG_UNUSED (line), - const cpp_string * ARG_UNUSED (str)) -{ - if (!flag_no_ident) - { - /* Convert escapes in the string. */ - cpp_string cstr = { 0, 0 }; - if (cpp_interpret_string (pfile, str, 1, &cstr, CPP_STRING)) - { - targetm.asm_out.output_ident ((const char *) cstr.text); - free (CONST_CAST (unsigned char *, cstr.text)); - } - } -} - -/* Called at the start of every non-empty line. TOKEN is the first - lexed token on the line. Used for diagnostic line numbers. */ -static void -cb_line_change (cpp_reader * ARG_UNUSED (pfile), const cpp_token *token, - int parsing_args) -{ - if (token->type != CPP_EOF && !parsing_args) - input_location = token->src_loc; -} - -void -fe_file_change (const struct line_map *new_map) -{ - if (new_map == NULL) - return; - - if (new_map->reason == LC_ENTER) - { - /* Don't stack the main buffer on the input stack; - we already did in compile_file. */ - if (!MAIN_FILE_P (new_map)) - { - unsigned int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1); - int line = 0; - if (included_at > BUILTINS_LOCATION) - line = SOURCE_LINE (new_map - 1, included_at); - - input_location = new_map->start_location; - (*debug_hooks->start_source_file) (line, LINEMAP_FILE (new_map)); -#ifndef NO_IMPLICIT_EXTERN_C - if (c_header_level) - ++c_header_level; - else if (LINEMAP_SYSP (new_map) == 2) - { - c_header_level = 1; - ++pending_lang_change; - } -#endif - } - } - else if (new_map->reason == LC_LEAVE) - { -#ifndef NO_IMPLICIT_EXTERN_C - if (c_header_level && --c_header_level == 0) - { - if (LINEMAP_SYSP (new_map) == 2) - warning (0, "badly nested C headers from preprocessor"); - --pending_lang_change; - } -#endif - input_location = new_map->start_location; - - (*debug_hooks->end_source_file) (LINEMAP_LINE (new_map)); - } - - update_header_times (LINEMAP_FILE (new_map)); - input_location = new_map->start_location; -} - -static void -cb_def_pragma (cpp_reader *pfile, source_location loc) -{ - /* Issue a warning message if we have been asked to do so. Ignore - unknown pragmas in system headers unless an explicit - -Wunknown-pragmas has been given. */ - if (warn_unknown_pragmas > in_system_header) - { - const unsigned char *space, *name; - const cpp_token *s; - location_t fe_loc = loc; - - space = name = (const unsigned char *) ""; - s = cpp_get_token (pfile); - if (s->type != CPP_EOF) - { - space = cpp_token_as_text (pfile, s); - s = cpp_get_token (pfile); - if (s->type == CPP_NAME) - name = cpp_token_as_text (pfile, s); - } - - warning_at (fe_loc, OPT_Wunknown_pragmas, "ignoring #pragma %s %s", - space, name); - } -} - -/* #define callback for DWARF and DWARF2 debug info. */ -static void -cb_define (cpp_reader *pfile, source_location loc, cpp_hashnode *node) -{ - const struct line_map *map = linemap_lookup (line_table, loc); - (*debug_hooks->define) (SOURCE_LINE (map, loc), - (const char *) cpp_macro_definition (pfile, node)); -} - -/* #undef callback for DWARF and DWARF2 debug info. */ -static void -cb_undef (cpp_reader * ARG_UNUSED (pfile), source_location loc, - cpp_hashnode *node) -{ - const struct line_map *map = linemap_lookup (line_table, loc); - (*debug_hooks->undef) (SOURCE_LINE (map, loc), - (const char *) NODE_NAME (node)); -} - -/* Read a token and return its type. Fill *VALUE with its value, if - applicable. Fill *CPP_FLAGS with the token's flags, if it is - non-NULL. */ - -enum cpp_ttype -c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags, - int lex_flags) -{ - static bool no_more_pch; - const cpp_token *tok; - enum cpp_ttype type; - unsigned char add_flags = 0; - enum overflow_type overflow = OT_NONE; - - timevar_push (TV_CPP); - retry: - tok = cpp_get_token_with_location (parse_in, loc); - type = tok->type; - - retry_after_at: - switch (type) - { - case CPP_PADDING: - goto retry; - - case CPP_NAME: - *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node.node)); - break; - - case CPP_NUMBER: - { - const char *suffix = NULL; - unsigned int flags = cpp_classify_number (parse_in, tok, &suffix, *loc); - - switch (flags & CPP_N_CATEGORY) - { - case CPP_N_INVALID: - /* cpplib has issued an error. */ - *value = error_mark_node; - break; - - case CPP_N_INTEGER: - /* C++ uses '0' to mark virtual functions as pure. - Set PURE_ZERO to pass this information to the C++ parser. */ - if (tok->val.str.len == 1 && *tok->val.str.text == '0') - add_flags = PURE_ZERO; - *value = interpret_integer (tok, flags, &overflow); - break; - - case CPP_N_FLOATING: - *value = interpret_float (tok, flags, suffix, &overflow); - break; - - default: - gcc_unreachable (); - } - - if (flags & CPP_N_USERDEF) - { - char *str; - tree literal; - tree suffix_id = get_identifier (suffix); - int len = tok->val.str.len - strlen (suffix); - /* If this is going to be used as a C string to pass to a - raw literal operator, we need to add a trailing NUL. */ - tree num_string = build_string (len + 1, - (const char *) tok->val.str.text); - TREE_TYPE (num_string) = char_array_type_node; - num_string = fix_string_type (num_string); - str = CONST_CAST (char *, TREE_STRING_POINTER (num_string)); - str[len] = '\0'; - literal = build_userdef_literal (suffix_id, *value, overflow, - num_string); - *value = literal; - } - } - break; - - case CPP_ATSIGN: - /* An @ may give the next token special significance in Objective-C. */ - if (c_dialect_objc ()) - { - location_t atloc = *loc; - location_t newloc; - - retry_at: - tok = cpp_get_token_with_location (parse_in, &newloc); - type = tok->type; - switch (type) - { - case CPP_PADDING: - goto retry_at; - - case CPP_STRING: - case CPP_WSTRING: - case CPP_STRING16: - case CPP_STRING32: - case CPP_UTF8STRING: - type = lex_string (tok, value, true, true); - break; - - case CPP_NAME: - *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node.node)); - if (OBJC_IS_AT_KEYWORD (C_RID_CODE (*value)) - || OBJC_IS_CXX_KEYWORD (C_RID_CODE (*value))) - { - type = CPP_AT_NAME; - /* Note the complication: if we found an OBJC_CXX - keyword, for example, 'class', we will be - returning a token of type CPP_AT_NAME and rid - code RID_CLASS (not RID_AT_CLASS). The language - parser needs to convert that to RID_AT_CLASS. - */ - break; - } - /* FALLTHROUGH */ - - default: - /* ... or not. */ - error_at (atloc, "stray %<@%> in program"); - *loc = newloc; - goto retry_after_at; - } - break; - } - - /* FALLTHROUGH */ - case CPP_HASH: - case CPP_PASTE: - { - unsigned char name[8]; - - *cpp_spell_token (parse_in, tok, name, true) = 0; - - error_at (*loc, "stray %qs in program", name); - } - - goto retry; - - case CPP_OTHER: - { - cppchar_t c = tok->val.str.text[0]; - - if (c == '"' || c == '\'') - error ("missing terminating %c character", (int) c); - else if (ISGRAPH (c)) - error ("stray %qc in program", (int) c); - else - error ("stray %<\\%o%> in program", (int) c); - } - goto retry; - - case CPP_CHAR_USERDEF: - case CPP_WCHAR_USERDEF: - case CPP_CHAR16_USERDEF: - case CPP_CHAR32_USERDEF: - { - tree literal; - cpp_token temp_tok = *tok; - const char *suffix = cpp_get_userdef_suffix (tok); - temp_tok.val.str.len -= strlen (suffix); - temp_tok.type = cpp_userdef_char_remove_type (type); - literal = build_userdef_literal (get_identifier (suffix), - lex_charconst (&temp_tok), - OT_NONE, NULL_TREE); - *value = literal; - } - break; - - case CPP_CHAR: - case CPP_WCHAR: - case CPP_CHAR16: - case CPP_CHAR32: - *value = lex_charconst (tok); - break; - - case CPP_STRING_USERDEF: - case CPP_WSTRING_USERDEF: - case CPP_STRING16_USERDEF: - case CPP_STRING32_USERDEF: - case CPP_UTF8STRING_USERDEF: - { - tree literal, string; - const char *suffix = cpp_get_userdef_suffix (tok); - string = build_string (tok->val.str.len - strlen (suffix), - (const char *) tok->val.str.text); - literal = build_userdef_literal (get_identifier (suffix), - string, OT_NONE, NULL_TREE); - *value = literal; - } - break; - - case CPP_STRING: - case CPP_WSTRING: - case CPP_STRING16: - case CPP_STRING32: - case CPP_UTF8STRING: - if ((lex_flags & C_LEX_STRING_NO_JOIN) == 0) - { - type = lex_string (tok, value, false, - (lex_flags & C_LEX_STRING_NO_TRANSLATE) == 0); - break; - } - *value = build_string (tok->val.str.len, (const char *) tok->val.str.text); - break; - - case CPP_PRAGMA: - *value = build_int_cst (integer_type_node, tok->val.pragma); - break; - - /* These tokens should not be visible outside cpplib. */ - case CPP_HEADER_NAME: - case CPP_MACRO_ARG: - gcc_unreachable (); - - /* CPP_COMMENT will appear when compiling with -C and should be - ignored. */ - case CPP_COMMENT: - goto retry; - - default: - *value = NULL_TREE; - break; - } - - if (cpp_flags) - *cpp_flags = tok->flags | add_flags; - - if (!no_more_pch) - { - no_more_pch = true; - c_common_no_more_pch (); - } - - timevar_pop (TV_CPP); - - return type; -} - -/* Returns the narrowest C-visible unsigned type, starting with the - minimum specified by FLAGS, that can fit HIGH:LOW, or itk_none if - there isn't one. */ - -static enum integer_type_kind -narrowest_unsigned_type (unsigned HOST_WIDE_INT low, - unsigned HOST_WIDE_INT high, - unsigned int flags) -{ - int itk; - - if ((flags & CPP_N_WIDTH) == CPP_N_SMALL) - itk = itk_unsigned_int; - else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM) - itk = itk_unsigned_long; - else - itk = itk_unsigned_long_long; - - for (; itk < itk_none; itk += 2 /* skip unsigned types */) - { - tree upper; - - if (integer_types[itk] == NULL_TREE) - continue; - upper = TYPE_MAX_VALUE (integer_types[itk]); - - if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high - || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high - && TREE_INT_CST_LOW (upper) >= low)) - return (enum integer_type_kind) itk; - } - - return itk_none; -} - -/* Ditto, but narrowest signed type. */ -static enum integer_type_kind -narrowest_signed_type (unsigned HOST_WIDE_INT low, - unsigned HOST_WIDE_INT high, unsigned int flags) -{ - int itk; - - if ((flags & CPP_N_WIDTH) == CPP_N_SMALL) - itk = itk_int; - else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM) - itk = itk_long; - else - itk = itk_long_long; - - - for (; itk < itk_none; itk += 2 /* skip signed types */) - { - tree upper; - - if (integer_types[itk] == NULL_TREE) - continue; - upper = TYPE_MAX_VALUE (integer_types[itk]); - - if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high - || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high - && TREE_INT_CST_LOW (upper) >= low)) - return (enum integer_type_kind) itk; - } - - return itk_none; -} - -/* Interpret TOKEN, an integer with FLAGS as classified by cpplib. */ -static tree -interpret_integer (const cpp_token *token, unsigned int flags, - enum overflow_type *overflow) -{ - tree value, type; - enum integer_type_kind itk; - cpp_num integer; - cpp_options *options = cpp_get_options (parse_in); - - *overflow = OT_NONE; - - integer = cpp_interpret_integer (parse_in, token, flags); - integer = cpp_num_sign_extend (integer, options->precision); - if (integer.overflow) - *overflow = OT_OVERFLOW; - - /* The type of a constant with a U suffix is straightforward. */ - if (flags & CPP_N_UNSIGNED) - itk = narrowest_unsigned_type (integer.low, integer.high, flags); - else - { - /* The type of a potentially-signed integer constant varies - depending on the base it's in, the standard in use, and the - length suffixes. */ - enum integer_type_kind itk_u - = narrowest_unsigned_type (integer.low, integer.high, flags); - enum integer_type_kind itk_s - = narrowest_signed_type (integer.low, integer.high, flags); - - /* In both C89 and C99, octal and hex constants may be signed or - unsigned, whichever fits tighter. We do not warn about this - choice differing from the traditional choice, as the constant - is probably a bit pattern and either way will work. */ - if ((flags & CPP_N_RADIX) != CPP_N_DECIMAL) - itk = MIN (itk_u, itk_s); - else - { - /* In C99, decimal constants are always signed. - In C89, decimal constants that don't fit in long have - undefined behavior; we try to make them unsigned long. - In GCC's extended C89, that last is true of decimal - constants that don't fit in long long, too. */ - - itk = itk_s; - if (itk_s > itk_u && itk_s > itk_long) - { - if (!flag_isoc99) - { - if (itk_u < itk_unsigned_long) - itk_u = itk_unsigned_long; - itk = itk_u; - warning (0, "this decimal constant is unsigned only in ISO C90"); - } - else - warning (OPT_Wtraditional, - "this decimal constant would be unsigned in ISO C90"); - } - } - } - - if (itk == itk_none) - /* cpplib has already issued a warning for overflow. */ - type = ((flags & CPP_N_UNSIGNED) - ? widest_unsigned_literal_type_node - : widest_integer_literal_type_node); - else - { - type = integer_types[itk]; - if (itk > itk_unsigned_long - && (flags & CPP_N_WIDTH) != CPP_N_LARGE) - emit_diagnostic - ((c_dialect_cxx () ? cxx_dialect == cxx98 : !flag_isoc99) - ? DK_PEDWARN : DK_WARNING, - input_location, OPT_Wlong_long, - (flags & CPP_N_UNSIGNED) - ? "integer constant is too large for %<unsigned long%> type" - : "integer constant is too large for %<long%> type"); - } - - value = build_int_cst_wide (type, integer.low, integer.high); - - /* Convert imaginary to a complex type. */ - if (flags & CPP_N_IMAGINARY) - value = build_complex (NULL_TREE, build_int_cst (type, 0), value); - - return value; -} - -/* Interpret TOKEN, a floating point number with FLAGS as classified - by cpplib. For C++0X SUFFIX may contain a user-defined literal suffix. */ -static tree -interpret_float (const cpp_token *token, unsigned int flags, - const char *suffix, enum overflow_type *overflow) -{ - tree type; - tree const_type; - tree value; - REAL_VALUE_TYPE real; - REAL_VALUE_TYPE real_trunc; - char *copy; - size_t copylen; - - *overflow = OT_NONE; - - /* Default (no suffix) depends on whether the FLOAT_CONST_DECIMAL64 - pragma has been used and is either double or _Decimal64. Types - that are not allowed with decimal float default to double. */ - if (flags & CPP_N_DEFAULT) - { - flags ^= CPP_N_DEFAULT; - flags |= CPP_N_MEDIUM; - - if (((flags & CPP_N_HEX) == 0) && ((flags & CPP_N_IMAGINARY) == 0)) - { - warning (OPT_Wunsuffixed_float_constants, - "unsuffixed float constant"); - if (float_const_decimal64_p ()) - flags |= CPP_N_DFLOAT; - } - } - - /* Decode _Fract and _Accum. */ - if (flags & CPP_N_FRACT || flags & CPP_N_ACCUM) - return interpret_fixed (token, flags); - - /* Decode type based on width and properties. */ - if (flags & CPP_N_DFLOAT) - if ((flags & CPP_N_WIDTH) == CPP_N_LARGE) - type = dfloat128_type_node; - else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL) - type = dfloat32_type_node; - else - type = dfloat64_type_node; - else - if (flags & CPP_N_WIDTH_MD) - { - char suffix; - enum machine_mode mode; - - if ((flags & CPP_N_WIDTH_MD) == CPP_N_MD_W) - suffix = 'w'; - else - suffix = 'q'; - - mode = targetm.c.mode_for_suffix (suffix); - if (mode == VOIDmode) - { - error ("unsupported non-standard suffix on floating constant"); - - return error_mark_node; - } - else - pedwarn (input_location, OPT_Wpedantic, "non-standard suffix on floating constant"); - - type = c_common_type_for_mode (mode, 0); - gcc_assert (type); - } - else if ((flags & CPP_N_WIDTH) == CPP_N_LARGE) - type = long_double_type_node; - else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL - || flag_single_precision_constant) - type = float_type_node; - else - type = double_type_node; - - const_type = excess_precision_type (type); - if (!const_type) - const_type = type; - - /* Copy the constant to a nul-terminated buffer. If the constant - has any suffixes, cut them off; REAL_VALUE_ATOF/ REAL_VALUE_HTOF - can't handle them. */ - copylen = token->val.str.len; - if (flags & CPP_N_USERDEF) - copylen -= strlen (suffix); - else if (flags & CPP_N_DFLOAT) - copylen -= 2; - else - { - if ((flags & CPP_N_WIDTH) != CPP_N_MEDIUM) - /* Must be an F or L or machine defined suffix. */ - copylen--; - if (flags & CPP_N_IMAGINARY) - /* I or J suffix. */ - copylen--; - } - - copy = (char *) alloca (copylen + 1); - memcpy (copy, token->val.str.text, copylen); - copy[copylen] = '\0'; - - real_from_string3 (&real, copy, TYPE_MODE (const_type)); - if (const_type != type) - /* Diagnosing if the result of converting the value with excess - precision to the semantic type would overflow (with associated - double rounding) is more appropriate than diagnosing if the - result of converting the string directly to the semantic type - would overflow. */ - real_convert (&real_trunc, TYPE_MODE (type), &real); - - /* Both C and C++ require a diagnostic for a floating constant - outside the range of representable values of its type. Since we - have __builtin_inf* to produce an infinity, this is now a - mandatory pedwarn if the target does not support infinities. */ - if (REAL_VALUE_ISINF (real) - || (const_type != type && REAL_VALUE_ISINF (real_trunc))) - { - *overflow = OT_OVERFLOW; - if (!(flags & CPP_N_USERDEF)) - { - if (!MODE_HAS_INFINITIES (TYPE_MODE (type))) - pedwarn (input_location, 0, - "floating constant exceeds range of %qT", type); - else - warning (OPT_Woverflow, - "floating constant exceeds range of %qT", type); - } - } - /* We also give a warning if the value underflows. */ - else if (REAL_VALUES_EQUAL (real, dconst0) - || (const_type != type - && REAL_VALUES_EQUAL (real_trunc, dconst0))) - { - REAL_VALUE_TYPE realvoidmode; - int oflow = real_from_string (&realvoidmode, copy); - *overflow = (oflow == 0 ? OT_NONE - : (oflow < 0 ? OT_UNDERFLOW : OT_OVERFLOW)); - if (!(flags & CPP_N_USERDEF)) - { - if (oflow < 0 || !REAL_VALUES_EQUAL (realvoidmode, dconst0)) - warning (OPT_Woverflow, "floating constant truncated to zero"); - } - } - - /* Create a node with determined type and value. */ - value = build_real (const_type, real); - if (flags & CPP_N_IMAGINARY) - { - value = build_complex (NULL_TREE, convert (const_type, - integer_zero_node), value); - if (type != const_type) - { - const_type = TREE_TYPE (value); - type = build_complex_type (type); - } - } - - if (type != const_type) - value = build1 (EXCESS_PRECISION_EXPR, type, value); - - return value; -} - -/* Interpret TOKEN, a fixed-point number with FLAGS as classified - by cpplib. */ - -static tree -interpret_fixed (const cpp_token *token, unsigned int flags) -{ - tree type; - tree value; - FIXED_VALUE_TYPE fixed; - char *copy; - size_t copylen; - - copylen = token->val.str.len; - - if (flags & CPP_N_FRACT) /* _Fract. */ - { - if (flags & CPP_N_UNSIGNED) /* Unsigned _Fract. */ - { - if ((flags & CPP_N_WIDTH) == CPP_N_LARGE) - { - type = unsigned_long_long_fract_type_node; - copylen -= 4; - } - else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM) - { - type = unsigned_long_fract_type_node; - copylen -= 3; - } - else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL) - { - type = unsigned_short_fract_type_node; - copylen -= 3; - } - else - { - type = unsigned_fract_type_node; - copylen -= 2; - } - } - else /* Signed _Fract. */ - { - if ((flags & CPP_N_WIDTH) == CPP_N_LARGE) - { - type = long_long_fract_type_node; - copylen -= 3; - } - else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM) - { - type = long_fract_type_node; - copylen -= 2; - } - else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL) - { - type = short_fract_type_node; - copylen -= 2; - } - else - { - type = fract_type_node; - copylen --; - } - } - } - else /* _Accum. */ - { - if (flags & CPP_N_UNSIGNED) /* Unsigned _Accum. */ - { - if ((flags & CPP_N_WIDTH) == CPP_N_LARGE) - { - type = unsigned_long_long_accum_type_node; - copylen -= 4; - } - else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM) - { - type = unsigned_long_accum_type_node; - copylen -= 3; - } - else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL) - { - type = unsigned_short_accum_type_node; - copylen -= 3; - } - else - { - type = unsigned_accum_type_node; - copylen -= 2; - } - } - else /* Signed _Accum. */ - { - if ((flags & CPP_N_WIDTH) == CPP_N_LARGE) - { - type = long_long_accum_type_node; - copylen -= 3; - } - else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM) - { - type = long_accum_type_node; - copylen -= 2; - } - else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL) - { - type = short_accum_type_node; - copylen -= 2; - } - else - { - type = accum_type_node; - copylen --; - } - } - } - - copy = (char *) alloca (copylen + 1); - memcpy (copy, token->val.str.text, copylen); - copy[copylen] = '\0'; - - fixed_from_string (&fixed, copy, TYPE_MODE (type)); - - /* Create a node with determined type and value. */ - value = build_fixed (type, fixed); - - return value; -} - -/* Convert a series of STRING, WSTRING, STRING16, STRING32 and/or - UTF8STRING tokens into a tree, performing string constant - concatenation. TOK is the first of these. VALP is the location to - write the string into. OBJC_STRING indicates whether an '@' token - preceded the incoming token (in that case, the strings can either - be ObjC strings, preceded by a single '@', or normal strings, not - preceded by '@'. The result will be a CPP_OBJC_STRING). Returns - the CPP token type of the result (CPP_STRING, CPP_WSTRING, - CPP_STRING32, CPP_STRING16, CPP_UTF8STRING, or CPP_OBJC_STRING). - - This is unfortunately more work than it should be. If any of the - strings in the series has an L prefix, the result is a wide string - (6.4.5p4). Whether or not the result is a wide string affects the - meaning of octal and hexadecimal escapes (6.4.4.4p6,9). But escape - sequences do not continue across the boundary between two strings in - a series (6.4.5p7), so we must not lose the boundaries. Therefore - cpp_interpret_string takes a vector of cpp_string structures, which - we must arrange to provide. */ - -static enum cpp_ttype -lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate) -{ - tree value; - size_t concats = 0; - struct obstack str_ob; - cpp_string istr; - enum cpp_ttype type = tok->type; - - /* Try to avoid the overhead of creating and destroying an obstack - for the common case of just one string. */ - cpp_string str = tok->val.str; - cpp_string *strs = &str; - - /* objc_at_sign_was_seen is only used when doing Objective-C string - concatenation. It is 'true' if we have seen an '@' before the - current string, and 'false' if not. We must see exactly one or - zero '@' before each string. */ - bool objc_at_sign_was_seen = false; - - retry: - tok = cpp_get_token (parse_in); - switch (tok->type) - { - case CPP_PADDING: - goto retry; - case CPP_ATSIGN: - if (objc_string) - { - if (objc_at_sign_was_seen) - error ("repeated %<@%> before Objective-C string"); - - objc_at_sign_was_seen = true; - goto retry; - } - /* FALLTHROUGH */ - - default: - break; - - case CPP_WSTRING: - case CPP_STRING16: - case CPP_STRING32: - case CPP_UTF8STRING: - if (type != tok->type) - { - if (type == CPP_STRING) - type = tok->type; - else - error ("unsupported non-standard concatenation of string literals"); - } - - case CPP_STRING: - if (!concats) - { - gcc_obstack_init (&str_ob); - obstack_grow (&str_ob, &str, sizeof (cpp_string)); - } - - concats++; - obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string)); - if (objc_string) - objc_at_sign_was_seen = false; - goto retry; - } - - /* It is an error if we saw a '@' with no following string. */ - if (objc_at_sign_was_seen) - error ("stray %<@%> in program"); - - /* We have read one more token than we want. */ - _cpp_backup_tokens (parse_in, 1); - if (concats) - strs = XOBFINISH (&str_ob, cpp_string *); - - if (concats && !objc_string && !in_system_header) - warning (OPT_Wtraditional, - "traditional C rejects string constant concatenation"); - - if ((translate - ? cpp_interpret_string : cpp_interpret_string_notranslate) - (parse_in, strs, concats + 1, &istr, type)) - { - value = build_string (istr.len, (const char *) istr.text); - free (CONST_CAST (unsigned char *, istr.text)); - } - else - { - /* Callers cannot generally handle error_mark_node in this context, - so return the empty string instead. cpp_interpret_string has - issued an error. */ - switch (type) - { - default: - case CPP_STRING: - case CPP_UTF8STRING: - value = build_string (1, ""); - break; - case CPP_STRING16: - value = build_string (TYPE_PRECISION (char16_type_node) - / TYPE_PRECISION (char_type_node), - "\0"); /* char16_t is 16 bits */ - break; - case CPP_STRING32: - value = build_string (TYPE_PRECISION (char32_type_node) - / TYPE_PRECISION (char_type_node), - "\0\0\0"); /* char32_t is 32 bits */ - break; - case CPP_WSTRING: - value = build_string (TYPE_PRECISION (wchar_type_node) - / TYPE_PRECISION (char_type_node), - "\0\0\0"); /* widest supported wchar_t - is 32 bits */ - break; - } - } - - switch (type) - { - default: - case CPP_STRING: - case CPP_UTF8STRING: - TREE_TYPE (value) = char_array_type_node; - break; - case CPP_STRING16: - TREE_TYPE (value) = char16_array_type_node; - break; - case CPP_STRING32: - TREE_TYPE (value) = char32_array_type_node; - break; - case CPP_WSTRING: - TREE_TYPE (value) = wchar_array_type_node; - } - *valp = fix_string_type (value); - - if (concats) - obstack_free (&str_ob, 0); - - return objc_string ? CPP_OBJC_STRING : type; -} - -/* Converts a (possibly wide) character constant token into a tree. */ -static tree -lex_charconst (const cpp_token *token) -{ - cppchar_t result; - tree type, value; - unsigned int chars_seen; - int unsignedp = 0; - - result = cpp_interpret_charconst (parse_in, token, - &chars_seen, &unsignedp); - - if (token->type == CPP_WCHAR) - type = wchar_type_node; - else if (token->type == CPP_CHAR32) - type = char32_type_node; - else if (token->type == CPP_CHAR16) - type = char16_type_node; - /* In C, a character constant has type 'int'. - In C++ 'char', but multi-char charconsts have type 'int'. */ - else if (!c_dialect_cxx () || chars_seen > 1) - type = integer_type_node; - else - type = char_type_node; - - /* Cast to cppchar_signed_t to get correct sign-extension of RESULT - before possibly widening to HOST_WIDE_INT for build_int_cst. */ - if (unsignedp || (cppchar_signed_t) result >= 0) - value = build_int_cst_wide (type, result, 0); - else - value = build_int_cst_wide (type, (cppchar_signed_t) result, -1); - - return value; -} diff --git a/gcc-4.8.1/gcc/c-family/c-objc.h b/gcc-4.8.1/gcc/c-family/c-objc.h deleted file mode 100644 index bf4e3d536..000000000 --- a/gcc-4.8.1/gcc/c-family/c-objc.h +++ /dev/null @@ -1,114 +0,0 @@ -/* Definitions of Objective-C front-end entry points used for C and C++. - Copyright (C) 1987-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#ifndef GCC_C_COMMON_OBJC_H -#define GCC_C_COMMON_OBJC_H - -/* ObjC ivar visibility types. */ -typedef enum objc_ivar_visibility_kind { - OBJC_IVAR_VIS_PROTECTED = 0, - OBJC_IVAR_VIS_PUBLIC = 1, - OBJC_IVAR_VIS_PRIVATE = 2, - OBJC_IVAR_VIS_PACKAGE = 3 -} objc_ivar_visibility_kind; - -/* Objective-C / Objective-C++ entry points. */ - -/* The following ObjC/ObjC++ functions are called by the C and/or C++ - front-ends; they all must have corresponding stubs in stub-objc.c. */ -extern void objc_write_global_declarations (void); -extern tree objc_is_class_name (tree); -extern tree objc_is_object_ptr (tree); -extern void objc_check_decl (tree); -extern void objc_check_global_decl (tree); -extern tree objc_common_type (tree, tree); -extern bool objc_compare_types (tree, tree, int, tree); -extern bool objc_have_common_type (tree, tree, int, tree); -extern bool objc_diagnose_private_ivar (tree); -extern void objc_volatilize_decl (tree); -extern tree objc_rewrite_function_call (tree, tree); -extern tree objc_message_selector (void); -extern tree objc_lookup_ivar (tree, tree); -extern void objc_clear_super_receiver (void); -extern int objc_is_public (tree, tree); -extern tree objc_is_id (tree); -extern void objc_declare_alias (tree, tree); -extern void objc_declare_class (tree); -extern void objc_declare_protocol (tree, tree); -extern tree objc_build_message_expr (tree, tree); -extern tree objc_finish_message_expr (tree, tree, tree, tree*); -extern tree objc_build_selector_expr (location_t, tree); -extern tree objc_build_protocol_expr (tree); -extern tree objc_build_encode_expr (tree); -extern tree objc_build_string_object (tree); -extern tree objc_get_protocol_qualified_type (tree, tree); -extern tree objc_get_class_reference (tree); -extern tree objc_get_class_ivars (tree); -extern bool objc_detect_field_duplicates (bool); -extern void objc_start_class_interface (tree, tree, tree, tree); -extern void objc_start_category_interface (tree, tree, tree, tree); -extern void objc_start_protocol (tree, tree, tree); -extern void objc_continue_interface (void); -extern void objc_finish_interface (void); -extern void objc_start_class_implementation (tree, tree); -extern void objc_start_category_implementation (tree, tree); -extern void objc_continue_implementation (void); -extern void objc_finish_implementation (void); -extern void objc_set_visibility (objc_ivar_visibility_kind); -extern tree objc_build_method_signature (bool, tree, tree, tree, bool); -extern void objc_add_method_declaration (bool, tree, tree); -extern bool objc_start_method_definition (bool, tree, tree, tree); -extern void objc_finish_method_definition (tree); -extern void objc_add_instance_variable (tree); -extern tree objc_build_keyword_decl (tree, tree, tree, tree); -extern tree objc_build_throw_stmt (location_t, tree); -extern void objc_begin_try_stmt (location_t, tree); -extern tree objc_finish_try_stmt (void); -extern void objc_begin_catch_clause (tree); -extern void objc_finish_catch_clause (void); -extern void objc_build_finally_clause (location_t, tree); -extern tree objc_build_synchronized (location_t, tree, tree); -extern int objc_static_init_needed_p (void); -extern tree objc_generate_static_init_call (tree); -extern tree objc_generate_write_barrier (tree, enum tree_code, tree); -extern void objc_set_method_opt (bool); -extern void objc_finish_foreach_loop (location_t, tree, tree, tree, tree, tree); -extern bool objc_method_decl (enum tree_code); -extern void objc_add_property_declaration (location_t, tree, bool, bool, bool, - bool, bool, bool, tree, tree); -extern tree objc_maybe_build_component_ref (tree, tree); -extern tree objc_build_class_component_ref (tree, tree); -extern tree objc_maybe_build_modify_expr (tree, tree); -extern tree objc_build_incr_expr_for_property_ref (location_t, enum tree_code, - tree, tree); -extern void objc_add_synthesize_declaration (location_t, tree); -extern void objc_add_dynamic_declaration (location_t, tree); -extern const char * objc_maybe_printable_name (tree, int); -extern bool objc_is_property_ref (tree); -extern bool objc_string_ref_type_p (tree); -extern void objc_check_format_arg (tree, tree); -extern void objc_finish_function (void); -extern void objc_maybe_warn_exceptions (location_t); - -/* The following are provided by the C and C++ front-ends, and called by - ObjC/ObjC++. */ -extern void *objc_get_current_scope (void); -extern void objc_mark_locals_volatile (void *); - -#endif /* ! GCC_C_COMMON_OBJC_H */ diff --git a/gcc-4.8.1/gcc/c-family/c-omp.c b/gcc-4.8.1/gcc/c-family/c-omp.c deleted file mode 100644 index f05b60a40..000000000 --- a/gcc-4.8.1/gcc/c-family/c-omp.c +++ /dev/null @@ -1,641 +0,0 @@ -/* This file contains routines to construct GNU OpenMP constructs, - called from parsing in the C and C++ front ends. - - Copyright (C) 2005-2013 Free Software Foundation, Inc. - Contributed by Richard Henderson <rth@redhat.com>, - Diego Novillo <dnovillo@redhat.com>. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tree.h" -#include "c-common.h" -#include "gimple.h" /* For create_tmp_var_raw. */ -#include "langhooks.h" - - -/* Complete a #pragma omp master construct. STMT is the structured-block - that follows the pragma. LOC is the l*/ - -tree -c_finish_omp_master (location_t loc, tree stmt) -{ - tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt)); - SET_EXPR_LOCATION (t, loc); - return t; -} - -/* Complete a #pragma omp critical construct. STMT is the structured-block - that follows the pragma, NAME is the identifier in the pragma, or null - if it was omitted. LOC is the location of the #pragma. */ - -tree -c_finish_omp_critical (location_t loc, tree body, tree name) -{ - tree stmt = make_node (OMP_CRITICAL); - TREE_TYPE (stmt) = void_type_node; - OMP_CRITICAL_BODY (stmt) = body; - OMP_CRITICAL_NAME (stmt) = name; - SET_EXPR_LOCATION (stmt, loc); - return add_stmt (stmt); -} - -/* Complete a #pragma omp ordered construct. STMT is the structured-block - that follows the pragma. LOC is the location of the #pragma. */ - -tree -c_finish_omp_ordered (location_t loc, tree stmt) -{ - tree t = build1 (OMP_ORDERED, void_type_node, stmt); - SET_EXPR_LOCATION (t, loc); - return add_stmt (t); -} - - -/* Complete a #pragma omp barrier construct. LOC is the location of - the #pragma. */ - -void -c_finish_omp_barrier (location_t loc) -{ - tree x; - - x = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER); - x = build_call_expr_loc (loc, x, 0); - add_stmt (x); -} - - -/* Complete a #pragma omp taskwait construct. LOC is the location of the - pragma. */ - -void -c_finish_omp_taskwait (location_t loc) -{ - tree x; - - x = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT); - x = build_call_expr_loc (loc, x, 0); - add_stmt (x); -} - - -/* Complete a #pragma omp taskyield construct. LOC is the location of the - pragma. */ - -void -c_finish_omp_taskyield (location_t loc) -{ - tree x; - - x = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD); - x = build_call_expr_loc (loc, x, 0); - add_stmt (x); -} - - -/* Complete a #pragma omp atomic construct. For CODE OMP_ATOMIC - the expression to be implemented atomically is LHS opcode= RHS. - For OMP_ATOMIC_READ V = LHS, for OMP_ATOMIC_CAPTURE_{NEW,OLD} LHS - opcode= RHS with the new or old content of LHS returned. - LOC is the location of the atomic statement. The value returned - is either error_mark_node (if the construct was erroneous) or an - OMP_ATOMIC* node which should be added to the current statement - tree with add_stmt. */ - -tree -c_finish_omp_atomic (location_t loc, enum tree_code code, - enum tree_code opcode, tree lhs, tree rhs, - tree v, tree lhs1, tree rhs1) -{ - tree x, type, addr; - - if (lhs == error_mark_node || rhs == error_mark_node - || v == error_mark_node || lhs1 == error_mark_node - || rhs1 == error_mark_node) - return error_mark_node; - - /* ??? According to one reading of the OpenMP spec, complex type are - supported, but there are no atomic stores for any architecture. - But at least icc 9.0 doesn't support complex types here either. - And lets not even talk about vector types... */ - type = TREE_TYPE (lhs); - if (!INTEGRAL_TYPE_P (type) - && !POINTER_TYPE_P (type) - && !SCALAR_FLOAT_TYPE_P (type)) - { - error_at (loc, "invalid expression type for %<#pragma omp atomic%>"); - return error_mark_node; - } - - /* ??? Validate that rhs does not overlap lhs. */ - - /* Take and save the address of the lhs. From then on we'll reference it - via indirection. */ - addr = build_unary_op (loc, ADDR_EXPR, lhs, 0); - if (addr == error_mark_node) - return error_mark_node; - addr = save_expr (addr); - if (TREE_CODE (addr) != SAVE_EXPR - && (TREE_CODE (addr) != ADDR_EXPR - || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL)) - { - /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize - it even after unsharing function body. */ - tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL); - DECL_CONTEXT (var) = current_function_decl; - addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL); - } - lhs = build_indirect_ref (loc, addr, RO_NULL); - - if (code == OMP_ATOMIC_READ) - { - x = build1 (OMP_ATOMIC_READ, type, addr); - SET_EXPR_LOCATION (x, loc); - return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR, - loc, x, NULL_TREE); - return x; - } - - /* There are lots of warnings, errors, and conversions that need to happen - in the course of interpreting a statement. Use the normal mechanisms - to do this, and then take it apart again. */ - x = build_modify_expr (input_location, lhs, NULL_TREE, opcode, - input_location, rhs, NULL_TREE); - if (x == error_mark_node) - return error_mark_node; - gcc_assert (TREE_CODE (x) == MODIFY_EXPR); - rhs = TREE_OPERAND (x, 1); - - /* Punt the actual generation of atomic operations to common code. */ - if (code == OMP_ATOMIC) - type = void_type_node; - x = build2 (code, type, addr, rhs); - SET_EXPR_LOCATION (x, loc); - - /* Generally it is hard to prove lhs1 and lhs are the same memory - location, just diagnose different variables. */ - if (rhs1 - && TREE_CODE (rhs1) == VAR_DECL - && TREE_CODE (lhs) == VAR_DECL - && rhs1 != lhs) - { - if (code == OMP_ATOMIC) - error_at (loc, "%<#pragma omp atomic update%> uses two different variables for memory"); - else - error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory"); - return error_mark_node; - } - - if (code != OMP_ATOMIC) - { - /* Generally it is hard to prove lhs1 and lhs are the same memory - location, just diagnose different variables. */ - if (lhs1 && TREE_CODE (lhs1) == VAR_DECL && TREE_CODE (lhs) == VAR_DECL) - { - if (lhs1 != lhs) - { - error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory"); - return error_mark_node; - } - } - x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR, - loc, x, NULL_TREE); - if (rhs1 && rhs1 != lhs) - { - tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0); - if (rhs1addr == error_mark_node) - return error_mark_node; - x = omit_one_operand_loc (loc, type, x, rhs1addr); - } - if (lhs1 && lhs1 != lhs) - { - tree lhs1addr = build_unary_op (loc, ADDR_EXPR, lhs1, 0); - if (lhs1addr == error_mark_node) - return error_mark_node; - if (code == OMP_ATOMIC_CAPTURE_OLD) - x = omit_one_operand_loc (loc, type, x, lhs1addr); - else - { - x = save_expr (x); - x = omit_two_operands_loc (loc, type, x, x, lhs1addr); - } - } - } - else if (rhs1 && rhs1 != lhs) - { - tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0); - if (rhs1addr == error_mark_node) - return error_mark_node; - x = omit_one_operand_loc (loc, type, x, rhs1addr); - } - - return x; -} - - -/* Complete a #pragma omp flush construct. We don't do anything with - the variable list that the syntax allows. LOC is the location of - the #pragma. */ - -void -c_finish_omp_flush (location_t loc) -{ - tree x; - - x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE); - x = build_call_expr_loc (loc, x, 0); - add_stmt (x); -} - - -/* Check and canonicalize #pragma omp for increment expression. - Helper function for c_finish_omp_for. */ - -static tree -check_omp_for_incr_expr (location_t loc, tree exp, tree decl) -{ - tree t; - - if (!INTEGRAL_TYPE_P (TREE_TYPE (exp)) - || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl))) - return error_mark_node; - - if (exp == decl) - return build_int_cst (TREE_TYPE (exp), 0); - - switch (TREE_CODE (exp)) - { - CASE_CONVERT: - t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl); - if (t != error_mark_node) - return fold_convert_loc (loc, TREE_TYPE (exp), t); - break; - case MINUS_EXPR: - t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl); - if (t != error_mark_node) - return fold_build2_loc (loc, MINUS_EXPR, - TREE_TYPE (exp), t, TREE_OPERAND (exp, 1)); - break; - case PLUS_EXPR: - t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl); - if (t != error_mark_node) - return fold_build2_loc (loc, PLUS_EXPR, - TREE_TYPE (exp), t, TREE_OPERAND (exp, 1)); - t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl); - if (t != error_mark_node) - return fold_build2_loc (loc, PLUS_EXPR, - TREE_TYPE (exp), TREE_OPERAND (exp, 0), t); - break; - case COMPOUND_EXPR: - { - /* cp_build_modify_expr forces preevaluation of the RHS to make - sure that it is evaluated before the lvalue-rvalue conversion - is applied to the LHS. Reconstruct the original expression. */ - tree op0 = TREE_OPERAND (exp, 0); - if (TREE_CODE (op0) == TARGET_EXPR - && !VOID_TYPE_P (TREE_TYPE (op0))) - { - tree op1 = TREE_OPERAND (exp, 1); - tree temp = TARGET_EXPR_SLOT (op0); - if (TREE_CODE_CLASS (TREE_CODE (op1)) == tcc_binary - && TREE_OPERAND (op1, 1) == temp) - { - op1 = copy_node (op1); - TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0); - return check_omp_for_incr_expr (loc, op1, decl); - } - } - break; - } - default: - break; - } - - return error_mark_node; -} - -/* Validate and emit code for the OpenMP directive #pragma omp for. - DECLV is a vector of iteration variables, for each collapsed loop. - INITV, CONDV and INCRV are vectors containing initialization - expressions, controlling predicates and increment expressions. - BODY is the body of the loop and PRE_BODY statements that go before - the loop. */ - -tree -c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv, - tree incrv, tree body, tree pre_body) -{ - location_t elocus; - bool fail = false; - int i; - - gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv)); - gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv)); - gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv)); - for (i = 0; i < TREE_VEC_LENGTH (declv); i++) - { - tree decl = TREE_VEC_ELT (declv, i); - tree init = TREE_VEC_ELT (initv, i); - tree cond = TREE_VEC_ELT (condv, i); - tree incr = TREE_VEC_ELT (incrv, i); - - elocus = locus; - if (EXPR_HAS_LOCATION (init)) - elocus = EXPR_LOCATION (init); - - /* Validate the iteration variable. */ - if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)) - && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE) - { - error_at (elocus, "invalid type for iteration variable %qE", decl); - fail = true; - } - - /* In the case of "for (int i = 0...)", init will be a decl. It should - have a DECL_INITIAL that we can turn into an assignment. */ - if (init == decl) - { - elocus = DECL_SOURCE_LOCATION (decl); - - init = DECL_INITIAL (decl); - if (init == NULL) - { - error_at (elocus, "%qE is not initialized", decl); - init = integer_zero_node; - fail = true; - } - - init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR, - /* FIXME diagnostics: This should - be the location of the INIT. */ - elocus, - init, - NULL_TREE); - } - gcc_assert (TREE_CODE (init) == MODIFY_EXPR); - gcc_assert (TREE_OPERAND (init, 0) == decl); - - if (cond == NULL_TREE) - { - error_at (elocus, "missing controlling predicate"); - fail = true; - } - else - { - bool cond_ok = false; - - if (EXPR_HAS_LOCATION (cond)) - elocus = EXPR_LOCATION (cond); - - if (TREE_CODE (cond) == LT_EXPR - || TREE_CODE (cond) == LE_EXPR - || TREE_CODE (cond) == GT_EXPR - || TREE_CODE (cond) == GE_EXPR - || TREE_CODE (cond) == NE_EXPR - || TREE_CODE (cond) == EQ_EXPR) - { - tree op0 = TREE_OPERAND (cond, 0); - tree op1 = TREE_OPERAND (cond, 1); - - /* 2.5.1. The comparison in the condition is computed in - the type of DECL, otherwise the behavior is undefined. - - For example: - long n; int i; - i < n; - - according to ISO will be evaluated as: - (long)i < n; - - We want to force: - i < (int)n; */ - if (TREE_CODE (op0) == NOP_EXPR - && decl == TREE_OPERAND (op0, 0)) - { - TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0); - TREE_OPERAND (cond, 1) - = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl), - TREE_OPERAND (cond, 1)); - } - else if (TREE_CODE (op1) == NOP_EXPR - && decl == TREE_OPERAND (op1, 0)) - { - TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0); - TREE_OPERAND (cond, 0) - = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl), - TREE_OPERAND (cond, 0)); - } - - if (decl == TREE_OPERAND (cond, 0)) - cond_ok = true; - else if (decl == TREE_OPERAND (cond, 1)) - { - TREE_SET_CODE (cond, - swap_tree_comparison (TREE_CODE (cond))); - TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0); - TREE_OPERAND (cond, 0) = decl; - cond_ok = true; - } - - if (TREE_CODE (cond) == NE_EXPR - || TREE_CODE (cond) == EQ_EXPR) - { - if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))) - cond_ok = false; - else if (operand_equal_p (TREE_OPERAND (cond, 1), - TYPE_MIN_VALUE (TREE_TYPE (decl)), - 0)) - TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR - ? GT_EXPR : LE_EXPR); - else if (operand_equal_p (TREE_OPERAND (cond, 1), - TYPE_MAX_VALUE (TREE_TYPE (decl)), - 0)) - TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR - ? LT_EXPR : GE_EXPR); - else - cond_ok = false; - } - } - - if (!cond_ok) - { - error_at (elocus, "invalid controlling predicate"); - fail = true; - } - } - - if (incr == NULL_TREE) - { - error_at (elocus, "missing increment expression"); - fail = true; - } - else - { - bool incr_ok = false; - - if (EXPR_HAS_LOCATION (incr)) - elocus = EXPR_LOCATION (incr); - - /* Check all the valid increment expressions: v++, v--, ++v, --v, - v = v + incr, v = incr + v and v = v - incr. */ - switch (TREE_CODE (incr)) - { - case POSTINCREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case PREDECREMENT_EXPR: - if (TREE_OPERAND (incr, 0) != decl) - break; - - incr_ok = true; - if (POINTER_TYPE_P (TREE_TYPE (decl)) - && TREE_OPERAND (incr, 1)) - { - tree t = fold_convert_loc (elocus, - sizetype, TREE_OPERAND (incr, 1)); - - if (TREE_CODE (incr) == POSTDECREMENT_EXPR - || TREE_CODE (incr) == PREDECREMENT_EXPR) - t = fold_build1_loc (elocus, NEGATE_EXPR, sizetype, t); - t = fold_build_pointer_plus (decl, t); - incr = build2 (MODIFY_EXPR, void_type_node, decl, t); - } - break; - - case MODIFY_EXPR: - if (TREE_OPERAND (incr, 0) != decl) - break; - if (TREE_OPERAND (incr, 1) == decl) - break; - if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR - && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl - || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl)) - incr_ok = true; - else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR - || (TREE_CODE (TREE_OPERAND (incr, 1)) - == POINTER_PLUS_EXPR)) - && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl) - incr_ok = true; - else - { - tree t = check_omp_for_incr_expr (elocus, - TREE_OPERAND (incr, 1), - decl); - if (t != error_mark_node) - { - incr_ok = true; - t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t); - incr = build2 (MODIFY_EXPR, void_type_node, decl, t); - } - } - break; - - default: - break; - } - if (!incr_ok) - { - error_at (elocus, "invalid increment expression"); - fail = true; - } - } - - TREE_VEC_ELT (initv, i) = init; - TREE_VEC_ELT (incrv, i) = incr; - } - - if (fail) - return NULL; - else - { - tree t = make_node (OMP_FOR); - - TREE_TYPE (t) = void_type_node; - OMP_FOR_INIT (t) = initv; - OMP_FOR_COND (t) = condv; - OMP_FOR_INCR (t) = incrv; - OMP_FOR_BODY (t) = body; - OMP_FOR_PRE_BODY (t) = pre_body; - - SET_EXPR_LOCATION (t, locus); - return add_stmt (t); - } -} - - -/* Divide CLAUSES into two lists: those that apply to a parallel - construct, and those that apply to a work-sharing construct. Place - the results in *PAR_CLAUSES and *WS_CLAUSES respectively. In - addition, add a nowait clause to the work-sharing list. LOC is the - location of the OMP_PARALLEL*. */ - -void -c_split_parallel_clauses (location_t loc, tree clauses, - tree *par_clauses, tree *ws_clauses) -{ - tree next; - - *par_clauses = NULL; - *ws_clauses = build_omp_clause (loc, OMP_CLAUSE_NOWAIT); - - for (; clauses ; clauses = next) - { - next = OMP_CLAUSE_CHAIN (clauses); - - switch (OMP_CLAUSE_CODE (clauses)) - { - case OMP_CLAUSE_PRIVATE: - case OMP_CLAUSE_SHARED: - case OMP_CLAUSE_FIRSTPRIVATE: - case OMP_CLAUSE_LASTPRIVATE: - case OMP_CLAUSE_REDUCTION: - case OMP_CLAUSE_COPYIN: - case OMP_CLAUSE_IF: - case OMP_CLAUSE_NUM_THREADS: - case OMP_CLAUSE_DEFAULT: - OMP_CLAUSE_CHAIN (clauses) = *par_clauses; - *par_clauses = clauses; - break; - - case OMP_CLAUSE_SCHEDULE: - case OMP_CLAUSE_ORDERED: - case OMP_CLAUSE_COLLAPSE: - OMP_CLAUSE_CHAIN (clauses) = *ws_clauses; - *ws_clauses = clauses; - break; - - default: - gcc_unreachable (); - } - } -} - -/* True if OpenMP sharing attribute of DECL is predetermined. */ - -enum omp_clause_default_kind -c_omp_predetermined_sharing (tree decl) -{ - /* Variables with const-qualified type having no mutable member - are predetermined shared. */ - if (TREE_READONLY (decl)) - return OMP_CLAUSE_DEFAULT_SHARED; - - return OMP_CLAUSE_DEFAULT_UNSPECIFIED; -} diff --git a/gcc-4.8.1/gcc/c-family/c-opts.c b/gcc-4.8.1/gcc/c-family/c-opts.c deleted file mode 100644 index 4b6990a60..000000000 --- a/gcc-4.8.1/gcc/c-family/c-opts.c +++ /dev/null @@ -1,1505 +0,0 @@ -/* C/ObjC/C++ command line option handling. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Contributed by Neil Booth. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tree.h" -#include "c-common.h" -#include "c-pragma.h" -#include "flags.h" -#include "toplev.h" -#include "langhooks.h" -#include "diagnostic.h" -#include "intl.h" -#include "cppdefault.h" -#include "incpath.h" -#include "debug.h" /* For debug_hooks. */ -#include "opts.h" -#include "options.h" -#include "mkdeps.h" -#include "c-target.h" -#include "tm.h" /* For BYTES_BIG_ENDIAN, - DOLLARS_IN_IDENTIFIERS, - STDC_0_IN_SYSTEM_HEADERS, - TARGET_FLT_EVAL_METHOD_NON_DEFAULT and - TARGET_OPTF. */ -#include "tm_p.h" /* For C_COMMON_OVERRIDE_OPTIONS. */ - -#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 - -/* CPP's options. */ -cpp_options *cpp_opts; - -/* Input filename. */ -static const char *this_input_filename; - -/* Filename and stream for preprocessed output. */ -static const char *out_fname; -static FILE *out_stream; - -/* Append dependencies to deps_file. */ -static bool deps_append; - -/* If dependency switches (-MF etc.) have been given. */ -static bool deps_seen; - -/* If -v seen. */ -static bool verbose; - -/* Dependency output file. */ -static const char *deps_file; - -/* The prefix given by -iprefix, if any. */ -static const char *iprefix; - -/* The multilib directory given by -imultilib, if any. */ -static const char *imultilib; - -/* The system root, if any. Overridden by -isysroot. */ -static const char *sysroot = TARGET_SYSTEM_ROOT; - -/* Zero disables all standard directories for headers. */ -static bool std_inc = true; - -/* Zero disables the C++-specific standard directories for headers. */ -static bool std_cxx_inc = true; - -/* If the quote chain has been split by -I-. */ -static bool quote_chain_split; - -/* Number of deferred options. */ -static size_t deferred_count; - -/* Number of deferred options scanned for -include. */ -static size_t include_cursor; - -/* Whether any standard preincluded header has been preincluded. */ -static bool done_preinclude; - -static void handle_OPT_d (const char *); -static void set_std_cxx98 (int); -static void set_std_cxx11 (int); -static void set_std_cxx1y (int); -static void set_std_c89 (int, int); -static void set_std_c99 (int); -static void set_std_c11 (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 c_finish_options (void); - -#ifndef STDC_0_IN_SYSTEM_HEADERS -#define STDC_0_IN_SYSTEM_HEADERS 0 -#endif - -/* Holds switches parsed by c_common_handle_option (), but whose - handling is deferred to c_common_post_options (). */ -static void defer_opt (enum opt_code, const char *); -static struct deferred_opt -{ - enum opt_code code; - const char *arg; -} *deferred_opts; - - -extern const unsigned int -c_family_lang_mask = (CL_C | CL_CXX | CL_ObjC | CL_ObjCXX); - -/* Defer option CODE with argument ARG. */ -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++; -} - -/* Return language mask for option parsing. */ -unsigned int -c_common_option_lang_mask (void) -{ - static const unsigned int lang_flags[] = {CL_C, CL_ObjC, CL_CXX, CL_ObjCXX}; - - return lang_flags[c_language]; -} - -/* Common diagnostics initialization. */ -void -c_common_initialize_diagnostics (diagnostic_context *context) -{ - /* This is conditionalized only because that is the way the front - ends used to do it. Maybe this should be unconditional? */ - if (c_dialect_cxx ()) - { - /* By default wrap lines at 80 characters. Is getenv - ("COLUMNS") preferable? */ - diagnostic_line_cutoff (context) = 80; - /* By default, emit location information once for every - diagnostic message. */ - diagnostic_prefixing_rule (context) = DIAGNOSTICS_SHOW_PREFIX_ONCE; - } - - context->opt_permissive = OPT_fpermissive; -} - -/* Whether options from all C-family languages should be accepted - quietly. */ -static bool accept_all_c_family_options = false; - -/* Return whether to complain about a wrong-language option. */ -bool -c_common_complain_wrong_lang_p (const struct cl_option *option) -{ - if (accept_all_c_family_options - && (option->flags & c_family_lang_mask)) - return false; - - return true; -} - -/* Initialize options structure OPTS. */ -void -c_common_init_options_struct (struct gcc_options *opts) -{ - opts->x_flag_exceptions = c_dialect_cxx (); - opts->x_warn_pointer_arith = c_dialect_cxx (); - opts->x_warn_write_strings = c_dialect_cxx (); - opts->x_flag_warn_unused_result = true; - - /* By default, C99-like requirements for complex multiply and divide. */ - opts->x_flag_complex_method = 2; -} - -/* Common initialization before calling option handlers. */ -void -c_common_init_options (unsigned int decoded_options_count, - struct cl_decoded_option *decoded_options) -{ - unsigned int i; - struct cpp_callbacks *cb; - - parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89, - ident_hash, line_table); - cb = cpp_get_callbacks (parse_in); - cb->error = c_cpp_error; - - cpp_opts = cpp_get_options (parse_in); - cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS; - cpp_opts->objc = c_dialect_objc (); - - /* Reset to avoid warnings on internal definitions. We set it just - before passing on command-line options to cpplib. */ - cpp_opts->warn_dollars = 0; - - deferred_opts = XNEWVEC (struct deferred_opt, decoded_options_count); - - if (c_language == clk_c) - { - /* If preprocessing assembly language, accept any of the C-family - front end options since the driver may pass them through. */ - for (i = 1; i < decoded_options_count; i++) - if (decoded_options[i].opt_index == OPT_lang_asm) - { - accept_all_c_family_options = true; - break; - } - } -} - -/* Handle switch SCODE with argument ARG. VALUE is true, unless no- - form of an -f or -W option was given. Returns false if the switch was - invalid, true if valid. Use HANDLERS in recursive handle_option calls. */ -bool -c_common_handle_option (size_t scode, const char *arg, int value, - int kind, location_t loc, - const struct cl_option_handlers *handlers) -{ - const struct cl_option *option = &cl_options[scode]; - enum opt_code code = (enum opt_code) scode; - bool result = true; - - /* Prevent resetting the language standard to a C dialect when the driver - has already determined that we're looking at assembler input. */ - bool preprocessing_asm_p = (cpp_get_options (parse_in)->lang == CLK_ASM); - - switch (code) - { - default: - if (cl_options[code].flags & c_family_lang_mask) - { - if ((option->flags & CL_TARGET) - && ! targetcm.handle_c_option (scode, arg, value)) - result = false; - break; - } - result = false; - 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_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 (input_location, "obsolete option -I- used, please use -iquote instead"); - } - break; - - case OPT_M: - case OPT_MM: - /* When doing dependencies with -M or -MM, suppress normal - preprocessed output, but still do -dM etc. as software - depends on this. Preprocessed output does occur if -MD, -MMD - or environment var dependency generation is used. */ - cpp_opts->deps.style = (code == OPT_M ? DEPS_SYSTEM: DEPS_USER); - flag_no_output = 1; - break; - - case OPT_MD: - case OPT_MMD: - cpp_opts->deps.style = (code == OPT_MD ? DEPS_SYSTEM: DEPS_USER); - cpp_opts->deps.need_preprocessor_output = true; - 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_U: - defer_opt (code, arg); - break; - - case OPT_Wall: - /* ??? Don't add new options here. Use LangEnabledBy in c.opt. */ - - cpp_opts->warn_trigraphs = value; - cpp_opts->warn_comments = value; - cpp_opts->warn_num_sign_change = value; - break; - - case OPT_Wbuiltin_macro_redefined: - cpp_opts->warn_builtin_macro_redefined = value; - break; - - case OPT_Wcomment: - cpp_opts->warn_comments = value; - break; - - case OPT_Wc___compat: - cpp_opts->warn_cxx_operator_names = value; - break; - - case OPT_Wdeprecated: - cpp_opts->cpp_warn_deprecated = value; - break; - - case OPT_Wendif_labels: - cpp_opts->warn_endif_labels = value; - break; - - case OPT_Winvalid_pch: - cpp_opts->warn_invalid_pch = value; - break; - - case OPT_Wliteral_suffix: - cpp_opts->warn_literal_suffix = value; - break; - - case OPT_Wlong_long: - cpp_opts->cpp_warn_long_long = value; - 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_Wnormalized_: - if (kind == DK_ERROR) - { - gcc_assert (!arg); - inform (input_location, "-Werror=normalized=: set -Wnormalized=nfc"); - cpp_opts->warn_normalize = normalized_C; - } - else - { - 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_Wtraditional: - cpp_opts->cpp_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: - /* Set to greater than 1, so that even unknown pragmas in - system headers will be warned about. */ - /* ??? There is no way to handle this automatically for now. */ - warn_unknown_pragmas = value * 2; - break; - - case OPT_ansi: - if (!c_dialect_cxx ()) - set_std_c89 (false, true); - else - set_std_cxx98 (true); - break; - - case OPT_d: - handle_OPT_d (arg); - break; - - case OPT_fcanonical_system_headers: - cpp_opts->canonical_system_headers = value; - break; - - case OPT_fcond_mismatch: - if (!c_dialect_cxx ()) - { - flag_cond_mismatch = value; - break; - } - warning (0, "switch %qs is no longer supported", option->opt_text); - break; - - case OPT_fbuiltin_: - if (value) - result = false; - else - disable_builtin_function (arg); - break; - - case OPT_fdirectives_only: - cpp_opts->directives_only = value; - break; - - case OPT_fdollars_in_identifiers: - cpp_opts->dollars_in_ident = value; - break; - - case OPT_ffreestanding: - value = !value; - /* Fall through.... */ - case OPT_fhosted: - flag_hosted = value; - flag_no_builtin = !value; - break; - - case OPT_fconstant_string_class_: - constant_string_class_name = arg; - break; - - case OPT_fextended_identifiers: - cpp_opts->extended_identifiers = value; - break; - - case OPT_foperator_names: - cpp_opts->operator_names = 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; - global_dc->permissive = value; - break; - - case OPT_fpreprocessed: - cpp_opts->preprocessed = value; - break; - - case OPT_fdebug_cpp: - cpp_opts->debug = 1; - break; - - case OPT_ftrack_macro_expansion: - if (value) - value = 2; - /* Fall Through. */ - - case OPT_ftrack_macro_expansion_: - if (arg && *arg != '\0') - cpp_opts->track_macro_expansion = value; - else - cpp_opts->track_macro_expansion = 2; - break; - - case OPT_frepo: - flag_use_repository = value; - if (value) - flag_implicit_templates = 0; - break; - - case OPT_ftabstop_: - /* It is documented that we silently ignore silly values. */ - 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_fvisibility_inlines_hidden: - visibility_options.inlines_hidden = value; - break; - - case OPT_femit_struct_debug_baseonly: - set_struct_debug_option (&global_options, loc, "base"); - break; - - case OPT_femit_struct_debug_reduced: - set_struct_debug_option (&global_options, loc, - "dir:ord:sys,dir:gen:any,ind:base"); - break; - - case OPT_femit_struct_debug_detailed_: - set_struct_debug_option (&global_options, loc, arg); - break; - - case OPT_fext_numeric_literals: - cpp_opts->ext_numeric_literals = value; - 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_imultilib: - imultilib = 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_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; - - /* We need to handle the -Wpedantic switch here, rather than in - c_common_post_options, so that a subsequent -Wno-endif-labels - is not overridden. */ - case OPT_Wpedantic: - cpp_opts->cpp_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: - if (!preprocessing_asm_p) - set_std_cxx98 (code == OPT_std_c__98 /* ISO */); - break; - - case OPT_std_c__11: - case OPT_std_gnu__11: - if (!preprocessing_asm_p) - { - set_std_cxx11 (code == OPT_std_c__11 /* ISO */); - if (code == OPT_std_c__11) - cpp_opts->ext_numeric_literals = 0; - } - break; - - case OPT_std_c__1y: - case OPT_std_gnu__1y: - if (!preprocessing_asm_p) - { - set_std_cxx1y (code == OPT_std_c__1y /* ISO */); - if (code == OPT_std_c__1y) - cpp_opts->ext_numeric_literals = 0; - } - break; - - case OPT_std_c90: - case OPT_std_iso9899_199409: - if (!preprocessing_asm_p) - set_std_c89 (code == OPT_std_iso9899_199409 /* c94 */, true /* ISO */); - break; - - case OPT_std_gnu90: - if (!preprocessing_asm_p) - set_std_c89 (false /* c94 */, false /* ISO */); - break; - - case OPT_std_c99: - if (!preprocessing_asm_p) - set_std_c99 (true /* ISO */); - break; - - case OPT_std_gnu99: - if (!preprocessing_asm_p) - set_std_c99 (false /* ISO */); - break; - - case OPT_std_c11: - if (!preprocessing_asm_p) - set_std_c11 (true /* ISO */); - break; - - case OPT_std_gnu11: - if (!preprocessing_asm_p) - set_std_c11 (false /* ISO */); - break; - - case OPT_trigraphs: - cpp_opts->trigraphs = 1; - break; - - case OPT_traditional_cpp: - cpp_opts->traditional = 1; - break; - - case OPT_v: - verbose = true; - break; - - case OPT_Wabi: - warn_psabi = value; - break; - } - - switch (c_language) - { - case clk_c: - C_handle_option_auto (&global_options, &global_options_set, - scode, arg, value, - c_family_lang_mask, kind, - loc, handlers, global_dc); - break; - - case clk_objc: - ObjC_handle_option_auto (&global_options, &global_options_set, - scode, arg, value, - c_family_lang_mask, kind, - loc, handlers, global_dc); - break; - - case clk_cxx: - CXX_handle_option_auto (&global_options, &global_options_set, - scode, arg, value, - c_family_lang_mask, kind, - loc, handlers, global_dc); - break; - - case clk_objcxx: - ObjCXX_handle_option_auto (&global_options, &global_options_set, - scode, arg, value, - c_family_lang_mask, kind, - loc, handlers, global_dc); - break; - - default: - gcc_unreachable (); - } - - return result; -} - -/* Default implementation of TARGET_HANDLE_C_OPTION. */ - -bool -default_handle_c_option (size_t code ATTRIBUTE_UNUSED, - const char *arg ATTRIBUTE_UNUSED, - int value ATTRIBUTE_UNUSED) -{ - return false; -} - -/* Post-switch processing. */ -bool -c_common_post_options (const char **pfilename) -{ - struct cpp_callbacks *cb; - - /* Canonicalize the input and output filenames. */ - if (in_fnames == NULL) - { - in_fnames = XNEWVEC (const char *, 1); - in_fnames[0] = ""; - } - 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, imultilib, - std_inc, std_cxx_inc && c_dialect_cxx (), verbose); - -#ifdef C_COMMON_OVERRIDE_OPTIONS - /* Some machines may reject certain combinations of C - language-specific options. */ - C_COMMON_OVERRIDE_OPTIONS; -#endif - - /* Excess precision other than "fast" requires front-end - support. */ - if (c_dialect_cxx ()) - { - if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD - && TARGET_FLT_EVAL_METHOD_NON_DEFAULT) - sorry ("-fexcess-precision=standard for C++"); - flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; - } - else if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT) - flag_excess_precision_cmdline = (flag_iso - ? EXCESS_PRECISION_STANDARD - : EXCESS_PRECISION_FAST); - - /* By default we use C99 inline semantics in GNU99 or C99 mode. C99 - inline semantics are not supported in GNU89 or C89 mode. */ - if (flag_gnu89_inline == -1) - flag_gnu89_inline = !flag_isoc99; - else if (!flag_gnu89_inline && !flag_isoc99) - error ("-fno-gnu89-inline is only supported in GNU99 or C99 mode"); - - /* Default to ObjC sjlj exception handling if NeXT runtime. */ - if (flag_objc_sjlj_exceptions < 0) - flag_objc_sjlj_exceptions = flag_next_runtime; - if (flag_objc_exceptions && !flag_objc_sjlj_exceptions) - flag_exceptions = 1; - - /* -Woverlength-strings is off by default, but is enabled by -Wpedantic. - It is never enabled in C++, as the minimum limit is not normative - in that standard. */ - if (c_dialect_cxx ()) - warn_overlength_strings = 0; - - /* Wmain is enabled by default in C++ but not in C. */ - /* Wmain is disabled by default for -ffreestanding (!flag_hosted), - even if -Wall or -Wpedantic was given (warn_main will be 2 if set - by -Wall, 1 if set by -Wmain). */ - if (warn_main == -1) - warn_main = (c_dialect_cxx () && flag_hosted) ? 1 : 0; - else if (warn_main == 2) - warn_main = flag_hosted ? 1 : 0; - - /* In C, -Wall and -Wc++-compat enable -Wenum-compare; if it has not - yet been set, it is disabled by default. In C++, it is enabled - by default. */ - if (warn_enum_compare == -1) - warn_enum_compare = c_dialect_cxx () ? 1 : 0; - - /* -Wpacked-bitfield-compat is on by default for the C languages. The - warning is issued in stor-layout.c which is not part of the front-end so - we need to selectively turn it on here. */ - if (warn_packed_bitfield_compat == -1) - warn_packed_bitfield_compat = 1; - - /* Special format checking options don't work without -Wformat; warn if - they are used. */ - if (!warn_format) - { - warning (OPT_Wformat_y2k, - "-Wformat-y2k ignored without -Wformat"); - warning (OPT_Wformat_extra_args, - "-Wformat-extra-args ignored without -Wformat"); - warning (OPT_Wformat_zero_length, - "-Wformat-zero-length ignored without -Wformat"); - warning (OPT_Wformat_nonliteral, - "-Wformat-nonliteral ignored without -Wformat"); - warning (OPT_Wformat_contains_nul, - "-Wformat-contains-nul ignored without -Wformat"); - warning (OPT_Wformat_security, - "-Wformat-security ignored without -Wformat"); - } - - /* -Wimplicit-function-declaration is enabled by default for C99. */ - if (warn_implicit_function_declaration == -1) - warn_implicit_function_declaration = flag_isoc99; - - if (cxx_dialect >= cxx0x) - { - /* If we're allowing C++0x constructs, don't warn about C++98 - identifiers which are keywords in C++0x. */ - warn_cxx0x_compat = 0; - - if (warn_narrowing == -1) - warn_narrowing = 1; - } - else if (warn_narrowing == -1) - warn_narrowing = 0; - - if (flag_extern_tls_init) - { -#if !defined (ASM_OUTPUT_DEF) || !SUPPORTS_WEAK - /* Lazy TLS initialization for a variable in another TU requires - alias and weak reference support. */ - if (flag_extern_tls_init > 0) - sorry ("external TLS initialization functions not supported " - "on this target"); - flag_extern_tls_init = 0; -#else - flag_extern_tls_init = 1; -#endif - } - - if (flag_preprocess_only) - { - /* Open the output now. We must do so even if flag_no_output is - on, because there may be other output than from the actual - preprocessing (e.g. from -dM). */ - 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 (); - - /* When writing a PCH file, avoid reading some other PCH file, - because the default address space slot then can't be used - for the output PCH file. */ - if (pch_file) - { - c_common_no_more_pch (); - /* Only -g0 and -gdwarf* are supported with PCH, for other - debug formats we warn here and refuse to load any PCH files. */ - if (write_symbols != NO_DEBUG && write_symbols != DWARF2_DEBUG) - warning (OPT_Wdeprecated, - "the \"%s\" debug format cannot be used with " - "pre-compiled headers", debug_type_names[write_symbols]); - } - else if (write_symbols != NO_DEBUG && write_symbols != DWARF2_DEBUG) - c_common_no_more_pch (); - - /* Yuk. WTF is this? I do know ObjC relies on it somewhere. */ - 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; - - *pfilename = this_input_filename - = cpp_read_main_file (parse_in, in_fnames[0]); - /* Don't do any compilation or preprocessing if there is no input file. */ - 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 ()); - - /* Disable LTO output when outputting a precompiled header. */ - if (pch_file && flag_lto) - { - flag_lto = 0; - flag_generate_lto = 0; - } - - return flag_preprocess_only; -} - -/* Front end initialization common to C, ObjC and C++. */ -bool -c_common_init (void) -{ - /* Set up preprocessor arithmetic. Must be done after call to - c_common_nodes_and_builtins for type nodes to be good. */ - 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; - - /* This can't happen until after wchar_precision and bytes_big_endian - are known. */ - cpp_init_iconv (parse_in); - - if (version_flag) - { - int i; - fputs ("Compiler executable checksum: ", stderr); - for (i = 0; i < 16; i++) - fprintf (stderr, "%02x", executable_checksum[i]); - putc ('\n', stderr); - } - - /* Has to wait until now so that cpplib has its hash table. */ - init_pragma (); - - if (flag_preprocess_only) - { - c_finish_options (); - preprocess_file (parse_in); - return false; - } - - return true; -} - -/* Initialize the integrated preprocessor after debug output has been - initialized; loop over each input file. */ -void -c_common_parse_file (void) -{ - unsigned int i; - - i = 0; - for (;;) - { - c_finish_options (); - pch_init (); - push_file_scope (); - c_parse_file (); - pop_file_scope (); - /* And end the main input file, if the debug writer wants it */ - 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); - cpp_clear_file_cache (parse_in); - this_input_filename - = cpp_read_main_file (parse_in, in_fnames[i]); - /* If an input file is missing, abandon further compilation. - cpplib has issued a diagnostic. */ - if (!this_input_filename) - break; - } -} - -/* Common finish hook for the C, ObjC and C++ front ends. */ -void -c_common_finish (void) -{ - FILE *deps_stream = NULL; - - /* Don't write the deps file if there are errors. */ - if (cpp_opts->deps.style != DEPS_NONE && !seen_error ()) - { - /* If -M or -MM was seen without -MF, default output to the - output stream. */ - 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); - } - } - - /* For performance, avoid tearing down cpplib's internal structures - with cpp_destroy (). */ - 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); -} - -/* Either of two environment variables can specify output of - dependencies. Their value is either "OUTPUT_FILE" or "OUTPUT_FILE - DEPS_TARGET", where OUTPUT_FILE is the file to write deps info to - and DEPS_TARGET is the target to mention in the deps. They also - result in dependency information being appended to the output file - rather than overwriting it, and like Sun's compiler - SUNPRO_DEPENDENCIES suppresses the dependency on the main file. */ -static void -check_deps_environment_vars (void) -{ - char *spec; - - spec = getenv ("DEPENDENCIES_OUTPUT"); - if (spec) - cpp_opts->deps.style = DEPS_USER; - else - { - spec = getenv ("SUNPRO_DEPENDENCIES"); - if (spec) - { - cpp_opts->deps.style = DEPS_SYSTEM; - cpp_opts->deps.ignore_main_file = true; - } - } - - if (spec) - { - /* Find the space before the DEPS_TARGET, if there is one. */ - char *s = strchr (spec, ' '); - if (s) - { - /* Let the caller perform MAKE quoting. */ - defer_opt (OPT_MT, s + 1); - *s = '\0'; - } - - /* Command line -MF overrides environment variables and default. */ - if (!deps_file) - deps_file = spec; - - deps_append = 1; - deps_seen = true; - } -} - -/* Handle deferred command line switches. */ -static void -handle_deferred_opts (void) -{ - size_t i; - struct deps *deps; - - /* Avoid allocating the deps buffer if we don't need it. - (This flag may be true without there having been -MT or -MQ - options, but we'll still need the deps buffer.) */ - 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); - } -} - -/* These settings are appropriate for GCC, but not necessarily so for - cpplib as a library. */ -static void -sanitize_cpp_opts (void) -{ - /* If we don't know what style of dependencies to output, complain - if any other dependency switches have been given. */ - if (deps_seen && cpp_opts->deps.style == DEPS_NONE) - error ("to generate dependencies you must specify either -M or -MM"); - - /* -dM and dependencies suppress normal output; do it here so that - the last -d[MDN] switch overrides earlier ones. */ - if (flag_dump_macros == 'M') - flag_no_output = 1; - - /* By default, -fdirectives-only implies -dD. This allows subsequent phases - to perform proper macro expansion. */ - if (cpp_opts->directives_only && !cpp_opts->preprocessed && !flag_dump_macros) - flag_dump_macros = 'D'; - - /* Disable -dD, -dN and -dI if normal output is suppressed. Allow - -dM since at least glibc relies on -M -dM to work. */ - /* Also, flag_no_output implies flag_no_line_commands, always. */ - if (flag_no_output) - { - if (flag_dump_macros != 'M') - flag_dump_macros = 0; - flag_dump_includes = 0; - flag_no_line_commands = 1; - } - else if (cpp_opts->deps.missing_files) - error ("-MG may only be used with -M or -MM"); - - cpp_opts->unsigned_char = !flag_signed_char; - cpp_opts->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS; - - /* Wlong-long is disabled by default. It is enabled by: - [-Wpedantic | -Wtraditional] -std=[gnu|c]++98 ; or - [-Wpedantic | -Wtraditional] -std=non-c99 . - - Either -Wlong-long or -Wno-long-long override any other settings. */ - if (warn_long_long == -1) - warn_long_long = ((pedantic || warn_traditional) - && (c_dialect_cxx () ? cxx_dialect == cxx98 : !flag_isoc99)); - cpp_opts->cpp_warn_long_long = warn_long_long; - - /* Similarly with -Wno-variadic-macros. No check for c99 here, since - this also turns off warnings about GCCs extension. */ - cpp_opts->warn_variadic_macros - = cpp_warn_variadic_macros && (pedantic || warn_traditional); - - /* If we're generating preprocessor output, emit current directory - if explicitly requested or if debugging information is enabled. - ??? Maybe we should only do it for debugging formats that - actually output the current directory? */ - if (flag_working_directory == -1) - flag_working_directory = (debug_info_level != DINFO_LEVEL_NONE); - - if (cpp_opts->directives_only) - { - if (cpp_warn_unused_macros) - error ("-fdirectives-only is incompatible with -Wunused_macros"); - if (cpp_opts->traditional) - error ("-fdirectives-only is incompatible with -traditional"); - } -} - -/* Add include path with a prefix at the front of its name. */ -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); -} - -/* Handle -D, -U, -A, -imacros, and the first -include. */ -static void -c_finish_options (void) -{ - if (!cpp_opts->preprocessed) - { - size_t i; - - { - /* Make sure all of the builtins about to be declared have - BUILTINS_LOCATION has their source_location. */ - source_location builtins_loc = BUILTINS_LOCATION; - cpp_force_token_locations (parse_in, &builtins_loc); - - cpp_init_builtins (parse_in, flag_hosted); - c_cpp_builtins (parse_in); - - cpp_stop_forcing_token_locations (parse_in); - } - - /* We're about to send user input to cpplib, so make it warn for - things that we previously (when we sent it internal definitions) - told it to not warn. - - C99 permits implementation-defined characters in identifiers. - The documented meaning of -std= is to turn off extensions that - conflict with the specified standard, and since a strictly - conforming program cannot contain a '$', we do not condition - their acceptance on the -std= setting. */ - cpp_opts->warn_dollars = (cpp_opts->cpp_pedantic && !cpp_opts->c99); - - cb_file_change (parse_in, - linemap_add (line_table, LC_RENAME, 0, - _("<command-line>"), 0)); - - 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); - } - } - - /* Start the main input file, if the debug writer wants it. */ - if (debug_hooks->start_end_main_source_file - && !flag_preprocess_only) - (*debug_hooks->start_source_file) (0, this_input_filename); - - /* Handle -imacros after -D and -U. */ - 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)) - { - /* Disable push_command_line_include callback for now. */ - include_cursor = deferred_count + 1; - cpp_scan_nooutput (parse_in); - } - } - } - else - { - if (cpp_opts->directives_only) - cpp_init_special_builtins (parse_in); - - /* Start the main input file, if the debug writer wants it. */ - if (debug_hooks->start_end_main_source_file - && !flag_preprocess_only) - (*debug_hooks->start_source_file) (0, this_input_filename); - } - - include_cursor = 0; - push_command_line_include (); -} - -/* Give CPP the next file given by -include, if any. */ -static void -push_command_line_include (void) -{ - if (!done_preinclude) - { - done_preinclude = true; - if (flag_hosted && std_inc && !cpp_opts->preprocessed) - { - const char *preinc = targetcm.c_preinclude (); - if (preinc && cpp_push_default_include (parse_in, preinc)) - return; - } - } - - pch_cpp_save_state (); - - 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++; - /* -Wunused-macros should only warn about macros defined hereafter. */ - cpp_opts->warn_unused_macros = cpp_warn_unused_macros; - /* Restore the line map from <command line>. */ - if (!cpp_opts->preprocessed) - cpp_change_file (parse_in, LC_RENAME, this_input_filename); - - /* Set this here so the client can change the option if it wishes, - and after stacking the main file so we don't trace the main file. */ - line_table->trace_includes = cpp_opts->print_include_names; - } -} - -/* File change callback. Has to handle -include files. */ -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))) - { - pch_cpp_save_state (); - push_command_line_include (); - } -} - -void -cb_dir_change (cpp_reader * ARG_UNUSED (pfile), const char *dir) -{ - if (!set_src_pwd (dir)) - warning (0, "too late for # directive to set debug directory"); -} - -/* Set the C 89 standard (with 1994 amendments if C94, without GNU - extensions if ISO). There is no concept of gnu94. */ -static void -set_std_c89 (int c94, int iso) -{ - 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_isoc11 = 0; -} - -/* Set the C 99 standard (without GNU extensions if ISO). */ -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_isoc11 = 0; - flag_isoc99 = 1; - flag_isoc94 = 1; -} - -/* Set the C 11 standard (without GNU extensions if ISO). */ -static void -set_std_c11 (int iso) -{ - cpp_set_lang (parse_in, iso ? CLK_STDC11: CLK_GNUC11); - flag_no_asm = iso; - flag_no_nonansi_builtin = iso; - flag_iso = iso; - flag_isoc11 = 1; - flag_isoc99 = 1; - flag_isoc94 = 1; -} - -/* Set the C++ 98 standard (without GNU extensions if ISO). */ -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; - cxx_dialect = cxx98; -} - -/* Set the C++ 2011 standard (without GNU extensions if ISO). */ -static void -set_std_cxx11 (int iso) -{ - cpp_set_lang (parse_in, iso ? CLK_CXX11: CLK_GNUCXX11); - flag_no_gnu_keywords = iso; - flag_no_nonansi_builtin = iso; - flag_iso = iso; - /* C++11 includes the C99 standard library. */ - flag_isoc94 = 1; - flag_isoc99 = 1; - cxx_dialect = cxx11; -} - -/* Set the C++ 201y draft standard (without GNU extensions if ISO). */ -static void -set_std_cxx1y (int iso) -{ - cpp_set_lang (parse_in, iso ? CLK_CXX11: CLK_GNUCXX11); - flag_no_gnu_keywords = iso; - flag_no_nonansi_builtin = iso; - flag_iso = iso; - /* C++11 includes the C99 standard library. */ - flag_isoc94 = 1; - flag_isoc99 = 1; - cxx_dialect = cxx1y; -} - -/* Args to -d specify what to dump. Silently ignore - unrecognized options; they may be aimed at toplev.c. */ -static void -handle_OPT_d (const char *arg) -{ - char c; - - while ((c = *arg++) != '\0') - switch (c) - { - case 'M': /* Dump macros only. */ - case 'N': /* Dump names. */ - case 'D': /* Dump definitions. */ - case 'U': /* Dump used macros. */ - flag_dump_macros = c; - break; - - case 'I': - flag_dump_includes = 1; - break; - } -} diff --git a/gcc-4.8.1/gcc/c-family/c-pch.c b/gcc-4.8.1/gcc/c-family/c-pch.c deleted file mode 100644 index 7b0eca7fd..000000000 --- a/gcc-4.8.1/gcc/c-family/c-pch.c +++ /dev/null @@ -1,439 +0,0 @@ -/* Precompiled header implementation for the C languages. - Copyright (C) 2000-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "version.h" -#include "cpplib.h" -#include "tree.h" -#include "flags.h" -#include "c-common.h" -#include "debug.h" -#include "c-pragma.h" -#include "ggc.h" -#include "langhooks.h" -#include "hosthooks.h" -#include "target.h" -#include "opts.h" -#include "timevar.h" - -/* This is a list of flag variables that must match exactly, and their - names for the error message. The possible values for *flag_var must - fit in a 'signed char'. */ - -static const struct c_pch_matching -{ - int *flag_var; - const char *flag_name; -} pch_matching[] = { - { &flag_exceptions, "-fexceptions" }, -}; - -enum { - MATCH_SIZE = ARRAY_SIZE (pch_matching) -}; - -/* The value of the checksum in the dummy compiler that is actually - checksummed. That compiler should never be run. */ -static const char no_checksum[16] = { 0 }; - -/* Information about flags and suchlike that affect PCH validity. - - Before this structure is read, both an initial 8-character identification - string, and a 16-byte checksum, have been read and validated. */ - -struct c_pch_validity -{ - unsigned char debug_info_type; - signed char match[MATCH_SIZE]; - void (*pch_init) (void); - size_t target_data_length; -}; - -#define IDENT_LENGTH 8 - -/* The file we'll be writing the PCH to. */ -static FILE *pch_outfile; - -static const char *get_ident (void); - -/* Compute an appropriate 8-byte magic number for the PCH file, so that - utilities like file(1) can identify it, and so that GCC can quickly - ignore non-PCH files and PCH files that are of a completely different - format. */ - -static const char * -get_ident (void) -{ - static char result[IDENT_LENGTH]; - static const char templ[] = "gpch.014"; - static const char c_language_chars[] = "Co+O"; - - memcpy (result, templ, IDENT_LENGTH); - result[4] = c_language_chars[c_language]; - - return result; -} - -/* Whether preprocessor state should be saved by pch_init. */ - -static bool pch_ready_to_save_cpp_state = false; - -/* Prepare to write a PCH file, if one is being written. This is - called at the start of compilation. */ - -void -pch_init (void) -{ - FILE *f; - struct c_pch_validity v; - void *target_validity; - static const char partial_pch[] = "gpcWrite"; - - if (!pch_file) - return; - - f = fopen (pch_file, "w+b"); - if (f == NULL) - fatal_error ("can%'t create precompiled header %s: %m", pch_file); - pch_outfile = f; - - gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0); - - memset (&v, '\0', sizeof (v)); - v.debug_info_type = write_symbols; - { - size_t i; - for (i = 0; i < MATCH_SIZE; i++) - { - v.match[i] = *pch_matching[i].flag_var; - gcc_assert (v.match[i] == *pch_matching[i].flag_var); - } - } - v.pch_init = &pch_init; - target_validity = targetm.get_pch_validity (&v.target_data_length); - - if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1 - || fwrite (executable_checksum, 16, 1, f) != 1 - || fwrite (&v, sizeof (v), 1, f) != 1 - || fwrite (target_validity, v.target_data_length, 1, f) != 1) - fatal_error ("can%'t write to %s: %m", pch_file); - - /* Let the debugging format deal with the PCHness. */ - (*debug_hooks->handle_pch) (0); - - if (pch_ready_to_save_cpp_state) - pch_cpp_save_state (); - - XDELETE (target_validity); -} - -/* Whether preprocessor state has been saved in a PCH file. */ - -static bool pch_cpp_state_saved = false; - -/* Save preprocessor state in a PCH file, after implicitly included - headers have been read. If the PCH file has not yet been opened, - record that state should be saved when it is opened. */ - -void -pch_cpp_save_state (void) -{ - if (!pch_cpp_state_saved) - { - if (pch_outfile) - { - cpp_save_state (parse_in, pch_outfile); - pch_cpp_state_saved = true; - } - else - pch_ready_to_save_cpp_state = true; - } -} - -/* Write the PCH file. This is called at the end of a compilation which - will produce a PCH file. */ - -void -c_common_write_pch (void) -{ - timevar_push (TV_PCH_SAVE); - - targetm.prepare_pch_save (); - - (*debug_hooks->handle_pch) (1); - - cpp_write_pch_deps (parse_in, pch_outfile); - - gt_pch_save (pch_outfile); - - timevar_push (TV_PCH_CPP_SAVE); - cpp_write_pch_state (parse_in, pch_outfile); - timevar_pop (TV_PCH_CPP_SAVE); - - if (fseek (pch_outfile, 0, SEEK_SET) != 0 - || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1) - fatal_error ("can%'t write %s: %m", pch_file); - - fclose (pch_outfile); - - timevar_pop (TV_PCH_SAVE); -} - -/* Check the PCH file called NAME, open on FD, to see if it can be - used in this compilation. Return 1 if valid, 0 if the file can't - be used now but might be if it's seen later in the compilation, and - 2 if this file could never be used in the compilation. */ - -int -c_common_valid_pch (cpp_reader *pfile, const char *name, int fd) -{ - int sizeread; - int result; - char ident[IDENT_LENGTH + 16]; - const char *pch_ident; - struct c_pch_validity v; - - /* Perform a quick test of whether this is a valid - precompiled header for the current language. */ - - gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0); - - sizeread = read (fd, ident, IDENT_LENGTH + 16); - if (sizeread == -1) - fatal_error ("can%'t read %s: %m", name); - else if (sizeread != IDENT_LENGTH + 16) - { - if (cpp_get_options (pfile)->warn_invalid_pch) - cpp_error (pfile, CPP_DL_WARNING, "%s: too short to be a PCH file", - name); - return 2; - } - - pch_ident = get_ident(); - if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0) - { - if (cpp_get_options (pfile)->warn_invalid_pch) - { - if (memcmp (ident, pch_ident, 5) == 0) - /* It's a PCH, for the right language, but has the wrong version. - */ - cpp_error (pfile, CPP_DL_WARNING, - "%s: not compatible with this GCC version", name); - else if (memcmp (ident, pch_ident, 4) == 0) - /* It's a PCH for the wrong language. */ - cpp_error (pfile, CPP_DL_WARNING, "%s: not for %s", name, - lang_hooks.name); - else - /* Not any kind of PCH. */ - cpp_error (pfile, CPP_DL_WARNING, "%s: not a PCH file", name); - } - return 2; - } - if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0) - { - if (cpp_get_options (pfile)->warn_invalid_pch) - cpp_error (pfile, CPP_DL_WARNING, - "%s: created by a different GCC executable", name); - return 2; - } - - /* At this point, we know it's a PCH file created by this - executable, so it ought to be long enough that we can read a - c_pch_validity structure. */ - if (read (fd, &v, sizeof (v)) != sizeof (v)) - fatal_error ("can%'t read %s: %m", name); - - /* The allowable debug info combinations are that either the PCH file - was built with the same as is being used now, or the PCH file was - built for some kind of debug info but now none is in use. */ - if (v.debug_info_type != write_symbols - && write_symbols != NO_DEBUG) - { - if (cpp_get_options (pfile)->warn_invalid_pch) - cpp_error (pfile, CPP_DL_WARNING, - "%s: created with -g%s, but used with -g%s", name, - debug_type_names[v.debug_info_type], - debug_type_names[write_symbols]); - return 2; - } - - /* Check flags that must match exactly. */ - { - size_t i; - for (i = 0; i < MATCH_SIZE; i++) - if (*pch_matching[i].flag_var != v.match[i]) - { - if (cpp_get_options (pfile)->warn_invalid_pch) - cpp_error (pfile, CPP_DL_WARNING, - "%s: settings for %s do not match", name, - pch_matching[i].flag_name); - return 2; - } - } - - /* If the text segment was not loaded at the same address as it was - when the PCH file was created, function pointers loaded from the - PCH will not be valid. We could in theory remap all the function - pointers, but no support for that exists at present. - Since we have the same executable, it should only be necessary to - check one function. */ - if (v.pch_init != &pch_init) - { - if (cpp_get_options (pfile)->warn_invalid_pch) - cpp_error (pfile, CPP_DL_WARNING, - "%s: had text segment at different address", name); - return 2; - } - - /* Check the target-specific validity data. */ - { - void *this_file_data = xmalloc (v.target_data_length); - const char *msg; - - if ((size_t) read (fd, this_file_data, v.target_data_length) - != v.target_data_length) - fatal_error ("can%'t read %s: %m", name); - msg = targetm.pch_valid_p (this_file_data, v.target_data_length); - free (this_file_data); - if (msg != NULL) - { - if (cpp_get_options (pfile)->warn_invalid_pch) - cpp_error (pfile, CPP_DL_WARNING, "%s: %s", name, msg); - return 2; - } - } - - /* Check the preprocessor macros are the same as when the PCH was - generated. */ - - result = cpp_valid_state (pfile, name, fd); - if (result == -1) - return 2; - else - return result == 0; -} - -/* If non-NULL, this function is called after a precompile header file - is loaded. */ -void (*lang_post_pch_load) (void); - -/* Load in the PCH file NAME, open on FD. It was originally searched for - by ORIG_NAME. */ - -void -c_common_read_pch (cpp_reader *pfile, const char *name, - int fd, const char *orig_name ATTRIBUTE_UNUSED) -{ - FILE *f; - struct save_macro_data *smd; - expanded_location saved_loc; - bool saved_trace_includes; - - timevar_push (TV_PCH_RESTORE); - - f = fdopen (fd, "rb"); - if (f == NULL) - { - cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen"); - close (fd); - goto end; - } - - cpp_get_callbacks (parse_in)->valid_pch = NULL; - - /* Save the location and then restore it after reading the PCH. */ - saved_loc = expand_location (line_table->highest_line); - saved_trace_includes = line_table->trace_includes; - - timevar_push (TV_PCH_CPP_RESTORE); - cpp_prepare_state (pfile, &smd); - timevar_pop (TV_PCH_CPP_RESTORE); - - gt_pch_restore (f); - cpp_set_line_map (pfile, line_table); - rebuild_location_adhoc_htab (line_table); - - timevar_push (TV_PCH_CPP_RESTORE); - if (cpp_read_state (pfile, name, f, smd) != 0) - { - fclose (f); - timevar_pop (TV_PCH_CPP_RESTORE); - goto end; - } - timevar_pop (TV_PCH_CPP_RESTORE); - - - fclose (f); - - line_table->trace_includes = saved_trace_includes; - linemap_add (line_table, LC_ENTER, 0, saved_loc.file, saved_loc.line); - - /* Give the front end a chance to take action after a PCH file has - been loaded. */ - if (lang_post_pch_load) - (*lang_post_pch_load) (); - -end: - timevar_pop (TV_PCH_RESTORE); -} - -/* Indicate that no more PCH files should be read. */ - -void -c_common_no_more_pch (void) -{ - if (cpp_get_callbacks (parse_in)->valid_pch) - { - cpp_get_callbacks (parse_in)->valid_pch = NULL; - host_hooks.gt_pch_use_address (NULL, 0, -1, 0); - } -} - -/* Handle #pragma GCC pch_preprocess, to load in the PCH file. */ - -void -c_common_pch_pragma (cpp_reader *pfile, const char *name) -{ - int fd; - - if (!cpp_get_options (pfile)->preprocessed) - { - error ("pch_preprocess pragma should only be used with -fpreprocessed"); - inform (input_location, "use #include instead"); - return; - } - - fd = open (name, O_RDONLY | O_BINARY, 0666); - if (fd == -1) - fatal_error ("%s: couldn%'t open PCH file: %m", name); - - if (c_common_valid_pch (pfile, name, fd) != 1) - { - if (!cpp_get_options (pfile)->warn_invalid_pch) - inform (input_location, "use -Winvalid-pch for more information"); - fatal_error ("%s: PCH file was invalid", name); - } - - c_common_read_pch (pfile, name, fd, name); - - close (fd); -} - diff --git a/gcc-4.8.1/gcc/c-family/c-ppoutput.c b/gcc-4.8.1/gcc/c-family/c-ppoutput.c deleted file mode 100644 index 4a1534667..000000000 --- a/gcc-4.8.1/gcc/c-family/c-ppoutput.c +++ /dev/null @@ -1,668 +0,0 @@ -/* Preprocess only, using cpplib. - Copyright (C) 1995-2013 Free Software Foundation, Inc. - Written by Per Bothner, 1994-95. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "cpplib.h" -#include "../libcpp/internal.h" -#include "tree.h" -#include "c-common.h" /* For flags. */ -#include "c-pragma.h" /* For parse_in. */ - -/* Encapsulates state used to convert a stream of tokens into a text - file. */ -static struct -{ - FILE *outf; /* Stream to write to. */ - const cpp_token *prev; /* Previous token. */ - const cpp_token *source; /* Source token for spacing. */ - int src_line; /* Line number currently being written. */ - unsigned char printed; /* Nonzero if something output at line. */ - bool first_time; /* pp_file_change hasn't been called yet. */ - const char *src_file; /* Current source file. */ -} print; - -/* Defined and undefined macros being queued for output with -dU at - the next newline. */ -typedef struct macro_queue -{ - struct macro_queue *next; /* Next macro in the list. */ - char *macro; /* The name of the macro if not - defined, the full definition if - defined. */ -} macro_queue; -static macro_queue *define_queue, *undef_queue; - -/* General output routines. */ -static void scan_translation_unit (cpp_reader *); -static void print_lines_directives_only (int, const void *, size_t); -static void scan_translation_unit_directives_only (cpp_reader *); -static void scan_translation_unit_trad (cpp_reader *); -static void account_for_newlines (const unsigned char *, size_t); -static int dump_macro (cpp_reader *, cpp_hashnode *, void *); -static void dump_queued_macros (cpp_reader *); - -static void print_line_1 (source_location, const char*, FILE *); -static void print_line (source_location, const char *); -static void maybe_print_line_1 (source_location, FILE *); -static void maybe_print_line (source_location); -static void do_line_change (cpp_reader *, const cpp_token *, - source_location, int); - -/* Callback routines for the parser. Most of these are active only - in specific modes. */ -static void cb_line_change (cpp_reader *, const cpp_token *, int); -static void cb_define (cpp_reader *, source_location, cpp_hashnode *); -static void cb_undef (cpp_reader *, source_location, cpp_hashnode *); -static void cb_used_define (cpp_reader *, source_location, cpp_hashnode *); -static void cb_used_undef (cpp_reader *, source_location, cpp_hashnode *); -static void cb_include (cpp_reader *, source_location, const unsigned char *, - const char *, int, const cpp_token **); -static void cb_ident (cpp_reader *, source_location, const cpp_string *); -static void cb_def_pragma (cpp_reader *, source_location); -static void cb_read_pch (cpp_reader *pfile, const char *name, - int fd, const char *orig_name); - -/* Preprocess and output. */ -void -preprocess_file (cpp_reader *pfile) -{ - /* A successful cpp_read_main_file guarantees that we can call - cpp_scan_nooutput or cpp_get_token next. */ - if (flag_no_output && pfile->buffer) - { - /* Scan -included buffers, then the main file. */ - while (pfile->buffer->prev) - cpp_scan_nooutput (pfile); - cpp_scan_nooutput (pfile); - } - else if (cpp_get_options (pfile)->traditional) - scan_translation_unit_trad (pfile); - else if (cpp_get_options (pfile)->directives_only - && !cpp_get_options (pfile)->preprocessed) - scan_translation_unit_directives_only (pfile); - else - scan_translation_unit (pfile); - - /* -dM command line option. Should this be elsewhere? */ - if (flag_dump_macros == 'M') - cpp_forall_identifiers (pfile, dump_macro, NULL); - - /* Flush any pending output. */ - if (print.printed) - putc ('\n', print.outf); -} - -/* Set up the callbacks as appropriate. */ -void -init_pp_output (FILE *out_stream) -{ - cpp_callbacks *cb = cpp_get_callbacks (parse_in); - - if (!flag_no_output) - { - cb->line_change = cb_line_change; - /* Don't emit #pragma or #ident directives if we are processing - assembly language; the assembler may choke on them. */ - if (cpp_get_options (parse_in)->lang != CLK_ASM) - { - cb->ident = cb_ident; - cb->def_pragma = cb_def_pragma; - } - } - - if (flag_dump_includes) - cb->include = cb_include; - - if (flag_pch_preprocess) - { - cb->valid_pch = c_common_valid_pch; - cb->read_pch = cb_read_pch; - } - - if (flag_dump_macros == 'N' || flag_dump_macros == 'D') - { - cb->define = cb_define; - cb->undef = cb_undef; - } - - if (flag_dump_macros == 'U') - { - cb->before_define = dump_queued_macros; - cb->used_define = cb_used_define; - cb->used_undef = cb_used_undef; - } - - /* Initialize the print structure. */ - print.src_line = 1; - print.printed = 0; - print.prev = 0; - print.outf = out_stream; - print.first_time = 1; - print.src_file = ""; -} - -/* Writes out the preprocessed file, handling spacing and paste - avoidance issues. */ -static void -scan_translation_unit (cpp_reader *pfile) -{ - bool avoid_paste = false; - bool do_line_adjustments - = cpp_get_options (parse_in)->lang != CLK_ASM - && !flag_no_line_commands; - bool in_pragma = false; - - print.source = NULL; - for (;;) - { - source_location loc; - const cpp_token *token = cpp_get_token_with_location (pfile, &loc); - - if (token->type == CPP_PADDING) - { - avoid_paste = true; - if (print.source == NULL - || (!(print.source->flags & PREV_WHITE) - && token->val.source == NULL)) - print.source = token->val.source; - continue; - } - - if (token->type == CPP_EOF) - break; - - /* Subtle logic to output a space if and only if necessary. */ - if (avoid_paste) - { - int src_line = LOCATION_LINE (loc); - - if (print.source == NULL) - print.source = token; - - if (src_line != print.src_line - && do_line_adjustments - && !in_pragma) - { - do_line_change (pfile, token, loc, false); - putc (' ', print.outf); - } - else if (print.source->flags & PREV_WHITE - || (print.prev - && cpp_avoid_paste (pfile, print.prev, token)) - || (print.prev == NULL && token->type == CPP_HASH)) - putc (' ', print.outf); - } - else if (token->flags & PREV_WHITE) - { - int src_line = LOCATION_LINE (loc); - - if (src_line != print.src_line - && do_line_adjustments - && !in_pragma) - do_line_change (pfile, token, loc, false); - putc (' ', print.outf); - } - - avoid_paste = false; - print.source = NULL; - print.prev = token; - if (token->type == CPP_PRAGMA) - { - const char *space; - const char *name; - - maybe_print_line (token->src_loc); - fputs ("#pragma ", print.outf); - c_pp_lookup_pragma (token->val.pragma, &space, &name); - if (space) - fprintf (print.outf, "%s %s", space, name); - else - fprintf (print.outf, "%s", name); - print.printed = 1; - in_pragma = true; - } - else if (token->type == CPP_PRAGMA_EOL) - { - maybe_print_line (token->src_loc); - in_pragma = false; - } - else - { - if (cpp_get_options (parse_in)->debug) - linemap_dump_location (line_table, token->src_loc, - print.outf); - cpp_output_token (token, print.outf); - } - - if (token->type == CPP_COMMENT) - account_for_newlines (token->val.str.text, token->val.str.len); - } -} - -static void -print_lines_directives_only (int lines, const void *buf, size_t size) -{ - print.src_line += lines; - fwrite (buf, 1, size, print.outf); -} - -/* Writes out the preprocessed file, handling spacing and paste - avoidance issues. */ -static void -scan_translation_unit_directives_only (cpp_reader *pfile) -{ - struct _cpp_dir_only_callbacks cb; - - cb.print_lines = print_lines_directives_only; - cb.maybe_print_line = maybe_print_line; - - _cpp_preprocess_dir_only (pfile, &cb); -} - -/* Adjust print.src_line for newlines embedded in output. */ -static void -account_for_newlines (const unsigned char *str, size_t len) -{ - while (len--) - if (*str++ == '\n') - print.src_line++; -} - -/* Writes out a traditionally preprocessed file. */ -static void -scan_translation_unit_trad (cpp_reader *pfile) -{ - while (_cpp_read_logical_line_trad (pfile)) - { - size_t len = pfile->out.cur - pfile->out.base; - maybe_print_line (pfile->out.first_line); - fwrite (pfile->out.base, 1, len, print.outf); - print.printed = 1; - if (!CPP_OPTION (pfile, discard_comments)) - account_for_newlines (pfile->out.base, len); - } -} - -/* If the token read on logical line LINE needs to be output on a - different line to the current one, output the required newlines or - a line marker, and return 1. Otherwise return 0. */ - -static void -maybe_print_line_1 (source_location src_loc, FILE *stream) -{ - int src_line = LOCATION_LINE (src_loc); - const char *src_file = LOCATION_FILE (src_loc); - - /* End the previous line of text. */ - if (print.printed) - { - putc ('\n', stream); - print.src_line++; - print.printed = 0; - } - - if (!flag_no_line_commands - && src_line >= print.src_line - && src_line < print.src_line + 8 - && strcmp (src_file, print.src_file) == 0) - { - while (src_line > print.src_line) - { - putc ('\n', stream); - print.src_line++; - } - } - else - print_line_1 (src_loc, "", stream); - -} - -/* If the token read on logical line LINE needs to be output on a - different line to the current one, output the required newlines or - a line marker, and return 1. Otherwise return 0. */ - -static void -maybe_print_line (source_location src_loc) -{ - if (cpp_get_options (parse_in)->debug) - linemap_dump_location (line_table, src_loc, - print.outf); - maybe_print_line_1 (src_loc, print.outf); -} - -/* Output a line marker for logical line LINE. Special flags are "1" - or "2" indicating entering or leaving a file. */ - -static void -print_line_1 (source_location src_loc, const char *special_flags, FILE *stream) -{ - /* End any previous line of text. */ - if (print.printed) - putc ('\n', stream); - print.printed = 0; - - if (!flag_no_line_commands) - { - const char *file_path = LOCATION_FILE (src_loc); - int sysp; - size_t to_file_len = strlen (file_path); - unsigned char *to_file_quoted = - (unsigned char *) alloca (to_file_len * 4 + 1); - unsigned char *p; - - print.src_line = LOCATION_LINE (src_loc); - print.src_file = file_path; - - /* cpp_quote_string does not nul-terminate, so we have to do it - ourselves. */ - p = cpp_quote_string (to_file_quoted, - (const unsigned char *) file_path, - to_file_len); - *p = '\0'; - fprintf (stream, "# %u \"%s\"%s", - print.src_line == 0 ? 1 : print.src_line, - to_file_quoted, special_flags); - - sysp = in_system_header_at (src_loc); - if (sysp == 2) - fputs (" 3 4", stream); - else if (sysp == 1) - fputs (" 3", stream); - - putc ('\n', stream); - } -} - -/* Output a line marker for logical line LINE. Special flags are "1" - or "2" indicating entering or leaving a file. */ - -static void -print_line (source_location src_loc, const char *special_flags) -{ - if (cpp_get_options (parse_in)->debug) - linemap_dump_location (line_table, src_loc, - print.outf); - print_line_1 (src_loc, special_flags, print.outf); -} - -/* Helper function for cb_line_change and scan_translation_unit. */ -static void -do_line_change (cpp_reader *pfile, const cpp_token *token, - source_location src_loc, int parsing_args) -{ - if (define_queue || undef_queue) - dump_queued_macros (pfile); - - if (token->type == CPP_EOF || parsing_args) - return; - - maybe_print_line (src_loc); - print.prev = 0; - print.source = 0; - - /* Supply enough spaces to put this token in its original column, - one space per column greater than 2, since scan_translation_unit - will provide a space if PREV_WHITE. Don't bother trying to - reconstruct tabs; we can't get it right in general, and nothing - ought to care. Some things do care; the fault lies with them. */ - if (!CPP_OPTION (pfile, traditional)) - { - int spaces = LOCATION_COLUMN (src_loc) - 2; - print.printed = 1; - - while (-- spaces >= 0) - putc (' ', print.outf); - } -} - -/* Called when a line of output is started. TOKEN is the first token - of the line, and at end of file will be CPP_EOF. */ -static void -cb_line_change (cpp_reader *pfile, const cpp_token *token, - int parsing_args) -{ - do_line_change (pfile, token, token->src_loc, parsing_args); -} - -static void -cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, - const cpp_string *str) -{ - maybe_print_line (line); - fprintf (print.outf, "#ident %s\n", str->text); - print.src_line++; -} - -static void -cb_define (cpp_reader *pfile, source_location line, cpp_hashnode *node) -{ - const struct line_map *map; - - maybe_print_line (line); - fputs ("#define ", print.outf); - - /* 'D' is whole definition; 'N' is name only. */ - if (flag_dump_macros == 'D') - fputs ((const char *) cpp_macro_definition (pfile, node), - print.outf); - else - fputs ((const char *) NODE_NAME (node), print.outf); - - putc ('\n', print.outf); - linemap_resolve_location (line_table, line, - LRK_MACRO_DEFINITION_LOCATION, - &map); - if (LINEMAP_LINE (map) != 0) - print.src_line++; -} - -static void -cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, - cpp_hashnode *node) -{ - maybe_print_line (line); - fprintf (print.outf, "#undef %s\n", NODE_NAME (node)); - print.src_line++; -} - -static void -cb_used_define (cpp_reader *pfile, source_location line ATTRIBUTE_UNUSED, - cpp_hashnode *node) -{ - macro_queue *q; - if (node->flags & NODE_BUILTIN) - return; - q = XNEW (macro_queue); - q->macro = xstrdup ((const char *) cpp_macro_definition (pfile, node)); - q->next = define_queue; - define_queue = q; -} - -static void -cb_used_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, - source_location line ATTRIBUTE_UNUSED, - cpp_hashnode *node) -{ - macro_queue *q; - q = XNEW (macro_queue); - q->macro = xstrdup ((const char *) NODE_NAME (node)); - q->next = undef_queue; - undef_queue = q; -} - -static void -dump_queued_macros (cpp_reader *pfile ATTRIBUTE_UNUSED) -{ - macro_queue *q; - - /* End the previous line of text. */ - if (print.printed) - { - putc ('\n', print.outf); - print.src_line++; - print.printed = 0; - } - - for (q = define_queue; q;) - { - macro_queue *oq; - fputs ("#define ", print.outf); - fputs (q->macro, print.outf); - putc ('\n', print.outf); - print.src_line++; - oq = q; - q = q->next; - free (oq->macro); - free (oq); - } - define_queue = NULL; - for (q = undef_queue; q;) - { - macro_queue *oq; - fprintf (print.outf, "#undef %s\n", q->macro); - print.src_line++; - oq = q; - q = q->next; - free (oq->macro); - free (oq); - } - undef_queue = NULL; -} - -static void -cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, - const unsigned char *dir, const char *header, int angle_brackets, - const cpp_token **comments) -{ - maybe_print_line (line); - if (angle_brackets) - fprintf (print.outf, "#%s <%s>", dir, header); - else - fprintf (print.outf, "#%s \"%s\"", dir, header); - - if (comments != NULL) - { - while (*comments != NULL) - { - if ((*comments)->flags & PREV_WHITE) - putc (' ', print.outf); - cpp_output_token (*comments, print.outf); - ++comments; - } - } - - putc ('\n', print.outf); - print.src_line++; -} - -/* Callback called when -fworking-director and -E to emit working - directory in cpp output file. */ - -void -pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir) -{ - size_t to_file_len = strlen (dir); - unsigned char *to_file_quoted = - (unsigned char *) alloca (to_file_len * 4 + 1); - unsigned char *p; - - /* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */ - p = cpp_quote_string (to_file_quoted, (const unsigned char *) dir, to_file_len); - *p = '\0'; - fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted); -} - -/* The file name, line number or system header flags have changed, as - described in MAP. */ - -void -pp_file_change (const struct line_map *map) -{ - const char *flags = ""; - - if (flag_no_line_commands) - return; - - if (map != NULL) - { - input_location = map->start_location; - if (print.first_time) - { - /* Avoid printing foo.i when the main file is foo.c. */ - if (!cpp_get_options (parse_in)->preprocessed) - print_line (map->start_location, flags); - print.first_time = 0; - } - else - { - /* Bring current file to correct line when entering a new file. */ - if (map->reason == LC_ENTER) - { - const struct line_map *from = INCLUDED_FROM (line_table, map); - maybe_print_line (LAST_SOURCE_LINE_LOCATION (from)); - } - if (map->reason == LC_ENTER) - flags = " 1"; - else if (map->reason == LC_LEAVE) - flags = " 2"; - print_line (map->start_location, flags); - } - } -} - -/* Copy a #pragma directive to the preprocessed output. */ -static void -cb_def_pragma (cpp_reader *pfile, source_location line) -{ - maybe_print_line (line); - fputs ("#pragma ", print.outf); - cpp_output_line (pfile, print.outf); - print.src_line++; -} - -/* Dump out the hash table. */ -static int -dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED) -{ - if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) - { - fputs ("#define ", print.outf); - fputs ((const char *) cpp_macro_definition (pfile, node), - print.outf); - putc ('\n', print.outf); - print.src_line++; - } - - return 1; -} - -/* Load in the PCH file NAME, open on FD. It was originally searched for - by ORIG_NAME. Also, print out a #include command so that the PCH - file can be loaded when the preprocessed output is compiled. */ - -static void -cb_read_pch (cpp_reader *pfile, const char *name, - int fd, const char *orig_name ATTRIBUTE_UNUSED) -{ - c_common_read_pch (pfile, name, fd, orig_name); - - fprintf (print.outf, "#pragma GCC pch_preprocess \"%s\"\n", name); - print.src_line++; -} diff --git a/gcc-4.8.1/gcc/c-family/c-pragma.c b/gcc-4.8.1/gcc/c-family/c-pragma.c deleted file mode 100644 index 7d8a1a605..000000000 --- a/gcc-4.8.1/gcc/c-family/c-pragma.c +++ /dev/null @@ -1,1382 +0,0 @@ -/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack. - Copyright (C) 1992-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "tree.h" -#include "function.h" /* For cfun. FIXME: Does the parser know - when it is inside a function, so that - we don't have to look at cfun? */ -#include "cpplib.h" -#include "c-pragma.h" -#include "flags.h" -#include "c-common.h" -#include "tm_p.h" /* For REGISTER_TARGET_PRAGMAS (why is - this not a target hook?). */ -#include "vec.h" -#include "target.h" -#include "diagnostic.h" -#include "opts.h" -#include "plugin.h" -#include "cgraph.h" - -#define GCC_BAD(gmsgid) \ - do { warning (OPT_Wpragmas, gmsgid); return; } while (0) -#define GCC_BAD2(gmsgid, arg) \ - do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0) - -typedef struct GTY(()) align_stack { - int alignment; - tree id; - struct align_stack * prev; -} align_stack; - -static GTY(()) struct align_stack * alignment_stack; - -static void handle_pragma_pack (cpp_reader *); - -/* If we have a "global" #pragma pack(<n>) in effect when the first - #pragma pack(push,<n>) is encountered, this stores the value of - maximum_field_alignment in effect. When the final pop_alignment() - happens, we restore the value to this, not to a value of 0 for - maximum_field_alignment. Value is in bits. */ -static int default_alignment; -#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = *(alignment_stack == NULL \ - ? &default_alignment \ - : &alignment_stack->alignment) = (ALIGN)) - -static void push_alignment (int, tree); -static void pop_alignment (tree); - -/* Push an alignment value onto the stack. */ -static void -push_alignment (int alignment, tree id) -{ - align_stack * entry; - - entry = ggc_alloc_align_stack (); - - entry->alignment = alignment; - entry->id = id; - entry->prev = alignment_stack; - - /* The current value of maximum_field_alignment is not necessarily - 0 since there may be a #pragma pack(<n>) in effect; remember it - so that we can restore it after the final #pragma pop(). */ - if (alignment_stack == NULL) - default_alignment = maximum_field_alignment; - - alignment_stack = entry; - - maximum_field_alignment = alignment; -} - -/* Undo a push of an alignment onto the stack. */ -static void -pop_alignment (tree id) -{ - align_stack * entry; - - if (alignment_stack == NULL) - GCC_BAD ("#pragma pack (pop) encountered without matching #pragma pack (push)"); - - /* If we got an identifier, strip away everything above the target - entry so that the next step will restore the state just below it. */ - if (id) - { - for (entry = alignment_stack; entry; entry = entry->prev) - if (entry->id == id) - { - alignment_stack = entry; - break; - } - if (entry == NULL) - warning (OPT_Wpragmas, "\ -#pragma pack(pop, %E) encountered without matching #pragma pack(push, %E)" - , id, id); - } - - entry = alignment_stack->prev; - - maximum_field_alignment = entry ? entry->alignment : default_alignment; - - alignment_stack = entry; -} - -/* #pragma pack () - #pragma pack (N) - - #pragma pack (push) - #pragma pack (push, N) - #pragma pack (push, ID) - #pragma pack (push, ID, N) - #pragma pack (pop) - #pragma pack (pop, ID) */ -static void -handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy)) -{ - tree x, id = 0; - int align = -1; - enum cpp_ttype token; - enum { set, push, pop } action; - - if (pragma_lex (&x) != CPP_OPEN_PAREN) - GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored"); - - token = pragma_lex (&x); - if (token == CPP_CLOSE_PAREN) - { - action = set; - align = initial_max_fld_align; - } - else if (token == CPP_NUMBER) - { - if (TREE_CODE (x) != INTEGER_CST) - GCC_BAD ("invalid constant in %<#pragma pack%> - ignored"); - align = TREE_INT_CST_LOW (x); - action = set; - if (pragma_lex (&x) != CPP_CLOSE_PAREN) - GCC_BAD ("malformed %<#pragma pack%> - ignored"); - } - else if (token == CPP_NAME) - { -#define GCC_BAD_ACTION do { if (action != pop) \ - GCC_BAD ("malformed %<#pragma pack(push[, id][, <n>])%> - ignored"); \ - else \ - GCC_BAD ("malformed %<#pragma pack(pop[, id])%> - ignored"); \ - } while (0) - - const char *op = IDENTIFIER_POINTER (x); - if (!strcmp (op, "push")) - action = push; - else if (!strcmp (op, "pop")) - action = pop; - else - GCC_BAD2 ("unknown action %qE for %<#pragma pack%> - ignored", x); - - while ((token = pragma_lex (&x)) == CPP_COMMA) - { - token = pragma_lex (&x); - if (token == CPP_NAME && id == 0) - { - id = x; - } - else if (token == CPP_NUMBER && action == push && align == -1) - { - if (TREE_CODE (x) != INTEGER_CST) - GCC_BAD ("invalid constant in %<#pragma pack%> - ignored"); - align = TREE_INT_CST_LOW (x); - if (align == -1) - action = set; - } - else - GCC_BAD_ACTION; - } - - if (token != CPP_CLOSE_PAREN) - GCC_BAD_ACTION; -#undef GCC_BAD_ACTION - } - else - GCC_BAD ("malformed %<#pragma pack%> - ignored"); - - if (pragma_lex (&x) != CPP_EOF) - warning (OPT_Wpragmas, "junk at end of %<#pragma pack%>"); - - if (flag_pack_struct) - GCC_BAD ("#pragma pack has no effect with -fpack-struct - ignored"); - - if (action != pop) - switch (align) - { - case 0: - case 1: - case 2: - case 4: - case 8: - case 16: - align *= BITS_PER_UNIT; - break; - case -1: - if (action == push) - { - align = maximum_field_alignment; - break; - } - default: - GCC_BAD2 ("alignment must be a small power of two, not %d", align); - } - - switch (action) - { - case set: SET_GLOBAL_ALIGNMENT (align); break; - case push: push_alignment (align, id); break; - case pop: pop_alignment (id); break; - } -} - -typedef struct GTY(()) pending_weak_d -{ - tree name; - tree value; -} pending_weak; - - -static GTY(()) vec<pending_weak, va_gc> *pending_weaks; - -static void apply_pragma_weak (tree, tree); -static void handle_pragma_weak (cpp_reader *); - -static void -apply_pragma_weak (tree decl, tree value) -{ - if (value) - { - value = build_string (IDENTIFIER_LENGTH (value), - IDENTIFIER_POINTER (value)); - decl_attributes (&decl, build_tree_list (get_identifier ("alias"), - build_tree_list (NULL, value)), - 0); - } - - if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl) - && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma. */ - && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) - warning (OPT_Wpragmas, "applying #pragma weak %q+D after first use " - "results in unspecified behavior", decl); - - declare_weak (decl); -} - -void -maybe_apply_pragma_weak (tree decl) -{ - tree id; - int i; - pending_weak *pe; - - /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed. */ - - /* No weak symbols pending, take the short-cut. */ - if (!pending_weaks) - return; - /* If it's not visible outside this file, it doesn't matter whether - it's weak. */ - if (!DECL_EXTERNAL (decl) && !TREE_PUBLIC (decl)) - return; - /* If it's not a function or a variable, it can't be weak. - FIXME: what kinds of things are visible outside this file but - aren't functions or variables? Should this be an assert instead? */ - if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL) - return; - - id = DECL_ASSEMBLER_NAME (decl); - - FOR_EACH_VEC_ELT (*pending_weaks, i, pe) - if (id == pe->name) - { - apply_pragma_weak (decl, pe->value); - pending_weaks->unordered_remove (i); - break; - } -} - -/* Process all "#pragma weak A = B" directives where we have not seen - a decl for A. */ -void -maybe_apply_pending_pragma_weaks (void) -{ - tree alias_id, id, decl; - int i; - pending_weak *pe; - symtab_node target; - - if (!pending_weaks) - return; - - FOR_EACH_VEC_ELT (*pending_weaks, i, pe) - { - alias_id = pe->name; - id = pe->value; - - if (id == NULL) - continue; - - target = symtab_node_for_asm (id); - decl = build_decl (UNKNOWN_LOCATION, - target ? TREE_CODE (target->symbol.decl) : FUNCTION_DECL, - alias_id, default_function_type); - - DECL_ARTIFICIAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - DECL_WEAK (decl) = 1; - if (TREE_CODE (decl) == VAR_DECL) - TREE_STATIC (decl) = 1; - if (!target) - { - error ("%q+D aliased to undefined symbol %qE", - decl, id); - continue; - } - - assemble_alias (decl, id); - } -} - -/* #pragma weak name [= value] */ -static void -handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy)) -{ - tree name, value, x, decl; - enum cpp_ttype t; - - value = 0; - - if (pragma_lex (&name) != CPP_NAME) - GCC_BAD ("malformed #pragma weak, ignored"); - t = pragma_lex (&x); - if (t == CPP_EQ) - { - if (pragma_lex (&value) != CPP_NAME) - GCC_BAD ("malformed #pragma weak, ignored"); - t = pragma_lex (&x); - } - if (t != CPP_EOF) - warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>"); - - decl = identifier_global_value (name); - if (decl && DECL_P (decl)) - { - apply_pragma_weak (decl, value); - if (value) - assemble_alias (decl, value); - } - else - { - pending_weak pe = {name, value}; - vec_safe_push (pending_weaks, pe); - } -} - -/* GCC supports two #pragma directives for renaming the external - symbol associated with a declaration (DECL_ASSEMBLER_NAME), for - compatibility with the Solaris and VMS system headers. GCC also - has its own notation for this, __asm__("name") annotations. - - Corner cases of these features and their interaction: - - 1) Both pragmas silently apply only to declarations with external - linkage (that is, TREE_PUBLIC || DECL_EXTERNAL). Asm labels - do not have this restriction. - - 2) In C++, both #pragmas silently apply only to extern "C" declarations. - Asm labels do not have this restriction. - - 3) If any of the three ways of changing DECL_ASSEMBLER_NAME is - applied to a decl whose DECL_ASSEMBLER_NAME is already set, and the - new name is different, a warning issues and the name does not change. - - 4) The "source name" for #pragma redefine_extname is the DECL_NAME, - *not* the DECL_ASSEMBLER_NAME. - - 5) If #pragma extern_prefix is in effect and a declaration occurs - with an __asm__ name, the #pragma extern_prefix is silently - ignored for that declaration. - - 6) If #pragma extern_prefix and #pragma redefine_extname apply to - the same declaration, whichever triggered first wins, and a warning - is issued. (We would like to have #pragma redefine_extname always - win, but it can appear either before or after the declaration, and - if it appears afterward, we have no way of knowing whether a modified - DECL_ASSEMBLER_NAME is due to #pragma extern_prefix.) */ - -typedef struct GTY(()) pending_redefinition_d { - tree oldname; - tree newname; -} pending_redefinition; - - -static GTY(()) vec<pending_redefinition, va_gc> *pending_redefine_extname; - -static void handle_pragma_redefine_extname (cpp_reader *); - -/* #pragma redefine_extname oldname newname */ -static void -handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy)) -{ - tree oldname, newname, decls, x; - enum cpp_ttype t; - bool found; - - if (pragma_lex (&oldname) != CPP_NAME) - GCC_BAD ("malformed #pragma redefine_extname, ignored"); - if (pragma_lex (&newname) != CPP_NAME) - GCC_BAD ("malformed #pragma redefine_extname, ignored"); - t = pragma_lex (&x); - if (t != CPP_EOF) - warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>"); - - found = false; - for (decls = c_linkage_bindings (oldname); - decls; ) - { - tree decl; - if (TREE_CODE (decls) == TREE_LIST) - { - decl = TREE_VALUE (decls); - decls = TREE_CHAIN (decls); - } - else - { - decl = decls; - decls = NULL_TREE; - } - - if ((TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)) - && (TREE_CODE (decl) == FUNCTION_DECL - || TREE_CODE (decl) == VAR_DECL)) - { - found = true; - if (DECL_ASSEMBLER_NAME_SET_P (decl)) - { - const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - name = targetm.strip_name_encoding (name); - - if (strcmp (name, IDENTIFIER_POINTER (newname))) - warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " - "conflict with previous rename"); - } - else - change_decl_assembler_name (decl, newname); - } - } - - if (!found) - /* We have to add this to the rename list even if there's already - a global value that doesn't meet the above criteria, because in - C++ "struct foo {...};" puts "foo" in the current namespace but - does *not* conflict with a subsequent declaration of a function - or variable foo. See g++.dg/other/pragma-re-2.C. */ - add_to_renaming_pragma_list (oldname, newname); -} - -/* This is called from here and from ia64.c. */ -void -add_to_renaming_pragma_list (tree oldname, tree newname) -{ - unsigned ix; - pending_redefinition *p; - - FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p) - if (oldname == p->oldname) - { - if (p->newname != newname) - warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " - "conflict with previous #pragma redefine_extname"); - return; - } - - pending_redefinition e = {oldname, newname}; - vec_safe_push (pending_redefine_extname, e); -} - -/* The current prefix set by #pragma extern_prefix. */ -GTY(()) tree pragma_extern_prefix; - -/* Hook from the front ends to apply the results of one of the preceding - pragmas that rename variables. */ - -tree -maybe_apply_renaming_pragma (tree decl, tree asmname) -{ - unsigned ix; - pending_redefinition *p; - - /* The renaming pragmas are only applied to declarations with - external linkage. */ - if ((TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL) - || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) - || !has_c_linkage (decl)) - return asmname; - - /* If the DECL_ASSEMBLER_NAME is already set, it does not change, - but we may warn about a rename that conflicts. */ - if (DECL_ASSEMBLER_NAME_SET_P (decl)) - { - const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - oldname = targetm.strip_name_encoding (oldname); - - if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname)) - warning (OPT_Wpragmas, "asm declaration ignored due to " - "conflict with previous rename"); - - /* Take any pending redefine_extname off the list. */ - FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p) - if (DECL_NAME (decl) == p->oldname) - { - /* Only warn if there is a conflict. */ - if (strcmp (IDENTIFIER_POINTER (p->newname), oldname)) - warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " - "conflict with previous rename"); - - pending_redefine_extname->unordered_remove (ix); - break; - } - return 0; - } - - /* Find out if we have a pending #pragma redefine_extname. */ - FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p) - if (DECL_NAME (decl) == p->oldname) - { - tree newname = p->newname; - pending_redefine_extname->unordered_remove (ix); - - /* If we already have an asmname, #pragma redefine_extname is - ignored (with a warning if it conflicts). */ - if (asmname) - { - if (strcmp (TREE_STRING_POINTER (asmname), - IDENTIFIER_POINTER (newname)) != 0) - warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " - "conflict with __asm__ declaration"); - return asmname; - } - - /* Otherwise we use what we've got; #pragma extern_prefix is - silently ignored. */ - return build_string (IDENTIFIER_LENGTH (newname), - IDENTIFIER_POINTER (newname)); - } - - /* If we've got an asmname, #pragma extern_prefix is silently ignored. */ - if (asmname) - return asmname; - - /* If #pragma extern_prefix is in effect, apply it. */ - if (pragma_extern_prefix) - { - const char *prefix = TREE_STRING_POINTER (pragma_extern_prefix); - size_t plen = TREE_STRING_LENGTH (pragma_extern_prefix) - 1; - - const char *id = IDENTIFIER_POINTER (DECL_NAME (decl)); - size_t ilen = IDENTIFIER_LENGTH (DECL_NAME (decl)); - - char *newname = (char *) alloca (plen + ilen + 1); - - memcpy (newname, prefix, plen); - memcpy (newname + plen, id, ilen + 1); - - return build_string (plen + ilen, newname); - } - - /* Nada. */ - return 0; -} - - -static void handle_pragma_visibility (cpp_reader *); - -static vec<int> visstack; - -/* Push the visibility indicated by STR onto the top of the #pragma - visibility stack. KIND is 0 for #pragma GCC visibility, 1 for - C++ namespace with visibility attribute and 2 for C++ builtin - ABI namespace. push_visibility/pop_visibility calls must have - matching KIND, it is not allowed to push visibility using one - KIND and pop using a different one. */ - -void -push_visibility (const char *str, int kind) -{ - visstack.safe_push (((int) default_visibility) | (kind << 8)); - if (!strcmp (str, "default")) - default_visibility = VISIBILITY_DEFAULT; - else if (!strcmp (str, "internal")) - default_visibility = VISIBILITY_INTERNAL; - else if (!strcmp (str, "hidden")) - default_visibility = VISIBILITY_HIDDEN; - else if (!strcmp (str, "protected")) - default_visibility = VISIBILITY_PROTECTED; - else - GCC_BAD ("#pragma GCC visibility push() must specify default, internal, hidden or protected"); - visibility_options.inpragma = 1; -} - -/* Pop a level of the #pragma visibility stack. Return true if - successful. */ - -bool -pop_visibility (int kind) -{ - if (!visstack.length ()) - return false; - if ((visstack.last () >> 8) != kind) - return false; - default_visibility - = (enum symbol_visibility) (visstack.pop () & 0xff); - visibility_options.inpragma - = visstack.length () != 0; - return true; -} - -/* Sets the default visibility for symbols to something other than that - specified on the command line. */ - -static void -handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED) -{ - /* Form is #pragma GCC visibility push(hidden)|pop */ - tree x; - enum cpp_ttype token; - enum { bad, push, pop } action = bad; - - token = pragma_lex (&x); - if (token == CPP_NAME) - { - const char *op = IDENTIFIER_POINTER (x); - if (!strcmp (op, "push")) - action = push; - else if (!strcmp (op, "pop")) - action = pop; - } - if (bad == action) - GCC_BAD ("#pragma GCC visibility must be followed by push or pop"); - else - { - if (pop == action) - { - if (! pop_visibility (0)) - GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>"); - } - else - { - if (pragma_lex (&x) != CPP_OPEN_PAREN) - GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored"); - token = pragma_lex (&x); - if (token != CPP_NAME) - GCC_BAD ("malformed #pragma GCC visibility push"); - else - push_visibility (IDENTIFIER_POINTER (x), 0); - if (pragma_lex (&x) != CPP_CLOSE_PAREN) - GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored"); - } - } - if (pragma_lex (&x) != CPP_EOF) - warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>"); -} - -static void -handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy)) -{ - const char *kind_string, *option_string; - unsigned int option_index; - enum cpp_ttype token; - diagnostic_t kind; - tree x; - struct cl_option_handlers handlers; - - token = pragma_lex (&x); - if (token != CPP_NAME) - GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>"); - kind_string = IDENTIFIER_POINTER (x); - if (strcmp (kind_string, "error") == 0) - kind = DK_ERROR; - else if (strcmp (kind_string, "warning") == 0) - kind = DK_WARNING; - else if (strcmp (kind_string, "ignored") == 0) - kind = DK_IGNORED; - else if (strcmp (kind_string, "push") == 0) - { - diagnostic_push_diagnostics (global_dc, input_location); - return; - } - else if (strcmp (kind_string, "pop") == 0) - { - diagnostic_pop_diagnostics (global_dc, input_location); - return; - } - else - GCC_BAD ("expected [error|warning|ignored|push|pop] after %<#pragma GCC diagnostic%>"); - - token = pragma_lex (&x); - if (token != CPP_STRING) - GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind"); - option_string = TREE_STRING_POINTER (x); - set_default_handlers (&handlers); - for (option_index = 0; option_index < cl_options_count; option_index++) - if (strcmp (cl_options[option_index].opt_text, option_string) == 0) - { - control_warning_option (option_index, (int) kind, kind != DK_IGNORED, - input_location, c_family_lang_mask, &handlers, - &global_options, &global_options_set, - global_dc); - return; - } - GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind"); -} - -/* Parse #pragma GCC target (xxx) to set target specific options. */ -static void -handle_pragma_target(cpp_reader *ARG_UNUSED(dummy)) -{ - enum cpp_ttype token; - tree x; - bool close_paren_needed_p = false; - - if (cfun) - { - error ("#pragma GCC option is not allowed inside functions"); - return; - } - - token = pragma_lex (&x); - if (token == CPP_OPEN_PAREN) - { - close_paren_needed_p = true; - token = pragma_lex (&x); - } - - if (token != CPP_STRING) - { - GCC_BAD ("%<#pragma GCC option%> is not a string"); - return; - } - - /* Strings are user options. */ - else - { - tree args = NULL_TREE; - - do - { - /* Build up the strings now as a tree linked list. Skip empty - strings. */ - if (TREE_STRING_LENGTH (x) > 0) - args = tree_cons (NULL_TREE, x, args); - - token = pragma_lex (&x); - while (token == CPP_COMMA) - token = pragma_lex (&x); - } - while (token == CPP_STRING); - - if (close_paren_needed_p) - { - if (token == CPP_CLOSE_PAREN) - token = pragma_lex (&x); - else - GCC_BAD ("%<#pragma GCC target (string [,string]...)%> does " - "not have a final %<)%>"); - } - - if (token != CPP_EOF) - { - error ("#pragma GCC target string... is badly formed"); - return; - } - - /* put arguments in the order the user typed them. */ - args = nreverse (args); - - if (targetm.target_option.pragma_parse (args, NULL_TREE)) - current_target_pragma = args; - } -} - -/* Handle #pragma GCC optimize to set optimization options. */ -static void -handle_pragma_optimize (cpp_reader *ARG_UNUSED(dummy)) -{ - enum cpp_ttype token; - tree x; - bool close_paren_needed_p = false; - tree optimization_previous_node = optimization_current_node; - - if (cfun) - { - error ("#pragma GCC optimize is not allowed inside functions"); - return; - } - - token = pragma_lex (&x); - if (token == CPP_OPEN_PAREN) - { - close_paren_needed_p = true; - token = pragma_lex (&x); - } - - if (token != CPP_STRING && token != CPP_NUMBER) - { - GCC_BAD ("%<#pragma GCC optimize%> is not a string or number"); - return; - } - - /* Strings/numbers are user options. */ - else - { - tree args = NULL_TREE; - - do - { - /* Build up the numbers/strings now as a list. */ - if (token != CPP_STRING || TREE_STRING_LENGTH (x) > 0) - args = tree_cons (NULL_TREE, x, args); - - token = pragma_lex (&x); - while (token == CPP_COMMA) - token = pragma_lex (&x); - } - while (token == CPP_STRING || token == CPP_NUMBER); - - if (close_paren_needed_p) - { - if (token == CPP_CLOSE_PAREN) - token = pragma_lex (&x); - else - GCC_BAD ("%<#pragma GCC optimize (string [,string]...)%> does " - "not have a final %<)%>"); - } - - if (token != CPP_EOF) - { - error ("#pragma GCC optimize string... is badly formed"); - return; - } - - /* put arguments in the order the user typed them. */ - args = nreverse (args); - - parse_optimize_options (args, false); - current_optimize_pragma = chainon (current_optimize_pragma, args); - optimization_current_node = build_optimization_node (); - c_cpp_builtins_optimize_pragma (parse_in, - optimization_previous_node, - optimization_current_node); - } -} - -/* Stack of the #pragma GCC options created with #pragma GCC push_option. Save - both the binary representation of the options and the TREE_LIST of - strings that will be added to the function's attribute list. */ -typedef struct GTY(()) opt_stack { - struct opt_stack *prev; - tree target_binary; - tree target_strings; - tree optimize_binary; - tree optimize_strings; -} opt_stack; - -static GTY(()) struct opt_stack * options_stack; - -/* Handle #pragma GCC push_options to save the current target and optimization - options. */ - -static void -handle_pragma_push_options (cpp_reader *ARG_UNUSED(dummy)) -{ - enum cpp_ttype token; - tree x = 0; - opt_stack *p; - - token = pragma_lex (&x); - if (token != CPP_EOF) - { - warning (OPT_Wpragmas, "junk at end of %<#pragma push_options%>"); - return; - } - - p = ggc_alloc_opt_stack (); - p->prev = options_stack; - options_stack = p; - - /* Save optimization and target flags in binary format. */ - p->optimize_binary = build_optimization_node (); - p->target_binary = build_target_option_node (); - - /* Save optimization and target flags in string list format. */ - p->optimize_strings = copy_list (current_optimize_pragma); - p->target_strings = copy_list (current_target_pragma); -} - -/* Handle #pragma GCC pop_options to restore the current target and - optimization options from a previous push_options. */ - -static void -handle_pragma_pop_options (cpp_reader *ARG_UNUSED(dummy)) -{ - enum cpp_ttype token; - tree x = 0; - opt_stack *p; - - token = pragma_lex (&x); - if (token != CPP_EOF) - { - warning (OPT_Wpragmas, "junk at end of %<#pragma pop_options%>"); - return; - } - - if (! options_stack) - { - warning (OPT_Wpragmas, - "%<#pragma GCC pop_options%> without a corresponding " - "%<#pragma GCC push_options%>"); - return; - } - - p = options_stack; - options_stack = p->prev; - - if (p->target_binary != target_option_current_node) - { - (void) targetm.target_option.pragma_parse (NULL_TREE, p->target_binary); - target_option_current_node = p->target_binary; - } - - if (p->optimize_binary != optimization_current_node) - { - tree old_optimize = optimization_current_node; - cl_optimization_restore (&global_options, - TREE_OPTIMIZATION (p->optimize_binary)); - c_cpp_builtins_optimize_pragma (parse_in, old_optimize, - p->optimize_binary); - optimization_current_node = p->optimize_binary; - } - - current_target_pragma = p->target_strings; - current_optimize_pragma = p->optimize_strings; -} - -/* Handle #pragma GCC reset_options to restore the current target and - optimization options to the original options used on the command line. */ - -static void -handle_pragma_reset_options (cpp_reader *ARG_UNUSED(dummy)) -{ - enum cpp_ttype token; - tree x = 0; - tree new_optimize = optimization_default_node; - tree new_target = target_option_default_node; - - token = pragma_lex (&x); - if (token != CPP_EOF) - { - warning (OPT_Wpragmas, "junk at end of %<#pragma reset_options%>"); - return; - } - - if (new_target != target_option_current_node) - { - (void) targetm.target_option.pragma_parse (NULL_TREE, new_target); - target_option_current_node = new_target; - } - - if (new_optimize != optimization_current_node) - { - tree old_optimize = optimization_current_node; - cl_optimization_restore (&global_options, - TREE_OPTIMIZATION (new_optimize)); - c_cpp_builtins_optimize_pragma (parse_in, old_optimize, new_optimize); - optimization_current_node = new_optimize; - } - - current_target_pragma = NULL_TREE; - current_optimize_pragma = NULL_TREE; -} - -/* Print a plain user-specified message. */ - -static void -handle_pragma_message (cpp_reader *ARG_UNUSED(dummy)) -{ - enum cpp_ttype token; - tree x, message = 0; - - token = pragma_lex (&x); - if (token == CPP_OPEN_PAREN) - { - token = pragma_lex (&x); - if (token == CPP_STRING) - message = x; - else - GCC_BAD ("expected a string after %<#pragma message%>"); - if (pragma_lex (&x) != CPP_CLOSE_PAREN) - GCC_BAD ("malformed %<#pragma message%>, ignored"); - } - else if (token == CPP_STRING) - message = x; - else - GCC_BAD ("expected a string after %<#pragma message%>"); - - gcc_assert (message); - - if (pragma_lex (&x) != CPP_EOF) - warning (OPT_Wpragmas, "junk at end of %<#pragma message%>"); - - if (TREE_STRING_LENGTH (message) > 1) - inform (input_location, "#pragma message: %s", TREE_STRING_POINTER (message)); -} - -/* Mark whether the current location is valid for a STDC pragma. */ - -static bool valid_location_for_stdc_pragma; - -void -mark_valid_location_for_stdc_pragma (bool flag) -{ - valid_location_for_stdc_pragma = flag; -} - -/* Return true if the current location is valid for a STDC pragma. */ - -bool -valid_location_for_stdc_pragma_p (void) -{ - return valid_location_for_stdc_pragma; -} - -enum pragma_switch_t { PRAGMA_ON, PRAGMA_OFF, PRAGMA_DEFAULT, PRAGMA_BAD }; - -/* A STDC pragma must appear outside of external declarations or - preceding all explicit declarations and statements inside a compound - statement; its behavior is undefined if used in any other context. - It takes a switch of ON, OFF, or DEFAULT. */ - -static enum pragma_switch_t -handle_stdc_pragma (const char *pname) -{ - const char *arg; - tree t; - enum pragma_switch_t ret; - - if (!valid_location_for_stdc_pragma_p ()) - { - warning (OPT_Wpragmas, "invalid location for %<pragma %s%>, ignored", - pname); - return PRAGMA_BAD; - } - - if (pragma_lex (&t) != CPP_NAME) - { - warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname); - return PRAGMA_BAD; - } - - arg = IDENTIFIER_POINTER (t); - - if (!strcmp (arg, "ON")) - ret = PRAGMA_ON; - else if (!strcmp (arg, "OFF")) - ret = PRAGMA_OFF; - else if (!strcmp (arg, "DEFAULT")) - ret = PRAGMA_DEFAULT; - else - { - warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname); - return PRAGMA_BAD; - } - - if (pragma_lex (&t) != CPP_EOF) - { - warning (OPT_Wpragmas, "junk at end of %<#pragma %s%>", pname); - return PRAGMA_BAD; - } - - return ret; -} - -/* #pragma STDC FLOAT_CONST_DECIMAL64 ON - #pragma STDC FLOAT_CONST_DECIMAL64 OFF - #pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT */ - -static void -handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy)) -{ - if (c_dialect_cxx ()) - { - if (warn_unknown_pragmas > in_system_header) - warning (OPT_Wunknown_pragmas, - "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported" - " for C++"); - return; - } - - if (!targetm.decimal_float_supported_p ()) - { - if (warn_unknown_pragmas > in_system_header) - warning (OPT_Wunknown_pragmas, - "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported" - " on this target"); - return; - } - - pedwarn (input_location, OPT_Wpedantic, - "ISO C does not support %<#pragma STDC FLOAT_CONST_DECIMAL64%>"); - - switch (handle_stdc_pragma ("STDC FLOAT_CONST_DECIMAL64")) - { - case PRAGMA_ON: - set_float_const_decimal64 (); - break; - case PRAGMA_OFF: - case PRAGMA_DEFAULT: - clear_float_const_decimal64 (); - break; - case PRAGMA_BAD: - break; - } -} - -/* A vector of registered pragma callbacks, which is never freed. */ - -static vec<internal_pragma_handler> registered_pragmas; - -typedef struct -{ - const char *space; - const char *name; -} pragma_ns_name; - - -static vec<pragma_ns_name> registered_pp_pragmas; - -struct omp_pragma_def { const char *name; unsigned int id; }; -static const struct omp_pragma_def omp_pragmas[] = { - { "atomic", PRAGMA_OMP_ATOMIC }, - { "barrier", PRAGMA_OMP_BARRIER }, - { "critical", PRAGMA_OMP_CRITICAL }, - { "flush", PRAGMA_OMP_FLUSH }, - { "for", PRAGMA_OMP_FOR }, - { "master", PRAGMA_OMP_MASTER }, - { "ordered", PRAGMA_OMP_ORDERED }, - { "parallel", PRAGMA_OMP_PARALLEL }, - { "section", PRAGMA_OMP_SECTION }, - { "sections", PRAGMA_OMP_SECTIONS }, - { "single", PRAGMA_OMP_SINGLE }, - { "task", PRAGMA_OMP_TASK }, - { "taskwait", PRAGMA_OMP_TASKWAIT }, - { "taskyield", PRAGMA_OMP_TASKYIELD }, - { "threadprivate", PRAGMA_OMP_THREADPRIVATE } -}; - -void -c_pp_lookup_pragma (unsigned int id, const char **space, const char **name) -{ - const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas); - int i; - - for (i = 0; i < n_omp_pragmas; ++i) - if (omp_pragmas[i].id == id) - { - *space = "omp"; - *name = omp_pragmas[i].name; - return; - } - - if (id >= PRAGMA_FIRST_EXTERNAL - && (id < PRAGMA_FIRST_EXTERNAL + registered_pp_pragmas.length ())) - { - *space = registered_pp_pragmas[id - PRAGMA_FIRST_EXTERNAL].space; - *name = registered_pp_pragmas[id - PRAGMA_FIRST_EXTERNAL].name; - return; - } - - gcc_unreachable (); -} - -/* Front-end wrappers for pragma registration to avoid dragging - cpplib.h in almost everywhere. */ - -static void -c_register_pragma_1 (const char *space, const char *name, - internal_pragma_handler ihandler, bool allow_expansion) -{ - unsigned id; - - if (flag_preprocess_only) - { - pragma_ns_name ns_name; - - if (!allow_expansion) - return; - - ns_name.space = space; - ns_name.name = name; - registered_pp_pragmas.safe_push (ns_name); - id = registered_pp_pragmas.length (); - id += PRAGMA_FIRST_EXTERNAL - 1; - } - else - { - registered_pragmas.safe_push (ihandler); - id = registered_pragmas.length (); - id += PRAGMA_FIRST_EXTERNAL - 1; - - /* The C++ front end allocates 6 bits in cp_token; the C front end - allocates 7 bits in c_token. At present this is sufficient. */ - gcc_assert (id < 64); - } - - cpp_register_deferred_pragma (parse_in, space, name, id, - allow_expansion, false); -} - -/* Register a C pragma handler, using a space and a name. It disallows pragma - expansion (if you want it, use c_register_pragma_with_expansion instead). */ -void -c_register_pragma (const char *space, const char *name, - pragma_handler_1arg handler) -{ - internal_pragma_handler ihandler; - - ihandler.handler.handler_1arg = handler; - ihandler.extra_data = false; - ihandler.data = NULL; - c_register_pragma_1 (space, name, ihandler, false); -} - -/* Register a C pragma handler, using a space and a name, it also carries an - extra data field which can be used by the handler. It disallows pragma - expansion (if you want it, use c_register_pragma_with_expansion_and_data - instead). */ -void -c_register_pragma_with_data (const char *space, const char *name, - pragma_handler_2arg handler, void * data) -{ - internal_pragma_handler ihandler; - - ihandler.handler.handler_2arg = handler; - ihandler.extra_data = true; - ihandler.data = data; - c_register_pragma_1 (space, name, ihandler, false); -} - -/* Register a C pragma handler, using a space and a name. It allows pragma - expansion as in the following example: - - #define NUMBER 10 - #pragma count (NUMBER) - - Name expansion is still disallowed. */ -void -c_register_pragma_with_expansion (const char *space, const char *name, - pragma_handler_1arg handler) -{ - internal_pragma_handler ihandler; - - ihandler.handler.handler_1arg = handler; - ihandler.extra_data = false; - ihandler.data = NULL; - c_register_pragma_1 (space, name, ihandler, true); -} - -/* Register a C pragma handler, using a space and a name, it also carries an - extra data field which can be used by the handler. It allows pragma - expansion as in the following example: - - #define NUMBER 10 - #pragma count (NUMBER) - - Name expansion is still disallowed. */ -void -c_register_pragma_with_expansion_and_data (const char *space, const char *name, - pragma_handler_2arg handler, - void *data) -{ - internal_pragma_handler ihandler; - - ihandler.handler.handler_2arg = handler; - ihandler.extra_data = true; - ihandler.data = data; - c_register_pragma_1 (space, name, ihandler, true); -} - -void -c_invoke_pragma_handler (unsigned int id) -{ - internal_pragma_handler *ihandler; - pragma_handler_1arg handler_1arg; - pragma_handler_2arg handler_2arg; - - id -= PRAGMA_FIRST_EXTERNAL; - ihandler = ®istered_pragmas[id]; - if (ihandler->extra_data) - { - handler_2arg = ihandler->handler.handler_2arg; - handler_2arg (parse_in, ihandler->data); - } - else - { - handler_1arg = ihandler->handler.handler_1arg; - handler_1arg (parse_in); - } -} - -/* Set up front-end pragmas. */ -void -init_pragma (void) -{ - if (flag_openmp) - { - const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas); - int i; - - for (i = 0; i < n_omp_pragmas; ++i) - cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name, - omp_pragmas[i].id, true, true); - } - - if (!flag_preprocess_only) - cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess", - PRAGMA_GCC_PCH_PREPROCESS, false, false); - -#ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION - c_register_pragma_with_expansion (0, "pack", handle_pragma_pack); -#else - c_register_pragma (0, "pack", handle_pragma_pack); -#endif - c_register_pragma (0, "weak", handle_pragma_weak); - c_register_pragma ("GCC", "visibility", handle_pragma_visibility); - - c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic); - c_register_pragma ("GCC", "target", handle_pragma_target); - c_register_pragma ("GCC", "optimize", handle_pragma_optimize); - c_register_pragma ("GCC", "push_options", handle_pragma_push_options); - c_register_pragma ("GCC", "pop_options", handle_pragma_pop_options); - c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options); - - c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64", - handle_pragma_float_const_decimal64); - - c_register_pragma_with_expansion (0, "redefine_extname", - handle_pragma_redefine_extname); - - c_register_pragma_with_expansion (0, "message", handle_pragma_message); - -#ifdef REGISTER_TARGET_PRAGMAS - REGISTER_TARGET_PRAGMAS (); -#endif - - /* Allow plugins to register their own pragmas. */ - invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL); -} - -#include "gt-c-family-c-pragma.h" diff --git a/gcc-4.8.1/gcc/c-family/c-pragma.h b/gcc-4.8.1/gcc/c-family/c-pragma.h deleted file mode 100644 index 41215db00..000000000 --- a/gcc-4.8.1/gcc/c-family/c-pragma.h +++ /dev/null @@ -1,150 +0,0 @@ -/* Pragma related interfaces. - Copyright (C) 1995-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#ifndef GCC_C_PRAGMA_H -#define GCC_C_PRAGMA_H - -#include "cpplib.h" /* For enum cpp_ttype. */ - -/* Pragma identifiers built in to the front end parsers. Identifiers - for ancillary handlers will follow these. */ -typedef enum pragma_kind { - PRAGMA_NONE = 0, - - PRAGMA_OMP_ATOMIC, - PRAGMA_OMP_BARRIER, - PRAGMA_OMP_CRITICAL, - PRAGMA_OMP_FLUSH, - PRAGMA_OMP_FOR, - PRAGMA_OMP_MASTER, - PRAGMA_OMP_ORDERED, - PRAGMA_OMP_PARALLEL, - PRAGMA_OMP_PARALLEL_FOR, - PRAGMA_OMP_PARALLEL_SECTIONS, - PRAGMA_OMP_SECTION, - PRAGMA_OMP_SECTIONS, - PRAGMA_OMP_SINGLE, - PRAGMA_OMP_TASK, - PRAGMA_OMP_TASKWAIT, - PRAGMA_OMP_TASKYIELD, - PRAGMA_OMP_THREADPRIVATE, - - PRAGMA_GCC_PCH_PREPROCESS, - - PRAGMA_FIRST_EXTERNAL -} pragma_kind; - - -/* All clauses defined by OpenMP 2.5 and 3.0. - Used internally by both C and C++ parsers. */ -typedef enum pragma_omp_clause { - PRAGMA_OMP_CLAUSE_NONE = 0, - - PRAGMA_OMP_CLAUSE_COLLAPSE, - PRAGMA_OMP_CLAUSE_COPYIN, - PRAGMA_OMP_CLAUSE_COPYPRIVATE, - PRAGMA_OMP_CLAUSE_DEFAULT, - PRAGMA_OMP_CLAUSE_FIRSTPRIVATE, - PRAGMA_OMP_CLAUSE_IF, - PRAGMA_OMP_CLAUSE_LASTPRIVATE, - PRAGMA_OMP_CLAUSE_NOWAIT, - PRAGMA_OMP_CLAUSE_NUM_THREADS, - PRAGMA_OMP_CLAUSE_ORDERED, - PRAGMA_OMP_CLAUSE_PRIVATE, - PRAGMA_OMP_CLAUSE_REDUCTION, - PRAGMA_OMP_CLAUSE_SCHEDULE, - PRAGMA_OMP_CLAUSE_SHARED, - PRAGMA_OMP_CLAUSE_UNTIED, - PRAGMA_OMP_CLAUSE_FINAL, - PRAGMA_OMP_CLAUSE_MERGEABLE -} pragma_omp_clause; - -extern struct cpp_reader* parse_in; - -/* It's safe to always leave visibility pragma enabled as if - visibility is not supported on the host OS platform the - statements are ignored. */ -extern void push_visibility (const char *, int); -extern bool pop_visibility (int); - -extern void init_pragma (void); - -/* Front-end wrappers for pragma registration. */ -typedef void (*pragma_handler_1arg)(struct cpp_reader *); -/* A second pragma handler, which adds a void * argument allowing to pass extra - data to the handler. */ -typedef void (*pragma_handler_2arg)(struct cpp_reader *, void *); - -/* This union allows to abstract the different handlers. */ -union gen_pragma_handler { - pragma_handler_1arg handler_1arg; - pragma_handler_2arg handler_2arg; -}; -/* Internally used to keep the data of the handler. */ -struct internal_pragma_handler_d { - union gen_pragma_handler handler; - /* Permits to know if handler is a pragma_handler_1arg (extra_data is false) - or a pragma_handler_2arg (extra_data is true). */ - bool extra_data; - /* A data field which can be used when extra_data is true. */ - void * data; -}; -typedef struct internal_pragma_handler_d internal_pragma_handler; - -extern void c_register_pragma (const char *space, const char *name, - pragma_handler_1arg handler); -extern void c_register_pragma_with_data (const char *space, const char *name, - pragma_handler_2arg handler, - void *data); - -extern void c_register_pragma_with_expansion (const char *space, - const char *name, - pragma_handler_1arg handler); -extern void c_register_pragma_with_expansion_and_data (const char *space, - const char *name, - pragma_handler_2arg handler, - void *data); -extern void c_invoke_pragma_handler (unsigned int); - -extern void maybe_apply_pragma_weak (tree); -extern void maybe_apply_pending_pragma_weaks (void); -extern tree maybe_apply_renaming_pragma (tree, tree); -extern void add_to_renaming_pragma_list (tree, tree); - -extern enum cpp_ttype pragma_lex (tree *); - -/* Flags for use with c_lex_with_flags. The values here were picked - so that 0 means to translate and join strings. */ -#define C_LEX_STRING_NO_TRANSLATE 1 /* Do not lex strings into - execution character set. */ -#define C_LEX_STRING_NO_JOIN 2 /* Do not concatenate strings - nor translate them into execution - character set. */ - -/* This is not actually available to pragma parsers. It's merely a - convenient location to declare this function for c-lex, after - having enum cpp_ttype declared. */ -extern enum cpp_ttype c_lex_with_flags (tree *, location_t *, unsigned char *, - int); - -extern void c_pp_lookup_pragma (unsigned int, const char **, const char **); - -extern GTY(()) tree pragma_extern_prefix; - -#endif /* GCC_C_PRAGMA_H */ diff --git a/gcc-4.8.1/gcc/c-family/c-pretty-print.c b/gcc-4.8.1/gcc/c-family/c-pretty-print.c deleted file mode 100644 index 13dd613d8..000000000 --- a/gcc-4.8.1/gcc/c-family/c-pretty-print.c +++ /dev/null @@ -1,2397 +0,0 @@ -/* Subroutines common to both C and C++ pretty-printers. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "tree.h" -#include "intl.h" -#include "c-pretty-print.h" -#include "tree-pretty-print.h" -#include "tree-iterator.h" -#include "diagnostic.h" - -/* Translate if being used for diagnostics, but not for dump files or - __PRETTY_FUNCTION. */ -#define M_(msgid) (pp_translate_identifiers (pp) ? _(msgid) : (msgid)) - -/* The pretty-printer code is primarily designed to closely follow - (GNU) C and C++ grammars. That is to be contrasted with spaghetti - codes we used to have in the past. Following a structured - approach (preferably the official grammars) is believed to make it - much easier to add extensions and nifty pretty-printing effects that - takes expression or declaration contexts into account. */ - - -#define pp_c_maybe_whitespace(PP) \ - do { \ - if (pp_base (PP)->padding == pp_before) \ - pp_c_whitespace (PP); \ - } while (0) - -/* literal */ -static void pp_c_char (c_pretty_printer *, int); - -/* postfix-expression */ -static void pp_c_initializer_list (c_pretty_printer *, tree); -static void pp_c_brace_enclosed_initializer_list (c_pretty_printer *, tree); - -static void pp_c_multiplicative_expression (c_pretty_printer *, tree); -static void pp_c_additive_expression (c_pretty_printer *, tree); -static void pp_c_shift_expression (c_pretty_printer *, tree); -static void pp_c_relational_expression (c_pretty_printer *, tree); -static void pp_c_equality_expression (c_pretty_printer *, tree); -static void pp_c_and_expression (c_pretty_printer *, tree); -static void pp_c_exclusive_or_expression (c_pretty_printer *, tree); -static void pp_c_inclusive_or_expression (c_pretty_printer *, tree); -static void pp_c_logical_and_expression (c_pretty_printer *, tree); -static void pp_c_conditional_expression (c_pretty_printer *, tree); -static void pp_c_assignment_expression (c_pretty_printer *, tree); - -/* declarations. */ - - -/* Helper functions. */ - -void -pp_c_whitespace (c_pretty_printer *pp) -{ - pp_space (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_left_paren (c_pretty_printer *pp) -{ - pp_left_paren (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_right_paren (c_pretty_printer *pp) -{ - pp_right_paren (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_left_brace (c_pretty_printer *pp) -{ - pp_left_brace (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_right_brace (c_pretty_printer *pp) -{ - pp_right_brace (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_left_bracket (c_pretty_printer *pp) -{ - pp_left_bracket (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_right_bracket (c_pretty_printer *pp) -{ - pp_right_bracket (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_dot (c_pretty_printer *pp) -{ - pp_dot (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_ampersand (c_pretty_printer *pp) -{ - pp_ampersand (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_star (c_pretty_printer *pp) -{ - pp_star (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_arrow (c_pretty_printer *pp) -{ - pp_arrow (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_semicolon (c_pretty_printer *pp) -{ - pp_semicolon (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_complement (c_pretty_printer *pp) -{ - pp_complement (pp); - pp_base (pp)->padding = pp_none; -} - -void -pp_c_exclamation (c_pretty_printer *pp) -{ - pp_exclamation (pp); - pp_base (pp)->padding = pp_none; -} - -/* Print out the external representation of QUALIFIERS. */ - -void -pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type) -{ - const char *p = pp_last_position_in_text (pp); - bool previous = false; - - if (!qualifiers) - return; - - /* The C programming language does not have references, but it is much - simpler to handle those here rather than going through the same - logic in the C++ pretty-printer. */ - if (p != NULL && (*p == '*' || *p == '&')) - pp_c_whitespace (pp); - - if (qualifiers & TYPE_QUAL_CONST) - { - pp_c_ws_string (pp, func_type ? "__attribute__((const))" : "const"); - previous = true; - } - - if (qualifiers & TYPE_QUAL_VOLATILE) - { - if (previous) - pp_c_whitespace (pp); - pp_c_ws_string (pp, func_type ? "__attribute__((noreturn))" : "volatile"); - previous = true; - } - - if (qualifiers & TYPE_QUAL_RESTRICT) - { - if (previous) - pp_c_whitespace (pp); - pp_c_ws_string (pp, (flag_isoc99 && !c_dialect_cxx () - ? "restrict" : "__restrict__")); - } -} - -/* Pretty-print T using the type-cast notation '( type-name )'. */ - -static void -pp_c_type_cast (c_pretty_printer *pp, tree t) -{ - pp_c_left_paren (pp); - pp_type_id (pp, t); - pp_c_right_paren (pp); -} - -/* We're about to pretty-print a pointer type as indicated by T. - Output a whitespace, if needed, preparing for subsequent output. */ - -void -pp_c_space_for_pointer_operator (c_pretty_printer *pp, tree t) -{ - if (POINTER_TYPE_P (t)) - { - tree pointee = strip_pointer_operator (TREE_TYPE (t)); - if (TREE_CODE (pointee) != ARRAY_TYPE - && TREE_CODE (pointee) != FUNCTION_TYPE) - pp_c_whitespace (pp); - } -} - - -/* Declarations. */ - -/* C++ cv-qualifiers are called type-qualifiers in C. Print out the - cv-qualifiers of T. If T is a declaration then it is the cv-qualifier - of its type. Take care of possible extensions. - - type-qualifier-list: - type-qualifier - type-qualifier-list type-qualifier - - type-qualifier: - const - restrict -- C99 - __restrict__ -- GNU C - address-space-qualifier -- GNU C - volatile - - address-space-qualifier: - identifier -- GNU C */ - -void -pp_c_type_qualifier_list (c_pretty_printer *pp, tree t) -{ - int qualifiers; - - if (!t || t == error_mark_node) - return; - - if (!TYPE_P (t)) - t = TREE_TYPE (t); - - qualifiers = TYPE_QUALS (t); - pp_c_cv_qualifiers (pp, qualifiers, - TREE_CODE (t) == FUNCTION_TYPE); - - if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (t))) - { - const char *as = c_addr_space_name (TYPE_ADDR_SPACE (t)); - pp_c_identifier (pp, as); - } -} - -/* pointer: - * type-qualifier-list(opt) - * type-qualifier-list(opt) pointer */ - -static void -pp_c_pointer (c_pretty_printer *pp, tree t) -{ - if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL) - t = TREE_TYPE (t); - switch (TREE_CODE (t)) - { - case POINTER_TYPE: - /* It is easier to handle C++ reference types here. */ - case REFERENCE_TYPE: - if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE) - pp_c_pointer (pp, TREE_TYPE (t)); - if (TREE_CODE (t) == POINTER_TYPE) - pp_c_star (pp); - else - pp_c_ampersand (pp); - pp_c_type_qualifier_list (pp, t); - break; - - /* ??? This node is now in GENERIC and so shouldn't be here. But - we'll fix that later. */ - case DECL_EXPR: - pp_declaration (pp, DECL_EXPR_DECL (t)); - pp_needs_newline (pp) = true; - break; - - default: - pp_unsupported_tree (pp, t); - } -} - -/* type-specifier: - void - char - short - int - long - float - double - signed - unsigned - _Bool -- C99 - _Complex -- C99 - _Imaginary -- C99 - struct-or-union-specifier - enum-specifier - typedef-name. - - GNU extensions. - simple-type-specifier: - __complex__ - __vector__ */ - -void -pp_c_type_specifier (c_pretty_printer *pp, tree t) -{ - const enum tree_code code = TREE_CODE (t); - switch (code) - { - case ERROR_MARK: - pp_c_ws_string (pp, M_("<type-error>")); - break; - - case IDENTIFIER_NODE: - pp_c_identifier (pp, IDENTIFIER_POINTER (t)); - break; - - case VOID_TYPE: - case BOOLEAN_TYPE: - case INTEGER_TYPE: - case REAL_TYPE: - case FIXED_POINT_TYPE: - if (TYPE_NAME (t)) - { - t = TYPE_NAME (t); - pp_c_type_specifier (pp, t); - } - else - { - int prec = TYPE_PRECISION (t); - if (ALL_FIXED_POINT_MODE_P (TYPE_MODE (t))) - t = c_common_type_for_mode (TYPE_MODE (t), TYPE_SATURATING (t)); - else - t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t)); - if (TYPE_NAME (t)) - { - pp_c_type_specifier (pp, t); - if (TYPE_PRECISION (t) != prec) - { - pp_string (pp, ":"); - pp_decimal_int (pp, prec); - } - } - else - { - switch (code) - { - case INTEGER_TYPE: - pp_string (pp, (TYPE_UNSIGNED (t) - ? M_("<unnamed-unsigned:") - : M_("<unnamed-signed:"))); - break; - case REAL_TYPE: - pp_string (pp, M_("<unnamed-float:")); - break; - case FIXED_POINT_TYPE: - pp_string (pp, M_("<unnamed-fixed:")); - break; - default: - gcc_unreachable (); - } - pp_decimal_int (pp, prec); - pp_string (pp, ">"); - } - } - break; - - case TYPE_DECL: - if (DECL_NAME (t)) - pp_id_expression (pp, t); - else - pp_c_ws_string (pp, M_("<typedef-error>")); - break; - - case UNION_TYPE: - case RECORD_TYPE: - case ENUMERAL_TYPE: - if (code == UNION_TYPE) - pp_c_ws_string (pp, "union"); - else if (code == RECORD_TYPE) - pp_c_ws_string (pp, "struct"); - else if (code == ENUMERAL_TYPE) - pp_c_ws_string (pp, "enum"); - else - pp_c_ws_string (pp, M_("<tag-error>")); - - if (TYPE_NAME (t)) - pp_id_expression (pp, TYPE_NAME (t)); - else - pp_c_ws_string (pp, M_("<anonymous>")); - break; - - default: - pp_unsupported_tree (pp, t); - break; - } -} - -/* specifier-qualifier-list: - type-specifier specifier-qualifier-list-opt - type-qualifier specifier-qualifier-list-opt - - - Implementation note: Because of the non-linearities in array or - function declarations, this routine prints not just the - specifier-qualifier-list of such entities or types of such entities, - but also the 'pointer' production part of their declarators. The - remaining part is done by pp_declarator or pp_c_abstract_declarator. */ - -void -pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t) -{ - const enum tree_code code = TREE_CODE (t); - - if (!(pp->flags & pp_c_flag_gnu_v3) && code != POINTER_TYPE) - pp_c_type_qualifier_list (pp, t); - switch (code) - { - case REFERENCE_TYPE: - case POINTER_TYPE: - { - /* Get the types-specifier of this type. */ - tree pointee = strip_pointer_operator (TREE_TYPE (t)); - pp_c_specifier_qualifier_list (pp, pointee); - if (TREE_CODE (pointee) == ARRAY_TYPE - || TREE_CODE (pointee) == FUNCTION_TYPE) - { - pp_c_whitespace (pp); - pp_c_left_paren (pp); - pp_c_attributes_display (pp, TYPE_ATTRIBUTES (pointee)); - } - else if (!c_dialect_cxx ()) - pp_c_whitespace (pp); - pp_ptr_operator (pp, t); - } - break; - - case FUNCTION_TYPE: - case ARRAY_TYPE: - pp_c_specifier_qualifier_list (pp, TREE_TYPE (t)); - break; - - case VECTOR_TYPE: - case COMPLEX_TYPE: - if (code == COMPLEX_TYPE) - pp_c_ws_string (pp, (flag_isoc99 && !c_dialect_cxx () - ? "_Complex" : "__complex__")); - else if (code == VECTOR_TYPE) - { - pp_c_ws_string (pp, "__vector"); - pp_c_left_paren (pp); - pp_wide_integer (pp, TYPE_VECTOR_SUBPARTS (t)); - pp_c_right_paren (pp); - pp_c_whitespace (pp); - } - pp_c_specifier_qualifier_list (pp, TREE_TYPE (t)); - break; - - default: - pp_simple_type_specifier (pp, t); - break; - } - if ((pp->flags & pp_c_flag_gnu_v3) && code != POINTER_TYPE) - pp_c_type_qualifier_list (pp, t); -} - -/* parameter-type-list: - parameter-list - parameter-list , ... - - parameter-list: - parameter-declaration - parameter-list , parameter-declaration - - parameter-declaration: - declaration-specifiers declarator - declaration-specifiers abstract-declarator(opt) */ - -void -pp_c_parameter_type_list (c_pretty_printer *pp, tree t) -{ - bool want_parm_decl = DECL_P (t) && !(pp->flags & pp_c_flag_abstract); - tree parms = want_parm_decl ? DECL_ARGUMENTS (t) : TYPE_ARG_TYPES (t); - pp_c_left_paren (pp); - if (parms == void_list_node) - pp_c_ws_string (pp, "void"); - else - { - bool first = true; - for ( ; parms && parms != void_list_node; parms = TREE_CHAIN (parms)) - { - if (!first) - pp_separate_with (pp, ','); - first = false; - pp_declaration_specifiers - (pp, want_parm_decl ? parms : TREE_VALUE (parms)); - if (want_parm_decl) - pp_declarator (pp, parms); - else - pp_abstract_declarator (pp, TREE_VALUE (parms)); - } - } - pp_c_right_paren (pp); -} - -/* abstract-declarator: - pointer - pointer(opt) direct-abstract-declarator */ - -static void -pp_c_abstract_declarator (c_pretty_printer *pp, tree t) -{ - if (TREE_CODE (t) == POINTER_TYPE) - { - if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) - pp_c_right_paren (pp); - t = TREE_TYPE (t); - } - - pp_direct_abstract_declarator (pp, t); -} - -/* direct-abstract-declarator: - ( abstract-declarator ) - direct-abstract-declarator(opt) [ assignment-expression(opt) ] - direct-abstract-declarator(opt) [ * ] - direct-abstract-declarator(opt) ( parameter-type-list(opt) ) */ - -void -pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t) -{ - switch (TREE_CODE (t)) - { - case POINTER_TYPE: - pp_abstract_declarator (pp, t); - break; - - case FUNCTION_TYPE: - pp_c_parameter_type_list (pp, t); - pp_direct_abstract_declarator (pp, TREE_TYPE (t)); - break; - - case ARRAY_TYPE: - pp_c_left_bracket (pp); - if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t))) - { - tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (t)); - tree type = TREE_TYPE (maxval); - - if (host_integerp (maxval, 0)) - pp_wide_integer (pp, tree_low_cst (maxval, 0) + 1); - else - pp_expression (pp, fold_build2 (PLUS_EXPR, type, maxval, - build_int_cst (type, 1))); - } - pp_c_right_bracket (pp); - pp_direct_abstract_declarator (pp, TREE_TYPE (t)); - break; - - case IDENTIFIER_NODE: - case VOID_TYPE: - case BOOLEAN_TYPE: - case INTEGER_TYPE: - case REAL_TYPE: - case FIXED_POINT_TYPE: - case ENUMERAL_TYPE: - case RECORD_TYPE: - case UNION_TYPE: - case VECTOR_TYPE: - case COMPLEX_TYPE: - case TYPE_DECL: - break; - - default: - pp_unsupported_tree (pp, t); - break; - } -} - -/* type-name: - specifier-qualifier-list abstract-declarator(opt) */ - -void -pp_c_type_id (c_pretty_printer *pp, tree t) -{ - pp_c_specifier_qualifier_list (pp, t); - pp_abstract_declarator (pp, t); -} - -/* storage-class-specifier: - typedef - extern - static - auto - register */ - -void -pp_c_storage_class_specifier (c_pretty_printer *pp, tree t) -{ - if (TREE_CODE (t) == TYPE_DECL) - pp_c_ws_string (pp, "typedef"); - else if (DECL_P (t)) - { - if (DECL_REGISTER (t)) - pp_c_ws_string (pp, "register"); - else if (TREE_STATIC (t) && TREE_CODE (t) == VAR_DECL) - pp_c_ws_string (pp, "static"); - } -} - -/* function-specifier: - inline */ - -void -pp_c_function_specifier (c_pretty_printer *pp, tree t) -{ - if (TREE_CODE (t) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (t)) - pp_c_ws_string (pp, "inline"); -} - -/* declaration-specifiers: - storage-class-specifier declaration-specifiers(opt) - type-specifier declaration-specifiers(opt) - type-qualifier declaration-specifiers(opt) - function-specifier declaration-specifiers(opt) */ - -void -pp_c_declaration_specifiers (c_pretty_printer *pp, tree t) -{ - pp_storage_class_specifier (pp, t); - pp_function_specifier (pp, t); - pp_c_specifier_qualifier_list (pp, DECL_P (t) ? TREE_TYPE (t) : t); -} - -/* direct-declarator - identifier - ( declarator ) - direct-declarator [ type-qualifier-list(opt) assignment-expression(opt) ] - direct-declarator [ static type-qualifier-list(opt) assignment-expression(opt)] - direct-declarator [ type-qualifier-list static assignment-expression ] - direct-declarator [ type-qualifier-list * ] - direct-declarator ( parameter-type-list ) - direct-declarator ( identifier-list(opt) ) */ - -void -pp_c_direct_declarator (c_pretty_printer *pp, tree t) -{ - switch (TREE_CODE (t)) - { - case VAR_DECL: - case PARM_DECL: - case TYPE_DECL: - case FIELD_DECL: - case LABEL_DECL: - pp_c_space_for_pointer_operator (pp, TREE_TYPE (t)); - pp_c_tree_decl_identifier (pp, t); - break; - - case ARRAY_TYPE: - case POINTER_TYPE: - pp_abstract_declarator (pp, TREE_TYPE (t)); - break; - - case FUNCTION_TYPE: - pp_parameter_list (pp, t); - pp_abstract_declarator (pp, TREE_TYPE (t)); - break; - - case FUNCTION_DECL: - pp_c_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t))); - pp_c_tree_decl_identifier (pp, t); - if (pp_c_base (pp)->flags & pp_c_flag_abstract) - pp_abstract_declarator (pp, TREE_TYPE (t)); - else - { - pp_parameter_list (pp, t); - pp_abstract_declarator (pp, TREE_TYPE (TREE_TYPE (t))); - } - break; - - case INTEGER_TYPE: - case REAL_TYPE: - case FIXED_POINT_TYPE: - case ENUMERAL_TYPE: - case UNION_TYPE: - case RECORD_TYPE: - break; - - default: - pp_unsupported_tree (pp, t); - break; - } -} - - -/* declarator: - pointer(opt) direct-declarator */ - -void -pp_c_declarator (c_pretty_printer *pp, tree t) -{ - switch (TREE_CODE (t)) - { - case INTEGER_TYPE: - case REAL_TYPE: - case FIXED_POINT_TYPE: - case ENUMERAL_TYPE: - case UNION_TYPE: - case RECORD_TYPE: - break; - - case VAR_DECL: - case PARM_DECL: - case FIELD_DECL: - case ARRAY_TYPE: - case FUNCTION_TYPE: - case FUNCTION_DECL: - case TYPE_DECL: - pp_direct_declarator (pp, t); - break; - - - default: - pp_unsupported_tree (pp, t); - break; - } -} - -/* declaration: - declaration-specifiers init-declarator-list(opt) ; */ - -void -pp_c_declaration (c_pretty_printer *pp, tree t) -{ - pp_declaration_specifiers (pp, t); - pp_c_init_declarator (pp, t); -} - -/* Pretty-print ATTRIBUTES using GNU C extension syntax. */ - -void -pp_c_attributes (c_pretty_printer *pp, tree attributes) -{ - if (attributes == NULL_TREE) - return; - - pp_c_ws_string (pp, "__attribute__"); - pp_c_left_paren (pp); - pp_c_left_paren (pp); - for (; attributes != NULL_TREE; attributes = TREE_CHAIN (attributes)) - { - pp_tree_identifier (pp, TREE_PURPOSE (attributes)); - if (TREE_VALUE (attributes)) - pp_c_call_argument_list (pp, TREE_VALUE (attributes)); - - if (TREE_CHAIN (attributes)) - pp_separate_with (pp, ','); - } - pp_c_right_paren (pp); - pp_c_right_paren (pp); -} - -/* Pretty-print ATTRIBUTES using GNU C extension syntax for attributes - marked to be displayed on disgnostic. */ - -void -pp_c_attributes_display (c_pretty_printer *pp, tree a) -{ - bool is_first = true; - - if (a == NULL_TREE) - return; - - for (; a != NULL_TREE; a = TREE_CHAIN (a)) - { - const struct attribute_spec *as; - as = lookup_attribute_spec (TREE_PURPOSE (a)); - if (!as || as->affects_type_identity == false) - continue; - if (is_first) - { - pp_c_ws_string (pp, "__attribute__"); - pp_c_left_paren (pp); - pp_c_left_paren (pp); - is_first = false; - } - else - { - pp_separate_with (pp, ','); - } - pp_tree_identifier (pp, TREE_PURPOSE (a)); - if (TREE_VALUE (a)) - pp_c_call_argument_list (pp, TREE_VALUE (a)); - } - - if (!is_first) - { - pp_c_right_paren (pp); - pp_c_right_paren (pp); - pp_c_whitespace (pp); - } -} - -/* function-definition: - declaration-specifiers declarator compound-statement */ - -void -pp_c_function_definition (c_pretty_printer *pp, tree t) -{ - pp_declaration_specifiers (pp, t); - pp_declarator (pp, t); - pp_needs_newline (pp) = true; - pp_statement (pp, DECL_SAVED_TREE (t)); - pp_newline_and_flush (pp); -} - - -/* Expressions. */ - -/* Print out a c-char. This is called solely for characters which are - in the *target* execution character set. We ought to convert them - back to the *host* execution character set before printing, but we - have no way to do this at present. A decent compromise is to print - all characters as if they were in the host execution character set, - and not attempt to recover any named escape characters, but render - all unprintables as octal escapes. If the host and target character - sets are the same, this produces relatively readable output. If they - are not the same, strings may appear as gibberish, but that's okay - (in fact, it may well be what the reader wants, e.g. if they are looking - to see if conversion to the target character set happened correctly). - - A special case: we need to prefix \, ", and ' with backslashes. It is - correct to do so for the *host*'s \, ", and ', because the rest of the - file appears in the host character set. */ - -static void -pp_c_char (c_pretty_printer *pp, int c) -{ - if (ISPRINT (c)) - { - switch (c) - { - case '\\': pp_string (pp, "\\\\"); break; - case '\'': pp_string (pp, "\\\'"); break; - case '\"': pp_string (pp, "\\\""); break; - default: pp_character (pp, c); - } - } - else - pp_scalar (pp, "\\%03o", (unsigned) c); -} - -/* Print out a STRING literal. */ - -void -pp_c_string_literal (c_pretty_printer *pp, tree s) -{ - const char *p = TREE_STRING_POINTER (s); - int n = TREE_STRING_LENGTH (s) - 1; - int i; - pp_doublequote (pp); - for (i = 0; i < n; ++i) - pp_c_char (pp, p[i]); - pp_doublequote (pp); -} - -/* Pretty-print an INTEGER literal. */ - -static void -pp_c_integer_constant (c_pretty_printer *pp, tree i) -{ - /* We are going to compare the type of I to other types using - pointer comparison so we need to use its canonical type. */ - tree type = - TYPE_CANONICAL (TREE_TYPE (i)) - ? TYPE_CANONICAL (TREE_TYPE (i)) - : TREE_TYPE (i); - - if (host_integerp (i, 0)) - pp_wide_integer (pp, TREE_INT_CST_LOW (i)); - else if (host_integerp (i, 1)) - pp_unsigned_wide_integer (pp, TREE_INT_CST_LOW (i)); - else - { - unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (i); - HOST_WIDE_INT high = TREE_INT_CST_HIGH (i); - if (tree_int_cst_sgn (i) < 0) - { - pp_character (pp, '-'); - high = ~high + !low; - low = -low; - } - sprintf (pp_buffer (pp)->digit_buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX, - (unsigned HOST_WIDE_INT) high, (unsigned HOST_WIDE_INT) low); - pp_string (pp, pp_buffer (pp)->digit_buffer); - } - if (TYPE_UNSIGNED (type)) - pp_character (pp, 'u'); - if (type == long_integer_type_node || type == long_unsigned_type_node) - pp_character (pp, 'l'); - else if (type == long_long_integer_type_node - || type == long_long_unsigned_type_node) - pp_string (pp, "ll"); - else if (type == int128_integer_type_node - || type == int128_unsigned_type_node) - pp_string (pp, "I128"); -} - -/* Print out a CHARACTER literal. */ - -static void -pp_c_character_constant (c_pretty_printer *pp, tree c) -{ - tree type = TREE_TYPE (c); - if (type == wchar_type_node) - pp_character (pp, 'L'); - pp_quote (pp); - if (host_integerp (c, TYPE_UNSIGNED (type))) - pp_c_char (pp, tree_low_cst (c, TYPE_UNSIGNED (type))); - else - pp_scalar (pp, "\\x%x", (unsigned) TREE_INT_CST_LOW (c)); - pp_quote (pp); -} - -/* Print out a BOOLEAN literal. */ - -static void -pp_c_bool_constant (c_pretty_printer *pp, tree b) -{ - if (b == boolean_false_node) - { - if (c_dialect_cxx ()) - pp_c_ws_string (pp, "false"); - else if (flag_isoc99) - pp_c_ws_string (pp, "_False"); - else - pp_unsupported_tree (pp, b); - } - else if (b == boolean_true_node) - { - if (c_dialect_cxx ()) - pp_c_ws_string (pp, "true"); - else if (flag_isoc99) - pp_c_ws_string (pp, "_True"); - else - pp_unsupported_tree (pp, b); - } - else if (TREE_CODE (b) == INTEGER_CST) - pp_c_integer_constant (pp, b); - else - pp_unsupported_tree (pp, b); -} - -/* Attempt to print out an ENUMERATOR. Return true on success. Else return - false; that means the value was obtained by a cast, in which case - print out the type-id part of the cast-expression -- the casted value - is then printed by pp_c_integer_literal. */ - -static bool -pp_c_enumeration_constant (c_pretty_printer *pp, tree e) -{ - bool value_is_named = true; - tree type = TREE_TYPE (e); - tree value; - - /* Find the name of this constant. */ - for (value = TYPE_VALUES (type); - value != NULL_TREE && !tree_int_cst_equal (TREE_VALUE (value), e); - value = TREE_CHAIN (value)) - ; - - if (value != NULL_TREE) - pp_id_expression (pp, TREE_PURPOSE (value)); - else - { - /* Value must have been cast. */ - pp_c_type_cast (pp, type); - value_is_named = false; - } - - return value_is_named; -} - -/* Print out a REAL value as a decimal-floating-constant. */ - -static void -pp_c_floating_constant (c_pretty_printer *pp, tree r) -{ - const struct real_format *fmt - = REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (r))); - - REAL_VALUE_TYPE floating_cst = TREE_REAL_CST (r); - bool is_decimal = floating_cst.decimal; - - /* See ISO C++ WG N1822. Note: The fraction 643/2136 approximates - log10(2) to 7 significant digits. */ - int max_digits10 = 2 + (is_decimal ? fmt->p : fmt->p * 643L / 2136); - - real_to_decimal (pp_buffer (pp)->digit_buffer, &TREE_REAL_CST (r), - sizeof (pp_buffer (pp)->digit_buffer), - max_digits10, 1); - - pp_string (pp, pp_buffer(pp)->digit_buffer); - if (TREE_TYPE (r) == float_type_node) - pp_character (pp, 'f'); - else if (TREE_TYPE (r) == long_double_type_node) - pp_character (pp, 'l'); - else if (TREE_TYPE (r) == dfloat128_type_node) - pp_string (pp, "dl"); - else if (TREE_TYPE (r) == dfloat64_type_node) - pp_string (pp, "dd"); - else if (TREE_TYPE (r) == dfloat32_type_node) - pp_string (pp, "df"); -} - -/* Print out a FIXED value as a decimal-floating-constant. */ - -static void -pp_c_fixed_constant (c_pretty_printer *pp, tree r) -{ - fixed_to_decimal (pp_buffer (pp)->digit_buffer, &TREE_FIXED_CST (r), - sizeof (pp_buffer (pp)->digit_buffer)); - pp_string (pp, pp_buffer(pp)->digit_buffer); -} - -/* Pretty-print a compound literal expression. GNU extensions include - vector constants. */ - -static void -pp_c_compound_literal (c_pretty_printer *pp, tree e) -{ - tree type = TREE_TYPE (e); - pp_c_type_cast (pp, type); - - switch (TREE_CODE (type)) - { - case RECORD_TYPE: - case UNION_TYPE: - case ARRAY_TYPE: - case VECTOR_TYPE: - case COMPLEX_TYPE: - pp_c_brace_enclosed_initializer_list (pp, e); - break; - - default: - pp_unsupported_tree (pp, e); - break; - } -} - -/* Pretty-print a COMPLEX_EXPR expression. */ - -static void -pp_c_complex_expr (c_pretty_printer *pp, tree e) -{ - /* Handle a few common special cases, otherwise fallback - to printing it as compound literal. */ - tree type = TREE_TYPE (e); - tree realexpr = TREE_OPERAND (e, 0); - tree imagexpr = TREE_OPERAND (e, 1); - - /* Cast of an COMPLEX_TYPE expression to a different COMPLEX_TYPE. */ - if (TREE_CODE (realexpr) == NOP_EXPR - && TREE_CODE (imagexpr) == NOP_EXPR - && TREE_TYPE (realexpr) == TREE_TYPE (type) - && TREE_TYPE (imagexpr) == TREE_TYPE (type) - && TREE_CODE (TREE_OPERAND (realexpr, 0)) == REALPART_EXPR - && TREE_CODE (TREE_OPERAND (imagexpr, 0)) == IMAGPART_EXPR - && TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0) - == TREE_OPERAND (TREE_OPERAND (imagexpr, 0), 0)) - { - pp_c_type_cast (pp, type); - pp_expression (pp, TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0)); - return; - } - - /* Cast of an scalar expression to COMPLEX_TYPE. */ - if ((integer_zerop (imagexpr) || real_zerop (imagexpr)) - && TREE_TYPE (realexpr) == TREE_TYPE (type)) - { - pp_c_type_cast (pp, type); - if (TREE_CODE (realexpr) == NOP_EXPR) - realexpr = TREE_OPERAND (realexpr, 0); - pp_expression (pp, realexpr); - return; - } - - pp_c_compound_literal (pp, e); -} - -/* constant: - integer-constant - floating-constant - fixed-point-constant - enumeration-constant - character-constant */ - -void -pp_c_constant (c_pretty_printer *pp, tree e) -{ - const enum tree_code code = TREE_CODE (e); - - switch (code) - { - case INTEGER_CST: - { - tree type = TREE_TYPE (e); - if (type == boolean_type_node) - pp_c_bool_constant (pp, e); - else if (type == char_type_node) - pp_c_character_constant (pp, e); - else if (TREE_CODE (type) == ENUMERAL_TYPE - && pp_c_enumeration_constant (pp, e)) - ; - else - pp_c_integer_constant (pp, e); - } - break; - - case REAL_CST: - pp_c_floating_constant (pp, e); - break; - - case FIXED_CST: - pp_c_fixed_constant (pp, e); - break; - - case STRING_CST: - pp_c_string_literal (pp, e); - break; - - case COMPLEX_CST: - /* Sometimes, we are confused and we think a complex literal - is a constant. Such thing is a compound literal which - grammatically belongs to postfix-expr production. */ - pp_c_compound_literal (pp, e); - break; - - default: - pp_unsupported_tree (pp, e); - break; - } -} - -/* Pretty-print a string such as an identifier, without changing its - encoding, preceded by whitespace is necessary. */ - -void -pp_c_ws_string (c_pretty_printer *pp, const char *str) -{ - pp_c_maybe_whitespace (pp); - pp_string (pp, str); - pp_base (pp)->padding = pp_before; -} - -/* Pretty-print an IDENTIFIER_NODE, which may contain UTF-8 sequences - that need converting to the locale encoding, preceded by whitespace - is necessary. */ - -void -pp_c_identifier (c_pretty_printer *pp, const char *id) -{ - pp_c_maybe_whitespace (pp); - pp_identifier (pp, id); - pp_base (pp)->padding = pp_before; -} - -/* Pretty-print a C primary-expression. - primary-expression: - identifier - constant - string-literal - ( expression ) */ - -void -pp_c_primary_expression (c_pretty_printer *pp, tree e) -{ - switch (TREE_CODE (e)) - { - case VAR_DECL: - case PARM_DECL: - case FIELD_DECL: - case CONST_DECL: - case FUNCTION_DECL: - case LABEL_DECL: - pp_c_tree_decl_identifier (pp, e); - break; - - case IDENTIFIER_NODE: - pp_c_tree_identifier (pp, e); - break; - - case ERROR_MARK: - pp_c_ws_string (pp, M_("<erroneous-expression>")); - break; - - case RESULT_DECL: - pp_c_ws_string (pp, M_("<return-value>")); - break; - - case INTEGER_CST: - case REAL_CST: - case FIXED_CST: - case STRING_CST: - pp_c_constant (pp, e); - break; - - case TARGET_EXPR: - pp_c_ws_string (pp, "__builtin_memcpy"); - pp_c_left_paren (pp); - pp_ampersand (pp); - pp_primary_expression (pp, TREE_OPERAND (e, 0)); - pp_separate_with (pp, ','); - pp_ampersand (pp); - pp_initializer (pp, TREE_OPERAND (e, 1)); - if (TREE_OPERAND (e, 2)) - { - pp_separate_with (pp, ','); - pp_c_expression (pp, TREE_OPERAND (e, 2)); - } - pp_c_right_paren (pp); - break; - - default: - /* FIXME: Make sure we won't get into an infinite loop. */ - pp_c_left_paren (pp); - pp_expression (pp, e); - pp_c_right_paren (pp); - break; - } -} - -/* Print out a C initializer -- also support C compound-literals. - initializer: - assignment-expression: - { initializer-list } - { initializer-list , } */ - -static void -pp_c_initializer (c_pretty_printer *pp, tree e) -{ - if (TREE_CODE (e) == CONSTRUCTOR) - pp_c_brace_enclosed_initializer_list (pp, e); - else - pp_expression (pp, e); -} - -/* init-declarator: - declarator: - declarator = initializer */ - -void -pp_c_init_declarator (c_pretty_printer *pp, tree t) -{ - pp_declarator (pp, t); - /* We don't want to output function definitions here. There are handled - elsewhere (and the syntactic form is bogus anyway). */ - if (TREE_CODE (t) != FUNCTION_DECL && DECL_INITIAL (t)) - { - tree init = DECL_INITIAL (t); - /* This C++ bit is handled here because it is easier to do so. - In templates, the C++ parser builds a TREE_LIST for a - direct-initialization; the TREE_PURPOSE is the variable to - initialize and the TREE_VALUE is the initializer. */ - if (TREE_CODE (init) == TREE_LIST) - { - pp_c_left_paren (pp); - pp_expression (pp, TREE_VALUE (init)); - pp_right_paren (pp); - } - else - { - pp_space (pp); - pp_equal (pp); - pp_space (pp); - pp_c_initializer (pp, init); - } - } -} - -/* initializer-list: - designation(opt) initializer - initializer-list , designation(opt) initializer - - designation: - designator-list = - - designator-list: - designator - designator-list designator - - designator: - [ constant-expression ] - identifier */ - -static void -pp_c_initializer_list (c_pretty_printer *pp, tree e) -{ - tree type = TREE_TYPE (e); - const enum tree_code code = TREE_CODE (type); - - if (TREE_CODE (e) == CONSTRUCTOR) - { - pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e)); - return; - } - - switch (code) - { - case RECORD_TYPE: - case UNION_TYPE: - case ARRAY_TYPE: - { - tree init = TREE_OPERAND (e, 0); - for (; init != NULL_TREE; init = TREE_CHAIN (init)) - { - if (code == RECORD_TYPE || code == UNION_TYPE) - { - pp_c_dot (pp); - pp_c_primary_expression (pp, TREE_PURPOSE (init)); - } - else - { - pp_c_left_bracket (pp); - if (TREE_PURPOSE (init)) - pp_c_constant (pp, TREE_PURPOSE (init)); - pp_c_right_bracket (pp); - } - pp_c_whitespace (pp); - pp_equal (pp); - pp_c_whitespace (pp); - pp_initializer (pp, TREE_VALUE (init)); - if (TREE_CHAIN (init)) - pp_separate_with (pp, ','); - } - } - return; - - case VECTOR_TYPE: - if (TREE_CODE (e) == VECTOR_CST) - { - unsigned i; - for (i = 0; i < VECTOR_CST_NELTS (e); ++i) - { - if (i > 0) - pp_separate_with (pp, ','); - pp_expression (pp, VECTOR_CST_ELT (e, i)); - } - } - else - break; - return; - - case COMPLEX_TYPE: - if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR) - { - const bool cst = TREE_CODE (e) == COMPLEX_CST; - pp_expression (pp, cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0)); - pp_separate_with (pp, ','); - pp_expression (pp, cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1)); - } - else - break; - return; - - default: - break; - } - - pp_unsupported_tree (pp, type); -} - -/* Pretty-print a brace-enclosed initializer-list. */ - -static void -pp_c_brace_enclosed_initializer_list (c_pretty_printer *pp, tree l) -{ - pp_c_left_brace (pp); - pp_c_initializer_list (pp, l); - pp_c_right_brace (pp); -} - - -/* This is a convenient function, used to bridge gap between C and C++ - grammars. - - id-expression: - identifier */ - -void -pp_c_id_expression (c_pretty_printer *pp, tree t) -{ - switch (TREE_CODE (t)) - { - case VAR_DECL: - case PARM_DECL: - case CONST_DECL: - case TYPE_DECL: - case FUNCTION_DECL: - case FIELD_DECL: - case LABEL_DECL: - pp_c_tree_decl_identifier (pp, t); - break; - - case IDENTIFIER_NODE: - pp_c_tree_identifier (pp, t); - break; - - default: - pp_unsupported_tree (pp, t); - break; - } -} - -/* postfix-expression: - primary-expression - postfix-expression [ expression ] - postfix-expression ( argument-expression-list(opt) ) - postfix-expression . identifier - postfix-expression -> identifier - postfix-expression ++ - postfix-expression -- - ( type-name ) { initializer-list } - ( type-name ) { initializer-list , } */ - -void -pp_c_postfix_expression (c_pretty_printer *pp, tree e) -{ - enum tree_code code = TREE_CODE (e); - switch (code) - { - case POSTINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - pp_postfix_expression (pp, TREE_OPERAND (e, 0)); - pp_string (pp, code == POSTINCREMENT_EXPR ? "++" : "--"); - break; - - case ARRAY_REF: - pp_postfix_expression (pp, TREE_OPERAND (e, 0)); - pp_c_left_bracket (pp); - pp_expression (pp, TREE_OPERAND (e, 1)); - pp_c_right_bracket (pp); - break; - - case CALL_EXPR: - { - call_expr_arg_iterator iter; - tree arg; - pp_postfix_expression (pp, CALL_EXPR_FN (e)); - pp_c_left_paren (pp); - FOR_EACH_CALL_EXPR_ARG (arg, iter, e) - { - pp_expression (pp, arg); - if (more_call_expr_args_p (&iter)) - pp_separate_with (pp, ','); - } - pp_c_right_paren (pp); - break; - } - - case UNORDERED_EXPR: - pp_c_ws_string (pp, flag_isoc99 - ? "isunordered" - : "__builtin_isunordered"); - goto two_args_fun; - - case ORDERED_EXPR: - pp_c_ws_string (pp, flag_isoc99 - ? "!isunordered" - : "!__builtin_isunordered"); - goto two_args_fun; - - case UNLT_EXPR: - pp_c_ws_string (pp, flag_isoc99 - ? "!isgreaterequal" - : "!__builtin_isgreaterequal"); - goto two_args_fun; - - case UNLE_EXPR: - pp_c_ws_string (pp, flag_isoc99 - ? "!isgreater" - : "!__builtin_isgreater"); - goto two_args_fun; - - case UNGT_EXPR: - pp_c_ws_string (pp, flag_isoc99 - ? "!islessequal" - : "!__builtin_islessequal"); - goto two_args_fun; - - case UNGE_EXPR: - pp_c_ws_string (pp, flag_isoc99 - ? "!isless" - : "!__builtin_isless"); - goto two_args_fun; - - case UNEQ_EXPR: - pp_c_ws_string (pp, flag_isoc99 - ? "!islessgreater" - : "!__builtin_islessgreater"); - goto two_args_fun; - - case LTGT_EXPR: - pp_c_ws_string (pp, flag_isoc99 - ? "islessgreater" - : "__builtin_islessgreater"); - goto two_args_fun; - - two_args_fun: - pp_c_left_paren (pp); - pp_expression (pp, TREE_OPERAND (e, 0)); - pp_separate_with (pp, ','); - pp_expression (pp, TREE_OPERAND (e, 1)); - pp_c_right_paren (pp); - break; - - case ABS_EXPR: - pp_c_ws_string (pp, "__builtin_abs"); - pp_c_left_paren (pp); - pp_expression (pp, TREE_OPERAND (e, 0)); - pp_c_right_paren (pp); - break; - - case COMPONENT_REF: - { - tree object = TREE_OPERAND (e, 0); - if (TREE_CODE (object) == INDIRECT_REF) - { - pp_postfix_expression (pp, TREE_OPERAND (object, 0)); - pp_c_arrow (pp); - } - else - { - pp_postfix_expression (pp, object); - pp_c_dot (pp); - } - pp_expression (pp, TREE_OPERAND (e, 1)); - } - break; - - case BIT_FIELD_REF: - { - tree type = TREE_TYPE (e); - - type = signed_or_unsigned_type_for (TYPE_UNSIGNED (type), type); - if (type - && tree_int_cst_equal (TYPE_SIZE (type), TREE_OPERAND (e, 1))) - { - HOST_WIDE_INT bitpos = tree_low_cst (TREE_OPERAND (e, 2), 0); - HOST_WIDE_INT size = tree_low_cst (TYPE_SIZE (type), 0); - if ((bitpos % size) == 0) - { - pp_c_left_paren (pp); - pp_c_left_paren (pp); - pp_type_id (pp, type); - pp_c_star (pp); - pp_c_right_paren (pp); - pp_c_ampersand (pp); - pp_expression (pp, TREE_OPERAND (e, 0)); - pp_c_right_paren (pp); - pp_c_left_bracket (pp); - pp_wide_integer (pp, bitpos / size); - pp_c_right_bracket (pp); - break; - } - } - pp_unsupported_tree (pp, e); - } - break; - - case MEM_REF: - pp_c_expression (pp, e); - break; - - case COMPLEX_CST: - case VECTOR_CST: - pp_c_compound_literal (pp, e); - break; - - case COMPLEX_EXPR: - pp_c_complex_expr (pp, e); - break; - - case COMPOUND_LITERAL_EXPR: - e = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (e)); - /* Fall through. */ - case CONSTRUCTOR: - pp_initializer (pp, e); - break; - - case VA_ARG_EXPR: - pp_c_ws_string (pp, "__builtin_va_arg"); - pp_c_left_paren (pp); - pp_assignment_expression (pp, TREE_OPERAND (e, 0)); - pp_separate_with (pp, ','); - pp_type_id (pp, TREE_TYPE (e)); - pp_c_right_paren (pp); - break; - - case ADDR_EXPR: - if (TREE_CODE (TREE_OPERAND (e, 0)) == FUNCTION_DECL) - { - pp_c_id_expression (pp, TREE_OPERAND (e, 0)); - break; - } - /* else fall through. */ - - default: - pp_primary_expression (pp, e); - break; - } -} - -/* Print out an expression-list; E is expected to be a TREE_LIST. */ - -void -pp_c_expression_list (c_pretty_printer *pp, tree e) -{ - for (; e != NULL_TREE; e = TREE_CHAIN (e)) - { - pp_expression (pp, TREE_VALUE (e)); - if (TREE_CHAIN (e)) - pp_separate_with (pp, ','); - } -} - -/* Print out V, which contains the elements of a constructor. */ - -void -pp_c_constructor_elts (c_pretty_printer *pp, vec<constructor_elt, va_gc> *v) -{ - unsigned HOST_WIDE_INT ix; - tree value; - - FOR_EACH_CONSTRUCTOR_VALUE (v, ix, value) - { - pp_expression (pp, value); - if (ix != vec_safe_length (v) - 1) - pp_separate_with (pp, ','); - } -} - -/* Print out an expression-list in parens, as if it were the argument - list to a function. */ - -void -pp_c_call_argument_list (c_pretty_printer *pp, tree t) -{ - pp_c_left_paren (pp); - if (t && TREE_CODE (t) == TREE_LIST) - pp_c_expression_list (pp, t); - pp_c_right_paren (pp); -} - -/* unary-expression: - postfix-expression - ++ cast-expression - -- cast-expression - unary-operator cast-expression - sizeof unary-expression - sizeof ( type-id ) - - unary-operator: one of - * & + - ! ~ - - GNU extensions. - unary-expression: - __alignof__ unary-expression - __alignof__ ( type-id ) - __real__ unary-expression - __imag__ unary-expression */ - -void -pp_c_unary_expression (c_pretty_printer *pp, tree e) -{ - enum tree_code code = TREE_CODE (e); - switch (code) - { - case PREINCREMENT_EXPR: - case PREDECREMENT_EXPR: - pp_string (pp, code == PREINCREMENT_EXPR ? "++" : "--"); - pp_c_unary_expression (pp, TREE_OPERAND (e, 0)); - break; - - case ADDR_EXPR: - case INDIRECT_REF: - case NEGATE_EXPR: - case BIT_NOT_EXPR: - case TRUTH_NOT_EXPR: - case CONJ_EXPR: - /* String literal are used by address. */ - if (code == ADDR_EXPR && TREE_CODE (TREE_OPERAND (e, 0)) != STRING_CST) - pp_ampersand (pp); - else if (code == INDIRECT_REF) - pp_c_star (pp); - else if (code == NEGATE_EXPR) - pp_minus (pp); - else if (code == BIT_NOT_EXPR || code == CONJ_EXPR) - pp_complement (pp); - else if (code == TRUTH_NOT_EXPR) - pp_exclamation (pp); - pp_c_cast_expression (pp, TREE_OPERAND (e, 0)); - break; - - case MEM_REF: - if (TREE_CODE (TREE_OPERAND (e, 0)) == ADDR_EXPR - && integer_zerop (TREE_OPERAND (e, 1))) - pp_c_expression (pp, TREE_OPERAND (TREE_OPERAND (e, 0), 0)); - else - { - pp_c_star (pp); - if (!integer_zerop (TREE_OPERAND (e, 1))) - { - pp_c_left_paren (pp); - if (!integer_onep (TYPE_SIZE_UNIT - (TREE_TYPE (TREE_TYPE (TREE_OPERAND (e, 0)))))) - pp_c_type_cast (pp, ptr_type_node); - } - pp_c_cast_expression (pp, TREE_OPERAND (e, 0)); - if (!integer_zerop (TREE_OPERAND (e, 1))) - { - pp_plus (pp); - pp_c_integer_constant (pp, - fold_convert (ssizetype, - TREE_OPERAND (e, 1))); - pp_c_right_paren (pp); - } - } - break; - - case REALPART_EXPR: - case IMAGPART_EXPR: - pp_c_ws_string (pp, code == REALPART_EXPR ? "__real__" : "__imag__"); - pp_c_whitespace (pp); - pp_unary_expression (pp, TREE_OPERAND (e, 0)); - break; - - default: - pp_postfix_expression (pp, e); - break; - } -} - -/* cast-expression: - unary-expression - ( type-name ) cast-expression */ - -void -pp_c_cast_expression (c_pretty_printer *pp, tree e) -{ - switch (TREE_CODE (e)) - { - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - CASE_CONVERT: - case VIEW_CONVERT_EXPR: - pp_c_type_cast (pp, TREE_TYPE (e)); - pp_c_cast_expression (pp, TREE_OPERAND (e, 0)); - break; - - default: - pp_unary_expression (pp, e); - } -} - -/* multiplicative-expression: - cast-expression - multiplicative-expression * cast-expression - multiplicative-expression / cast-expression - multiplicative-expression % cast-expression */ - -static void -pp_c_multiplicative_expression (c_pretty_printer *pp, tree e) -{ - enum tree_code code = TREE_CODE (e); - switch (code) - { - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case TRUNC_MOD_EXPR: - pp_multiplicative_expression (pp, TREE_OPERAND (e, 0)); - pp_c_whitespace (pp); - if (code == MULT_EXPR) - pp_c_star (pp); - else if (code == TRUNC_DIV_EXPR) - pp_slash (pp); - else - pp_modulo (pp); - pp_c_whitespace (pp); - pp_c_cast_expression (pp, TREE_OPERAND (e, 1)); - break; - - default: - pp_c_cast_expression (pp, e); - break; - } -} - -/* additive-expression: - multiplicative-expression - additive-expression + multiplicative-expression - additive-expression - multiplicative-expression */ - -static void -pp_c_additive_expression (c_pretty_printer *pp, tree e) -{ - enum tree_code code = TREE_CODE (e); - switch (code) - { - case POINTER_PLUS_EXPR: - case PLUS_EXPR: - case MINUS_EXPR: - pp_c_additive_expression (pp, TREE_OPERAND (e, 0)); - pp_c_whitespace (pp); - if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR) - pp_plus (pp); - else - pp_minus (pp); - pp_c_whitespace (pp); - pp_multiplicative_expression (pp, TREE_OPERAND (e, 1)); - break; - - default: - pp_multiplicative_expression (pp, e); - break; - } -} - -/* additive-expression: - additive-expression - shift-expression << additive-expression - shift-expression >> additive-expression */ - -static void -pp_c_shift_expression (c_pretty_printer *pp, tree e) -{ - enum tree_code code = TREE_CODE (e); - switch (code) - { - case LSHIFT_EXPR: - case RSHIFT_EXPR: - pp_c_shift_expression (pp, TREE_OPERAND (e, 0)); - pp_c_whitespace (pp); - pp_string (pp, code == LSHIFT_EXPR ? "<<" : ">>"); - pp_c_whitespace (pp); - pp_c_additive_expression (pp, TREE_OPERAND (e, 1)); - break; - - default: - pp_c_additive_expression (pp, e); - } -} - -/* relational-expression: - shift-expression - relational-expression < shift-expression - relational-expression > shift-expression - relational-expression <= shift-expression - relational-expression >= shift-expression */ - -static void -pp_c_relational_expression (c_pretty_printer *pp, tree e) -{ - enum tree_code code = TREE_CODE (e); - switch (code) - { - case LT_EXPR: - case GT_EXPR: - case LE_EXPR: - case GE_EXPR: - pp_c_relational_expression (pp, TREE_OPERAND (e, 0)); - pp_c_whitespace (pp); - if (code == LT_EXPR) - pp_less (pp); - else if (code == GT_EXPR) - pp_greater (pp); - else if (code == LE_EXPR) - pp_string (pp, "<="); - else if (code == GE_EXPR) - pp_string (pp, ">="); - pp_c_whitespace (pp); - pp_c_shift_expression (pp, TREE_OPERAND (e, 1)); - break; - - default: - pp_c_shift_expression (pp, e); - break; - } -} - -/* equality-expression: - relational-expression - equality-expression == relational-expression - equality-equality != relational-expression */ - -static void -pp_c_equality_expression (c_pretty_printer *pp, tree e) -{ - enum tree_code code = TREE_CODE (e); - switch (code) - { - case EQ_EXPR: - case NE_EXPR: - pp_c_equality_expression (pp, TREE_OPERAND (e, 0)); - pp_c_whitespace (pp); - pp_string (pp, code == EQ_EXPR ? "==" : "!="); - pp_c_whitespace (pp); - pp_c_relational_expression (pp, TREE_OPERAND (e, 1)); - break; - - default: - pp_c_relational_expression (pp, e); - break; - } -} - -/* AND-expression: - equality-expression - AND-expression & equality-equality */ - -static void -pp_c_and_expression (c_pretty_printer *pp, tree e) -{ - if (TREE_CODE (e) == BIT_AND_EXPR) - { - pp_c_and_expression (pp, TREE_OPERAND (e, 0)); - pp_c_whitespace (pp); - pp_ampersand (pp); - pp_c_whitespace (pp); - pp_c_equality_expression (pp, TREE_OPERAND (e, 1)); - } - else - pp_c_equality_expression (pp, e); -} - -/* exclusive-OR-expression: - AND-expression - exclusive-OR-expression ^ AND-expression */ - -static void -pp_c_exclusive_or_expression (c_pretty_printer *pp, tree e) -{ - if (TREE_CODE (e) == BIT_XOR_EXPR - || TREE_CODE (e) == TRUTH_XOR_EXPR) - { - pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0)); - if (TREE_CODE (e) == BIT_XOR_EXPR) - pp_c_maybe_whitespace (pp); - else - pp_c_whitespace (pp); - pp_carret (pp); - pp_c_whitespace (pp); - pp_c_and_expression (pp, TREE_OPERAND (e, 1)); - } - else - pp_c_and_expression (pp, e); -} - -/* inclusive-OR-expression: - exclusive-OR-expression - inclusive-OR-expression | exclusive-OR-expression */ - -static void -pp_c_inclusive_or_expression (c_pretty_printer *pp, tree e) -{ - if (TREE_CODE (e) == BIT_IOR_EXPR) - { - pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0)); - pp_c_whitespace (pp); - pp_bar (pp); - pp_c_whitespace (pp); - pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 1)); - } - else - pp_c_exclusive_or_expression (pp, e); -} - -/* logical-AND-expression: - inclusive-OR-expression - logical-AND-expression && inclusive-OR-expression */ - -static void -pp_c_logical_and_expression (c_pretty_printer *pp, tree e) -{ - if (TREE_CODE (e) == TRUTH_ANDIF_EXPR - || TREE_CODE (e) == TRUTH_AND_EXPR) - { - pp_c_logical_and_expression (pp, TREE_OPERAND (e, 0)); - pp_c_whitespace (pp); - pp_string (pp, "&&"); - pp_c_whitespace (pp); - pp_c_inclusive_or_expression (pp, TREE_OPERAND (e, 1)); - } - else - pp_c_inclusive_or_expression (pp, e); -} - -/* logical-OR-expression: - logical-AND-expression - logical-OR-expression || logical-AND-expression */ - -void -pp_c_logical_or_expression (c_pretty_printer *pp, tree e) -{ - if (TREE_CODE (e) == TRUTH_ORIF_EXPR - || TREE_CODE (e) == TRUTH_OR_EXPR) - { - pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0)); - pp_c_whitespace (pp); - pp_string (pp, "||"); - pp_c_whitespace (pp); - pp_c_logical_and_expression (pp, TREE_OPERAND (e, 1)); - } - else - pp_c_logical_and_expression (pp, e); -} - -/* conditional-expression: - logical-OR-expression - logical-OR-expression ? expression : conditional-expression */ - -static void -pp_c_conditional_expression (c_pretty_printer *pp, tree e) -{ - if (TREE_CODE (e) == COND_EXPR) - { - pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0)); - pp_c_whitespace (pp); - pp_question (pp); - pp_c_whitespace (pp); - pp_expression (pp, TREE_OPERAND (e, 1)); - pp_c_whitespace (pp); - pp_colon (pp); - pp_c_whitespace (pp); - pp_c_conditional_expression (pp, TREE_OPERAND (e, 2)); - } - else - pp_c_logical_or_expression (pp, e); -} - - -/* assignment-expression: - conditional-expression - unary-expression assignment-operator assignment-expression - - assignment-expression: one of - = *= /= %= += -= >>= <<= &= ^= |= */ - -static void -pp_c_assignment_expression (c_pretty_printer *pp, tree e) -{ - if (TREE_CODE (e) == MODIFY_EXPR - || TREE_CODE (e) == INIT_EXPR) - { - pp_c_unary_expression (pp, TREE_OPERAND (e, 0)); - pp_c_whitespace (pp); - pp_equal (pp); - pp_space (pp); - pp_c_expression (pp, TREE_OPERAND (e, 1)); - } - else - pp_c_conditional_expression (pp, e); -} - -/* expression: - assignment-expression - expression , assignment-expression - - Implementation note: instead of going through the usual recursion - chain, I take the liberty of dispatching nodes to the appropriate - functions. This makes some redundancy, but it worths it. That also - prevents a possible infinite recursion between pp_c_primary_expression () - and pp_c_expression (). */ - -void -pp_c_expression (c_pretty_printer *pp, tree e) -{ - switch (TREE_CODE (e)) - { - case INTEGER_CST: - pp_c_integer_constant (pp, e); - break; - - case REAL_CST: - pp_c_floating_constant (pp, e); - break; - - case FIXED_CST: - pp_c_fixed_constant (pp, e); - break; - - case STRING_CST: - pp_c_string_literal (pp, e); - break; - - case IDENTIFIER_NODE: - case FUNCTION_DECL: - case VAR_DECL: - case CONST_DECL: - case PARM_DECL: - case RESULT_DECL: - case FIELD_DECL: - case LABEL_DECL: - case ERROR_MARK: - pp_primary_expression (pp, e); - break; - - case SSA_NAME: - if (SSA_NAME_VAR (e) - && !DECL_ARTIFICIAL (SSA_NAME_VAR (e))) - pp_c_expression (pp, SSA_NAME_VAR (e)); - else - pp_c_ws_string (pp, M_("<unknown>")); - break; - - case POSTINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case ARRAY_REF: - case CALL_EXPR: - case COMPONENT_REF: - case BIT_FIELD_REF: - case COMPLEX_CST: - case COMPLEX_EXPR: - case VECTOR_CST: - case ORDERED_EXPR: - case UNORDERED_EXPR: - case LTGT_EXPR: - case UNEQ_EXPR: - case UNLE_EXPR: - case UNLT_EXPR: - case UNGE_EXPR: - case UNGT_EXPR: - case ABS_EXPR: - case CONSTRUCTOR: - case COMPOUND_LITERAL_EXPR: - case VA_ARG_EXPR: - pp_postfix_expression (pp, e); - break; - - case CONJ_EXPR: - case ADDR_EXPR: - case INDIRECT_REF: - case MEM_REF: - case NEGATE_EXPR: - case BIT_NOT_EXPR: - case TRUTH_NOT_EXPR: - case PREINCREMENT_EXPR: - case PREDECREMENT_EXPR: - case REALPART_EXPR: - case IMAGPART_EXPR: - pp_c_unary_expression (pp, e); - break; - - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - CASE_CONVERT: - case VIEW_CONVERT_EXPR: - pp_c_cast_expression (pp, e); - break; - - case MULT_EXPR: - case TRUNC_MOD_EXPR: - case TRUNC_DIV_EXPR: - pp_multiplicative_expression (pp, e); - break; - - case LSHIFT_EXPR: - case RSHIFT_EXPR: - pp_c_shift_expression (pp, e); - break; - - case LT_EXPR: - case GT_EXPR: - case LE_EXPR: - case GE_EXPR: - pp_c_relational_expression (pp, e); - break; - - case BIT_AND_EXPR: - pp_c_and_expression (pp, e); - break; - - case BIT_XOR_EXPR: - case TRUTH_XOR_EXPR: - pp_c_exclusive_or_expression (pp, e); - break; - - case BIT_IOR_EXPR: - pp_c_inclusive_or_expression (pp, e); - break; - - case TRUTH_ANDIF_EXPR: - case TRUTH_AND_EXPR: - pp_c_logical_and_expression (pp, e); - break; - - case TRUTH_ORIF_EXPR: - case TRUTH_OR_EXPR: - pp_c_logical_or_expression (pp, e); - break; - - case EQ_EXPR: - case NE_EXPR: - pp_c_equality_expression (pp, e); - break; - - case COND_EXPR: - pp_conditional_expression (pp, e); - break; - - case POINTER_PLUS_EXPR: - case PLUS_EXPR: - case MINUS_EXPR: - pp_c_additive_expression (pp, e); - break; - - case MODIFY_EXPR: - case INIT_EXPR: - pp_assignment_expression (pp, e); - break; - - case COMPOUND_EXPR: - pp_c_left_paren (pp); - pp_expression (pp, TREE_OPERAND (e, 0)); - pp_separate_with (pp, ','); - pp_assignment_expression (pp, TREE_OPERAND (e, 1)); - pp_c_right_paren (pp); - break; - - case NON_LVALUE_EXPR: - case SAVE_EXPR: - pp_expression (pp, TREE_OPERAND (e, 0)); - break; - - case TARGET_EXPR: - pp_postfix_expression (pp, TREE_OPERAND (e, 1)); - break; - - case BIND_EXPR: - case GOTO_EXPR: - /* We don't yet have a way of dumping statements in a - human-readable format. */ - pp_string (pp, "({...})"); - break; - - case C_MAYBE_CONST_EXPR: - pp_c_expression (pp, C_MAYBE_CONST_EXPR_EXPR (e)); - break; - - default: - pp_unsupported_tree (pp, e); - break; - } -} - - - -/* Statements. */ - -void -pp_c_statement (c_pretty_printer *pp, tree stmt) -{ - if (stmt == NULL) - return; - - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - - dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true); -} - - -/* Initialize the PRETTY-PRINTER for handling C codes. */ - -void -pp_c_pretty_printer_init (c_pretty_printer *pp) -{ - pp->offset_list = 0; - - pp->flags = 0; - - pp->declaration = pp_c_declaration; - pp->declaration_specifiers = pp_c_declaration_specifiers; - pp->declarator = pp_c_declarator; - pp->direct_declarator = pp_c_direct_declarator; - pp->type_specifier_seq = pp_c_specifier_qualifier_list; - pp->abstract_declarator = pp_c_abstract_declarator; - pp->direct_abstract_declarator = pp_c_direct_abstract_declarator; - pp->ptr_operator = pp_c_pointer; - pp->parameter_list = pp_c_parameter_type_list; - pp->type_id = pp_c_type_id; - pp->simple_type_specifier = pp_c_type_specifier; - pp->function_specifier = pp_c_function_specifier; - pp->storage_class_specifier = pp_c_storage_class_specifier; - - pp->statement = pp_c_statement; - - pp->constant = pp_c_constant; - pp->id_expression = pp_c_id_expression; - pp->primary_expression = pp_c_primary_expression; - pp->postfix_expression = pp_c_postfix_expression; - pp->unary_expression = pp_c_unary_expression; - pp->initializer = pp_c_initializer; - pp->multiplicative_expression = pp_c_multiplicative_expression; - pp->conditional_expression = pp_c_conditional_expression; - pp->assignment_expression = pp_c_assignment_expression; - pp->expression = pp_c_expression; -} - - -/* Print the tree T in full, on file FILE. */ - -void -print_c_tree (FILE *file, tree t) -{ - static c_pretty_printer pp_rec; - static bool initialized = 0; - c_pretty_printer *pp = &pp_rec; - - if (!initialized) - { - initialized = 1; - pp_construct (pp_base (pp), NULL, 0); - pp_c_pretty_printer_init (pp); - pp_needs_newline (pp) = true; - } - pp_base (pp)->buffer->stream = file; - - pp_statement (pp, t); - - pp_newline_and_flush (pp); -} - -/* Print the tree T in full, on stderr. */ - -DEBUG_FUNCTION void -debug_c_tree (tree t) -{ - print_c_tree (stderr, t); - fputc ('\n', stderr); -} - -/* Output the DECL_NAME of T. If T has no DECL_NAME, output a string made - up of T's memory address. */ - -void -pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t) -{ - const char *name; - - gcc_assert (DECL_P (t)); - - if (DECL_NAME (t)) - name = IDENTIFIER_POINTER (DECL_NAME (t)); - else - { - static char xname[8]; - sprintf (xname, "<U%4x>", ((unsigned)((uintptr_t)(t) & 0xffff))); - name = xname; - } - - pp_c_identifier (pp, name); -} diff --git a/gcc-4.8.1/gcc/c-family/c-pretty-print.h b/gcc-4.8.1/gcc/c-family/c-pretty-print.h deleted file mode 100644 index 04b72c49d..000000000 --- a/gcc-4.8.1/gcc/c-family/c-pretty-print.h +++ /dev/null @@ -1,215 +0,0 @@ -/* Various declarations for the C and C++ pretty-printers. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#ifndef GCC_C_PRETTY_PRINTER -#define GCC_C_PRETTY_PRINTER - -#include "tree.h" -#include "c-family/c-common.h" -#include "pretty-print.h" - - -typedef enum - { - pp_c_flag_abstract = 1 << 1, - pp_c_flag_gnu_v3 = 1 << 2, - pp_c_flag_last_bit = 3 - } pp_c_pretty_print_flags; - - -/* The data type used to bundle information necessary for pretty-printing - a C or C++ entity. */ -typedef struct c_pretty_print_info c_pretty_printer; - -/* The type of a C pretty-printer 'member' function. */ -typedef void (*c_pretty_print_fn) (c_pretty_printer *, tree); - -/* The datatype that contains information necessary for pretty-printing - a tree that represents a C construct. Any pretty-printer for a - language using C/c++ syntax can derive from this datatype and reuse - facilities provided here. It can do so by having a subobject of type - c_pretty_printer and override the macro pp_c_base to return a pointer - to that subobject. Such a pretty-printer has the responsibility to - initialize the pp_base() part, then call pp_c_pretty_printer_init - to set up the components that are specific to the C pretty-printer. - A derived pretty-printer can override any function listed in the - vtable below. See cp/cxx-pretty-print.h and cp/cxx-pretty-print.c - for an example of derivation. */ -struct c_pretty_print_info -{ - pretty_printer base; - /* Points to the first element of an array of offset-list. - Not used yet. */ - int *offset_list; - - pp_flags flags; - - /* These must be overridden by each of the C and C++ front-end to - reflect their understanding of syntactic productions when they differ. */ - c_pretty_print_fn declaration; - c_pretty_print_fn declaration_specifiers; - c_pretty_print_fn declarator; - c_pretty_print_fn abstract_declarator; - c_pretty_print_fn direct_abstract_declarator; - c_pretty_print_fn type_specifier_seq; - c_pretty_print_fn direct_declarator; - c_pretty_print_fn ptr_operator; - c_pretty_print_fn parameter_list; - c_pretty_print_fn type_id; - c_pretty_print_fn simple_type_specifier; - c_pretty_print_fn function_specifier; - c_pretty_print_fn storage_class_specifier; - c_pretty_print_fn initializer; - - c_pretty_print_fn statement; - - c_pretty_print_fn constant; - c_pretty_print_fn id_expression; - c_pretty_print_fn primary_expression; - c_pretty_print_fn postfix_expression; - c_pretty_print_fn unary_expression; - c_pretty_print_fn multiplicative_expression; - c_pretty_print_fn conditional_expression; - c_pretty_print_fn assignment_expression; - c_pretty_print_fn expression; -}; - -/* Override the pp_base macro. Derived pretty-printers should not - touch this macro. Instead they should override pp_c_base instead. */ -#undef pp_base -#define pp_base(PP) (&pp_c_base (PP)->base) - - -#define pp_c_tree_identifier(PPI, ID) \ - pp_c_identifier (PPI, IDENTIFIER_POINTER (ID)) - -#define pp_declaration(PPI, T) \ - pp_c_base (PPI)->declaration (pp_c_base (PPI), T) -#define pp_declaration_specifiers(PPI, D) \ - pp_c_base (PPI)->declaration_specifiers (pp_c_base (PPI), D) -#define pp_abstract_declarator(PP, D) \ - pp_c_base (PP)->abstract_declarator (pp_c_base (PP), D) -#define pp_type_specifier_seq(PPI, D) \ - pp_c_base (PPI)->type_specifier_seq (pp_c_base (PPI), D) -#define pp_declarator(PPI, D) \ - pp_c_base (PPI)->declarator (pp_c_base (PPI), D) -#define pp_direct_declarator(PPI, D) \ - pp_c_base (PPI)->direct_declarator (pp_c_base (PPI), D) -#define pp_direct_abstract_declarator(PP, D) \ - pp_c_base (PP)->direct_abstract_declarator (pp_c_base (PP), D) -#define pp_ptr_operator(PP, D) \ - pp_c_base (PP)->ptr_operator (pp_c_base (PP), D) -#define pp_parameter_list(PPI, T) \ - pp_c_base (PPI)->parameter_list (pp_c_base (PPI), T) -#define pp_type_id(PPI, D) \ - pp_c_base (PPI)->type_id (pp_c_base (PPI), D) -#define pp_simple_type_specifier(PP, T) \ - pp_c_base (PP)->simple_type_specifier (pp_c_base (PP), T) -#define pp_function_specifier(PP, D) \ - pp_c_base (PP)->function_specifier (pp_c_base (PP), D) -#define pp_storage_class_specifier(PP, D) \ - pp_c_base (PP)->storage_class_specifier (pp_c_base (PP), D); - -#define pp_statement(PPI, S) \ - pp_c_base (PPI)->statement (pp_c_base (PPI), S) - -#define pp_constant(PP, E) \ - pp_c_base (PP)->constant (pp_c_base (PP), E) -#define pp_id_expression(PP, E) \ - pp_c_base (PP)->id_expression (pp_c_base (PP), E) -#define pp_primary_expression(PPI, E) \ - pp_c_base (PPI)->primary_expression (pp_c_base (PPI), E) -#define pp_postfix_expression(PPI, E) \ - pp_c_base (PPI)->postfix_expression (pp_c_base (PPI), E) -#define pp_unary_expression(PPI, E) \ - pp_c_base (PPI)->unary_expression (pp_c_base (PPI), E) -#define pp_initializer(PPI, E) \ - pp_c_base (PPI)->initializer (pp_c_base (PPI), E) -#define pp_multiplicative_expression(PPI, E) \ - pp_c_base (PPI)->multiplicative_expression (pp_c_base (PPI), E) -#define pp_conditional_expression(PPI, E) \ - pp_c_base (PPI)->conditional_expression (pp_c_base (PPI), E) -#define pp_assignment_expression(PPI, E) \ - pp_c_base (PPI)->assignment_expression (pp_c_base (PPI), E) -#define pp_expression(PP, E) \ - pp_c_base (PP)->expression (pp_c_base (PP), E) - - -/* Returns the c_pretty_printer base object of PRETTY-PRINTER. This - macro must be overridden by any subclass of c_pretty_print_info. */ -#define pp_c_base(PP) (PP) - -extern void pp_c_pretty_printer_init (c_pretty_printer *); -void pp_c_whitespace (c_pretty_printer *); -void pp_c_left_paren (c_pretty_printer *); -void pp_c_right_paren (c_pretty_printer *); -void pp_c_left_brace (c_pretty_printer *); -void pp_c_right_brace (c_pretty_printer *); -void pp_c_left_bracket (c_pretty_printer *); -void pp_c_right_bracket (c_pretty_printer *); -void pp_c_dot (c_pretty_printer *); -void pp_c_ampersand (c_pretty_printer *); -void pp_c_star (c_pretty_printer *); -void pp_c_arrow (c_pretty_printer *); -void pp_c_semicolon (c_pretty_printer *); -void pp_c_complement (c_pretty_printer *); -void pp_c_exclamation (c_pretty_printer *); -void pp_c_space_for_pointer_operator (c_pretty_printer *, tree); - -/* Declarations. */ -void pp_c_tree_decl_identifier (c_pretty_printer *, tree); -void pp_c_function_definition (c_pretty_printer *, tree); -void pp_c_attributes (c_pretty_printer *, tree); -void pp_c_attributes_display (c_pretty_printer *, tree); -void pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type); -void pp_c_type_qualifier_list (c_pretty_printer *, tree); -void pp_c_parameter_type_list (c_pretty_printer *, tree); -void pp_c_declaration (c_pretty_printer *, tree); -void pp_c_declaration_specifiers (c_pretty_printer *, tree); -void pp_c_declarator (c_pretty_printer *, tree); -void pp_c_direct_declarator (c_pretty_printer *, tree); -void pp_c_specifier_qualifier_list (c_pretty_printer *, tree); -void pp_c_function_specifier (c_pretty_printer *, tree); -void pp_c_type_id (c_pretty_printer *, tree); -void pp_c_direct_abstract_declarator (c_pretty_printer *, tree); -void pp_c_type_specifier (c_pretty_printer *, tree); -void pp_c_storage_class_specifier (c_pretty_printer *, tree); -/* Statements. */ -void pp_c_statement (c_pretty_printer *, tree); -/* Expressions. */ -void pp_c_expression (c_pretty_printer *, tree); -void pp_c_logical_or_expression (c_pretty_printer *, tree); -void pp_c_expression_list (c_pretty_printer *, tree); -void pp_c_constructor_elts (c_pretty_printer *, vec<constructor_elt, va_gc> *); -void pp_c_call_argument_list (c_pretty_printer *, tree); -void pp_c_unary_expression (c_pretty_printer *, tree); -void pp_c_cast_expression (c_pretty_printer *, tree); -void pp_c_postfix_expression (c_pretty_printer *, tree); -void pp_c_primary_expression (c_pretty_printer *, tree); -void pp_c_init_declarator (c_pretty_printer *, tree); -void pp_c_constant (c_pretty_printer *, tree); -void pp_c_id_expression (c_pretty_printer *, tree); -void pp_c_ws_string (c_pretty_printer *, const char *); -void pp_c_identifier (c_pretty_printer *, const char *); -void pp_c_string_literal (c_pretty_printer *, tree); - -void print_c_tree (FILE *file, tree t); - -#endif /* GCC_C_PRETTY_PRINTER */ diff --git a/gcc-4.8.1/gcc/c-family/c-semantics.c b/gcc-4.8.1/gcc/c-family/c-semantics.c deleted file mode 100644 index 44dc0bf7e..000000000 --- a/gcc-4.8.1/gcc/c-family/c-semantics.c +++ /dev/null @@ -1,163 +0,0 @@ -/* This file contains subroutine used by the C front-end to construct GENERIC. - Copyright (C) 2000-2013 Free Software Foundation, Inc. - Written by Benjamin Chelf (chelf@codesourcery.com). - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "tree.h" -#include "function.h" -#include "splay-tree.h" -#include "c-common.h" -#include "flags.h" -#include "tree-iterator.h" - -/* Create an empty statement tree rooted at T. */ - -tree -push_stmt_list (void) -{ - tree t; - t = alloc_stmt_list (); - vec_safe_push (stmt_list_stack, t); - return t; -} - -/* Finish the statement tree rooted at T. */ - -tree -pop_stmt_list (tree t) -{ - tree u = NULL_TREE; - - /* Pop statement lists until we reach the target level. The extra - nestings will be due to outstanding cleanups. */ - while (1) - { - u = stmt_list_stack->pop (); - if (!stmt_list_stack->is_empty ()) - { - tree x = stmt_list_stack->last (); - STATEMENT_LIST_HAS_LABEL (x) |= STATEMENT_LIST_HAS_LABEL (u); - } - if (t == u) - break; - } - - gcc_assert (u != NULL_TREE); - - /* If the statement list is completely empty, just return it. This is - just as good small as build_empty_stmt, with the advantage that - statement lists are merged when they appended to one another. So - using the STATEMENT_LIST avoids pathological buildup of EMPTY_STMT_P - statements. */ - if (TREE_SIDE_EFFECTS (t)) - { - tree_stmt_iterator i = tsi_start (t); - - /* If the statement list contained exactly one statement, then - extract it immediately. */ - if (tsi_one_before_end_p (i)) - { - u = tsi_stmt (i); - tsi_delink (&i); - free_stmt_list (t); - t = u; - } - } - - return t; -} - -/* Build a generic statement based on the given type of node and - arguments. Similar to `build_nt', except that we set - EXPR_LOCATION to LOC. */ -/* ??? This should be obsolete with the lineno_stmt productions - in the grammar. */ - -tree -build_stmt (location_t loc, enum tree_code code, ...) -{ - tree ret; - int length, i; - va_list p; - bool side_effects; - - /* This function cannot be used to construct variably-sized nodes. */ - gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp); - - va_start (p, code); - - ret = make_node (code); - TREE_TYPE (ret) = void_type_node; - length = TREE_CODE_LENGTH (code); - SET_EXPR_LOCATION (ret, loc); - - /* TREE_SIDE_EFFECTS will already be set for statements with - implicit side effects. Here we make sure it is set for other - expressions by checking whether the parameters have side - effects. */ - - side_effects = false; - for (i = 0; i < length; i++) - { - tree t = va_arg (p, tree); - if (t && !TYPE_P (t)) - side_effects |= TREE_SIDE_EFFECTS (t); - TREE_OPERAND (ret, i) = t; - } - - TREE_SIDE_EFFECTS (ret) |= side_effects; - - va_end (p); - return ret; -} - -/* Build a REALPART_EXPR or IMAGPART_EXPR, according to CODE, from ARG. */ - -tree -build_real_imag_expr (location_t location, enum tree_code code, tree arg) -{ - tree ret; - tree arg_type = TREE_TYPE (arg); - - gcc_assert (code == REALPART_EXPR || code == IMAGPART_EXPR); - - if (TREE_CODE (arg_type) == COMPLEX_TYPE) - { - ret = build1 (code, TREE_TYPE (TREE_TYPE (arg)), arg); - SET_EXPR_LOCATION (ret, location); - } - else if (INTEGRAL_TYPE_P (arg_type) || SCALAR_FLOAT_TYPE_P (arg_type)) - { - ret = (code == REALPART_EXPR - ? arg - : omit_one_operand_loc (location, arg_type, - integer_zero_node, arg)); - } - else - { - error_at (location, "wrong type argument to %s", - code == REALPART_EXPR ? "__real" : "__imag"); - ret = error_mark_node; - } - - return ret; -} diff --git a/gcc-4.8.1/gcc/c-family/c-target-def.h b/gcc-4.8.1/gcc/c-family/c-target-def.h deleted file mode 100644 index e33396916..000000000 --- a/gcc-4.8.1/gcc/c-family/c-target-def.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Default initializers for C-family target hooks. - Copyright (C) 2011-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#include "c-family/c-target-hooks-def.h" -#include "tree.h" -#include "c-family/c-common.h" -#include "hooks.h" diff --git a/gcc-4.8.1/gcc/c-family/c-target.def b/gcc-4.8.1/gcc/c-family/c-target.def deleted file mode 100644 index 80042df40..000000000 --- a/gcc-4.8.1/gcc/c-family/c-target.def +++ /dev/null @@ -1,106 +0,0 @@ -/* Target hook definitions for C-family front ends. - Copyright (C) 2001-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* See target-hooks-macros.h for details of macros that should be - provided by the including file, and how to use them here. */ -#include "target-hooks-macros.h" - -#undef HOOK_TYPE -#define HOOK_TYPE "C Target Hook" - -HOOK_VECTOR (TARGETCM_INITIALIZER, gcc_targetcm) - -#undef HOOK_PREFIX -#define HOOK_PREFIX "TARGET_" - -/* Handle target switch CODE (an OPT_* value). ARG is the argument - passed to the switch; it is NULL if no argument was. VALUE is the - value of ARG if CODE specifies a UInteger option, otherwise it is - 1 if the positive form of the switch was used and 0 if the negative - form was. Return true if the switch was valid. */ -DEFHOOK -(handle_c_option, - "", - bool, (size_t code, const char *arg, int value), - default_handle_c_option) - -/* Targets may provide a string object type that can be used within - and between C, C++, and Objective-C dialects. */ - -DEFHOOK -(objc_construct_string_object, - "Targets may provide a string object type that can be used within\ - and between C, C++ and their respective Objective-C dialects.\ - A string object might, for example, embed encoding and length information.\ - These objects are considered opaque to the compiler and handled as references.\ - An ideal implementation makes the composition of the string object\ - match that of the Objective-C @code{NSString} (@code{NXString} for GNUStep),\ - allowing efficient interworking between C-only and Objective-C code.\ - If a target implements string objects then this hook should return a\ - reference to such an object constructed from the normal `C' string\ - representation provided in @var{string}.\ - At present, the hook is used by Objective-C only, to obtain a\ - common-format string object when the target provides one.", - tree, (tree string), - NULL) - -DEFHOOK -(objc_declare_unresolved_class_reference, - "Declare that Objective C class @var{classname} is referenced\ - by the current TU.", - void, (const char *classname), - NULL) - -DEFHOOK -(objc_declare_class_definition, - "Declare that Objective C class @var{classname} is defined\ - by the current TU.", - void, (const char *classname), - NULL) - -DEFHOOK -(string_object_ref_type_p, - "If a target implements string objects then this hook should return\ - @code{true} if @var{stringref} is a valid reference to such an object.", - bool, (const_tree stringref), - hook_bool_const_tree_false) - -DEFHOOK -(check_string_object_format_arg, - "If a target implements string objects then this hook should should\ - provide a facility to check the function arguments in @var{args_list}\ - against the format specifiers in @var{format_arg} where the type of\ - @var{format_arg} is one recognized as a valid string reference type.", - void, (tree format_arg, tree args_list), - NULL) - -DEFHOOK -(c_preinclude, - "Define this hook to return the name of a header file to be included at\ - the start of all compilations, as if it had been included with\ - @code{#include <@var{file}>}. If this hook returns @code{NULL}, or is\ - not defined, or the header is not found, or if the user specifies\ - @option{-ffreestanding} or @option{-nostdinc}, no header is included.\n\ -\n\ - This hook can be used together with a header provided by the system C\ - library to implement ISO C requirements for certain macros to be\ - predefined that describe properties of the whole implementation rather\ - than just the compiler.", - const char *, (void), - hook_constcharptr_void_null) - -HOOK_VECTOR_END (C90_EMPTY_HACK) diff --git a/gcc-4.8.1/gcc/c-family/c-target.h b/gcc-4.8.1/gcc/c-family/c-target.h deleted file mode 100644 index 176f3fa07..000000000 --- a/gcc-4.8.1/gcc/c-family/c-target.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Data structure definitions for target-specific C-family behavior. - Copyright (C) 2001-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - -#ifndef GCC_C_TARGET_H -#define GCC_C_TARGET_H - -#define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME; -#define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS; -#define DEFHOOK_UNDOC DEFHOOK -#define HOOKSTRUCT(FRAGMENT) FRAGMENT - -#include "c-target.def" - -/* Each target can provide their own. */ -extern struct gcc_targetcm targetcm; - -#endif /* GCC_C_TARGET_H */ diff --git a/gcc-4.8.1/gcc/c-family/c.opt b/gcc-4.8.1/gcc/c-family/c.opt deleted file mode 100644 index 10ae84dbb..000000000 --- a/gcc-4.8.1/gcc/c-family/c.opt +++ /dev/null @@ -1,1451 +0,0 @@ -; Options for the C, ObjC, C++ and ObjC++ front ends. -; Copyright (C) 2003-2013 Free Software Foundation, Inc. -; -; This file is part of GCC. -; -; GCC is free software; you can redistribute it and/or modify it under -; the terms of the GNU General Public License as published by the Free -; Software Foundation; either version 3, or (at your option) any later -; version. -; -; GCC is distributed in the hope that it will be useful, but WITHOUT ANY -; WARRANTY; without even the implied warranty of MERCHANTABILITY or -; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -; for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; <http://www.gnu.org/licenses/>. - -; See the GCC internals manual for a description of this file's format. - -; Please try to keep this file in ASCII collating order. - -Language -C - -Language -ObjC - -Language -C++ - -Language -ObjC++ - --all-warnings -C ObjC C++ ObjC++ Warning Alias(Wall) - --ansi -C ObjC C++ ObjC++ Alias(ansi) - --assert -C ObjC C++ ObjC++ Separate Alias(A) MissingArgError(assertion missing after %qs) - --assert= -C ObjC C++ ObjC++ Joined Alias(A) MissingArgError(assertion missing after %qs) - --comments -C ObjC C++ ObjC++ Alias(C) - --comments-in-macros -C ObjC C++ ObjC++ Alias(CC) - --define-macro -C ObjC C++ ObjC++ Separate Alias(D) MissingArgError(macro name missing after %qs) - --define-macro= -C ObjC C++ ObjC++ Joined Alias(D) MissingArgError(macro name missing after %qs) - --dependencies -C ObjC C++ ObjC++ Alias(M) - --dump -C ObjC C++ ObjC++ Separate Alias(d) - --dump= -C ObjC C++ ObjC++ Joined Alias(d) - --imacros -C ObjC C++ ObjC++ Separate Alias(imacros) MissingArgError(missing filename after %qs) - --imacros= -C ObjC C++ ObjC++ Joined Alias(imacros) MissingArgError(missing filename after %qs) - --include -C ObjC C++ ObjC++ Separate Alias(include) MissingArgError(missing filename after %qs) - --include= -C ObjC C++ ObjC++ Joined Alias(include) MissingArgError(missing filename after %qs) - --include-barrier -C ObjC C++ ObjC++ Alias(I, -) - --include-directory -C ObjC C++ ObjC++ Separate Alias(I) MissingArgError(missing path after %qs) - --include-directory= -C ObjC C++ ObjC++ Joined Alias(I) MissingArgError(missing path after %qs) - --include-directory-after -C ObjC C++ ObjC++ Separate Alias(idirafter) MissingArgError(missing path after %qs) - --include-directory-after= -C ObjC C++ ObjC++ Joined Alias(idirafter) MissingArgError(missing path after %qs) - --include-prefix -C ObjC C++ ObjC++ Separate Alias(iprefix) - --include-prefix= -C ObjC C++ ObjC++ JoinedOrMissing Alias(iprefix) - --include-with-prefix -C ObjC C++ ObjC++ Separate Alias(iwithprefix) - --include-with-prefix= -C ObjC C++ ObjC++ JoinedOrMissing Alias(iwithprefix) - --include-with-prefix-after -C ObjC C++ ObjC++ Separate Alias(iwithprefix) - --include-with-prefix-after= -C ObjC C++ ObjC++ JoinedOrMissing Alias(iwithprefix) - --include-with-prefix-before -C ObjC C++ ObjC++ Separate Alias(iwithprefixbefore) - --include-with-prefix-before= -C ObjC C++ ObjC++ JoinedOrMissing Alias(iwithprefixbefore) - --no-integrated-cpp -Driver Alias(no-integrated-cpp) - --no-line-commands -C ObjC C++ ObjC++ Alias(P) - --no-standard-includes -C ObjC C++ ObjC++ Alias(nostdinc) - --no-warnings -C ObjC C++ ObjC++ Alias(w) - --output -C ObjC C++ ObjC++ Separate Alias(o) - --output= -C ObjC C++ ObjC++ Joined Alias(o) - --output-pch= -C ObjC C++ ObjC++ Joined Separate - --pedantic -C ObjC C++ ObjC++ Alias(pedantic) - --preprocess -C ObjC C++ ObjC++ Undocumented Alias(E) - --print-missing-file-dependencies -C ObjC C++ ObjC++ Alias(MG) - --trace-includes -C ObjC C++ ObjC++ Alias(H) - --traditional -Driver Alias(traditional) - --traditional-cpp -C ObjC C++ ObjC++ Alias(traditional-cpp) - --trigraphs -C ObjC C++ ObjC++ Alias(trigraphs) - --undefine-macro -C ObjC C++ ObjC++ Separate Alias(U) MissingArgError(macro name missing after %qs) - --undefine-macro= -C ObjC C++ ObjC++ Joined Alias(U) MissingArgError(macro name missing after %qs) - --user-dependencies -C ObjC C++ ObjC++ Alias(MM) - --verbose -Common C ObjC C++ ObjC++ Alias(v) - --write-dependencies -C ObjC C++ ObjC++ NoDriverArg Separate Alias(MD) MissingArgError(missing filename after %qs) - --write-user-dependencies -C ObjC C++ ObjC++ NoDriverArg Separate Alias(MMD) MissingArgError(missing filename after %qs) - -A -C ObjC C++ ObjC++ Joined Separate MissingArgError(assertion missing after %qs) --A<question>=<answer> Assert the <answer> to <question>. Putting '-' before <question> disables the <answer> to <question> - -C -C ObjC C++ ObjC++ -Do not discard comments - -CC -C ObjC C++ ObjC++ -Do not discard comments in macro expansions - -D -C ObjC C++ ObjC++ Joined Separate MissingArgError(macro name missing after %qs) --D<macro>[=<val>] Define a <macro> with <val> as its value. If just <macro> is given, <val> is taken to be 1 - -E -C ObjC C++ ObjC++ Undocumented Var(flag_preprocess_only) - -F -Driver C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path after %qs) --F <dir> Add <dir> to the end of the main framework include path - -H -C ObjC C++ ObjC++ -Print the name of header files as they are used - -I -C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path after %qs) --I <dir> Add <dir> to the end of the main include path - -M -C ObjC C++ ObjC++ -Generate make dependencies - -MD -C ObjC C++ ObjC++ NoDriverArg Separate MissingArgError(missing filename after %qs) -Generate make dependencies and compile - -MF -C ObjC C++ ObjC++ Joined Separate MissingArgError(missing filename after %qs) --MF <file> Write dependency output to the given file - -MG -C ObjC C++ ObjC++ -Treat missing header files as generated files - -MM -C ObjC C++ ObjC++ -Like -M but ignore system header files - -MMD -C ObjC C++ ObjC++ NoDriverArg Separate MissingArgError(missing filename after %qs) -Like -MD but ignore system header files - -MP -C ObjC C++ ObjC++ -Generate phony targets for all headers - -MQ -C ObjC C++ ObjC++ Joined Separate MissingArgError(missing makefile target after %qs) --MQ <target> Add a MAKE-quoted target - -MT -C ObjC C++ ObjC++ Joined Separate MissingArgError(missing makefile target after %qs) --MT <target> Add an unquoted target - -P -C ObjC C++ ObjC++ -Do not generate #line directives - -U -C ObjC C++ ObjC++ Joined Separate MissingArgError(macro name missing after %qs) --U<macro> Undefine <macro> - -Wabi -C ObjC C++ ObjC++ LTO Var(warn_abi) Warning -Warn about things that will change when compiling with an ABI-compliant compiler - -Wabi-tag -C++ ObjC++ Var(warn_abi_tag) Warning -Warn if a subobject has an abi_tag attribute that the complete object type does not have - -Wpsabi -C ObjC C++ ObjC++ LTO Var(warn_psabi) Init(1) Undocumented - -Waddress -C ObjC C++ ObjC++ Var(warn_address) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) -Warn about suspicious uses of memory addresses - -Wall -C ObjC C++ ObjC++ Warning -Enable most warning messages - -Warray-bounds -LangEnabledBy(C ObjC C++ ObjC++,Wall) -; in common.opt - -Wassign-intercept -ObjC ObjC++ Var(warn_assign_intercept) Warning -Warn whenever an Objective-C assignment is being intercepted by the garbage collector - -Wbad-function-cast -C ObjC Var(warn_bad_function_cast) Warning -Warn about casting functions to incompatible types - -Wbuiltin-macro-redefined -C ObjC C++ ObjC++ Warning -Warn when a built-in preprocessor macro is undefined or redefined - -Wc++-compat -C ObjC Var(warn_cxx_compat) Warning -Warn about C constructs that are not in the common subset of C and C++ - -Wc++0x-compat -C++ ObjC++ Var(warn_cxx0x_compat) Warning LangEnabledBy(C++ ObjC++,Wall) -Deprecated in favor of -Wc++11-compat - -Wc++11-compat -C++ ObjC++ Warning Alias(Wc++0x-compat) -Warn about C++ constructs whose meaning differs between ISO C++ 1998 and ISO C++ 2011 - -Wcast-qual -C ObjC C++ ObjC++ Var(warn_cast_qual) Warning -Warn about casts which discard qualifiers - -Wchar-subscripts -C ObjC C++ ObjC++ Var(warn_char_subscripts) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) -Warn about subscripts whose type is \"char\" - -Wclobbered -C ObjC C++ ObjC++ Var(warn_clobbered) Warning EnabledBy(Wextra) -Warn about variables that might be changed by \"longjmp\" or \"vfork\" - -Wcomment -C ObjC C++ ObjC++ Warning -Warn about possibly nested block comments, and C++ comments spanning more than one physical line - -Wcomments -C ObjC C++ ObjC++ Warning Alias(Wcomment) -Synonym for -Wcomment - -Wconversion -C ObjC C++ ObjC++ Var(warn_conversion) Warning -Warn for implicit type conversions that may change a value - -Wconversion-null -C++ ObjC++ Var(warn_conversion_null) Init(1) Warning -Warn for converting NULL from/to a non-pointer type - -Wctor-dtor-privacy -C++ ObjC++ Var(warn_ctor_dtor_privacy) Warning -Warn when all constructors and destructors are private - -Wdeclaration-after-statement -C ObjC Var(warn_declaration_after_statement) Warning -Warn when a declaration is found after a statement - -Wdelete-non-virtual-dtor -C++ ObjC++ Var(warn_delnonvdtor) Warning LangEnabledBy(C++ ObjC++,Wall) -Warn about deleting polymorphic objects with non-virtual destructors - -Wdelete-non-virtual-dtor -LangEnabledBy(C++ ObjC++,Weffc++) -; - -Wdeprecated -C C++ ObjC ObjC++ Var(warn_deprecated) Init(1) Warning -Warn if a deprecated compiler feature, class, method, or field is used - -Wdiv-by-zero -C ObjC C++ ObjC++ Var(warn_div_by_zero) Init(1) Warning -Warn about compile-time integer division by zero - -Weffc++ -C++ ObjC++ Var(warn_ecpp) Warning -Warn about violations of Effective C++ style rules - -Wempty-body -C ObjC C++ ObjC++ Var(warn_empty_body) Warning EnabledBy(Wextra) -Warn about an empty body in an if or else statement - -Wendif-labels -C ObjC C++ ObjC++ Warning -Warn about stray tokens after #elif and #endif - -Wenum-compare -C ObjC C++ ObjC++ Var(warn_enum_compare) Init(-1) Warning LangEnabledBy(C ObjC,Wall) -Warn about comparison of different enum types - -Wenum-compare -LangEnabledBy(C ObjC,Wc++-compat) -; - -Werror -C ObjC C++ ObjC++ -; Documented in common.opt - -Werror-implicit-function-declaration -C ObjC RejectNegative Warning Alias(Werror=, implicit-function-declaration) -This switch is deprecated; use -Werror=implicit-function-declaration instead - -Wfloat-equal -C ObjC C++ ObjC++ Var(warn_float_equal) Warning -Warn if testing floating point numbers for equality - -Wformat -C ObjC C++ ObjC++ Warning Alias(Wformat=, 1, 0) -Warn about printf/scanf/strftime/strfmon format string anomalies - -Wformat-contains-nul -C ObjC C++ ObjC++ Var(warn_format_contains_nul) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=, warn_format >= 1, 0) -Warn about format strings that contain NUL bytes - -Wformat-extra-args -C ObjC C++ ObjC++ Var(warn_format_extra_args) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=, warn_format >= 1, 0) -Warn if passing too many arguments to a function for its format string - -Wformat-nonliteral -C ObjC C++ ObjC++ Var(warn_format_nonliteral) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=, warn_format >= 2, 0) -Warn about format strings that are not literals - -Wformat-security -C ObjC C++ ObjC++ Var(warn_format_security) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=, warn_format >= 2, 0) -Warn about possible security problems with format functions - -Wformat-y2k -C ObjC C++ ObjC++ Var(warn_format_y2k) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=,warn_format >= 2, 0) -Warn about strftime formats yielding 2-digit years - -Wformat-zero-length -C ObjC C++ ObjC++ Var(warn_format_zero_length) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=,warn_format >= 1, 0) -Warn about zero-length formats - -Wformat= -C ObjC C++ ObjC++ Joined RejectNegative UInteger Var(warn_format) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall, 1, 0) -Warn about printf/scanf/strftime/strfmon format string anomalies - -Wignored-qualifiers -C C++ Var(warn_ignored_qualifiers) Warning EnabledBy(Wextra) -Warn whenever type qualifiers are ignored. - -Winit-self -C ObjC C++ ObjC++ Var(warn_init_self) Warning LangEnabledBy(C++ ObjC++,Wall) -Warn about variables which are initialized to themselves - -Wimplicit -C ObjC Var(warn_implicit) Warning LangEnabledBy(C ObjC,Wall) -Warn about implicit declarations - -Wdouble-promotion -C ObjC C++ ObjC++ Var(warn_double_promotion) Warning -Warn about implicit conversions from \"float\" to \"double\" - -Wimplicit-function-declaration -C ObjC Var(warn_implicit_function_declaration) Init(-1) Warning LangEnabledBy(C ObjC,Wimplicit) -Warn about implicit function declarations - -Wimplicit-int -C ObjC Var(warn_implicit_int) Warning LangEnabledBy(C ObjC,Wimplicit) -Warn when a declaration does not specify a type - -Wimport -C ObjC C++ ObjC++ Undocumented Ignore - -Winherited-variadic-ctor -C++ ObjC++ Var(warn_inh_var_ctor) Init(1) Warning -Warn about C++11 inheriting constructors when the base has a variadic constructor - -Wint-to-pointer-cast -C ObjC C++ ObjC++ Var(warn_int_to_pointer_cast) Init(1) Warning -Warn when there is a cast to a pointer from an integer of a different size - -Winvalid-offsetof -C++ ObjC++ Var(warn_invalid_offsetof) Init(1) Warning -Warn about invalid uses of the \"offsetof\" macro - -Winvalid-pch -C ObjC C++ ObjC++ Warning -Warn about PCH files that are found but not used - -Wjump-misses-init -C ObjC Var(warn_jump_misses_init) Warning LangEnabledby(C ObjC,Wc++-compat) -Warn when a jump misses a variable initialization - -Wliteral-suffix -C++ ObjC++ Warning -Warn when a string or character literal is followed by a ud-suffix which does not begin with an underscore. - -Wlogical-op -C ObjC C++ ObjC++ Var(warn_logical_op) Init(0) Warning -Warn when a logical operator is suspiciously always evaluating to true or false - -Wlong-long -C ObjC C++ ObjC++ Var(warn_long_long) Init(-1) Warning -Do not warn about using \"long long\" when -pedantic - -Wmain -C ObjC C++ ObjC++ Var(warn_main) Init(-1) Warning LangEnabledBy(C ObjC,Wall, 2, 0) -Warn about suspicious declarations of \"main\" - -Wmain -LangEnabledBy(C ObjC C++ ObjC++,Wpedantic, 2, 0) -; - -Wmissing-braces -C ObjC C++ ObjC++ Var(warn_missing_braces) Warning LangEnabledBy(C ObjC,Wall) -Warn about possibly missing braces around initializers - -Wmissing-declarations -C ObjC C++ ObjC++ Var(warn_missing_declarations) Warning -Warn about global functions without previous declarations - -Wmissing-field-initializers -C ObjC C++ ObjC++ Var(warn_missing_field_initializers) Warning EnabledBy(Wextra) -Warn about missing fields in struct initializers - -Wsizeof-pointer-memaccess -C ObjC C++ ObjC++ Var(warn_sizeof_pointer_memaccess) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) - -Wsuggest-attribute=format -C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning -Warn about functions which might be candidates for format attributes - -Wswitch -C ObjC C++ ObjC++ Var(warn_switch) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) -Warn about enumerated switches, with no default, missing a case - -Wswitch-default -C ObjC C++ ObjC++ Var(warn_switch_default) Warning -Warn about enumerated switches missing a \"default:\" statement - -Wswitch-enum -C ObjC C++ ObjC++ Var(warn_switch_enum) Warning -Warn about all enumerated switches missing a specific case - -Wmissing-format-attribute -C ObjC C++ ObjC++ Alias(Wsuggest-attribute=format) -; - -Wmissing-include-dirs -C ObjC C++ ObjC++ Warning -Warn about user-specified include directories that do not exist - -Wmissing-parameter-type -C ObjC Var(warn_missing_parameter_type) Warning EnabledBy(Wextra) -Warn about function parameters declared without a type specifier in K&R-style functions - -Wmissing-prototypes -C ObjC Var(warn_missing_prototypes) Warning -Warn about global functions without prototypes - -Wmudflap -C ObjC C++ ObjC++ Var(warn_mudflap) Init(1) Warning -Warn about constructs not instrumented by -fmudflap - -Wmultichar -C ObjC C++ ObjC++ Warning -Warn about use of multi-character character constants - -Wnarrowing -C ObjC C++ ObjC++ Warning Var(warn_narrowing) Init(-1) LangEnabledBy(C++ ObjC++,Wall) -Warn about narrowing conversions within { } that are ill-formed in C++11 - -Wnarrowing -C ObjC C++ ObjC++ LangEnabledBy(C++ ObjC++,Wc++0x-compat) -; - -Wnested-externs -C ObjC Var(warn_nested_externs) Warning -Warn about \"extern\" declarations not at file scope - -Wnoexcept -C++ ObjC++ Var(warn_noexcept) Warning -Warn when a noexcept expression evaluates to false even though the expression can't actually throw - -Wnon-template-friend -C++ ObjC++ Var(warn_nontemplate_friend) Init(1) Warning -Warn when non-templatized friend functions are declared within a template - -Wnon-virtual-dtor -C++ ObjC++ Var(warn_nonvdtor) Warning -Warn about non-virtual destructors - -Wnonnull -C ObjC C++ ObjC++ Var(warn_nonnull) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=,warn_format >= 1,0) -Warn about NULL being passed to argument slots marked as requiring non-NULL - -Wnonnull -C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall) -; - -Wnormalized= -C ObjC C++ ObjC++ Joined Warning --Wnormalized=<id|nfc|nfkc> Warn about non-normalised Unicode strings - -Wold-style-cast -C++ ObjC++ Var(warn_old_style_cast) Warning -Warn if a C-style cast is used in a program - -Wold-style-declaration -C ObjC Var(warn_old_style_declaration) Warning EnabledBy(Wextra) -Warn for obsolescent usage in a declaration - -Wold-style-definition -C ObjC Var(warn_old_style_definition) Warning -Warn if an old-style parameter definition is used - -Woverlength-strings -C ObjC C++ ObjC++ Var(warn_overlength_strings) Warning LangEnabledBy(C ObjC C++ ObjC++,Wpedantic) -Warn if a string is longer than the maximum portable length specified by the standard - -Woverloaded-virtual -C++ ObjC++ Var(warn_overloaded_virtual) Warning -Warn about overloaded virtual function names - -Woverride-init -C ObjC Var(warn_override_init) Warning EnabledBy(Wextra) -Warn about overriding initializers without side effects - -Wpacked-bitfield-compat -C ObjC C++ ObjC++ Var(warn_packed_bitfield_compat) Init(-1) Warning -Warn about packed bit-fields whose offset changed in GCC 4.4 - -Wparentheses -C ObjC C++ ObjC++ Var(warn_parentheses) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) -Warn about possibly missing parentheses - -Wpedantic -C ObjC C++ ObjC++ Warning -; Documented in common.opt - -Wpmf-conversions -C++ ObjC++ Var(warn_pmf2ptr) Init(1) Warning -Warn when converting the type of pointers to member functions - -Wpointer-arith -C ObjC C++ ObjC++ Var(warn_pointer_arith) Warning -Warn about function pointer arithmetic - -Wpointer-sign -C ObjC Var(warn_pointer_sign) Warning LangEnabledBy(C ObjC,Wall) -Warn when a pointer differs in signedness in an assignment - -Wpointer-sign -C ObjC LangEnabledBy(C ObjC,Wpedantic) -; - -Wpointer-to-int-cast -C ObjC Var(warn_pointer_to_int_cast) Init(1) Warning -Warn when a pointer is cast to an integer of a different size - -Wpragmas -C ObjC C++ ObjC++ Var(warn_pragmas) Init(1) Warning -Warn about misuses of pragmas - -Wproperty-assign-default -ObjC ObjC++ Var(warn_property_assign_default) Init(1) Warning -Warn if a property for an Objective-C object has no assign semantics specified - -Wprotocol -ObjC ObjC++ Var(warn_protocol) Init(1) Warning -Warn if inherited methods are unimplemented - -Wredundant-decls -C ObjC C++ ObjC++ Var(warn_redundant_decls) Warning -Warn about multiple declarations of the same object - -Wreorder -C++ ObjC++ Var(warn_reorder) Warning LangEnabledBy(C++ ObjC++,Wall) -Warn when the compiler reorders code - -Wreturn-local-addr -C ObjC C++ ObjC++ Var(warn_return_local_addr) Init(1) Warning -Warn about returning a pointer/reference to a local or temporary variable. - -Wreturn-type -C ObjC C++ ObjC++ Var(warn_return_type) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) -Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++) - -Wselector -ObjC ObjC++ Var(warn_selector) Warning -Warn if a selector has multiple methods - -Wsequence-point -C ObjC C++ ObjC++ Var(warn_sequence_point) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) -Warn about possible violations of sequence point rules - -Wsign-compare -C ObjC C++ ObjC++ Var(warn_sign_compare) Warning LangEnabledBy(C++ ObjC++,Wall) -Warn about signed-unsigned comparisons - -Wsign-compare -C ObjC C++ ObjC++ EnabledBy(Wextra) -; - -Wsign-conversion -C ObjC C++ ObjC++ Var(warn_sign_conversion) LangEnabledBy(C ObjC,Wconversion) -Warn for implicit type conversions between signed and unsigned integers - -Wsign-promo -C++ ObjC++ Var(warn_sign_promo) Warning -Warn when overload promotes from unsigned to signed - -Wstrict-null-sentinel -C++ ObjC++ Warning Var(warn_strict_null_sentinel) -Warn about uncasted NULL used as sentinel - -Wstrict-prototypes -C ObjC Var(warn_strict_prototypes) Warning -Warn about unprototyped function declarations - -Wstrict-aliasing= -C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall, 3, 0) -; - -Wstrict-overflow= -C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall, 1, 0) -; - -Wstrict-selector-match -ObjC ObjC++ Var(warn_strict_selector_match) Warning -Warn if type signatures of candidate methods do not match exactly - -Wsync-nand -C C++ Var(warn_sync_nand) Init(1) Warning -Warn when __sync_fetch_and_nand and __sync_nand_and_fetch built-in functions are used - -Wsynth -C++ ObjC++ Var(warn_synth) Warning -Deprecated. This switch has no effect - -Wsystem-headers -C ObjC C++ ObjC++ Warning -; Documented in common.opt - -Wtraditional -C ObjC Var(warn_traditional) Warning -Warn about features not present in traditional C - -Wtraditional-conversion -C ObjC Var(warn_traditional_conversion) Warning -Warn of prototypes causing type conversions different from what would happen in the absence of prototype - -Wtrigraphs -C ObjC C++ ObjC++ Warning -Warn if trigraphs are encountered that might affect the meaning of the program - -Wundeclared-selector -ObjC ObjC++ Var(warn_undeclared_selector) Warning -Warn about @selector()s without previously declared methods - -Wundef -C ObjC C++ ObjC++ Warning -Warn if an undefined macro is used in an #if directive - -Wuninitialized -C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall) -; - -Wmaybe-uninitialized -C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall) -; - -Wunknown-pragmas -C ObjC C++ ObjC++ Warning Var(warn_unknown_pragmas) LangEnabledBy(C ObjC C++ ObjC++,Wall, 1, 0) -Warn about unrecognized pragmas - -Wunsuffixed-float-constants -C ObjC Var(warn_unsuffixed_float_constants) Warning -Warn about unsuffixed float constants - -Wunused -C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall) -; documented in common.opt - -Wunused-local-typedefs -C ObjC C++ ObjC++ Var(warn_unused_local_typedefs) Warning EnabledBy(Wunused) -Warn when typedefs locally defined in a function are not used - -Wunused-macros -C ObjC C++ ObjC++ Var(cpp_warn_unused_macros) Warning -Warn about macros defined in the main file that are not used - -Wunused-result -C ObjC C++ ObjC++ Var(warn_unused_result) Init(1) Warning -Warn if a caller of a function, marked with attribute warn_unused_result, does not use its return value - -Wvariadic-macros -C ObjC C++ ObjC++ Var(cpp_warn_variadic_macros) Init(1) Warning -Warn about using variadic macros - -Wvarargs -C ObjC C++ ObjC++ Warning Var(warn_varargs) Init(1) -Warn about questionable usage of the macros used to retrieve variable arguments - -Wvla -C ObjC C++ ObjC++ Var(warn_vla) Init(-1) Warning -Warn if a variable length array is used - -Wvolatile-register-var -C ObjC C++ ObjC++ Var(warn_volatile_register_var) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) -Warn when a register variable is declared volatile - -Wvirtual-move-assign -C++ ObjC++ Var(warn_virtual_move_assign) Warning Init(1) -Warn if a virtual base has a non-trivial move assignment operator - -Wwrite-strings -C ObjC C++ ObjC++ Var(warn_write_strings) Warning -In C++, nonzero means warn about deprecated conversion from string literals to 'char *'. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard. - -Wzero-as-null-pointer-constant -C++ ObjC++ Var(warn_zero_as_null_pointer_constant) Warning -Warn when a literal '0' is used as null pointer - -Wuseless-cast -C++ ObjC++ Var(warn_useless_cast) Warning -Warn about useless casts - -ansi -C ObjC C++ ObjC++ -A synonym for -std=c89 (for C) or -std=c++98 (for C++) - -d -C ObjC C++ ObjC++ Joined -; Documented in common.opt. FIXME - what about -dI, -dD, -dN and -dD? - -faccess-control -C++ ObjC++ Var(flag_access_control) Init(1) -Enforce class member access control semantics - -fada-spec-parent= -C ObjC C++ ObjC++ RejectNegative Joined Var(ada_specs_parent) --fada-spec-parent=unit Dump Ada specs as child units of given parent - -fall-virtual -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) - -fallow-parameterless-variadic-functions -C ObjC Var(flag_allow_parameterless_variadic_functions) -Allow variadic functions without named parameter - -falt-external-templates -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) -No longer supported - -fasm -C ObjC C++ ObjC++ Var(flag_no_asm, 0) -Recognize the \"asm\" keyword - -; Define extra predefined macros for use in libgcc. -fbuilding-libgcc -C ObjC C++ ObjC++ Undocumented Var(flag_building_libgcc) - -fbuiltin -C ObjC C++ ObjC++ Var(flag_no_builtin, 0) -Recognize built-in functions - -fbuiltin- -C ObjC C++ ObjC++ Joined - -fcanonical-system-headers -C ObjC C++ ObjC++ -Where shorter, use canonicalized paths to systems headers. - -fcheck-new -C++ ObjC++ Var(flag_check_new) -Check the return value of new - -fcond-mismatch -C ObjC C++ ObjC++ -Allow the arguments of the '?' operator to have different types - -fconserve-space -C++ ObjC++ Var(flag_conserve_space) -Does nothing. Preserved for backward compatibility. - -fconstant-string-class= -ObjC ObjC++ Joined MissingArgError(no class name specified with %qs) --fconst-string-class=<name> Use class <name> for constant strings - -fconstexpr-depth= -C++ ObjC++ Joined RejectNegative UInteger Var(max_constexpr_depth) Init(512) --fconstexpr-depth=<number> Specify maximum constexpr recursion depth - -fdebug-cpp -C ObjC C++ ObjC++ -Emit debug annotations during preprocessing - -fdeduce-init-list -C++ ObjC++ Var(flag_deduce_init_list) Init(0) --fdeduce-init-list enable deduction of std::initializer_list for a template type parameter from a brace-enclosed initializer-list - -fdefault-inline -C++ ObjC++ Ignore -Does nothing. Preserved for backward compatibility. - -fdirectives-only -C ObjC C++ ObjC++ -Preprocess directives only. - -fdollars-in-identifiers -C ObjC C++ ObjC++ -Permit '$' as an identifier character - -fdump-ada-spec -C ObjC C++ ObjC++ RejectNegative Var(flag_dump_ada_spec) -Write all declarations as Ada code transitively - -fdump-ada-spec-slim -C ObjC C++ ObjC++ RejectNegative Var(flag_dump_ada_spec_slim) -Write all declarations as Ada code for the given file only - -felide-constructors -C++ ObjC++ Var(flag_elide_constructors) Init(1) - -fenforce-eh-specs -C++ ObjC++ Var(flag_enforce_eh_specs) Init(1) -Generate code to check exception specifications - -fenum-int-equiv -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) - -fexec-charset= -C ObjC C++ ObjC++ Joined RejectNegative --fexec-charset=<cset> Convert all strings and character constants to character set <cset> - -fextended-identifiers -C ObjC C++ ObjC++ -Permit universal character names (\\u and \\U) in identifiers - -finput-charset= -C ObjC C++ ObjC++ Joined RejectNegative --finput-charset=<cset> Specify the default character set for source files - -fextern-tls-init -C++ ObjC++ Var(flag_extern_tls_init) Init(-1) -Support dynamic initialization of thread-local variables in a different translation unit - -fexternal-templates -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) - -ffor-scope -C++ ObjC++ Var(flag_new_for_scope) Init(1) -Scope of for-init-statement variables is local to the loop - -ffreestanding -C ObjC C++ ObjC++ -Do not assume that standard C libraries and \"main\" exist - -fgnu-keywords -C++ ObjC++ Var(flag_no_gnu_keywords, 0) -Recognize GNU-defined keywords - -fgnu-runtime -ObjC ObjC++ Report RejectNegative Var(flag_next_runtime,0) Init(NEXT_OBJC_RUNTIME) -Generate code for GNU runtime environment - -fgnu89-inline -C ObjC Var(flag_gnu89_inline) Init(-1) -Use traditional GNU semantics for inline functions - -fguiding-decls -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) - -fhandle-exceptions -C++ ObjC++ Optimization Alias(fexceptions) Warn({-fhandle-exceptions has been renamed -fexceptions (and is now on by default)}) - -fhonor-std -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) - -fhosted -C ObjC -Assume normal C execution environment - -fhuge-objects -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) -No longer supported - -fimplement-inlines -C++ ObjC++ Var(flag_implement_inlines) Init(1) -Export functions even if they can be inlined - -fimplicit-inline-templates -C++ ObjC++ Var(flag_implicit_inline_templates) Init(1) -Emit implicit instantiations of inline templates - -fimplicit-templates -C++ ObjC++ Var(flag_implicit_templates) Init(1) -Emit implicit instantiations of templates - -ffriend-injection -C++ ObjC++ Var(flag_friend_injection) -Inject friend functions into enclosing namespace - -fkeep-inline-dllexport -C C++ ObjC ObjC++ Var(flag_keep_inline_dllexport) Init(1) Report Condition(TARGET_DLLIMPORT_DECL_ATTRIBUTES) -Don't emit dllexported inline functions unless needed - -flabels-ok -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) - -flax-vector-conversions -C ObjC C++ ObjC++ Var(flag_lax_vector_conversions) -Allow implicit conversions between vectors with differing numbers of subparts and/or differing element types. - -fms-extensions -C ObjC C++ ObjC++ Var(flag_ms_extensions) -Don't warn about uses of Microsoft extensions - -fmudflap -C ObjC C++ ObjC++ RejectNegative Report Var(flag_mudflap) -Add mudflap bounds-checking instrumentation for single-threaded program - -fmudflapth -C ObjC C++ ObjC++ RejectNegative Report Var(flag_mudflap,2) -Add mudflap bounds-checking instrumentation for multi-threaded program - -fmudflapir -C ObjC C++ ObjC++ RejectNegative Report Var(flag_mudflap_ignore_reads) -Ignore read operations when inserting mudflap instrumentation - -fname-mangling-version- -C++ ObjC++ Joined Ignore Warn(switch %qs is no longer supported) - -fnew-abi -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) - -fnext-runtime -ObjC ObjC++ Report RejectNegative Var(flag_next_runtime) -Generate code for NeXT (Apple Mac OS X) runtime environment - -fnil-receivers -ObjC ObjC++ Var(flag_nil_receivers) Init(1) -Assume that receivers of Objective-C messages may be nil - -fnonansi-builtins -C++ ObjC++ Var(flag_no_nonansi_builtin, 0) - -fnonnull-objects -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) - -fnothrow-opt -C++ ObjC++ Optimization Var(flag_nothrow_opt) -Treat a throw() exception specification as noexcept to improve code size - -fobjc-abi-version= -ObjC ObjC++ Joined Report RejectNegative UInteger Var(flag_objc_abi) -Specify which ABI to use for Objective-C family code and meta-data generation. - -; Generate special '- .cxx_construct' and '- .cxx_destruct' methods -; to initialize any non-POD ivars in Objective-C++ classes. -fobjc-call-cxx-cdtors -ObjC++ Var(flag_objc_call_cxx_cdtors) -Generate special Objective-C methods to initialize/destroy non-POD C++ ivars, if needed - -fobjc-direct-dispatch -ObjC ObjC++ Var(flag_objc_direct_dispatch) -Allow fast jumps to the message dispatcher - -; Nonzero means that we will allow new ObjC exception syntax (@throw, -; @try, etc.) in source code. -fobjc-exceptions -ObjC ObjC++ Var(flag_objc_exceptions) -Enable Objective-C exception and synchronization syntax - -fobjc-gc -ObjC ObjC++ Var(flag_objc_gc) -Enable garbage collection (GC) in Objective-C/Objective-C++ programs - -fobjc-nilcheck -ObjC ObjC++ Var(flag_objc_nilcheck,1) -Enable inline checks for nil receivers with the NeXT runtime and ABI version 2. - -; Nonzero means that we generate NeXT setjmp based exceptions. -fobjc-sjlj-exceptions -ObjC ObjC++ Var(flag_objc_sjlj_exceptions) Init(-1) -Enable Objective-C setjmp exception handling runtime - -fobjc-std=objc1 -ObjC ObjC++ Var(flag_objc1_only) -Conform to the Objective-C 1.0 language as implemented in GCC 4.0 - -fopenmp -C ObjC C++ ObjC++ Var(flag_openmp) -Enable OpenMP (implies -frecursive in Fortran) - -foperator-names -C++ ObjC++ -Recognize C++ keywords like \"compl\" and \"xor\" - -foptional-diags -C++ ObjC++ Ignore -Does nothing. Preserved for backward compatibility. - -fpch-deps -C ObjC C++ ObjC++ - -fpch-preprocess -C ObjC C++ ObjC++ -Look for and use PCH files even when preprocessing - -fpermissive -C++ ObjC++ Var(flag_permissive) -Downgrade conformance errors to warnings - -fplan9-extensions -C ObjC Var(flag_plan9_extensions) -Enable Plan 9 language extensions - -fpreprocessed -C ObjC C++ ObjC++ -Treat the input file as already preprocessed - -ftrack-macro-expansion -C ObjC C++ ObjC++ JoinedOrMissing RejectNegative UInteger -; converted into ftrack-macro-expansion= - -ftrack-macro-expansion= -C ObjC C++ ObjC++ JoinedOrMissing RejectNegative UInteger --ftrack-macro-expansion=<0|1|2> Track locations of tokens coming from macro expansion and display them in error messages - -fpretty-templates -C++ ObjC++ Var(flag_pretty_templates) Init(1) --fno-pretty-templates Do not pretty-print template specializations as the template signature followed by the arguments - -freplace-objc-classes -ObjC ObjC++ Var(flag_replace_objc_classes) -Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime - -frepo -C++ ObjC++ -Enable automatic template instantiation - -frtti -C++ ObjC++ Optimization Var(flag_rtti) Init(1) -Generate run time type descriptor information - -fshort-double -C ObjC C++ ObjC++ Optimization Var(flag_short_double) -Use the same size for double as for float - -fshort-enums -C ObjC C++ ObjC++ Optimization Var(flag_short_enums) -Use the narrowest integer type possible for enumeration types - -fshort-wchar -C ObjC C++ ObjC++ Optimization Var(flag_short_wchar) -Force the underlying type for \"wchar_t\" to be \"unsigned short\" - -fsigned-bitfields -C ObjC C++ ObjC++ Var(flag_signed_bitfields) Init(1) -When \"signed\" or \"unsigned\" is not given make the bitfield signed - -fsigned-char -C ObjC C++ ObjC++ LTO Var(flag_signed_char) -Make \"char\" signed by default - -fsquangle -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) - -fstats -C++ ObjC++ Var(flag_detailed_statistics) -Display statistics accumulated during compilation - -fstrict-enums -C++ ObjC++ Optimization Var(flag_strict_enums) -Assume that values of enumeration type are always within the minimum range of that type - -fstrict-prototype -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) - -ftabstop= -C ObjC C++ ObjC++ Joined RejectNegative UInteger --ftabstop=<number> Distance between tab stops for column reporting - -ftemplate-backtrace-limit= -C++ ObjC++ Joined RejectNegative UInteger Var(template_backtrace_limit) Init(10) -Set the maximum number of template instantiation notes for a single warning or error - -ftemplate-depth- -C++ ObjC++ Joined RejectNegative Undocumented Alias(ftemplate-depth=) - -ftemplate-depth= -C++ ObjC++ Joined RejectNegative UInteger --ftemplate-depth=<number> Specify maximum template instantiation depth - -fthis-is-variable -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) - -fthreadsafe-statics -C++ ObjC++ Optimization Var(flag_threadsafe_statics) Init(1) --fno-threadsafe-statics Do not generate thread-safe code for initializing local statics - -funsigned-bitfields -C ObjC C++ ObjC++ Var(flag_signed_bitfields, 0) -When \"signed\" or \"unsigned\" is not given make the bitfield unsigned - -funsigned-char -C ObjC C++ ObjC++ LTO Var(flag_signed_char, 0) -Make \"char\" unsigned by default - -fuse-cxa-atexit -C++ ObjC++ Var(flag_use_cxa_atexit) Init(DEFAULT_USE_CXA_ATEXIT) -Use __cxa_atexit to register destructors - -fuse-cxa-get-exception-ptr -C++ ObjC++ Var(flag_use_cxa_get_exception_ptr) Init(2) -Use __cxa_get_exception_ptr in exception handling - -fvisibility-inlines-hidden -C++ ObjC++ -Marks all inlined functions and methods as having hidden visibility - -fvisibility-ms-compat -C++ ObjC++ Var(flag_visibility_ms_compat) -Changes visibility to match Microsoft Visual Studio by default - -fvtable-gc -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) -No longer supported - -fvtable-thunks -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) -No longer supported - -fweak -C++ ObjC++ Var(flag_weak) Init(1) -Emit common-like symbols as weak symbols - -fwide-exec-charset= -C ObjC C++ ObjC++ Joined RejectNegative --fwide-exec-charset=<cset> Convert all wide strings and character constants to character set <cset> - -fworking-directory -C ObjC C++ ObjC++ Var(flag_working_directory) Init(-1) -Generate a #line directive pointing at the current working directory - -fxref -C++ ObjC++ Ignore Warn(switch %qs is no longer supported) -No longer supported - -fzero-link -ObjC ObjC++ Var(flag_zero_link) -Generate lazy class lookup (via objc_getClass()) for use in Zero-Link mode - -gen-decls -ObjC ObjC++ Var(flag_gen_declaration) -Dump declarations to a .decl file - -femit-struct-debug-baseonly -C ObjC C++ ObjC++ --femit-struct-debug-baseonly Aggressive reduced debug info for structs - -femit-struct-debug-reduced -C ObjC C++ ObjC++ --femit-struct-debug-reduced Conservative reduced debug info for structs - -femit-struct-debug-detailed= -C ObjC C++ ObjC++ Joined --femit-struct-debug-detailed=<spec-list> Detailed reduced debug info for structs - -fext-numeric-literals -C++ ObjC++ -Interpret imaginary, fixed-point, or other gnu number suffix as the corresponding -number literal rather than a user-defined number literal. - -idirafter -C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path after %qs) --idirafter <dir> Add <dir> to the end of the system include path - -imacros -C ObjC C++ ObjC++ Joined Separate MissingArgError(missing filename after %qs) --imacros <file> Accept definition of macros in <file> - -imultilib -C ObjC C++ ObjC++ Joined Separate --imultilib <dir> Set <dir> to be the multilib include subdirectory - -include -C ObjC C++ ObjC++ Joined Separate MissingArgError(missing filename after %qs) --include <file> Include the contents of <file> before other files - -iprefix -C ObjC C++ ObjC++ Joined Separate --iprefix <path> Specify <path> as a prefix for next two options - -isysroot -C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path after %qs) --isysroot <dir> Set <dir> to be the system root directory - -isystem -C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path after %qs) --isystem <dir> Add <dir> to the start of the system include path - -iquote -C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path after %qs) --iquote <dir> Add <dir> to the end of the quote include path - -iwithprefix -C ObjC C++ ObjC++ Joined Separate --iwithprefix <dir> Add <dir> to the end of the system include path - -iwithprefixbefore -C ObjC C++ ObjC++ Joined Separate --iwithprefixbefore <dir> Add <dir> to the end of the main include path - -lang-asm -C Undocumented RejectDriver - -no-integrated-cpp -Driver - -nostdinc -C ObjC C++ ObjC++ -Do not search standard system include directories (those specified with -isystem will still be used) - -nostdinc++ -C++ ObjC++ -Do not search standard system include directories for C++ - -o -C ObjC C++ ObjC++ Joined Separate -; Documented in common.opt - -pedantic -C ObjC C++ ObjC++ Alias(Wpedantic) -; Documented in common.opt - -print-objc-runtime-info -ObjC ObjC++ -Generate C header of platform-specific features - -remap -C ObjC C++ ObjC++ -Remap file names when including files - -std=c++98 -C++ ObjC++ -Conform to the ISO 1998 C++ standard revised by the 2003 technical corrigendum - -std=c++03 -C++ ObjC++ Alias(std=c++98) -Conform to the ISO 1998 C++ standard revised by the 2003 technical corrigendum - -std=c++11 -C++ ObjC++ -Conform to the ISO 2011 C++ standard (experimental and incomplete support) - -std=c++0x -C++ ObjC++ Alias(std=c++11) -Deprecated in favor of -std=c++11 - -std=c++1y -C++ ObjC++ -Conform to the ISO 201y(7?) C++ draft standard (experimental and incomplete support) - -std=c11 -C ObjC -Conform to the ISO 2011 C standard (experimental and incomplete support) - -std=c1x -C ObjC Alias(std=c11) -Deprecated in favor of -std=c11 - -std=c89 -C ObjC Alias(std=c90) -Conform to the ISO 1990 C standard - -std=c90 -C ObjC -Conform to the ISO 1990 C standard - -std=c99 -C ObjC -Conform to the ISO 1999 C standard - -std=c9x -C ObjC Alias(std=c99) -Deprecated in favor of -std=c99 - -std=gnu++98 -C++ ObjC++ -Conform to the ISO 1998 C++ standard revised by the 2003 technical -corrigendum with GNU extensions - -std=gnu++03 -C++ ObjC++ Alias(std=gnu++98) -Conform to the ISO 1998 C++ standard revised by the 2003 technical -corrigendum with GNU extensions - -std=gnu++11 -C++ ObjC++ -Conform to the ISO 2011 C++ standard with GNU extensions (experimental and incomplete support) - -std=gnu++0x -C++ ObjC++ Alias(std=gnu++11) -Deprecated in favor of -std=gnu++11 - -std=gnu++1y -C++ ObjC++ -Conform to the ISO 201y(7?) C++ draft standard with GNU extensions (experimental and incomplete support) - -std=gnu11 -C ObjC -Conform to the ISO 2011 C standard with GNU extensions (experimental and incomplete support) - -std=gnu1x -C ObjC Alias(std=gnu11) -Deprecated in favor of -std=gnu11 - -std=gnu89 -C ObjC Alias(std=gnu90) -Conform to the ISO 1990 C standard with GNU extensions - -std=gnu90 -C ObjC -Conform to the ISO 1990 C standard with GNU extensions - -std=gnu99 -C ObjC -Conform to the ISO 1999 C standard with GNU extensions - -std=gnu9x -C ObjC Alias(std=gnu99) -Deprecated in favor of -std=gnu99 - -std=iso9899:1990 -C ObjC Alias(std=c90) -Conform to the ISO 1990 C standard - -std=iso9899:199409 -C ObjC -Conform to the ISO 1990 C standard as amended in 1994 - -std=iso9899:1999 -C ObjC Alias(std=c99) -Conform to the ISO 1999 C standard - -std=iso9899:199x -C ObjC Alias(std=c99) -Deprecated in favor of -std=iso9899:1999 - -std=iso9899:2011 -C ObjC Alias(std=c11) -Conform to the ISO 2011 C standard (experimental and incomplete support) - -traditional -Driver - -traditional-cpp -C ObjC C++ ObjC++ -Enable traditional preprocessing - -trigraphs -C ObjC C++ ObjC++ --trigraphs Support ISO C trigraphs - -undef -C ObjC C++ ObjC++ Var(flag_undef) -Do not predefine system-specific and GCC-specific macros - -v -C ObjC C++ ObjC++ -; Documented in common.opt - -w -C ObjC C++ ObjC++ -; Documented in common.opt - -; This comment is to ensure we retain the blank line above. diff --git a/gcc-4.8.1/gcc/c-family/cppspec.c b/gcc-4.8.1/gcc/c-family/cppspec.c deleted file mode 100644 index 21d0b730b..000000000 --- a/gcc-4.8.1/gcc/c-family/cppspec.c +++ /dev/null @@ -1,198 +0,0 @@ -/* Specific flags and argument handling of the C preprocessor. - Copyright (C) 1999-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "gcc.h" -#include "opts.h" - -/* The `cpp' executable installed in $(bindir) and $(cpp_install_dir) - is a customized version of the gcc driver. It forces -E; -S and -c - are errors. It defaults to -x c for files with unrecognized - extensions, unless -x options appear in argv, in which case we - assume the user knows what they're doing. If no explicit input is - mentioned, it will read stdin. */ - -/* Suffixes for known sorts of input files. Note that we do not list - files which are normally considered to have been preprocessed already, - since the user's expectation is that `cpp' always preprocesses. */ -static const char *const known_suffixes[] = -{ - ".c", ".C", ".S", ".m", - ".cc", ".cxx", ".cpp", ".cp", ".c++", - ".sx", - NULL -}; - -/* Filter the command line before processing by the gcc driver proper. */ -void -lang_specific_driver (struct cl_decoded_option **in_decoded_options, - unsigned int *in_decoded_options_count, - int *in_added_libraries ATTRIBUTE_UNUSED) -{ - struct cl_decoded_option *decoded_options = *in_decoded_options; - unsigned int argc = *in_decoded_options_count; - - /* Do we need to read stdin? */ - int read_stdin = 1; - - /* Do we need to insert -E? */ - int need_E = 1; - - /* Have we seen an input file? */ - int seen_input = 0; - - /* Positions to insert -xc, -xassembler-with-cpp, and -o, if necessary. - 0 means unnecessary. */ - unsigned int lang_c_here = 0; - unsigned int lang_S_here = 0; - unsigned int o_here = 0; - - /* Do we need to fix up an input file with an unrecognized suffix? */ - int need_fixups = 1; - - unsigned int i, j; - struct cl_decoded_option *new_decoded_options; - unsigned int new_argc; - extern int is_cpp_driver; - - is_cpp_driver = 1; - - /* First pass. If we see an -S or -c, barf. If we see an input file, - turn off read_stdin. If we see a second input file, it is actually - the output file. If we see a third input file, barf. */ - for (i = 1; i < argc; i++) - { - switch (decoded_options[i].opt_index) - { - case OPT_E: - need_E = 0; - break; - - case OPT_S: - case OPT_c: - fatal_error ("%qs is not a valid option to the preprocessor", - decoded_options[i].orig_option_with_args_text); - return; - - case OPT_x: - need_fixups = 0; - break; - - case OPT_SPECIAL_input_file: - { - const char *file = decoded_options[i].arg; - - if (strcmp (file, "-") == 0) - read_stdin = 0; - else - { - seen_input++; - if (seen_input == 3) - { - fatal_error ("too many input files"); - return; - } - else if (seen_input == 2) - { - o_here = i; - } - else - { - read_stdin = 0; - if (need_fixups) - { - int l = strlen (file); - int known = 0; - const char *const *suff; - - for (suff = known_suffixes; *suff; suff++) - if (!strcmp (*suff, &file[l - strlen(*suff)])) - { - known = 1; - break; - } - - if (! known) - { - /* .s files are a special case; we have to - treat them like .S files so - -D__ASSEMBLER__ will be in effect. */ - if (!strcmp (".s", &file[l - 2])) - lang_S_here = i; - else - lang_c_here = i; - } - } - } - } - } - break; - } - } - - /* If we don't need to edit the command line, we can bail early. */ - - new_argc = argc + need_E + read_stdin + !!lang_c_here + !!lang_S_here; - - if (new_argc == argc && !o_here) - return; - - new_decoded_options = XNEWVEC (struct cl_decoded_option, new_argc); - - new_decoded_options[0] = decoded_options[0]; - j = 1; - - if (need_E) - generate_option (OPT_E, NULL, 1, CL_DRIVER, &new_decoded_options[j++]); - - for (i = 1; i < argc; i++, j++) - { - if (i == lang_c_here) - generate_option (OPT_x, "c", 1, CL_DRIVER, &new_decoded_options[j++]); - else if (i == lang_S_here) - generate_option (OPT_x, "assembler-with-cpp", 1, CL_DRIVER, - &new_decoded_options[j++]); - else if (i == o_here) - { - generate_option (OPT_o, decoded_options[i].arg, 1, CL_DRIVER, - &new_decoded_options[j]); - continue; - } - - new_decoded_options[j] = decoded_options[i]; - } - - if (read_stdin) - generate_option_input_file ("-", &new_decoded_options[j++]); - - *in_decoded_options_count = new_argc; - *in_decoded_options = new_decoded_options; -} - -/* Called before linking. Returns 0 on success and -1 on failure. */ -int lang_specific_pre_link (void) -{ - return 0; /* Not used for cpp. */ -} - -/* Number of extra output files that lang_specific_pre_link may generate. */ -int lang_specific_extra_outfiles = 0; /* Not used for cpp. */ diff --git a/gcc-4.8.1/gcc/c-family/stub-objc.c b/gcc-4.8.1/gcc/c-family/stub-objc.c deleted file mode 100644 index a2dbe4911..000000000 --- a/gcc-4.8.1/gcc/c-family/stub-objc.c +++ /dev/null @@ -1,462 +0,0 @@ -/* Stub functions for Objective-C and Objective-C++ routines - that are called from within the C and C++ front-ends, - respectively. - Copyright (C) 1991-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tree.h" -#include "c-common.h" -#include "c-objc.h" - -tree -objc_is_class_name (tree ARG_UNUSED (arg)) -{ - return 0; -} - -tree -objc_is_id (tree ARG_UNUSED (arg)) -{ - return 0; -} - -tree -objc_is_object_ptr (tree ARG_UNUSED (arg)) -{ - return 0; -} - -bool objc_diagnose_private_ivar (tree ARG_UNUSED (arg)) -{ - return false; -} - -tree -objc_lookup_ivar (tree other, tree ARG_UNUSED (arg)) -{ - /* Just use whatever C/C++ found. */ - return other; -} - -void -objc_check_decl (tree ARG_UNUSED (decl)) -{ -} - -void -objc_check_global_decl (tree ARG_UNUSED (decl)) -{ -} - -tree -objc_common_type (tree ARG_UNUSED (type1), tree ARG_UNUSED (type2)) -{ - return 0; -} - -bool -objc_compare_types (tree ARG_UNUSED (ltyp), tree ARG_UNUSED (rtyp), - int ARG_UNUSED (argno), tree ARG_UNUSED (callee)) -{ - return false; -} - -bool -objc_have_common_type (tree ARG_UNUSED (ltyp), tree ARG_UNUSED (rtyp), - int ARG_UNUSED (argno), tree ARG_UNUSED (callee)) -{ - return false; -} - -void -objc_volatilize_decl (tree ARG_UNUSED (decl)) -{ -} - -tree -objc_rewrite_function_call (tree function, tree ARG_UNUSED (first_param)) -{ - return function; -} - -tree -objc_message_selector (void) -{ - return 0; -} - -void -objc_declare_alias (tree ARG_UNUSED (alias), tree ARG_UNUSED (orig)) -{ -} - -void -objc_declare_class (tree ARG_UNUSED (identifier)) -{ -} - -void -objc_declare_protocol (tree ARG_UNUSED (name), tree ARG_UNUSED (attributes)) -{ -} - -void -objc_start_protocol (tree ARG_UNUSED (proto), - tree ARG_UNUSED (protorefs), - tree ARG_UNUSED (attribs)) -{ -} - -void -objc_set_method_opt (bool ARG_UNUSED (optional)) -{ -} - -void -objc_start_class_interface (tree ARG_UNUSED (name), - tree ARG_UNUSED (super), - tree ARG_UNUSED (protos), - tree ARG_UNUSED (attribs)) -{ -} - -void -objc_start_category_interface (tree ARG_UNUSED (name), - tree ARG_UNUSED (categ), - tree ARG_UNUSED (protos), - tree ARG_UNUSED (attribs)) -{ -} - -void -objc_continue_interface (void) -{ -} - -void -objc_finish_interface (void) -{ -} - -void -objc_add_instance_variable (tree ARG_UNUSED (decl)) -{ -} - -void -objc_set_visibility (objc_ivar_visibility_kind ARG_UNUSED (vis)) -{ -} - -void -objc_start_class_implementation (tree ARG_UNUSED (name), - tree ARG_UNUSED (super)) -{ -} - -void -objc_start_category_implementation (tree ARG_UNUSED (name), - tree ARG_UNUSED (categ)) -{ -} - -void -objc_continue_implementation (void) -{ -} - -void -objc_clear_super_receiver (void) -{ -} - -void -objc_finish_implementation (void) -{ -} - -void -objc_add_method_declaration (bool ARG_UNUSED (is_class_method), - tree ARG_UNUSED (signature), - tree ARG_UNUSED (attributes)) -{ -} - -bool -objc_start_method_definition (bool ARG_UNUSED (is_class_method), - tree ARG_UNUSED (signature), - tree ARG_UNUSED (attributes), - tree ARG_UNUSED (expr)) -{ - return true; -} - -void -objc_finish_method_definition (tree ARG_UNUSED (fndecl)) -{ -} - -bool -objc_method_decl (enum tree_code ARG_UNUSED(opcode)) -{ - return false; -} - -tree -objc_build_keyword_decl (tree ARG_UNUSED (selector), - tree ARG_UNUSED (type), - tree ARG_UNUSED (identifier), - tree ARG_UNUSED (attributes)) -{ - return 0; -} - -tree -objc_build_method_signature (bool ARG_UNUSED (is_class_method), - tree ARG_UNUSED (rettype), - tree ARG_UNUSED (selectors), - tree ARG_UNUSED (optparms), - bool ARG_UNUSED (ellipsis)) -{ - return 0; -} - -tree -objc_build_encode_expr (tree ARG_UNUSED (expr)) -{ - return 0; -} - -tree -objc_build_protocol_expr (tree ARG_UNUSED (expr)) -{ - return 0; -} - -tree -objc_build_selector_expr (location_t ARG_UNUSED (loc), tree ARG_UNUSED (expr)) -{ - return 0; -} - -tree -objc_build_message_expr (tree ARG_UNUSED (receiver), tree ARG_UNUSED (args)) -{ - return 0; -} - -tree -objc_build_string_object (tree ARG_UNUSED (str)) -{ - return 0; -} - -tree -objc_get_class_reference (tree ARG_UNUSED (name)) -{ - return 0; -} - -bool -objc_detect_field_duplicates (bool ARG_UNUSED (check_superclasses_only)) -{ - return false; -} - -tree -objc_get_protocol_qualified_type (tree ARG_UNUSED (name), - tree ARG_UNUSED (protos)) -{ - return 0; -} - -int -objc_static_init_needed_p (void) -{ - return 0; -} - -tree -objc_generate_static_init_call (tree ARG_UNUSED (ctors)) -{ - return 0; -} - -int -objc_is_public (tree ARG_UNUSED (expr), tree ARG_UNUSED (identifier)) -{ - return 1; -} - -tree -objc_get_class_ivars (tree ARG_UNUSED (name)) -{ - return 0; -} - -void -objc_add_property_declaration (location_t ARG_UNUSED (location), - tree ARG_UNUSED (decl), - bool ARG_UNUSED (parsed_property_readonly), - bool ARG_UNUSED (parsed_property_readwrite), - bool ARG_UNUSED (parsed_property_assign), - bool ARG_UNUSED (parsed_property_retain), - bool ARG_UNUSED (parsed_property_copy), - bool ARG_UNUSED (parsed_property_nonatomic), - tree ARG_UNUSED (parsed_property_getter_ident), - tree ARG_UNUSED (parsed_property_setter_ident)) -{ -} - -bool -objc_is_property_ref (tree ARG_UNUSED (node)) -{ - return 0; -} - -tree -objc_maybe_build_component_ref (tree ARG_UNUSED (datum), tree ARG_UNUSED (component)) -{ - return 0; -} - -tree -objc_build_class_component_ref (tree ARG_UNUSED (datum), tree ARG_UNUSED (component)) -{ - return 0; -} - -tree -objc_maybe_build_modify_expr (tree ARG_UNUSED (lhs), tree ARG_UNUSED (rhs)) -{ - return 0; -} - -tree -objc_build_incr_expr_for_property_ref (location_t ARG_UNUSED (location), - enum tree_code ARG_UNUSED (code), - tree ARG_UNUSED (argument), - tree ARG_UNUSED (increment)) -{ - return 0; -} - -void -objc_add_synthesize_declaration (location_t ARG_UNUSED (start_locus), - tree ARG_UNUSED (property_and_ivar_list)) -{ -} - -void -objc_add_dynamic_declaration (location_t ARG_UNUSED (start_locus), - tree ARG_UNUSED (property_list)) -{ -} - -const char * -objc_maybe_printable_name (tree ARG_UNUSED (decl), - int ARG_UNUSED (v)) -{ - return NULL; -} - -tree -objc_build_throw_stmt (location_t ARG_UNUSED (loc), tree ARG_UNUSED (expr)) -{ - return 0; -} - -tree -objc_build_synchronized (location_t ARG_UNUSED (start_locus), - tree ARG_UNUSED (mutex), tree ARG_UNUSED (body)) -{ - return 0; -} - -void -objc_begin_try_stmt (location_t ARG_UNUSED (try_locus), tree ARG_UNUSED (body)) -{ -} - -void -objc_begin_catch_clause (tree ARG_UNUSED (decl)) -{ -} - -void -objc_finish_catch_clause (void) -{ -} - -void -objc_build_finally_clause (location_t ARG_UNUSED (finally_locus), - tree ARG_UNUSED (body)) -{ -} - -tree -objc_finish_try_stmt (void) -{ - return 0; -} - -tree -objc_generate_write_barrier (tree ARG_UNUSED (lhs), - enum tree_code ARG_UNUSED (modifycode), - tree ARG_UNUSED (rhs)) -{ - return 0; -} - -void -objc_finish_foreach_loop (location_t ARG_UNUSED (location), tree ARG_UNUSED (object_expression), - tree ARG_UNUSED (collection_expression), tree ARG_UNUSED (for_body), - tree ARG_UNUSED (break_label), tree ARG_UNUSED (continue_label)) -{ - return; -} - -void -objc_write_global_declarations (void) -{ -} - -bool -objc_string_ref_type_p (tree ARG_UNUSED (strp)) -{ - return false; -} - -void -objc_check_format_arg (tree ARG_UNUSED (format_arg), - tree ARG_UNUSED (args_list)) -{ -} - -void -objc_finish_function (void) -{ -} - -void -objc_maybe_warn_exceptions (location_t ARG_UNUSED (loc)) -{ -} |