From 2a700917616a2cc0e751adb76d8f71348a80b0d8 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 10 Dec 2021 11:24:56 +0200 Subject: Enter abstract elements into substitution map We cannot just omit them because they may serve as "links" between the root of the substitution group and non-abstract elements that use these elements as their roots. --- libxsd/xsd/cxx/tree/type-factory-map.hxx | 7 +++++-- libxsd/xsd/cxx/tree/type-factory-map.txx | 16 ++++++++++------ xsd/xsd/cxx/tree/tree-source.cxx | 28 ++++++++++++++++++++-------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/libxsd/xsd/cxx/tree/type-factory-map.hxx b/libxsd/xsd/cxx/tree/type-factory-map.hxx index e20acfe..d52982f 100644 --- a/libxsd/xsd/cxx/tree/type-factory-map.hxx +++ b/libxsd/xsd/cxx/tree/type-factory-map.hxx @@ -150,11 +150,14 @@ namespace xsd // // - template + template struct element_factory_initializer { + typedef typename type_factory_map::factory factory; + element_factory_initializer (const C* root_name, const C* root_ns, - const C* subst_name, const C* subst_ns); + const C* subst_name, const C* subst_ns, + factory); ~element_factory_initializer (); diff --git a/libxsd/xsd/cxx/tree/type-factory-map.txx b/libxsd/xsd/cxx/tree/type-factory-map.txx index 1eddb25..5a9dc38 100644 --- a/libxsd/xsd/cxx/tree/type-factory-map.txx +++ b/libxsd/xsd/cxx/tree/type-factory-map.txx @@ -302,6 +302,9 @@ namespace xsd if (i != element_map_.end ()) { + // Note that we may find an abstract element in which case the + // returned factory will be NULL. + // f = find_substitution (i->second, qn); } } @@ -455,21 +458,22 @@ namespace xsd // // - template - element_factory_initializer:: + template + element_factory_initializer:: element_factory_initializer (const C* root_name, const C* root_ns, - const C* subst_name, const C* subst_ns) + const C* subst_name, const C* subst_ns, + factory f) : root_name_ (root_name), root_ns_ (root_ns), subst_name_ (subst_name), subst_ns_ (subst_ns) { type_factory_map_instance ().register_element ( xml::qualified_name (root_name, root_ns), xml::qualified_name (subst_name, subst_ns), - &factory_impl); + f); } - template - element_factory_initializer:: + template + element_factory_initializer:: ~element_factory_initializer () { type_factory_map_instance ().unregister_element ( diff --git a/xsd/xsd/cxx/tree/tree-source.cxx b/xsd/xsd/cxx/tree/tree-source.cxx index 00e895b..d702509 100644 --- a/xsd/xsd/cxx/tree/tree-source.cxx +++ b/xsd/xsd/cxx/tree/tree-source.cxx @@ -3727,24 +3727,36 @@ namespace CXX } } - if (!abst && polymorphic && e.substitutes_p () && - !options.suppress_parsing ()) + // Note that we cannot just omit this element if it's abstract + // because it may serve as a "link" between the root of the + // substitution group and a non-abstract element that uses this + // element as its root (see element_factory_map::find_substitution() + // for details). + // + if (polymorphic && e.substitutes_p () && !options.suppress_parsing ()) { String const& name (ename (e)); Type& r (e.substitutes ().root ()); os << "static" << endl << "const ::xsd::cxx::tree::element_factory_initializer< " << - poly_plate << ", " << char_type << ", "; - - belongs (e, belongs_); - - os << " >" << endl + poly_plate << ", " << char_type << " >" << endl << "_xsd_" << name << "_element_factory_init (" << endl << strlit (r.name ()) << "," << endl << strlit (r.namespace_ ().name ()) << "," << endl << strlit (e.name ()) << "," << endl - << strlit (e.namespace_ ().name ()) << ");" + << strlit (e.namespace_ ().name ()) << "," << endl; + + if (abst) + os << "0"; + else + { + os << "&::xsd::cxx::tree::factory_impl< "; + belongs (e, belongs_); + os << " >"; + } + + os << ");" << endl << endl; } -- cgit v1.1