aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c-opts.c7
-rw-r--r--gcc/common.opt13
-rw-r--r--gcc/dwarf2out.c83
-rw-r--r--gcc/flag-types.h35
-rw-r--r--gcc/flags.h5
-rw-r--r--gcc/optc-gen.awk1
-rw-r--r--gcc/opth-gen.awk6
-rw-r--r--gcc/opts.c164
-rw-r--r--gcc/toplev.c6
-rw-r--r--gcc/toplev.h2
12 files changed, 195 insertions, 155 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b065ee3..31ace53 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,28 @@
2010-11-19 Joseph Myers <joseph@codesourcery.com>
+ * common.opt (debug_struct_ordinary, debug_struct_generic): New
+ Variable entries.
+ * dwarf2out.c (matches_main_base, dump_struct_debug, DUMP_GSTRUCT,
+ should_emit_struct_debug): Move from opts.c.
+ * flag-types.h (enum debug_struct_file): Move from opts.c.
+ * flags.h (should_emit_struct_debug): Remove.
+ (base_of_path): Declare.
+ (set_struct_debug_option): Add gcc_options parameter.
+ * optc-gen.awk, opth-gen.awk: Handle array variables.
+ * opts.c (enum debug_struct_file, debug_struct_ordinary,
+ debug_struct_generic): Remove.
+ (set_struct_debug_option): Add gcc_options parameter.
+ (base_of_path): Remove static.
+ (main_input_basename, main_input_baselength, matches_main_base,
+ dump_struct_debug, DUMP_GSTRUCT, should_emit_struct_debug):
+ Remove.
+ * toplev.c (main_input_basename, main_input_baselength): Define
+ here.
+ * toplev.h (main_input_basename, main_input_baselength): Declare
+ here.
+
+2010-11-19 Joseph Myers <joseph@codesourcery.com>
+
* common.opt (flag_instrument_functions_exclude_functions,
flag_instrument_functions_exclude_files): New Variable
definitions.
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 61dc8b6..9369068 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,8 @@
+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.
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 3d70136..7d12859 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -654,15 +654,16 @@ c_common_handle_option (size_t scode, const char *arg, int value,
break;
case OPT_femit_struct_debug_baseonly:
- set_struct_debug_option ("base");
+ set_struct_debug_option (&global_options, "base");
break;
case OPT_femit_struct_debug_reduced:
- set_struct_debug_option ("dir:ord:sys,dir:gen:any,ind:base");
+ set_struct_debug_option (&global_options,
+ "dir:ord:sys,dir:gen:any,ind:base");
break;
case OPT_femit_struct_debug_detailed_:
- set_struct_debug_option (arg);
+ set_struct_debug_option (&global_options, arg);
break;
case OPT_idirafter:
diff --git a/gcc/common.opt b/gcc/common.opt
index 9a1f905..9e38c4c 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -113,6 +113,19 @@ void *flag_instrument_functions_exclude_functions
Variable
void *flag_instrument_functions_exclude_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.
+
+Variable
+enum debug_struct_file debug_struct_ordinary[DINFO_USAGE_NUM_ENUMS] = { DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY }
+
+Variable
+enum debug_struct_file debug_struct_generic[DINFO_USAGE_NUM_ENUMS] = { DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY }
+
###
Driver
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 3285dac..32bb4dc 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -546,6 +546,89 @@ static struct dw_loc_descr_struct *mem_loc_descriptor
#define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG)
#endif
+/* Match the base name of a file to the base name of a compilation unit. */
+
+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
+
+static 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);
+}
+
/* Hook used by __throw. */
rtx
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index 4259985..6eb6c3f 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -58,6 +58,41 @@ enum debug_info_usage
DINFO_USAGE_NUM_ENUMS /* The number of enumerators. */
};
+/* 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. */
+};
+
/* Enumerate visibility settings. This is deliberately ordered from most
to least visibility. */
#ifndef SYMBOL_VISIBILITY_DEFINED
diff --git a/gcc/flags.h b/gcc/flags.h
index 3cc65a4..4edb784 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -37,8 +37,9 @@ extern const char *const debug_type_names[];
/* Specify how much debugging info to generate. */
extern enum debug_info_level debug_info_level;
-extern bool should_emit_struct_debug (tree type_decl, enum debug_info_usage);
-extern void set_struct_debug_option (const char *value);
+extern int base_of_path (const char *path, const char **base_out);
+extern void set_struct_debug_option (struct gcc_options *opts,
+ const char *value);
/* Nonzero means use GNU-only extensions in the generated symbolic
debugging information. */
diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk
index fbe8007..97bbd43 100644
--- a/gcc/optc-gen.awk
+++ b/gcc/optc-gen.awk
@@ -91,6 +91,7 @@ for (i = 0; i < n_extra_vars; i++) {
sub(".*= *", "", init)
sub(" *=.*", "", var)
sub("^.*[ *]", "", var)
+ sub("\\[.*\\]$", "", var)
} else {
init = "0"
}
diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk
index 677225e..4588a53 100644
--- a/gcc/opth-gen.awk
+++ b/gcc/opth-gen.awk
@@ -86,13 +86,17 @@ for (i = 0; i < n_extra_vars; i++) {
orig_var = var
name = var
type = var
+ type_after = var
sub("^.*[ *]", "", name)
+ sub("\\[.*\\]$", "", name)
+ sub("\\[.*\\]$", "", type)
sub(" *" name "$", "", type)
+ sub("^.*" name, "", type_after)
var_seen[name] = 1
print "#ifdef GENERATOR_FILE"
print "extern " orig_var ";"
print "#else"
- print " " type " x_" name ";"
+ print " " type " x_" name type_after ";"
print "#define " name " global_options.x_" name
print "#endif"
}
diff --git a/gcc/opts.c b/gcc/opts.c
index b2787ce..dc3278d 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. */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index c77db52..78e3afd 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -133,6 +133,12 @@ unsigned int save_decoded_options_count;
const char *main_input_filename;
+/* Pointer to base name in main_input_filename, with directories and a
+ single final extension removed, and the length of this base
+ name. */
+const char *main_input_basename;
+int main_input_baselength;
+
/* Used to enable -fvar-tracking, -fweb and -frename-registers according
to optimize in process_options (). */
#define AUTODETECT_VALUE 2
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 0f6c021..426c861 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -73,6 +73,8 @@ extern unsigned local_tick;
/* Top-level source file. */
extern const char *main_input_filename;
+extern const char *main_input_basename;
+extern int main_input_baselength;
extern const char *profile_data_prefix;
extern bool exit_after_options;