From 716aa3c87b818de0cfb86ec601d8f7083842e326 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 1 Sep 2024 21:18:49 +0200 Subject: [PATCH] Fixing issue #1835 (saving a PCell as cell renders a layout that cannot be read) --- src/db/db/dbCommonReader.cc | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/db/db/dbCommonReader.cc b/src/db/db/dbCommonReader.cc index 108a62851..2c1a876df 100644 --- a/src/db/db/dbCommonReader.cc +++ b/src/db/db/dbCommonReader.cc @@ -23,6 +23,7 @@ #include "dbCommonReader.h" +#include "dbColdProxy.h" #include "dbStream.h" #include "tlXMLParser.h" @@ -475,7 +476,7 @@ CommonReaderBase::finish (db::Layout &layout) } if (name) { - // need to rename: add a new madding to m_layer_map_out and adjust the layout's layer properties + // need to rename: add a new mapping to m_layer_map_out and adjust the layout's layer properties db::LayerProperties lpp = lp; join_layer_names (lpp.name, *name); layout.set_properties (*i, lpp); @@ -580,9 +581,32 @@ CommonReader::read (db::Layout &layout, const db::LoadLayoutOptions &options) } // A cleanup may be necessary because of the following scenario: if library proxies contain subcells - // which are proxies itself, the proxy update may make them orphans (the proxies are regenerated). + // which are proxies themselves, the proxy update may make them orphans (the proxies are regenerated). // The cleanup will removed these. - layout.cleanup (); + + // Adressing issue #1835 (reading proxy-only GDS file renders empty layout) we do not delete + // the first (non-cold) proxy if there are only proxy top cells. + // We never clean up the top cell if there is a single one. This catches the case of having + // defunct proxies for top cells. + + std::set keep; + if (layout.end_top_cells () - layout.begin_top_down () == 1) { + keep.insert (*layout.begin_top_down ()); + } else { + for (auto c = layout.begin_top_down (); c != layout.end_top_cells (); ++c) { + const db::Cell *cptr = &layout.cell (*c); + if (cptr->is_proxy ()) { + if (! dynamic_cast (cptr) && keep.empty ()) { + keep.insert (*c); + } + } else { + keep.clear (); + break; + } + } + } + + layout.cleanup (keep); return layer_map_out (); }