PR macros/13205:
authorTom Tromey <tromey@redhat.com>
Wed, 16 May 2012 20:31:10 +0000 (20:31 +0000)
committerTom Tromey <tromey@redhat.com>
Wed, 16 May 2012 20:31:10 +0000 (20:31 +0000)
* macrotab.h: (macro_define_special): Declare.
(enum macro_special_kind): New.
(struct macro_definition) <argc, replacement>: Update comments.
* macrotab.c (new_macro_definition): Unconditionally set 'argc'.
(macro_define_object_internal): New function.
(macro_define_object): Use it.
(macro_define_special): New function.
(fixup_definition): New function.
(macro_lookup_definition, foreach_macro_in_scope)
(foreach_macro): Use fixup_definition.
* macroexp.h (macro_stringify): Declare.
* macroexp.c (free_buffer_return_text): New function.
(stringify): Constify "arg".
(macro_stringify): New function.
* dwarf2read.c (macro_start_file): Call macro_define_special.
testsuite
* gdb.base/macscp1.c (macscp_expr): Add comment.
* gdb.base/macscp.exp: Test __FILE__ and __LINE__.

gdb/ChangeLog
gdb/dwarf2read.c
gdb/macroexp.c
gdb/macroexp.h
gdb/macrotab.c
gdb/macrotab.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/macscp.exp
gdb/testsuite/gdb.base/macscp1.c

index 0a3557265610422f79a8b6e0c10db1981abc17bc..c0d6ab96219d3f8b133b02fdc3345922d81dc95f 100644 (file)
@@ -1,3 +1,22 @@
+2012-05-16  Tom Tromey  <tromey@redhat.com>
+
+       PR macros/13205:
+       * macrotab.h: (macro_define_special): Declare.
+       (enum macro_special_kind): New.
+       (struct macro_definition) <argc, replacement>: Update comments.
+       * macrotab.c (new_macro_definition): Unconditionally set 'argc'.
+       (macro_define_object_internal): New function.
+       (macro_define_object): Use it.
+       (macro_define_special): New function.
+       (fixup_definition): New function.
+       (macro_lookup_definition, foreach_macro_in_scope)
+       (foreach_macro): Use fixup_definition.
+       * macroexp.h (macro_stringify): Declare.
+       * macroexp.c (free_buffer_return_text): New function.
+       (stringify): Constify "arg".
+       (macro_stringify): New function.
+       * dwarf2read.c (macro_start_file): Call macro_define_special.
+
 2012-05-16  Maciej W. Rozycki  <macro@codesourcery.com>
             Maciej W. Rozycki  <macro@mips.com>
 
index f06dea68e690f8092f07b7566a9d6a9f30c49d24..f89742b180a01f3516d059de0749d5b6d8ec8d6c 100644 (file)
@@ -15572,9 +15572,12 @@ macro_start_file (int file, int line,
                                       objfile->macro_cache);
 
   if (! current_file)
-    /* If we have no current file, then this must be the start_file
-       directive for the compilation unit's main source file.  */
-    current_file = macro_set_main (pending_macros, full_name);
+    {
+      /* If we have no current file, then this must be the start_file
+        directive for the compilation unit's main source file.  */
+      current_file = macro_set_main (pending_macros, full_name);
+      macro_define_special (pending_macros);
+    }
   else
     current_file = macro_include (current_file, line, full_name);
 
index d5e4e40326301b36fb1d4cfd2cc602c08d0933f5..22b904e624950ed35b97215072553fdd95f3236c 100644 (file)
@@ -113,6 +113,17 @@ free_buffer (struct macro_buffer *b)
     xfree (b->text);
 }
 
+/* Like free_buffer, but return the text as an xstrdup()d string.
+   This only exists to try to make the API relatively clean.  */
+
+static char *
+free_buffer_return_text (struct macro_buffer *b)
+{
+  gdb_assert (! b->shared);
+  gdb_assert (b->size);
+  /* Nothing to do.  */
+  return b->text;
+}
 
 /* A cleanup function for macro buffers.  */
 static void
@@ -639,7 +650,7 @@ append_tokens_without_splicing (struct macro_buffer *dest,
    stringify; it is LEN bytes long.  */
 
 static void
-stringify (struct macro_buffer *dest, char *arg, int len)
+stringify (struct macro_buffer *dest, const char *arg, int len)
 {
   /* Trim initial whitespace from ARG.  */
   while (len > 0 && macro_is_whitespace (*arg))
@@ -682,6 +693,21 @@ stringify (struct macro_buffer *dest, char *arg, int len)
   dest->last_token = dest->len;
 }
 
+/* See macroexp.h.  */
+
+char *
+macro_stringify (const char *str)
+{
+  struct macro_buffer buffer;
+  int len = strlen (str);
+  char *result;
+
+  init_buffer (&buffer, len);
+  stringify (&buffer, str, len);
+
+  return free_buffer_return_text (&buffer);
+}
+
 \f
 /* Expanding macros!  */
 
index 289619eba953b974ca435cf7e77bf7a98499a2d0..dba03f6722490c5d740dadf30e3a94f7791fd9a6 100644 (file)
@@ -91,4 +91,9 @@ int macro_is_identifier_nondigit (int c);
 int macro_is_digit (int c);
 
 
+/* Stringify STR according to C rules and return an xmalloc'd pointer
+   to the result.  */
+
+char *macro_stringify (const char *str);
+
 #endif /* MACROEXP_H */
index 74288398898ef21a4fba526ba2c6a4c191f14cf2..e65e5dc842525c081bd327dfa61c82d88daaf4a2 100644 (file)
@@ -28,6 +28,7 @@
 #include "gdb_assert.h"
 #include "bcache.h"
 #include "complaints.h"
+#include "macroexp.h"
 
 \f
 /* The macro table structure.  */
@@ -565,6 +566,7 @@ new_macro_definition (struct macro_table *t,
   d->table = t;
   d->kind = kind;
   d->replacement = macro_bcache_str (t, replacement);
+  d->argc = argc;
 
   if (kind == macro_function_like)
     {
@@ -579,7 +581,6 @@ new_macro_definition (struct macro_table *t,
 
       /* Now bcache the array of argument pointers itself.  */
       d->argv = macro_bcache (t, cached_argv, cached_argv_size);
-      d->argc = argc;
     }
 
   /* We don't bcache the entire definition structure because it's got
@@ -742,10 +743,12 @@ check_for_redefinition (struct macro_source_file *source, int line,
     return 0;
 }
 
+/* A helper function to define a new object-like macro.  */
 
-void
-macro_define_object (struct macro_source_file *source, int line,
-                     const char *name, const char *replacement)
+static void
+macro_define_object_internal (struct macro_source_file *source, int line,
+                             const char *name, const char *replacement,
+                             enum macro_special_kind kind)
 {
   struct macro_table *t = source->table;
   struct macro_key *k = NULL;
@@ -771,10 +774,28 @@ macro_define_object (struct macro_source_file *source, int line,
     return;
 
   k = new_macro_key (t, name, source, line);
-  d = new_macro_definition (t, macro_object_like, 0, 0, replacement);
+  d = new_macro_definition (t, macro_object_like, kind, 0, replacement);
   splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d);
 }
 
+void
+macro_define_object (struct macro_source_file *source, int line,
+                    const char *name, const char *replacement)
+{
+  macro_define_object_internal (source, line, name, replacement,
+                               macro_ordinary);
+}
+
+/* See macrotab.h.  */
+
+void
+macro_define_special (struct macro_table *table)
+{
+  macro_define_object_internal (table->main_source, -1, "__FILE__", "",
+                               macro_FILE);
+  macro_define_object_internal (table->main_source, -1, "__LINE__", "",
+                               macro_LINE);
+}
 
 void
 macro_define_function (struct macro_source_file *source, int line,
@@ -859,6 +880,36 @@ macro_undef (struct macro_source_file *source, int line,
     }
 }
 
+/* A helper function that rewrites the definition of a special macro,
+   when needed.  */
+
+static struct macro_definition *
+fixup_definition (const char *filename, int line, struct macro_definition *def)
+{
+  static char *saved_expansion;
+
+  if (saved_expansion)
+    {
+      xfree (saved_expansion);
+      saved_expansion = NULL;
+    }
+
+  if (def->kind == macro_object_like)
+    {
+      if (def->argc == macro_FILE)
+       {
+         saved_expansion = macro_stringify (filename);
+         def->replacement = saved_expansion;
+       }
+      else if (def->argc == macro_LINE)
+       {
+         saved_expansion = xstrprintf ("%d", line);
+         def->replacement = saved_expansion;
+       }
+    }
+
+  return def;
+}
 
 struct macro_definition *
 macro_lookup_definition (struct macro_source_file *source,
@@ -867,7 +918,8 @@ macro_lookup_definition (struct macro_source_file *source,
   splay_tree_node n = find_definition (name, source, line);
 
   if (n)
-    return (struct macro_definition *) n->value;
+    return fixup_definition (source->filename, line,
+                            (struct macro_definition *) n->value);
   else
     return 0;
 }
@@ -910,7 +962,9 @@ foreach_macro (splay_tree_node node, void *arg)
 {
   struct macro_for_each_data *datum = (struct macro_for_each_data *) arg;
   struct macro_key *key = (struct macro_key *) node->key;
-  struct macro_definition *def = (struct macro_definition *) node->value;
+  struct macro_definition *def
+    = fixup_definition (key->start_file->filename, key->start_line,
+                       (struct macro_definition *) node->value);
 
   (*datum->fn) (key->name, def, key->start_file, key->start_line,
                datum->user_data);
@@ -936,7 +990,9 @@ foreach_macro_in_scope (splay_tree_node node, void *info)
 {
   struct macro_for_each_data *datum = (struct macro_for_each_data *) info;
   struct macro_key *key = (struct macro_key *) node->key;
-  struct macro_definition *def = (struct macro_definition *) node->value;
+  struct macro_definition *def
+    = fixup_definition (datum->file->filename, datum->line,
+                       (struct macro_definition *) node->value);
 
   /* See if this macro is defined before the passed-in line, and
      extends past that line.  */
index 8316cc375d61a8f34fca15d94734c6bb9888675e..92f165611dea51843a5500734d13fc39e1baaaeb 100644 (file)
@@ -212,6 +212,10 @@ struct macro_source_file *macro_include (struct macro_source_file *source,
                                          int line,
                                          const char *included);
 
+/* Define any special macros, like __FILE__ or __LINE__.  This should
+   be called once, on the main source file.  */
+
+void macro_define_special (struct macro_table *table);
 
 /* Find any source file structure for a file named NAME, either
    included into SOURCE, or SOURCE itself.  Return zero if we have
@@ -261,6 +265,17 @@ enum macro_kind
   macro_function_like
 };
 
+/* Different kinds of special macros.  */
+
+enum macro_special_kind
+{
+  /* Ordinary.  */
+  macro_ordinary,
+  /* The special macro __FILE__.  */
+  macro_FILE,
+  /* The special macro __LINE__.  */
+  macro_LINE
+};
 
 /* A preprocessor symbol definition.  */
 struct macro_definition
@@ -273,12 +288,17 @@ struct macro_definition
 
   /* If `kind' is `macro_function_like', the number of arguments it
      takes, and their names.  The names, and the array of pointers to
-     them, are in the table's bcache, if it has one.  */
-  int argc : 31;
+     them, are in the table's bcache, if it has one.  If `kind' is
+     `macro_object_like', then this is actually a `macro_special_kind'
+     describing the macro.  */
+  int argc : 30;
   const char * const *argv;
 
-  /* The replacement string (body) of the macro.  This is in the
-     table's bcache, if it has one.  */
+  /* The replacement string (body) of the macro.  For ordinary macros,
+     this is in the table's bcache, if it has one.  For special macros
+     like __FILE__, this value is only valid until the next use of any
+     special macro definition; that is, it is reset each time any
+     special macro is looked up or iterated over.  */
   const char *replacement;
 };
 
index 93e0a0dd5a737a6a125937da72368cad74dd3fdc..236007d30130f318a76f5b989c2e69ceb119f884 100644 (file)
@@ -1,3 +1,8 @@
+2012-05-16  Tom Tromey  <tromey@redhat.com>
+
+       * gdb.base/macscp1.c (macscp_expr): Add comment.
+       * gdb.base/macscp.exp: Test __FILE__ and __LINE__.
+
 2012-05-16  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * gdb.base/return-nodebug.exp: Also test float and double types.
index fa2173a417ec031bd4a950a4b695098bc1934035..44a526b4fe4eb38a950b7ac599612786bae7a1ea 100644 (file)
@@ -227,6 +227,10 @@ list_and_check_macro macscp3_2 WHERE {macscp3.h macscp1.c {before macscp3_2}}
 gdb_test "info macro FROM_COMMANDLINE" \
         "Defined at \[^\r\n\]*:0\r\n-DFROM_COMMANDLINE=ARG"
 
+gdb_test "info macro __FILE__" "#define __FILE__ \".*macscp3.h\"" \
+    "info macro __FILE__ before running"
+gdb_test "info macro __LINE__" "#define __LINE__ 26" \
+    "info macro __LINE__ before running"
 
 # Although GDB's macro table structures distinguish between multiple
 # #inclusions of the same file, GDB's other structures don't.  So the
@@ -466,7 +470,7 @@ gdb_test "print MACRO_TO_EXPAND" \
     " = 0" \
     "print expression with macro after removing override"
 
-gdb_test "next" "foo = 2;" "next to definition 2"
+gdb_test "next" "foo = 2;.*" "next to definition 2"
 
 gdb_test "print MACRO_TO_EXPAND" \
     "No symbol \"MACRO_TO_EXPAND\" in current context\." \
@@ -673,3 +677,7 @@ gdb_test_no_output "macro define si_addr fields.fault.si_addr" \
 gdb_test "macro expand siginfo.si_addr" \
   "expands to: siginfo.fields.fault.si_addr" \
   "macro expand siginfo.si_addr"
+
+gdb_test "print __FILE__" " = \".*macscp1.c\""
+gdb_test "print __LINE__" \
+    " = [gdb_get_line_number {stopping point for line test}]"
index e754b2684d37b488f2b746d34cdc6313c6f24921..b1eb0b4490aec8adecc8e379bbf77ae353f4de2c 100644 (file)
@@ -91,7 +91,7 @@ macscp_expr (void)
 #define MACRO_TO_EXPAND foo
   foo = 1;
 #undef MACRO_TO_EXPAND
-  foo = 2;
+  foo = 2;                     /* stopping point for line test */
 }
 
 #define TWENTY_THREE 23