diff options
Diffstat (limited to 'gcc/opts.c')
-rw-r--r-- | gcc/opts.c | 164 |
1 files changed, 15 insertions, 149 deletions
diff --git a/gcc/opts.c b/gcc/opts.c index b2787ce9660..dc3278d0bb0 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -53,53 +53,6 @@ enum debug_info_type write_symbols = NO_DEBUG; the definitions of the different possible levels. */ enum debug_info_level debug_info_level = DINFO_LEVEL_NONE; -/* A major contribution to object and executable size is debug - information size. A major contribution to debug information size - is struct descriptions replicated in several object files. The - following flags attempt to reduce this information. The basic - idea is to not emit struct debugging information in the current - compilation unit when that information will be generated by - another compilation unit. - - Debug information for a struct defined in the current source - file should be generated in the object file. Likewise the - debug information for a struct defined in a header should be - generated in the object file of the corresponding source file. - Both of these case are handled when the base name of the file of - the struct definition matches the base name of the source file - of the current compilation unit. This matching emits minimal - struct debugging information. - - The base file name matching rule above will fail to emit debug - information for structs defined in system headers. So a second - category of files includes system headers in addition to files - with matching bases. - - The remaining types of files are library headers and application - headers. We cannot currently distinguish these two types. */ - -enum debug_struct_file -{ - DINFO_STRUCT_FILE_NONE, /* Debug no structs. */ - DINFO_STRUCT_FILE_BASE, /* Debug structs defined in files with the - same base name as the compilation unit. */ - DINFO_STRUCT_FILE_SYS, /* Also debug structs defined in system - header files. */ - DINFO_STRUCT_FILE_ANY /* Debug structs defined in all files. */ -}; - -/* Generic structs (e.g. templates not explicitly specialized) - may not have a compilation unit associated with them, and so - may need to be treated differently from ordinary structs. - - Structs only handled by reference (indirectly), will also usually - not need as much debugging information. */ - -static enum debug_struct_file debug_struct_ordinary[DINFO_USAGE_NUM_ENUMS] - = { DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY }; -static enum debug_struct_file debug_struct_generic[DINFO_USAGE_NUM_ENUMS] - = { DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY }; - /* Run the second compilation of -fcompare-debug. Not defined using Var in common.opt because this is used in Ada code and so must be an actual variable not a macro. */ @@ -113,7 +66,7 @@ int flag_compare_debug; ? ((string += sizeof prefix - 1), 1) : 0) void -set_struct_debug_option (const char *spec) +set_struct_debug_option (struct gcc_options *opts, const char *spec) { /* various labels for comparison */ static char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:"; @@ -158,27 +111,27 @@ set_struct_debug_option (const char *spec) { if (ord) { - debug_struct_ordinary[DINFO_USAGE_DFN] = files; - debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files; - debug_struct_ordinary[DINFO_USAGE_IND_USE] = files; + opts->x_debug_struct_ordinary[DINFO_USAGE_DFN] = files; + opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files; + opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] = files; } if (gen) { - debug_struct_generic[DINFO_USAGE_DFN] = files; - debug_struct_generic[DINFO_USAGE_DIR_USE] = files; - debug_struct_generic[DINFO_USAGE_IND_USE] = files; + opts->x_debug_struct_generic[DINFO_USAGE_DFN] = files; + opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] = files; + opts->x_debug_struct_generic[DINFO_USAGE_IND_USE] = files; } } else { if (ord) - debug_struct_ordinary[usage] = files; + opts->x_debug_struct_ordinary[usage] = files; if (gen) - debug_struct_generic[usage] = files; + opts->x_debug_struct_generic[usage] = files; } if (*spec == ',') - set_struct_debug_option (spec+1); + set_struct_debug_option (opts, spec+1); else { /* No more -femit-struct-debug-detailed specifications. @@ -186,10 +139,10 @@ set_struct_debug_option (const char *spec) if (*spec != '\0') error ("argument %qs to %<-femit-struct-debug-detailed%> unknown", spec); - if (debug_struct_ordinary[DINFO_USAGE_DIR_USE] - < debug_struct_ordinary[DINFO_USAGE_IND_USE] - || debug_struct_generic[DINFO_USAGE_DIR_USE] - < debug_struct_generic[DINFO_USAGE_IND_USE]) + if (opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] + < opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] + || opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] + < opts->x_debug_struct_generic[DINFO_USAGE_IND_USE]) error ("%<-femit-struct-debug-detailed=dir:...%> must allow at least" " as much as %<-femit-struct-debug-detailed=ind:...%>"); } @@ -197,7 +150,7 @@ set_struct_debug_option (const char *spec) /* Find the base name of a path, stripping off both directories and a single final extension. */ -static int +int base_of_path (const char *path, const char **base_out) { const char *base = path; @@ -221,93 +174,6 @@ base_of_path (const char *path, const char **base_out) return dot - base; } -/* Match the base name of a file to the base name of a compilation unit. */ - -static const char *main_input_basename; -static int main_input_baselength; - -static int -matches_main_base (const char *path) -{ - /* Cache the last query. */ - static const char *last_path = NULL; - static int last_match = 0; - if (path != last_path) - { - const char *base; - int length = base_of_path (path, &base); - last_path = path; - last_match = (length == main_input_baselength - && memcmp (base, main_input_basename, length) == 0); - } - return last_match; -} - -#ifdef DEBUG_DEBUG_STRUCT - -static int -dump_struct_debug (tree type, enum debug_info_usage usage, - enum debug_struct_file criterion, int generic, - int matches, int result) -{ - /* Find the type name. */ - tree type_decl = TYPE_STUB_DECL (type); - tree t = type_decl; - const char *name = 0; - if (TREE_CODE (t) == TYPE_DECL) - t = DECL_NAME (t); - if (t) - name = IDENTIFIER_POINTER (t); - - fprintf (stderr, " struct %d %s %s %s %s %d %p %s\n", - criterion, - DECL_IN_SYSTEM_HEADER (type_decl) ? "sys" : "usr", - matches ? "bas" : "hdr", - generic ? "gen" : "ord", - usage == DINFO_USAGE_DFN ? ";" : - usage == DINFO_USAGE_DIR_USE ? "." : "*", - result, - (void*) type_decl, name); - return result; -} -#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \ - dump_struct_debug (type, usage, criterion, generic, matches, result) - -#else - -#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \ - (result) - -#endif - - -bool -should_emit_struct_debug (tree type, enum debug_info_usage usage) -{ - enum debug_struct_file criterion; - tree type_decl; - bool generic = lang_hooks.types.generic_p (type); - - if (generic) - criterion = debug_struct_generic[usage]; - else - criterion = debug_struct_ordinary[usage]; - - if (criterion == DINFO_STRUCT_FILE_NONE) - return DUMP_GSTRUCT (type, usage, criterion, generic, false, false); - if (criterion == DINFO_STRUCT_FILE_ANY) - return DUMP_GSTRUCT (type, usage, criterion, generic, false, true); - - type_decl = TYPE_STUB_DECL (type); - - if (criterion == DINFO_STRUCT_FILE_SYS && DECL_IN_SYSTEM_HEADER (type_decl)) - return DUMP_GSTRUCT (type, usage, criterion, generic, false, true); - - if (matches_main_base (DECL_SOURCE_FILE (type_decl))) - return DUMP_GSTRUCT (type, usage, criterion, generic, true, true); - return DUMP_GSTRUCT (type, usage, criterion, generic, false, false); -} - /* Nonzero means use GNU-only extensions in the generated symbolic debugging information. Currently, this only has an effect when write_symbols is set to DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */ |