diff --git a/src/db/db/dbRecursiveShapeIterator.cc b/src/db/db/dbRecursiveShapeIterator.cc index 6b91ff9b2..ee23140ac 100644 --- a/src/db/db/dbRecursiveShapeIterator.cc +++ b/src/db/db/dbRecursiveShapeIterator.cc @@ -93,7 +93,6 @@ RecursiveShapeIterator::RecursiveShapeIterator () // anything. Not necessary reasonable. m_layer = 0; m_has_layers = false; - mp_layout = 0; mp_shapes = 0; mp_top_cell = 0; mp_cell = 0; @@ -113,7 +112,6 @@ RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes) { m_layer = 0; m_has_layers = false; - mp_layout = 0; mp_shapes = &shapes; mp_top_cell = 0; m_overlapping = false; @@ -125,7 +123,6 @@ RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes, const { m_layer = 0; m_has_layers = false; - mp_layout = 0; mp_shapes = &shapes; mp_top_cell = 0; m_overlapping = overlapping; @@ -137,7 +134,6 @@ RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes, const { m_layer = 0; m_has_layers = false; - mp_layout = 0; mp_shapes = &shapes; mp_top_cell = 0; m_overlapping = overlapping; @@ -150,7 +146,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const { m_layer = layer; m_has_layers = false; - mp_layout = &layout; + mp_layout.reset (const_cast (&layout)); mp_shapes = 0; mp_top_cell = &cell; m_overlapping = overlapping; @@ -163,7 +159,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const { m_layer = layer; m_has_layers = false; - mp_layout = &layout; + mp_layout.reset (const_cast (&layout)); mp_shapes = 0; mp_top_cell = &cell; m_overlapping = overlapping; @@ -176,7 +172,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const { m_layer = layer; m_has_layers = false; - mp_layout = &layout; + mp_layout.reset (const_cast (&layout)); mp_shapes = 0; mp_top_cell = &cell; m_overlapping = false; @@ -190,7 +186,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const m_layer = 0; m_layers = layers; m_has_layers = true; - mp_layout = &layout; + mp_layout.reset (const_cast (&layout)); mp_shapes = 0; mp_top_cell = &cell; m_overlapping = overlapping; @@ -204,7 +200,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const m_layer = 0; m_layers = layers; m_has_layers = true; - mp_layout = &layout; + mp_layout.reset (const_cast (&layout)); mp_shapes = 0; mp_top_cell = &cell; m_overlapping = overlapping; @@ -218,7 +214,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const m_layer = 0; m_layers = layers; m_has_layers = true; - mp_layout = &layout; + mp_layout.reset (const_cast (&layout)); mp_shapes = 0; mp_top_cell = &cell; m_overlapping = false; @@ -232,7 +228,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const m_layer = 0; m_layers.insert (m_layers.end (), layers.begin (), layers.end ()); m_has_layers = true; - mp_layout = &layout; + mp_layout.reset (const_cast (&layout)); mp_shapes = 0; mp_top_cell = &cell; m_overlapping = overlapping; @@ -246,7 +242,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const m_layer = 0; m_layers.insert (m_layers.end (), layers.begin (), layers.end ()); m_has_layers = true; - mp_layout = &layout; + mp_layout.reset (const_cast (&layout)); mp_shapes = 0; mp_top_cell = &cell; m_overlapping = overlapping; @@ -260,7 +256,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const m_layer = 0; m_layers.insert (m_layers.end (), layers.begin (), layers.end ()); m_has_layers = true; - mp_layout = &layout; + mp_layout.reset (const_cast (&layout)); mp_shapes = 0; mp_top_cell = &cell; m_overlapping = false; @@ -691,6 +687,8 @@ RecursiveShapeIterator::next_shape (RecursiveShapeReceiver *receiver) const if (! m_inst.at_end () && int (m_inst_iterators.size ()) < m_max_depth) { + tl_assert (mp_layout); + // determine whether the cell is empty with respect to the layers specified bool is_empty = false; if (! m_has_layers) { @@ -754,6 +752,8 @@ RecursiveShapeIterator::next_shape (RecursiveShapeReceiver *receiver) const void RecursiveShapeIterator::down (RecursiveShapeReceiver *receiver) const { + tl_assert (mp_layout); + m_trans_stack.push_back (m_trans); m_cells.push_back (mp_cell); diff --git a/src/db/db/dbRecursiveShapeIterator.h b/src/db/db/dbRecursiveShapeIterator.h index 2370f65a7..330563c20 100644 --- a/src/db/db/dbRecursiveShapeIterator.h +++ b/src/db/db/dbRecursiveShapeIterator.h @@ -29,6 +29,7 @@ #include "dbLayout.h" #include "dbInstElement.h" #include "tlAssert.h" +#include "tlObject.h" #include #include @@ -306,7 +307,7 @@ public: */ const layout_type *layout () const { - return mp_layout; + return mp_layout.get (); } /** @@ -765,7 +766,7 @@ private: std::set m_start, m_stop; cplx_trans_type m_global_trans; - const layout_type *mp_layout; + tl::weak_ptr mp_layout; const cell_type *mp_top_cell; const shapes_type *mp_shapes; diff --git a/src/db/unit_tests/dbRecursiveShapeIteratorTests.cc b/src/db/unit_tests/dbRecursiveShapeIteratorTests.cc index 077f47793..c4dc63ae2 100644 --- a/src/db/unit_tests/dbRecursiveShapeIteratorTests.cc +++ b/src/db/unit_tests/dbRecursiveShapeIteratorTests.cc @@ -1515,3 +1515,42 @@ TEST(10) "end\n" ); } + +TEST(11_LayoutIsWeakPointer) +{ + std::unique_ptr g (new db::Layout ()); + g->insert_layer (0); + g->insert_layer (1); + db::Cell &c0 (g->cell (g->add_cell ())); + db::Cell &c1 (g->cell (g->add_cell ())); + db::Cell &c2 (g->cell (g->add_cell ())); + db::Cell &c3 (g->cell (g->add_cell ())); + + db::Box b (0, 100, 1000, 1200); + c1.shapes (0).insert (b); + c2.shapes (0).insert (b); + c3.shapes (0).insert (b); + + db::Box bb (1, 101, 1001, 1201); + c2.shapes (1).insert (bb); + + db::Trans tt; + c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), tt)); + c0.insert (db::CellInstArray (db::CellInst (c2.cell_index ()), db::Trans (db::Vector (100, -100)))); + c0.insert (db::CellInstArray (db::CellInst (c3.cell_index ()), db::Trans (1))); + c2.insert (db::CellInstArray (db::CellInst (c3.cell_index ()), db::Trans (db::Vector (1100, 0)))); + + std::string x; + + db::RecursiveShapeIterator i1 (*g, c0, 0, db::Box (0, 0, 100, 100)); + x = collect(i1, *g); + EXPECT_EQ (x, "[$2](0,100;1000,1200)/[$3](100,0;1100,1100)"); + + g.reset (new db::Layout ()); + + // now the layout is gone and the iterator stays silent (weak pointer to layout) + // NOTE: this only works on reset or re-initialization. Not during iteration. + i1.reset (); + x = collect(i1, *g); + EXPECT_EQ (x, ""); +}