aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-02-11 17:01:02 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-02-11 17:01:02 +0200
commitd4a78b31a1a045471c2fe12d2618d9d5edf78fb2 (patch)
tree090738555bb18f9a22ad7916f34bcd50273e9cb2
parent7c064687415c895334650321bd5bc34453b0ce38 (diff)
Fix recursive polymorphic parsing in C++/Parser
New test: cxx/parser/polymorphism/recursive.
-rw-r--r--tests/cxx/parser/polymorphism/makefile2
-rw-r--r--tests/cxx/parser/polymorphism/recursive/driver.cxx70
-rw-r--r--tests/cxx/parser/polymorphism/recursive/makefile80
-rw-r--r--tests/cxx/parser/polymorphism/recursive/output22
-rw-r--r--tests/cxx/parser/polymorphism/recursive/test-pimpl.cxx149
-rw-r--r--tests/cxx/parser/polymorphism/recursive/test-pimpl.hxx96
-rw-r--r--tests/cxx/parser/polymorphism/recursive/test.xml15
-rw-r--r--tests/cxx/parser/polymorphism/recursive/test.xsd53
-rw-r--r--tests/cxx/parser/polymorphism/same-type/driver.cxx2
-rw-r--r--xsd/cxx/parser/element-validation-source.cxx43
-rw-r--r--xsd/cxx/parser/elements.cxx6
-rw-r--r--xsd/cxx/parser/elements.hxx3
-rw-r--r--xsd/cxx/parser/name-processor.cxx8
-rw-r--r--xsd/cxx/parser/parser-header.cxx3
-rw-r--r--xsd/cxx/parser/parser-source.cxx48
15 files changed, 547 insertions, 53 deletions
diff --git a/tests/cxx/parser/polymorphism/makefile b/tests/cxx/parser/polymorphism/makefile
index ac7cc89..6e1a12e 100644
--- a/tests/cxx/parser/polymorphism/makefile
+++ b/tests/cxx/parser/polymorphism/makefile
@@ -5,7 +5,7 @@
include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
-tests := same-type
+tests := same-type recursive
default := $(out_base)/
test := $(out_base)/.test
diff --git a/tests/cxx/parser/polymorphism/recursive/driver.cxx b/tests/cxx/parser/polymorphism/recursive/driver.cxx
new file mode 100644
index 0000000..c91a1c0
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/recursive/driver.cxx
@@ -0,0 +1,70 @@
+// file : tests/cxx/parser/polymorphism/recursive/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2011 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test polymorphic recursive parsing.
+//
+
+#include <string>
+#include <iostream>
+
+#include "test-pskel.hxx"
+#include "test-pimpl.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::int_pimpl int_p;
+
+ root_pimpl root_p;
+ expression_pimpl expression_p;
+ recursive_pimpl recursive_p;
+ value_a_pimpl value_a_p;
+ value_b_pimpl value_b_p;
+
+ xml_schema::parser_map_impl expression_map;
+
+ // Connect the parsers together.
+ //
+ root_p.parsers (expression_p);
+ expression_map.insert(value_a_p);
+ expression_map.insert(value_b_p);
+ expression_map.insert(recursive_p);
+
+ root_p.expression_parser(expression_map);
+
+ recursive_p.parsers(expression_p);
+ recursive_p.expression_parser(expression_map);
+
+ value_a_p.parsers(int_p);
+ value_b_p.parsers(int_p);
+
+ xml_schema::document doc_p (root_p, "test", "root", true);
+
+ root_p.pre ();
+ doc_p.parse (argv[1]);
+ root_p.post_root ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (std::ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/polymorphism/recursive/makefile b/tests/cxx/parser/polymorphism/recursive/makefile
new file mode 100644
index 0000000..4ae706e
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/recursive/makefile
@@ -0,0 +1,80 @@
+# file : tests/cxx/parser/polymorphism/recursive/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2011 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx test-pimpl.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+genf := $(xsd:.xsd=-pskel.hxx) $(xsd:.xsd=-pskel.ixx) $(xsd:.xsd=-pskel.cxx)
+gen := $(addprefix $(out_base)/,$(genf))
+
+$(gen): xsd := $(out_root)/xsd/xsd
+$(gen): xsd_options := --generate-polymorphic
+$(gen): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+# Generated .gitignore.
+#
+ifeq ($(out_base),$(src_base))
+$(gen): | $(out_base)/.gitignore
+$(driver): | $(out_base)/.gitignore
+
+$(out_base)/.gitignore: files := driver $(genf)
+$(clean): $(out_base)/.gitignore.clean
+
+$(call include,$(bld_root)/git/gitignore.make)
+endif
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/polymorphism/recursive/output b/tests/cxx/parser/polymorphism/recursive/output
new file mode 100644
index 0000000..28a835f
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/recursive/output
@@ -0,0 +1,22 @@
+root start
+recursive start
+value_a begin
+value->constant
+value: post_expression override
+value_a: post_value override
+value_a end
+recursive->expression event
+recursive start
+value_b begin
+value->constant
+value: post_expression override
+value_b: post_value override
+value_b end
+recursive->expression event
+recursive: post_expression override
+recursive end
+recursive->expression event
+recursive: post_expression override
+recursive end
+root->expression
+root end
diff --git a/tests/cxx/parser/polymorphism/recursive/test-pimpl.cxx b/tests/cxx/parser/polymorphism/recursive/test-pimpl.cxx
new file mode 100644
index 0000000..3be2921
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/recursive/test-pimpl.cxx
@@ -0,0 +1,149 @@
+// file : tests/cxx/parser/polymorphism/recursive/test-pimpl.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2011 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <iostream>
+
+#include "test-pimpl.hxx"
+
+using namespace std;
+
+namespace test
+{
+ // root_pimpl
+ //
+
+ void root_pimpl::
+ pre ()
+ {
+ cout << "root start" << endl;
+ }
+
+ void root_pimpl::
+ expression ()
+ {
+ cout << "root->expression" << endl;
+ }
+
+ void root_pimpl::
+ post_root ()
+ {
+ cout << "root end" << endl;
+ }
+
+ // expression_pimpl
+ //
+
+ void expression_pimpl::
+ pre ()
+ {
+ cout << "expression begin" << endl;
+ }
+
+ void expression_pimpl::
+ post_expression ()
+ {
+ cout << "expression end" << endl;
+ }
+
+ // recursive_pimpl
+ //
+
+ void recursive_pimpl::
+ pre ()
+ {
+ cout << "recursive start" << endl;
+ }
+
+ void recursive_pimpl::
+ expression ()
+ {
+ cout << "recursive->expression event" << endl;
+ }
+
+ void recursive_pimpl::
+ post_expression ()
+ {
+ cout << "recursive: post_expression override" << endl;
+ post_recursive ();
+ }
+
+ void recursive_pimpl::
+ post_recursive ()
+ {
+ cout << "recursive end" << endl;
+ }
+
+ // value_pimpl
+ //
+
+ void value_pimpl::
+ pre ()
+ {
+ cout << "value begin" << endl;
+ }
+
+ void value_pimpl::
+ constant (int)
+ {
+ cout << "value->constant" << endl;
+ }
+
+ void value_pimpl::
+ post_expression ()
+ {
+ cout << "value: post_expression override" << endl;
+ post_value ();
+ }
+
+ void value_pimpl::
+ post_value ()
+ {
+ cout << "value end" << endl;
+ }
+
+ // value_a_pimpl
+ //
+
+ void value_a_pimpl::
+ pre ()
+ {
+ cout << "value_a begin" << endl;
+ }
+
+ void value_a_pimpl::
+ post_value ()
+ {
+ cout << "value_a: post_value override" << endl;
+ post_value_a ();
+ }
+
+ void value_a_pimpl::
+ post_value_a ()
+ {
+ cout << "value_a end" << endl;
+ }
+
+ // value_b_pimpl
+ //
+
+ void value_b_pimpl::
+ pre ()
+ {
+ cout << "value_b begin" << endl;
+ }
+
+ void value_b_pimpl::
+ post_value ()
+ {
+ cout << "value_b: post_value override" << endl;
+ post_value_b ();
+ }
+
+ void value_b_pimpl::
+ post_value_b ()
+ {
+ cout << "value_b end" << endl;
+ }
+}
diff --git a/tests/cxx/parser/polymorphism/recursive/test-pimpl.hxx b/tests/cxx/parser/polymorphism/recursive/test-pimpl.hxx
new file mode 100644
index 0000000..2dc2d35
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/recursive/test-pimpl.hxx
@@ -0,0 +1,96 @@
+// file : tests/cxx/parser/polymorphism/recursive/test-pimpl.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2011 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef TEST_PIMPL_HXX
+#define TEST_PIMPL_HXX
+
+#include "test-pskel.hxx"
+
+namespace test
+{
+ class root_pimpl: public virtual root_pskel
+ {
+ public:
+ virtual void
+ pre ();
+
+ virtual void
+ expression ();
+
+ virtual void
+ post_root ();
+ };
+
+ class expression_pimpl: public virtual expression_pskel
+ {
+ public:
+ virtual void
+ pre ();
+
+ virtual void
+ post_expression ();
+ };
+
+ class recursive_pimpl: public virtual recursive_pskel,
+ public expression_pimpl
+ {
+ public:
+ virtual void
+ pre ();
+
+ virtual void
+ expression ();
+
+ virtual void
+ post_expression ();
+
+ virtual void
+ post_recursive ();
+ };
+
+ class value_pimpl: public virtual value_pskel, public expression_pimpl
+ {
+ public:
+ virtual void
+ pre ();
+
+ virtual void
+ constant (int);
+
+ virtual void
+ post_expression ();
+
+ virtual void
+ post_value ();
+ };
+
+ class value_a_pimpl: public virtual value_a_pskel, public value_pimpl
+ {
+ public:
+ virtual void
+ pre ();
+
+ virtual void
+ post_value ();
+
+ virtual void
+ post_value_a ();
+ };
+
+ class value_b_pimpl: public virtual value_b_pskel, public value_pimpl
+ {
+ public:
+ virtual void
+ pre ();
+
+ virtual void
+ post_value ();
+
+ virtual void
+ post_value_b ();
+ };
+}
+
+#endif // TEST_PIMPL_HXX
diff --git a/tests/cxx/parser/polymorphism/recursive/test.xml b/tests/cxx/parser/polymorphism/recursive/test.xml
new file mode 100644
index 0000000..42035ba
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/recursive/test.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root xmlns="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+ <recursive>
+ <value-a>
+ <constant>1</constant>
+ </value-a>
+ <recursive>
+ <value-b>
+ <constant>2</constant>
+ </value-b>
+ </recursive>
+ </recursive>
+</root>
diff --git a/tests/cxx/parser/polymorphism/recursive/test.xsd b/tests/cxx/parser/polymorphism/recursive/test.xsd
new file mode 100644
index 0000000..affcc8a
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/recursive/test.xsd
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:t="test"
+ targetNamespace="test"
+ elementFormDefault="qualified">
+
+ <element name="root" type="t:root"/>
+ <complexType name="root">
+ <sequence>
+ <element ref="t:expression" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="expression" type="t:expression" abstract="true"/>
+ <complexType name="expression" abstract="true"/>
+
+ <element name="recursive" type="t:recursive" substitutionGroup="t:expression"/>
+ <complexType name="recursive">
+ <complexContent>
+ <extension base="t:expression">
+ <sequence minOccurs="0" maxOccurs="unbounded">
+ <element ref="t:expression"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <element name="value" type="t:value" abstract="true" substitutionGroup="t:expression"/>
+ <complexType name="value" abstract="true">
+ <complexContent>
+ <extension base="t:expression">
+ <sequence>
+ <element name="constant" type="int"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <element name="value-a" type="t:value-a" substitutionGroup="t:expression"/>
+ <complexType name="value-a">
+ <complexContent>
+ <extension base="t:value"/>
+ </complexContent>
+ </complexType>
+
+ <element name="value-b" type="t:value-b" substitutionGroup="t:expression"/>
+ <complexType name="value-b">
+ <complexContent>
+ <extension base="t:value"/>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/tests/cxx/parser/polymorphism/same-type/driver.cxx b/tests/cxx/parser/polymorphism/same-type/driver.cxx
index 086d2fb..0163709 100644
--- a/tests/cxx/parser/polymorphism/same-type/driver.cxx
+++ b/tests/cxx/parser/polymorphism/same-type/driver.cxx
@@ -45,7 +45,7 @@ main (int argc, char* argv[])
base_p.parsers (string_p);
type_p.parsers (base_p);
- xml_schema::document doc_p (type_p, "test", "root");
+ xml_schema::document doc_p (type_p, "test", "root", true);
type_p.pre ();
doc_p.parse (argv[1]);
diff --git a/xsd/cxx/parser/element-validation-source.cxx b/xsd/cxx/parser/element-validation-source.cxx
index bf7fec2..a96dc6c 100644
--- a/xsd/cxx/parser/element-validation-source.cxx
+++ b/xsd/cxx/parser/element-validation-source.cxx
@@ -196,6 +196,7 @@ namespace CXX
if (Element* e = dynamic_cast<Element*> (&p))
{
SemanticGraph::Type& type (e->type ());
+ String const& fq_type (fq_name (type));
Boolean poly (polymorphic && !anonymous (type));
String name, inst, def_parser, map;
@@ -203,13 +204,15 @@ namespace CXX
if (e->context ().count("name"))
{
name = ename (*e);
- inst = poly ? emember_cache (*e) : emember (*e);
if (poly)
{
def_parser = emember (*e);
map = emember_map (*e);
+ inst = "p";
}
+ else
+ inst = L"this->" + emember (*e);
}
else
{
@@ -222,13 +225,15 @@ namespace CXX
Element& fe (dynamic_cast<Element&>(ip.first->named ()));
name = ename (fe);
- inst = poly ? emember_cache (fe) : emember (fe);
if (poly)
{
def_parser = emember (fe);
map = emember_map (fe);
+ inst = "p";
}
+ else
+ inst = L"this->" + emember (fe);
}
if (poly)
@@ -243,8 +248,10 @@ namespace CXX
type_id += type_ns;
}
- os << "if (t == 0 && this->" << def_parser << " != 0)" << endl
- << "this->" << inst << " = this->" << def_parser << ";"
+ os << fq_type << "* p = 0;"
+ << endl
+ << "if (t == 0 && this->" << def_parser << " != 0)" << endl
+ << inst << " = this->" << def_parser << ";"
<< "else"
<< "{"
<< string_type << " ts (" << fq_name (type) <<
@@ -254,7 +261,7 @@ namespace CXX
<< "t = &ts;"
<< endl
<< "if (this->" << def_parser << " != 0 && *t == ts)" << endl
- << "this->" << inst << " = this->" << def_parser << ";"
+ << inst << " = this->" << def_parser << ";"
<< "else"
<< "{";
@@ -269,34 +276,38 @@ namespace CXX
" > (*t);"
<< endl
<< "if (this->" << map << " != 0)" << endl
- << "this->" << inst << " = dynamic_cast< " <<
- fq_name (type) << "* > (" << endl
+ << inst << " = dynamic_cast< " << fq_type << "* > (" << endl
<< "this->" << map << "->find (*t));"
- << "else" << endl
- << "this->" << inst << " = 0;"
<< "}"
<< "}";
}
os << "this->" << complex_base << "::context_.top ()." <<
- "parser_ = this->" << inst << ";"
+ "parser_ = " << inst << ";"
<< endl
- << "if (this->" << inst << ")" << endl
- << "this->" << inst << "->pre ();"
+ << "if (" << inst << ")" << endl
+ << inst << "->pre ();"
<< "}"
<< "else" // start
- << "{"
- << "if (this->" << inst << ")"
+ << "{";
+
+ if (poly)
+ os << fq_type << "* p =" << endl
+ << "static_cast< " << fq_type << "* > (" << endl
+ << "this->" << complex_base << "::context_.top ().parser_);"
+ << endl;
+
+ os << "if (" << inst << ")"
<< "{";
String const& ret (ret_type (type));
String const& post (post_name (type));
if (ret == L"void")
- os << "this->" << inst << "->" << post << " ();"
+ os << inst << "->" << post << " ();"
<< "this->" << name << " ();";
else
- os << arg_type (type) << " tmp (this->" << inst << "->" <<
+ os << arg_type (type) << " tmp (" << inst << "->" <<
post << " ());"
<< "this->" << name << " (tmp);";
diff --git a/xsd/cxx/parser/elements.cxx b/xsd/cxx/parser/elements.cxx
index f504cf5..585d42c 100644
--- a/xsd/cxx/parser/elements.cxx
+++ b/xsd/cxx/parser/elements.cxx
@@ -181,12 +181,6 @@ namespace CXX
}
String const& Context::
- emember_cache (SemanticGraph::Member& m)
- {
- return m.context ().get<String> ("member-cache");
- }
-
- String const& Context::
emember_map (SemanticGraph::Member& m)
{
return m.context ().get<String> ("member-map");
diff --git a/xsd/cxx/parser/elements.hxx b/xsd/cxx/parser/elements.hxx
index aebccd3..edcd9f2 100644
--- a/xsd/cxx/parser/elements.hxx
+++ b/xsd/cxx/parser/elements.hxx
@@ -90,9 +90,6 @@ namespace CXX
emember (SemanticGraph::Member&);
static String const&
- emember_cache (SemanticGraph::Member&);
-
- static String const&
emember_map (SemanticGraph::Member&);
public:
diff --git a/xsd/cxx/parser/name-processor.cxx b/xsd/cxx/parser/name-processor.cxx
index a173a15..dff4050 100644
--- a/xsd/cxx/parser/name-processor.cxx
+++ b/xsd/cxx/parser/name-processor.cxx
@@ -156,9 +156,6 @@ namespace CXX
!m.type ().context ().count ("anonymous"))
{
m.context ().set (
- "member-cache", find_name (base + L"_parser_cache_", set_));
-
- m.context ().set (
"member-map", find_name (base + L"_parser_map_", set_));
m.context ().set (
@@ -292,7 +289,7 @@ namespace CXX
m.is_a<SemanticGraph::Element> () &&
!m.type ().context ().count ("anonymous"));
- String parser, member, member_cache, member_map, member_map_impl;
+ String parser, member, member_map, member_map_impl;
try
{
@@ -306,7 +303,6 @@ namespace CXX
if (poly)
{
- member_cache = bm.context ().get<String> ("member-cache");
member_map = bm.context ().get<String> ("member-map");
member_map_impl = bm.context ().get<String> ("member-map-impl");
}
@@ -322,7 +318,6 @@ namespace CXX
if (poly)
{
- member_cache = find_name (base + L"_parser_cache_", set_);
member_map = find_name (base + L"_parser_map_", set_);
member_map_impl = find_name (base + L"_parser_map_impl_", set_);
}
@@ -333,7 +328,6 @@ namespace CXX
if (poly)
{
- m.context ().set ("member-cache", member_cache);
m.context ().set ("member-map", member_map);
m.context ().set ("member-map-impl", member_map_impl);
}
diff --git a/xsd/cxx/parser/parser-header.cxx b/xsd/cxx/parser/parser-header.cxx
index c4bf8fd..3a7d86f 100644
--- a/xsd/cxx/parser/parser-header.cxx
+++ b/xsd/cxx/parser/parser-header.cxx
@@ -295,8 +295,7 @@ namespace CXX
m.is_a<SemanticGraph::Element> () &&
!anonymous (m.type ()))
{
- os << type << "* " << emember_cache (m) << ";"
- << "const " << parser_map << "* " << emember_map (m) << ";"
+ os << "const " << parser_map << "* " << emember_map (m) << ";"
<< endl;
}
}
diff --git a/xsd/cxx/parser/parser-source.cxx b/xsd/cxx/parser/parser-source.cxx
index 81ea9cb..59ddaba 100644
--- a/xsd/cxx/parser/parser-source.cxx
+++ b/xsd/cxx/parser/parser-source.cxx
@@ -290,8 +290,6 @@ namespace CXX
Boolean poly (polymorphic && !anonymous (e.type ()));
- String const& inst (poly ? emember_cache (e) : emember (e));
-
os << "if (";
if (poly && e.global_p ())
@@ -321,9 +319,12 @@ namespace CXX
os << ")"
<< "{";
+ String inst;
+
if (poly)
{
SemanticGraph::Type& t (e.type ());
+ inst = "p";
// For pre-computing length.
//
@@ -339,8 +340,10 @@ namespace CXX
String const& member (emember (e));
String const& member_map (emember_map (e));
- os << "if (t == 0 && this->" << member << " != 0)" << endl
- << "this->" << inst << " = this->" << member << ";"
+ os << fq_type << "* p = 0;"
+ << endl
+ << "if (t == 0 && this->" << member << " != 0)" << endl
+ << inst << " = this->" << member << ";"
<< "else"
<< "{"
<< string_type << " ts (" << fq_type <<
@@ -350,21 +353,21 @@ namespace CXX
<< "t = &ts;"
<< endl
<< "if (this->" << member << " != 0 && *t == ts)" << endl
- << "this->" << inst << " = this->" << member << ";"
+ << inst << " = this->" << member << ";"
<< "else if (this->" << member_map << " != 0)" << endl
- << "this->" << inst << " = dynamic_cast< " << fq_type <<
+ << inst << " = dynamic_cast< " << fq_type <<
"* > (" << endl
<< "this->" << member_map << "->find (*t));"
- << "else" << endl
- << "this->" << inst << " = 0;"
<< "}";
}
+ else
+ inst = L"this->" + emember (e);
os << "this->" << complex_base << "::context_.top ().parser_ = " <<
- "this->" << inst << ";"
+ inst << ";"
<< endl
- << "if (this->" << inst << ")" << endl
- << "this->" << inst << "->pre ();" // _start_element calls _pre
+ << "if (" << inst << ")" << endl
+ << inst << "->pre ();" // _start_element calls _pre
<< endl
<< "return true;"
<< "}";
@@ -388,9 +391,7 @@ namespace CXX
return;
Boolean poly (polymorphic && !anonymous (e.type ()));
-
String const& name (ename (e));
- String const& inst (poly ? emember_cache (e) : emember (e));
os << "if (";
@@ -426,18 +427,31 @@ namespace CXX
SemanticGraph::Type& type (e.type ());
String const& post (post_name (type));
+ String inst;
+
+ if (poly)
+ {
+ String const& fq_type (fq_name (type));
+ inst = "p";
+
+ os << fq_type << "* p =" << endl
+ << "static_cast< " << fq_type << "* > (" << endl
+ << "this->" << complex_base << "::context_.top ().parser_);"
+ << endl;
+ }
+ else
+ inst = L"this->" + emember (e);
- os << "if (this->" << inst << ")";
+ os << "if (" << inst << ")";
if (ret_type (type) == L"void")
os << "{"
- << "this->" << inst << "->" << post << " ();"
+ << inst << "->" << post << " ();"
<< "this->" << name << " ();"
<< "}";
else
os << endl
- << "this->" << name << " (this->" << inst << "->" <<
- post << " ());"
+ << "this->" << name << " (" << inst << "->" << post << " ());"
<< endl;
os << "return true;"