]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/
authorJan Kratochvil <jan.kratochvil@redhat.com>
Sun, 9 Oct 2011 19:41:17 +0000 (19:41 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Sun, 9 Oct 2011 19:41:17 +0000 (19:41 +0000)
Support @entry in input expressions.
* c-exp.y (ENTRY, unknown_cpp_name): New.
(exp: UNKNOWN_CPP_NAME): Change to `exp: unknown_cpp_name'.
(unknown_cpp_name: UNKNOWN_CPP_NAME, unknown_cpp_name: ENTRY)
(variable: name_not_typename '@' ENTRY, name: ENTRY)
(name_not_typename: ENTRY): New.
(yylex): Recognize ENTRY.
* eval.c (evaluate_subexp_standard): Support also OP_VAR_ENTRY_VALUE.
* expprint.c (print_subexp_standard, dump_subexp_body_standard):
Likewise.
* parse.c (operator_length_standard): Likewise.
* std-operator.def: New operator OP_VAR_ENTRY_VALUE.

gdb/doc/
Support @entry in input expressions.
* gdb.texinfo (Variables): Describe @entry names suffix.
(Print Settings): Add anchor for `set print entry-values'.

gdb/testsuite/
Support @entry in input expressions.
* gdb.arch/amd64-entry-value.exp (entry: p i@entry, entry: p j@entry)
(entry_stack: p s1@entry, entry_stack: p s2@entry)
(entry_stack: p d9@entry, entry_stack: p da@entry, tailcall: p i@entry)
(tailcall: p j@entry): New tests.
* gdb.cp/koenig.cc (A::entry): New function.
(main): Call it.
* gdb.cp/koenig.exp (p entry (c)): New test.

12 files changed:
gdb/ChangeLog
gdb/c-exp.y
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/eval.c
gdb/expprint.c
gdb/parse.c
gdb/std-operator.def
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.arch/amd64-entry-value.exp
gdb/testsuite/gdb.cp/koenig.cc
gdb/testsuite/gdb.cp/koenig.exp

index 63e37e2c283134c539cabd1a5a83986e5c4d97c8..5d1339e3d807348083efbf032b17396870dfcdc9 100644 (file)
@@ -1,3 +1,18 @@
+2011-10-09  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Support @entry in input expressions.
+       * c-exp.y (ENTRY, unknown_cpp_name): New.
+       (exp: UNKNOWN_CPP_NAME): Change to `exp: unknown_cpp_name'.
+       (unknown_cpp_name: UNKNOWN_CPP_NAME, unknown_cpp_name: ENTRY)
+       (variable: name_not_typename '@' ENTRY, name: ENTRY)
+       (name_not_typename: ENTRY): New.
+       (yylex): Recognize ENTRY.
+       * eval.c (evaluate_subexp_standard): Support also OP_VAR_ENTRY_VALUE.
+       * expprint.c (print_subexp_standard, dump_subexp_body_standard):
+       Likewise.
+       * parse.c (operator_length_standard): Likewise.
+       * std-operator.def: New operator OP_VAR_ENTRY_VALUE.
+
 2011-10-09  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        Display referenced values in backtraces.
index 94d0737073864d268a0acbcee176bbf21b9a9a6b..5cc1e9614e9305fab87fe2baa73a38ff4bbdb545 100644 (file)
@@ -186,6 +186,7 @@ static struct stoken operator_stoken (const char *);
 %token <tsval> STRING
 %token <tsval> CHAR
 %token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
+%token <ssym> ENTRY
 %token <ssym> UNKNOWN_CPP_NAME
 %token <voidval> COMPLETE
 %token <tsym> TYPENAME
@@ -194,6 +195,9 @@ static struct stoken operator_stoken (const char *);
 %type <ssym> name_not_typename
 %type <tsym> typename
 
+/* It is UNKNOWN_CPP_NAME or ENTRY, depending on the context.  */
+%type <ssym> unknown_cpp_name
+
 /* A NAME_OR_INT is a symbol which is not known in the symbol table,
    but which would parse as a valid number in the current input radix.
    E.g. "c" when input_radix==16.  Depending on the parse, it will be
@@ -392,7 +396,7 @@ exp :       exp '('
                          write_exp_elt_opcode (OP_FUNCALL); }
        ;
 
-exp    :       UNKNOWN_CPP_NAME '('
+exp    :       unknown_cpp_name '('
                        {
                          /* This could potentially be a an argument defined
                             lookup function (Koenig).  */
@@ -415,6 +419,10 @@ exp        :       UNKNOWN_CPP_NAME '('
                        }
        ;
 
+unknown_cpp_name       : UNKNOWN_CPP_NAME
+                       | ENTRY
+                       ;
+
 lcurly :       '{'
                        { start_arglist (); }
        ;
@@ -756,6 +764,21 @@ block      :       block COLONCOLON name
                          $$ = SYMBOL_BLOCK_VALUE (tem); }
        ;
 
+variable:      name_not_typename '@' ENTRY
+                       { struct symbol *sym = $1.sym;
+
+                         if (sym == NULL || !SYMBOL_IS_ARGUMENT (sym)
+                             || !symbol_read_needs_frame (sym))
+                           error (_("@entry can be used only for function "
+                                    "parameters, not for \"%s\""),
+                                  copy_name ($1.stoken));
+
+                         write_exp_elt_opcode (OP_VAR_ENTRY_VALUE);
+                         write_exp_elt_sym (sym);
+                         write_exp_elt_opcode (OP_VAR_ENTRY_VALUE);
+                       }
+       ;
+
 variable:      block COLONCOLON name
                        { struct symbol *sym;
                          sym = lookup_symbol (copy_name ($3), $1,
@@ -1317,11 +1340,13 @@ name    :       NAME { $$ = $1.stoken; }
        |       TYPENAME { $$ = $1.stoken; }
        |       NAME_OR_INT  { $$ = $1.stoken; }
        |       UNKNOWN_CPP_NAME  { $$ = $1.stoken; }
+       |       ENTRY { $$ = $1.stoken; }
        |       operator { $$ = $1; }
        ;
 
 name_not_typename :    NAME
        |       BLOCKNAME
+       |       ENTRY
 /* These would be useful if name_not_typename was useful, but it is just
    a fake for "variable", so these cause reduce/reduce conflicts because
    the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable,
@@ -2525,6 +2550,11 @@ yylex (void)
   current.token = lex_one_token ();
   if (current.token == NAME)
     current.token = classify_name (expression_context_block);
+  if ((current.token == NAME || current.token == UNKNOWN_CPP_NAME)
+      && yylval.sval.length == strlen ("entry")
+      && strncmp (yylval.sval.ptr, "entry", strlen ("entry")) == 0)
+    current.token = ENTRY;
+
   if (parse_language->la_language != language_cplus
       || (current.token != TYPENAME && current.token != COLONCOLON))
     return current.token;
index 7763cce50603f7ff73358dcab8226215c4518558..808cf212b76665a9b45f66fb5884d74b11ff3078 100644 (file)
@@ -1,3 +1,9 @@
+2011-10-09  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Support @entry in input expressions.
+       * gdb.texinfo (Variables): Describe @entry names suffix.
+       (Print Settings): Add anchor for `set print entry-values'.
+
 2011-10-09  Jan Kratochvil  <jan.kratochvil@redhat.com>
            Eli Zaretskii  <eliz@gnu.org>
 
index 9de96c1c9aea89ba607c6cb86df8c7e14a767572..1ea2ba39fb0aa0f806af5d2c8d76e68c7ec92b42 100644 (file)
@@ -7277,6 +7277,23 @@ If you ask to print an object whose contents are unknown to
 by the debug information, @value{GDBN} will say @samp{<incomplete
 type>}.  @xref{Symbols, incomplete type}, for more about this.
 
+If you append @kbd{@@entry} string to a function parameter name you get its
+value at the time the function got called.  If the value is not available an
+error message is printed.  Entry values are available only with some compilers.
+Entry values are normally also printed at the function parameter list according
+to @ref{set print entry-values}.
+
+@smallexample
+Breakpoint 1, d (i=30) at gdb.base/entry-value.c:29
+29       i++;
+(gdb) next
+30       e (i);
+(gdb) print i
+$1 = 31
+(gdb) print i@@entry
+$2 = 30
+@end smallexample
+
 Strings are identified as arrays of @code{char} values without specified
 signedness.  Arrays of either @code{signed char} or @code{unsigned char} get
 printed as arrays of 1 byte sized integers.  @code{-fsigned-char} or
@@ -7941,6 +7958,7 @@ thus speeding up the display of each Ada frame.
 @item show print frame-arguments
 Show how the value of arguments should be displayed when printing a frame.
 
+@anchor{set print entry-values}
 @item set print entry-values @var{value}
 @kindex set print entry-values
 Set printing of frame argument values at function entry.  In some cases
index af225c4670ae6339c34fab85315540eda39e3b6e..09564498975f770cd0d7f88a550853d1471378fa 100644 (file)
@@ -860,6 +860,27 @@ evaluate_subexp_standard (struct type *expect_type,
        return ret;
       }
 
+    case OP_VAR_ENTRY_VALUE:
+      (*pos) += 2;
+      if (noside == EVAL_SKIP)
+       goto nosideret;
+
+      {
+       struct symbol *sym = exp->elts[pc + 1].symbol;
+       struct frame_info *frame;
+
+       if (noside == EVAL_AVOID_SIDE_EFFECTS)
+         return value_zero (SYMBOL_TYPE (sym), not_lval);
+
+       if (SYMBOL_CLASS (sym) != LOC_COMPUTED
+           || SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry == NULL)
+         error (_("Symbol \"%s\" does not have any specific entry value"),
+                SYMBOL_PRINT_NAME (sym));
+
+       frame = get_selected_frame (NULL);
+       return SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry (sym, frame);
+      }
+
     case OP_LAST:
       (*pos) += 2;
       return
index 2b6e4160676f9a0c89e86b76633557d372504327..0e0f1c3703466b672026847186581b5f26d1b3a4 100644 (file)
@@ -135,6 +135,16 @@ print_subexp_standard (struct expression *exp, int *pos,
       }
       return;
 
+    case OP_VAR_ENTRY_VALUE:
+      {
+       struct block *b;
+
+       (*pos) += 2;
+       fprintf_filtered (stream, "%s@entry",
+                         SYMBOL_PRINT_NAME (exp->elts[pc + 1].symbol));
+      }
+      return;
+
     case OP_LAST:
       (*pos) += 2;
       fprintf_filtered (stream, "$%d",
@@ -853,6 +863,13 @@ dump_subexp_body_standard (struct expression *exp,
                        SYMBOL_PRINT_NAME (exp->elts[elt + 1].symbol));
       elt += 3;
       break;
+    case OP_VAR_ENTRY_VALUE:
+      fprintf_filtered (stream, "Entry value of symbol @");
+      gdb_print_host_address (exp->elts[elt].symbol, stream);
+      fprintf_filtered (stream, " (%s)",
+                       SYMBOL_PRINT_NAME (exp->elts[elt].symbol));
+      elt += 2;
+      break;
     case OP_LAST:
       fprintf_filtered (stream, "History element %ld",
                        (long) exp->elts[elt].longconst);
index bb6e0e656aa47af17ee6c7b1a94ce38cca66182d..7d157fe99b3a04bada075133593811bd8e4d8055 100644 (file)
@@ -853,6 +853,7 @@ operator_length_standard (const struct expression *expr, int endpos,
     case OP_BOOL:
     case OP_LAST:
     case OP_INTERNALVAR:
+    case OP_VAR_ENTRY_VALUE:
       oplen = 3;
       break;
 
index 2c771415b787e6c563152afdcbde53b5f5c672c0..3b6b0ae6050420aca698fbb6c54b5a191a7a7ca8 100644 (file)
@@ -139,6 +139,12 @@ OP (OP_DOUBLE)
    use the selected frame.  */
 OP (OP_VAR_VALUE)
 
+/* OP_VAR_ENTRY_VALUE takes one struct symbol * in the following element,
+   followed by another OP_VAR_ENTRY_VALUE, making three exp_elements.
+   somename@entry may mean parameter value as present at the entry of the
+   current function.  Implemented via DW_OP_GNU_entry_value.  */
+OP (OP_VAR_ENTRY_VALUE)
+
 /* OP_LAST is followed by an integer in the next exp_element.
    The integer is zero for the last value printed,
    or it is the absolute number of a history element.
index 74826cfbb483b5a0e57b5a30d9a13df3535aa2e9..e3df529a845e3bef28ea906cb1e696aa3f505ec3 100644 (file)
@@ -1,3 +1,14 @@
+2011-10-09  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Support @entry in input expressions.
+       * gdb.arch/amd64-entry-value.exp (entry: p i@entry, entry: p j@entry)
+       (entry_stack: p s1@entry, entry_stack: p s2@entry)
+       (entry_stack: p d9@entry, entry_stack: p da@entry, tailcall: p i@entry)
+       (tailcall: p j@entry): New tests.
+       * gdb.cp/koenig.cc (A::entry): New function.
+       (main): Call it.
+       * gdb.cp/koenig.exp (p entry (c)): New test.
+
 2011-10-09  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        Display @entry parameter values (without references).
index fcccdd8701de17b7a791b68ec73b956eccad1faf..10a82ab682081162adc3835d5e050aca01122f74 100644 (file)
@@ -51,7 +51,9 @@ gdb_continue_to_breakpoint "entry: breakhere"
 gdb_test "bt" "^bt\r\n#0 +d *\\(i=31, i@entry=30, j=31\\.5, j@entry=30\\.5\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in main .*" \
         "entry: bt"
 gdb_test "p i" " = 31" "entry: p i"
+gdb_test "p i@entry" " = 30" "entry: p i@entry"
 gdb_test "p j" { = 31\.5} "entry: p j"
+gdb_test "p j@entry" { = 30\.5} "entry: p j@entry"
 
 
 # Test @entry values when parameter in function is locexpr (and not loclist).
@@ -76,9 +78,13 @@ gdb_test "bt" "^bt\r\n#0 +stacktest *\\(r1=r1@entry=1, r2=r2@entry=2, \[^\r\n\]+
         "entry_stack: bt"
 
 gdb_test "p s1" " = 3" "entry_stack: p s1"
+gdb_test "p s1@entry" " = 11" "entry_stack: p s1@entry"
 gdb_test "p s2" " = 4" "entry_stack: p s2"
+gdb_test "p s2@entry" " = 12" "entry_stack: p s2@entry"
 gdb_test "p d9" " = 3\\.5" "entry_stack: p d9"
+gdb_test "p d9@entry" " = 11\\.5" "entry_stack: p d9@entry"
 gdb_test "p da" " = 4\\.5" "entry_stack: p da"
+gdb_test "p da@entry" " = 12\\.5" "entry_stack: p da@entry"
 
 
 # Test various kinds of `set print entry-values'.
@@ -159,7 +165,9 @@ gdb_continue_to_breakpoint "tailcall: breakhere"
 gdb_test "bt" "^bt\r\n#0 +d *\\(i=71, i@entry=70, j=73\\.5, j@entry=72\\.5\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in c \\(i=i@entry=7, j=j@entry=7\\.25\\) \[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in b \\(i=i@entry=5, j=j@entry=5\\.25\\) \[^\r\n\]*\r\n#3 +0x\[0-9a-f\]+ in main \[^\r\n\]*" \
         "tailcall: bt"
 gdb_test "p i" " = 71" "tailcall: p i"
+gdb_test "p i@entry" " = 70" "tailcall: p i@entry"
 gdb_test "p j" " = 73\\.5" "tailcall: p j"
+gdb_test "p j@entry" " = 72\\.5" "tailcall: p j@entry"
 
 # Test $sp simulation for tail call frames.
 #gdb_test {p/x $sp} " = 0x.*"
index e2190f1c6c779377e678d4b632f278946b9e3a50..01e2637cfbd7d92896697eb5cecc1fd3ac56034e 100644 (file)
@@ -24,6 +24,11 @@ namespace A
     return 33;
   }
 
+  int
+  entry (C c)
+  {
+    return 44;
+  }
 }
 
 struct B
@@ -245,6 +250,7 @@ main ()
   A::first (c);
   first (0, c);
   second (0, 0, c, 0, 0);
+  entry (c);
   A::first (b.c);
 
   E::O eo;
index 7d5e5ab74fe5593e8c233ac3651bf10de9b63d2e..6ee35622169691006c85cdee82d34cdb19737acf 100644 (file)
@@ -33,6 +33,9 @@ gdb_test "p first(c)" "= 11"
 # the qualifying parameter
 gdb_test "p second(0,0,c,0,0)" "= 33"
 
+# Test the name "entry" being used for `variablename@entry' entry values.
+gdb_test "p entry (c)" " = 44"
+
 # Test that koenig lookup finds correct function
 # even if it is overloaded
 gdb_test "p first(0,c)" "= 22"