From ca3505b872f679db23998055fef0e2d424171ab1 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 21 Mar 2026 11:17:39 +0100 Subject: [PATCH] Part of the bugfix for #2305 - properly mapping cell indexes after library reload --- src/db/db/dbLibrary.cc | 21 +++++++++++++++------ src/db/db/dbLibrary.h | 5 ++++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/db/db/dbLibrary.cc b/src/db/db/dbLibrary.cc index 0af31331c..66c1217cf 100644 --- a/src/db/db/dbLibrary.cc +++ b/src/db/db/dbLibrary.cc @@ -164,16 +164,25 @@ Library::rename (const std::string &name) void Library::refresh () { + // save a copy of the layout, so we can refer to it + std::unique_ptr org_layout (new db::Layout (layout ())); + std::string name = reload (); rename (name); layout ().refresh (); - remap_to (this); + remap_to (this, org_layout.get ()); } void -Library::remap_to (db::Library *other) +Library::remap_to (db::Library *other, db::Layout *original_layout) { + tl_assert (other != this || original_layout != 0); + + if (! original_layout) { + original_layout = &layout (); + } + // Hint: in the loop over the referrers we might unregister (delete from m_referrers) a referrer because no more cells refer to us. // Hence we must not directly iterate of m_referrers. std::vector > referrers; @@ -194,7 +203,7 @@ Library::remap_to (db::Library *other) db::LibraryProxy *lib_proxy = dynamic_cast (&*c); if (lib_proxy && lib_proxy->lib_id () == get_id ()) { - db::Cell *lib_cell = &layout ().cell (lib_proxy->library_cell_index ()); + db::Cell *lib_cell = &original_layout->cell (lib_proxy->library_cell_index ()); db::PCellVariant *lib_pcell = dynamic_cast (lib_cell); if (lib_pcell) { pcells_to_map.push_back (std::make_pair (lib_proxy, lib_pcell)); @@ -218,7 +227,7 @@ Library::remap_to (db::Library *other) std::pair pn (false, 0); if (other) { - pn = other->layout ().pcell_by_name (lp->first->get_basic_name ().c_str ()); + pn = other->layout ().pcell_by_name (original_layout->cell (lp->first->library_cell_index ()).get_basic_name ().c_str ()); } if (! pn.first) { @@ -230,7 +239,7 @@ Library::remap_to (db::Library *other) } else { - const db::PCellDeclaration *old_pcell_decl = layout ().pcell_declaration (lib_pcell->pcell_id ()); + const db::PCellDeclaration *old_pcell_decl = original_layout->pcell_declaration (lib_pcell->pcell_id ()); const db::PCellDeclaration *new_pcell_decl = other->layout ().pcell_declaration (pn.second); if (! old_pcell_decl || ! new_pcell_decl) { @@ -267,7 +276,7 @@ Library::remap_to (db::Library *other) std::pair cn (false, 0); if (other) { - cn = other->layout ().cell_by_name ((*lp)->get_basic_name ().c_str ()); + cn = other->layout ().cell_by_name (original_layout->cell ((*lp)->library_cell_index ()).get_basic_name ().c_str ()); } if (! cn.first) { diff --git a/src/db/db/dbLibrary.h b/src/db/db/dbLibrary.h index cd3513a4d..b0883e788 100644 --- a/src/db/db/dbLibrary.h +++ b/src/db/db/dbLibrary.h @@ -237,8 +237,11 @@ public: * @brief Remap the library proxies to a different library * * After remapping, "other" can replace "this". + * When calling with "other=this", a pointer to the original + * layout needs to be supplied, because in that case, the + * layout of "this" is already replaced. */ - void remap_to (db::Library *other); + void remap_to (db::Library *other, Layout *original_layout = 0); /** * @brief This event is fired if proxies get retired on unretired