Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Re: [rfa] teach lookup_symbol about namespace scope
@ 2003-05-19  9:55 Paul Hilfinger
  2003-05-19 16:35 ` David Carlton
  0 siblings, 1 reply; 13+ messages in thread
From: Paul Hilfinger @ 2003-05-19  9:55 UTC (permalink / raw)
  To: ezannoni, carlton; +Cc: drow, cagney, gdb-patches, jimb, brobecker


Yes, Ada does do things weirdly at the moment, and will probably continue
to do so, but I don't think this need worry anybody.  Our particular needs
are:

1. We do NOT cache demangled names, and we look up all symbols using
   mangled names.  Originally, we just followed C++, but changed when
   we discovered that our customers had HUGE executables for which the
   startup and memory costs became substantial.  David Carlton expressed
   concern that our approach must cause maintenance problems, but to date
   (i.e., since early 1998), the approach has caused no problems for us.

2. We generally expect multiple symbol matches, rather than just taking
   the first match, and therefore our main lookup routine returns a list
   of symbols.

3. Linkage (mangled) names have the form 
        <prefix>__<simple name><optional suffic>
   and we need to be able to match this name given either
   either <prefix>__<simple name> or <simple name>.  


In our sources, I have introduced a macro SYMBOL_SEARCH_NAME that in
the Ada case is equivalent to SYMBOL_LINKAGE_NAME and in other cases
to the demangled name.  As long as symbol tables (hash tables, etc.)
are built and searched according to the search name, everything just
works.  To handle the need for a symbol list (as Elena mentions) we
simply wrote our own lookup_symbol.  We'll certainly take advantage of
any opportunity to dump the latter code, of course, and will
contribute little hooks if that's what it takes.  However, it wasn't
difficult to create our version in the first place and it has not been
hard to maintain, so even in the worst case (i.e., we have to rewrite
symbol lookup entirely) it will not be a terrible problem.  Besides, I
am confident that with the spiffy new design we're seeing, adaptation
for Ada should be even easier than before.

Paul Hilfinger


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

* Re: [rfa] teach lookup_symbol about namespace scope
  2003-05-19  9:55 [rfa] teach lookup_symbol about namespace scope Paul Hilfinger
@ 2003-05-19 16:35 ` David Carlton
  2003-05-20 11:10   ` Paul Hilfinger
  0 siblings, 1 reply; 13+ messages in thread
From: David Carlton @ 2003-05-19 16:35 UTC (permalink / raw)
  To: Paul Hilfinger; +Cc: ezannoni, drow, cagney, gdb-patches, jimb, brobecker

On Fri, 16 May 2003 10:53:34 -0400 , Paul Hilfinger <hilfingr@gnat.com> said:

> 1. We do NOT cache demangled names, and we look up all symbols using
>    mangled names.  Originally, we just followed C++, but changed when
>    we discovered that our customers had HUGE executables for which the
>    startup and memory costs became substantial.  David Carlton expressed
>    concern that our approach must cause maintenance problems, but to date
>    (i.e., since early 1998), the approach has caused no problems for
>    us.

Changes over the last half-year might make things worse for you folks,
but they might not; probably there's no point worrying about it in
advance until concrete problems start to arise.  Daniel's changes
earlier this year help with the costs of demangling, but they aren't
going to vanish.

> 2. We generally expect multiple symbol matches, rather than just taking
>    the first match, and therefore our main lookup routine returns a list
>    of symbols.

We could probably use this feature in the non-Ada case, too, to get
C++ right...

> 3. Linkage (mangled) names have the form 
>         <prefix>__<simple name><optional suffic>
>    and we need to be able to match this name given either
>    either <prefix>__<simple name> or <simple name>.  

I'm curious: how frequent is this optional suffix?  Because this looks
so simple that it seems like the time costs for demangling would be
very small: all you have to do is skip "prefix__" and then check for
the optional suffix (which I assume is easy to recognize?), and it
seems to me that other costs in building symbol information would
swamp that.  And we could design a scheme where, if the suffix was
absent, the mangled and demangled names would share memory, since the
demangled name is a final substring of the mangled name.  So if that's
the common case, then the memory cost would go away as well.  We'd
have to tinker with symbol_set_names a bit, but that's okay: there's
already a somewhat gross Java hack in there, and having to
special-case Ada as well would give us an excuse to clean it up.

> In our sources, I have introduced a macro SYMBOL_SEARCH_NAME that in
> the Ada case is equivalent to SYMBOL_LINKAGE_NAME and in other cases
> to the demangled name.

Do Ada symbols have both the demangled and linkage name set?  Because
if you're never setting the demangled name, I would think that you
wouldn't have to use a special macro in the Ada case.  (By the way, we
used to have a different macro called SYMBOL_SEARCH_NAME, but that's a
separate issue.)

> To handle the need for a symbol list (as Elena mentions) we simply
> wrote our own lookup_symbol.  We'll certainly take advantage of any
> opportunity to dump the latter code, of course, and will contribute
> little hooks if that's what it takes.  However, it wasn't difficult
> to create our version in the first place and it has not been hard to
> maintain, so even in the worst case (i.e., we have to rewrite symbol
> lookup entirely) it will not be a terrible problem.  Besides, I am
> confident that with the spiffy new design we're seeing, adaptation
> for Ada should be even easier than before.

Sounds great.

David Carlton
carlton@math.stanford.edu


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

* Re: [rfa] teach lookup_symbol about namespace scope
  2003-05-19 16:35 ` David Carlton
@ 2003-05-20 11:10   ` Paul Hilfinger
  2003-05-20 16:17     ` David Carlton
  0 siblings, 1 reply; 13+ messages in thread
From: Paul Hilfinger @ 2003-05-20 11:10 UTC (permalink / raw)
  To: carlton; +Cc: ezannoni, drow, cagney, gdb-patches, jimb, brobecker


David,

> > 2. We generally expect multiple symbol matches, rather than just taking
> >    the first match, and therefore our main lookup routine returns a list
> >    of symbols.

> We could probably use this feature in the non-Ada case, too, to get
> C++ right...

Perhaps a lookup procedure with a function parameter that serves as a 
callback.  The procedure would call its callback argument with each matching 
symbol (and the usual void* kludge ... uh, I mean ... argument for extra 
state information); the callback could return 0 or 1 to indicate whether to
stop.  The current lookup_symbol could simply use this routine.


> > 3. Linkage (mangled) names have the form 
> >         <prefix>__<simple name><optional suffic>
> >    and we need to be able to match this name given either
> >    either <prefix>__<simple name> or <simple name>.  
> 
> I'm curious: how frequent is this optional suffix?  Because this looks
> so simple that it seems like the time costs for demangling would be
> very small: all you have to do is skip "prefix__" and then check for
> the optional suffix (which I assume is easy to recognize?), and it
> seems to me that other costs in building symbol information would
> swamp that.  And we could design a scheme where, if the suffix was
> absent, the mangled and demangled names would share memory, since the
> demangled name is a final substring of the mangled name. 

Sorry; I was unclear.  The MANGLED names have the form shown, but
<prefix>__<simple name> is NOT the demangled name.  Binary operators
get renamed and "." goes to "__".  Hmm. We did the latter mangling
because of fear that some linkers or assemblers would not take kindly
to "."s in names.  Perhaps revisitation is in order; I honestly don't
know what the situation is these days vis-a-vis non-alphanumeric characters
in symbol names.

> Do Ada symbols have both the demangled and linkage name set?  Because
> if you're never setting the demangled name, I would think that you
> wouldn't have to use a special macro in the Ada case.  (By the way, we
> used to have a different macro called SYMBOL_SEARCH_NAME, but that's a
> separate issue.)

I'm not sure which of your macros then would yield the right value for 
all languages.  The idea was for SYMBOL_SEARCH_NAME to return the form 
of name for a symbol that a specific language does searches on.  We still
need SYMBOL_NATURAL_NAME and SYMBOL_PRINT_NAME to print out demangled
forms of the name (which for Ada would involve a procedure call).  

Paul 


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

* Re: [rfa] teach lookup_symbol about namespace scope
  2003-05-20 11:10   ` Paul Hilfinger
@ 2003-05-20 16:17     ` David Carlton
  0 siblings, 0 replies; 13+ messages in thread
From: David Carlton @ 2003-05-20 16:17 UTC (permalink / raw)
  To: Paul Hilfinger; +Cc: ezannoni, drow, cagney, gdb-patches, jimb, brobecker

On Tue, 20 May 2003 07:10:41 -0400 (EDT), Paul Hilfinger <hilfingr@gnat.com> said:

>> > 3. Linkage (mangled) names have the form 
>> >         <prefix>__<simple name><optional suffic>
>> >    and we need to be able to match this name given either
>> >    either <prefix>__<simple name> or <simple name>.  
>> 
>> I'm curious: how frequent is this optional suffix?  Because this looks
>> so simple that it seems like the time costs for demangling would be
>> very small: all you have to do is skip "prefix__" and then check for
>> the optional suffix (which I assume is easy to recognize?), and it
>> seems to me that other costs in building symbol information would
>> swamp that.  And we could design a scheme where, if the suffix was
>> absent, the mangled and demangled names would share memory, since the
>> demangled name is a final substring of the mangled name. 

> Sorry; I was unclear.  The MANGLED names have the form shown, but
> <prefix>__<simple name> is NOT the demangled name.  Binary operators
> get renamed and "." goes to "__".

I guess I'd been assuming/hoping that <simple name> was normally the
demangled name.  Binary operators don't worry me so much, but is "."
some sort of package/module/etc. operator that shows up all over the
place?  If so, I guess there's no way around making a copy.

>> Do Ada symbols have both the demangled and linkage name set?  Because
>> if you're never setting the demangled name, I would think that you
>> wouldn't have to use a special macro in the Ada case.  (By the way, we
>> used to have a different macro called SYMBOL_SEARCH_NAME, but that's a
>> separate issue.)

> I'm not sure which of your macros then would yield the right value for 
> all languages.  The idea was for SYMBOL_SEARCH_NAME to return the form 
> of name for a symbol that a specific language does searches on.  We still
> need SYMBOL_NATURAL_NAME and SYMBOL_PRINT_NAME to print out demangled
> forms of the name (which for Ada would involve a procedure call).  

Ah, interesting.  That does sound like a consistent and reasonable way
to do things, given your desire to not store demangled names.

Thanks for the info!

David Carlton
carlton@math.stanford.edu


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

* Re: [rfa] teach lookup_symbol about namespace scope
  2003-05-16 20:51           ` David Carlton
@ 2003-05-17  0:09             ` Joel Brobecker
  0 siblings, 0 replies; 13+ messages in thread
From: Joel Brobecker @ 2003-05-17  0:09 UTC (permalink / raw)
  To: David Carlton
  Cc: Elena Zannoni, Daniel Jacobowitz, cagney, gdb-patches,
	Jim Blandy, Adam Fedor

Hi David,

> Ada is weird, likes to do things its own way (it apparently handles
> (de)mangled names in a completely different way from C++), and doesn't
> even compile right now.  If some Ada person wants to speak up and talk
> about what Ada needs for language lookup, that would be great, but
> otherwise I'm not going to worry about it.

We are currently studying your design, and evaluating it with respect to
Ada. We hope to be able to provide some feedback soon.

Yeah, Ada does not compile. We are slowly making progress at getting our
sources sorted out to help the merge. In the meantime, if you are
interested in getting an ada-aware debugger, you can CVS checkout our
sources. It's based on 5.3, and it's avail at http://libre.act-europe.fr/GDB/.

-- 
Joel


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

* Re: [rfa] teach lookup_symbol about namespace scope
  2003-05-16 19:49         ` Elena Zannoni
@ 2003-05-16 20:51           ` David Carlton
  2003-05-17  0:09             ` Joel Brobecker
  0 siblings, 1 reply; 13+ messages in thread
From: David Carlton @ 2003-05-16 20:51 UTC (permalink / raw)
  To: Elena Zannoni
  Cc: Daniel Jacobowitz, cagney, gdb-patches, Jim Blandy, Adam Fedor

On Fri, 16 May 2003 15:55:10 -0400, Elena Zannoni <ezannoni@redhat.com> said:
> David Carlton writes:

>> Some possibilities:

>> 2) Put language-specific hooks in the generic lookup_symbol function.

>> 3) Have the knowledge about what to do actually embedded in the blocks
>> themselves.

>> Option 3 might well be a good idea in the long term, and probably my
>> dictionary patch will begin to set up the framework necessary for
>> that, but it's far too big a leap for me to want to consider that now:
>> I just want to get C++ working better.

> Option 3 is the long term goal, I think Adndrew agrees with this and
> has ideas about integrating language knowedge with frames. For this
> we need to better understand the ada code as well, and I haven't
> looked at it too closely. Ideally I would like to have namespace
> support in gdb 6, so we have a tradeoff to make.

I'd like to have my branch merged in by GDB 6, but I'm not sure we're
going to be able to finish it.  Either way, though, I think that
option 3 should be looked at as a long-term plan that shouldn't stand
in the way of more immediate goals.  It seems to me that option 2
would be a natural first step along the journey to option 3: it will
let us get some experience with what sorts of functionality needs to
depend on the current language (or possibly on other data), so that
our eventual design will be nice and clean.

>> So that leaves us with option 2.  And, actually, I think there's a
>> natural place to put a hook:
>> 
>> * Allow languages complete control as to what happens after the local
>> variables are looked up.
>> 
>> Local variable lookup is, I hope, fairly uniform across languages.
>> But the 'is_a_field_of_this' check isn't relevant to C.  The new
>> namespace stuff isn't relevant to C.  And all of that happens after
>> local variables are looked up, either before or instead of
>> global/static symbol lookup.  So that seems to me to be the right
>> place to allow languages to seize control; if we need more hooks
>> later, we can add them, but that will give us some place to start, and
>> will allow me to move my namespace lookup algorithm to cp-support.c or
>> cp-namespace.c.  I assume this would work for whatever needs
>> Objective-C has; I'll add Adam to the Cc: list in case he wants to
>> chime in.  (We should really add him to the MAINTAINERS list as
>> Objective-C maintainer one of these days.)

> This is what I was trying to say. If we could branch off the main
> search algorithm to do language specific actions. I was thinking that
> the current algorithm could be left in place, and yours could be used
> in case of c++ being detected.

> for the record the algorithm goes roughly like this (correct me if not):

> 0. search symbol in local block
> 1. search symbol in static block of the current file
> 2. search symbol in all symtabs of the global blocks for the program
> 3. search symbol in all psymtabs of the global blocks for the program
> 4. search symbol in all symtabs of the static blocks for the program
> 5. search symbol in all psymtabs of the static blocks for the
>    program

There's another step between 0 and 1, where we do the 'field_of_this'
check.

> You have moved 1, 2, and 3 within the new namespace lookup algorithm,
> which becomes a no-op for the non-c++ case.  I was wondering if we
> could leave 1 through 5 in place, and have a c++ version for 1, 2, 3.
> Well, to be honest I was thinking that we could do

> 0.
> <cplus stuff> or <ada stuff> or <objc stuff> or....
> 1.
> 2.
> 3.
> 4.
> 5.

> instead of

> 0.
> |_______________
> |\       \      \
> | \       \      \
> 1. 1c++   1ada  1objc  .....fortran, pascal,....
> 2. 2c++   2ada  2objc
> 3. 3c++   3ada  3objc
> | /       /      /
> |/_______/______/
> 4.
> 5.

> But I see now that with each scope algorithm being basically
> language specific, we may not be able to do what I first intended.

Right.  I mean, I could write a C++-specific function that searches
all of the namespaces in scope other than the global namespace, in
which case it could fit right before step 1, but it wouldn't be
natural to do so.  And steps 1,2,3 are fairly intertwined.  For
example, steps 2 and 3 really should be thought of as a single step
"look up a global variable", where the symtab/psymtab issue is an
internal matter for the data structures to deal with.  And, in C++,
you can't separate out step 1 from steps 2/3: you have to do them all
for each namespace in scope, so you can't provide a hook for step 1
and another hook for steps 2/3.

So that's why I want to replace steps 1-3 as a whole on a per-language
basis: the breakdown of the algorithm in those steps depends on the
language involved (as well as on the particular data structures being
used).

> (even 1.2.3. are actually C specific, so we will probably end up w/o
> a default search algorithm, don't know)

I figure that that we can let the various fallback languages (unknown,
minimal, asm, whatever they're called) default to the C lookup
mechanism.

> Hmm, thinking out loud. What about 'set language blah'? Should this
> honor that?

Ah.  Right.  I hadn't looked at language.h too much when I sent my
last message, but now I see that GDB has a notion of the current
language.  So I guess we should use that instead of trying to get
information from the current block somehow?

>> If this sounds good, I'll get to work on it; it should be easy
>> enough to do, I think.  I have a pretty good idea of what functions
>> symtab.c will want to export to make life easier for other
>> languages.

> I think it's an ok plan. I think some Ada person should chime in as
> well to see if we can resolve the duplication of code in ada-lang.c,
> or at least understand what they need out of the symbol table.

Ada is weird, likes to do things its own way (it apparently handles
(de)mangled names in a completely different way from C++), and doesn't
even compile right now.  If some Ada person wants to speak up and talk
about what Ada needs for language lookup, that would be great, but
otherwise I'm not going to worry about it.

David Carlton
carlton@math.stanford.edu


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

* Re: [rfa] teach lookup_symbol about namespace scope
  2003-05-16 17:26       ` David Carlton
@ 2003-05-16 19:49         ` Elena Zannoni
  2003-05-16 20:51           ` David Carlton
  0 siblings, 1 reply; 13+ messages in thread
From: Elena Zannoni @ 2003-05-16 19:49 UTC (permalink / raw)
  To: David Carlton
  Cc: Elena Zannoni, Daniel Jacobowitz, cagney, gdb-patches,
	Jim Blandy, Adam Fedor

David Carlton writes:
 > On Fri, 16 May 2003 10:53:34 -0400, Elena Zannoni <ezannoni@redhat.com> said:
 > 
 > > OK, here it goes. I have been ruminating on this patch a long time,
 > > and I have really mixed feelings about it, no that's not accurate, I
 > > am completely torn about it.
 > 
 > I'm not surprised to hear that, because I basically share your
 > qualms.

pheeew! :-)

 > 
 > > On the other hand, the generic flow of control of the symbol search
 > > gets pulled into c++ territory.
 > 
 > Right.  So what do we do about that?  Some possibilities:
 > 
 > 1) Have a separate lookup-symbol function for each language, and make
 >    sure it gets called wherever is appropriate.
 > 
 > 2) Put language-specific hooks in the generic lookup_symbol function.
 > 
 > 3) Have the knowledge about what to do actually embedded in the blocks
 >    themselves.
 > 
 > I don't think option 1 is all that great an idea: e.g. C and C++ share
 > a parser (and might eventually share it with Objective C as well), so
 > you don't know which lookup function to call, or in decode_variable
 > (within decode_line_1), you don't really know what the ambient
 > language is, so you really want a single function that works for all
 > languages.
 > 

If by option 1 you mean the main lookup_symbol, I agree with the
above. It is called in places where you are not sure what to do.


 > Option 3 might well be a good idea in the long term, and probably my
 > dictionary patch will begin to set up the framework necessary for
 > that, but it's far too big a leap for me to want to consider that now:
 > I just want to get C++ working better.

Option 3 is the long term goal, I think Adndrew agrees with this and
has ideas about integrating language knowedge with frames. For this we
need to better understand the ada code as well, and I haven't looked
at it too closely. Ideally I would like to have namespace support in
gdb 6, so we have a tradeoff to make.

 > 
 > So that leaves us with option 2.  And, actually, I think there's a
 > natural place to put a hook:
 > 
 > * Allow languages complete control as to what happens after the local
 >   variables are looked up.
 > 
 > Local variable lookup is, I hope, fairly uniform across languages.
 > But the 'is_a_field_of_this' check isn't relevant to C.  The new
 > namespace stuff isn't relevant to C.  And all of that happens after
 > local variables are looked up, either before or instead of
 > global/static symbol lookup.  So that seems to me to be the right
 > place to allow languages to seize control; if we need more hooks
 > later, we can add them, but that will give us some place to start, and
 > will allow me to move my namespace lookup algorithm to cp-support.c or
 > cp-namespace.c.  I assume this would work for whatever needs
 > Objective-C has; I'll add Adam to the Cc: list in case he wants to
 > chime in.  (We should really add him to the MAINTAINERS list as
 > Objective-C maintainer one of these days.)
 > 

This is what I was trying to say. If we could branch off the main
search algorithm to do language specific actions. I was thinking that
the current algorithm could be left in place, and yours could be used
in case of c++ being detected.

for the record the algorithm goes roughly like this (correct me if not):

0. search symbol in local block
1. search symbol in static block of the current file
2. search symbol in all symtabs of the global blocks for the program
3. search symbol in all psymtabs of the global blocks for the program
4. search symbol in all symtabs of the static blocks for the program
5. search symbol in all psymtabs of the static blocks for the program

You have moved 1, 2, and 3 within the new namespace lookup algorithm,
which becomes a no-op for the non-c++ case.  I was wondering if we
could leave 1 through 5 in place, and have a c++ version for 1, 2, 3.
Well, to be honest I was thinking that we could do

0.
<cplus stuff> or <ada stuff> or <objc stuff> or....
1.
2.
3.
4.
5.

instead of

0.
|_______________
|\       \      \
| \       \      \
1. 1c++   1ada  1objc  .....fortran, pascal,....
2. 2c++   2ada  2objc
3. 3c++   3ada  3objc
| /       /      /
|/_______/______/
4.
5.

But I see now that with each scope algorithm being basically language
specific, we may not be able to do what I first intended.

(even 1.2.3. are actually C specific, so we will probably end up w/o a default
search algorithm, don't know)

Hmm, thinking out loud. What about 'set language blah'? Should this
honor that?

 > To get this to work, we'll obviously need to provide a way to locate
 > the language associated to a given block.  My first instinct was to
 > add a 'language' member to each block, but poking around, the symtab
 > already has that information: how about just adding a 'symtab' member
 > to each block?  (Or even just to global blocks, if that is any easier
 > to write: we can bury the details of its access in a function
 > 'block_symtab'.)  That would help make sure that the information is
 > consistent, and would let us get rid of the ALL_SYMTABS bit in
 > lookup_symbol_aux_block.

hmm, I am wondering, we have language info in the symtab, and in the
symbols already, do we need it to add it somewhere else too? I think
we could access it like you say. However I am bit concerned that we
would add a lot of loops through the blocks.


 > 
 > If this sounds good, I'll get to work on it; it should be easy enough
 > to do, I think.  I have a pretty good idea of what functions symtab.c
 > will want to export to make life easier for other languages.

I think it's an ok plan. I think some Ada person should chime in as
well to see if we can resolve the duplication of code in ada-lang.c,
or at least understand what they need out of the symbol table.

elena

 > 
 > > Anyway, here is the symtab.c portion of the patch updated to reflect
 > > the namespace-->domain changes.
 > 
 > Thanks.
 > 
 > > (about the test changes: do you use namespace1.cc at all? I don't see
 > > you hooking that up to anything).
 > 
 > Oh, whoops, sorry about that.  Good thing Daniel was asking me to
 > include tests for symbols in namespace1.cc that are actually supposed
 > to find a variable instead of not do so...
 > 
 > David Carlton
 > carlton@math.stanford.edu


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

* Re: [rfa] teach lookup_symbol about namespace scope
  2003-05-16 14:48     ` Elena Zannoni
@ 2003-05-16 17:26       ` David Carlton
  2003-05-16 19:49         ` Elena Zannoni
  0 siblings, 1 reply; 13+ messages in thread
From: David Carlton @ 2003-05-16 17:26 UTC (permalink / raw)
  To: Elena Zannoni
  Cc: Daniel Jacobowitz, cagney, gdb-patches, Jim Blandy, Adam Fedor

On Fri, 16 May 2003 10:53:34 -0400, Elena Zannoni <ezannoni@redhat.com> said:

> OK, here it goes. I have been ruminating on this patch a long time,
> and I have really mixed feelings about it, no that's not accurate, I
> am completely torn about it.

I'm not surprised to hear that, because I basically share your
qualms.

> On the other hand, the generic flow of control of the symbol search
> gets pulled into c++ territory.

Right.  So what do we do about that?  Some possibilities:

1) Have a separate lookup-symbol function for each language, and make
   sure it gets called wherever is appropriate.

2) Put language-specific hooks in the generic lookup_symbol function.

3) Have the knowledge about what to do actually embedded in the blocks
   themselves.

I don't think option 1 is all that great an idea: e.g. C and C++ share
a parser (and might eventually share it with Objective C as well), so
you don't know which lookup function to call, or in decode_variable
(within decode_line_1), you don't really know what the ambient
language is, so you really want a single function that works for all
languages.

Option 3 might well be a good idea in the long term, and probably my
dictionary patch will begin to set up the framework necessary for
that, but it's far too big a leap for me to want to consider that now:
I just want to get C++ working better.

So that leaves us with option 2.  And, actually, I think there's a
natural place to put a hook:

* Allow languages complete control as to what happens after the local
  variables are looked up.

Local variable lookup is, I hope, fairly uniform across languages.
But the 'is_a_field_of_this' check isn't relevant to C.  The new
namespace stuff isn't relevant to C.  And all of that happens after
local variables are looked up, either before or instead of
global/static symbol lookup.  So that seems to me to be the right
place to allow languages to seize control; if we need more hooks
later, we can add them, but that will give us some place to start, and
will allow me to move my namespace lookup algorithm to cp-support.c or
cp-namespace.c.  I assume this would work for whatever needs
Objective-C has; I'll add Adam to the Cc: list in case he wants to
chime in.  (We should really add him to the MAINTAINERS list as
Objective-C maintainer one of these days.)

To get this to work, we'll obviously need to provide a way to locate
the language associated to a given block.  My first instinct was to
add a 'language' member to each block, but poking around, the symtab
already has that information: how about just adding a 'symtab' member
to each block?  (Or even just to global blocks, if that is any easier
to write: we can bury the details of its access in a function
'block_symtab'.)  That would help make sure that the information is
consistent, and would let us get rid of the ALL_SYMTABS bit in
lookup_symbol_aux_block.

If this sounds good, I'll get to work on it; it should be easy enough
to do, I think.  I have a pretty good idea of what functions symtab.c
will want to export to make life easier for other languages.

> Anyway, here is the symtab.c portion of the patch updated to reflect
> the namespace-->domain changes.

Thanks.

> (about the test changes: do you use namespace1.cc at all? I don't see
> you hooking that up to anything).

Oh, whoops, sorry about that.  Good thing Daniel was asking me to
include tests for symbols in namespace1.cc that are actually supposed
to find a variable instead of not do so...

David Carlton
carlton@math.stanford.edu


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

* Re: [rfa] teach lookup_symbol about namespace scope
  2003-04-24 20:44   ` David Carlton
@ 2003-05-16 14:48     ` Elena Zannoni
  2003-05-16 17:26       ` David Carlton
  0 siblings, 1 reply; 13+ messages in thread
From: Elena Zannoni @ 2003-05-16 14:48 UTC (permalink / raw)
  To: David Carlton; +Cc: Daniel Jacobowitz, cagney, gdb-patches, Jim Blandy


OK, here it goes. I have been ruminating on this patch a long time,
and I have really mixed feelings about it, no that's not accurate, I
am completely torn about it.

On one hand, I really like the algorithm to do the search recursively.
It is very clean and elegant. I have to admit that it took me a long
time to understand what it did, but it may just be me, lacking
concentration these days. Only after I applied the patch and stepped
through the code, I could see how it worked. Probably adding comments
would solve the problem, though.

On the other hand, the generic flow of control of the symbol search
gets pulled into c++ territory. This worries me because other
languages have other requirements, and it would be nice if we could
integrate language specific search portions into the generic lookup
code.  We have right now C++, ObjC, Ada, each with their own specific
rules. For instance ada-lang.c "resolves" the problem by doing an
almost total rewrite of the symbol lookup to suit the Ada scope rules.
With ObjC we have a couple of points where the control flow does
additional extra steps, and I think this is the right model, because
those points can become, in a not too distant future, points of entry
into language vectors functions. I would like to have a similar
structure for the C++ specific code. Sadly, doing this means to
disrupt your algorithm, and would require building list(s) of possible
scopes to be searched, and search each in turn, instead of using the
local state of the recursive calls as a list of items to check.
Unless of course, you can think of something else.

I would like to hear other people's opinions as well, on this issue.

Anyway, here is the symtab.c portion of the patch updated to reflect
the namespace-->domain changes. Block.c and block.h changes are ok.

(about the test changes: do you use namespace1.cc at all? I don't see
you hooking that up to anything).

elena


--- symtab.c	Fri May 16 10:49:23 2003
+++ symtab.c.dc	Thu May 15 13:44:22 2003
@@ -53,6 +53,8 @@
 #include "gdb_stat.h"
 #include <ctype.h>
 #include "cp-abi.h"
+#include "cp-support.h"
+#include "gdb_assert.h"
 
 /* Prototypes for local functions */
 
@@ -93,8 +95,7 @@
 					const char *mangled_name,
 					const struct block *block,
 					const domain_enum domain,
-					struct symtab **symtab,
-					const struct block **static_block);
+					struct symtab **symtab);
 
 static
 struct symbol *lookup_symbol_aux_block (const char *name,
@@ -126,6 +127,22 @@
 					  struct symtab **symtab);
 #endif
 
+static
+struct symbol *lookup_symbol_aux_namespace_scope (const char *name,
+						  const char *linkage_name,
+						  const struct block *block,
+						  domain_enum domain,
+						  struct symtab **symtab,
+						  const char *scope,
+						  int scope_len);
+
+static struct symbol *lookup_symbol_aux_file (const char *name,
+					      const char *linkage_name,
+					      const struct block *block,
+					      const domain_enum domain,
+					      struct symtab **symtab,
+					      int anonymous_namespace);
+
 static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
 
 /* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
@@ -959,7 +976,7 @@
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
   sym = lookup_symbol_aux_local (name, mangled_name, block, domain,
-				 symtab, &static_block);
+				 symtab);
   if (sym != NULL)
     return sym;
 
@@ -1025,50 +1042,10 @@
 	}
     }
 
-  /* If there's a static block to search, search it next.  */
-
-  /* NOTE: carlton/2002-12-05: There is a question as to whether or
-     not it would be appropriate to search the current global block
-     here as well.  (That's what this code used to do before the
-     is_a_field_of_this check was moved up.)  On the one hand, it's
-     redundant with the lookup_symbol_aux_symtabs search that happens
-     next.  On the other hand, if decode_line_1 is passed an argument
-     like filename:var, then the user presumably wants 'var' to be
-     searched for in filename.  On the third hand, there shouldn't be
-     multiple global variables all of which are named 'var', and it's
-     not like decode_line_1 has ever restricted its search to only
-     global variables in a single filename.  All in all, only
-     searching the static block here seems best: it's correct and it's
-     cleanest.  */
-
-  /* NOTE: carlton/2002-12-05: There's also a possible performance
-     issue here: if you usually search for global symbols in the
-     current file, then it would be slightly better to search the
-     current global block before searching all the symtabs.  But there
-     are other factors that have a much greater effect on performance
-     than that one, so I don't think we should worry about that for
-     now.  */
-
-  if (static_block != NULL)
-    {
-      sym = lookup_symbol_aux_block (name, mangled_name, static_block,
-				     domain, symtab);
-      if (sym != NULL)
-	return sym;
-    }
+  sym = lookup_symbol_aux_namespace_scope (name, mangled_name, block,
+					   domain, symtab,
+					   block_scope (block), 0);
 
-  /* Now search all global blocks.  Do the symtab's first, then
-     check the psymtab's. If a psymtab indicates the existence
-     of the desired name as a global, then do psymtab-to-symtab
-     conversion on the fly and return the found symbol. */
-
-  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, mangled_name,
-				   domain, symtab);
-  if (sym != NULL)
-    return sym;
-
-  sym = lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, mangled_name,
-				    domain, symtab);
   if (sym != NULL)
     return sym;
 
@@ -1094,27 +1071,24 @@
 }
 
 /* Check to see if the symbol is defined in BLOCK or its superiors.
-   Don't search STATIC_BLOCK or GLOBAL_BLOCK.  If we don't find a
-   match, store the address of STATIC_BLOCK in static_block.  */
+   Don't search STATIC_BLOCK or GLOBAL_BLOCK.  */
 
 static struct symbol *
 lookup_symbol_aux_local (const char *name, const char *mangled_name,
 			 const struct block *block,
 			 const domain_enum domain,
-			 struct symtab **symtab,
-			 const struct block **static_block)
+			 struct symtab **symtab)
 {
   struct symbol *sym;
-  
-  /* Check if either no block is specified or it's a global block.  */
+  const struct block *static_block = block_static_block (block);
 
-  if (block == NULL || BLOCK_SUPERBLOCK (block) == NULL)
-    {
-      *static_block = NULL;
-      return NULL;
-    }
+  /* Either no block is specified or it's a global block.  */
+
+  if (static_block == NULL)
+    return NULL;
 
-  while (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) != NULL)
+
+  while (block != static_block)
     {
       sym = lookup_symbol_aux_block (name, mangled_name, block, domain,
 				     symtab);
@@ -1123,9 +1097,8 @@
       block = BLOCK_SUPERBLOCK (block);
     }
 
-  /* We've reached the static block.  */
+  /* We've reached the static block without finding a result.  */
 
-  *static_block = block;
   return NULL;
 }
 
@@ -1390,6 +1363,157 @@
 }
 #endif /* 0 */
 
+/* Lookup NAME at namespace scope (or, in C terms, in static and
+   global variables).  SCOPE is the namespace that the current
+   function is defined within; only consider namespaces whose length
+   is at least SCOPE_LEN.  (This is to make the recursion easier.)  */
+
+static struct symbol *
+lookup_symbol_aux_namespace_scope (const char *name,
+				   const char *linkage_name,
+				   const struct block *block,
+				   domain_enum domain,
+				   struct symtab **symtab,
+				   const char *scope,
+				   int scope_len)
+{
+  char *cp_namespace;
+
+  if (scope[scope_len] != '\0')
+    {
+      struct symbol *sym;
+      int new_scope_len = scope_len;
+
+      /* If the current scope is followed by "::", skip past that.  */
+      if (new_scope_len != 0)
+	{
+	  gdb_assert (scope[new_scope_len] == ':');
+	  new_scope_len += 2;
+	}
+      new_scope_len += cp_find_first_component (scope + new_scope_len);
+      sym = lookup_symbol_aux_namespace_scope (name, linkage_name, block,
+					       domain, symtab,
+					       scope, new_scope_len);
+      if (sym != NULL)
+	return sym;
+    }
+
+  cp_namespace = alloca (scope_len + 1);
+  strncpy (cp_namespace, scope, scope_len);
+  cp_namespace[scope_len] = '\0';
+  return lookup_symbol_namespace (cp_namespace, name, linkage_name,
+				  block, domain, symtab);
+}
+
+/* Look up NAME in the C++ namespace CP_NAMESPACE, applying the using
+   directives that are active in BLOCK.  Otherwise, arguments are as
+   in lookup_symbol_aux.  */
+
+struct symbol *
+lookup_symbol_namespace (const char *cp_namespace,
+			 const char *name,
+			 const char *linkage_name,
+			 const struct block *block,
+			 domain_enum domain,
+			 struct symtab **symtab)
+{
+  const struct using_direct *current;
+  struct symbol *sym;
+
+  /* First, go through the using directives.  If any of them add new
+     names to the namespace we're searching in, see if we can find a
+     match by applying them.  */
+
+  for (current = block_using (block);
+       current != NULL;
+       current = current->next)
+    {
+      if (strcmp (cp_namespace, current->outer) == 0)
+	{
+	  sym = lookup_symbol_namespace (current->inner,
+					 name,
+					 linkage_name,
+					 block,
+					 domain,
+					 symtab);
+	  if (sym != NULL)
+	    return sym;
+	}
+    }
+
+  /* We didn't find anything by applying any of the using directives
+     that are still applicable; so let's see if we've got a match
+     using the current namespace.  */
+  
+  if (cp_namespace[0] == '\0')
+    {
+      return lookup_symbol_aux_file (name, linkage_name, block,
+				     domain, symtab,
+				     0);
+    }
+  else
+    {
+      char *concatenated_name
+	= alloca (strlen (cp_namespace) + 2 + strlen (name) + 1);
+      strcpy (concatenated_name, cp_namespace);
+      strcat (concatenated_name, "::");
+      strcat (concatenated_name, name);
+      sym = lookup_symbol_aux_file (concatenated_name, linkage_name,
+				    block, domain, symtab,
+				    cp_is_anonymous (cp_namespace));
+      return sym;
+    }
+}
+
+/* Look up NAME in BLOCK's static block and in global blocks.  If
+   ANONYMOUS_NAMESPACE is nonzero, don't look in other files' global
+   blocks, just in the one belonging to this file.  */
+
+static struct symbol *
+lookup_symbol_aux_file (const char *name,
+			const char *linkage_name,
+			const struct block *block,
+			const domain_enum domain,
+			struct symtab **symtab,
+			int anonymous_namespace)
+{
+  struct symbol *sym = NULL;
+  const struct block *static_block = block_static_block (block);
+
+  if (static_block != NULL)
+    {
+      sym = lookup_symbol_aux_block (name, linkage_name, static_block,
+				     domain, symtab);
+      if (sym != NULL)
+	return sym;
+    }
+
+  if (anonymous_namespace)
+    {
+      const struct block *global_block = NULL;
+      if (static_block != NULL)
+	global_block = BLOCK_SUPERBLOCK (static_block);
+      else if (block != NULL)
+	global_block = block;
+      
+      if (global_block != NULL)
+	return lookup_symbol_aux_block (name, linkage_name, global_block,
+					domain, symtab);
+      else
+	return NULL;
+    }
+  else
+    {
+      sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
+				       domain, symtab);
+      if (sym != NULL)
+	return sym;
+      else
+	return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name,
+					   domain, symtab);
+    }
+}
+
 /* Look, in partial_symtab PST, for symbol whose natural name is NAME.
    If LINKAGE_NAME is non-NULL, check in addition that the symbol's
    linkage name matches it.  Check the global symbols if GLOBAL, the


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

* Re: [rfa] teach lookup_symbol about namespace scope
  2003-04-24 20:18 ` Daniel Jacobowitz
@ 2003-04-24 20:44   ` David Carlton
  2003-05-16 14:48     ` Elena Zannoni
  0 siblings, 1 reply; 13+ messages in thread
From: David Carlton @ 2003-04-24 20:44 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches, Elena Zannoni, Jim Blandy

On Thu, 24 Apr 2003 10:33:56 -0400, Daniel Jacobowitz <drow@mvista.com> said:
> On Wed, Apr 23, 2003 at 06:24:43PM -0700, David Carlton wrote:

>> I think that's about it, though I'm probably forgetting something.
>> This needs symtab approval, though obviously I'd appreciate it if
>> Daniel could look it over as well.  Tested on GCC 3.2, DWARF 2,
>> i686-pc-linux-gnu; no new regressions.  (And I've been using a version
>> of this for months on my branch, too.)

> Would you add a test for successfully printing out a variable in
> namespace C in the second source file?  I'm guessing from context that
> it will work now.

Sure, that makes sense.  I certainly hope that it will work. :-)

> Other than that, I like this patch from the C++ perspective.

Great, thanks!

David Carlton
carlton@math.stanford.edu


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

* Re: [rfa] teach lookup_symbol about namespace scope
  2003-04-24 14:34 David Carlton
  2003-04-24 20:14 ` Eli Zaretskii
@ 2003-04-24 20:18 ` Daniel Jacobowitz
  2003-04-24 20:44   ` David Carlton
  1 sibling, 1 reply; 13+ messages in thread
From: Daniel Jacobowitz @ 2003-04-24 20:18 UTC (permalink / raw)
  To: David Carlton; +Cc: gdb-patches, Elena Zannoni, Jim Blandy

On Wed, Apr 23, 2003 at 06:24:43PM -0700, David Carlton wrote:
> I think that's about it, though I'm probably forgetting something.
> This needs symtab approval, though obviously I'd appreciate it if
> Daniel could look it over as well.  Tested on GCC 3.2, DWARF 2,
> i686-pc-linux-gnu; no new regressions.  (And I've been using a version
> of this for months on my branch, too.)

Would you add a test for successfully printing out a variable in
namespace C in the second source file?  I'm guessing from context that
it will work now.

Other than that, I like this patch from the C++ perspective.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


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

* Re: [rfa] teach lookup_symbol about namespace scope
  2003-04-24 14:34 David Carlton
@ 2003-04-24 20:14 ` Eli Zaretskii
  2003-04-24 20:18 ` Daniel Jacobowitz
  1 sibling, 0 replies; 13+ messages in thread
From: Eli Zaretskii @ 2003-04-24 20:14 UTC (permalink / raw)
  To: carlton; +Cc: gdb-patches, ezannoni, jimb, drow

> From: David Carlton <carlton@bactrian.org>
> Date: 23 Apr 2003 18:24:43 -0700
> 
> 	* config/djgpp/fnchange.lst: Add namespace1.cc.

This part of the patch is okay; thanks.


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

* [rfa] teach lookup_symbol about namespace scope
@ 2003-04-24 14:34 David Carlton
  2003-04-24 20:14 ` Eli Zaretskii
  2003-04-24 20:18 ` Daniel Jacobowitz
  0 siblings, 2 replies; 13+ messages in thread
From: David Carlton @ 2003-04-24 14:34 UTC (permalink / raw)
  To: gdb-patches; +Cc: Elena Zannoni, Jim Blandy, Daniel Jacobowitz

This patch teaches lookup_symbol and friends about namespace scope and
about using directives.  Basically, if you have a situation

namespace C {
  namespace D {
    void f()
    {
      // body of f
    }
  }
}

and you're in a breakpoint within 'f', then, when looking up a name
'x', you first look for C::D::x, then C::x, and finally x.  Also, you
might have to apply using directives.  (We currently only generate
using directives to tell us about anonymous namespaces.)

Some notes:

* This replaces the calls in lookup_symbol_aux to lookup a symbol in
  the current file's static block and in all files' global blocks with
  a call to lookup_symbol_aux_namespace_scope.

* That latter latter function, in turn, goes through all the
  namespaces in scope, in the correct order, and tries to find the
  symbol in each of them.

* It does that by calling a function lookup_symbol_namespace.  This
  function I've exported, even though it's only being used with
  symtab.c, because it will be useful from other files in future
  patches.

* lookup_symbol_namespace goes through all the using directives and
  tries to apply them; if none of them work, it searches the current
  namespace.  It does that by calling 'lookup_symbol_file'.

* lookup_symbol_file is where the original calls to search the current
  file's static block and all files' global blocks was moved to.
  Except that it's a bit uglier than that: if we're looking for a
  symbol within an anonymous namespace, we should only search the
  current file's global block.

* Since I never got an answer about the fate of
  lookup_symbol_aux_minsyms, I just deleted the bad part of that
  function and commented out the rest.  If there's a feeling that
  that's bad, I can handle the situation slightly differently; also, I
  can easily commit that part of the patch separately if desired.

* This is all safe in the non-C++ case: it reverts to the old behavior
  in that situation, and the cost of the few extra function calls
  involved will be swamped by the cost of actually doing the work of
  looking up symbols.

I think that's about it, though I'm probably forgetting something.
This needs symtab approval, though obviously I'd appreciate it if
Daniel could look it over as well.  Tested on GCC 3.2, DWARF 2,
i686-pc-linux-gnu; no new regressions.  (And I've been using a version
of this for months on my branch, too.)

David Carlton
carlton@bactrian.org

2003-04-23  David Carlton  <carlton@bactrian.org>

	* symtab.h: Declare lookup_symbol_namespace.
	* symtab.c: Include cp-support.h, gdb_assert.h.
	(lookup_symbol_aux): Delete calls to lookup_symbol_aux_minsyms.
	Delete 'static_block' variable.
	Handle static and global search via
	lookup_symbol_aux_namespace_scope.
	(lookup_symbol_aux_local): Delete 'static_block' argument.
	(lookup_symbol_aux_minsyms): Delete lookup by mangled name;
	comment out rest of function.
	(lookup_symbol_aux_namespace_scope): New.
	(lookup_symbol_namespace, lookup_symbol_aux_file): Ditto.
	* block.h: Declare block_scope, block_using, block_static_block.
	* block.c (block_scope): New.
	(block_using, block_static_block): Ditto.
	* Makefile.in (symtab.o): Depend on cp_support_h and gdb_assert.
	* config/djgpp/fnchange.lst: Add namespace1.cc.

2003-04-23  David Carlton  <carlton@bactrian.org>

	* gdb.c++/namespace.exp: Add namespace scope and anonymous
	namespace tests.
	Bump copyright date.
	* gdb.c++/namespace.cc: Add anonymous namespace and namespace C
	and everything within it.
	(main): Call C::D::marker2.
	* gdb.c++/namespace1.cc: New file.

Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.68
diff -u -p -r1.68 symtab.h
--- symtab.h	14 Apr 2003 19:55:27 -0000	1.68
+++ symtab.h	24 Apr 2003 00:46:53 -0000
@@ -1003,6 +1003,15 @@ extern struct symbol *lookup_symbol (con
 				     const namespace_enum, int *,
 				     struct symtab **);
 
+/* Lookup a symbol within a namespace.  */
+
+extern struct symbol *lookup_symbol_namespace (const char *cp_namespace,
+					       const char *name,
+					       const char *linkage_name,
+					       const struct block *block,
+					       namespace_enum gdb_namespace,
+					       struct symtab **symtab);
+
 /* lookup a symbol by name, within a specified block */
 
 extern struct symbol *lookup_block_symbol (const struct block *, const char *,
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.101
diff -u -p -r1.101 symtab.c
--- symtab.c	14 Apr 2003 19:56:32 -0000	1.101
+++ symtab.c	24 Apr 2003 01:07:52 -0000
@@ -52,6 +52,8 @@
 #include "gdb_stat.h"
 #include <ctype.h>
 #include "cp-abi.h"
+#include "cp-support.h"
+#include "gdb_assert.h"
 
 /* Prototypes for local functions */
 
@@ -92,8 +94,7 @@ struct symbol *lookup_symbol_aux_local (
 					const char *mangled_name,
 					const struct block *block,
 					const namespace_enum namespace,
-					struct symtab **symtab,
-					const struct block **static_block);
+					struct symtab **symtab);
 
 static
 struct symbol *lookup_symbol_aux_block (const char *name,
@@ -116,12 +117,30 @@ struct symbol *lookup_symbol_aux_psymtab
 					   const namespace_enum namespace,
 					   struct symtab **symtab);
 
+#if 0
 static
 struct symbol *lookup_symbol_aux_minsyms (const char *name,
 					  const char *mangled_name,
 					  const namespace_enum namespace,
 					  int *is_a_field_of_this,
 					  struct symtab **symtab);
+#endif
+
+static
+struct symbol *lookup_symbol_aux_namespace_scope (const char *name,
+						  const char *linkage_name,
+						  const struct block *block,
+						  namespace_enum namespace,
+						  struct symtab **symtab,
+						  const char *scope,
+						  int scope_len);
+
+static struct symbol *lookup_symbol_aux_file (const char *name,
+					      const char *linkage_name,
+					      const struct block *block,
+					      const namespace_enum namespace,
+					      struct symtab **symtab,
+					      int anonymous_namespace);
 
 static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
 
@@ -943,7 +962,7 @@ lookup_symbol_aux (const char *name, con
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
   sym = lookup_symbol_aux_local (name, mangled_name, block, namespace,
-				 symtab, &static_block);
+				 symtab);
   if (sym != NULL)
     return sym;
 
@@ -1009,65 +1028,12 @@ lookup_symbol_aux (const char *name, con
 	}
     }
 
-  /* If there's a static block to search, search it next.  */
-
-  /* NOTE: carlton/2002-12-05: There is a question as to whether or
-     not it would be appropriate to search the current global block
-     here as well.  (That's what this code used to do before the
-     is_a_field_of_this check was moved up.)  On the one hand, it's
-     redundant with the lookup_symbol_aux_symtabs search that happens
-     next.  On the other hand, if decode_line_1 is passed an argument
-     like filename:var, then the user presumably wants 'var' to be
-     searched for in filename.  On the third hand, there shouldn't be
-     multiple global variables all of which are named 'var', and it's
-     not like decode_line_1 has ever restricted its search to only
-     global variables in a single filename.  All in all, only
-     searching the static block here seems best: it's correct and it's
-     cleanest.  */
-
-  /* NOTE: carlton/2002-12-05: There's also a possible performance
-     issue here: if you usually search for global symbols in the
-     current file, then it would be slightly better to search the
-     current global block before searching all the symtabs.  But there
-     are other factors that have a much greater effect on performance
-     than that one, so I don't think we should worry about that for
-     now.  */
-
-  if (static_block != NULL)
-    {
-      sym = lookup_symbol_aux_block (name, mangled_name, static_block,
-				     namespace, symtab);
-      if (sym != NULL)
-	return sym;
-    }
-
-  /* Now search all global blocks.  Do the symtab's first, then
-     check the psymtab's. If a psymtab indicates the existence
-     of the desired name as a global, then do psymtab-to-symtab
-     conversion on the fly and return the found symbol. */
-
-  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, mangled_name,
-				   namespace, symtab);
-  if (sym != NULL)
-    return sym;
-
-#ifndef HPUXHPPA
-
-  /* Check for the possibility of the symbol being a function or
-     a mangled variable that is stored in one of the minimal symbol tables.
-     Eventually, all global symbols might be resolved in this way.  */
-
-  sym = lookup_symbol_aux_minsyms (name, mangled_name,
-				   namespace, is_a_field_of_this,
-				   symtab);
-  
-  if (sym != NULL)
-    return sym;
-
-#endif
+  /* Now search this block's static block, and all the global blocks.
+     In the C++ case, do lookup in namespace scope.  */
 
-  sym = lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, mangled_name,
-				    namespace, symtab);
+  sym = lookup_symbol_aux_namespace_scope (name, mangled_name, block,
+					   namespace, symtab,
+					   block_scope (block), 0);
   if (sym != NULL)
     return sym;
 
@@ -1087,60 +1053,29 @@ lookup_symbol_aux (const char *name, con
   if (sym != NULL)
     return sym;
 
-#ifdef HPUXHPPA
-
-  /* Check for the possibility of the symbol being a function or
-     a global variable that is stored in one of the minimal symbol tables.
-     The "minimal symbol table" is built from linker-supplied info.
-
-     RT: I moved this check to last, after the complete search of
-     the global (p)symtab's and static (p)symtab's. For HP-generated
-     symbol tables, this check was causing a premature exit from
-     lookup_symbol with NULL return, and thus messing up symbol lookups
-     of things like "c::f". It seems to me a check of the minimal
-     symbol table ought to be a last resort in any case. I'm vaguely
-     worried about the comment below which talks about FORTRAN routines "foo_"
-     though... is it saying we need to do the "minsym" check before
-     the static check in this case? 
-   */
-
-
-  sym = lookup_symbol_aux_minsyms (name, mangled_name,
-				   namespace, is_a_field_of_this,
-				   symtab);
-  
-  if (sym != NULL)
-    return sym;
-
-#endif
-
   if (symtab != NULL)
     *symtab = NULL;
   return NULL;
 }
 
 /* Check to see if the symbol is defined in BLOCK or its superiors.
-   Don't search STATIC_BLOCK or GLOBAL_BLOCK.  If we don't find a
-   match, store the address of STATIC_BLOCK in static_block.  */
+   Don't search STATIC_BLOCK or GLOBAL_BLOCK.  */
 
 static struct symbol *
 lookup_symbol_aux_local (const char *name, const char *mangled_name,
 			 const struct block *block,
 			 const namespace_enum namespace,
-			 struct symtab **symtab,
-			 const struct block **static_block)
+			 struct symtab **symtab)
 {
   struct symbol *sym;
-  
-  /* Check if either no block is specified or it's a global block.  */
+  const struct block *static_block = block_static_block (block);
 
-  if (block == NULL || BLOCK_SUPERBLOCK (block) == NULL)
-    {
-      *static_block = NULL;
-      return NULL;
-    }
+  /* Either no block is specified or it's a global block.  */
+
+  if (static_block == NULL)
+    return NULL;
 
-  while (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) != NULL)
+  while (block != static_block)
     {
       sym = lookup_symbol_aux_block (name, mangled_name, block, namespace,
 				     symtab);
@@ -1149,9 +1084,8 @@ lookup_symbol_aux_local (const char *nam
       block = BLOCK_SUPERBLOCK (block);
     }
 
-  /* We've reached the static block.  */
+  /* We've reached the static block without finding a result.  */
 
-  *static_block = block;
   return NULL;
 }
 
@@ -1290,6 +1224,7 @@ lookup_symbol_aux_psymtabs (int block_in
   return NULL;
 }
 
+#if 0
 /* Check for the possibility of the symbol being a function or a
    mangled variable that is stored in one of the minimal symbol
    tables.  Eventually, all global symbols might be resolved in this
@@ -1303,6 +1238,11 @@ lookup_symbol_aux_psymtabs (int block_in
    some additional conditions held as well, and it caused problems
    with HP-generated symbol tables.  */
 
+/* NOTE: carlton/2003-04-23: This function was once used as part of
+   lookup_symbol.  It is currently unnecessary for correctness
+   reasons, however, and using it doesn't seem to be any faster than
+   using lookup_symbol_aux_psymtabs, so I'm commenting it out.  */
+
 static struct symbol *
 lookup_symbol_aux_minsyms (const char *name,
 			   const char *mangled_name,
@@ -1403,20 +1343,162 @@ lookup_symbol_aux_minsyms (const char *n
 		*symtab = s;
 	      return fixup_symbol_section (sym, s->objfile);
 	    }
-	  else if (MSYMBOL_TYPE (msymbol) != mst_text
-		   && MSYMBOL_TYPE (msymbol) != mst_file_text
-		   && !STREQ (name, DEPRECATED_SYMBOL_NAME (msymbol)))
-	    {
-	      /* This is a mangled variable, look it up by its
-	         mangled name.  */
-	      return lookup_symbol_aux (DEPRECATED_SYMBOL_NAME (msymbol), mangled_name,
-					NULL, namespace, is_a_field_of_this,
-					symtab);
-	    }
 	}
     }
 
   return NULL;
+}
+#endif /* 0 */
+
+/* Lookup NAME at namespace scope (or, in C terms, in static and
+   global variables).  SCOPE is the namespace that the current
+   function is defined within; only consider namespaces whose length
+   is at least SCOPE_LEN.  (This is to make the recursion easier.)  */
+
+static struct symbol *
+lookup_symbol_aux_namespace_scope (const char *name,
+				   const char *linkage_name,
+				   const struct block *block,
+				   namespace_enum namespace,
+				   struct symtab **symtab,
+				   const char *scope,
+				   int scope_len)
+{
+  char *cp_namespace;
+
+  if (scope[scope_len] != '\0')
+    {
+      struct symbol *sym;
+      int new_scope_len = scope_len;
+
+      /* If the current scope is followed by "::", skip past that.  */
+      if (new_scope_len != 0)
+	{
+	  gdb_assert (scope[new_scope_len] == ':');
+	  new_scope_len += 2;
+	}
+      new_scope_len += cp_find_first_component (scope + new_scope_len);
+      sym = lookup_symbol_aux_namespace_scope (name, linkage_name, block,
+					       namespace, symtab,
+					       scope, new_scope_len);
+      if (sym != NULL)
+	return sym;
+    }
+
+  cp_namespace = alloca (scope_len + 1);
+  strncpy (cp_namespace, scope, scope_len);
+  cp_namespace[scope_len] = '\0';
+  return lookup_symbol_namespace (cp_namespace, name, linkage_name,
+				  block, namespace, symtab);
+}
+
+/* Look up NAME in the C++ namespace CP_NAMESPACE, applying the using
+   directives that are active in BLOCK.  Otherwise, arguments are as
+   in lookup_symbol_aux.  */
+
+struct symbol *
+lookup_symbol_namespace (const char *cp_namespace,
+			 const char *name,
+			 const char *linkage_name,
+			 const struct block *block,
+			 namespace_enum gdb_namespace,
+			 struct symtab **symtab)
+{
+  const struct using_direct *current;
+  struct symbol *sym;
+
+  /* First, go through the using directives.  If any of them add new
+     names to the namespace we're searching in, see if we can find a
+     match by applying them.  */
+
+  for (current = block_using (block);
+       current != NULL;
+       current = current->next)
+    {
+      if (strcmp (cp_namespace, current->outer) == 0)
+	{
+	  sym = lookup_symbol_namespace (current->inner,
+					 name,
+					 linkage_name,
+					 block,
+					 gdb_namespace,
+					 symtab);
+	  if (sym != NULL)
+	    return sym;
+	}
+    }
+
+  /* We didn't find anything by applying any of the using directives
+     that are still applicable; so let's see if we've got a match
+     using the current namespace.  */
+  
+  if (cp_namespace[0] == '\0')
+    {
+      return lookup_symbol_aux_file (name, linkage_name, block,
+				     gdb_namespace, symtab,
+				     0);
+    }
+  else
+    {
+      char *concatenated_name
+	= alloca (strlen (cp_namespace) + 2 + strlen (name) + 1);
+      strcpy (concatenated_name, cp_namespace);
+      strcat (concatenated_name, "::");
+      strcat (concatenated_name, name);
+      sym = lookup_symbol_aux_file (concatenated_name, linkage_name,
+				    block, gdb_namespace, symtab,
+				    cp_is_anonymous (cp_namespace));
+      return sym;
+    }
+}
+
+/* Look up NAME in BLOCK's static block and in global blocks.  If
+   ANONYMOUS_NAMESPACE is nonzero, don't look in other files' global
+   blocks, just in the one belonging to this file.  */
+
+static struct symbol *
+lookup_symbol_aux_file (const char *name,
+			const char *linkage_name,
+			const struct block *block,
+			const namespace_enum namespace,
+			struct symtab **symtab,
+			int anonymous_namespace)
+{
+  struct symbol *sym = NULL;
+  const struct block *static_block = block_static_block (block);
+
+  if (static_block != NULL)
+    {
+      sym = lookup_symbol_aux_block (name, linkage_name, static_block,
+				     namespace, symtab);
+      if (sym != NULL)
+	return sym;
+    }
+
+  if (anonymous_namespace)
+    {
+      const struct block *global_block = NULL;
+      if (static_block != NULL)
+	global_block = BLOCK_SUPERBLOCK (static_block);
+      else if (block != NULL)
+	global_block = block;
+      
+      if (global_block != NULL)
+	return lookup_symbol_aux_block (name, linkage_name, global_block,
+					namespace, symtab);
+      else
+	return NULL;
+    }
+  else
+    {
+      sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
+				       namespace, symtab);
+      if (sym != NULL)
+	return sym;
+      else
+	return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name,
+					   namespace, symtab);
+    }
 }
 
 /* Look, in partial_symtab PST, for symbol whose natural name is NAME.
Index: block.h
===================================================================
RCS file: /cvs/src/src/gdb/block.h,v
retrieving revision 1.3
diff -u -p -r1.3 block.h
--- block.h	15 Apr 2003 23:07:11 -0000	1.3
+++ block.h	24 Apr 2003 00:43:48 -0000
@@ -200,11 +200,17 @@ extern struct block *block_for_pc (CORE_
 
 extern struct block *block_for_pc_sect (CORE_ADDR, asection *);
 
+extern const char *block_scope (const struct block *block);
+
 extern void block_set_scope (struct block *block, const char *scope,
 			     struct obstack *obstack);
 
+extern struct using_direct *block_using (const struct block *block);
+
 extern void block_set_using (struct block *block,
 			     struct using_direct *using,
 			     struct obstack *obstack);
+
+extern const struct block *block_static_block (const struct block *block);
 
 #endif /* BLOCK_H */
Index: block.c
===================================================================
RCS file: /cvs/src/src/gdb/block.c,v
retrieving revision 1.3
diff -u -p -r1.3 block.c
--- block.c	15 Apr 2003 23:07:11 -0000	1.3
+++ block.c	24 Apr 2003 00:46:01 -0000
@@ -155,8 +155,25 @@ block_for_pc (register CORE_ADDR pc)
   return block_for_pc_sect (pc, find_pc_mapped_section (pc));
 }
 
-/* Now come some functions designed to deal with C++ namespace
-   issues.  */
+/* Now come some functions designed to deal with C++ namespace issues.
+   The accessors are safe to use even in the non-C++ case.  */
+
+/* This returns the namespace that BLOCK is enclosed in, or "" if it
+   isn't enclosed in a namespace at all.  This travels the chain of
+   superblocks looking for a scope, if necessary.  */
+
+const char *
+block_scope (const struct block *block)
+{
+  for (; block != NULL; block = BLOCK_SUPERBLOCK (block))
+    {
+      if (BLOCK_NAMESPACE (block) != NULL
+	  && BLOCK_NAMESPACE (block)->scope != NULL)
+	return BLOCK_NAMESPACE (block)->scope;
+    }
+
+  return "";
+}
 
 /* Set BLOCK's scope member to SCOPE; if needed, allocate memory via
    OBSTACK.  (It won't make a copy of SCOPE, however, so that already
@@ -171,6 +188,27 @@ block_set_scope (struct block *block, co
   BLOCK_NAMESPACE (block)->scope = scope;
 }
 
+/* This returns the first using directives associated to BLOCK, if
+   any.  */
+
+/* FIXME: carlton/2003-04-23: This uses the fact that we currently
+   only have using directives in static blocks, because we only
+   generate using directives from anonymous namespaces.  Eventually,
+   when we support using directives everywhere, we'll want to replace
+   this by some iterator functions.  */
+
+struct using_direct *
+block_using (const struct block *block)
+{
+  const struct block *static_block = block_static_block (block);
+
+  if (static_block == NULL
+      || BLOCK_NAMESPACE (static_block) == NULL)
+    return NULL;
+  else
+    return BLOCK_NAMESPACE (static_block)->using;
+}
+
 /* Set BLOCK's using member to USING; if needed, allocate memory via
    OBSTACK.  (It won't make a copy of USING, however, so that already
    has to be allocated correctly.)  */
@@ -198,4 +236,19 @@ block_initialize_namespace (struct block
       BLOCK_NAMESPACE (block)->scope = NULL;
       BLOCK_NAMESPACE (block)->using = NULL;
     }
+}
+
+/* Return the static block associated to BLOCK.  Return NULL if block
+   is NULL or if block is a global block.  */
+
+const struct block *
+block_static_block (const struct block *block)
+{
+  if (block == NULL || BLOCK_SUPERBLOCK (block) == NULL)
+    return NULL;
+
+  while (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) != NULL)
+    block = BLOCK_SUPERBLOCK (block);
+
+  return block;
 }
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.365
diff -u -p -r1.365 Makefile.in
--- Makefile.in	21 Apr 2003 16:48:36 -0000	1.365
+++ Makefile.in	24 Apr 2003 00:43:20 -0000
@@ -2275,7 +2275,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h)
 	$(gdbcmd_h) $(call_cmds_h) $(gdb_regex_h) $(expression_h) \
 	$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) \
 	$(filenames_h) $(gdb_obstack_h) $(gdb_string_h) $(gdb_stat_h) \
-	$(cp_abi_h) $(source_h) $(block_h)
+	$(cp_abi_h) $(source_h) $(block_h) $(cp_support_h) $(gdb_assert_h)
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
 	$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
 	$(gdb_wait_h) $(dcache_h) $(regcache_h)
Index: fnchange.lst
===================================================================
RCS file: /cvs/src/src/gdb/config/djgpp/fnchange.lst,v
retrieving revision 1.46
diff -u -p -r1.46 fnchange.lst
--- fnchange.lst	5 Feb 2003 06:41:15 -0000	1.46
+++ fnchange.lst	24 Apr 2003 01:08:12 -0000
@@ -243,6 +243,7 @@
 @V@/gdb/testsuite/gdb.c++/misc.cc @V@/gdb/testsuite/gdb.cxx/misc.cc
 @V@/gdb/testsuite/gdb.c++/misc.exp @V@/gdb/testsuite/gdb.cxx/misc.exp
 @V@/gdb/testsuite/gdb.c++/namespace.cc @V@/gdb/testsuite/gdb.cxx/namespace.cc
+@V@/gdb/testsuite/gdb.c++/namespace1.cc @V@/gdb/testsuite/gdb.cxx/namesp1.cc
 @V@/gdb/testsuite/gdb.c++/namespace.exp @V@/gdb/testsuite/gdb.cxx/namespace.exp
 @V@/gdb/testsuite/gdb.c++/overload.cc @V@/gdb/testsuite/gdb.cxx/overload.cc
 @V@/gdb/testsuite/gdb.c++/overload.exp @V@/gdb/testsuite/gdb.cxx/overload.exp
Index: namespace.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/namespace.exp,v
retrieving revision 1.12
diff -u -p -r1.12 namespace.exp
--- namespace.exp	10 Jan 2002 20:46:16 -0000	1.12
+++ namespace.exp	24 Apr 2003 01:05:04 -0000
@@ -1,4 +1,4 @@
-# Copyright 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+# Copyright 1997, 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -186,3 +186,27 @@ gdb_expect {
    timeout { fail "(timeout) break BBB::Class::xyzq" }
 }
 
+# Test to see if the appropriate namespaces are in scope when trying
+# to print out stuff from within a function defined within a
+# namespace.
+
+if ![runto "C::D::marker2"] then {
+    perror "couldn't run to marker2"
+    continue
+}
+
+gdb_test "print c" "\\$\[0-9\].* = 1"
+gdb_test "print cc" "No symbol \"cc\" in current context."
+gdb_test "print 'C::cc'" "\\$\[0-9\].* = 2"
+gdb_test "print cd" "\\$\[0-9\].* = 3"
+gdb_test "print 'E::cde'" "\\$\[0-9\].* = 5"
+gdb_test "print shadow" "\\$\[0-9\].* = 13"
+
+# Some anonymous namespace tests.
+
+gdb_test "print cX" "\\$\[0-9\].* = 6"
+gdb_test "print 'F::cXf'" "\\$\[0-9\].* = 7"
+gdb_test "print X" "\\$\[0-9\].* = 9"
+gdb_test "print 'G::Xg'" "\\$\[0-9\].* = 10"
+gdb_test "print cXOtherFile" "No symbol \"cXOtherFile\" in current context."
+gdb_test "print XOtherFile" "No symbol \"XOtherFile\" in current context."
Index: namespace.cc
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/namespace.cc,v
retrieving revision 1.1
diff -u -p -r1.1 namespace.cc
--- namespace.cc	12 Jun 2000 01:31:41 -0000	1.1
+++ namespace.cc	24 Apr 2003 01:04:52 -0000
@@ -68,6 +68,70 @@ void marker1(void)
   return;
 }
 
+namespace
+{
+  int X = 9;
+
+  namespace G
+  {
+    int Xg = 10;
+  }
+}
+
+namespace C
+{
+  int c = 1;
+  int shadow = 12;
+
+  namespace
+  {
+    int cX = 6;
+    
+    namespace F
+    {
+      int cXf = 7;
+    }
+  }
+
+  namespace C
+  {
+    int cc = 2;
+  }
+
+  namespace D
+  {
+    int cd = 3;
+    int shadow = 13;
+
+    namespace E
+    {
+      int cde = 5;
+    }
+
+    void marker2 (void)
+    {
+      // NOTE: carlton/2003-04-23: I'm listing the expressions that I
+      // plan to have GDB try to print out, just to make sure that the
+      // compiler and I agree which ones should be legal!  It's easy
+      // to screw up when testing the boundaries of namespace stuff.
+      c;
+      //cc;
+      C::cc;
+      cd;
+      E::cde;
+      shadow;
+      cX;
+      F::cXf;
+      X;
+      G::Xg;
+      //cXOtherFile;
+      //XOtherFile;
+
+      return;
+    }
+
+  }
+}
 
 int main ()
 {
@@ -95,9 +159,5 @@ int main ()
 
   marker1();
   
+  C::D::marker2 ();
 }
-
-  
-
-
-
--- /dev/null	2002-08-30 16:31:37.000000000 -0700
+++ namespace1.cc	2003-04-23 18:04:04.000000000 -0700
@@ -0,0 +1,29 @@
+# Copyright 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+namespace C
+{
+  namespace {
+    int cXOtherFile = 29;
+  };
+}
+
+namespace {
+  int XOtherFile = 317;
+}


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

end of thread, other threads:[~2003-05-20 16:17 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-05-19  9:55 [rfa] teach lookup_symbol about namespace scope Paul Hilfinger
2003-05-19 16:35 ` David Carlton
2003-05-20 11:10   ` Paul Hilfinger
2003-05-20 16:17     ` David Carlton
  -- strict thread matches above, loose matches on Subject: below --
2003-04-24 14:34 David Carlton
2003-04-24 20:14 ` Eli Zaretskii
2003-04-24 20:18 ` Daniel Jacobowitz
2003-04-24 20:44   ` David Carlton
2003-05-16 14:48     ` Elena Zannoni
2003-05-16 17:26       ` David Carlton
2003-05-16 19:49         ` Elena Zannoni
2003-05-16 20:51           ` David Carlton
2003-05-17  0:09             ` Joel Brobecker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox