mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
c09ebee0d3ae9148e33aa861cbd857bf2d4100ba
Consider the C construct:
typedef struct foo
{
int a;
int b;
} foo;
GDB will see two types here, 'struct foo' and the typedef 'foo'.
However, if we use 'info types foo' we will see this:
File test.c:
18: struct foo;
At least that's what I see with current HEAD of master. However, it
is really just luck that we see the 'struct' here. See more below.
When searching for symbols matching 'foo' GDB ends up in the function
global_symbol_searcher::add_matching_symbols, where we consider all
possible matching symbols. This will include the 'struct foo' and the
typedef 'foo'. However, before a new symbols is added to the results,
we attempt to remove duplicates with this code:
/* Match, insert if not already in the results. */
symbol_search ss (block, sym);
if (result_set->find (ss) == result_set->end ())
result_set->insert (ss);
If a symbol is already present in result_set then it will not be added
a second time.
The symbol_search equality check is done using the function
symbol_search::compare_search_syms, this function does a number of
checks, but at the end, any two symbols that are in the same block
within the same file, with the same name, are considered the same,
even if the types of those symbols are different.
This makes sense in most cases, it usually wouldn't make sense to have
two symbols within a single block with different types. But the
'struct foo' and typedef 'foo' case is a bit of a strange one. Within
DWARF and GDB we consider both of these as just types. But in C
types and structure names live in different namespaces, and so we can
have both in the same block. I don't think that GDB should consider
these two as the same, especially if we consider something really
ill-advised like this:
struct foo
{
int a;
int b;
};
typedef int foo;
This is perfectly valid C code, 'struct foo' and the typedef 'foo' are
in different namespaces, and can be used within the same block. But
please, never write C code like this.
Given the above, I think, when asked about 'foo', GDB should, report
both 'struct foo' and the typedef 'foo'.
To do this I propose extending symbol_search::compare_search_syms such
that if two symbol_search objects are in the same block, within the
same file, and they have the same name, then if just one of them is a
typedef, the two objects will not be considered equal. The results
will be sorted by line number if the line numbers are different, or,
if the line numbers are the same, the non-typedef will be sorted
first. This means that for something like this:
typedef struct foo { int a; } foo;
We'll get an 'info types foo' result like:
File test.c:
18: struct foo;
18: typedef struct foo foo;
I mentioned earlier that it is really just luck that we see 'struct
foo'. I ran into this problem while working on another patch. When
testing with the 'debug-types' board file I was seeing the typedef
being reported rather than the struct. In "normal" DWARF given the
'typedef struct foo { ...} foo;' construct, the compiler will usually
emit the struct definition first, and then the typedef definition. So
when GDB parses the DWARF it sees the struct first. It is the typedef
that becomes the duplicate which is not added to the results list.
But with the 'debug-types' board the compiler moves the struct
definition out to the .debug_types section. And GDB now parses the CU
containing the typedef first, and then expands the structure
definition from the separate section afterwards. As a result, it is
the structure that is now considered the duplicate, and the typedef is
the result that gets reported.
I think this is yet another motivation for this patch. Changes like
this (the use of .debug_types section) shouldn't impact what results
GDB shows to the user.
There is an interesting update to the gdb.base/info-types.exp.tcl test
script. In this case the C results only needed to change to include
the typedef. The C++ results already included both the struct and the
typedef in the expected results. The reason for this is that C places
both the struct baz_t and the typedef for baz_t into the global block,
while C++ places the struct in the global block, and the typedef into
the static block. I have no idea why there's a difference in the
placement, but I'm choosing to believe the difference is correct. But
this explains why only the C results needed to change. If anything
this (I think) is yet another justification for this change; having C
not show the typedef in this case seems weird when the same source
code compiled as C++ does show the typedef.
Approved-By: Tom Tromey <tom@tromey.com>
…
…
…
…
…
…
…
…
…
…
README for GNU development tools This directory contains various GNU compilers, assemblers, linkers, debuggers, etc., plus their support routines, definitions, and documentation. If you are receiving this as part of a GDB release, see the file gdb/README. If with a binutils release, see binutils/README, and so on. That'll give you info about this package -- supported targets, how to use it, how to report bugs, etc. It is now possible to automatically configure and build a variety of tools with one command. To build all of the tools contained herein, run the ``configure'' script here, e.g.: ./configure make To install them (by default in /usr/local/bin, /usr/local/lib, etc), then do: make install (If the configure script can't determine your type of computer, give it the name as an argument, for instance ``./configure sun4''. You can use the script ``config.sub'' to test whether a name is recognized; if it is, config.sub translates it to a triplet specifying CPU, vendor, and OS.) If you have more than one compiler on your system, it is often best to explicitly set CC in the environment before running configure, and to also set CC when running make. For example (assuming sh/bash/ksh): CC=gcc ./configure make A similar example using csh: setenv CC gcc ./configure make Much of the code and documentation enclosed is copyright by the Free Software Foundation, Inc. See the file COPYING or COPYING.LIB in the various directories, for a description of the GNU General Public License terms under which you can copy the files. REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info on where and how to report problems.
Description
Languages
C
50.5%
Makefile
22.7%
Assembly
13.2%
C++
5.9%
Roff
1.5%
Other
5.6%