|
List Info
Thread: how to support C type qualifiers applied to arrays?
|
|
| how to support C type qualifiers applied
to arrays? |

|
2006-11-27 22:42:12 |
Consider the following:
[config: Fedora Core 5, x86_64, gdb 6.3 and GCC 4.1.]
% cat -n const_array.c
1 const volatile int array[5] = {1,2,3,4,5};
2 volatile int s;
3
4 int
5 main()
6 {
7 int i;
8 for (i = 0, s = 0; i < 5; ++i) s += array[i];
9 }
Above, what we'd like to see is that the qualifiers
"const" and "volatile" on references to
the array named
'array' are known to gdb.
Not so:
(gdb) ptype s
type = volatile int
(gdb) ptype array
type = int [5]
(gdb) ptype array[4]
type = int
The lack of c-v qualifiers on 'array' above, probably
doesn't
impact GDB or its users very much at the moment. However,
it does impact the development of GDB support for
an experimental dialect of "C" called UPC (see http://upc.gwu.edu),
which is something that I'm working on at the moment.
In UPC a new qualifier, "shared", is added to
indicate that a variable
is shared across all UPC threads. "shared" can be
applied to
scalars, arrays, structures and other "C" language
objects.
Thus, if 'array' above is to be shared, it would be
declared:
shared int array[5];
Accesses to UPC shared objects cannot generally be
implemented
as direct loads and stores. The UPC compiler also needs to
know that an array indexing operation is being performed
on a shared array, because UPC's indexing operation
propagates
over every thread (A[i+1] may index the data on the next
thread
in sequence from the thread with affinity to A[i], for
example).
GDB will need to know about the UPC "shared"
qualifier
as well so that GDB can properly access UPC shared objects.
Extending C-V qualifiers to include other qualifiers within
GDB isn't difficult. However, GDB's lack of support for C-V
qualifiers on array types is a major obstacle to properly
supporting
accesses to UPC shared arrays.
I'm wondering if anyone has looked at how GDB handles
qualifiers
on array types and array accesses, or if you can suggest how
that might best be supported?
-----
The discussion below adds detail, and explores a few
alternatives.
Running "objdump -W const_array", we can print out
the
DWARF information.
Here is the declaration of "array":
<1><c6>: Abbrev Number: 7 (DW_TAG_variable)
DW_AT_name : array
DW_AT_decl_file : 1
DW_AT_decl_line : 1
DW_AT_type : <de>
DW_AT_external : 1
DW_AT_location : 9 byte block: 3 60 8 50 0 0 0 0 0
(DW_OP_addr:
500860)
The type definition is at die offset <de>. Following
that reference, we see the chain of const and volatile:
<1><de>: Abbrev Number: 8 (DW_TAG_const_type)
DW_AT_type : <e3>
<1><e3>: Abbrev Number: 9
(DW_TAG_volatile_type)
DW_AT_type : <a1>
Where the underlying array type is given by <a1>:
<1><a1>: Abbrev Number: 5 (DW_TAG_array_type)
DW_AT_sibling : <b1>
DW_AT_type : <9a>
<1><9a>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : int
DW_AT_byte_size : 4
DW_AT_encoding : 5 (signed)
There are two ways of looking at the debugging info.
generated above:
1. The DWARF 2 info. accurately reflects the original
declaration.
2. The "const" and "volatile" attributes
should be
propagated to the element type. Thus above, we should
have seen the type of "array" (schematically) as:
(array_type (domain int 5)
(element_type
(const (volatile (base_type int)))))
-----
A few questions that arise:
Q: Is GCC generating an inaccurate DWARF 2 representation
to describe a qualified array type, or is GDB not
interpreting the DWARF 2 information correctly?
Q: Which representation (associating qualifiers with the
array or with the array's ultimate element type) most
accurately reflects "C" semantics?
Due to the large installed GCC installed base (as well as
that of
other compilers which generate DWARF 2 information in a
similar
fashion to GCC), we maximize interoperability
if we localize the representation issue to GDB, rather
than going back to GCC to generate a different
Dwarf 2 representation.
Taking a look at read_tag_const_type() in dwarf2read.c:
static void
read_tag_const_type (struct die_info *die, struct dwarf2_cu
*cu)
{
struct type *base_type;
if (die->type)
{
return;
}
base_type = die_type (die, cu);
set_die_type (die, make_cv_type (1, TYPE_VOLATILE
(base_type), base_type,
0),
cu);
}
We see that make_cv_type() is called to qualify 'base_type'
as "const".
Make_cv_type() does this by setting a flag bit in the
'instance_flags'
field of base_type. In our example above, 'base_type' is an
array type.
Thus, gdb applies the C-V qualifiers encoded in the DWARF 2
representation
to the containing array type, but does not propagate these
qualifiers to
the element type.
-----
In order to make GDB aware that an array type, or an indexed
array
element is qualified, two approaches come to mind:
1) Encode the fact that the array's elements are C-V
qualified
by propagating the C-V qualifiers down to the element type.
If we know that base_type above isn't otherwise aliased
(i.e.,
linked into some other type chain), we could try something
like the following:
base_type = die_type (die, cu);
if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
{
struct type *final_array_type = type;
struct type *final_elem_type TYPE_TARGET_TYPE
(final_array_type);
/* Propagate qualifiers down to the element type of an
array. */
while (TYPE_CODE (final_elem_type) == TYPE_CODE_ARRAY)
{
final_array_type = final_elem_type;
final_elem_type = TYPE_TARGET_TYPE
(final_array_type);
}
final_elem_type = make_cv_type (1, TYPE_VOLATILE
(final_elem_type),
final_elem_type, 0);
TYPE_TARGET_TYPE (final_array_type) = final_elem_type;
}
else
{
base_type = make_cv_type (1, TYPE_VOLATILE
(base_type), base_type, 0);
}
set_die_type (die, base_type, cu);
If make_cv_type() were generalized to accept various
qualifier flags, we
could place the logic that propagates the C-V qualifiers
into this
new implementation of make_cv_type(), thus simplifying the
callers like
read_tag_const_type() above, so that they are unaware of the
propagation.
2) Dynamically compute whether and array type or array
indexing
operation will result in a qualified type. This moves
the calculation shown above into GDB's expression evaluation
logic.
Performing the propagation of type qualifiers in the
expression
evaluator is further complicated by the fact that the
qualifier information will have to be propagated up and down
the tree.
For example:
typedef const int c5_t[5];
typedef volatile c5_t v10_c5_t[10];
v10_c5_t A[20];
if we ask:
) ptype A[10]
we'd probably expect to see:
volatile const int [10][5]
which traverses down the tree, to the element type in order
to
calculate the final type of the array elements. Thus, we
might
view the "const" and "volatile"
qualifiers as being propagated
up the tree to any referencing type or value expression.
Similarly,
) ptype A[10][9]
should yield
volatile const int [5]
which propagates the volatile attribute of A[10][9] down the
expression
tree and combines it with the const qualifier of the c5_t
type.
-----
I haven't looked at GDB's expression evaluator to determine
if the dynamic
calculation of the qualifiers is feasible or not. The
dynamic calculation
method has the advantage that it leaves the symbol readers
alone and can
also properly handle cross object file references (which are
handled via
symbolic tag references).
I'd appreciate hearing any comments/ideas that you have on
this
topic, including whether I've properly characterized the
problem
and the proposed solutions.
|
|
| how to support C type qualifiers applied
to arrays? |

|
2006-11-27 23:09:48 |
On Mon, Nov 27, 2006 at 02:42:12PM -0800, Gary Funck wrote:
> Q: Is GCC generating an inaccurate DWARF 2
representation
> to describe a qualified array type, or is GDB not
> interpreting the DWARF 2 information correctly?
I will defer to experts on this but I believe GCC is
incorrect.
In C there is no such thing as a "qualified array
type". The array has
an element type (which can be c-v qualified) and a bound,
and no
qualifiers of its own. But you can say "int x[const
1]". You can't
define variables of this type, but you can use them in
function
declarations. I believe it means roughly "int *const
x" within the
function; normally you can write:
int f(int x[1])
{
x[0] = 1;
x++;
return 0;
}
But this is invalid:
int f(int x[const 1])
{
x[0] = 1;
x++;
return 0;
}
So, by stuffing qualifiers on the outside, we lose the
ability to
present that. But GCC emits debug info for those as int
f(int *)
and int f(int * const) respectively, so it's irrelevant in
practice.
We can assume the qualifiers belonged to the element type in
GDB.
> We see that make_cv_type() is called to qualify
'base_type' as "const".
> Make_cv_type() does this by setting a flag bit in the
'instance_flags'
> field of base_type. In our example above, 'base_type'
is an array type.
My first recommendation would be to have make_cv_type create
a new
array type, with the qualified element type. However, doing
this
without being excessively wasteful might require care - you
couldn't
reuse main_type since the qualified array could not share
main_type.
But the waste is acceptably small.
The alternative would be to have a function called to get
the base type
of an array which did appropriate qualification at that
point. The
easiest way to do it might be to make TYPE_TARGET_TYPE into
an
appropriate function. Better than auditing the 465 or so
calls.
The first is probably better. It should be done in
gdbtypes.c, not
in the DWARF reader specifically.
I see that these are roughly the same two possibilities you
offered
I would do it at a different level than expression
evaluation, though,
as you can see above, if I took the second option.
--
Daniel Jacobowitz
CodeSourcery
|
|
| how to support C type qualifiers applied
to arrays? |

|
2006-11-27 23:31:12 |
Daniel Jacobowitz <drow false.org> writes:
> On Mon, Nov 27, 2006 at 02:42:12PM -0800, Gary Funck
wrote:
>> Q: Is GCC generating an inaccurate DWARF 2
representation
>> to describe a qualified array type, or is GDB not
>> interpreting the DWARF 2 information correctly?
>
> I will defer to experts on this but I believe GCC is
incorrect.
I think GCC is wrong, too. The DWARF is unambiguous, and
it's
attaching the qualifiers to the wrong part of the type tree,
just as
Daniel says.
> My first recommendation would be to have make_cv_type
create a new
> array type, with the qualified element type. However,
doing this
> without being excessively wasteful might require care -
you couldn't
> reuse main_type since the qualified array could not
share main_type.
> But the waste is acceptably small.
If this were a less obscure feature, then I could see GDB
deliberately
misreading the DWARF to accomodate GCC. But in this case,
it doesn't
seem like a show-stopper; wouldn't it be better to just
report the GCC
bug and let GDB continue to interpret DWARF as written?
These kludges
come back to haunt us. I gather Gary is working with a
modified GCC
anyway, so it shouldn't be hard for him to fix his compiler.
(If
that's not so, Gary, please set me straight.)
|
|
| how to support C type qualifiers applied
to arrays? |

|
2006-11-27 23:44:58 |
On Mon, 27 Nov 2006, Daniel Jacobowitz wrote:
> On Mon, Nov 27, 2006 at 02:42:12PM -0800, Gary Funck
wrote:
> > Q: Is GCC generating an inaccurate DWARF 2
representation
> > to describe a qualified array type, or is GDB not
> > interpreting the DWARF 2 information correctly?
>
> I will defer to experts on this but I believe GCC is
incorrect.
Specifically, GCC bug 8354 (all the patch links in that bug
are broken:
GCC bug 20588: so refer to the mbox archives, but there
isn't anything
much worthwhile in the patch referenced) deals with the
DWARF 2
information for arrays and type qualifiers.
--
Joseph S. Myers
joseph codesourcery.com
|
|
| how to support C type qualifiers applied
to arrays? |

|
2006-11-27 23:52:48 |
On Mon, Nov 27, 2006 at 03:31:12PM -0800, Jim Blandy wrote:
> If this were a less obscure feature, then I could see
GDB deliberately
> misreading the DWARF to accomodate GCC. But in this
case, it doesn't
> seem like a show-stopper; wouldn't it be better to just
report the GCC
> bug and let GDB continue to interpret DWARF as written?
These kludges
> come back to haunt us. I gather Gary is working with a
modified GCC
> anyway, so it shouldn't be hard for him to fix his
compiler. (If
> that's not so, Gary, please set me straight.)
I've no particular preference. Thanks for the PR reference,
Joseph.
--
Daniel Jacobowitz
CodeSourcery
|
|
| how to support C type qualifiers applied
to arrays? |

|
2006-11-27 23:55:21 |
On Mon, Nov 27, 2006 at 11:44:58PM +0000, Joseph S. Myers
wrote:
> Specifically, GCC bug 8354 (all the patch links in that
bug are broken:
> GCC bug 20588: so refer to the mbox archives, but there
isn't anything
> much worthwhile in the patch referenced) deals with the
DWARF 2
> information for arrays and type qualifiers.
Thanks. Having dug through the archives, Jim's message
suggests that
it should be just a matter of a couple hours for someone
interested to
fix GCC.
--
Daniel Jacobowitz
CodeSourcery
|
|
| how to support C type qualifiers applied
to arrays? |

|
2006-12-14 20:22:11 |
> -----Original Message-----
> From: Daniel Jacobowitz
> Sent: Monday, November 27, 2006 3:55 PM
>
> Thanks. Having dug through the archives, Jim's message
suggests that
> it should be just a matter of a couple hours for
someone interested to
> fix GCC.
The referenced PR is here:
http
://gcc.gnu.org/bugzilla/show_bug.cgi?id=8354
Jim's reply is here,
h
ttp://gcc.gnu.org/bugzilla/attachment.cgi?id=12702
After spending a few days on this, I can pretty safely say
that it doesn't appear to me that fixing this in GCC is
straightforward.
The main difficulty is that GCC doesn't create new qualified
types for declarations. Rather, it sets TREE_READONLY()
and TREE_THIS_VOLATILE() in the DECL node for declarations
such as:
volatile int A[10];
Structures add an additional wrinkle:
struct s_struct
{
int a;
float b;
char c[10];
};
volatile struct s_struct S;
Here, GCC sets TREE_THIS_VOLATILE in the DECL node of S,
but does not attempt to clone the type description of
s_struct, and to populate the volatile qualifier across all
contained member types. This works for GCC because it
propagates the qualifiers as it evaluates expressions.
Thus when evaluating S.c[10], GCC starts with the knowledge
that S is volatile, thus S.c is volatile, and S.c[1] is
volatile.
For GCC to fix the problem, it need to rewrite the type
definition for the type of S, along these lines:
typedef volatile int v_int;
typedef volatile float v_float;
typedef volatile char v_char;
struct v_s_struct
{
v_int a;
v_float b;
v_char c[10];
};
typedef volatile struct v_s_struct v_s_t;
v_s_t S;
Typedefs above are used to illustrate that
"volatile" must
be factored to the lowest level types of the components,
and must also appear at the struct level to accommodate
operations on the entire structure.
When things are done this way, GDB gets understands
that everything related to S is volatile:
(gdb) ptype S
type = volatile struct v_s_struct {
volatile int a;
volatile float b;
char c[10];
}
well, almost. GDB didn't track the fact that the
struct member "c" is also volatile, because GCC
failed
to encode the element type of the array as being
volatile:
<2><70>: Abbrev Number: 6 (DW_TAG_member)
DW_AT_name : c
DW_AT_decl_file : 1
DW_AT_decl_line : 8
DW_AT_type : <94>
DW_AT_data_member_location: 2 byte block: 23 8
(DW_OP_plus_uconst:
8)
<1><94>: Abbrev Number: 2
(DW_TAG_volatile_type)
DW_AT_type : <7d>
<1><7d>: Abbrev Number: 7 (DW_TAG_array_type)
DW_AT_sibling : <8d>
DW_AT_type : <45>
<1><45>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : (indirect string, offset: 0x3f):
char
DW_AT_byte_size : 1
DW_AT_encoding : 6 (signed char)
If GDB tracked the type qualifiers applied during
expression evaluation in a fashion similar to GCC, there
would be no issue.
This lack of ability to properly track qualifiers when
evaluating expressions isn't much of an issue for regular
"C",
though it might confuse users of GDB who do things like
ptype S.a
and expect GDB to come back with "volatile int"
(in the
first version of the example which did not use typedefs).
To implement debugging of "UPC" programs it
is important to be able to track the "shared"
qualifier,
because accesses to shared variables generally requires
callng a runtime procedure in the program being debugged,
or knowledge of the methods for accessing shared variables.
The bottom line is that the fix in GCC appears to be more
difficult than it first appears, and probably the best
approach is for GDB to properly track type qualifiers
as it evaluates expressions.
I'd appreciate hearing from developers more knowledgeable
in the internals of GCC and GDB, to confirm/deny my
observations
above, and to perhaps suggest better approaches.
|
|
| how to support C type qualifiers applied
to arrays? |

|
2006-12-15 22:37:18 |
"Gary Funck" <gary intrepid.com> writes:
> The main difficulty is that GCC doesn't create new
qualified
> types for declarations. Rather, it sets
TREE_READONLY()
> and TREE_THIS_VOLATILE() in the DECL node for
declarations
> such as:
>
> volatile int A[10];
Ugh. That's a shame. Can't dwarf2out.c fix things up as it
builds
the tree of struct die_structs from the GCC 'tree' type
tree?
> Structures add an additional wrinkle:
>
> struct s_struct
> {
> int a;
> float b;
> char c[10];
> };
> volatile struct s_struct S;
>
> Here, GCC sets TREE_THIS_VOLATILE in the DECL node of
S,
> but does not attempt to clone the type description of
> s_struct, and to populate the volatile qualifier across
all
> contained member types. This works for GCC because it
> propagates the qualifiers as it evaluates expressions.
> Thus when evaluating S.c[10], GCC starts with the
knowledge
> that S is volatile, thus S.c is volatile, and S.c[1] is
> volatile.
Okay --- this is a different problem altogether. This one
is indeed
GDB's fault: referring to a field of a volatile- or
const-qualified
structure should get you a member with the same qualifiers.
ISO/IEC
9899:1999 (E), 6.5.2.3 paragraph 3 says:
A postfix expression followed by the . operator and an
identifier
designates a member of a structure or union object. The
value is
that of the named member, and is an lvalue if the first
expression
is an lvalue. If the first expression has qualified
type, the
result has the so-qualified version of the type of the
designated
member.
GDB doesn't implement the behavior described in that that
last
sentence.
GCC, however, is producing the right DWARF for this (in
Fedora Core
5, at least):
$ cat volatile-struct.c
struct s_struct
{
int a;
float b;
char c[10];
};
volatile struct s_struct S;
$ gcc -c -g volatile-struct.c
$ readelf -wi volatile-struct.o
The section .debug_info contains:
Compilation Unit offset 0x0:
Length: 226
Version: 2
Abbrev Offset: 0
Pointer Size: 4
<0><b>: Abbrev Number: 1
(DW_TAG_compile_unit)
DW_AT_stmt_list : 0
DW_AT_high_pc : 0
DW_AT_low_pc : 0
DW_AT_producer : GNU C 4.1.1 20060525 (Red Hat
4.1.1-1)
DW_AT_language : 1 (ANSI C)
DW_AT_name : volatile-struct.c
DW_AT_comp_dir : /home/jimb/play
<1><62>: Abbrev Number: 2
(DW_TAG_structure_type)
DW_AT_sibling : <98>
DW_AT_name : s_struct
DW_AT_byte_size : 20
DW_AT_decl_file : 1
DW_AT_decl_line : 2
<2><73>: Abbrev Number: 3 (DW_TAG_member)
DW_AT_name : a
DW_AT_decl_file : 1
DW_AT_decl_line : 3
DW_AT_type : <98>
DW_AT_data_member_location: 2 byte block: 23 0
(DW_OP_plus_uconst: 0)
<2><7f>: Abbrev Number: 3 (DW_TAG_member)
DW_AT_name : b
DW_AT_decl_file : 1
DW_AT_decl_line : 4
DW_AT_type : <9f>
DW_AT_data_member_location: 2 byte block: 23 4
(DW_OP_plus_uconst: 4)
<2><8b>: Abbrev Number: 3 (DW_TAG_member)
DW_AT_name : c
DW_AT_decl_file : 1
DW_AT_decl_line : 5
DW_AT_type : <a8>
DW_AT_data_member_location: 2 byte block: 23 8
(DW_OP_plus_uconst: 8)
<1><98>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : int
DW_AT_byte_size : 4
DW_AT_encoding : 5 (signed)
<1><9f>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : float
DW_AT_byte_size : 4
DW_AT_encoding : 4 (float)
<1><a8>: Abbrev Number: 5 (DW_TAG_array_type)
DW_AT_sibling : <b8>
DW_AT_type : <c8>
<2><b1>: Abbrev Number: 6
(DW_TAG_subrange_type)
DW_AT_type : <b8>
DW_AT_upper_bound : 9
<1><b8>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : unsigned int
DW_AT_byte_size : 4
DW_AT_encoding : 7 (unsigned)
<1><c8>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : char
DW_AT_byte_size : 1
DW_AT_encoding : 6 (signed char)
<1><d0>: Abbrev Number: 7 (DW_TAG_variable)
DW_AT_name : S
DW_AT_decl_file : 1
DW_AT_decl_line : 7
DW_AT_type : <e0>
DW_AT_external : 1
DW_AT_location : 5 byte block: 3 0 0 0 0
(DW_OP_addr: 0)
<1><e0>: Abbrev Number: 8
(DW_TAG_volatile_type)
DW_AT_type : <62>
$
Note that we've got (making up some notation, but I think
it's clear
enough):
variable "S" {
type: &volatile_type {
type: &structure_type "s_struct" {
... }
}
}
Which is exactly what it should be: a volatile qualifier
applied to a
structure type. The DWARF info should not contain a
separate instance
of s_struct with volatile qualifiers propagated down to all
its
members; that's GDB's job.
But as we've agreed before, the debug info for the array
case you
originally posted is wrong:
$ cat volatile-array.c
volatile int A[10];
$ gcc -g -c volatile-array.c
$ readelf -wi volatile-array.o
The section .debug_info contains:
Compilation Unit offset 0x0:
Length: 154
Version: 2
Abbrev Offset: 0
Pointer Size: 4
<0><b>: Abbrev Number: 1
(DW_TAG_compile_unit)
DW_AT_stmt_list : 0
DW_AT_high_pc : 0
DW_AT_low_pc : 0
DW_AT_producer : GNU C 4.1.1 20060525 (Red Hat
4.1.1-1)
DW_AT_language : 1 (ANSI C)
DW_AT_name : volatile-array.c
DW_AT_comp_dir : /home/jimb/play
<1><61>: Abbrev Number: 2 (DW_TAG_array_type)
DW_AT_sibling : <71>
DW_AT_type : <81>
<2><6a>: Abbrev Number: 3
(DW_TAG_subrange_type)
DW_AT_type : <71>
DW_AT_upper_bound : 9
<1><71>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : unsigned int
DW_AT_byte_size : 4
DW_AT_encoding : 7 (unsigned)
<1><81>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : int
DW_AT_byte_size : 4
DW_AT_encoding : 5 (signed)
<1><88>: Abbrev Number: 5 (DW_TAG_variable)
DW_AT_name : A
DW_AT_decl_file : 1
DW_AT_decl_line : 1
DW_AT_type : <98>
DW_AT_external : 1
DW_AT_location : 5 byte block: 3 0 0 0 0
(DW_OP_addr: 0)
<1><98>: Abbrev Number: 6
(DW_TAG_volatile_type)
DW_AT_type : <61>
$
The DWARF type should reflect 'volatile' applied to the
element type,
as it's written in the C code:
variable "A" {
type: &array_type {
type: &volatile_type {
type: &base_type "int" { ... }
}
}
}
whereas the DWARF above is:
variable "A" {
type: &volatile_type {
type: &array_type {
type: base_type "int" { ... }
}
}
}
> For GCC to fix the problem, it need to rewrite the type
> definition for the type of S, along these lines:
>
> typedef volatile int v_int;
> typedef volatile float v_float;
> typedef volatile char v_char;
> struct v_s_struct
> {
> v_int a;
> v_float b;
> v_char c[10];
> };
> typedef volatile struct v_s_struct v_s_t;
> v_s_t S;
>
> Typedefs above are used to illustrate that
"volatile" must
> be factored to the lowest level types of the
components,
> and must also appear at the struct level to accommodate
> operations on the entire structure.
Just to be clear: GCC should *not* perform the
transformation you're
suggesting here and record the result in the DWARF info.
GDB should
propagate the qualifiers itself.
|
|
| how to support C type qualifiers applied
to arrays? |

|
2006-12-19 19:08:47 |
Jim Blandy wrote:
>
> "Gary Funck" <gary intrepid.com> writes:
> > The main difficulty is that GCC doesn't create new
qualified
> > types for declarations. Rather, it sets
TREE_READONLY()
> > and TREE_THIS_VOLATILE() in the DECL node for
declarations
> > such as:
> >
> > volatile int A[10];
>
> Ugh. That's a shame. Can't dwarf2out.c fix things up
as it builds
> the tree of struct die_structs from the GCC 'tree' type
tree?
In theory, it should be possible. I worked on this a bit,
but I think
to do it right, this fix will require contribution/direction
from someone
more conversant in the GCC front-end, and more knowledgeable
about how
the other language front-ends use both the DWARF 2
generation
routines, and the extent to which they depend upon the type
information
remaining in its current form.
Three approaches to fixing the front end to create
appropriate DWARF 2 information come to mind:
(1) Change the GCC front-end, so that when it creates
type information and associates the type information
with a declaration that it fully qualifies the type
definition,
in a way that preserves language semantics, yet also ensures
that the correct DWARF 2 information is generated for
qualified
types.
(2) Create the fully qualified type definition in
dwarf2out.c
(probably in routines that handle DECL items such as
gen_formal_parameter_die(), gen_variable_die() and
gen_field_die()).
There are two likely sub-approaches: (i) keep this fully
qualified type definition on the side, parallel to the
existing
type definition structure, or (ii) smash the new fully
qualified
type into the DECL node's TREE_TYPE() value. Keeping a
parallel definition may be difficult because various parts
of dwarfout.c may need to refer back to the DECL node's type
value, and all places that do this will have to be found and
fixed.
Cross-type references and typedef's create another set of
problems.
Rewriting the declaration's type value is the most
straightforward,
but runs the risk of violating various assumptions made by
the
language front-ends, and will require a rather elaborate
"deep copy"
mechanism to make sure the fix up is done correctly.
(3) Run a final pass over the internal DWARF tree built
within
dwarfout.c to fix up the type qualifiers, basically
propagating
the const_ and volatile_ qualifiers down to lower levels as
required. This is probably doable, but will slow down DWARF
generation for all compilations, even if most compilations
seldom use "const" and "volatile" (and
other qualifiers, such
as UPC's "shared", "strict", and
"relaxed"). In this case, it
seems that dwarf2out.c is fixing representation
issues that more correctly should be solved in the
front-end.
Given the tradeoffs, choice (1) above, where the type
description
is fully qualified at the time the type is bound to the DECL
item,
seems more correct, but may impact the correct operation of
the various language front-ends and therefore will require
more
care and more study. Choice (2) is perhaps a bad
compromise,
and choice (3) is likely workable, but kludgy.
|
|
| how to support C type qualifiers applied
to arrays? |

|
2006-12-20 02:40:15 |
> From: Jim Blandy
> Sent: Friday, December 15, 2006 2:37 PM
>
> "Gary Funck" <gary intrepid.com> writes:
> > Here, GCC sets TREE_THIS_VOLATILE in the DECL node
of S,
> > but does not attempt to clone the type description
of
> > s_struct, and to populate the volatile qualifier
across all
> > contained member types. This works for GCC
because it
> > propagates the qualifiers as it evaluates
expressions.
> > Thus when evaluating S.c[10], GCC starts with the
knowledge
> > that S is volatile, thus S.c is volatile, and
S.c[1] is
> > volatile.
>
> Okay --- this is a different problem altogether. This
one is indeed
> GDB's fault: referring to a field of a volatile- or
const-qualified
> structure should get you a member with the same
qualifiers.
> [...]
> > Typedefs above are used to illustrate that
"volatile" must
> > be factored to the lowest level types of the
components,
> > and must also appear at the struct level to
accommodate
> > operations on the entire structure.
>
> Just to be clear: GCC should *not* perform the
transformation you're
> suggesting here and record the result in the DWARF
info. GDB should
> propagate the qualifiers itself.
This leads to the next question: how difficult will it be to
teach GDB to properly track type qualifiers when evaluating
expressions? Which files/functions will likely need to be
changed? Are there mechanisms within GDB already that track
various value attributes along with the expression values
themselves?
|
|
[1-10]
|
|