public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* Re: software archaeology: fixing method calls
@ 2001-04-24 13:38 Michael Elizabeth Chastain
  0 siblings, 0 replies; 2+ messages in thread
From: Michael Elizabeth Chastain @ 2001-04-24 13:38 UTC (permalink / raw)
  To: gdb, jimb

Jim Blandy writes:

> - For TYPE_CODE_FUNC, the types of the arguments are stored in
>   `fields', just as if they were members of a structure. This lets us
>   store the names of the arguments.
> 
> - However, for TYPE_CODE_METHOD, the types of the arguments are stored
>   in `type_specific.arg_types'.
> 
> Why is this?

I don't know why, but I saw this too -- this was my first CR a long
time ago.  I traced it back to Michael Tiemann's original design.
It may come from a time before ordinary C functions had parameters.

> However, this means that invoking functions that expect reference
> arguments is impossible if you don't know the types of the arguments:
> you can't tell whether to pass boo's value (1), or boo's address
> (&boo).

Hmmm, if a function expects a reference argument, then it's written
in a language like C++ or Java where all functions are prototyped.
I guess the user would still lose if they compiled that source file
with no debugging information.

> - We could change the definition of TYPE_CODE_METHOD to put the
>   arguments in the same place TYPE_CODE_FUNCTION does.

I prefer this too.

Michael

^ permalink raw reply	[flat|nested] 2+ messages in thread

* software archaeology: fixing method calls
@ 2001-04-24 12:02 Jim Blandy
  0 siblings, 0 replies; 2+ messages in thread
From: Jim Blandy @ 2001-04-24 12:02 UTC (permalink / raw)
  To: gdb

This is kind of interesting.  

Here are some excerpts from gdbtypes.h:

enum type_code
  {
    ...
    TYPE_CODE_FUNC,		/* Function type */
    ...
    TYPE_CODE_METHOD,		/* Method type */
    ...
  };
...

struct type
  {
    /* Code for kind of type */
    enum type_code code;
    ...

    /* Number of fields described for this type */
    short nfields;

    /* For structure and union types, a description of each field.
        ...
       For a function type, a "field" for each parameter type.
        ...
     */
    struct field
      {
        ...
      }
     *fields;

    /* Slot to point to additional language-specific fields of this type.  */
    union type_specific
      {
	/* ARG_TYPES is for TYPE_CODE_METHOD.
	   Contains the type of each argument, ending with a void type
	   after the last argument for normal member functions or a NULL
	   pointer after the last argument for functions with variable
	   arguments.  */

	struct type **arg_types;
        ...
      }
    type_specific;
  };


Now, this is a bit odd:

- For TYPE_CODE_FUNC, the types of the arguments are stored in
  `fields', just as if they were members of a structure. This lets us
  store the names of the arguments.

- However, for TYPE_CODE_METHOD, the types of the arguments are stored
  in `type_specific.arg_types'.

Why is this?

Back in 1992, TYPE_CODE_FUNC used `type_specific.arg_types' as well.
In 1995, they migrated to fields, for reasons I don't yet understand.
TYPE_CODE_METHOD was left as is.

The test suite detects some problems this causes when we try to invoke
methods that take arguments by reference:

FAIL: gdb.c++/classes.exp: base class (&param)->a
FAIL: gdb.c++/classes.exp: base class (&param)->x
FAIL: gdb.c++/classes.exp: inherited class (&param)->a
FAIL: gdb.c++/classes.exp: inherited class (&param)->x

To remind folks how C++ reference arguments work: you declare your
function or member function like this:

    foo (int &x)  /* foo takes an integer variable by reference */
    {
      x++;
    }

and then you call it like this:

    {
      int boo = 1;

      foo (boo);

      /* Now boo is 2.  */
    }

Underneath the hood, C++ passes boo's address to foo, and foo
automatically dereferences that pointer for any operations on x.

However, this means that invoking functions that expect reference
arguments is impossible if you don't know the types of the arguments:
you can't tell whether to pass boo's value (1), or boo's address
(&boo).

In valops.c, hand_function_call does have the necessary logic to deal
with this correctly: if the formal parameter's type is a reference, it
takes the address of the actual parameter.  Unfortunately, if we're
invoking a method, the argument types are in a different place, and
hand_function_call doesn't check for them there.

There are two alternatives:

- We could change hand_function_call to find method argument types
  where they live now.

- We could change the definition of TYPE_CODE_METHOD to put the
  arguments in the same place TYPE_CODE_FUNCTION does.

I prefer the latter, since it gives similar types similar
representations.

Comments?

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2001-04-24 13:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-04-24 13:38 software archaeology: fixing method calls Michael Elizabeth Chastain
  -- strict thread matches above, loose matches on Subject: below --
2001-04-24 12:02 Jim Blandy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).