common.opt (debug_struct_ordinary, [...]): New Variable entries.
* 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. c-family: * c-opts.c (c_common_handle_option): Update calls to set_struct_debug_option. From-SVN: r166944
This commit is contained in:
parent
6a1f6c9c86
commit
69ccdddbb8
@ -1,3 +1,26 @@
|
||||
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,
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -91,6 +91,7 @@ for (i = 0; i < n_extra_vars; i++) {
|
||||
sub(".*= *", "", init)
|
||||
sub(" *=.*", "", var)
|
||||
sub("^.*[ *]", "", var)
|
||||
sub("\\[.*\\]$", "", var)
|
||||
} else {
|
||||
init = "0"
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
|
164
gcc/opts.c
164
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. */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user