This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB 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: [RFA/dwarf] save nested Ada subprograms as global symbol


> >     Thus, for brevity, the debugger acts as if there were implicit with
> >     and use clauses in effect for all user-written packages, making it
> >     unnecessary to fully qualify most names with their packages,
> >     regardless of context. Where this causes ambiguity, GDB asks the
> >     user's intent.
> > 
> > In the case of Hello.First and Goodbye.First, the user should expect
> > that a breakpoint should be inserted in each function.  If the user
> > wants to specifically break on say Hello.First, then he should use
> > its fully qualified name.
> 
> "for all user-written packages"; functions aren't packages, are they?

Hmm, yes, you are right. I'm stretching the documented behavior.
Functions are not packages, but it seemed natural to treat them
as such for symbol name resolution: The full name is Goodbye.First,
and "First" should match too. So if we modify the debugger, I'll have
to remember to update the documentation as well.

> > > A related example in C++ would be:
> > > 
> > > namespace A {
> > >   void first () { }
> > > 
> > >   void second () { first (); }
> > > }
> > > 
> > > int main()
> > > {
> > >   A::second ();
> > > }
> You don't have to be in second to break on first - sorry if that was
> unclear.  You have to be in second for "break first" to work.

Do I have to be inside namespace A, you mean?

> "break A::first" always works.

That's good to hear. Similarly, "break Goodbye.First" should work too,
IMO, but for some reason, it doesn't. It works with AdaCore's version,
though. I guess it's so uncommon for me to be using the fully qualified
name that I've never thought of having a test that verifies this.
I will leave that specific problem for another day.

> If I put a breakpoint on "search" from my application and GDB
> also stopped at "std::search<Iter1, Iter2, Equals>" instantiated from
> the Standard Template Library, I'd be very surprised.  I said
> "search", not "std::search", and GDB knows where to look for something
> named "search"; if you haven't said "using std", it shouldn't search
> std.  But this is a fairly clear difference between the expectations
> of C++ and Ada developers.

I'm also realizing that the habits of C++ and Ada developers seem pretty
different in some ways. I think that part of it is because of differences
in the language. In Ada, if you "use" a package, then you no longer need
to specify the scopy when you refer to an entity. So it's very common
to see a call to a function using its unqualified name, and the resolution
of that name is not just dependent on the scope where it's used, it's
also dependent on what "use" clauses have been defined. I don't know
that this is possible in C++. I'm assuming that "search" from inside
std means "std::search", but that "search" from any other context can
never mean "std::search", hence the surprise factor in C++.

> A closer analogy to nested procedures may be class methods.  Are the
> names of functions in packages normally relatively unique?  How about
> for nested functions?  In C++, names within namespaces are relatively
> unique, and method names are not ("next", "iterator", etc.).

If I simplify a bit how the linkage name of any entity is generated,
the process is fairly simple. The name of an entity is prefixed by
the name of the context followed by "__" followed by the name of the
entity in lowercase. For instance:

   package body Pck is
      procedure Do_Nothing is
         procedure First is null procedure;
      begin
         Pck.Do_Nothing.First;
      end Do_Nothing;
   end Pck;

The linkage name of Pck.Do_Nothing is "pck__do_nothing".  Similarly,
the linkage name of Pck.Do_Nothing.First is "pck__do_nothing__first".

> Anyway, I'm certainly willing to follow your lead on what Ada users
> expect.  I'm wondering if I'm barking at the wrong part of your
> message, though.  Does the symbol for the nested subprogram end up
> with an unqualified name (e.g., "first") in the global symbol table?

The symbol name for the nested subprogram is qualified.

> IMO the symbol table should reflect the program structure.

You mean that the symbol should be stored in the scope where
the function is defined? (which is what my patch is UNdoing).

I would tend to agree.  The goal is to make it easy for the user to use
the debugger, and I think that being able to break on nested subprograms
without having to specify the scope is an important feature. I certainly
have been relying on it quite a bit. The problem is on how to implement
this feature.  The approach I chose was to make the symbol global
instead of nested. Pretty quick and effective - I'm still unsure of
the consequences at the user-level of this approach.  Another way we could
do would be to expand the symbol search routine to look inside functions
for nested functions.  But I'm concerned about the peformance aspect of
this. What do you think?

-- 
Joel


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