From e4c22d3686da0e973e21eae0561c1169c0eeff36 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 26 Mar 2009 17:09:53 +0200 Subject: Implement support for XML Schema polymorphism in C++/Hybrid examples/cxx/hybrid/polyroot/ examples/cxx/hybrid/polymorphism/: new examples tests/cxx/hybrid/polymorphism/: new tests --- xsde/cxx/elements.cxx | 9 +- xsde/cxx/hybrid/aggregate-elements.hxx | 31 +++ xsde/cxx/hybrid/aggregate-include.hxx | 223 ++++++++++++++++ xsde/cxx/hybrid/cli.hxx | 10 + xsde/cxx/hybrid/elements.cxx | 7 +- xsde/cxx/hybrid/elements.hxx | 12 +- xsde/cxx/hybrid/generator.cxx | 130 +++++++++- xsde/cxx/hybrid/generator.hxx | 63 +++-- xsde/cxx/hybrid/parser-aggregate-header.cxx | 315 +++++++++++++++++----- xsde/cxx/hybrid/parser-aggregate-source.cxx | 162 +++++++++++- xsde/cxx/hybrid/parser-header.cxx | 35 +++ xsde/cxx/hybrid/parser-name-processor.cxx | 11 +- xsde/cxx/hybrid/parser-name-processor.hxx | 3 +- xsde/cxx/hybrid/parser-source.cxx | 52 ++++ xsde/cxx/hybrid/serializer-aggregate-header.cxx | 330 ++++++++++++++++++------ xsde/cxx/hybrid/serializer-aggregate-source.cxx | 169 +++++++++++- xsde/cxx/hybrid/serializer-header.cxx | 35 +++ xsde/cxx/hybrid/serializer-name-processor.cxx | 13 +- xsde/cxx/hybrid/serializer-name-processor.hxx | 3 +- xsde/cxx/hybrid/serializer-source.cxx | 100 +++++++ xsde/cxx/hybrid/tree-header.cxx | 94 +++++-- xsde/cxx/hybrid/tree-inline.cxx | 9 - xsde/cxx/hybrid/tree-name-processor.cxx | 13 +- xsde/cxx/hybrid/tree-name-processor.hxx | 3 +- xsde/cxx/hybrid/tree-size-processor.cxx | 274 ++++++++++++++++++-- xsde/cxx/hybrid/tree-size-processor.hxx | 5 +- xsde/cxx/hybrid/tree-source.cxx | 225 +++++++++++++++- xsde/cxx/hybrid/validator.cxx | 9 +- xsde/cxx/parser/generator.cxx | 10 +- xsde/cxx/parser/generator.hxx | 17 +- xsde/cxx/parser/name-processor.cxx | 11 +- xsde/cxx/parser/name-processor.hxx | 5 +- xsde/cxx/parser/validator.cxx | 2 + xsde/cxx/serializer/generator.cxx | 10 +- xsde/cxx/serializer/generator.hxx | 17 +- xsde/cxx/serializer/name-processor.cxx | 11 +- xsde/cxx/serializer/name-processor.hxx | 5 +- xsde/cxx/serializer/validator.cxx | 2 + 38 files changed, 2144 insertions(+), 291 deletions(-) create mode 100644 xsde/cxx/hybrid/aggregate-elements.hxx create mode 100644 xsde/cxx/hybrid/aggregate-include.hxx (limited to 'xsde/cxx') diff --git a/xsde/cxx/elements.cxx b/xsde/cxx/elements.cxx index 6116856..79fd6c5 100644 --- a/xsde/cxx/elements.cxx +++ b/xsde/cxx/elements.cxx @@ -194,8 +194,15 @@ namespace CXX if (schema.used ()) { + // Here we need to detect a special multi-schema compilation + // case where the root schemas are imported into a special + // schema that doesn't have a namespace. + // SemanticGraph::Uses& u (*schema.used_begin ()); - path = u.path (); + SemanticGraph::Schema& s (u.user ()); + + if (s.names_begin () != s.names_end ()) + path = u.path (); } String pair; diff --git a/xsde/cxx/hybrid/aggregate-elements.hxx b/xsde/cxx/hybrid/aggregate-elements.hxx new file mode 100644 index 0000000..aa4c504 --- /dev/null +++ b/xsde/cxx/hybrid/aggregate-elements.hxx @@ -0,0 +1,31 @@ +// file : xsde/cxx/hybrid/aggregate-elements.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CXX_HYBRID_AGGREGATE_ELEMENTS_HXX +#define CXX_HYBRID_AGGREGATE_ELEMENTS_HXX + +#include + +#include + +namespace CXX +{ + namespace Hybrid + { + typedef + Cult::Containers::Map + TypeInstanceMap; + + struct InstanceInfo + { + SemanticGraph::Type* type; + String name; + }; + + typedef Cult::Containers::Map TypeIdInstanceMap; + } +} + +#endif // CXX_HYBRID_AGGREGATE_ELEMENTS_HXX diff --git a/xsde/cxx/hybrid/aggregate-include.hxx b/xsde/cxx/hybrid/aggregate-include.hxx new file mode 100644 index 0000000..9bd50bb --- /dev/null +++ b/xsde/cxx/hybrid/aggregate-include.hxx @@ -0,0 +1,223 @@ +// file : xsde/cxx/hybrid/aggregate-include.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CXX_HYBRID_AGGREGATE_INCLUDE_HXX +#define CXX_HYBRID_AGGREGATE_INCLUDE_HXX + +#include + +#include +#include + +#include + +namespace CXX +{ + namespace Hybrid + { + // Parser/serializer implementation includes for additional + // schemas (polymorphic code). + // + + // For base types we only want member's types, but not the + // base itself. + // + struct BaseInclude: Traversal::Complex, Context + { + BaseInclude (Context& c) + : Context (c) + { + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + inherits (c); + + if (!restriction_p (c)) + { + names (c); + contains_compositor (c); + } + } + }; + + struct TypeInclude: Traversal::Type, + Traversal::Complex, + Context + { + TypeInclude (Context& c) + : Context (c), base_ (c) + { + *this >> inherits_ >> base_ >> inherits_; + + *this >> contains_compositor_; + base_ >> contains_compositor_; + + *this >> names_; + base_ >> names_; + + contains_compositor_ >> compositor_; + compositor_ >> contains_particle_; + contains_particle_ >> compositor_; + contains_particle_ >> particle_; + + names_ >> attribute_; + + particle_ >> belongs_; + attribute_ >> belongs_; + belongs_ >> *this; + } + + virtual Void + traverse (SemanticGraph::Type& t) + { + if (types_.find (&t) != types_.end ()) + return; + + types_.insert (&t); + + if (polymorphic (t)) + collect (t); + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + if (types_.find (&c) != types_.end ()) + return; + + types_.insert (&c); + + if (polymorphic (c)) + collect (c); + + inherits (c); + + if (!restriction_p (c)) + { + names (c); + contains_compositor (c); + } + } + + private: + virtual Void + collect (SemanticGraph::Type& t) + { + using SemanticGraph::Type; + + for (Type::BegetsIterator i (t.begets_begin ()); + i != t.begets_end (); + ++i) + { + Type& d (i->derived ()); + emit (d); + dispatch (d); + collect (d); + } + } + + virtual Void + emit (SemanticGraph::Type& t) + { + using SemanticGraph::Schema; + + Schema* s (&dynamic_cast (t.scope ().scope ())); + + // If this is not a top-level schema, get one that + // includes/import/sources this schema. Top-level schema + // is either not used by any other schema or is imported + // into a special schema that doesn't have a namespace. + // + for (;;) + { + if (!s->used ()) + break; + + SemanticGraph::Uses& u (*s->used_begin ()); + Schema& us (u.user ()); + + if (us.names_begin () == us.names_end ()) + break; + + s = &us; + } + + + if (s != &schema_root && schemas_.find (s) == schemas_.end ()) + { + schemas_.insert (s); + + SemanticGraph::Path path (s->used_begin ()->path ()); + + // Try to use the portable representation of the path. If that + // fails, fall back to the native representation. + // + NarrowString path_str; + try + { + path_str = path.string (); + } + catch (SemanticGraph::InvalidPath const&) + { + path_str = path.native_file_string (); + } + + String inc_path (hxx_expr->merge (path_str)); + os << "#include " << process_include_path (inc_path) << endl + << endl; + } + } + + private: + Cult::Containers::Set types_; + Cult::Containers::Set schemas_; + + BaseInclude base_; + Traversal::Inherits inherits_; + + Traversal::Compositor compositor_; + Traversal::Element particle_; + Traversal::ContainsCompositor contains_compositor_; + Traversal::ContainsParticle contains_particle_; + + Traversal::Names names_; + Traversal::Attribute attribute_; + + Traversal::Belongs belongs_; + }; + + struct AggregateInclude: Traversal::Type, + Traversal::Element, + Context + { + AggregateInclude (Context& c, Char const* key) + : Context (c), key_ (key), type_include_ (c) + { + } + + virtual Void + traverse (SemanticGraph::Type& t) + { + if (t.context ().count (key_)) + type_include_.dispatch (t); + } + + virtual Void + traverse (SemanticGraph::Element& e) + { + if (e.context ().count (key_)) + type_include_.dispatch (e.type ()); + } + + private: + Char const* key_; + TypeInclude type_include_; + }; + } +} + +#endif // CXX_HYBRID_AGGREGATE_INCLUDE_HXX diff --git a/xsde/cxx/hybrid/cli.hxx b/xsde/cxx/hybrid/cli.hxx index 0d1ec70..80b91bc 100644 --- a/xsde/cxx/hybrid/cli.hxx +++ b/xsde/cxx/hybrid/cli.hxx @@ -41,6 +41,11 @@ namespace CXX extern Key generate_xml_schema; extern Key extern_xml_schema; extern Key suppress_reset; + extern Key generate_polymorphic; + extern Key runtime_polymorphic; + extern Key polymorphic_type; + extern Key generate_typeinfo; + extern Key polymorphic_schema; extern Key reuse_style_mixin; extern Key custom_data; extern Key custom_type; @@ -123,6 +128,11 @@ namespace CXX generate_xml_schema, Boolean, extern_xml_schema, NarrowString, suppress_reset, Boolean, + generate_polymorphic, Boolean, + runtime_polymorphic, Boolean, + polymorphic_type, Cult::Containers::Vector, + generate_typeinfo, Boolean, + polymorphic_schema, Cult::Containers::Vector, reuse_style_mixin, Boolean, custom_data, Cult::Containers::Vector, custom_type, Cult::Containers::Vector, diff --git a/xsde/cxx/hybrid/elements.cxx b/xsde/cxx/hybrid/elements.cxx index 80dc5c4..4edbc06 100644 --- a/xsde/cxx/hybrid/elements.cxx +++ b/xsde/cxx/hybrid/elements.cxx @@ -33,8 +33,7 @@ namespace CXX options (ops), exceptions (!ops.value ()), stl (!ops.value ()), - poly_code (false), - poly_runtime (false), + poly_code (ops.value ()), reset (!ops.value ()), detach (ops.value ()), mixin (ops.value ()), @@ -55,6 +54,10 @@ namespace CXX ixdrstream (ixdrstream_), oxdrstream (oxdrstream_) { + typeinfo = poly_code && + (ops.value () || + ops.value ()); + String xs_ns (xs_ns_name ()); string_type = L"::xsde::cxx::ro_string"; diff --git a/xsde/cxx/hybrid/elements.hxx b/xsde/cxx/hybrid/elements.hxx index 7f3ba3a..8452976 100644 --- a/xsde/cxx/hybrid/elements.hxx +++ b/xsde/cxx/hybrid/elements.hxx @@ -42,9 +42,9 @@ namespace CXX exceptions (c.exceptions), stl (c.stl), poly_code (c.poly_code), - poly_runtime (c.poly_runtime), reset (c.reset), detach (c.detach), + typeinfo (c.typeinfo), mixin (c.mixin), tiein (c.tiein), fwd_expr (c.fwd_expr), @@ -71,9 +71,9 @@ namespace CXX exceptions (c.exceptions), stl (c.stl), poly_code (c.poly_code), - poly_runtime (c.poly_runtime), reset (c.reset), detach (c.detach), + typeinfo (c.typeinfo), mixin (c.mixin), tiein (c.tiein), fwd_expr (c.fwd_expr), @@ -534,6 +534,12 @@ namespace CXX return t.context ().count ("recursive"); } + Boolean + polymorphic (SemanticGraph::Type& t) + { + return t.context ().count ("polymorphic"); + } + public: String istream (NarrowString const& is) const; @@ -559,9 +565,9 @@ namespace CXX Boolean exceptions; Boolean stl; Boolean poly_code; - Boolean poly_runtime; Boolean reset; Boolean detach; + Boolean typeinfo; Boolean mixin; Boolean tiein; diff --git a/xsde/cxx/hybrid/generator.cxx b/xsde/cxx/hybrid/generator.cxx index 14afad6..3eba4ba 100644 --- a/xsde/cxx/hybrid/generator.cxx +++ b/xsde/cxx/hybrid/generator.cxx @@ -129,6 +129,11 @@ namespace CXX extern Key generate_xml_schema = "generate-xml-schema"; extern Key extern_xml_schema = "extern-xml-schema"; extern Key suppress_reset = "suppress-reset"; + extern Key generate_polymorphic = "generate-polymorphic"; + extern Key runtime_polymorphic = "runtime-polymorphic"; + extern Key polymorphic_type = "polymorphic-type"; + extern Key generate_typeinfo = "generate-typeinfo"; + extern Key polymorphic_schema = "polymorphic-schema"; extern Key reuse_style_mixin = "reuse-style-mixin"; extern Key custom_data = "custom-data"; extern Key custom_type = "custom-type"; @@ -285,6 +290,32 @@ namespace CXX << " reset code." << endl; + e << "--generate-polymorphic" << endl + << " Generate polymorphism-aware code. Specify this\n" + << " option if you use substitution groups or xsi:type." + << endl; + + e << "--runtime-polymorphic" << endl + << " Generate non-polymorphic code that uses the\n" + << " runtime library configured with polymorphism\n" + << " support." + << endl; + + e << "--polymorphic-type " << endl + << " Indicate that is a root of a polymorphic\n" + << " type hierarchy." + << endl; + + e << "--generate-typeinfo" << endl + << " Generate type information functions for\n" + << " polymorphic object model types." + << endl; + + e << "--polymorphic-schema " << endl + << " Indicate that contains derivations of\n" + << " polymorphic types." + << endl; + e << "--reuse-style-mixin" << endl << " Generate code that supports the mixin base\n" << " parser/serializer implementation reuse style." @@ -783,6 +814,8 @@ namespace CXX r->value () = h.value (); r->value () = h.value (); r->value () = h.value (); + r->value () = h.value (); + r->value () = h.value (); r->value () = h.value (); r->value () = h.value (); r->value () = h.value (); @@ -862,6 +895,8 @@ namespace CXX r->value () = h.value (); r->value () = h.value (); r->value () = h.value (); + r->value () = h.value (); + r->value () = h.value (); r->value () = h.value (); r->value () = h.value (); r->value () = h.value (); @@ -924,16 +959,44 @@ namespace CXX Void Hybrid::Generator:: calculate_size (CLI::Options const& ops, XSDFrontend::SemanticGraph::Schema& schema, - XSDFrontend::SemanticGraph::Path const& file) + XSDFrontend::SemanticGraph::Path const& file, + const WarningSet& disabled_warnings) { // Determine which types are fixed/variable-sized. // TreeSizeProcessor proc; - if (!proc.process (ops, schema, file)) + if (!proc.process (ops, schema, file, disabled_warnings)) throw Failed (); } + Void Hybrid::Generator:: + process_tree_names (CLI::Options const& ops, + XSDFrontend::SemanticGraph::Schema& schema, + XSDFrontend::SemanticGraph::Path const& file) + { + TreeNameProcessor proc; + proc.process (ops, schema, file, false); + } + + Void Hybrid::Generator:: + process_parser_names (CLI::Options const& ops, + XSDFrontend::SemanticGraph::Schema& schema, + XSDFrontend::SemanticGraph::Path const& file) + { + ParserNameProcessor proc; + proc.process (ops, schema, file, false); + } + + Void Hybrid::Generator:: + process_serializer_names (CLI::Options const& ops, + XSDFrontend::SemanticGraph::Schema& schema, + XSDFrontend::SemanticGraph::Path const& file) + { + SerializerNameProcessor proc; + proc.process (ops, schema, file, false); + } + namespace { template @@ -1095,7 +1158,7 @@ namespace CXX // { TreeNameProcessor proc; - proc.process (ops, schema, file_path); + proc.process (ops, schema, file_path, true); } // Generate code. @@ -1819,7 +1882,7 @@ namespace CXX // { ParserNameProcessor proc; - proc.process (ops, schema, file_path); + proc.process (ops, schema, file_path, true); } NarrowString name (file_path.leaf ()); @@ -1976,6 +2039,8 @@ namespace CXX guard_prefix += '_'; + Boolean aggr (ops.value ()); + // HXX // { @@ -2012,6 +2077,14 @@ namespace CXX hxx << "#include " << endl << endl; + // Define omit aggregate macro. + // + hxx << "#ifndef XSDE_OMIT_PAGGR" << endl + << "# define XSDE_OMIT_PAGGR" << endl + << "# define " << guard << "_CLEAR_OMIT_PAGGR" << endl + << "#endif" << endl + << endl; + // Set auto-indentation. // Indentation::Clip hxx_clip (hxx); @@ -2021,9 +2094,24 @@ namespace CXX generate_parser_header (ctx); - if (ops.value ()) + // Clear omit aggregate macro. + // + hxx << "#ifdef " << guard << "_CLEAR_OMIT_PAGGR" << endl + << "# undef XSDE_OMIT_PAGGR" << endl + << "#endif" << endl + << endl; + + if (aggr) + { + hxx << "#ifndef XSDE_OMIT_PAGGR" << endl + << endl; + generate_parser_aggregate_header (ctx); + hxx << "#endif // XSDE_OMIT_PAGGR" << endl + << endl; + } + hxx << "#include " << endl << endl; } @@ -2090,7 +2178,7 @@ namespace CXX generate_parser_source (ctx); - if (ops.value ()) + if (aggr) generate_parser_aggregate_source (ctx); } @@ -2198,7 +2286,7 @@ namespace CXX // { SerializerNameProcessor proc; - proc.process (ops, schema, file_path); + proc.process (ops, schema, file_path, true); } NarrowString name (file_path.leaf ()); @@ -2342,6 +2430,7 @@ namespace CXX if (guard_prefix) guard_prefix += '_'; + Boolean aggr (ops.value ()); // HXX // @@ -2379,6 +2468,14 @@ namespace CXX hxx << "#include " << endl << endl; + // Define omit aggregate macro. + // + hxx << "#ifndef XSDE_OMIT_SAGGR" << endl + << "# define XSDE_OMIT_SAGGR" << endl + << "# define " << guard << "_CLEAR_OMIT_SAGGR" << endl + << "#endif" << endl + << endl; + // Set auto-indentation. // Indentation::Clip hxx_clip (hxx); @@ -2388,9 +2485,24 @@ namespace CXX generate_serializer_header (ctx); - if (ops.value ()) + // Clear omit aggregate macro. + // + hxx << "#ifdef " << guard << "_CLEAR_OMIT_SAGGR" << endl + << "# undef XSDE_OMIT_SAGGR" << endl + << "#endif" << endl + << endl; + + if (aggr) + { + hxx << "#ifndef XSDE_OMIT_SAGGR" << endl + << endl; + generate_serializer_aggregate_header (ctx); + hxx << "#endif // XSDE_OMIT_SAGGR" << endl + << endl; + } + hxx << "#include " << endl << endl; } @@ -2457,7 +2569,7 @@ namespace CXX generate_serializer_source (ctx); - if (ops.value ()) + if (aggr) generate_serializer_aggregate_source (ctx); } diff --git a/xsde/cxx/hybrid/generator.hxx b/xsde/cxx/hybrid/generator.hxx index ff29750..6f506b2 100644 --- a/xsde/cxx/hybrid/generator.hxx +++ b/xsde/cxx/hybrid/generator.hxx @@ -44,42 +44,67 @@ namespace CXX static Serializer::CLI::Options* serializer_options (CLI::Options const&); - struct Failed {}; - + // Calculate type sizes. + // static Void calculate_size ( - CLI::Options const& options, + CLI::Options const&, XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file); + XSDFrontend::SemanticGraph::Path const&, + WarningSet const& disabled_warnings); + + // Assign names to global declarations. + // + static Void + process_tree_names ( + CLI::Options const&, + XSDFrontend::SemanticGraph::Schema&, + XSDFrontend::SemanticGraph::Path const&); + + static Void + process_parser_names ( + CLI::Options const&, + XSDFrontend::SemanticGraph::Schema&, + XSDFrontend::SemanticGraph::Path const&); + + static Void + process_serializer_names ( + CLI::Options const&, + XSDFrontend::SemanticGraph::Schema&, + XSDFrontend::SemanticGraph::Path const&); + + // Generate code. + // + struct Failed {}; static UnsignedLong generate_tree ( - CLI::Options const& options, + CLI::Options const&, XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file, - const WarningSet& disabled_warnings, + XSDFrontend::SemanticGraph::Path const&, + WarningSet const& disabled_warnings, TypeMap::Namespaces& parser_type_map, TypeMap::Namespaces& serializer_type_map, - FileList& file_list, - AutoUnlinks& unlinks); + FileList&, + AutoUnlinks&); static UnsignedLong generate_parser ( - CLI::Options const& options, + CLI::Options const&, XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file, - const WarningSet& disabled_warnings, - FileList& file_list, - AutoUnlinks& unlinks); + XSDFrontend::SemanticGraph::Path const&, + WarningSet const& disabled_warnings, + FileList&, + AutoUnlinks&); static UnsignedLong generate_serializer ( - CLI::Options const& options, + CLI::Options const&, XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file, - const WarningSet& disabled_warnings, - FileList& file_list, - AutoUnlinks& unlinks); + XSDFrontend::SemanticGraph::Path const&, + WarningSet const& disabled_warnings, + FileList&, + AutoUnlinks&); private: Generator (); diff --git a/xsde/cxx/hybrid/parser-aggregate-header.cxx b/xsde/cxx/hybrid/parser-aggregate-header.cxx index a717c68..c75eb54 100644 --- a/xsde/cxx/hybrid/parser-aggregate-header.cxx +++ b/xsde/cxx/hybrid/parser-aggregate-header.cxx @@ -4,11 +4,12 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include +#include #include #include -#include #include namespace CXX @@ -17,10 +18,6 @@ namespace CXX { namespace { - typedef - Cult::Containers::Map - TypeInstanceMap; - typedef Cult::Containers::Set InstanceSet; // For base types we only want member's types, but not the @@ -108,8 +105,15 @@ namespace CXX Context { - ParserDef (Context& c, TypeInstanceMap& map, InstanceSet& set) - : Context (c), map_ (map), set_ (set), base_ (c) + ParserDef (Context& c, + TypeInstanceMap& map, + TypeIdInstanceMap& tid_map, + InstanceSet& set) + : Context (c), + map_ (map), + tid_map_ (tid_map), + set_ (set), + base_ (c) { *this >> inherits_ >> base_ >> inherits_; @@ -136,8 +140,10 @@ namespace CXX { if (map_.find (&t) == map_.end ()) { - String inst (find_instance_name (t)); - map_[&t] = inst; + map_[&t] = find_instance_name (t); + + if (polymorphic (t)) + collect (t); } } @@ -146,10 +152,12 @@ namespace CXX { if (map_.find (&l) == map_.end ()) { - String inst (find_instance_name (l)); - map_[&l] = inst; + map_[&l] = find_instance_name (l); dispatch (l.argumented ().type ()); + + if (polymorphic (l)) + collect (l); } } @@ -158,8 +166,7 @@ namespace CXX { if (map_.find (&c) == map_.end ()) { - String inst (find_instance_name (c)); - map_[&c] = inst; + map_[&c] = find_instance_name (c); // Use base type's parsers in case of a restriction // since we are not capable of using a derived type @@ -172,6 +179,38 @@ namespace CXX names (c); contains_compositor (c); } + + if (polymorphic (c)) + collect (c); + } + } + + virtual Void + collect (SemanticGraph::Type& t) + { + using SemanticGraph::Type; + + for (Type::BegetsIterator i (t.begets_begin ()); + i != t.begets_end (); + ++i) + { + Type& d (i->derived ()); + + String id (d.name ()); + if (String ns = xml_ns_name (d)) + { + id += L' '; + id += ns; + } + + dispatch (d); + + if (tid_map_.find (id) == tid_map_.end ()) + { + tid_map_[id].type = &d; + tid_map_[id].name = map_.find (&d)->second; + collect (d); + } } } @@ -475,10 +514,7 @@ namespace CXX fund_type (SemanticGraph::Type& t, String const& name) { if (map_.find (&t) == map_.end ()) - { - String inst (find_instance_name (name)); - map_[&t] = inst; - } + map_[&t] = find_instance_name (name); } String @@ -504,6 +540,7 @@ namespace CXX } TypeInstanceMap& map_; + TypeIdInstanceMap& tid_map_; InstanceSet& set_; BaseType base_; @@ -535,37 +572,65 @@ namespace CXX if (!tc.count ("paggr")) return; + Boolean poly (polymorphic (t)); String const& name (tc.get ("paggr")); - String pre (unclash (name, "pre")); - String post (unclash (name, "post")); + String pre; + String post; String root_parser (unclash (name, "root_parser")); + String root_map; String error, reset; + String parser_map, parser_map_entries; InstanceSet set; - set.insert (pre); - set.insert (post); set.insert (name); set.insert (root_parser); - if (!exceptions) + if (poly) + { + root_map = unclash (name, "root_map"); + set.insert (root_map); + } + else + { + pre = unclash (name, "pre"); + post = unclash (name, "post"); + + set.insert (pre); + set.insert (post); + } + + if (!poly && !exceptions) { error = unclash (name, "_error"); set.insert (error); } - if (Context::reset) + if (!poly && Context::reset) { reset = unclash (name, "reset"); set.insert (reset); } + if (poly_code) + { + parser_map = unclash (name, "parser_map_"); + parser_map_entries = unclash (name, "parser_map_entries_"); + + tc.set ("paggr-parser-map", parser_map); + tc.set ("paggr-parser-map-entries", parser_map_entries); + } + tc.set ("paggr-map", TypeInstanceMap ()); TypeInstanceMap& map (tc.get ("paggr-map")); + TypeIdInstanceMap tid_map; - ParserDef def (*this, map, set); + ParserDef def (*this, map, tid_map, set); def.dispatch (t); + if (poly_code && !tid_map.empty ()) + tc.set ("paggr-tid-map", tid_map); + String const& root_member (map.find (&t)->second); os << "// Parser aggregate for the " << comment (t.name ()) << @@ -581,24 +646,27 @@ namespace CXX os << name << " ();" << endl; - // pre () - // - os << "void" << endl - << pre << " ()" - << "{" - << "this->" << root_member << ".pre ();" - << "}"; + if (!poly) + { + // pre () + // + os << "void" << endl + << pre << " ()" + << "{" + << "this->" << root_member << ".pre ();" + << "}"; - // post () - // - String const& ret (pret_type (t)); + // post () + // + String const& ret (pret_type (t)); - os << ret << endl - << post << " ()" - << "{" - << (ret == L"void" ? "" : "return ") << "this->" << - root_member << "." << post_name (t) << " ();" - << "}"; + os << ret << endl + << post << " ()" + << "{" + << (ret == L"void" ? "" : "return ") << "this->" << + root_member << "." << post_name (t) << " ();" + << "}"; + } // root_parser () // @@ -608,9 +676,23 @@ namespace CXX << "return this->" << root_member << ";" << "}"; + if (poly) + { + // root_map () + // + if (poly) + { + os << "const " << xs_ns_name () + L"::parser_map&" << endl + << root_map << " ()" + << "{" + << "return this->" << parser_map << ";" + << "}"; + } + } + // _error () // - if (error) + if (!poly && error) { os << xs_ns_name () << "::parser_error" << endl << error << " ()" @@ -626,8 +708,12 @@ namespace CXX os << "void" << endl << reset << " ()" << "{" - << "this->" << root_member << "._reset ();" - << "}"; + << "this->" << root_member << "._reset ();"; + + if (poly && tid_map.size () > 0) + os << "this->" << parser_map << ".reset ();"; + + os << "}"; } os << "public:" << endl; @@ -636,6 +722,13 @@ namespace CXX i != end; ++i) os << fq_name (*i->first, "p:impl") << " " << i->second << ";"; + if (tid_map.size () > 0) + { + os << endl + << "::xsde::cxx::hybrid::parser_map_impl " << parser_map << ";" + << "::xsde::cxx::hybrid::parser_map_impl::entry " << + parser_map_entries << "[" << tid_map.size () << "UL];"; + } os << "};"; } }; @@ -656,41 +749,70 @@ namespace CXX return; SemanticGraph::Type& t (e.type ()); + Boolean poly (polymorphic (t)); String const& name (ec.get ("paggr")); - String pre (unclash (name, "pre")); - String post (unclash (name, "post")); + String pre; + String post; String root_parser (unclash (name, "root_parser")); + String root_map; String root_name (unclash (name, "root_name")); String root_namespace (unclash (name, "root_namespace")); String error, reset; + String parser_map, parser_map_entries; InstanceSet set; - set.insert (pre); - set.insert (post); set.insert (name); set.insert (root_parser); + + if (poly) + { + root_map = unclash (name, "root_map"); + set.insert (root_map); + } + else + { + pre = unclash (name, "pre"); + post = unclash (name, "post"); + + set.insert (pre); + set.insert (post); + } + set.insert (root_name); set.insert (root_namespace); - if (!exceptions) + if (!poly && !exceptions) { error = unclash (name, "_error"); set.insert (error); } - if (Context::reset) + if (!poly && Context::reset) { reset = unclash (name, "reset"); set.insert (reset); } + if (poly_code) + { + parser_map = unclash (name, "parser_map_"); + parser_map_entries = unclash (name, "parser_map_entries_"); + + ec.set ("paggr-parser-map", parser_map); + ec.set ("paggr-parser-map-entries", parser_map_entries); + } + ec.set ("paggr-map", TypeInstanceMap ()); TypeInstanceMap& map (ec.get ("paggr-map")); + TypeIdInstanceMap tid_map; - ParserDef def (*this, map, set); + ParserDef def (*this, map, tid_map, set); def.dispatch (t); + if (poly_code && !tid_map.empty ()) + ec.set ("paggr-tid-map", tid_map); + String const& root_member (map.find (&t)->second); os << "// Parser aggregate for the " << comment (e.name ()) << @@ -706,24 +828,27 @@ namespace CXX os << name << " ();" << endl; - // pre () - // - os << "void" << endl - << pre << " ()" - << "{" - << "this->" << root_member << ".pre ();" - << "}"; + if (!poly) + { + // pre () + // + os << "void" << endl + << pre << " ()" + << "{" + << "this->" << root_member << ".pre ();" + << "}"; - // post () - // - String const& ret (pret_type (t)); + // post () + // + String const& ret (pret_type (t)); - os << ret << endl - << post << " ()" - << "{" - << (ret == L"void" ? "" : "return ") << "this->" << - root_member << "." << post_name (t) << " ();" - << "}"; + os << ret << endl + << post << " ()" + << "{" + << (ret == L"void" ? "" : "return ") << "this->" << + root_member << "." << post_name (t) << " ();" + << "}"; + } // root_parser () // @@ -733,6 +858,20 @@ namespace CXX << "return this->" << root_member << ";" << "}"; + if (poly) + { + // root_map () + // + if (poly) + { + os << "const " << xs_ns_name () + L"::parser_map&" << endl + << root_map << " ()" + << "{" + << "return this->" << parser_map << ";" + << "}"; + } + } + // root_name () // os << "static const char*" << endl @@ -747,7 +886,7 @@ namespace CXX // _error () // - if (error) + if (!poly && error) { os << xs_ns_name () << "::parser_error" << endl << error << " ()" @@ -763,8 +902,12 @@ namespace CXX os << "void" << endl << reset << " ()" << "{" - << "this->" << root_member << "._reset ();" - << "}"; + << "this->" << root_member << "._reset ();"; + + if (poly && tid_map.size () > 0) + os << "this->" << parser_map << ".reset ();"; + + os << "}"; } os << "public:" << endl; @@ -773,6 +916,14 @@ namespace CXX i != end; ++i) os << fq_name (*i->first, "p:impl") << " " << i->second << ";"; + if (tid_map.size () > 0) + { + os << endl + << "::xsde::cxx::hybrid::parser_map_impl " << parser_map << ";" + << "::xsde::cxx::hybrid::parser_map_impl::entry " << + parser_map_entries << "[" << tid_map.size () << "UL];"; + } + os << "};"; } }; @@ -801,6 +952,10 @@ namespace CXX if (gen) { + if (ctx.poly_code) + ctx.os << "#include " << endl + << endl; + // Emit "weak" header includes that are used in the file-per-type // compilation model. // @@ -813,6 +968,28 @@ namespace CXX schema.dispatch (ctx.schema_root); } + // Emit includes for additional schemas that define derived + // polymorphic types. + // + if (ctx.poly_code) + { + Traversal::Schema schema; + Traversal::Sources sources; + + schema >> sources >> schema; + + Traversal::Names schema_names; + Traversal::Namespace ns; + Traversal::Names names; + AggregateInclude include (ctx, "paggr"); + + schema >> schema_names >> ns >> names >> include; + + schema.dispatch (ctx.schema_root); + } + + // Generate code. + // Traversal::Schema schema; Traversal::Sources sources; diff --git a/xsde/cxx/hybrid/parser-aggregate-source.cxx b/xsde/cxx/hybrid/parser-aggregate-source.cxx index 6e80318..055cffb 100644 --- a/xsde/cxx/hybrid/parser-aggregate-source.cxx +++ b/xsde/cxx/hybrid/parser-aggregate-source.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include #include #include @@ -16,10 +17,6 @@ namespace CXX { namespace { - typedef - Cult::Containers::Map - TypeInstanceMap; - // // struct ParticleArg: Traversal::Element, Context @@ -186,6 +183,57 @@ namespace CXX TypeInstanceMap& map_; }; + // + // + struct ParserMapConnect: Traversal::Complex, + Traversal::Element, + Context + { + ParserMapConnect (Context& c, String const& inst, String const& map) + : Context (c), inst_ (inst), map_ (map) + { + *this >> inherits_ >> *this; + + *this >> contains_compositor_; + contains_compositor_ >> compositor_; + compositor_ >> contains_particle_; + contains_particle_ >> compositor_; + contains_particle_ >> *this; + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + inherits (c); + + if (!restriction_p (c)) + contains_compositor (c); + } + + virtual Void + traverse (SemanticGraph::Element& e) + { + SemanticGraph::Type& t (e.type ()); + + if (polymorphic (t)) + { + os << "this->" << inst_ << "." << + e.context ().get ("p:parser") << " (" << map_ << ");"; + } + } + + private: + String const& inst_; + String const& map_; + + Traversal::Inherits inherits_; + + Traversal::Compositor compositor_; + Traversal::Element particle_; + Traversal::ContainsCompositor contains_compositor_; + Traversal::ContainsParticle contains_particle_; + }; + struct GlobalType: Traversal::Type, Context { GlobalType (Context& c) @@ -208,18 +256,67 @@ namespace CXX << "//" << endl << endl; + TypeIdInstanceMap* tid_map (0); + + if (poly_code && tc.count ("paggr-tid-map")) + tid_map = &tc.get ("paggr-tid-map"); + // c-tor () // os << name << "::" << endl - << name << " ()" - << "{"; + << name << " ()"; + + if (tid_map) + { + os << endl + << ": " << tc.get ("paggr-parser-map") << " (" << + tc.get ("paggr-parser-map-entries") << ", " << + tid_map->size () << "UL)"; + } + + os << "{"; + // Populate the polymorphic parser map. + // + if (tid_map) + { + String const& entry (tc.get ("paggr-parser-map-entries")); + + Size n (0); + + for (TypeIdInstanceMap::Iterator i (tid_map->begin ()); + i != tid_map->end (); + ++i, ++n) + { + os << entry << "[" << n << "UL].type_id = " << + fq_name (*i->second.type, "p:name") << "::_static_type ();" + << entry << "[" << n << "UL].parser = &this->" << + i->second.name << ";" + << endl; + } + } + + // Connect parsers. + // ParserConnect connect (*this, map); for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) connect.dispatch (*i->first); + // Connect the parser map. + // + if (tid_map) + { + for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); + i != end; ++i) + { + ParserMapConnect t ( + *this, i->second, tc.get ("paggr-parser-map")); + t.dispatch (*i->first); + } + } + os << "}"; } }; @@ -246,18 +343,67 @@ namespace CXX << "//" << endl << endl; + TypeIdInstanceMap* tid_map (0); + + if (poly_code && ec.count ("paggr-tid-map")) + tid_map = &ec.get ("paggr-tid-map"); + // c-tor () // os << name << "::" << endl - << name << " ()" - << "{"; + << name << " ()"; + + if (tid_map) + { + os << endl + << ": " << ec.get ("paggr-parser-map") << " (" << + ec.get ("paggr-parser-map-entries") << ", " << + tid_map->size () << "UL)"; + } + + os << "{"; + + // Populate the polymorphic parser map. + // + if (tid_map) + { + String const& entry (ec.get ("paggr-parser-map-entries")); + + Size n (0); + + for (TypeIdInstanceMap::Iterator i (tid_map->begin ()); + i != tid_map->end (); + ++i, ++n) + { + os << entry << "[" << n << "UL].type_id = " << + fq_name (*i->second.type, "p:name") << "::_static_type ();" + << entry << "[" << n << "UL].parser = &this->" << + i->second.name << ";" + << endl; + } + } + // Connect parsers. + // ParserConnect connect (*this, map); for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) connect.dispatch (*i->first); + // Connect the parser map. + // + if (tid_map) + { + for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); + i != end; ++i) + { + ParserMapConnect t ( + *this, i->second, ec.get ("paggr-parser-map")); + t.dispatch (*i->first); + } + } + os << "}"; // root_name () diff --git a/xsde/cxx/hybrid/parser-header.cxx b/xsde/cxx/hybrid/parser-header.cxx index 72cc2e3..6a893c5 100644 --- a/xsde/cxx/hybrid/parser-header.cxx +++ b/xsde/cxx/hybrid/parser-header.cxx @@ -347,6 +347,34 @@ namespace CXX } }; + // + // + struct PostOverride: Traversal::Complex, Context + { + PostOverride (Context& c) + : Context (c) + { + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + if (c.inherits_p ()) + { + SemanticGraph::Type& b (c.inherits ().base ()); + + if (polymorphic (b)) + { + if (tiein) + dispatch (b); + + os << "virtual " << pret_type (b) << endl + << post_name (b) << " ();" + << endl; + } + } + } + }; // // @@ -354,6 +382,8 @@ namespace CXX { Complex (Context& c) : Context (c), + post_override_ (c), + // State. // compositor_state_ (c), @@ -472,6 +502,9 @@ namespace CXX // post // + if (polymorphic (c)) + post_override_.dispatch (c); + os << "virtual " << ret << endl << post_name (c) << " ();" << endl; @@ -546,6 +579,8 @@ namespace CXX } private: + PostOverride post_override_; + // State. // CompositorState compositor_state_; diff --git a/xsde/cxx/hybrid/parser-name-processor.cxx b/xsde/cxx/hybrid/parser-name-processor.cxx index 740cf36..c635aec 100644 --- a/xsde/cxx/hybrid/parser-name-processor.cxx +++ b/xsde/cxx/hybrid/parser-name-processor.cxx @@ -657,7 +657,8 @@ namespace CXX Void process_impl (CLI::Options const& ops, SemanticGraph::Schema& tu, - SemanticGraph::Path const& file) + SemanticGraph::Path const& file, + Boolean deep) { Context ctx (ops, tu, file); @@ -686,6 +687,9 @@ namespace CXX schema.dispatch (tu); } + if (!deep) + return; + // Pass two - assign names inside complex types. Here we don't // need to go into included/imported schemas. // @@ -717,9 +721,10 @@ namespace CXX Void ParserNameProcessor:: process (CLI::Options const& ops, SemanticGraph::Schema& tu, - SemanticGraph::Path const& file) + SemanticGraph::Path const& file, + Boolean deep) { - process_impl (ops, tu, file); + process_impl (ops, tu, file, deep); } } } diff --git a/xsde/cxx/hybrid/parser-name-processor.hxx b/xsde/cxx/hybrid/parser-name-processor.hxx index ea3e985..d0e1970 100644 --- a/xsde/cxx/hybrid/parser-name-processor.hxx +++ b/xsde/cxx/hybrid/parser-name-processor.hxx @@ -24,7 +24,8 @@ namespace CXX Void process (CLI::Options const& options, XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file); + XSDFrontend::SemanticGraph::Path const& file, + Boolean deep); }; } } diff --git a/xsde/cxx/hybrid/parser-source.cxx b/xsde/cxx/hybrid/parser-source.cxx index 4c4237c..505d661 100644 --- a/xsde/cxx/hybrid/parser-source.cxx +++ b/xsde/cxx/hybrid/parser-source.cxx @@ -904,11 +904,59 @@ namespace CXX // // + struct PostOverride: Traversal::Complex, Context + { + PostOverride (Context& c) + : Context (c), scope_ (0) + { + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + Boolean clear (false); + + if (scope_ == 0) + { + scope_ = &c; + clear = true; + } + + if (c.inherits_p ()) + { + SemanticGraph::Type& b (c.inherits ().base ()); + + if (polymorphic (b)) + { + if (tiein) + dispatch (b); + + String const& scope (epimpl_custom (*scope_)); + + os << pret_type (b) << " " << scope << "::" << endl + << post_name (b) << " ()" + << "{" + << "return this->" << post_name (c) << " ();" + << "}"; + } + } + + if (clear) + scope_ = 0; + } + + private: + SemanticGraph::Complex* scope_; + }; + + // + // struct Complex: Traversal::Complex, Context { Complex (Context& c) : Context (c), base_name_ (c, TypeName::base), + post_override_ (c), compositor_callback_ (c), particle_callback_ (c), attribute_callback_ (c) @@ -1253,6 +1301,9 @@ namespace CXX // post // + if (polymorphic (c)) + post_override_.dispatch (c); + os << ret << " " << name << "::" << endl << post_name (c) << " ()" << "{"; @@ -1350,6 +1401,7 @@ namespace CXX private: TypeName base_name_; + PostOverride post_override_; CompositorCallback compositor_callback_; ParticleCallback particle_callback_; diff --git a/xsde/cxx/hybrid/serializer-aggregate-header.cxx b/xsde/cxx/hybrid/serializer-aggregate-header.cxx index b697715..3e3260f 100644 --- a/xsde/cxx/hybrid/serializer-aggregate-header.cxx +++ b/xsde/cxx/hybrid/serializer-aggregate-header.cxx @@ -4,6 +4,8 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include +#include #include #include @@ -17,10 +19,6 @@ namespace CXX { namespace { - typedef - Cult::Containers::Map - TypeInstanceMap; - typedef Cult::Containers::Set InstanceSet; // For base types we only want member's types, but not the @@ -108,8 +106,15 @@ namespace CXX Context { - SerializerDef (Context& c, TypeInstanceMap& map, InstanceSet& set) - : Context (c), map_ (map), set_ (set), base_ (c) + SerializerDef (Context& c, + TypeInstanceMap& map, + TypeIdInstanceMap& tid_map, + InstanceSet& set) + : Context (c), + map_ (map), + tid_map_ (tid_map), + set_ (set), + base_ (c) { *this >> inherits_ >> base_ >> inherits_; @@ -136,8 +141,10 @@ namespace CXX { if (map_.find (&t) == map_.end ()) { - String inst (find_instance_name (t)); - map_[&t] = inst; + map_[&t] = find_instance_name (t); + + if (polymorphic (t)) + collect (t); } } @@ -146,10 +153,11 @@ namespace CXX { if (map_.find (&l) == map_.end ()) { - String inst (find_instance_name (l)); - map_[&l] = inst; - + map_[&l] = find_instance_name (l); dispatch (l.argumented ().type ()); + + if (polymorphic (l)) + collect (l); } } @@ -158,8 +166,7 @@ namespace CXX { if (map_.find (&c) == map_.end ()) { - String inst (find_instance_name (c)); - map_[&c] = inst; + map_[&c] = find_instance_name (c); // Use base type's serializers in case of a restriction // since we are not capable of using a derived type @@ -172,6 +179,38 @@ namespace CXX names (c); contains_compositor (c); } + + if (polymorphic (c)) + collect (c); + } + } + + virtual Void + collect (SemanticGraph::Type& t) + { + using SemanticGraph::Type; + + for (Type::BegetsIterator i (t.begets_begin ()); + i != t.begets_end (); + ++i) + { + Type& d (i->derived ()); + + String id (d.name ()); + if (String ns = xml_ns_name (d)) + { + id += L' '; + id += ns; + } + + dispatch (d); + + if (tid_map_.find (id) == tid_map_.end ()) + { + tid_map_[id].type = &d; + tid_map_[id].name = map_.find (&d)->second; + collect (d); + } } } @@ -475,10 +514,7 @@ namespace CXX fund_type (SemanticGraph::Type& t, String const& name) { if (map_.find (&t) == map_.end ()) - { - String inst (find_instance_name (name)); - map_[&t] = inst; - } + map_[&t] = find_instance_name (name); } String @@ -504,6 +540,7 @@ namespace CXX } TypeInstanceMap& map_; + TypeIdInstanceMap& tid_map_; InstanceSet& set_; BaseType base_; @@ -535,37 +572,65 @@ namespace CXX if (!tc.count ("saggr")) return; + Boolean poly (polymorphic (t)); String const& name (tc.get ("saggr")); - String pre (unclash (name, "pre")); - String post (unclash (name, "post")); + String pre; + String post; String root_serializer (unclash (name, "root_serializer")); + String root_map; String error, reset; + String serializer_map, serializer_map_entries; InstanceSet set; - set.insert (pre); - set.insert (post); set.insert (name); set.insert (root_serializer); - if (!exceptions) + if (poly) + { + root_map = unclash (name, "root_map"); + set.insert (root_map); + } + else + { + pre = unclash (name, "pre"); + post = unclash (name, "post"); + + set.insert (pre); + set.insert (post); + } + + if (!poly && !exceptions) { error = unclash (name, "_error"); set.insert (error); } - if (Context::reset) + if (!poly && Context::reset) { reset = unclash (name, "reset"); set.insert (reset); } + if (poly_code) + { + serializer_map = unclash (name, "serializer_map_"); + serializer_map_entries = unclash (name, "serializer_map_entries_"); + + tc.set ("saggr-serializer-map", serializer_map); + tc.set ("saggr-serializer-map-entries", serializer_map_entries); + } + tc.set ("saggr-map", TypeInstanceMap ()); TypeInstanceMap& map (tc.get ("saggr-map")); + TypeIdInstanceMap tid_map; - SerializerDef def (*this, map, set); + SerializerDef def (*this, map, tid_map, set); def.dispatch (t); + if (poly_code && !tid_map.empty ()) + tc.set ("saggr-tid-map", tid_map); + String const& root_member (map.find (&t)->second); os << "// Serializer aggregate for the " << comment (t.name ()) << @@ -581,29 +646,32 @@ namespace CXX os << name << " ();" << endl; - // pre () - // - String const& arg (sarg_type (t)); + if (!poly) + { + // pre () + // + String const& arg (sarg_type (t)); - os << "void" << endl - << pre << " ("; + os << "void" << endl + << pre << " ("; - if (arg != L"void") - os << arg << " x"; + if (arg != L"void") + os << arg << " x"; - os <<")" - << "{" - << "this->" << root_member << ".pre (" << - (arg != L"void" ? "x" : "") << ");" - << "}"; + os <<")" + << "{" + << "this->" << root_member << ".pre (" << + (arg != L"void" ? "x" : "") << ");" + << "}"; - // post () - // - os << "void" << endl - << post << " ()" - << "{" - << "this->" << root_member << ".post ();" - << "}"; + // post () + // + os << "void" << endl + << post << " ()" + << "{" + << "this->" << root_member << ".post ();" + << "}"; + } // root_serializer () // @@ -613,9 +681,23 @@ namespace CXX << "return this->" << root_member << ";" << "}"; + if (poly) + { + // root_map () + // + if (poly) + { + os << "const " << xs_ns_name () + L"::serializer_map&" << endl + << root_map << " ()" + << "{" + << "return this->" << serializer_map << ";" + << "}"; + } + } + // _error () // - if (error) + if (!poly && error) { os << xs_ns_name () << "::serializer_error" << endl << error << " ()" @@ -631,8 +713,12 @@ namespace CXX os << "void" << endl << reset << " ()" << "{" - << "this->" << root_member << "._reset ();" - << "}"; + << "this->" << root_member << "._reset ();"; + + if (poly && tid_map.size () > 0) + os << "this->" << serializer_map << ".reset ();"; + + os << "}"; } os << "public:" << endl; @@ -641,6 +727,15 @@ namespace CXX i != end; ++i) os << fq_name (*i->first, "s:impl") << " " << i->second << ";"; + if (tid_map.size () > 0) + { + os << endl + << "::xsde::cxx::hybrid::serializer_map_impl " << + serializer_map << ";" + << "::xsde::cxx::hybrid::serializer_map_impl::entry " << + serializer_map_entries << "[" << tid_map.size () << "UL];"; + } + os << "};"; } }; @@ -661,41 +756,70 @@ namespace CXX return; SemanticGraph::Type& t (e.type ()); + Boolean poly (polymorphic (t)); String const& name (ec.get ("saggr")); - String pre (unclash (name, "pre")); - String post (unclash (name, "post")); + String pre; + String post; String root_serializer (unclash (name, "root_serializer")); + String root_map; String root_name (unclash (name, "root_name")); String root_namespace (unclash (name, "root_namespace")); String error, reset; + String serializer_map, serializer_map_entries; InstanceSet set; - set.insert (pre); - set.insert (post); set.insert (name); set.insert (root_serializer); + + if (poly) + { + root_map = unclash (name, "root_map"); + set.insert (root_map); + } + else + { + pre = unclash (name, "pre"); + post = unclash (name, "post"); + + set.insert (pre); + set.insert (post); + } + set.insert (root_name); set.insert (root_namespace); - if (!exceptions) + if (!poly && !exceptions) { error = unclash (name, "_error"); set.insert (error); } - if (Context::reset) + if (!poly && Context::reset) { reset = unclash (name, "reset"); set.insert (reset); } + if (poly_code) + { + serializer_map = unclash (name, "serializer_map_"); + serializer_map_entries = unclash (name, "serializer_map_entries_"); + + ec.set ("saggr-serializer-map", serializer_map); + ec.set ("saggr-serializer-map-entries", serializer_map_entries); + } + ec.set ("saggr-map", TypeInstanceMap ()); TypeInstanceMap& map (ec.get ("saggr-map")); + TypeIdInstanceMap tid_map; - SerializerDef def (*this, map, set); + SerializerDef def (*this, map, tid_map, set); def.dispatch (t); + if (poly_code && !tid_map.empty ()) + ec.set ("saggr-tid-map", tid_map); + String const& root_member (map.find (&t)->second); os << "// Serializer aggregate for the " << comment (e.name ()) << @@ -711,29 +835,32 @@ namespace CXX os << name << " ();" << endl; - // pre () - // - String const& arg (sarg_type (t)); + if (!poly) + { + // pre () + // + String const& arg (sarg_type (t)); - os << "void" << endl - << pre << " ("; + os << "void" << endl + << pre << " ("; - if (arg != L"void") - os << arg << " x"; + if (arg != L"void") + os << arg << " x"; - os <<")" - << "{" - << "this->" << root_member << ".pre (" << - (arg != L"void" ? "x" : "") << ");" - << "}"; + os <<")" + << "{" + << "this->" << root_member << ".pre (" << + (arg != L"void" ? "x" : "") << ");" + << "}"; - // post () - // - os << "void" << endl - << post << " ()" - << "{" - << "this->" << root_member << ".post ();" - << "}"; + // post () + // + os << "void" << endl + << post << " ()" + << "{" + << "this->" << root_member << ".post ();" + << "}"; + } // root_serializer () // @@ -743,6 +870,20 @@ namespace CXX << "return this->" << root_member << ";" << "}"; + if (poly) + { + // root_map () + // + if (poly) + { + os << "const " << xs_ns_name () + L"::serializer_map&" << endl + << root_map << " ()" + << "{" + << "return this->" << serializer_map << ";" + << "}"; + } + } + // root_name () // os << "static const char*" << endl @@ -757,7 +898,7 @@ namespace CXX // _error () // - if (error) + if (!poly && error) { os << xs_ns_name () << "::serializer_error" << endl << error << " ()" @@ -773,8 +914,12 @@ namespace CXX os << "void" << endl << reset << " ()" << "{" - << "this->" << root_member << "._reset ();" - << "}"; + << "this->" << root_member << "._reset ();"; + + if (poly && tid_map.size () > 0) + os << "this->" << serializer_map << ".reset ();"; + + os << "}"; } os << "public:" << endl; @@ -783,6 +928,15 @@ namespace CXX i != end; ++i) os << fq_name (*i->first, "s:impl") << " " << i->second << ";"; + if (tid_map.size () > 0) + { + os << endl + << "::xsde::cxx::hybrid::serializer_map_impl " << + serializer_map << ";" + << "::xsde::cxx::hybrid::serializer_map_impl::entry " << + serializer_map_entries << "[" << tid_map.size () << "UL];"; + } + os << "};"; } }; @@ -811,6 +965,10 @@ namespace CXX if (gen) { + if (ctx.poly_code) + ctx.os << "#include " << endl + << endl; + // Emit "weak" header includes that are used in the file-per-type // compilation model. // @@ -823,6 +981,28 @@ namespace CXX schema.dispatch (ctx.schema_root); } + // Emit includes for additional schemas that define derived + // polymorphic types. + // + if (ctx.poly_code) + { + Traversal::Schema schema; + Traversal::Sources sources; + + schema >> sources >> schema; + + Traversal::Names schema_names; + Traversal::Namespace ns; + Traversal::Names names; + AggregateInclude include (ctx, "saggr"); + + schema >> schema_names >> ns >> names >> include; + + schema.dispatch (ctx.schema_root); + } + + // Generate code. + // Traversal::Schema schema; Traversal::Sources sources; diff --git a/xsde/cxx/hybrid/serializer-aggregate-source.cxx b/xsde/cxx/hybrid/serializer-aggregate-source.cxx index 7e305b6..0422031 100644 --- a/xsde/cxx/hybrid/serializer-aggregate-source.cxx +++ b/xsde/cxx/hybrid/serializer-aggregate-source.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include #include #include @@ -16,10 +17,6 @@ namespace CXX { namespace { - typedef - Cult::Containers::Map - TypeInstanceMap; - // // struct ParticleArg: Traversal::Element, Context @@ -186,6 +183,62 @@ namespace CXX TypeInstanceMap& map_; }; + // + // + struct SerializerMapConnect: Traversal::Complex, + Traversal::Element, + Context + { + SerializerMapConnect (Context& c, + String const& inst, + String const& map) + : Context (c), inst_ (inst), map_ (map) + { + *this >> inherits_ >> *this; + + *this >> contains_compositor_; + contains_compositor_ >> compositor_; + compositor_ >> contains_particle_; + contains_particle_ >> compositor_; + contains_particle_ >> *this; + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + inherits (c); + + if (!restriction_p (c)) + contains_compositor (c); + } + + virtual Void + traverse (SemanticGraph::Element& e) + { + SemanticGraph::Type& t (e.type ()); + + if (polymorphic (t)) + { + os << "this->" << inst_ << "." << + e.context ().get ("s:serializer") << " (" << + map_ << ");"; + } + } + + private: + String const& inst_; + String const& map_; + + Traversal::Inherits inherits_; + + Traversal::Compositor compositor_; + Traversal::Element particle_; + Traversal::ContainsCompositor contains_compositor_; + Traversal::ContainsParticle contains_particle_; + }; + + // + // struct GlobalType: Traversal::Type, Context { GlobalType (Context& c) @@ -208,18 +261,68 @@ namespace CXX << "//" << endl << endl; + TypeIdInstanceMap* tid_map (0); + + if (poly_code && tc.count ("saggr-tid-map")) + tid_map = &tc.get ("saggr-tid-map"); + // c-tor () // os << name << "::" << endl - << name << " ()" - << "{"; + << name << " ()"; + + if (tid_map) + { + os << endl + << ": " << tc.get ("saggr-serializer-map") << " (" << + tc.get ("saggr-serializer-map-entries") << ", " << + tid_map->size () << "UL)"; + } + + os << "{"; + // Populate the polymorphic serializer map. + // + if (tid_map) + { + String const& entry ( + tc.get ("saggr-serializer-map-entries")); + + Size n (0); + + for (TypeIdInstanceMap::Iterator i (tid_map->begin ()); + i != tid_map->end (); + ++i, ++n) + { + os << entry << "[" << n << "UL].type_id = " << + fq_name (*i->second.type, "s:name") << "::_static_type ();" + << entry << "[" << n << "UL].serializer = &this->" << + i->second.name << ";" + << endl; + } + } + + // Connect parsers. + // SerializerConnect connect (*this, map); for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) connect.dispatch (*i->first); + // Connect the serializer map. + // + if (tid_map) + { + for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); + i != end; ++i) + { + SerializerMapConnect t ( + *this, i->second, tc.get ("saggr-serializer-map")); + t.dispatch (*i->first); + } + } + os << "}"; } }; @@ -246,18 +349,68 @@ namespace CXX << "//" << endl << endl; + TypeIdInstanceMap* tid_map (0); + + if (poly_code && ec.count ("saggr-tid-map")) + tid_map = &ec.get ("saggr-tid-map"); + // c-tor () // os << name << "::" << endl - << name << " ()" - << "{"; + << name << " ()"; + + if (tid_map) + { + os << endl + << ": " << ec.get ("saggr-serializer-map") << " (" << + ec.get ("saggr-serializer-map-entries") << ", " << + tid_map->size () << "UL)"; + } + + os << "{"; + + // Populate the polymorphic serializer map. + // + if (tid_map) + { + String const& entry ( + ec.get ("saggr-serializer-map-entries")); + + Size n (0); + + for (TypeIdInstanceMap::Iterator i (tid_map->begin ()); + i != tid_map->end (); + ++i, ++n) + { + os << entry << "[" << n << "UL].type_id = " << + fq_name (*i->second.type, "s:name") << "::_static_type ();" + << entry << "[" << n << "UL].serializer = &this->" << + i->second.name << ";" + << endl; + } + } + // Connect parsers. + // SerializerConnect connect (*this, map); for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) connect.dispatch (*i->first); + // Connect the serializer map. + // + if (tid_map) + { + for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); + i != end; ++i) + { + SerializerMapConnect t ( + *this, i->second, ec.get ("saggr-serializer-map")); + t.dispatch (*i->first); + } + } + os << "}"; // root_name () diff --git a/xsde/cxx/hybrid/serializer-header.cxx b/xsde/cxx/hybrid/serializer-header.cxx index 20f4e15..db0578f 100644 --- a/xsde/cxx/hybrid/serializer-header.cxx +++ b/xsde/cxx/hybrid/serializer-header.cxx @@ -343,10 +343,40 @@ namespace CXX // // + struct PreOverride: Traversal::Complex, Context + { + PreOverride (Context& c) + : Context (c) + { + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + if (c.inherits_p ()) + { + SemanticGraph::Type& b (c.inherits ().base ()); + + if (polymorphic (b)) + { + if (tiein) + dispatch (b); + + os << "virtual void" << endl + << "pre (" << sarg_type (b) << ");" + << endl; + } + } + } + }; + + // + // struct Complex : Traversal::Complex, Context { Complex (Context& c) : Context (c), + pre_override_ (c), // State. // @@ -422,6 +452,9 @@ namespace CXX // pre // + if (polymorphic (c)) + pre_override_.dispatch (c); + os << "virtual void" << endl << "pre (" << arg << ");" << endl; @@ -522,6 +555,8 @@ namespace CXX } private: + PreOverride pre_override_; + // State. // CompositorState compositor_state_; diff --git a/xsde/cxx/hybrid/serializer-name-processor.cxx b/xsde/cxx/hybrid/serializer-name-processor.cxx index ba4a268..2f7d296 100644 --- a/xsde/cxx/hybrid/serializer-name-processor.cxx +++ b/xsde/cxx/hybrid/serializer-name-processor.cxx @@ -265,7 +265,7 @@ namespace CXX if (!name) return; - String const& skel (lc.get ("p:name")); + String const& skel (lc.get ("s:name")); NameSet set; set.insert (name); @@ -672,7 +672,8 @@ namespace CXX Void process_impl (CLI::Options const& ops, SemanticGraph::Schema& tu, - SemanticGraph::Path const& file) + SemanticGraph::Path const& file, + Boolean deep) { Context ctx (ops, tu, file); @@ -701,6 +702,9 @@ namespace CXX schema.dispatch (tu); } + if (!deep) + return; + // Pass two - assign names inside complex types. Here we don't // need to go into included/imported schemas. // @@ -732,9 +736,10 @@ namespace CXX Void SerializerNameProcessor:: process (CLI::Options const& ops, SemanticGraph::Schema& tu, - SemanticGraph::Path const& file) + SemanticGraph::Path const& file, + Boolean deep) { - process_impl (ops, tu, file); + process_impl (ops, tu, file, deep); } } } diff --git a/xsde/cxx/hybrid/serializer-name-processor.hxx b/xsde/cxx/hybrid/serializer-name-processor.hxx index f69dfe4..b607c24 100644 --- a/xsde/cxx/hybrid/serializer-name-processor.hxx +++ b/xsde/cxx/hybrid/serializer-name-processor.hxx @@ -24,7 +24,8 @@ namespace CXX Void process (CLI::Options const& options, XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file); + XSDFrontend::SemanticGraph::Path const& file, + Boolean deep); }; } } diff --git a/xsde/cxx/hybrid/serializer-source.cxx b/xsde/cxx/hybrid/serializer-source.cxx index 6e82bd0..540d742 100644 --- a/xsde/cxx/hybrid/serializer-source.cxx +++ b/xsde/cxx/hybrid/serializer-source.cxx @@ -783,12 +783,35 @@ namespace CXX << esname (e) << " ()" << "{"; + if (polymorphic (t)) + { + if (stl) + { + os << "const ::std::string& dt = " << access << iter << + "->_dynamic_type ();" + << "if (dt != " << esskel (t) << "::_static_type ())" << endl + << "this->_context ().type_id (dt.c_str ());" + << endl; + } + else + { + os << "const char* dt = " << access << iter << + "->_dynamic_type ();" + << "if (strcmp (dt, " << esskel (t) << + "::_static_type ()) != 0)" << endl + << "this->_context ().type_id (dt);" + << endl; + } + } + if (ret != L"void") { os << "return "; type_pass_.dispatch (t); os << "*" << access << iter << "++;"; } + else + os << access << iter << "++;"; os << "}"; } @@ -807,6 +830,27 @@ namespace CXX << esname (e) << " ()" << "{"; + if (polymorphic (t)) + { + if (stl) + { + os << "const ::std::string& dt = " << access << ename (e) << + " ()._dynamic_type ();" + << "if (dt != " << esskel (t) << "::_static_type ())" << endl + << "this->_context ().type_id (dt.c_str ());" + << endl; + } + else + { + os << "const char* dt = " << access << ename (e) << + " ()._dynamic_type ();" + << "if (strcmp (dt, " << esskel (t) << + "::_static_type ()) != 0)" << endl + << "this->_context ().type_id (dt);" + << endl; + } + } + if (ret != L"void") { os << "return "; @@ -870,11 +914,59 @@ namespace CXX // // + struct PreOverride: Traversal::Complex, Context + { + PreOverride (Context& c) + : Context (c), scope_ (0) + { + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + Boolean clear (false); + + if (scope_ == 0) + { + scope_ = &c; + clear = true; + } + + if (c.inherits_p ()) + { + SemanticGraph::Type& b (c.inherits ().base ()); + + if (polymorphic (b)) + { + if (tiein) + dispatch (b); + + String const& scope (esimpl_custom (*scope_)); + + os << "void " << scope << "::" << endl + << "pre (" << sarg_type (b) << " x)" + << "{" + << "this->pre (static_cast< " << sarg_type (c) << " > (x));" + << "}"; + } + } + + if (clear) + scope_ = 0; + } + + private: + SemanticGraph::Complex* scope_; + }; + + // + // struct Complex: Traversal::Complex, Context { Complex (Context& c) : Context (c), type_pass_ (c), + pre_override_ (c), // Initializers. // @@ -961,6 +1053,9 @@ namespace CXX // pre // + if (polymorphic (c)) + pre_override_.dispatch (c); + String const& arg (sarg_type (c)); os << "void " << name << "::" << endl @@ -1136,6 +1231,7 @@ namespace CXX private: TypePass type_pass_; + PreOverride pre_override_; // Initializers. // @@ -1159,6 +1255,10 @@ namespace CXX Void generate_serializer_source (Context& ctx) { + if (ctx.poly_code && !ctx.stl) + ctx.os << "#include " << endl + << endl; + Traversal::Schema schema; Traversal::Sources sources; diff --git a/xsde/cxx/hybrid/tree-header.cxx b/xsde/cxx/hybrid/tree-header.cxx index c2e8bf4..3003e4c 100644 --- a/xsde/cxx/hybrid/tree-header.cxx +++ b/xsde/cxx/hybrid/tree-header.cxx @@ -32,6 +32,9 @@ namespace CXX // if (name) { + Boolean cd (lc.count ("cd-name")); + Boolean poly (polymorphic (l)); + os << "// " << comment (l.name ()) << " (variable-length)" << endl << "//" << endl; @@ -50,17 +53,23 @@ namespace CXX os << "public:" << endl << name << " ();"; + // d-tor + // + if (poly) + os << "virtual ~" << name << " ();"; + + os << endl; + // Custom data. // - if (lc.count ("cd-name")) + if (cd) { String const& name (ecd_name (l)); String const& sequence (ecd_sequence (l)); String const& iterator (ecd_iterator (l)); String const& const_iterator (ecd_const_iterator (l)); - os << endl - << "// Custom data." << endl + os << "// Custom data." << endl << "//" << endl; // sequence & iterators @@ -84,9 +93,28 @@ namespace CXX os << sequence << "&" << endl << name << " ();" << endl; + } + + if (poly && typeinfo) + { + os << "// Type information." << endl + << "//" << endl; + os << "static const " << + (stl ? "::std::string&" : "char*") << endl + << "_static_type ();" + << endl; + + os << "virtual const " << + (stl ? "::std::string&" : "char*") << endl + << "_dynamic_type () const;" + << endl; + } + + if (cd) + { os << "private:" << endl - << sequence << " " << ecd_member (l) << ";"; + << ecd_sequence (l) << " " << ecd_member (l) << ";"; } os << "};"; @@ -128,15 +156,18 @@ namespace CXX // if (name) { + Boolean fl (fixed_length (u)); + Boolean poly (polymorphic (u)); Boolean cd (uc.count ("cd-name")); - os << "// " << comment (u.name ()) << " (variable-length)" << endl + os << "// " << comment (u.name ()) << " (" << + (fl ? "fixed-length" : "variable-length") << ")" << endl << "//" << endl; os << "class " << name << "{"; - if (!fixed_length (u)) + if (!fl) os << "private:" << endl << name << " (const " << name << "&);" << name << "& operator= (const " << name << "&);" @@ -148,13 +179,18 @@ namespace CXX // os << name << " ();"; + // d-tor + // + if (!stl || poly) + os << (poly ? "virtual " : "") << "~" << name << " ();"; + + os << endl; + String const& value (uc.get ("value")); String const& member (uc.get ("value-member")); if (stl) { - os << endl; - // const std::string& // name () const // @@ -178,11 +214,6 @@ namespace CXX } else { - // d-tor - // - os << "~" << name << " ();" - << endl; - // const char* // name () const // @@ -250,6 +281,22 @@ namespace CXX << endl; } + if (poly && typeinfo) + { + os << "// Type information." << endl + << "//" << endl; + + os << "static const " << + (stl ? "::std::string&" : "char*") << endl + << "_static_type ();" + << endl; + + os << "virtual const " << + (stl ? "::std::string&" : "char*") << endl + << "_dynamic_type () const;" + << endl; + } + if (stl) { os << "private:" << endl @@ -2337,6 +2384,7 @@ namespace CXX if (name) { Boolean fl (fixed_length (c)); + Boolean poly (polymorphic (c)); Boolean restriction (restriction_p (c)); Boolean cd (cc.count ("cd-name")); @@ -2361,8 +2409,8 @@ namespace CXX // d-tor // - if (!restriction) - os << "~" << name << " ();"; + if (!restriction || poly) + os << (poly ? "virtual " : "") << "~" << name << " ();"; // copy c-tor & operator= // @@ -2421,6 +2469,22 @@ namespace CXX << endl; } + if (poly && typeinfo) + { + os << "// Type information." << endl + << "//" << endl; + + os << "static const " << + (stl ? "::std::string&" : "char*") << endl + << "_static_type ();" + << endl; + + os << "virtual const " << + (stl ? "::std::string&" : "char*") << endl + << "_dynamic_type () const;" + << endl; + } + if (!restriction || cd) os << "private:" << endl; diff --git a/xsde/cxx/hybrid/tree-inline.cxx b/xsde/cxx/hybrid/tree-inline.cxx index b1c60e6..7cb4b2c 100644 --- a/xsde/cxx/hybrid/tree-inline.cxx +++ b/xsde/cxx/hybrid/tree-inline.cxx @@ -150,15 +150,6 @@ namespace CXX } else { - // d-tor - // - os << inl - << name << "::" << endl - << "~" << name << " ()" - << "{" - << "delete[] this->" << member << ";" - << "}"; - // const char* // name () const // diff --git a/xsde/cxx/hybrid/tree-name-processor.cxx b/xsde/cxx/hybrid/tree-name-processor.cxx index a3a1dd3..9308598 100644 --- a/xsde/cxx/hybrid/tree-name-processor.cxx +++ b/xsde/cxx/hybrid/tree-name-processor.cxx @@ -2053,8 +2053,9 @@ namespace CXX Void process_impl (CLI::Options const& ops, - SemanticGraph::Schema& tu, - SemanticGraph::Path const& file) + SemanticGraph::Schema& tu, + SemanticGraph::Path const& file, + Boolean deep) { Context ctx (ops, tu, file); @@ -2120,6 +2121,9 @@ namespace CXX schema.dispatch (tu); } + if (!deep) + return; + // Pass three - assign names inside complex types. Here we don't // need to go into included/imported schemas. // @@ -2178,9 +2182,10 @@ namespace CXX Void TreeNameProcessor:: process (CLI::Options const& ops, SemanticGraph::Schema& tu, - SemanticGraph::Path const& file) + SemanticGraph::Path const& file, + Boolean deep) { - process_impl (ops, tu, file); + process_impl (ops, tu, file, deep); } } } diff --git a/xsde/cxx/hybrid/tree-name-processor.hxx b/xsde/cxx/hybrid/tree-name-processor.hxx index 4d884bc..17becee 100644 --- a/xsde/cxx/hybrid/tree-name-processor.hxx +++ b/xsde/cxx/hybrid/tree-name-processor.hxx @@ -24,7 +24,8 @@ namespace CXX Void process (CLI::Options const& options, XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file); + XSDFrontend::SemanticGraph::Path const& file, + Boolean deep); }; } } diff --git a/xsde/cxx/hybrid/tree-size-processor.cxx b/xsde/cxx/hybrid/tree-size-processor.cxx index a3b2231..33d829a 100644 --- a/xsde/cxx/hybrid/tree-size-processor.cxx +++ b/xsde/cxx/hybrid/tree-size-processor.cxx @@ -242,11 +242,15 @@ namespace CXX Type (Boolean& valid, TypeSet& custom_data, CustomTypeMap& custom_type_map, - Boolean stl_) + TypeSet& poly_types, + Boolean stl_, + Boolean poly_) : valid_ (valid), custom_data_ (custom_data), custom_type_map_ (custom_type_map), - stl (stl_) + poly_types_ (poly_types), + stl (stl_), + poly (poly_) { } @@ -364,9 +368,40 @@ namespace CXX Void set (SemanticGraph::Type& t, Boolean v) { + using SemanticGraph::Complex; + + String const& name (t.name ()); + + // Check if this type is polymorphic. + // + if (poly) + { + SemanticGraph::Context& ctx (t.context ()); + + if (!ctx.count ("polymorphic")) + { + // If our base is polymorphic then we are as well. + // + Boolean pb (false); + if (Complex* c = dynamic_cast (&t)) + { + pb = c->inherits_p () && + c->inherits ().base ().context ().count ("polymorphic"); + } + + if (pb || poly_types_.find (name) != poly_types_.end ()) + { + ctx.set ("polymorphic", true); + v = false; + } + } + else + v = false; + } + // Check if this is a custom type. // - CustomTypeMap::Iterator i = custom_type_map_.find (t.name ()); + CustomTypeMap::Iterator i = custom_type_map_.find (name); if (i != custom_type_map_.end ()) { @@ -390,7 +425,9 @@ namespace CXX Boolean& valid_; TypeSet& custom_data_; CustomTypeMap& custom_type_map_; + TypeSet& poly_types_; Boolean stl; + Boolean poly; typedef Containers::Vector Path; Path path_; @@ -453,8 +490,8 @@ namespace CXX Traversal::Fundamental::Entities { - FundType (Boolean stl_) - : stl (stl_) + FundType (Boolean stl_, TypeSet& poly_types) + : stl (stl_), poly_types_ (poly_types) { } @@ -463,7 +500,18 @@ namespace CXX virtual Void traverse (SemanticGraph::AnyType& t) { - set (t, true); + /* + @@ disabled + // Check if this type is marked polymorphic. + // + if (poly_types_.find (t.name ()) != poly_types_.end ()) + { + t.context ().set ("polymorphic", true); + set (t, false); + } + else + */ + set (t, true); } virtual Void @@ -755,6 +803,130 @@ namespace CXX private: Boolean stl; + TypeSet& poly_types_; + }; + + struct GlobalElement: Traversal::Element + { + GlobalElement (TypeSet& poly_types, + Boolean& valid, + const WarningSet& disabled_warnings) + : poly_types_ (poly_types), valid_ (valid), warning_ (true) + { + if (disabled_warnings.find ("all") != disabled_warnings.end () || + disabled_warnings.find ("H004") != disabled_warnings.end ()) + warning_ = false; + } + + virtual Void + traverse (Type& e) + { + using SemanticGraph::Schema; + + if (!e.substitutes_p ()) + return; + + // If we are a substitution for some element, then mark + // that element's type as polymorphic. + // + Type& r (e.substitutes ().root ()); + SemanticGraph::Type& rt (r.type ()); + SemanticGraph::Context& ctx (rt.context ()); + + if (ctx.count ("polymorphic")) + return; + + // Only user-defined and anyType can be declared polymorphic. + // + /* + @@ disabled + if (rt.is_a () || + rt.is_a ()) + */ + if (rt.is_a () || + rt.is_a () || + rt.is_a ()) + { + wcerr << r.file () << ":" << r.line () << ":" << r.column () + << ": error: built-in type '" << rt.name () << "' " + << "is expected to be polymorphic" << endl; + + wcerr << e.file () << ":" << e.line () << ":" << e.column () + << ": info: because type '" << rt.name () << "' is " + << "used in a substitution group declared here" << endl; + + /* + @@ disabled + wcerr << r.file () << ":" << r.line () << ":" << r.column () + << ": info: only user-defined types and anyType can " + << "be polymorphic in this mapping" << endl; + */ + + wcerr << r.file () << ":" << r.line () << ":" << r.column () + << ": info: only user-defined types can " + << "be polymorphic in this mapping" << endl; + + valid_ = false; + return; + } + + ctx.set ("polymorphic", true); + + if (!warning_) + return; + + Schema& es (dynamic_cast (e.scope ().scope ())); + Schema& rts (dynamic_cast (rt.scope ().scope ())); + + // If the root type and this element are in different schemas + // and the root type is not explicitly marked as polymorphic, + // then issue a warning. + // + if (&es != &rts && + !sources_p (es, rts) && + poly_types_.find (rt.name ()) == poly_types_.end ()) + { + wcerr << rt.file () << ":" << rt.line () << ":" << rt.column () + << ": warning H004: assuming type '" << rt.name () << "' " + << "is polymorphic" << endl; + + wcerr << e.file () << ":" << e.line () << ":" << e.column () + << ": info: because type '" << rt.name () << "' is " + << "used in a substitution group declared here" << endl; + + wcerr << rt.file () << ":" << rt.line () << ":" << rt.column () + << ": info: use --polymorphic-type to indicate this type " + << "is polymorphic when compiling schemas that " + << "reference it" << endl; + } + } + + private: + // Return true if root sources s. + // + Boolean + sources_p (SemanticGraph::Schema& root, SemanticGraph::Schema& s) + { + using SemanticGraph::Schema; + using SemanticGraph::Sources; + + for (Schema::UsesIterator i (root.uses_begin ()); + i != root.uses_end (); ++i) + { + if (i->is_a ()) + { + if (&i->schema () == &s || sources_p (i->schema (), s)) + return true; + } + } + + return false; + } + + private: + TypeSet& poly_types_; + Boolean& valid_; + Boolean warning_; }; // Go into sourced/included/imported schemas while making sure @@ -764,14 +936,19 @@ namespace CXX Traversal::Includes, Traversal::Imports { + Uses (Char const* seen_key) + : seen_key_ (seen_key) + { + } + virtual Void traverse (SemanticGraph::Sources& sr) { SemanticGraph::Schema& s (sr.schema ()); - if (!s.context ().count ("cxx-hybrid-size-processor-seen")) + if (!s.context ().count (seen_key_)) { - s.context ().set ("cxx-hybrid-size-processor-seen", true); + s.context ().set (seen_key_, true); Traversal::Sources::traverse (sr); } } @@ -781,9 +958,9 @@ namespace CXX { SemanticGraph::Schema& s (i.schema ()); - if (!s.context ().count ("cxx-hybrid-size-processor-seen")) + if (!s.context ().count (seen_key_)) { - s.context ().set ("cxx-hybrid-size-processor-seen", true); + s.context ().set (seen_key_, true); Traversal::Includes::traverse (i); } } @@ -793,21 +970,40 @@ namespace CXX { SemanticGraph::Schema& s (i.schema ()); - if (!s.context ().count ("cxx-hybrid-size-processor-seen")) + if (!s.context ().count (seen_key_)) { - s.context ().set ("cxx-hybrid-size-processor-seen", true); + s.context ().set (seen_key_, true); Traversal::Imports::traverse (i); } } + + private: + Char const* seen_key_; }; + Char const* pass_one_key = "cxx-hybrid-size-processor-seen-one"; + Char const* pass_two_key = "cxx-hybrid-size-processor-seen-two"; + Boolean process_impl (CLI::Options const& ops, SemanticGraph::Schema& tu, - SemanticGraph::Path const&) + SemanticGraph::Path const&, + const WarningSet& disabled_warnings) { Boolean valid (true); Boolean stl (!ops.value ()); + Boolean poly (ops.value ()); + + // Prepare a set of polymorphic types. + // + + TypeSet poly_types; + if (poly) + { + poly_types.insert ( + ops.value ().begin (), + ops.value ().end ()); + } // Root schema in the file-per-type mode is just a bunch // of includes without a namespace. @@ -824,7 +1020,7 @@ namespace CXX Traversal::Names schema_names; Traversal::Namespace ns; Traversal::Names ns_names; - FundType fund_type (stl); + FundType fund_type (stl, poly_types); schema >> schema_names >> ns >> ns_names >> fund_type; @@ -832,7 +1028,7 @@ namespace CXX } else { - // Pass one - assign sizes to fundamental types. + // First assign sizes to fundamental types. // { Traversal::Schema schema; @@ -844,7 +1040,7 @@ namespace CXX Traversal::Names xs_schema_names; Traversal::Namespace ns; Traversal::Names ns_names; - FundType fund_type (stl); + FundType fund_type (stl, poly_types); xs_schema >> xs_schema_names >> ns >> ns_names >> fund_type; @@ -855,7 +1051,7 @@ namespace CXX // processed which may happen in the file-per-type compilation // mode. // - if (!tu.context ().count ("cxx-hybrid-size-processor-seen")) + if (!tu.context ().count (pass_two_key)) { // Prepare a set of types with custom data. Here we are // only interested in detecting global types. If a type @@ -877,8 +1073,7 @@ namespace CXX } } - // Prepare a map of types custom types that specify type - // size. + // Prepare a map of custom types that specify type length. // CustomTypeMap custom_type_map; @@ -949,23 +1144,53 @@ namespace CXX } } + // Pass one - check substitution groups. + // + if (valid && poly) + { + Traversal::Schema schema; + Uses uses (pass_one_key); + + schema >> uses >> schema; + + Traversal::Names schema_names; + Traversal::Namespace ns; + Traversal::Names ns_names; + GlobalElement element (poly_types, valid, disabled_warnings); + + schema >> schema_names >> ns >> ns_names >> element; + + // Some twisted schemas do recusive self-inclusion. + // + tu.context ().set (pass_one_key, true); + + schema.dispatch (tu); + } + + // Pass two - process types. + // if (valid) { Traversal::Schema schema; - Uses uses; + Uses uses (pass_two_key); schema >> uses >> schema; Traversal::Names schema_names; Traversal::Namespace ns; Traversal::Names ns_names; - Type type (valid, custom_data_types, custom_type_map, stl); + Type type (valid, + custom_data_types, + custom_type_map, + poly_types, + stl, + poly); schema >> schema_names >> ns >> ns_names >> type; // Some twisted schemas do recusive self-inclusion. // - tu.context ().set ("cxx-hybrid-size-processor-seen", true); + tu.context ().set (pass_two_key, true); schema.dispatch (tu); } @@ -979,9 +1204,10 @@ namespace CXX Boolean TreeSizeProcessor:: process (CLI::Options const& ops, SemanticGraph::Schema& tu, - SemanticGraph::Path const& file) + SemanticGraph::Path const& file, + const WarningSet& disabled_warnings) { - return process_impl (ops, tu, file); + return process_impl (ops, tu, file, disabled_warnings); } } } diff --git a/xsde/cxx/hybrid/tree-size-processor.hxx b/xsde/cxx/hybrid/tree-size-processor.hxx index d9257a1..d82364f 100644 --- a/xsde/cxx/hybrid/tree-size-processor.hxx +++ b/xsde/cxx/hybrid/tree-size-processor.hxx @@ -12,6 +12,8 @@ #include +#include + namespace CXX { namespace Hybrid @@ -24,7 +26,8 @@ namespace CXX Boolean process (CLI::Options const& options, XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file); + XSDFrontend::SemanticGraph::Path const& file, + const WarningSet& disabled_warnings); }; } } diff --git a/xsde/cxx/hybrid/tree-source.cxx b/xsde/cxx/hybrid/tree-source.cxx index 6de3e35..2723046 100644 --- a/xsde/cxx/hybrid/tree-source.cxx +++ b/xsde/cxx/hybrid/tree-source.cxx @@ -14,6 +14,161 @@ namespace CXX { namespace { + struct List : Traversal::List, Context + { + List (Context& c) + : Context (c) + { + } + + virtual Void + traverse (Type& l) + { + String const& name (ename_custom (l)); + + // We may not need to generate the class if this type is + // being customized. + // + if (!name) + return; + + if (polymorphic (l)) + { + os << "// " << comment (l.name ()) << endl + << "//" << endl + << endl; + + // d-tor + // + os << name << "::" << endl + << "~" << name << " ()" + << "{" + << "}"; + + if (typeinfo) + { + String id (l.name ()); + + if (String ns = xml_ns_name (l)) + { + id += L' '; + id += ns; + } + + if (stl) + { + os << "static const ::std::string _xsde_" << name << + "_static_type_ = " << strlit (id) << ";" + << endl; + + os << "const ::std::string& " << name << "::" << endl + << "_static_type ()" + << "{" + << "return _xsde_" << name << "_static_type_;" + << "}"; + } + else + { + os << "const char* " << name << "::" << endl + << "_static_type ()" + << "{" + << "return " << strlit (id) << ";" + << "}"; + } + + os << "const " << (stl ? "::std::string& " : "char* ") << + name << "::" << endl + << "_dynamic_type () const" + << "{" + << "return _static_type ();" + << "}"; + } + } + } + }; + + // + // + struct Union : Traversal::Union, Context + { + Union (Context& c) + : Context (c) + { + } + + virtual Void + traverse (Type& u) + { + String const& name (ename_custom (u)); + + // We may not need to generate the class if this type is + // being customized. + // + if (!name) + return; + + Boolean poly (polymorphic (u)); + + if (!stl || poly) + { + os << "// " << comment (u.name ()) << endl + << "//" << endl + << endl; + + // d-tor + // + os << name << "::" << endl + << "~" << name << " ()" + << "{"; + + if (!stl) + os << "delete[] this->" << + u.context ().get ("value-member") << ";"; + + os << "}"; + + if (poly && typeinfo) + { + String id (u.name ()); + + if (String ns = xml_ns_name (u)) + { + id += L' '; + id += ns; + } + + if (stl) + { + os << "static const ::std::string _xsde_" << name << + "_static_type_ = " << strlit (id) << ";" + << endl; + + os << "const ::std::string& " << name << "::" << endl + << "_static_type ()" + << "{" + << "return _xsde_" << name << "_static_type_;" + << "}"; + } + else + { + os << "const char* " << name << "::" << endl + << "_static_type ()" + << "{" + << "return " << strlit (id) << ";" + << "}"; + } + + os << "const " << (stl ? "::std::string& " : "char* ") << + name << "::" << endl + << "_dynamic_type () const" + << "{" + << "return _static_type ();" + << "}"; + } + } + } + }; + struct ChoiceParticle: Traversal::Element, Traversal::Compositor, Context @@ -1464,6 +1619,7 @@ namespace CXX if (!name) return; + Boolean poly (polymorphic (c)); Boolean restriction (restriction_p (c)); os << "// " << comment (c.name ()) << endl @@ -1486,22 +1642,27 @@ namespace CXX os << "}"; - - if (!restriction) + // d-tor () + // + if (!restriction || poly) { - // d-tor () - // os << name << "::" << endl << "~" << name << " ()" << "{"; - Complex::names (c, attribute_names_dtor_); + if (!restriction) + { + Complex::names (c, attribute_names_dtor_); - if (c.contains_compositor_p ()) - Complex::contains_compositor (c, contains_compositor_dtor_); + if (c.contains_compositor_p ()) + Complex::contains_compositor (c, contains_compositor_dtor_); + } os << "}"; + } + if (!restriction) + { if (fixed_length (c)) { // copy c-tor @@ -1554,7 +1715,49 @@ namespace CXX // if (c.contains_compositor_p ()) Complex::contains_compositor (c, contains_compositor_func_); + } + + if (poly && typeinfo) + { + String id (c.name ()); + + if (String ns = xml_ns_name (c)) + { + id += L' '; + id += ns; + } + + if (stl) + { + os << "static const ::std::string _xsde_" << name << + "_static_type_ = " << strlit (id) << ";" + << endl; + os << "const ::std::string& " << name << "::" << endl + << "_static_type ()" + << "{" + << "return _xsde_" << name << "_static_type_;" + << "}"; + } + else + { + os << "const char* " << name << "::" << endl + << "_static_type ()" + << "{" + << "return " << strlit (id) << ";" + << "}"; + } + + os << "const " << (stl ? "::std::string& " : "char* ") << + name << "::" << endl + << "_dynamic_type () const" + << "{" + << "return _static_type ();" + << "}"; + } + + if (!restriction) + { // Nested c-tors, etc. // if (c.contains_compositor_p ()) @@ -1661,16 +1864,16 @@ namespace CXX Namespace ns (ctx); - //Union union_ (ctx); + List list (ctx); + Union union_ (ctx); Complex complex (ctx); - //Enumeration enumeration (ctx); schema >> sources >> schema; schema >> names_ns >> ns >> names; - //names >> union_; + names >> list; + names >> union_; names >> complex; - //names >> enumeration; schema.dispatch (ctx.schema_root); } diff --git a/xsde/cxx/hybrid/validator.cxx b/xsde/cxx/hybrid/validator.cxx index 65dd3e2..c799563 100644 --- a/xsde/cxx/hybrid/validator.cxx +++ b/xsde/cxx/hybrid/validator.cxx @@ -20,6 +20,9 @@ namespace CXX { namespace { + // H004 is used by tree-size-processor. + // + class ValidationContext: public Context { public: @@ -34,6 +37,8 @@ namespace CXX subst_group_warning_issued (subst_group_warning_issued_), subst_group_warning_issued_ (false) { + if (disabled_warnings_.find ("all") != disabled_warnings_.end ()) + disabled_warnings_all_ = true; } public: @@ -147,7 +152,6 @@ namespace CXX } } - /* virtual Void traverse (SemanticGraph::Element& e) { @@ -165,11 +169,10 @@ namespace CXX << "--generate-polymorphic was not specified" << endl; os << e.file () << ":" << e.line () << ":" << e.column () - << ": info: generated code may not be able to serialize " + << ": info: generated code may not be able to handle " << "some conforming instances" << endl; } } - */ // Return true if root sources s. // diff --git a/xsde/cxx/parser/generator.cxx b/xsde/cxx/parser/generator.cxx index e552c92..aed6e53 100644 --- a/xsde/cxx/parser/generator.cxx +++ b/xsde/cxx/parser/generator.cxx @@ -526,6 +526,14 @@ namespace CXX return spec; } + Void Parser::Generator:: + process_names (CLI::Options const& ops, + XSDFrontend::SemanticGraph::Schema& schema, + XSDFrontend::SemanticGraph::Path const& file) + { + NameProcessor proc; + proc.process (ops, schema, file, false); + } namespace { @@ -646,7 +654,7 @@ namespace CXX // { NameProcessor proc; - proc.process (ops, schema, file_path); + proc.process (ops, schema, file_path, true); } Boolean validation (!ops.value ()); diff --git a/xsde/cxx/parser/generator.hxx b/xsde/cxx/parser/generator.hxx index a261eca..305d8b1 100644 --- a/xsde/cxx/parser/generator.hxx +++ b/xsde/cxx/parser/generator.hxx @@ -35,17 +35,26 @@ namespace CXX static CLI::OptionsSpec options_spec (); + // Assign names to global declarations. + // + static Void + process_names (CLI::Options const&, + XSDFrontend::SemanticGraph::Schema&, + XSDFrontend::SemanticGraph::Path const&); + + // Generate code. + // struct Failed {}; static UnsignedLong - generate (CLI::Options const& options, + generate (CLI::Options const&, XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file, + XSDFrontend::SemanticGraph::Path const&, TypeMap::Namespaces& type_map, Boolean gen_driver, const WarningSet& disabled_warnings, - FileList& file_list, - AutoUnlinks& unlinks); + FileList&, + AutoUnlinks&); private: Generator (); diff --git a/xsde/cxx/parser/name-processor.cxx b/xsde/cxx/parser/name-processor.cxx index bc0e7a5..9c945b3 100644 --- a/xsde/cxx/parser/name-processor.cxx +++ b/xsde/cxx/parser/name-processor.cxx @@ -1224,7 +1224,8 @@ namespace CXX Void process_impl (CLI::Options const& ops, SemanticGraph::Schema& tu, - SemanticGraph::Path const& file) + SemanticGraph::Path const& file, + Boolean deep) { Context ctx (ops, tu, file); @@ -1290,6 +1291,9 @@ namespace CXX schema.dispatch (tu); } + if (!deep) + return; + // Pass three - assign names inside complex types. Here we don't // need to go into included/imported schemas. // @@ -1318,9 +1322,10 @@ namespace CXX Void NameProcessor:: process (CLI::Options const& ops, SemanticGraph::Schema& tu, - SemanticGraph::Path const& file) + SemanticGraph::Path const& file, + Boolean deep) { - process_impl (ops, tu, file); + process_impl (ops, tu, file, deep); } } } diff --git a/xsde/cxx/parser/name-processor.hxx b/xsde/cxx/parser/name-processor.hxx index 8d55f30..6a7af9f 100644 --- a/xsde/cxx/parser/name-processor.hxx +++ b/xsde/cxx/parser/name-processor.hxx @@ -22,9 +22,10 @@ namespace CXX { public: Void - process (CLI::Options const& options, + process (CLI::Options const&, XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file); + XSDFrontend::SemanticGraph::Path const&, + Boolean deep); }; } } diff --git a/xsde/cxx/parser/validator.cxx b/xsde/cxx/parser/validator.cxx index 570a0bf..842fc4e 100644 --- a/xsde/cxx/parser/validator.cxx +++ b/xsde/cxx/parser/validator.cxx @@ -34,6 +34,8 @@ namespace CXX subst_group_warning_issued (subst_group_warning_issued_), subst_group_warning_issued_ (false) { + if (disabled_warnings_.find ("all") != disabled_warnings_.end ()) + disabled_warnings_all_ = true; } public: diff --git a/xsde/cxx/serializer/generator.cxx b/xsde/cxx/serializer/generator.cxx index c27ef09..5e72d86 100644 --- a/xsde/cxx/serializer/generator.cxx +++ b/xsde/cxx/serializer/generator.cxx @@ -519,6 +519,14 @@ namespace CXX return spec; } + Void Serializer::Generator:: + process_names (CLI::Options const& ops, + XSDFrontend::SemanticGraph::Schema& schema, + XSDFrontend::SemanticGraph::Path const& file) + { + NameProcessor proc; + proc.process (ops, schema, file, false); + } namespace { @@ -637,7 +645,7 @@ namespace CXX // { NameProcessor proc; - proc.process (ops, schema, file_path); + proc.process (ops, schema, file_path, true); } // diff --git a/xsde/cxx/serializer/generator.hxx b/xsde/cxx/serializer/generator.hxx index a5b8558..eaa378d 100644 --- a/xsde/cxx/serializer/generator.hxx +++ b/xsde/cxx/serializer/generator.hxx @@ -35,17 +35,26 @@ namespace CXX static CLI::OptionsSpec options_spec (); + // Assign names to global declarations. + // + static Void + process_names (CLI::Options const&, + XSDFrontend::SemanticGraph::Schema&, + XSDFrontend::SemanticGraph::Path const&); + + // Generate code. + // struct Failed {}; static UnsignedLong - generate (CLI::Options const& options, + generate (CLI::Options const&, XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file, + XSDFrontend::SemanticGraph::Path const&, TypeMap::Namespaces& type_map, Boolean gen_driver, const WarningSet& disabled_warnings, - FileList& file_list, - AutoUnlinks& unlinks); + FileList&, + AutoUnlinks&); private: Generator (); diff --git a/xsde/cxx/serializer/name-processor.cxx b/xsde/cxx/serializer/name-processor.cxx index d68b823..140ad06 100644 --- a/xsde/cxx/serializer/name-processor.cxx +++ b/xsde/cxx/serializer/name-processor.cxx @@ -1307,7 +1307,8 @@ namespace CXX Void process_impl (CLI::Options const& ops, SemanticGraph::Schema& tu, - SemanticGraph::Path const& file) + SemanticGraph::Path const& file, + Boolean deep) { Context ctx (ops, tu, file); @@ -1373,6 +1374,9 @@ namespace CXX schema.dispatch (tu); } + if (!deep) + return; + // Pass three - assign names inside complex types. Here we don't // need to go into included/imported schemas. // @@ -1401,9 +1405,10 @@ namespace CXX Void NameProcessor:: process (CLI::Options const& ops, SemanticGraph::Schema& tu, - SemanticGraph::Path const& file) + SemanticGraph::Path const& file, + Boolean deep) { - process_impl (ops, tu, file); + process_impl (ops, tu, file, deep); } } } diff --git a/xsde/cxx/serializer/name-processor.hxx b/xsde/cxx/serializer/name-processor.hxx index bf69ba6..f7cd63b 100644 --- a/xsde/cxx/serializer/name-processor.hxx +++ b/xsde/cxx/serializer/name-processor.hxx @@ -22,9 +22,10 @@ namespace CXX { public: Void - process (CLI::Options const& options, + process (CLI::Options const&, XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file); + XSDFrontend::SemanticGraph::Path const&, + Boolean deep); }; } } diff --git a/xsde/cxx/serializer/validator.cxx b/xsde/cxx/serializer/validator.cxx index d9cc724..189ccac 100644 --- a/xsde/cxx/serializer/validator.cxx +++ b/xsde/cxx/serializer/validator.cxx @@ -34,6 +34,8 @@ namespace CXX subst_group_warning_issued (subst_group_warning_issued_), subst_group_warning_issued_ (false) { + if (disabled_warnings_.find ("all") != disabled_warnings_.end ()) + disabled_warnings_all_ = true; } public: -- cgit v1.1