The following patch enables GCC to record system include paths in module infos. This allows more precise parsing context to be established when compiling auxiliary modules -- FE behaves slightly differently when parsing system headers. There are also a couple of other cleanups in the patch.
David
Index: libgcc/dyn-ipa.c =================================================================== --- libgcc/dyn-ipa.c (revision 202477) +++ libgcc/dyn-ipa.c (working copy) @@ -2082,9 +2082,10 @@ gcov_write_module_info (const struct gco len = filename_len + src_filename_len; len += 2; /* each name string is led by a length. */ - num_strings = module_info->num_quote_paths + module_info->num_bracket_paths + - module_info->num_cpp_defines + module_info->num_cpp_includes + - module_info->num_cl_args; + num_strings = module_info->num_quote_paths + module_info->num_bracket_paths + + module_info->num_system_paths + + module_info->num_cpp_defines + module_info->num_cpp_includes + + module_info->num_cl_args; for (i = 0; i < num_strings; i++) { gcov_unsigned_t string_len @@ -2094,7 +2095,7 @@ gcov_write_module_info (const struct gco len += 1; /* Each string is lead by a length. */ } - len += 9; /* 9 more fields */ + len += 10; /* 9 more fields */ gcov_write_tag_length (GCOV_TAG_MODULE_INFO, len); gcov_write_unsigned (module_info->ident); @@ -2105,6 +2106,7 @@ gcov_write_module_info (const struct gco gcov_write_unsigned (module_info->lang); gcov_write_unsigned (module_info->num_quote_paths); gcov_write_unsigned (module_info->num_bracket_paths); + gcov_write_unsigned (module_info->num_system_paths); gcov_write_unsigned (module_info->num_cpp_defines); gcov_write_unsigned (module_info->num_cpp_includes); gcov_write_unsigned (module_info->num_cl_args); Index: gcc/gcov-io.c =================================================================== --- gcc/gcov-io.c (revision 202477) +++ gcc/gcov-io.c (working copy) @@ -594,10 +594,11 @@ gcov_read_module_info (struct gcov_modul mod_info->lang = gcov_read_unsigned (); mod_info->num_quote_paths = gcov_read_unsigned (); mod_info->num_bracket_paths = gcov_read_unsigned (); + mod_info->num_system_paths = gcov_read_unsigned (); mod_info->num_cpp_defines = gcov_read_unsigned (); mod_info->num_cpp_includes = gcov_read_unsigned (); mod_info->num_cl_args = gcov_read_unsigned (); - len -= 9; + len -= 10; filename_len = gcov_read_unsigned (); mod_info->da_filename = (char *) xmalloc (filename_len * @@ -613,9 +614,10 @@ gcov_read_module_info (struct gcov_modul ((gcov_unsigned_t *) mod_info->source_filename)[i] = gcov_read_unsigned (); len -= (src_filename_len + 1); - num_strings = mod_info->num_quote_paths + mod_info->num_bracket_paths + - mod_info->num_cpp_defines + mod_info->num_cpp_includes + - mod_info->num_cl_args; + num_strings = mod_info->num_quote_paths + mod_info->num_bracket_paths + + mod_info->num_system_paths + + mod_info->num_cpp_defines + mod_info->num_cpp_includes + + mod_info->num_cl_args; for (j = 0; j < num_strings; j++) { gcov_unsigned_t string_len = gcov_read_unsigned (); Index: gcc/gcov-io.h =================================================================== --- gcc/gcov-io.h (revision 202477) +++ gcc/gcov-io.h (working copy) @@ -537,6 +537,7 @@ struct gcov_module_info char *source_filename; gcov_unsigned_t num_quote_paths; gcov_unsigned_t num_bracket_paths; + gcov_unsigned_t num_system_paths; gcov_unsigned_t num_cpp_defines; gcov_unsigned_t num_cpp_includes; gcov_unsigned_t num_cl_args; Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 202477) +++ gcc/cp/cp-tree.h (working copy) @@ -5512,6 +5512,7 @@ extern tree get_template_argument_pack_e extern tree get_function_template_decl (const_tree); extern tree resolve_nondeduced_context (tree); extern hashval_t iterative_hash_template_arg (tree arg, hashval_t val); +extern void clear_pending_templates (void); /* in repo.c */ extern void init_repo (void); Index: gcc/cp/decl2.c =================================================================== --- gcc/cp/decl2.c (revision 202477) +++ gcc/cp/decl2.c (working copy) @@ -3890,10 +3890,12 @@ void cp_clear_deferred_fns (void) { vec_free (deferred_fns); + deferred_fns = NULL; keyed_classes = NULL; vec_free (no_linkage_decls); no_linkage_decls = NULL; cp_clear_constexpr_hashtable (); + clear_pending_templates (); } /* Collect declarations from all namespaces relevant to SOURCE_FILE. */ @@ -4225,18 +4227,19 @@ cp_process_pending_declarations (locatio if (L_IPO_IS_AUXILIARY_MODULE) { + tree fndecl; + int i; + gcc_assert (flag_dyn_ipa && L_IPO_COMP_MODE); /* Do some cleanup -- we do not really need static init function to be created for auxiliary modules -- they are created to keep funcdef_no consistent between profile use and profile gen. */ -#if FIXME_LIPO - for (i = 0; ssdf_decls->iterator (i, fndecl); ++i) + FOR_EACH_VEC_SAFE_ELT (ssdf_decls, i, fndecl) /* Such ssdf_decls are not called from GLOBAL ctor/dtor, mark them reachable to avoid being eliminated too early before gimplication. */ - cgraph_mark_reachable_node (cgraph_get_create_node (fndecl)); -#endif + cgraph_enqueue_node (cgraph_get_create_node (fndecl)); ssdf_decls = NULL; timevar_stop (TV_PHASE_DEFERRED); return; Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 202477) +++ gcc/cp/pt.c (working copy) @@ -59,6 +59,13 @@ struct GTY ((chain_next ("%h.next"))) pe static GTY(()) struct pending_template *pending_templates; static GTY(()) struct pending_template *last_pending_template; +void +clear_pending_templates (void) +{ + pending_templates = NULL; + last_pending_template = NULL; +} + int processing_template_parmlist; static int template_header_count; Index: gcc/coverage.c =================================================================== --- gcc/coverage.c (revision 202477) +++ gcc/coverage.c (working copy) @@ -264,6 +264,9 @@ static struct opt_desc force_matching_cg { "-fsized-delete", "-fno-sized-delete", false }, { "-frtti", "-fno-rtti", true }, { "-fstrict-aliasing", "-fno-strict-aliasing", true }, + { "-fsigned-char", "-funsigned-char", true }, + /* { "-fsigned-char", "-fno-signed-char", true }, + { "-funsigned-char", "-fno-unsigned-char", false }, */ { "-ansi", "", false }, { NULL, NULL, false } }; @@ -319,12 +322,12 @@ incompatible_cl_args (struct gcov_module bool warning_mismatch = false; bool non_warning_mismatch = false; hash_table <string_hasher> option_tab1, option_tab2; - unsigned int start_index1 = mod_info1->num_quote_paths + - mod_info1->num_bracket_paths + mod_info1->num_cpp_defines + - mod_info1->num_cpp_includes; - unsigned int start_index2 = mod_info2->num_quote_paths + - mod_info2->num_bracket_paths + mod_info2->num_cpp_defines + - mod_info2->num_cpp_includes; + unsigned int start_index1 = mod_info1->num_quote_paths + + mod_info1->num_bracket_paths + mod_info1->num_system_paths + + mod_info1->num_cpp_defines + mod_info1->num_cpp_includes; + unsigned int start_index2 = mod_info2->num_quote_paths + + mod_info2->num_bracket_paths + mod_info2->num_system_paths + + mod_info2->num_cpp_defines + mod_info2->num_cpp_includes; bool *cg_opts1, *cg_opts2, has_any_incompatible_cg_opts, has_incompatible_std; unsigned int num_cg_opts = 0; @@ -819,6 +822,7 @@ read_counts_file (const char *da_file_na info_sz = (sizeof (struct gcov_module_info) + sizeof (void *) * (mod_info->num_quote_paths + mod_info->num_bracket_paths + + mod_info->num_system_paths + mod_info->num_cpp_defines + mod_info->num_cpp_includes + mod_info->num_cl_args)); @@ -1796,8 +1800,8 @@ build_gcov_module_info_type (void) tree type, field, fields = NULL_TREE; tree string_type, index_type, string_array_type; - cpp_dir *quote_paths, *bracket_paths, *pdir; - int num_quote_paths = 0, num_bracket_paths = 0; + cpp_dir *quote_paths, *bracket_paths, *system_paths, *pdir; + int num_quote_paths = 0, num_bracket_paths = 0, num_system_paths = 0; type = lang_hooks.types.make_type (RECORD_TYPE); string_type = build_pointer_type ( @@ -1863,6 +1867,12 @@ build_gcov_module_info_type (void) DECL_CHAIN (field) = fields; fields = field; + /* Num system paths */ + field = build_decl (BUILTINS_LOCATION, FIELD_DECL, + NULL_TREE, get_gcov_unsigned_t ()); + DECL_CHAIN (field) = fields; + fields = field; + /* Num -D/-U options. */ field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); @@ -1881,7 +1891,7 @@ build_gcov_module_info_type (void) DECL_CHAIN (field) = fields; fields = field; - get_include_chains ("e_paths, &bracket_paths); + get_include_chains ("e_paths, &bracket_paths, &system_paths); for (pdir = quote_paths; pdir; pdir = pdir->next) { if (pdir == bracket_paths) @@ -1889,15 +1899,23 @@ build_gcov_module_info_type (void) num_quote_paths++; } for (pdir = bracket_paths; pdir; pdir = pdir->next) - num_bracket_paths++; + { + if (pdir == system_paths) + break; + num_bracket_paths++; + } + for (pdir = system_paths; pdir; pdir = pdir->next) + num_system_paths++; /* string array */ index_type = build_index_type (build_int_cst (NULL_TREE, num_quote_paths + num_bracket_paths + + num_system_paths + num_cpp_defines + num_cpp_includes + num_lipo_cl_args)); + string_array_type = build_array_type (string_type, index_type); field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, string_array_type); @@ -1919,8 +1937,8 @@ build_gcov_module_info_value (tree mod_t tree value = NULL_TREE; int file_name_len; tree filename_string, string_array_type, string_type; - cpp_dir *quote_paths, *bracket_paths, *pdir; - int num_quote_paths = 0, num_bracket_paths = 0; + cpp_dir *quote_paths, *bracket_paths, *system_paths, *pdir; + int num_quote_paths = 0, num_bracket_paths = 0, num_system_paths = 0; unsigned lang; char name_buf[50]; vec<constructor_elt,va_gc> *v = NULL, *path_v = NULL; @@ -1991,7 +2009,7 @@ build_gcov_module_info_value (tree mod_t build1 (ADDR_EXPR, string_type, filename_string)); info_fields = DECL_CHAIN (info_fields); - get_include_chains ("e_paths, &bracket_paths); + get_include_chains ("e_paths, &bracket_paths, &system_paths); for (pdir = quote_paths; pdir; pdir = pdir->next) { if (pdir == bracket_paths) @@ -1999,7 +2017,13 @@ build_gcov_module_info_value (tree mod_t num_quote_paths++; } for (pdir = bracket_paths; pdir; pdir = pdir->next) - num_bracket_paths++; + { + if (pdir == system_paths) + break; + num_bracket_paths++; + } + for (pdir = system_paths; pdir; pdir = pdir->next) + num_system_paths++; /* Num quote paths */ CONSTRUCTOR_APPEND_ELT (v, info_fields, @@ -2013,6 +2037,12 @@ build_gcov_module_info_value (tree mod_t num_bracket_paths)); info_fields = DECL_CHAIN (info_fields); + /* Num system paths */ + CONSTRUCTOR_APPEND_ELT (v, info_fields, + build_int_cstu (get_gcov_unsigned_t (), + num_system_paths)); + info_fields = DECL_CHAIN (info_fields); + /* Num -D/-U options. */ CONSTRUCTOR_APPEND_ELT (v, info_fields, build_int_cstu (get_gcov_unsigned_t (), @@ -2037,6 +2067,8 @@ build_gcov_module_info_value (tree mod_t quote_paths, num_quote_paths); build_inc_path_array_value (string_type, &path_v, bracket_paths, num_bracket_paths); + build_inc_path_array_value (string_type, &path_v, + system_paths, num_system_paths); build_str_array_value (string_type, &path_v, cpp_defines_head); build_str_array_value (string_type, &path_v, @@ -2536,21 +2568,21 @@ set_lipo_c_parsing_context (struct cpp_r i < mod_info->num_bracket_paths; i++, j++) add_path (xstrdup (mod_info->string_array[j]), BRACKET, 0, 1); + for (i = 0; i < mod_info->num_system_paths; i++, j++) + add_path (xstrdup (mod_info->string_array[j]), + SYSTEM, 0, 1); register_include_chains (parse_in, NULL, NULL, NULL, 0, 0, verbose); /* Setup defines/undefs. */ - for (i = 0, j = mod_info->num_quote_paths + mod_info->num_bracket_paths; - i < mod_info->num_cpp_defines; i++, j++) + for (i = 0; i < mod_info->num_cpp_defines; i++, j++) if (mod_info->string_array[j][0] == 'D') cpp_define (parse_in, mod_info->string_array[j] + 1); else cpp_undef (parse_in, mod_info->string_array[j] + 1); /* Setup -imacro/-include. */ - for (i = 0, j = mod_info->num_quote_paths + mod_info->num_bracket_paths + - mod_info->num_cpp_defines; i < mod_info->num_cpp_includes; - i++, j++) + for (i = 0; i < mod_info->num_cpp_includes; i++, j++) cpp_push_include (parse_in, mod_info->string_array[j]); } } @@ -2751,12 +2783,13 @@ void write_compilation_flags_to_asm (void) { size_t i; - cpp_dir *quote_paths, *bracket_paths, *pdir; + cpp_dir *quote_paths, *bracket_paths, *system_paths, *pdir; struct str_list *pdef, *pinc; int num_quote_paths = 0; int num_bracket_paths = 0; + int num_system_paths = 0; - get_include_chains ("e_paths, &bracket_paths); + get_include_chains ("e_paths, &bracket_paths, &system_paths); /* Write quote_paths to ASM section. */ switch_to_section (get_section (".gnu.switches.text.quote_paths", @@ -2780,10 +2813,28 @@ write_compilation_flags_to_asm (void) switch_to_section (get_section (".gnu.switches.text.bracket_paths", SECTION_DEBUG, NULL)); for (pdir = bracket_paths; pdir; pdir = pdir->next) - num_bracket_paths++; + { + if (pdir == system_paths) + break; + num_bracket_paths++; + } dw2_asm_output_nstring (in_fnames[0], (size_t)-1, NULL); dw2_asm_output_data_uleb128 (num_bracket_paths, NULL); for (pdir = bracket_paths; pdir; pdir = pdir->next) + { + if (pdir == system_paths) + break; + dw2_asm_output_nstring (pdir->name, (size_t)-1, NULL); + } + + /* Write system_paths to ASM section. */ + switch_to_section (get_section (".gnu.switches.text.system_paths", + SECTION_DEBUG, NULL)); + for (pdir = system_paths; pdir; pdir = pdir->next) + num_system_paths++; + dw2_asm_output_nstring (in_fnames[0], (size_t)-1, NULL); + dw2_asm_output_data_uleb128 (num_system_paths, NULL); + for (pdir = system_paths; pdir; pdir = pdir->next) dw2_asm_output_nstring (pdir->name, (size_t)-1, NULL); /* Write cpp_defines to ASM section. */ Index: gcc/cgraph.h =================================================================== --- gcc/cgraph.h (revision 202477) +++ gcc/cgraph.h (working copy) @@ -727,6 +727,7 @@ void fixup_same_cpp_alias_visibility (sy /* Initialize datastructures so DECL is a function in lowered gimple form. IN_SSA is true if the gimple is in SSA. */ basic_block init_lowered_empty_function (tree decl, bool in_ssa); +void cgraph_enqueue_node (struct cgraph_node *); /* In cgraphclones.c */ Index: gcc/cgraphunit.c =================================================================== --- gcc/cgraphunit.c (revision 202477) +++ gcc/cgraphunit.c (working copy) @@ -271,6 +271,12 @@ enqueue_node (symtab_node node) first = node; } +void +cgraph_enqueue_node (struct cgraph_node *node) +{ + enqueue_node ((symtab_node) node); +} + /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these functions into callgraph in a way so they look like ordinary reachable functions inserted into callgraph already at construction time. */ Index: gcc/incpath.c =================================================================== --- gcc/incpath.c (revision 202477) +++ gcc/incpath.c (working copy) @@ -457,10 +457,11 @@ add_path (char *path, int chain, int cxx in *BRACKETS and *QUOTES respectively. */ void -get_include_chains (cpp_dir **quotes, cpp_dir **brackets) +get_include_chains (cpp_dir **quotes, cpp_dir **brackets, cpp_dir **systems) { *quotes = heads[QUOTE]; *brackets = heads[BRACKET]; + *systems = heads[SYSTEM]; } /* Make HEAD and TAIL pointers to include paths resynchronized Index: gcc/incpath.h =================================================================== --- gcc/incpath.h (revision 202477) +++ gcc/incpath.h (working copy) @@ -21,7 +21,8 @@ extern void register_include_chains (cpp const char *, const char *, int, int, int); extern void add_cpp_dir_path (struct cpp_dir *, int); -extern void get_include_chains (cpp_dir **quotes, cpp_dir **brackets); +extern void get_include_chains (cpp_dir **quotes, cpp_dir **brackets, + cpp_dir **systems); extern void clear_include_chains (void); extern struct cpp_dir *get_added_cpp_dirs (int);