gdb
authorTom Tromey <tromey@redhat.com>
Thu, 11 Dec 2008 18:30:28 +0000 (18:30 +0000)
committerTom Tromey <tromey@redhat.com>
Thu, 11 Dec 2008 18:30:28 +0000 (18:30 +0000)
PR macros/2564:
* c-exp.y (macro_original_text, expansion_obstack,
expression_macro_scope): New globals.
(scan_macro_expansion): New function.
(scanning_macro_expansion): Likewise.
(finished_macro_expansion): Likewise.
(scan_macro_cleanup): Likewise.
(c_parse): Find macro scope.  Initialize obstack.
* c-lang.h (scan_macro_expansion, scanning_macro_expansion,
finished_macro_expansion, expression_macro_lookup_func,
expression_macro_lookup_baton): Remove.
* c-lang.c (scan_macro_expansion, scanning_macro_expansion,
finished_macro_expansion, expression_macro_lookup_func,
expression_macro_lookup_baton): Remove.
(macro_original_text, macro_expanded_text,
c_preprocess_and_parse): Remove.
(c_language_defn, cplus_language_defn, asm_language_defn,
minimal_language_defn): Use c_parse.
gdb/testsuite
* gdb.base/macscp.exp: Print "address.addr".
* gdb.base/macscp1.c (struct outer): New struct.
(address): New global.

gdb/ChangeLog
gdb/c-exp.y
gdb/c-lang.c
gdb/c-lang.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/macscp.exp
gdb/testsuite/gdb.base/macscp1.c

index 67b6515fd5500fc1874627d42196ed2741383cd7..f157b5a9ed94b26a77039772f728633faa798a86 100644 (file)
@@ -1,3 +1,24 @@
+2008-12-11  Tom Tromey  <tromey@redhat.com>
+
+       PR macros/2564:
+       * c-exp.y (macro_original_text, expansion_obstack,
+       expression_macro_scope): New globals.
+       (scan_macro_expansion): New function.
+       (scanning_macro_expansion): Likewise.
+       (finished_macro_expansion): Likewise.
+       (scan_macro_cleanup): Likewise.
+       (c_parse): Find macro scope.  Initialize obstack.
+       * c-lang.h (scan_macro_expansion, scanning_macro_expansion,
+       finished_macro_expansion, expression_macro_lookup_func,
+       expression_macro_lookup_baton): Remove.
+       * c-lang.c (scan_macro_expansion, scanning_macro_expansion,
+       finished_macro_expansion, expression_macro_lookup_func,
+       expression_macro_lookup_baton): Remove.
+       (macro_original_text, macro_expanded_text,
+       c_preprocess_and_parse): Remove.
+       (c_language_defn, cplus_language_defn, asm_language_defn,
+       minimal_language_defn): Use c_parse.
+
 2008-12-10  Pedro Alves  <pedro@codesourcery.com>
 
        * infcmd.c (until_next_command, finish_backward): Use get_frame_pc
index 153e2be3cf8a188549d81c65452d8e2270209c66..219b00862c12d6d49244b9b99f797d5cc4f3efff 100644 (file)
@@ -54,6 +54,8 @@ Boston, MA 02110-1301, USA.  */
 #include "block.h"
 #include "cp-support.h"
 #include "dfp.h"
+#include "gdb_assert.h"
+#include "macroscope.h"
 
 #define parse_type builtin_type (parse_gdbarch)
 
@@ -1396,6 +1398,85 @@ static const struct token tokentab2[] =
     {">=", GEQ, BINOP_END}
   };
 
+/* When we find that lexptr (the global var defined in parse.c) is
+   pointing at a macro invocation, we expand the invocation, and call
+   scan_macro_expansion to save the old lexptr here and point lexptr
+   into the expanded text.  When we reach the end of that, we call
+   end_macro_expansion to pop back to the value we saved here.  The
+   macro expansion code promises to return only fully-expanded text,
+   so we don't need to "push" more than one level.
+
+   This is disgusting, of course.  It would be cleaner to do all macro
+   expansion beforehand, and then hand that to lexptr.  But we don't
+   really know where the expression ends.  Remember, in a command like
+
+     (gdb) break *ADDRESS if CONDITION
+
+   we evaluate ADDRESS in the scope of the current frame, but we
+   evaluate CONDITION in the scope of the breakpoint's location.  So
+   it's simply wrong to try to macro-expand the whole thing at once.  */
+static char *macro_original_text;
+
+/* We save all intermediate macro expansions on this obstack for the
+   duration of a single parse.  The expansion text may sometimes have
+   to live past the end of the expansion, due to yacc lookahead.
+   Rather than try to be clever about saving the data for a single
+   token, we simply keep it all and delete it after parsing has
+   completed.  */
+static struct obstack expansion_obstack;
+
+static void
+scan_macro_expansion (char *expansion)
+{
+  char *copy;
+
+  /* We'd better not be trying to push the stack twice.  */
+  gdb_assert (! macro_original_text);
+
+  /* Copy to the obstack, and then free the intermediate
+     expansion.  */
+  copy = obstack_copy0 (&expansion_obstack, expansion, strlen (expansion));
+  xfree (expansion);
+
+  /* Save the old lexptr value, so we can return to it when we're done
+     parsing the expanded text.  */
+  macro_original_text = lexptr;
+  lexptr = copy;
+}
+
+
+static int
+scanning_macro_expansion (void)
+{
+  return macro_original_text != 0;
+}
+
+
+static void 
+finished_macro_expansion (void)
+{
+  /* There'd better be something to pop back to.  */
+  gdb_assert (macro_original_text);
+
+  /* Pop back to the original text.  */
+  lexptr = macro_original_text;
+  macro_original_text = 0;
+}
+
+
+static void
+scan_macro_cleanup (void *dummy)
+{
+  if (macro_original_text)
+    finished_macro_expansion ();
+
+  obstack_free (&expansion_obstack, NULL);
+}
+
+
+/* The scope used for macro expansion.  */
+static struct macro_scope *expression_macro_scope;
+
 /* This is set if a NAME token appeared at the very end of the input
    string, with no whitespace separating the name from the EOF.  This
    is used only when parsing to do field name completion.  */
@@ -1431,8 +1512,8 @@ yylex ()
   if (! scanning_macro_expansion ())
     {
       char *expanded = macro_expand_next (&lexptr,
-                                          expression_macro_lookup_func,
-                                          expression_macro_lookup_baton);
+                                          standard_macro_lookup,
+                                          expression_macro_scope);
 
       if (expanded)
         scan_macro_expansion (expanded);
@@ -1903,11 +1984,36 @@ yylex ()
 int
 c_parse (void)
 {
+  int result;
+  struct cleanup *back_to = make_cleanup (free_current_contents,
+                                         &expression_macro_scope);
+
+  /* Set up the scope for macro expansion.  */
+  expression_macro_scope = NULL;
+
+  if (expression_context_block)
+    expression_macro_scope
+      = sal_macro_scope (find_pc_line (expression_context_pc, 0));
+  else
+    expression_macro_scope = default_macro_scope ();
+  if (! expression_macro_scope)
+    expression_macro_scope = user_macro_scope ();
+
+  /* Initialize macro expansion code.  */
+  obstack_init (&expansion_obstack);
+  gdb_assert (! macro_original_text);
+  make_cleanup (scan_macro_cleanup, 0);
+
+  /* Initialize some state used by the lexer.  */
   last_was_structop = 0;
   saw_name_at_eof = 0;
-  return yyparse ();
+
+  result = yyparse ();
+  do_cleanups (back_to);
+  return result;
 }
 
+
 void
 yyerror (msg)
      char *msg;
index 067e42985afa60aa365b5232b35751840854aa5c..dc7b059c82861d42f10fefe68ba54b6fb47b1a87 100644 (file)
@@ -185,111 +185,6 @@ c_printstr (struct ui_file *stream, const gdb_byte *string,
 /* Preprocessing and parsing C and C++ expressions.  */
 
 
-/* When we find that lexptr (the global var defined in parse.c) is
-   pointing at a macro invocation, we expand the invocation, and call
-   scan_macro_expansion to save the old lexptr here and point lexptr
-   into the expanded text.  When we reach the end of that, we call
-   end_macro_expansion to pop back to the value we saved here.  The
-   macro expansion code promises to return only fully-expanded text,
-   so we don't need to "push" more than one level.
-
-   This is disgusting, of course.  It would be cleaner to do all macro
-   expansion beforehand, and then hand that to lexptr.  But we don't
-   really know where the expression ends.  Remember, in a command like
-
-     (gdb) break *ADDRESS if CONDITION
-
-   we evaluate ADDRESS in the scope of the current frame, but we
-   evaluate CONDITION in the scope of the breakpoint's location.  So
-   it's simply wrong to try to macro-expand the whole thing at once.  */
-static char *macro_original_text;
-static char *macro_expanded_text;
-
-
-void
-scan_macro_expansion (char *expansion)
-{
-  /* We'd better not be trying to push the stack twice.  */
-  gdb_assert (! macro_original_text);
-  gdb_assert (! macro_expanded_text);
-
-  /* Save the old lexptr value, so we can return to it when we're done
-     parsing the expanded text.  */
-  macro_original_text = lexptr;
-  lexptr = expansion;
-
-  /* Save the expanded text, so we can free it when we're finished.  */
-  macro_expanded_text = expansion;
-}
-
-
-int
-scanning_macro_expansion (void)
-{
-  return macro_original_text != 0;
-}
-
-
-void 
-finished_macro_expansion (void)
-{
-  /* There'd better be something to pop back to, and we better have
-     saved a pointer to the start of the expanded text.  */
-  gdb_assert (macro_original_text);
-  gdb_assert (macro_expanded_text);
-
-  /* Pop back to the original text.  */
-  lexptr = macro_original_text;
-  macro_original_text = 0;
-
-  /* Free the expanded text.  */
-  xfree (macro_expanded_text);
-  macro_expanded_text = 0;
-}
-
-
-static void
-scan_macro_cleanup (void *dummy)
-{
-  if (macro_original_text)
-    finished_macro_expansion ();
-}
-
-
-/* We set these global variables before calling c_parse, to tell it
-   how it to find macro definitions for the expression at hand.  */
-macro_lookup_ftype *expression_macro_lookup_func;
-void *expression_macro_lookup_baton;
-
-
-static int
-c_preprocess_and_parse (void)
-{
-  /* Set up a lookup function for the macro expander.  */
-  struct macro_scope *scope = 0;
-  struct cleanup *back_to = make_cleanup (free_current_contents, &scope);
-
-  if (expression_context_block)
-    scope = sal_macro_scope (find_pc_line (expression_context_pc, 0));
-  else
-    scope = default_macro_scope ();
-  if (! scope)
-    scope = user_macro_scope ();
-
-  expression_macro_lookup_func = standard_macro_lookup;
-  expression_macro_lookup_baton = (void *) scope;
-
-  gdb_assert (! macro_original_text);
-  make_cleanup (scan_macro_cleanup, 0);
-
-  {
-    int result = c_parse ();
-    do_cleanups (back_to);
-    return result;
-  }
-}
-
-
 \f
 /* Table mapping opcodes into strings for printing operators
    and precedences of the operators.  */
@@ -395,7 +290,7 @@ const struct language_defn c_language_defn =
   array_row_major,
   macro_expansion_c,
   &exp_descriptor_standard,
-  c_preprocess_and_parse,
+  c_parse,
   c_error,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
@@ -513,7 +408,7 @@ const struct language_defn cplus_language_defn =
   array_row_major,
   macro_expansion_c,
   &exp_descriptor_standard,
-  c_preprocess_and_parse,
+  c_parse,
   c_error,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
@@ -550,7 +445,7 @@ const struct language_defn asm_language_defn =
   array_row_major,
   macro_expansion_c,
   &exp_descriptor_standard,
-  c_preprocess_and_parse,
+  c_parse,
   c_error,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
@@ -592,7 +487,7 @@ const struct language_defn minimal_language_defn =
   array_row_major,
   macro_expansion_c,
   &exp_descriptor_standard,
-  c_preprocess_and_parse,
+  c_parse,
   c_error,
   null_post_parser,
   c_printchar,                 /* Print a character constant */
index cc9abde19d5c12f51ee25680fa11eabfcd7901b6..a8c95f93ab55df8e21e45553f3072815f229ab76 100644 (file)
@@ -55,13 +55,6 @@ extern void c_printstr (struct ui_file * stream, const gdb_byte *string,
                        int force_ellipses,
                        const struct value_print_options *options);
 
-extern void scan_macro_expansion (char *expansion);
-extern int scanning_macro_expansion (void);
-extern void finished_macro_expansion (void);
-
-extern macro_lookup_ftype *expression_macro_lookup_func;
-extern void *expression_macro_lookup_baton;
-
 extern void c_language_arch_info (struct gdbarch *gdbarch,
                                  struct language_arch_info *lai);
 
index 88cbff8b6bf1c50f44ad8ff1c176655c3ae631bb..cc5e3655bce810e3e2fa8d4e619c28bd6a926873 100644 (file)
@@ -1,3 +1,9 @@
+2008-12-11  Tom Tromey  <tromey@redhat.com>
+
+       * gdb.base/macscp.exp: Print "address.addr".
+       * gdb.base/macscp1.c (struct outer): New struct.
+       (address): New global.
+
 2008-12-09  Tom Tromey  <tromey@redhat.com>
 
        * gdb.base/commands.exp (redefine_backtrace_test): New proc.
index 9cb9ef5d9c4fb4d2f58848ee7bedfd6529bf1a9d..f7553a5c986c0c588228a0ac53936a0868988a34 100644 (file)
@@ -415,6 +415,10 @@ gdb_test "break [gdb_get_line_number "set breakpoint here"]" \
 
 gdb_test "continue" "foo = 0;.*" "continue to macsp_expr"
 
+gdb_test "print address.addr" \
+  " = 0" \
+  "print address.addr"
+
 gdb_test "print MACRO_TO_EXPAND" \
     "No symbol \"MACRO_TO_EXPAND\" in current context\." \
     "print expression with macro before define."
index 40f1217b2d615dae11d70123627015bab1993ae2..e754b2684d37b488f2b746d34cdc6313c6f24921 100644 (file)
 #define FORTY_EIGHT 48
 #undef  FORTY_EIGHT
 
+struct outer
+{
+  struct fields
+  {
+    struct fault
+    {
+      int addr;
+    } fault;
+  } fields;
+};
+struct outer address;
+
+#define addr fields.fault.addr
+
 /* A macro named UNTIL_<func> is #defined until just before the
    definition of the function <func>.