summaryrefslogtreecommitdiff
path: root/xsd/cxx/parser
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 /xsd/cxx/parser
parent7c064687415c895334650321bd5bc34453b0ce38 (diff)
Fix recursive polymorphic parsing in C++/Parser
New test: cxx/parser/polymorphism/recursive.
Diffstat (limited to 'xsd/cxx/parser')
-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
6 files changed, 60 insertions, 51 deletions
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;"