mirror of https://github.com/KLayout/klayout.git
* Fixed a compiler warning * Fixed #646 (crash on PCell Library "delete") The issue was mainly caused by a "cleanup" call on the library. Cleanup is supposed to remove excess top level PCell variants. For libraries this is not possible, as the library does not know which variants are used and which are not. In addition, some hardening against segfaults in case of defect layouts has been applied.
This commit is contained in:
parent
22df10f425
commit
511e30ef45
|
|
@ -272,6 +272,7 @@ Layout::Layout (db::Manager *manager)
|
|||
m_properties_repository (this),
|
||||
m_guiding_shape_layer (-1),
|
||||
m_waste_layer (-1),
|
||||
m_do_cleanup (false),
|
||||
m_editable (db::default_editable_mode ())
|
||||
{
|
||||
// .. nothing yet ..
|
||||
|
|
@ -287,6 +288,7 @@ Layout::Layout (bool editable, db::Manager *manager)
|
|||
m_properties_repository (this),
|
||||
m_guiding_shape_layer (-1),
|
||||
m_waste_layer (-1),
|
||||
m_do_cleanup (false),
|
||||
m_editable (editable)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
|
|
@ -306,6 +308,7 @@ Layout::Layout (const db::Layout &layout)
|
|||
m_properties_repository (this),
|
||||
m_guiding_shape_layer (-1),
|
||||
m_waste_layer (-1),
|
||||
m_do_cleanup (false),
|
||||
m_editable (layout.m_editable)
|
||||
{
|
||||
*this = layout;
|
||||
|
|
@ -1285,6 +1288,12 @@ Layout::allocate_new_cell ()
|
|||
void
|
||||
Layout::cleanup (const std::set<db::cell_index_type> &keep)
|
||||
{
|
||||
// only managed layouts will receive cleanup requests. Never library container layouts - these
|
||||
// cannot know if their proxies are not referenced by other proxies.
|
||||
if (! m_do_cleanup) {
|
||||
return;
|
||||
}
|
||||
|
||||
// deleting cells may create new top cells which need to be deleted as well, hence we iterate
|
||||
// until there are no more cells to delete
|
||||
while (true) {
|
||||
|
|
|
|||
|
|
@ -539,6 +539,21 @@ public:
|
|||
*/
|
||||
Layout &operator= (const Layout &d);
|
||||
|
||||
/**
|
||||
* @brief Specifies, if the layout participates in cleanup
|
||||
*
|
||||
* "cleanup" will be called to get rid of top level proxies.
|
||||
* This flag controls whether cleanup happens or not. Library
|
||||
* layouts for example must not loose proxies as they might
|
||||
* themselves be referenced.
|
||||
*
|
||||
* The default is OFF.
|
||||
*/
|
||||
void do_cleanup (bool f)
|
||||
{
|
||||
m_do_cleanup = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the layout
|
||||
*/
|
||||
|
|
@ -1761,6 +1776,7 @@ private:
|
|||
lib_proxy_map m_lib_proxy_map;
|
||||
int m_guiding_shape_layer;
|
||||
int m_waste_layer;
|
||||
bool m_do_cleanup;
|
||||
bool m_editable;
|
||||
meta_info m_meta_info;
|
||||
tl::Mutex m_lock;
|
||||
|
|
|
|||
|
|
@ -103,7 +103,8 @@ Library::unregister_proxy (db::LibraryProxy *lib_proxy, db::Layout *ly)
|
|||
db::cell_index_type ci = c->first;
|
||||
m_refcount.erase (c);
|
||||
// remove cells which are itself proxies and are no longer used
|
||||
if (layout ().cell (ci).is_proxy () && layout ().cell (ci).parent_cells () == 0) {
|
||||
db::Cell *lib_cell = &layout ().cell (ci);
|
||||
if (lib_cell && lib_cell->is_proxy () && lib_cell->parent_cells () == 0) {
|
||||
layout ().delete_cell (ci);
|
||||
}
|
||||
}
|
||||
|
|
@ -190,6 +191,7 @@ Library::remap_to (db::Library *other)
|
|||
|
||||
if (! pn.first) {
|
||||
|
||||
// substitute by static layout cell
|
||||
std::string name = r->first->cell_name (ci);
|
||||
db::Cell *old_cell = r->first->take_cell (ci);
|
||||
r->first->insert_cell (ci, name, new db::Cell (*old_cell));
|
||||
|
|
@ -201,6 +203,7 @@ Library::remap_to (db::Library *other)
|
|||
const db::PCellDeclaration *new_pcell_decl = other->layout ().pcell_declaration (pn.second);
|
||||
if (! old_pcell_decl || ! new_pcell_decl) {
|
||||
|
||||
// substitute by static layout cell
|
||||
std::string name = r->first->cell_name (ci);
|
||||
db::Cell *old_cell = r->first->take_cell (ci);
|
||||
r->first->insert_cell (ci, name, new db::Cell (*old_cell));
|
||||
|
|
@ -229,7 +232,7 @@ Library::remap_to (db::Library *other)
|
|||
|
||||
if (! cn.first) {
|
||||
|
||||
// unlink this proxy
|
||||
// unlink this proxy: substitute by static layout cell
|
||||
std::string name = r->first->cell_name (ci);
|
||||
db::Cell *old_cell = r->first->take_cell (ci);
|
||||
r->first->insert_cell (ci, name, new db::Cell (*old_cell));
|
||||
|
|
|
|||
|
|
@ -238,7 +238,12 @@ LibraryProxy::get_basic_name () const
|
|||
{
|
||||
Library *lib = LibraryManager::instance ().lib (lib_id ());
|
||||
if (lib) {
|
||||
return lib->layout ().cell (library_cell_index ()).get_basic_name ();
|
||||
const db::Cell *lib_cell = &lib->layout ().cell (library_cell_index ());
|
||||
if (! lib_cell) {
|
||||
return "<defunct>";
|
||||
} else {
|
||||
return lib_cell->get_basic_name ();
|
||||
}
|
||||
} else {
|
||||
return Cell::get_basic_name ();
|
||||
}
|
||||
|
|
@ -249,7 +254,12 @@ LibraryProxy::get_display_name () const
|
|||
{
|
||||
Library *lib = LibraryManager::instance ().lib (lib_id ());
|
||||
if (lib) {
|
||||
return lib->get_name () + "." + lib->layout ().cell (library_cell_index ()).get_display_name ();
|
||||
const db::Cell *lib_cell = &lib->layout ().cell (library_cell_index ());
|
||||
if (! lib_cell) {
|
||||
return lib->get_name () + "." + "<defunct>";
|
||||
} else {
|
||||
return lib->get_name () + "." + lib_cell->get_display_name ();
|
||||
}
|
||||
} else {
|
||||
return Cell::get_display_name ();
|
||||
}
|
||||
|
|
@ -260,7 +270,12 @@ LibraryProxy::get_qualified_name () const
|
|||
{
|
||||
Library *lib = LibraryManager::instance ().lib (lib_id ());
|
||||
if (lib) {
|
||||
return lib->get_name () + "." + lib->layout ().cell (library_cell_index ()).get_qualified_name ();
|
||||
const db::Cell *lib_cell = &lib->layout ().cell (library_cell_index ());
|
||||
if (! lib_cell) {
|
||||
return lib->get_name () + "." + "<defunct>";
|
||||
} else {
|
||||
return lib->get_name () + "." + lib_cell->get_qualified_name ();
|
||||
}
|
||||
} else {
|
||||
return Cell::get_qualified_name ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ LayoutHandle::LayoutHandle (db::Layout *layout, const std::string &filename)
|
|||
m_dirty (false),
|
||||
m_save_options_valid (false)
|
||||
{
|
||||
// layouts in the managed layouts space participate in spare proxy cleanup
|
||||
layout->do_cleanup (true);
|
||||
|
||||
file_watcher ().add_file (m_filename);
|
||||
|
||||
if (! m_filename.empty ()) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue