[2/2] XML writer: emit enclosing types of scoped declarations

Message ID 20210611170442.845802-3-gprocida@google.com
State New
Headers
Series Eliminate some duplicate types in XML |

Commit Message

Giuliano Procida June 11, 2021, 5:04 p.m. UTC
  Bug 26591 - detect pathologically redundant types in abixml

One source of duplicated type ids in ABI XML was the writer emitting
scoped (nested) typed declarations before a later TU causes the
emission of the complete enclosing type declaration.

This no longer seems to occur within the current test suite. The code
paths responsible are still active though, but don't ever appear to be
asked to emit nested member types.

This commit was my fix for the issue. It causes the outermost
enclosing type declaration to be emitted immediately, rather than a
nested member type. This prevents the later duplicate emission of the
enclosing type and all its nested member types.

This commit still does simplify the code paths and avoids the
potential emission of partial types (which were sometimes accompanied
by incorrect member-type access attributes).

	* src/abg-writer.cc: (write_decl_in_scope): Emit the enclosing
	types of any nested type declaration.

Signed-off-by: Giuliano Procida <gprocida@google.com>
---
 src/abg-writer.cc | 35 ++++++++++++-----------------------
 1 file changed, 12 insertions(+), 23 deletions(-)
  

Patch

diff --git a/src/abg-writer.cc b/src/abg-writer.cc
index 8aa95948..cf2693bf 100644
--- a/src/abg-writer.cc
+++ b/src/abg-writer.cc
@@ -1941,6 +1941,8 @@  write_decl(const decl_base_sptr& decl, write_context& ctxt, unsigned indent)
 
 /// Emit a declaration, along with its scope.
 ///
+/// If the scope includes another type declaration, emit that instead.
+///
 /// This function is called at the end of emitting a translation unit,
 /// to emit type declarations that were referenced by types that were
 /// emitted in the TU already, but that were not emitted themselves.
@@ -1972,6 +1974,7 @@  write_decl_in_scope(const decl_base_sptr&	decl,
   stack<string> closing_tags;
   stack<unsigned> closing_indents;
   unsigned indent = initial_indent;
+  bool done = false;
   for (list<scope_decl*>::const_iterator i = scopes.begin();
        i != scopes.end();
        ++i)
@@ -1987,43 +1990,29 @@  write_decl_in_scope(const decl_base_sptr&	decl,
 	    << "'>\n";
 	  closing_tags.push("</namespace-decl>");
 	  closing_indents.push(indent);
+	  indent += c.get_xml_element_indent();
 	}
-      // ... or a class.
+      // ... or a class ...
       else if (class_decl* c = is_class_type(*i))
 	{
 	  class_decl_sptr class_type(c, noop_deleter());
-	  write_class_decl_opening_tag(class_type, "", ctxt, indent,
-				       /*prepare_to_handle_members=*/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);
+	  write_class_decl(class_type, ctxt, indent);
+	  done = true;
 	}
+      // ... or a union.
       else if (union_decl *u = is_union_type(*i))
 	{
 	  union_decl_sptr union_type(u, noop_deleter());
-	  write_union_decl_opening_tag(union_type, "", ctxt, indent,
-				       /*prepare_to_handle_members=*/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);
+	  write_union_decl(union_type, ctxt, indent);
+	  done = true;
 	}
       else
 	// We should never reach this point.
 	abort();
-      indent += c.get_xml_element_indent();
     }
 
-  write_decl(decl, ctxt, indent);
+  if (!done)
+    write_decl(decl, ctxt, indent);
 
   while (!closing_tags.empty())
     {