[applying,to,mainline] writer: Don't forget data members when emitting referenced types

Message ID 87v86txtfm.fsf@redhat.com
State New
Headers
Series [applying,to,mainline] writer: Don't forget data members when emitting referenced types |

Commit Message

Dodji Seketeli Feb. 12, 2024, 9:29 p.m. UTC
  Hello,

When emitting a type referenced type in the ABIXML,
write_decl_in_scope just emits markup for the opening (and closing)
tags for the scopes up until the actual referenced type.  Then the
referenced type is emitted.

But then if the referenced type is a member type of a class A, for
instance, the other data members of that class are not emitted.  That
can cause the data members of A to be missing.  Oops.

To fix that, if a scope of the referenced type is itself a type,
write_decl_in_scope now emits the full type.

	* src/abg-writer.cc (write_decl_in_scope): If the scope of the
	decl to write is a type that was not yet emitted, then emit it in
	full.  Otherwise, just do things as we were doing previously.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Applying to the master branch.
---
 src/abg-writer.cc | 72 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 51 insertions(+), 21 deletions(-)
  

Patch

diff --git a/src/abg-writer.cc b/src/abg-writer.cc
index a6b8d6f7..24616364 100644
--- a/src/abg-writer.cc
+++ b/src/abg-writer.cc
@@ -2059,30 +2059,47 @@  write_decl_in_scope(const decl_base_sptr&	decl,
 	{
 	  c = is_class_type(look_through_decl_only_class(c));
 	  class_decl_sptr class_type(c, noop_deleter());
-	  write_class_decl_opening_tag(class_type, "", ctxt, indent,
-				       /*prepare_to_handle_empty=*/false);
-	  closing_tags.push("</class-decl>");
-	  closing_indents.push(indent);
-
-	  unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
-	  write_member_type_opening_tag(type, ctxt, nb_ws);
-	  indent = nb_ws;
-	  closing_tags.push("</member-type>");
-	  closing_indents.push(nb_ws);
+	  if (!ctxt.type_is_emitted(c))
+	    {
+	      write_type(class_type, ctxt, initial_indent);
+	      break;
+	    }
+	  else
+	    {
+	      write_class_decl_opening_tag(class_type, "", ctxt, indent,
+					   /*prepare_to_handle_empty=*/false);
+	      closing_tags.push("</class-decl>");
+	      closing_indents.push(indent);
+
+	      unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
+	      write_member_type_opening_tag(type, ctxt, nb_ws);
+	      indent = nb_ws;
+	      closing_tags.push("</member-type>");
+	      closing_indents.push(nb_ws);
+	    }
 	}
       else if (union_decl *u = is_union_type(*i))
 	{
+	  u = is_union_type(look_through_decl_only(u));
 	  union_decl_sptr union_type(u, noop_deleter());
-	  write_union_decl_opening_tag(union_type, "", ctxt, indent,
-				       /*prepare_to_handle_empty=*/false);
-	  closing_tags.push("</union-decl>");
-	  closing_indents.push(indent);
-
-	  unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
-	  write_member_type_opening_tag(type, ctxt, nb_ws);
-	  indent = nb_ws;
-	  closing_tags.push("</member-type>");
-	  closing_indents.push(nb_ws);
+	  if (!ctxt.type_is_emitted(u))
+	    {
+	      write_type(union_type, ctxt, initial_indent);
+	      break;
+	    }
+	  else
+	    {
+	      write_union_decl_opening_tag(union_type, "", ctxt, indent,
+					   /*prepare_to_handle_empty=*/false);
+	      closing_tags.push("</union-decl>");
+	      closing_indents.push(indent);
+
+	      unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
+	      write_member_type_opening_tag(type, ctxt, nb_ws);
+	      indent = nb_ws;
+	      closing_tags.push("</member-type>");
+	      closing_indents.push(nb_ws);
+	    }
 	}
       else
 	// We should never reach this point.
@@ -2090,7 +2107,20 @@  write_decl_in_scope(const decl_base_sptr&	decl,
       indent += c.get_xml_element_indent();
     }
 
-  write_decl(decl, ctxt, indent);
+  bool do_write = false;
+  if (type_base_sptr type = is_type(decl))
+    {
+      if (!ctxt.type_is_emitted(type))
+	do_write= true;
+    }
+  else
+    {
+      if (!ctxt.decl_is_emitted(decl))
+	do_write= true;
+    }
+
+  if (do_write)
+    write_decl(decl, ctxt, indent);
 
   while (!closing_tags.empty())
     {