gcc: add femit-struct-debug support to reduce Reduce dwarf debug size

Obtained from:	gcc 4.3 (rev. 123909; GPLv2)
MFC after:	3 weeks
This commit is contained in:
Pedro F. Giffuni 2013-11-16 01:16:24 +00:00
parent 966b6fbbae
commit 71fd392a23
12 changed files with 474 additions and 10 deletions

View File

@ -27,6 +27,57 @@
alignment for amdfam10 architecture. Increasing the max loop
alignment to 24 bytes.
2007-04-16 Lawrence Crowl <crowl@google.com>
* doc/invoke.texi (Debugging Options): Add documentation for the
-femit-struct-debug options -femit-struct-debug-baseonly,
-femit-struct-debug-reduced, and
-femit-struct-debug-detailed[=...].
* c-opts.c (c_common_handle_option): Add
OPT_femit_struct_debug_baseonly, OPT_femit_struct_debug_reduced,
and OPT_femit_struct_debug_detailed_.
* c.opt: Add specifications for
-femit-struct-debug-baseonly, -femit-struct-debug-reduced,
and -femit-struct-debug-detailed[=...].
* opts.c (set_struct_debug_option): Parse the
-femit-struct-debug-... options.
* opts.c (matches_main_base, main_input_basename,
main_input_baselength, base_of_path, matches_main_base): Add
variables and functions to compare header base name to compilation
unit base name.
* opts.c (should_emit_struct_debug): Add to determine to emit a
structure based on the option.
(dump_struct_debug) Also disabled function to debug this
function.
* opts.c (handle_options): Save the base name of the
compilation unit.
* langhooks-def.h (LANG_HOOKS_GENERIC_TYPE_P): Define.
(LANG_HOOKS_FOR_TYPES_INITIALIZER): Add.
This hook indicates if a type is generic. Set it by default
to "never generic".
* langhooks.h (struct lang_hooks_for_types): Add a new hook
to determine if a struct type is generic or not.
* cp/cp-tree.h (class_tmpl_impl_spec_p): Declare a C++ hook.
* cp/tree.c (class_tmpl_impl_spec_p): Implement the C++ hook.
* cp/cp-lang.c (LANG_HOOKS_GENERIC_TYPE_P): Override null C hook
with live C++ hook.
* flags.h (enum debug_info_usage): Add an enumeration to describe
a program's use of a structure type.
* dwarf2out.c (gen_struct_or_union_type_die): Add a new parameter
to indicate the program's usage of the type. Filter structs based
on the -femit-struct-debug-... specification.
(gen_type_die): Split into two routines, gen_type_die and
gen_type_die_with_usage. gen_type_die is now a wrapper
that assumes direct usage.
(gen_type_die_with_usage): Replace calls to gen_type_die
with gen_type_die_with_usage adding the program usage of
the referenced type.
(dwarf2out_imported_module_or_decl): Suppress struct debug
information using should_emit_struct_debug when appropriate.
2007-04-12 Richard Guenther <rguenther@suse.de> (r123736)
PR tree-optimization/24689

View File

@ -818,6 +818,18 @@ c_common_handle_option (size_t scode, const char *arg, int value)
flag_gen_declaration = 1;
break;
case OPT_femit_struct_debug_baseonly:
set_struct_debug_option ("base");
break;
case OPT_femit_struct_debug_reduced:
set_struct_debug_option ("dir:ord:sys,dir:gen:any,ind:base");
break;
case OPT_femit_struct_debug_detailed_:
set_struct_debug_option (arg);
break;
case OPT_idirafter:
add_path (xstrdup (arg), AFTER, 0, true);
break;

View File

@ -765,6 +765,18 @@ gen-decls
ObjC ObjC++
Dump declarations to a .decl file
femit-struct-debug-baseonly
C ObjC C++ ObjC++
-femit-struct-debug-baseonly Aggressive reduced debug info for structs
femit-struct-debug-reduced
C ObjC C++ ObjC++
-femit-struct-debug-reduced Conservative reduced debug info for structs
femit-struct-debug-detailed=
C ObjC C++ ObjC++ Joined
-femit-struct-debug-detailed=<spec-list> Detailed reduced debug info for structs
idirafter
C ObjC C++ ObjC++ Joined Separate
-idirafter <dir> Add <dir> to the end of the system include path

View File

@ -44,6 +44,8 @@ static void cp_init_ts (void);
#define LANG_HOOKS_NAME "GNU C++"
#undef LANG_HOOKS_INIT
#define LANG_HOOKS_INIT cxx_init
#undef LANG_HOOKS_GENERIC_TYPE_P
#define LANG_HOOKS_GENERIC_TYPE_P class_tmpl_impl_spec_p
#undef LANG_HOOKS_DECL_PRINTABLE_NAME
#define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name
#undef LANG_HOOKS_FOLD_OBJ_TYPE_REF

View File

@ -4373,6 +4373,7 @@ extern tree add_stmt_to_compound (tree, tree);
extern tree cxx_maybe_build_cleanup (tree);
extern void init_tree (void);
extern int pod_type_p (tree);
extern bool class_tmpl_impl_spec_p (tree);
extern int zero_init_p (tree);
extern tree canonical_type_variant (tree);
extern tree copy_binfo (tree, tree, tree,

View File

@ -1762,6 +1762,14 @@ pod_type_p (tree t)
return 1;
}
/* Nonzero iff type T is a class template implicit specialization. */
bool
class_tmpl_impl_spec_p (tree t)
{
return CLASS_TYPE_P (t) && CLASSTYPE_TEMPLATE_INSTANTIATION (t);
}
/* Returns 1 iff zero initialization of type T means actually storing
zeros in it. */

View File

@ -275,6 +275,8 @@ in the following sections.
-ftest-coverage -ftime-report -fvar-tracking @gol
-g -g@var{level} -gcoff -gdwarf-2 @gol
-ggdb -gstabs -gstabs+ -gvms -gxcoff -gxcoff+ @gol
-femit-struct-debug-baseonly -femit-struct-debug-reduced @gol
-femit-struct-debug-detailed@r{[}=@var{spec-list}@r{]} @gol
-p -pg -print-file-name=@var{library} -print-libgcc-file-name @gol
-print-multi-directory -print-multi-lib @gol
-print-prog-name=@var{program} -print-search-dirs -Q @gol
@ -3411,6 +3413,78 @@ Compress DWARF2 debugging information by eliminating duplicated
information about each symbol. This option only makes sense when
generating DWARF2 debugging information with @option{-gdwarf-2}.
@item -femit-struct-debug-baseonly
Emit debug information for struct-like types
only when the base name of the compilation source file
matches the base name of file in which the struct was defined.
This option substantially reduces the size of debugging information,
but at significant potential loss in type information to the debugger.
See @option{-femit-struct-debug-reduced} for a less aggressive option.
See @option{-femit-struct-debug-detailed} for more detailed control.
This option works only with DWARF 2.
@item -femit-struct-debug-reduced
Emit debug information for struct-like types
only when the base name of the compilation source file
matches the base name of file in which the type was defined,
unless the struct is a template or defined in a system header.
This option significantly reduces the size of debugging information,
with some potential loss in type information to the debugger.
See @option{-femit-struct-debug-baseonly} for a more aggressive option.
See @option{-femit-struct-debug-detailed} for more detailed control.
This option works only with DWARF 2.
@item -femit-struct-debug-detailed@r{[}=@var{spec-list}@r{]}
Specify the struct-like types
for which the compiler will generate debug information.
The intent is to reduce duplicate struct debug information
between different object files within the same program.
This option is a detailed version of
@option{-femit-struct-debug-reduced} and @option{-femit-struct-debug-baseonly},
which will serve for most needs.
A specification has the syntax
[@samp{dir:}|@samp{ind:}][@samp{ord:}|@samp{gen:}](@samp{any}|@samp{sys}|@samp{base}|@samp{none})
The optional first word limits the specification to
structs that are used directly (@samp{dir:}) or used indirectly (@samp{ind:}).
A struct type is used directly when it is the type of a variable, member.
Indirect uses arise through pointers to structs.
That is, when use of an incomplete struct would be legal, the use is indirect.
An example is
@samp{struct one direct; struct two * indirect;}.
The optional second word limits the specification to
ordinary structs (@samp{ord:}) or generic structs (@samp{gen:}).
Generic structs are a bit complicated to explain.
For C++, these are non-explicit specializations of template classes,
or non-template classes within the above.
Other programming languages have generics,
but @samp{-femit-struct-debug-detailed} does not yet implement them.
The third word specifies the source files for those
structs for which the compiler will emit debug information.
The values @samp{none} and @samp{any} have the normal meaning.
The value @samp{base} means that
the base of name of the file in which the type declaration appears
must match the base of the name of the main compilation file.
In practice, this means that
types declared in @file{foo.c} and @file{foo.h} will have debug information,
but types declared in other header will not.
The value @samp{sys} means those types satisfying @samp{base}
or declared in system or compiler headers.
You may need to experiment to determine the best settings for your application.
The default is @samp{-femit-struct-debug-detailed=all}.
This option works only with DWARF 2.
@cindex @command{prof}
@item -p
@opindex p

View File

@ -4215,7 +4215,8 @@ static void gen_ptr_to_mbr_type_die (tree, dw_die_ref);
static dw_die_ref gen_compile_unit_die (const char *);
static void gen_inheritance_die (tree, tree, dw_die_ref);
static void gen_member_die (tree, dw_die_ref);
static void gen_struct_or_union_type_die (tree, dw_die_ref);
static void gen_struct_or_union_type_die (tree, dw_die_ref,
enum debug_info_usage);
static void gen_subroutine_type_die (tree, dw_die_ref);
static void gen_typedef_die (tree, dw_die_ref);
static void gen_type_die (tree, dw_die_ref);
@ -12473,7 +12474,8 @@ gen_member_die (tree type, dw_die_ref context_die)
member DIEs needed by later specification DIEs. */
static void
gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
gen_struct_or_union_type_die (tree type, dw_die_ref context_die,
enum debug_info_usage usage)
{
dw_die_ref type_die = lookup_type_die (type);
dw_die_ref scope_die = 0;
@ -12482,6 +12484,7 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
&& (! TYPE_STUB_DECL (type)
|| ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))));
int ns_decl = (context_die && context_die->die_tag == DW_TAG_namespace);
complete = complete && should_emit_struct_debug (type, usage);
if (type_die && ! complete)
return;
@ -12609,7 +12612,8 @@ gen_typedef_die (tree decl, dw_die_ref context_die)
/* Generate a type description DIE. */
static void
gen_type_die (tree type, dw_die_ref context_die)
gen_type_die_with_usage (tree type, dw_die_ref context_die,
enum debug_info_usage usage)
{
int need_pop;
@ -12657,16 +12661,19 @@ gen_type_die (tree type, dw_die_ref context_die)
/* For these types, all that is required is that we output a DIE (or a
set of DIEs) to represent the "basis" type. */
gen_type_die (TREE_TYPE (type), context_die);
gen_type_die_with_usage (TREE_TYPE (type), context_die,
DINFO_USAGE_IND_USE);
break;
case OFFSET_TYPE:
/* This code is used for C++ pointer-to-data-member types.
Output a description of the relevant class type. */
gen_type_die (TYPE_OFFSET_BASETYPE (type), context_die);
gen_type_die_with_usage (TYPE_OFFSET_BASETYPE (type), context_die,
DINFO_USAGE_IND_USE);
/* Output a description of the type of the object pointed to. */
gen_type_die (TREE_TYPE (type), context_die);
gen_type_die_with_usage (TREE_TYPE (type), context_die,
DINFO_USAGE_IND_USE);
/* Now output a DIE to represent this pointer-to-data-member type
itself. */
@ -12675,13 +12682,15 @@ gen_type_die (tree type, dw_die_ref context_die)
case FUNCTION_TYPE:
/* Force out return type (in case it wasn't forced out already). */
gen_type_die (TREE_TYPE (type), context_die);
gen_type_die_with_usage (TREE_TYPE (type), context_die,
DINFO_USAGE_DIR_USE);
gen_subroutine_type_die (type, context_die);
break;
case METHOD_TYPE:
/* Force out return type (in case it wasn't forced out already). */
gen_type_die (TREE_TYPE (type), context_die);
gen_type_die_with_usage (TREE_TYPE (type), context_die,
DINFO_USAGE_DIR_USE);
gen_subroutine_type_die (type, context_die);
break;
@ -12707,7 +12716,7 @@ gen_type_die (tree type, dw_die_ref context_die)
&& AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
&& ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type)))
{
gen_type_die (TYPE_CONTEXT (type), context_die);
gen_type_die_with_usage (TYPE_CONTEXT (type), context_die, usage);
if (TREE_ASM_WRITTEN (type))
return;
@ -12731,7 +12740,7 @@ gen_type_die (tree type, dw_die_ref context_die)
gen_enumeration_type_die (type, context_die);
}
else
gen_struct_or_union_type_die (type, context_die);
gen_struct_or_union_type_die (type, context_die, usage);
if (need_pop)
pop_decl_scope ();
@ -12760,6 +12769,12 @@ gen_type_die (tree type, dw_die_ref context_die)
TREE_ASM_WRITTEN (type) = 1;
}
static void
gen_type_die (tree type, dw_die_ref context_die)
{
gen_type_die_with_usage (type, context_die, DINFO_USAGE_DIR_USE);
}
/* Generate a DIE for a tagged type instantiation. */
static void
@ -13357,7 +13372,11 @@ dwarf2out_imported_module_or_decl (tree decl, tree context)
if (!context)
scope_die = comp_unit_die;
else if (TYPE_P (context))
{
if (!should_emit_struct_debug (context, DINFO_USAGE_DIR_USE))
return;
scope_die = force_type_die (context);
}
else
scope_die = force_decl_die (context);
@ -13383,7 +13402,12 @@ dwarf2out_imported_module_or_decl (tree decl, tree context)
if (TYPE_CONTEXT (type))
if (TYPE_P (TYPE_CONTEXT (type)))
{
if (!should_emit_struct_debug (TYPE_CONTEXT (type),
DINFO_USAGE_DIR_USE))
return;
type_context_die = force_type_die (TYPE_CONTEXT (type));
}
else
type_context_die = force_decl_die (TYPE_CONTEXT (type));
else

View File

@ -23,6 +23,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#ifndef GCC_FLAGS_H
#define GCC_FLAGS_H
#include "coretypes.h"
#include "options.h"
enum debug_info_type
@ -54,6 +55,25 @@ enum debug_info_level
/* Specify how much debugging info to generate. */
extern enum debug_info_level debug_info_level;
/* 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 function determines whether or not debug information
should be generated for a given struct. The indirect parameter
indicates that the struct is being handled indirectly, via
a pointer. See opts.c for the implementation. */
enum debug_info_usage
{
DINFO_USAGE_DFN, /* A struct definition. */
DINFO_USAGE_DIR_USE, /* A direct use, such as the type of a variable. */
DINFO_USAGE_IND_USE, /* An indirect use, such as through a pointer. */
DINFO_USAGE_NUM_ENUMS /* The number of enumerators. */
};
extern bool should_emit_struct_debug (tree type_decl, enum debug_info_usage);
extern void set_struct_debug_option (const char *value);
/* Nonzero means use GNU-only extensions in the generated symbolic
debugging information. */
extern bool use_gnu_debug_info_extensions;

View File

@ -217,6 +217,7 @@ extern tree lhd_make_node (enum tree_code);
so we create a compile-time error instead. */
#define LANG_HOOKS_MAKE_TYPE lhd_make_node
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error
#define LANG_HOOKS_GENERIC_TYPE_P hook_bool_tree_false
#define LANG_HOOKS_TYPE_PROMOTES_TO lhd_type_promotes_to
#define LANG_HOOKS_REGISTER_BUILTIN_TYPE lhd_register_builtin_type
#define LANG_HOOKS_TYPE_MAX_SIZE lhd_return_null_tree
@ -231,6 +232,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_UNSIGNED_TYPE, \
LANG_HOOKS_SIGNED_TYPE, \
LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE, \
LANG_HOOKS_GENERIC_TYPE_P, \
LANG_HOOKS_TYPE_PROMOTES_TO, \
LANG_HOOKS_REGISTER_BUILTIN_TYPE, \
LANG_HOOKS_INCOMPLETE_TYPE_ERROR, \

View File

@ -119,6 +119,10 @@ struct lang_hooks_for_types
according to UNSIGNEDP. */
tree (*signed_or_unsigned_type) (int, tree);
/* True if the type is an instantiation of a generic type,
e.g. C++ template implicit specializations. */
bool (*generic_p) (tree);
/* Given a type, apply default promotions to unnamed function
arguments and return the new type. Return the same type if no
change. Required by any language that supports variadic

View File

@ -79,6 +79,256 @@ 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 thet 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 };
/* Parse the -femit-struct-debug-detailed option value
and set the flag variables. */
#define MATCH( prefix, string ) \
((strncmp (prefix, string, sizeof prefix - 1) == 0) \
? ((string += sizeof prefix - 1), 1) : 0)
void
set_struct_debug_option (const char *spec)
{
/* various labels for comparison */
static char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:";
static char ord_lbl[] = "ord:", gen_lbl[] = "gen:";
static char none_lbl[] = "none", any_lbl[] = "any";
static char base_lbl[] = "base", sys_lbl[] = "sys";
enum debug_struct_file files = DINFO_STRUCT_FILE_ANY;
/* Default is to apply to as much as possible. */
enum debug_info_usage usage = DINFO_USAGE_NUM_ENUMS;
int ord = 1, gen = 1;
/* What usage? */
if (MATCH (dfn_lbl, spec))
usage = DINFO_USAGE_DFN;
else if (MATCH (dir_lbl, spec))
usage = DINFO_USAGE_DIR_USE;
else if (MATCH (ind_lbl, spec))
usage = DINFO_USAGE_IND_USE;
/* Generics or not? */
if (MATCH (ord_lbl, spec))
gen = 0;
else if (MATCH (gen_lbl, spec))
ord = 0;
/* What allowable environment? */
if (MATCH (none_lbl, spec))
files = DINFO_STRUCT_FILE_NONE;
else if (MATCH (any_lbl, spec))
files = DINFO_STRUCT_FILE_ANY;
else if (MATCH (sys_lbl, spec))
files = DINFO_STRUCT_FILE_SYS;
else if (MATCH (base_lbl, spec))
files = DINFO_STRUCT_FILE_BASE;
else
error ("argument %qs to %<-femit-struct-debug-detailed%> not recognized",
spec);
/* Effect the specification. */
if (usage == DINFO_USAGE_NUM_ENUMS)
{
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;
}
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;
}
}
else
{
if (ord)
debug_struct_ordinary[usage] = files;
if (gen)
debug_struct_generic[usage] = files;
}
if (*spec == ',')
set_struct_debug_option (spec+1);
else
{
/* No more -femit-struct-debug-detailed specifications.
Do final checks. */
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])
error ("%<-femit-struct-debug-detailed=dir:...%> must allow at least"
" as much as %<-femit-struct-debug-detailed=ind:...%>");
}
}
/* Find the base name of a path, stripping off both directories and
a single final extension. */
static int
base_of_path (const char *path, const char **base_out)
{
const char *base = path;
const char *dot = 0;
const char *p = path;
char c = *p;
while (c)
{
if (IS_DIR_SEPARATOR(c))
{
base = p + 1;
dot = 0;
}
else if (c == '.')
dot = p;
c = *++p;
}
if (!dot)
dot = p;
*base_out = base;
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. */
@ -370,7 +620,11 @@ handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
if (opt[0] != '-' || opt[1] == '\0')
{
if (main_input_filename == NULL)
{
main_input_filename = opt;
main_input_baselength
= base_of_path (main_input_filename, &main_input_basename);
}
add_input_filename (opt);
n = 1;
continue;