Enabling MSVC debug builds with iterator debugging on

This commit is contained in:
klayoutmatthias 2022-07-25 21:06:56 +02:00
parent 17f8a92a66
commit 167bcbcc5f
8 changed files with 106 additions and 29 deletions

View File

@ -23,6 +23,7 @@
#include "dbCircuit.h"
#include "dbNetlist.h"
#include "dbLayout.h"
#include "tlIteratorUtils.h"
#include <set>
@ -169,7 +170,7 @@ const Pin *Circuit::pin_by_id (size_t id) const
return 0;
} else {
pin_list::iterator pi = m_pin_by_id [id];
if (pi == pin_list::iterator ()) {
if (tl::is_null_iterator (pi)) {
return 0;
} else {
return pi.operator-> ();
@ -179,7 +180,7 @@ const Pin *Circuit::pin_by_id (size_t id) const
void Circuit::rename_pin (size_t id, const std::string &name)
{
if (id < m_pin_by_id.size () && m_pin_by_id [id] != pin_list::iterator ()) {
if (id < m_pin_by_id.size () && ! tl::is_null_iterator (m_pin_by_id [id])) {
m_pin_by_id [id]->set_name (name);
}
}
@ -327,7 +328,7 @@ Pin &Circuit::add_pin (const std::string &name)
void Circuit::remove_pin (size_t id)
{
if (id < m_pin_by_id.size () && m_pin_by_id [id] != pin_list::iterator ()) {
if (id < m_pin_by_id.size () && ! tl::is_null_iterator (m_pin_by_id [id])) {
m_pins.erase (m_pin_by_id [id]);
m_pin_by_id [id] = pin_list::iterator ();
}
@ -653,7 +654,7 @@ const Net *Circuit::net_for_pin (size_t pin_id) const
{
if (pin_id < m_pin_refs.size ()) {
Net::pin_iterator p = m_pin_refs [pin_id];
if (p != Net::pin_iterator ()) {
if (! tl::is_null_iterator (p)) {
return p->net ();
}
}
@ -668,7 +669,7 @@ void Circuit::connect_pin (size_t pin_id, Net *net)
if (pin_id < m_pin_refs.size ()) {
Net::pin_iterator p = m_pin_refs [pin_id];
if (p != Net::pin_iterator () && p->net ()) {
if (! tl::is_null_iterator (p) && p->net ()) {
p->net ()->erase_pin (p);
}
m_pin_refs [pin_id] = Net::pin_iterator ();

View File

@ -23,6 +23,7 @@
#include "dbDevice.h"
#include "dbCircuit.h"
#include "dbDeviceClass.h"
#include "tlIteratorUtils.h"
namespace db
{
@ -39,7 +40,7 @@ Device::Device ()
Device::~Device ()
{
for (std::vector<Net::terminal_iterator>::const_iterator t = m_terminal_refs.begin (); t != m_terminal_refs.end (); ++t) {
if (*t != Net::terminal_iterator () && (*t)->net ()) {
if (! tl::is_null_iterator (*t) && (*t)->net ()) {
(*t)->net ()->erase_terminal (*t);
}
}
@ -125,7 +126,7 @@ const Net *Device::net_for_terminal (size_t terminal_id) const
{
if (terminal_id < m_terminal_refs.size ()) {
Net::terminal_iterator p = m_terminal_refs [terminal_id];
if (p != Net::terminal_iterator ()) {
if (! tl::is_null_iterator (p)) {
return p->net ();
}
}
@ -140,7 +141,7 @@ void Device::connect_terminal (size_t terminal_id, Net *net)
if (terminal_id < m_terminal_refs.size ()) {
Net::terminal_iterator p = m_terminal_refs [terminal_id];
if (p != Net::terminal_iterator () && p->net ()) {
if (! tl::is_null_iterator (p) && p->net ()) {
p->net ()->erase_terminal (p);
}
m_terminal_refs [terminal_id] = Net::terminal_iterator ();

View File

@ -94,7 +94,11 @@ public:
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
{
const generic_shape_iterator_delegate2<Iter> *o = dynamic_cast<const generic_shape_iterator_delegate2<Iter> *> (other);
#if defined(_MSC_VER) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL >= 2
return o && o->m_iter._Unwrapped () == m_iter._Unwrapped ();
#else
return o && o->m_iter == m_iter;
#endif
}
private:

View File

@ -25,14 +25,14 @@
#include "dbClip.h"
#include "dbRegion.h"
#include "dbPolygonTools.h"
#include "tlIteratorUtils.h"
namespace db
{
static HierarchyBuilderShapeInserter def_inserter;
static HierarchyBuilder::cell_map_type null_map;
static HierarchyBuilder::cell_map_type::const_iterator null_iterator = null_map.end ();
static HierarchyBuilder::cell_map_type::const_iterator null_iterator = HierarchyBuilder::cell_map_type::const_iterator ();
// -------------------------------------------------------------------------------------------
@ -286,7 +286,7 @@ HierarchyBuilder::end (const RecursiveShapeIterator *iter)
void
HierarchyBuilder::enter_cell (const RecursiveShapeIterator * /*iter*/, const db::Cell * /*cell*/, const db::Box & /*region*/, const box_tree_type * /*complex_region*/)
{
tl_assert (m_cm_entry != m_cell_map.end () && m_cm_entry != null_iterator);
tl_assert (! tl::is_equal_iterator_unchecked (m_cm_entry, null_iterator) && m_cm_entry != m_cell_map.end ());
m_cells_seen.insert (m_cm_entry->first);

View File

@ -22,6 +22,7 @@
#include "dbSubCircuit.h"
#include "dbCircuit.h"
#include "tlIteratorUtils.h"
namespace db
{
@ -38,7 +39,7 @@ SubCircuit::SubCircuit ()
SubCircuit::~SubCircuit()
{
for (std::vector<Net::subcircuit_pin_iterator>::const_iterator p = m_pin_refs.begin (); p != m_pin_refs.end (); ++p) {
if (*p != Net::subcircuit_pin_iterator () && (*p)->net ()) {
if (! tl::is_null_iterator (*p) && (*p)->net ()) {
(*p)->net ()->erase_subcircuit_pin (*p);
}
}
@ -112,7 +113,7 @@ const Net *SubCircuit::net_for_pin (size_t pin_id) const
{
if (pin_id < m_pin_refs.size ()) {
Net::subcircuit_pin_iterator p = m_pin_refs [pin_id];
if (p != Net::subcircuit_pin_iterator ()) {
if (! tl::is_null_iterator (p)) {
return p->net ();
}
}
@ -123,7 +124,7 @@ const NetSubcircuitPinRef *SubCircuit::netref_for_pin (size_t pin_id) const
{
if (pin_id < m_pin_refs.size ()) {
Net::subcircuit_pin_iterator p = m_pin_refs [pin_id];
if (p != Net::subcircuit_pin_iterator ()) {
if (! tl::is_null_iterator (p)) {
return p.operator-> ();
}
}
@ -138,7 +139,7 @@ void SubCircuit::connect_pin (size_t pin_id, Net *net)
if (pin_id < m_pin_refs.size ()) {
Net::subcircuit_pin_iterator p = m_pin_refs [pin_id];
if (p != Net::subcircuit_pin_iterator () && p->net ()) {
if (! tl::is_null_iterator (p) && p->net ()) {
p->net ()->erase_subcircuit_pin (p);
}
m_pin_refs [pin_id] = Net::subcircuit_pin_iterator ();

View File

@ -145,9 +145,10 @@ msvc {
QMAKE_CXXFLAGS_WARN_ON += \
# as we're using default-constructed iterators as "null" we can't have
# checked iterators with MSVC
DEFINES += _ITERATOR_DEBUG_LEVEL=0
# for stack trace support:
# lpsapi for GetModuleFileName and others
# dbghelp for SymFromAddr and other
LIBS += -lpsapi -ldbghelp
} else {
@ -171,9 +172,25 @@ msvc {
QMAKE_CXXFLAGS += -std=c++11
win32 {
QMAKE_LFLAGS += -Wl,--exclude-all-symbols
# for stack trace support:
# lpsapi for GetModuleFileName and others
# dbghelp for SymFromAddr and other
LIBS += -lpsapi -ldbghelp
QMAKE_CXXFLAGS += -Wa,-mbig-obj
} else {
QMAKE_CXXFLAGS += -fvisibility=hidden
}
*bsd* {
# stack trace support
LIBS += -lexecinfo
}
}

View File

@ -181,17 +181,6 @@ INCLUDEPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC $$LAYBASIC_INC $$LAYUI_INC
DEPENDPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC $$LAYBASIC_INC $$LAYUI_INC $$LAYVIEW_INC $$ANT_INC $$IMG_INC $$EDT_INC $$LYM_INC
LIBS += -L$$DESTDIR -lklayout_tl -lklayout_gsi -lklayout_db -lklayout_rdb -lklayout_lym -lklayout_laybasic -lklayout_layview -lklayout_layui -lklayout_ant -lklayout_img -lklayout_edt
win32 {
# for stack trace support:
# lpsapi for GetModuleFileName and others
# dbghelp for SymFromAddr and other
LIBS += -lpsapi -ldbghelp
}
*bsd* {
LIBS += -lexecinfo
}
INCLUDEPATH += $$QTBASIC_INC
DEPENDPATH += $$QTBASIC_INC

View File

@ -0,0 +1,64 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2022 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef HDR_tlIteratorUtils
#define HDR_tlIteratorUtils
namespace tl
{
/**
* @brief Checks an iterator against the default-constructed value
*
* This function takes care of using the right way of comparing iterators
* suitable for MSVC with iterator debugging on.
*/
template <class Iter>
static inline bool is_null_iterator (const Iter &iter)
{
#if defined(_MSC_VER) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL >= 2
return iter._Unwrapped () == Iter ()._Unwrapped ();
#else
return iter == Iter ();
#endif
}
/**
* @brief Checks an iterator against another one without iterator checking
*
* This function takes care of using the right way of comparing iterators
* suitable for MSVC with iterator debugging on.
*/
template <class Iter>
static inline bool is_equal_iterator_unchecked (const Iter &a, const Iter &b)
{
#if defined(_MSC_VER) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL >= 2
return a._Unwrapped () == b._Unwrapped ();
#else
return a == b;
#endif
}
}
#endif