[RFA] no frame needed when computing address of subprogram

Joel Brobecker brobecker@adacore.com
Wed Jan 2 13:55:00 GMT 2008


> Seems reasonable - but why does it have a block set?

Hmmm, that's an interesting question. ada-exp.y:

    static void
    write_var_from_sym (struct block *orig_left_context,
                        struct block *block,
                        struct symbol *sym)
    {
      if (orig_left_context == NULL && symbol_read_needs_frame (sym))
        {
          if (innermost_block == 0
              || contained_in (block, innermost_block))
            innermost_block = block;
        }

But the interesting part is the part that just follows:

    write_exp_elt_opcode (OP_VAR_VALUE);
    write_exp_elt_block (block);
    write_exp_elt_sym (sym);
    write_exp_elt_opcode (OP_VAR_VALUE);

Whereas, for C, we do:

    /* We want to use the selected frame, not
       another more inner frame which happens to
       be in the same block.  */
    write_exp_elt_block (NULL);

IIRC, this is because we provide in Ada support for specifying
the "context" of an expression. See "12.4.6.3 Additions to Ada":

    B::var means "the variable named var that appears in function or
    file B." When B is a file name, you must typically surround it in
    single quotes.
    
We use this particularly in the context of up-level reference, when
you are inside a nested procedure and trying to print the variable
defined in one of the enclosing scopes. Most of the time, this is
possible by directly using the variable name, but sometimes it's not,
because the variable is actually hidden by another variable of the
same name.

The rule where we set (or not) the block is:

    var_or_type:    NAME        %prec VAR
                                    { $$ = write_var_or_type (NULL, $1); }
            |       block NAME  %prec VAR
                                    { $$ = write_var_or_type ($1, $2); }

Still, your question still stands, who sets the block? I found
inside write_var_or_type the following code:

  if (block == NULL)
    block = expression_context_block;

Which at first sight would seem reasonable.  This code predates me,
so I'm not sure of the consequence of removing it. And there might
be some other places down the road where we actually do the same.
I will investigate more.

I suggest, however, that we still go ahead with the patch I sent,
because it protects all languages.

-- 
Joel



More information about the Gdb-patches mailing list