]> sourceware.org Git - libabigail.git/commitdiff
abidw: resolve declaration-only enums the same as classes
authorGiuliano Procida <gprocida@google.com>
Thu, 25 Aug 2022 11:48:56 +0000 (12:48 +0100)
committerDodji Seketeli <dodji@redhat.com>
Mon, 29 Aug 2022 11:11:53 +0000 (13:11 +0200)
The logic for resolving declaration-only enums and classes was almost
the same. However, the class code had a couple of extra improvements
that were missing from the enum code. One of these caused resolution
failures with Linux kernel ABIs, resulting in duplicate (declared /
defined) enums in ABI XML.

This change adds the improvements to the enum resolution code.

* src/abg-dwarf-reader.cc
(read_context::resolve_declaration_only_enums): Use an ordered
map to ensure TUs are always considered in the same order and
so improve ABI XML stability. Given multiple possible
definitions for a enum declaration, check to see if they are
equal and resolve the declaration to the first definition if
so.

Signed-off-by: Giuliano Procida <gprocida@google.com>
src/abg-dwarf-reader.cc

index cd34b7dbf199e48b1cc99d2144f1b8a87078b1c7..35027c57f7c1b74b921108c3db83dd3bc9cf2c0b 100644 (file)
@@ -4460,7 +4460,13 @@ public:
        if (!enums)
          continue;
 
-       unordered_map<string, enum_type_decl_sptr> per_tu_enum_map;
+       // This is a map that associates the translation unit path to
+       // the enum (that potentially defines the declarations that
+       // we consider) that are defined in that translation unit.  It
+       // should stay ordered by using the TU path as key to ensure
+       // stability of the order of enum definitions in ABIXML
+       // output.
+       map<string, enum_type_decl_sptr> per_tu_enum_map;
        for (type_base_wptrs_type::const_iterator c = enums->begin();
             c != enums->end();
             ++c)
@@ -4497,13 +4503,45 @@ public:
                  {
                    string tu_path =
                      (*j)->get_translation_unit()->get_absolute_path();
-                   unordered_map<string, enum_type_decl_sptr>::const_iterator e =
+                   map<string, enum_type_decl_sptr>::const_iterator e =
                      per_tu_enum_map.find(tu_path);
                    if (e != per_tu_enum_map.end())
                      (*j)->set_definition_of_declaration(e->second);
                    else if (per_tu_enum_map.size() == 1)
                      (*j)->set_definition_of_declaration
                        (per_tu_enum_map.begin()->second);
+                   else
+                     {
+                       // We are in case where there are more than
+                       // one definition for the declaration.  Let's
+                       // see if they are all equal.  If they are,
+                       // then the declaration resolves to the
+                       // definition.  Otherwise, we are in the case
+                       // 3/ described above.
+                       map<string,
+                           enum_type_decl_sptr>::const_iterator it;
+                       enum_type_decl_sptr first_enum =
+                         per_tu_enum_map.begin()->second;
+                       bool all_enum_definitions_are_equal = true;
+                       for (it = per_tu_enum_map.begin();
+                            it != per_tu_enum_map.end();
+                            ++it)
+                         {
+                           if (it == per_tu_enum_map.begin())
+                             continue;
+                           else
+                             {
+                               if (!compare_before_canonicalisation(it->second,
+                                                                    first_enum))
+                                 {
+                                   all_enum_definitions_are_equal = false;
+                                   break;
+                                 }
+                             }
+                         }
+                       if (all_enum_definitions_are_equal)
+                         (*j)->set_definition_of_declaration(first_enum);
+                     }
                  }
              }
            resolved_enums.push_back(i->first);
This page took 0.045993 seconds and 5 git commands to generate.