[02/11] ir: Fix getting the translation unit for an ABI artifact

Message ID 20240814125649.47119-2-dodji@redhat.com
State New
Headers
Series [01/11] Use smart pointers for variables exported from the ABI corpus |

Commit Message

Dodji Seketeli Aug. 14, 2024, 12:56 p.m. UTC
  From: Dodji Seketeli <dodji@redhat.com>

Sometimes when the current translation unit is not yet set for a given
artifact, we can infer it by getting the translation unit of the scope
of the artifact.  This patch performs that inference when the
translation unit is not yet set for the current artifact.

	* include/abg-fwd.h (get_translation_unit): Take a
	type_or_decl_base parameter, not a decl_base.
	* src/abg-ir.cc (get_translation_unit): Likewise.  If no
	translation has yet been associated with the ABI artifact, get it
	from its scope.
	(type_or_decl_base::get_corpus): Use the new get_translation_unit.
	(maybe_set_translation_unit): Assert that the translation unit is
	non-nil.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
---
 include/abg-fwd.h |  6 +++---
 src/abg-ir.cc     | 34 ++++++++++++++++++++++++++++------
 2 files changed, 31 insertions(+), 9 deletions(-)
  

Patch

diff --git a/include/abg-fwd.h b/include/abg-fwd.h
index afe4163d..8b46eb08 100644
--- a/include/abg-fwd.h
+++ b/include/abg-fwd.h
@@ -359,13 +359,13 @@  const global_scope*
 get_global_scope(const decl_base_sptr);
 
 translation_unit*
-get_translation_unit(const decl_base&);
+get_translation_unit(const type_or_decl_base&);
 
 translation_unit*
-get_translation_unit(const decl_base*);
+get_translation_unit(const type_or_decl_base*);
 
 translation_unit*
-get_translation_unit(const decl_base_sptr);
+get_translation_unit(const type_or_decl_base_sptr&);
 
 bool
 is_global_scope(const scope_decl&);
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index 62d870cd..f6d7c527 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -4220,7 +4220,7 @@  type_or_decl_base::has_artificial_location() const
 corpus*
 type_or_decl_base::get_corpus()
 {
-  translation_unit* tu = get_translation_unit();
+  translation_unit* tu = abigail::ir::get_translation_unit(this);
   if (!tu)
     return 0;
   return tu->get_corpus();
@@ -7984,6 +7984,8 @@  static void
 maybe_set_translation_unit(const decl_base_sptr& decl,
 			   translation_unit*     tu)
 {
+  ABG_ASSERT(tu);
+
   if (translation_unit* existing_tu = decl->get_translation_unit())
     // The decl already belongs to a translation unit.
     // Either:
@@ -10167,8 +10169,28 @@  types_are_compatible(const decl_base_sptr d1,
 /// @return the resulting translation unit, or null if the decl is not
 /// yet added to a translation unit.
 translation_unit*
-get_translation_unit(const decl_base& decl)
-{return const_cast<translation_unit*>(decl.get_translation_unit());}
+get_translation_unit(const type_or_decl_base& t)
+{
+  translation_unit* result =
+    const_cast<translation_unit*>(t.get_translation_unit());
+
+  if (result)
+    return result;
+
+  if (decl_base* decl = is_decl(&t))
+    {
+      scope_decl* scope = decl->get_scope();
+      while (scope)
+	{
+	  result = scope->get_translation_unit();
+	  if (result)
+	    break;
+	  scope = scope->get_scope();
+	}
+    }
+
+  return result;
+}
 
 /// Return the translation unit a declaration belongs to.
 ///
@@ -10177,8 +10199,8 @@  get_translation_unit(const decl_base& decl)
 /// @return the resulting translation unit, or null if the decl is not
 /// yet added to a translation unit.
 translation_unit*
-get_translation_unit(const decl_base* decl)
-{return decl ? get_translation_unit(*decl) : 0;}
+get_translation_unit(const type_or_decl_base* decl)
+{return decl ? get_translation_unit(*decl) : nullptr;}
 
 /// Return the translation unit a declaration belongs to.
 ///
@@ -10187,7 +10209,7 @@  get_translation_unit(const decl_base* decl)
 /// @return the resulting translation unit, or null if the decl is not
 /// yet added to a translation unit.
 translation_unit*
-get_translation_unit(const shared_ptr<decl_base> decl)
+get_translation_unit(const type_or_decl_base_sptr& decl)
 {return get_translation_unit(decl.get());}
 
 /// Tests whether if a given scope is the global scope.