This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Question on gimplify.c:create_tmp_var


On Sun, Jun 06, 2004 at 04:53:39PM -0400, Richard Kenner wrote:
> So we have two operations x.f5 and (x.f5).f1.  In both the GCC and Ada
> trees, this is a component reference, with two operands: one a "name"
> and one a field declaration.  x.f5 has a type of r1 in the Ada tree.  So
> the GCC tree corresponding to that operation should have the type
> corresponding to that Ada type of r1.  Likewise (x.f5).f1 has an *input*
> type of r1 and the "f1" corresponds to the FIELD_DECL in r1.
> 
> The logical thing to do is to first do x.f5.  If that ended up being some
> subtype, we convert it to r1.  The the second operation has an input type
> of r1, so all is fine.  

This is essentially no different from C++, in which multiple
inheritence is modeled as nesting of records.  So

	struct A
	{
	  int x;
	  char y;
	};
	struct B : public A
	{
	  char z;
	};

could be represented as

	struct A
	{
	  int x;
	  char y;
	};
	struct B
	{
	  struct A base_a;
	  char z;
	};

Except that for various ABI reasons, base_a must not contain any
tail padding, such that B::z is at offset 6.  Which means that
the type of base_a in the representation is a different type node
from struct A.

It turns out that this solution works very very well.

> If we leave the result of x.f5 in its GCC type even if it isn't the Ada
> type, we have a problem with the outer operation.  For one thing, the
> reference to "f1" corresponds to a FIELD_DECL in r1, as I said.  So we'd have
> to search for the corresponding FIELD_DECL in the "real" GCC type.  Since
> we can be talking about types with hundreds of fields, that can be an
> expensive operation.

What a trivial 1-1 mapping problem.  I do believe that this is
known technology.

Indeed, since it seems as if FIELD_DECLS are globally unique,
you could use one map for all of the remapped fields in all of
the types of the entire program.  Which would eliminate a lot
of fixed per-datastructure overhead.

> As another case, consider:
> 
> 	type r1 is record f1: integer; f2: character; end record;
> 
> r1 is aligned to a 4-byte boundary, so its normal size is 64 bits.
> But it actually only needs 40 bits.  It's valid in Ada to then write
> 
> 	type r2 is record
> 	   f3: r1;
> 	   f4, f5, f6: character;
> 	end record;
> 	for r2 use record
> 	   f3 at 0 range 0..39;
> 	   f4 at 5 range 0..7;
> 	   f5 at 6 range 0..7;
> 	   f6 at 7 range 0..7;
>         end record;
> 
> So we're forcing F3 to be a smaller record.  We do this by making another
> type corresponding to r1 that's packed down and we make f3 a bitfield.
> 
> But now if we have an object of type r2, say, x, and we do x.f3.f1, again
> we have a situation where the GCC type of (x.f3) is does not correspond
> to the Ada type of that operation.  So all the above applies.

Again, I don't see this as a problem at all.  Very like the existing
situation in C++.


r~


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]