From 9ae8282da74ec1fbc0f89d87e645cbaabfa609ce Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey@redhat.com>
Date: Thu, 30 Sep 2010 17:51:39 +0000
Subject: [PATCH] gdb 	* completer.c (count_struct_fields): Handle anonymous
 structs and 	unions. 	(add_struct_fields): Likewise. gdb/testsuite 
 * gdb.base/completion.exp: Test completion through anonymous 	union. 	*
 gdb.base/break1.c (struct some_struct): Add anonymous union.

---
 gdb/ChangeLog                         |  6 ++++++
 gdb/completer.c                       | 29 ++++++++++++++++++++++-----
 gdb/testsuite/ChangeLog               |  6 ++++++
 gdb/testsuite/gdb.base/break1.c       |  1 +
 gdb/testsuite/gdb.base/completion.exp |  4 ++++
 5 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c10ed117f6..dfbae8b08b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2010-09-30  Tom Tromey  <tromey@redhat.com>
+
+	* completer.c (count_struct_fields): Handle anonymous structs and
+	unions.
+	(add_struct_fields): Likewise.
+
 2010-09-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	Fix printing parameters of inlined functions.
diff --git a/gdb/completer.c b/gdb/completer.c
index 91b899d900..5d0898d04c 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -351,7 +351,15 @@ count_struct_fields (struct type *type)
       if (i < TYPE_N_BASECLASSES (type))
 	result += count_struct_fields (TYPE_BASECLASS (type, i));
       else if (TYPE_FIELD_NAME (type, i))
-	++result;
+	{
+	  if (TYPE_FIELD_NAME (type, i)[0] != '\0')
+	    ++result;
+	  else if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION)
+	    {
+	      /* Recurse into anonymous unions.  */
+	      result += count_struct_fields (TYPE_FIELD_TYPE (type, i));
+	    }
+	}
     }
 
   for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
@@ -380,11 +388,22 @@ add_struct_fields (struct type *type, int *nextp, char **output,
       if (i < TYPE_N_BASECLASSES (type))
 	add_struct_fields (TYPE_BASECLASS (type, i), nextp, output,
 			   fieldname, namelen);
-      else if (TYPE_FIELD_NAME (type, i)
-	       && ! strncmp (TYPE_FIELD_NAME (type, i), fieldname, namelen))
+      else if (TYPE_FIELD_NAME (type, i))
 	{
-	  output[*nextp] = xstrdup (TYPE_FIELD_NAME (type, i));
-	  ++*nextp;
+	  if (TYPE_FIELD_NAME (type, i)[0] != '\0')
+	    {
+	      if (! strncmp (TYPE_FIELD_NAME (type, i), fieldname, namelen))
+		{
+		  output[*nextp] = xstrdup (TYPE_FIELD_NAME (type, i));
+		  ++*nextp;
+		}
+	    }
+	  else if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION)
+	    {
+	      /* Recurse into anonymous unions.  */
+	      add_struct_fields (TYPE_FIELD_TYPE (type, i), nextp, output,
+				 fieldname, namelen);
+	    }
 	}
     }
 
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 42e7192109..56ee414d82 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2010-09-30  Tom Tromey  <tromey@redhat.com>
+
+	* gdb.base/completion.exp: Test completion through anonymous
+	union.
+	* gdb.base/break1.c (struct some_struct): Add anonymous union.
+
 2010-09-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	Fix printing parameters of inlined functions.
diff --git a/gdb/testsuite/gdb.base/break1.c b/gdb/testsuite/gdb.base/break1.c
index 93b563a293..ab8e00f64d 100644
--- a/gdb/testsuite/gdb.base/break1.c
+++ b/gdb/testsuite/gdb.base/break1.c
@@ -24,6 +24,7 @@ struct some_struct
 {
   int a_field;
   int b_field;
+  union { int z_field; };
 };
 
 struct some_struct values[50];
diff --git a/gdb/testsuite/gdb.base/completion.exp b/gdb/testsuite/gdb.base/completion.exp
index 1f7c214a6f..904ee9852b 100644
--- a/gdb/testsuite/gdb.base/completion.exp
+++ b/gdb/testsuite/gdb.base/completion.exp
@@ -684,6 +684,10 @@ gdb_expect  {
         timeout         { fail "(timeout) complete 'p &values\[0\] -> a' 2" }
         }
 
+gdb_test "complete p &values\[0\]->z" \
+    "p &values.0.->z_field" \
+    "copmletion of field in anonymous union"
+
 # The following tests used to simply try to complete `${objdir}/file',
 # and so on.  The problem is that ${objdir} can be very long; the
 # completed filename may be more than eighty characters wide.  When
-- 
2.42.0