mirror of https://github.com/KLayout/klayout.git
Issue 1114 (#1121)
* Two patches to enable building on MSYS with gcc 12.1 1. Complete explicit instantiations in dbHierProcessor 2. Strict weak ordering is not present for std::type_info (using "before" on gcc 12.1). We need to work with plain pointers and use a translation table to associate pointers with classes. * Fixed another place where std::type_info got important Co-authored-by: Matthias Koefferlein <matthias@klayout.de>
This commit is contained in:
parent
b1661d3c5e
commit
6ba372f1a9
|
|
@ -1261,13 +1261,20 @@ template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, d
|
|||
template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, db::Edge, db::Polygon>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, db::Edge, db::Edge>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::TextRef, db::TextRef>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::TextRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::TextRef, db::PolygonRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::TextRef, db::PolygonRef, db::TextRef>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::Edge, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::Edge, db::Edge>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::PolygonRef, db::Edge>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::PolygonRef, db::EdgePair>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, db::Polygon, db::EdgePair>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, db::Polygon, db::Edge>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Edge, db::Edge, db::Edge>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Edge, db::PolygonRef, db::Edge>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Edge, db::Edge, db::EdgePair>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Edge, db::PolygonRef, db::PolygonRef>;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// LocalProcessorResultComputationTask implementation
|
||||
|
|
|
|||
|
|
@ -49,9 +49,11 @@ namespace {
|
|||
|
||||
// TODO: thread-safe? Unlikely that multiple threads access this member -
|
||||
// we do a initial scan and after this no more write access here.
|
||||
typedef std::map<const std::type_info *, const ClassBase *, type_info_compare> ti_to_class_map_t;
|
||||
static ti_to_class_map_t *sp_ti_to_class = 0;
|
||||
// NOTE: MacOS/clang seems to have some issue with RTTI across shared objects. This map provides a name-based fallback
|
||||
static std::vector<const ClassBase *> *sp_classes = 0;
|
||||
typedef std::map<const ClassBase *, size_t> class_to_index_map_t;
|
||||
static class_to_index_map_t *sp_class_to_index = 0;
|
||||
typedef std::map<const std::type_info *, size_t> ti_to_class_map_t;
|
||||
static ti_to_class_map_t *sp_ti_to_class_index = 0;
|
||||
typedef std::map<std::string, const ClassBase *> tname_to_class_map_t;
|
||||
static tname_to_class_map_t *sp_tname_to_class = 0;
|
||||
|
||||
|
|
@ -67,9 +69,17 @@ ClassBase::ClassBase (const std::string &doc, const Methods &mm, bool do_registe
|
|||
mp_new_class_collection->push_back (this);
|
||||
|
||||
// invalidate the "typeinfo to class" map
|
||||
if (sp_ti_to_class) {
|
||||
delete sp_ti_to_class;
|
||||
sp_ti_to_class = 0;
|
||||
if (sp_classes) {
|
||||
delete sp_classes;
|
||||
sp_classes = 0;
|
||||
}
|
||||
if (sp_class_to_index) {
|
||||
delete sp_class_to_index;
|
||||
sp_class_to_index = 0;
|
||||
}
|
||||
if (sp_ti_to_class_index) {
|
||||
delete sp_ti_to_class_index;
|
||||
sp_ti_to_class_index = 0;
|
||||
}
|
||||
if (sp_tname_to_class) {
|
||||
delete sp_tname_to_class;
|
||||
|
|
@ -826,14 +836,25 @@ static void add_class_to_map (const gsi::ClassBase *c)
|
|||
ti = &c->type ();
|
||||
}
|
||||
|
||||
if (! sp_ti_to_class) {
|
||||
sp_ti_to_class = new ti_to_class_map_t ();
|
||||
if (! sp_classes) {
|
||||
sp_classes = new std::vector<const ClassBase *> ();
|
||||
}
|
||||
if (! sp_class_to_index) {
|
||||
sp_class_to_index = new class_to_index_map_t ();
|
||||
}
|
||||
if (! sp_ti_to_class_index) {
|
||||
sp_ti_to_class_index = new ti_to_class_map_t ();
|
||||
}
|
||||
if (! sp_tname_to_class) {
|
||||
sp_tname_to_class = new tname_to_class_map_t ();
|
||||
}
|
||||
|
||||
if (!sp_ti_to_class->insert (std::make_pair (ti, c)).second) {
|
||||
auto c2i = sp_class_to_index->insert (std::make_pair (c, sp_classes->size ())).first;
|
||||
if (c2i->second >= sp_classes->size ()) {
|
||||
sp_classes->push_back (c);
|
||||
}
|
||||
|
||||
if (!sp_ti_to_class_index->insert (std::make_pair (ti, c2i->second)).second) {
|
||||
// Duplicate registration of this class
|
||||
tl::error << "Duplicate registration of class " << c->name () << " (type " << ti->name () << ")";
|
||||
tl_assert (false);
|
||||
|
|
@ -844,27 +865,27 @@ static void add_class_to_map (const gsi::ClassBase *c)
|
|||
|
||||
const ClassBase *class_by_typeinfo_no_assert (const std::type_info &ti)
|
||||
{
|
||||
if (! sp_ti_to_class || sp_ti_to_class->empty ()) {
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
if (! sp_ti_to_class_index || sp_ti_to_class_index->empty ()) {
|
||||
for (auto c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
add_class_to_map (c.operator-> ());
|
||||
}
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
||||
for (auto c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
||||
add_class_to_map (c.operator-> ());
|
||||
}
|
||||
}
|
||||
|
||||
if (! sp_ti_to_class) {
|
||||
if (! sp_ti_to_class_index) {
|
||||
return 0;
|
||||
} else {
|
||||
ti_to_class_map_t::const_iterator c = sp_ti_to_class->find (&ti);
|
||||
if (c != sp_ti_to_class->end ()) {
|
||||
return c->second;
|
||||
auto c = sp_ti_to_class_index->find (&ti);
|
||||
if (c != sp_ti_to_class_index->end ()) {
|
||||
return sp_classes->operator[] (c->second);
|
||||
} else {
|
||||
// try name lookup
|
||||
tname_to_class_map_t::const_iterator cn = sp_tname_to_class->find (std::string (ti.name ()));
|
||||
auto cn = sp_tname_to_class->find (std::string (ti.name ()));
|
||||
if (cn != sp_tname_to_class->end ()) {
|
||||
// we can use this typeinfo as alias
|
||||
sp_ti_to_class->insert (std::make_pair (&ti, cn->second));
|
||||
sp_ti_to_class_index->insert (std::make_pair (&ti, sp_class_to_index->operator[] (cn->second)));
|
||||
return cn->second;
|
||||
} else {
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -144,22 +144,25 @@ struct VariantUserClassTableKey
|
|||
if (is_const != k.is_const) {
|
||||
return is_const < k.is_const;
|
||||
}
|
||||
if (*type != *k.type) {
|
||||
return type->before (*k.type);
|
||||
if (type != k.type) {
|
||||
return type < k.type;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator== (const VariantUserClassTableKey &k) const
|
||||
{
|
||||
return is_const == k.is_const && *type == *k.type;
|
||||
return is_const == k.is_const && type == k.type;
|
||||
}
|
||||
|
||||
const std::type_info *type;
|
||||
bool is_const;
|
||||
};
|
||||
|
||||
static std::map<VariantUserClassTableKey, const tl::VariantUserClassBase *> *sp_class_table = 0;
|
||||
static std::vector<const VariantUserClassBase *> *sp_classes = 0;
|
||||
static std::map<const VariantUserClassBase *, size_t> *sp_class_to_index = 0;
|
||||
static std::map<std::pair<std::string, bool>, size_t> *sp_class_index_by_name = 0;
|
||||
static std::map<VariantUserClassTableKey, size_t> *sp_class_table = 0;
|
||||
static std::map <std::string, const VariantUserClassBase *> s_user_type_by_name;
|
||||
|
||||
void
|
||||
|
|
@ -191,7 +194,7 @@ VariantUserClassBase::find_cls_by_name (const std::string &name)
|
|||
{
|
||||
tl_assert (! s_user_type_by_name.empty ());
|
||||
|
||||
std::map <std::string, const VariantUserClassBase *>::const_iterator s = s_user_type_by_name.find (tl::to_lower_case (name));
|
||||
auto s = s_user_type_by_name.find (tl::to_lower_case (name));
|
||||
if (s == s_user_type_by_name.end ()) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -199,33 +202,94 @@ VariantUserClassBase::find_cls_by_name (const std::string &name)
|
|||
return s->second;
|
||||
}
|
||||
|
||||
// type-info based interface
|
||||
|
||||
const tl::VariantUserClassBase *VariantUserClassBase::instance (const std::type_info &type, bool is_const)
|
||||
{
|
||||
tl_assert (sp_class_table != 0);
|
||||
std::map<VariantUserClassTableKey, const tl::VariantUserClassBase *>::const_iterator c = sp_class_table->find (VariantUserClassTableKey (type, is_const));
|
||||
tl_assert (c != sp_class_table->end ());
|
||||
return c->second;
|
||||
|
||||
const tl::VariantUserClassBase *inst = 0;
|
||||
|
||||
auto c = sp_class_table->find (VariantUserClassTableKey (type, is_const));
|
||||
if (c == sp_class_table->end ()) {
|
||||
|
||||
// fallback: lookup by name and update if required - sometimes, there may be two different type info objects for the same thing
|
||||
auto c2i = sp_class_index_by_name->find (std::make_pair (std::string (type.name ()), is_const));
|
||||
tl_assert (c2i != sp_class_index_by_name->end ());
|
||||
sp_class_table->insert (std::make_pair (VariantUserClassTableKey (type, is_const), c2i->second));
|
||||
inst = sp_classes->operator[] (c2i->second);
|
||||
|
||||
} else {
|
||||
inst = sp_classes->operator[] (c->second);
|
||||
}
|
||||
|
||||
tl_assert (inst != 0);
|
||||
return inst;
|
||||
}
|
||||
|
||||
void VariantUserClassBase::register_instance (const tl::VariantUserClassBase *inst, const std::type_info &type, bool is_const)
|
||||
{
|
||||
if (! sp_class_table) {
|
||||
sp_class_table = new std::map<VariantUserClassTableKey, const tl::VariantUserClassBase *> ();
|
||||
sp_class_table = new std::map<VariantUserClassTableKey, size_t> ();
|
||||
}
|
||||
(*sp_class_table)[VariantUserClassTableKey (type, is_const)] = inst;
|
||||
if (! sp_classes) {
|
||||
sp_classes = new std::vector<const tl::VariantUserClassBase *> ();
|
||||
}
|
||||
if (! sp_class_index_by_name) {
|
||||
sp_class_index_by_name = new std::map<std::pair<std::string, bool>, size_t> ();
|
||||
}
|
||||
if (! sp_class_to_index) {
|
||||
sp_class_to_index = new std::map<const VariantUserClassBase *, size_t> ();
|
||||
}
|
||||
|
||||
size_t index = sp_class_to_index->insert (std::make_pair (inst, sp_classes->size ())).first->second;
|
||||
if (index == sp_classes->size ()) {
|
||||
sp_classes->push_back (inst);
|
||||
}
|
||||
|
||||
(*sp_class_table)[VariantUserClassTableKey (type, is_const)] = index;
|
||||
(*sp_class_index_by_name) [std::make_pair (std::string (type.name ()), is_const)] = index;
|
||||
}
|
||||
|
||||
void VariantUserClassBase::unregister_instance (const tl::VariantUserClassBase *inst, const std::type_info &type, bool is_const)
|
||||
{
|
||||
if (sp_class_table) {
|
||||
std::map<VariantUserClassTableKey, const tl::VariantUserClassBase *>::iterator c = sp_class_table->find (VariantUserClassTableKey (type, is_const));
|
||||
if (c != sp_class_table->end () && c->second == inst) {
|
||||
|
||||
auto c = sp_class_table->find (VariantUserClassTableKey (type, is_const));
|
||||
if (c != sp_class_table->end ()) {
|
||||
sp_class_table->erase (c);
|
||||
sp_classes->operator[] (c->second) = 0;
|
||||
while (!sp_classes->empty () && sp_classes->back () == 0) {
|
||||
sp_classes->pop_back ();
|
||||
}
|
||||
}
|
||||
|
||||
auto cn = sp_class_index_by_name->find (std::make_pair (std::string (type.name ()), is_const));
|
||||
if (cn != sp_class_index_by_name->end ()) {
|
||||
sp_class_index_by_name->erase (cn);
|
||||
}
|
||||
|
||||
sp_class_to_index->erase (inst);
|
||||
|
||||
if (sp_class_table->empty ()) {
|
||||
delete sp_class_table;
|
||||
sp_class_table = 0;
|
||||
}
|
||||
|
||||
if (sp_classes->empty ()) {
|
||||
delete sp_classes;
|
||||
sp_classes = 0;
|
||||
}
|
||||
|
||||
if (sp_class_index_by_name->empty ()) {
|
||||
delete sp_class_index_by_name;
|
||||
sp_class_index_by_name = 0;
|
||||
}
|
||||
|
||||
if (sp_class_to_index->empty ()) {
|
||||
delete sp_class_to_index;
|
||||
sp_class_to_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue