summaryrefslogtreecommitdiff
path: root/gcc/opts.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/opts.c')
-rw-r--r--gcc/opts.c164
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. */