Re: [drow-cplus-branch rfa] using directives support

Daniel Jacobowitz
2002-10-22T02:45:20Z

On Mon, Oct 21, 2002 at 05:10:08PM -0700, David Carlton wrote:
> Here's some code to add support in GDB for using directives; it uses
> this to look up names from within functions defined in namespaces and
> for anonymous namespaces. In the latter case, it uses DWARF 2 (DWARF
> 3, actually) debugging info if its there; if not, it tries to deduce
> it on its own.
>
> It contains the code in
> <http://sources.redhat.com/ml/gdb-patches/2002-10/msg00240.html>; I'm
> including that because some of the relevant bits have changed (a few
> bugs in the lookup_symbol stuff that I didn't find until multiple
> using directives were in affect, and because struct using_direct has
> changed a bit. Unfortunately, it's not done changing yet - the more I
> understand the name lookup rules from the C++ Standard, the more of
> the mess it looks like. So there are some bugs that I know about
> involving in the way namespaces are handled in this code (basically, I
> try to fake "namespace scope" by adding a bunch of using directives),
> but it's a reasonable first start. Not ready for mainline, though.
>
> The modifications to the dwarf2read.c might be useful for you when
> you're trying to get classes located in the correct namespace.

> Tell me what you think. I realize that this is pretty large; I
> promise that I won't submit another patch for approval to the branch
> until this one (or a variant of it) has been approved, to cut down on
> the sizes of future patches...

It's approved, with some comments for you to think about. You're doing
a truly heroic amount of work here...

> +static void
> +scan_for_anonymous_namespaces (struct symbol *symbol)
> +{
> + const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
> + const char *beginning, *end;
> +
> + /* FIXME: carlton/2002-10-14: Should we do some sort of fast search
> + first to see if the substring "(anonymous namespace)" occurs in
> + name at all? */

Definitely! This is a hideously expensive search here...

> + - And operator names can contain parentheses or angle brackets.
> + Fortunately, I _think_ that operator names can only occur in a
> + fairly restrictive set of locations (in particular, they have be
> + at depth 0, don't they?). */

No :( This is one of the more hideous pieces of C++ I've ever written
and it took a little time to come up with:

class B {
public:
};
int operator+ (B const &, B const &)
{
return 1;
}

template <void *T> class C {
public:
static void * const cmem = T;
int member(void);
};

int theInt;

template <void *T> int C<T>::member(void) {
return 0;
}

C<(void *) &theInt> theC;
C<(void *) &operator+> theOtherC;

int func()
{
return theOtherC.member();
}

Gives us this gem:
00000000 W C<&operator+(B const &, B const &)>::member(void)

Not sure if this presents a problem; the parentheses in an operator
name will be matched, and you can't define an operator ->, can you?
Oh. operator>>. Um.... this grosser revision of the above code:

class B {
public:
};
int operator+ (B const &, B const &)
{
return 1;
}
int operator<< (B const &, B const &)
{
return 1;
}
int operator>> (B const &, B const &)
{
return 1;
}

template <void *T> class C {
public:
static void * const cmem = T;
int member(void);
};

int theInt;

template <void *T> int C<T>::member(void) {
return 0;
}

C<(void *) &theInt> theC;
C<(void *) &operator+> theOtherC;
C<(void *) &operator<<> theThirdC;
C<(void *) &operator>>> theFourthC;

int func()
{
return theC.member() + theOtherC.member() + theThirdC.member() + theFourthC.member();
}

Produces this terrifying output:
00000000 W C<&operator<<(B const &, B const &)>::member(void)
00000000 W C<&operator>>(B const &, B const &)>::member(void)

So I guess we need to look for those specifically. That's awful.

> +
> +/* FIXME: carlton/2002-10-09: Do all the functions here handle all the
> + above considerations correctly? */

Almost certainly not; I hadn't thought about the (anonymous namespace)
thing. It may be misdetected as the arg list; if it isn't, it's blind
luck.

> +/* Let's optimize away calls to strlen("operator"). */
> +
> +#define LENGTH_OF_OPERATOR 8

A recent GCC will do this for you, actually. If glibc doesn't get in
its way, at least.

> +/* FIXME: carlton/2002-10-07: That anonymous namespace example isn't
> + that great, since it really depends not only on what the
> + demangler's output is but also on the fact that the demangler's
> + output doesn't depend on the name of the file in question. Which,
> + alas, it doesn't, but should, leaving us with no way to distinguish
> + between anonymous namespaces in different files. Sigh... */

They may be responsive to fixing that...

> + /* FIXME: carlton/2002-10-10: is "is_a_field_of_this" always
> + non-NULL if we're in the C++ case? Maybe we should always do
> + this, and delete the two previous searches: this will always
> + search the global namespace, after all. */

I don't think it'll always be non-NULL - I think it's just set when the
caller cares about the answer. And why are searches in using
directives conditioned on this argument?

> + /* Contains information about what using directives or other
> + similar features are added by this block. This should always
> + be NULL for global blocks: if there are using directives that
> + affect an entire file, put it in the static block. */

I really hate what tabs do after patch markers and quoting markers...
:)

--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer