This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

FYI: fix PR macros/13205


I'm checking this in.

This adds support for the special macros __FILE__ and __LINE__ to gdb.
This is PR 13250.

This is a bit tricky because the macro definitions change depending on
context.  So, I needed some special logic for this.

Built and regtested on x86-64 Fedora 16.

GCC actually has a number of other special macros.  I did not implement
these, but I chose an implementation approach that makes it easy to add
them in the future if desired.  In particular it is trivial to expand
macro_special_kind.

Tom

b/gdb/ChangeLog:
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.

b/gdb/testsuite/ChangeLog:
2012-05-16  Tom Tromey  <tromey@redhat.com>

	* gdb.base/macscp1.c (macscp_expr): Add comment.
	* gdb.base/macscp.exp: Test __FILE__ and __LINE__.

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index f06dea6..f89742b 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -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);
 
diff --git a/gdb/macroexp.c b/gdb/macroexp.c
index d5e4e40..22b904e 100644
--- a/gdb/macroexp.c
+++ b/gdb/macroexp.c
@@ -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);
+}
+
 
 /* Expanding macros!  */
 
diff --git a/gdb/macroexp.h b/gdb/macroexp.h
index 289619e..dba03f6 100644
--- a/gdb/macroexp.h
+++ b/gdb/macroexp.h
@@ -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 */
diff --git a/gdb/macrotab.c b/gdb/macrotab.c
index 7428839..e65e5dc 100644
--- a/gdb/macrotab.c
+++ b/gdb/macrotab.c
@@ -28,6 +28,7 @@
 #include "gdb_assert.h"
 #include "bcache.h"
 #include "complaints.h"
+#include "macroexp.h"
 
 
 /* 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.  */
diff --git a/gdb/macrotab.h b/gdb/macrotab.h
index 8316cc3..92f1656 100644
--- a/gdb/macrotab.h
+++ b/gdb/macrotab.h
@@ -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;
 };
 
diff --git a/gdb/testsuite/gdb.base/macscp.exp b/gdb/testsuite/gdb.base/macscp.exp
index fa2173a..44a526b 100644
--- a/gdb/testsuite/gdb.base/macscp.exp
+++ b/gdb/testsuite/gdb.base/macscp.exp
@@ -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}]"
diff --git a/gdb/testsuite/gdb.base/macscp1.c b/gdb/testsuite/gdb.base/macscp1.c
index e754b26..b1eb0b4 100644
--- a/gdb/testsuite/gdb.base/macscp1.c
+++ b/gdb/testsuite/gdb.base/macscp1.c
@@ -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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]