aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS10
-rw-r--r--dist/examples/cxx/tree/custom/taxonomy/makefile1
-rw-r--r--dist/examples/cxx/tree/custom/taxonomy/taxonomy-7.1.vcproj4
-rw-r--r--dist/examples/cxx/tree/custom/taxonomy/taxonomy-8.0.vcproj8
-rw-r--r--dist/examples/cxx/tree/custom/taxonomy/taxonomy-9.0.vcproj8
-rw-r--r--dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-7.1.vcproj4
-rw-r--r--dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-8.0.vcproj8
-rw-r--r--dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-9.0.vcproj8
-rw-r--r--documentation/cxx/tree/manual/index.xhtml57
-rw-r--r--documentation/xsd.125
-rw-r--r--documentation/xsd.xhtml20
-rw-r--r--examples/cxx/tree/custom/taxonomy/README5
-rw-r--r--examples/cxx/tree/custom/taxonomy/makefile1
-rw-r--r--examples/cxx/tree/custom/taxonomy/people-custom.cxx23
-rw-r--r--examples/cxx/tree/custom/taxonomy/people-custom.hxx6
-rw-r--r--examples/cxx/tree/polymorphism/README6
-rw-r--r--tests/cxx/tree/complex/ctor/makefile3
-rw-r--r--tests/cxx/tree/polymorphism/comparison/makefile3
-rw-r--r--tests/cxx/tree/polymorphism/ostream/makefile3
-rw-r--r--tests/cxx/tree/prefix/makefile2
-rw-r--r--xsd/cxx/tree/cli.hxx4
-rw-r--r--xsd/cxx/tree/elements.cxx79
-rw-r--r--xsd/cxx/tree/elements.hxx41
-rw-r--r--xsd/cxx/tree/generator.cxx23
-rw-r--r--xsd/cxx/tree/parser-source.cxx8
-rw-r--r--xsd/cxx/tree/polymorphism-processor.cxx791
-rw-r--r--xsd/cxx/tree/polymorphism-processor.hxx35
-rw-r--r--xsd/cxx/tree/serialization-source.cxx41
-rw-r--r--xsd/cxx/tree/stream-extraction-source.cxx19
-rw-r--r--xsd/cxx/tree/stream-insertion-source.cxx26
-rw-r--r--xsd/cxx/tree/stream-source.cxx26
-rw-r--r--xsd/cxx/tree/tree-header.cxx49
-rw-r--r--xsd/cxx/tree/tree-source.cxx95
-rw-r--r--xsd/cxx/tree/validator.cxx3
-rw-r--r--xsd/makefile1
35 files changed, 1183 insertions, 263 deletions
diff --git a/NEWS b/NEWS
index 58512d4..956a9fd 100644
--- a/NEWS
+++ b/NEWS
@@ -46,6 +46,16 @@ Version 3.3.0
example and Section 2.9.2, "Element Map" in the C++/Tree Mapping
User Manual.
+ * Prior to this version when the --generate-polymorphic option is
+ specified the compiler treats all types as potentially polymorphic.
+ Now by default only type hierarchies used in substitution groups and
+ those explicitly declared polymorphic with the new --polymorphic-type
+ option are treated as polymorphic. This results in smaller and faster
+ generated code. If you would like to continue using the old behavior,
+ you will need to specify --polymorphic-type-all. For more information
+ on this change see Section 2.11, "Mapping for xsi:type and Substitution
+ Groups" in the C++/Tree Mapping User Manual.
+
* New option, --export-xml-schema, causes the compiler to export/import
types in the XML Schema namespace using the export symbol provided
with the --export-symbol option.
diff --git a/dist/examples/cxx/tree/custom/taxonomy/makefile b/dist/examples/cxx/tree/custom/taxonomy/makefile
index 0d4f068..11fa6ef 100644
--- a/dist/examples/cxx/tree/custom/taxonomy/makefile
+++ b/dist/examples/cxx/tree/custom/taxonomy/makefile
@@ -6,6 +6,7 @@ include $(root)/build/xsd/tree-rules.make
override XSDFLAGS += --generate-inline --generate-forward \
--generate-polymorphic \
+--polymorphic-type person \
--custom-type "person=person_impl<person_base>/person_base" \
--custom-type "superman=superman_impl<superman_base>/superman_base" \
--custom-type "batman=batman_impl<batman_base>/batman_base" \
diff --git a/dist/examples/cxx/tree/custom/taxonomy/taxonomy-7.1.vcproj b/dist/examples/cxx/tree/custom/taxonomy/taxonomy-7.1.vcproj
index befefb7..2f8b136 100644
--- a/dist/examples/cxx/tree/custom/taxonomy/taxonomy-7.1.vcproj
+++ b/dist/examples/cxx/tree/custom/taxonomy/taxonomy-7.1.vcproj
@@ -161,7 +161,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"/>
</FileConfiguration>
<FileConfiguration
@@ -169,7 +169,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"/>
</FileConfiguration>
</File>
diff --git a/dist/examples/cxx/tree/custom/taxonomy/taxonomy-8.0.vcproj b/dist/examples/cxx/tree/custom/taxonomy/taxonomy-8.0.vcproj
index ab1ccbf..72fe0ba 100644
--- a/dist/examples/cxx/tree/custom/taxonomy/taxonomy-8.0.vcproj
+++ b/dist/examples/cxx/tree/custom/taxonomy/taxonomy-8.0.vcproj
@@ -402,7 +402,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
@@ -412,7 +412,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
@@ -422,7 +422,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
@@ -432,7 +432,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
diff --git a/dist/examples/cxx/tree/custom/taxonomy/taxonomy-9.0.vcproj b/dist/examples/cxx/tree/custom/taxonomy/taxonomy-9.0.vcproj
index ccbc74b..fa728e2 100644
--- a/dist/examples/cxx/tree/custom/taxonomy/taxonomy-9.0.vcproj
+++ b/dist/examples/cxx/tree/custom/taxonomy/taxonomy-9.0.vcproj
@@ -399,7 +399,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
@@ -409,7 +409,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
@@ -419,7 +419,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
@@ -429,7 +429,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
diff --git a/dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-7.1.vcproj b/dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-7.1.vcproj
index 8e19b1e..bb699b1 100644
--- a/dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-7.1.vcproj
+++ b/dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-7.1.vcproj
@@ -161,7 +161,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"/>
</FileConfiguration>
<FileConfiguration
@@ -169,7 +169,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"/>
</FileConfiguration>
</File>
diff --git a/dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-8.0.vcproj b/dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-8.0.vcproj
index c3b9e02..f3a8e6a 100644
--- a/dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-8.0.vcproj
+++ b/dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-8.0.vcproj
@@ -402,7 +402,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
@@ -412,7 +412,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
@@ -422,7 +422,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
@@ -432,7 +432,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
diff --git a/dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-9.0.vcproj b/dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-9.0.vcproj
index 388dcf5..77eb684 100644
--- a/dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-9.0.vcproj
+++ b/dist/examples/cxx/tree/custom/taxonomy/taxonomy-xerces2-9.0.vcproj
@@ -399,7 +399,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
@@ -409,7 +409,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
@@ -419,7 +419,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
@@ -429,7 +429,7 @@
<Tool
Name="VCCustomBuildTool"
Description="xsd people.xsd"
- CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --custom-type &quot;person=person_impl&lt;person_base&gt;/person_base&quot; --custom-type &quot;superman=superman_impl&lt;superman_base&gt;/superman_base&quot; --custom-type &quot;batman=batman_impl&lt;batman_base&gt;/batman_base&quot; --fwd-prologue &quot;#include \&quot;people-custom-fwd.hxx\&quot;&quot; --hxx-prologue &quot;#include \&quot;people-custom.hxx\&quot;&quot; people.xsd"
Outputs="people-fwd.hxx,people.hxx;people.ixx;people.cxx"
/>
</FileConfiguration>
diff --git a/documentation/cxx/tree/manual/index.xhtml b/documentation/cxx/tree/manual/index.xhtml
index f1696c0..c00be9e 100644
--- a/documentation/cxx/tree/manual/index.xhtml
+++ b/documentation/cxx/tree/manual/index.xhtml
@@ -3470,6 +3470,63 @@ f (root&amp; r)
}
</pre>
+ <p>The mapping can often automatically determine which types are
+ polymorphic based on the substitution group declarations. However,
+ if your XML vocabulary is not using substitution groups or if
+ substitution groups are defined in a separate schema, then you will
+ need to use the <code>--polymorphic-type</code> option to specify
+ which types are polymorphic. When using this option you only need
+ to specify the root of a polymorphic type hierarchy and the mapping
+ will assume that all the derived types are also polymorphic.
+ Also note that you need to specify this option when compiling every
+ schema file that references the polymorphic type. Consider the following
+ two schemas as an example:</p>
+
+ <pre class="xml">
+&lt;!-- base.xsd -->
+&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ &lt;xs:complexType name="base">
+ &lt;xs:sequence>
+ &lt;xs:element name="b" type="xs:int"/>
+ &lt;/xs:sequence>
+ &lt;/xs:complexType>
+
+ &lt;!-- substitution group root -->
+ &lt;xs:element name="base" type="base"/>
+
+&lt;/xs:schema>
+ </pre>
+
+ <pre class="xml">
+&lt;!-- derived.xsd -->
+&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ &lt;include schemaLocation="base.xsd"/>
+
+ &lt;xs:complexType name="derived">
+ &lt;xs:complexContent>
+ &lt;xs:extension base="base">
+ &lt;xs:sequence>
+ &lt;xs:element name="d" type="xs:string"/>
+ &lt;/xs:sequence>
+ &lt;/xs:extension>
+ &lt;/xs:complexContent>
+ &lt;/xs:complexType>
+
+ &lt;xs:element name="derived" type="derived" substitutionGroup="base"/>
+
+&lt;/xs:schema>
+ </pre>
+
+ <p>In this example we need to specify "<code>--polymorphic-type base</code>"
+ when compiling both schemas because the substitution group is declared
+ in a schema other than the one defining type <code>base</code>.</p>
+
+ <p>You can also indicate that all types should be treated as polymorphic
+ with the <code>--polymorphic-type-all</code>. However, this may result
+ in slower generated code with a greater footprint.</p>
+
<!-- Mapping for any and anyAttribute -->
diff --git a/documentation/xsd.1 b/documentation/xsd.1
index 743f1af..762d865 100644
--- a/documentation/xsd.1
+++ b/documentation/xsd.1
@@ -739,6 +739,31 @@ are replaced with new lines.
Generate polymorphism-aware code. Specify this option if you use substitution
groups or
.BR xsi:type .
+Use the
+.B --polymorphic-type
+or
+.B --polymorphic-type-all
+option to specify which type hierarchies are polymorphic.
+
+.IP "\fB\--polymorphic-type \fItype\fR"
+Indicate that
+.I type
+is a root of a polymorphic type hierarchy. The compiler can often
+automatically determine which types are polymorphic based on the
+substitution group declarations. However, you may need to use this
+option if you are not using substitution groups or if substitution
+groups are defined in another schema. You need to specify this option
+when compiling every schema file that references
+.IR type .
+The
+.I type
+argument is an XML Schema type name that can be optionally qualified
+with a namespace in the
+.IB namespace # name
+form.
+
+.IP "\fB\--polymorphic-type-all\fR"
+Indicate that all types should be treated as polymorphic.
.IP "\fB\--generate-serialization\fR"
Generate serialization functions. Serialization functions convert
diff --git a/documentation/xsd.xhtml b/documentation/xsd.xhtml
index 1f1c5f8..46e8c1a 100644
--- a/documentation/xsd.xhtml
+++ b/documentation/xsd.xhtml
@@ -657,7 +657,25 @@
<dl class="options">
<dt><code><b>--generate-polymorphic</b></code></dt>
<dd>Generate polymorphism-aware code. Specify this option if you use
- substitution groups or <code><b>xsi:type</b></code>.</dd>
+ substitution groups or <code><b>xsi:type</b></code>. Use the
+ <code><b>--polymorphic-type</b></code> or
+ <code><b>--polymorphic-type-all</b></code> option to specify
+ which type hierarchies are polymorphic.</dd>
+
+ <dt><code><b>--polymorphic-type</b></code> <i>type</i></dt>
+ <dd>Indicate that <code><i>type</i></code> is a root of a polymorphic
+ type hierarchy. The compiler can often automatically determine
+ which types are polymorphic based on the substitution group
+ declarations. However, you may need to use this option if you are
+ not using substitution groups or if substitution groups are defined
+ in another schema. You need to specify this option when compiling
+ every schema file that references <code><i>type</i></code>. The
+ <code><i>type</i></code> argument is an XML Schema type name that
+ can be optionally qualified with a namespace in the
+ <code><i>namespace</i><b>#</b><i>name</i></code> form.</dd>
+
+ <dt><code><b>--polymorphic-type-all</b></code></dt>
+ <dd>Indicate that all types should be treated as polymorphic.</dd>
<dt><code><b>--generate-serialization</b></code></dt>
<dd>Generate serialization functions. Serialization functions
diff --git a/examples/cxx/tree/custom/taxonomy/README b/examples/cxx/tree/custom/taxonomy/README
index 356aef4..c2e425a 100644
--- a/examples/cxx/tree/custom/taxonomy/README
+++ b/examples/cxx/tree/custom/taxonomy/README
@@ -23,7 +23,10 @@ people.cxx
object model. These are generated by XSD from people.xsd with the
--custom-type option in order to customize the person, superman, and
batman types. Generation of the people-fwd.hxx forward declaration
- file is requested with the --generate-forward option.
+ file is requested with the --generate-forward option. Note also that
+ we use the --generate-polymorphic command line option as well as
+ --polymorphic-type to mark the type hierarchy starting with the
+ person type as polymorphic.
people-custom-fwd.hxx
Header file which forward-declares our own person, superman, and batman
diff --git a/examples/cxx/tree/custom/taxonomy/makefile b/examples/cxx/tree/custom/taxonomy/makefile
index 4ecb64a..ca3327c 100644
--- a/examples/cxx/tree/custom/taxonomy/makefile
+++ b/examples/cxx/tree/custom/taxonomy/makefile
@@ -44,6 +44,7 @@ $(gen): xsd_options := \
--generate-inline \
--generate-forward \
--generate-polymorphic \
+--polymorphic-type person \
--custom-type "person=person_impl<person_base>/person_base" \
--custom-type "superman=superman_impl<superman_base>/superman_base" \
--custom-type "batman=batman_impl<batman_base>/batman_base" \
diff --git a/examples/cxx/tree/custom/taxonomy/people-custom.cxx b/examples/cxx/tree/custom/taxonomy/people-custom.cxx
index 14c7087..321d2df 100644
--- a/examples/cxx/tree/custom/taxonomy/people-custom.cxx
+++ b/examples/cxx/tree/custom/taxonomy/people-custom.cxx
@@ -21,13 +21,6 @@ namespace people
template <typename base>
person_impl<base>::
- person_impl (std::auto_ptr<xml_schema::string>& name)
- : base (name)
- {
- }
-
- template <typename base>
- person_impl<base>::
person_impl (const xercesc::DOMElement& e,
xml_schema::flags f,
xml_schema::container* c)
@@ -74,13 +67,6 @@ namespace people
template <typename base>
superman_impl<base>::
- superman_impl (std::auto_ptr<xml_schema::string>& name, bool can_fly)
- : base (name, can_fly)
- {
- }
-
- template <typename base>
- superman_impl<base>::
superman_impl (const xercesc::DOMElement& e,
xml_schema::flags f,
xml_schema::container* c)
@@ -134,15 +120,6 @@ namespace people
template <typename base>
batman_impl<base>::
- batman_impl (std::auto_ptr<xml_schema::string>& name,
- bool can_fly,
- unsigned int wing_span)
- : base (name, can_fly, wing_span)
- {
- }
-
- template <typename base>
- batman_impl<base>::
batman_impl (const xercesc::DOMElement& e,
xml_schema::flags f,
xml_schema::container* c)
diff --git a/examples/cxx/tree/custom/taxonomy/people-custom.hxx b/examples/cxx/tree/custom/taxonomy/people-custom.hxx
index 23e7731..c601061 100644
--- a/examples/cxx/tree/custom/taxonomy/people-custom.hxx
+++ b/examples/cxx/tree/custom/taxonomy/people-custom.hxx
@@ -23,7 +23,6 @@ namespace people
{
public:
person_impl (const xml_schema::string& name);
- person_impl (std::auto_ptr<xml_schema::string>& name);
person_impl (const xercesc::DOMElement&,
xml_schema::flags = 0,
@@ -50,7 +49,6 @@ namespace people
{
public:
superman_impl (const xml_schema::string& name, bool can_fly);
- superman_impl (std::auto_ptr<xml_schema::string>& name, bool can_fly);
superman_impl (const xercesc::DOMElement&,
xml_schema::flags = 0,
@@ -80,10 +78,6 @@ namespace people
bool can_fly,
unsigned int wing_span);
- batman_impl (std::auto_ptr<xml_schema::string>& name,
- bool can_fly,
- unsigned int wing_span);
-
batman_impl (const xercesc::DOMElement&,
xml_schema::flags = 0,
xml_schema::container* = 0);
diff --git a/examples/cxx/tree/polymorphism/README b/examples/cxx/tree/polymorphism/README
index 05d794f..6e54e49 100644
--- a/examples/cxx/tree/polymorphism/README
+++ b/examples/cxx/tree/polymorphism/README
@@ -15,7 +15,11 @@ supermen.cxx
functions that convert XML instance documents to a tree-like in-memory
object model, and a set of serialization functions that convert the
object model back to XML. These are generated by XSD from supermen.xsd.
- Note the use of the --generate-polymorphic command line option.
+ Note also that we use the --generate-polymorphic command line option
+ and that we don't need to use --polymorphic-type to explicitly mark
+ types as polymorphic because this is automatically deduced by the
+ XSD compiler from the substitution groups used in the supermen.xsd
+ schema.
driver.cxx
Driver for the example. It first calls one of the parsing functions
diff --git a/tests/cxx/tree/complex/ctor/makefile b/tests/cxx/tree/complex/ctor/makefile
index 44776f6..66558f5 100644
--- a/tests/cxx/tree/complex/ctor/makefile
+++ b/tests/cxx/tree/complex/ctor/makefile
@@ -35,7 +35,8 @@ gen := $(addprefix $(out_base)/,$(genf))
$(gen): xsd := $(out_root)/xsd/xsd
$(gen): xsd_options := --generate-default-ctor --generate-from-base-ctor \
---generate-doxygen --generate-polymorphic --generate-comparison
+--generate-doxygen --generate-polymorphic --polymorphic-type-all \
+--generate-comparison
$(gen): $(out_root)/xsd/xsd
$(call include-dep,$(dep))
diff --git a/tests/cxx/tree/polymorphism/comparison/makefile b/tests/cxx/tree/polymorphism/comparison/makefile
index 6ab64a3..ad2c8ec 100644
--- a/tests/cxx/tree/polymorphism/comparison/makefile
+++ b/tests/cxx/tree/polymorphism/comparison/makefile
@@ -34,7 +34,8 @@ genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx)
gen := $(addprefix $(out_base)/,$(genf))
$(gen): xsd := $(out_root)/xsd/xsd
-$(gen): xsd_options := --generate-polymorphic --generate-comparison
+$(gen): xsd_options := --generate-polymorphic --polymorphic-type base \
+--generate-comparison
$(gen): $(out_root)/xsd/xsd
$(call include-dep,$(dep))
diff --git a/tests/cxx/tree/polymorphism/ostream/makefile b/tests/cxx/tree/polymorphism/ostream/makefile
index 313c1e3..661ba16 100644
--- a/tests/cxx/tree/polymorphism/ostream/makefile
+++ b/tests/cxx/tree/polymorphism/ostream/makefile
@@ -34,7 +34,8 @@ genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx)
gen := $(addprefix $(out_base)/,$(genf))
$(gen): xsd := $(out_root)/xsd/xsd
-$(gen): xsd_options := --generate-polymorphic --generate-ostream
+$(gen): xsd_options := --generate-polymorphic --polymorphic-type-all \
+--generate-ostream
$(gen): $(out_root)/xsd/xsd
$(call include-dep,$(dep))
diff --git a/tests/cxx/tree/prefix/makefile b/tests/cxx/tree/prefix/makefile
index 5de6fba..3317161 100644
--- a/tests/cxx/tree/prefix/makefile
+++ b/tests/cxx/tree/prefix/makefile
@@ -35,7 +35,7 @@ gen := $(addprefix $(out_base)/,$(genf))
$(gen): xsd := $(out_root)/xsd/xsd
$(gen): xsd_options := --generate-serialization --generate-polymorphic \
---root-element root
+--polymorphic-type foo\\\#base --root-element root
$(gen): $(out_root)/xsd/xsd
$(call include-dep,$(dep))
diff --git a/xsd/cxx/tree/cli.hxx b/xsd/cxx/tree/cli.hxx
index 538c10b..c4294b6 100644
--- a/xsd/cxx/tree/cli.hxx
+++ b/xsd/cxx/tree/cli.hxx
@@ -27,6 +27,8 @@ namespace CXX
extern Key char_encoding;
extern Key output_dir;
extern Key generate_polymorphic;
+ extern Key polymorphic_type;
+ extern Key polymorphic_type_all;
extern Key generate_serialization;
extern Key generate_inline;
extern Key generate_ostream;
@@ -123,6 +125,8 @@ namespace CXX
char_encoding, NarrowString,
output_dir, NarrowString,
generate_polymorphic, Boolean,
+ polymorphic_type, Cult::Containers::Vector<NarrowString>,
+ polymorphic_type_all, Boolean,
generate_serialization, Boolean,
generate_inline, Boolean,
generate_ostream, Boolean,
diff --git a/xsd/cxx/tree/elements.cxx b/xsd/cxx/tree/elements.cxx
index 31e0c08..0072e07 100644
--- a/xsd/cxx/tree/elements.cxx
+++ b/xsd/cxx/tree/elements.cxx
@@ -85,6 +85,7 @@ namespace CXX
generate_xml_schema (generate_xml_schema_),
doxygen (doxygen_),
polymorphic (ops.value<CLI::generate_polymorphic> ()),
+ polymorphic_all (ops.value<CLI::polymorphic_type_all> ()),
fwd_expr (fe),
hxx_expr (he),
ixx_expr (ie),
@@ -322,6 +323,7 @@ namespace CXX
generate_xml_schema (c.generate_xml_schema),
doxygen (c.doxygen),
polymorphic (c.polymorphic),
+ polymorphic_all (c.polymorphic_all),
fwd_expr (c.fwd_expr),
hxx_expr (c.hxx_expr),
ixx_expr (c.ixx_expr),
@@ -361,6 +363,7 @@ namespace CXX
generate_xml_schema (c.generate_xml_schema),
doxygen (c.doxygen),
polymorphic (c.polymorphic),
+ polymorphic_all (c.polymorphic_all),
fwd_expr (c.fwd_expr),
hxx_expr (c.hxx_expr),
ixx_expr (c.ixx_expr),
@@ -595,6 +598,20 @@ namespace CXX
}
}
+ Boolean Context::
+ polymorphic_p (SemanticGraph::Type& t)
+ {
+ if (polymorphic_all)
+ {
+ Boolean fund (false);
+ IsFundamentalType test (fund);
+ test.dispatch (t);
+ return !fund;
+ }
+ else
+ return t.context ().get<Boolean> ("polymorphic");
+ }
+
// GenerateDefautCtor
//
GenerateDefaultCtor::
@@ -710,15 +727,15 @@ namespace CXX
// HasComplexNonOptArgs
//
- HasComplexNonFundNonOptArgs::
- HasComplexNonFundNonOptArgs (Context& c,
- Boolean base,
- Boolean& complex,
- Boolean& non_fund,
- Boolean& clash)
+ HasComplexPolyNonOptArgs::
+ HasComplexPolyNonOptArgs (Context& c,
+ Boolean base,
+ Boolean& complex,
+ Boolean& poly,
+ Boolean& clash)
: Context (c),
complex_ (complex),
- non_fund_ (non_fund),
+ poly_ (poly),
clash_ (clash)
{
if (base)
@@ -727,7 +744,7 @@ namespace CXX
*this >> names_ >> *this;
}
- Void HasComplexNonFundNonOptArgs::
+ Void HasComplexPolyNonOptArgs::
traverse (SemanticGraph::Complex& c)
{
// No optimizations: need to check every arg for clashes.
@@ -736,28 +753,25 @@ namespace CXX
names (c, names_);
}
- Void HasComplexNonFundNonOptArgs::
+ Void HasComplexPolyNonOptArgs::
traverse (SemanticGraph::Element& e)
{
if (!skip (e) && min (e) == 1 && max (e) == 1)
{
- Boolean fund (false);
- IsFundamentalType t (fund);
+ Boolean poly (polymorphic && polymorphic_p (e.type ()));
+
+ Boolean simple (true);
+ IsSimpleType t (simple);
t.dispatch (e.type ());
- if (!fund)
- {
- non_fund_ = true;
+ if (poly)
+ poly_ = true;
- Boolean simple (true);
- IsSimpleType t (simple);
- t.dispatch (e.type ());
+ if (!simple)
+ complex_ = true;
- if (!simple)
- complex_ = true;
- else
- clash_ = false;
- }
+ if (poly && simple)
+ clash_ = false;
}
}
@@ -811,12 +825,9 @@ namespace CXX
auto_ptr = !simple;
break;
}
- case arg_non_fund_auto_ptr:
+ case arg_poly_auto_ptr:
{
- Boolean fund (false);
- IsFundamentalType t (fund);
- t.dispatch (e.type ());
- auto_ptr = !fund;
+ auto_ptr = polymorphic && polymorphic_p (e.type ());
break;
}
case arg_type:
@@ -947,12 +958,9 @@ namespace CXX
auto_ptr = !simple;
break;
}
- case arg_non_fund_auto_ptr:
+ case arg_poly_auto_ptr:
{
- Boolean fund (false);
- IsFundamentalType t (fund);
- t.dispatch (e.type ());
- auto_ptr = !fund;
+ auto_ptr = polymorphic && polymorphic_p (e.type ());
break;
}
case arg_type:
@@ -1039,12 +1047,9 @@ namespace CXX
auto_ptr = !simple;
break;
}
- case arg_non_fund_auto_ptr:
+ case arg_poly_auto_ptr:
{
- Boolean fund (false);
- IsFundamentalType t (fund);
- t.dispatch (e.type ());
- auto_ptr = !fund;
+ auto_ptr = polymorphic && polymorphic_p (e.type ());
break;
}
case arg_type:
diff --git a/xsd/cxx/tree/elements.hxx b/xsd/cxx/tree/elements.hxx
index 1caf378..2160baf 100644
--- a/xsd/cxx/tree/elements.hxx
+++ b/xsd/cxx/tree/elements.hxx
@@ -158,6 +158,18 @@ namespace CXX
Void
write_annotation (SemanticGraph::Annotation&);
+ //
+ //
+ public:
+ Boolean
+ polymorphic_p (SemanticGraph::Type&);
+
+ Boolean
+ anonymous_p (SemanticGraph::Type const& t)
+ {
+ return t.context ().count ("anonymous");
+ }
+
// Escaped names.
//
public:
@@ -400,6 +412,7 @@ namespace CXX
Boolean& generate_xml_schema;
Boolean& doxygen;
Boolean polymorphic;
+ Boolean polymorphic_all;
Regex const* fwd_expr;
Regex const* hxx_expr;
@@ -1437,20 +1450,20 @@ namespace CXX
};
// Test whether the type has any non-optional element of complex
- // (has attributes/elements) and non-fundamental types.
+ // (has attributes/elements) and polymorpjic types.
//
- struct HasComplexNonFundNonOptArgs: Traversal::Complex,
- Traversal::Element,
- Context
+ struct HasComplexPolyNonOptArgs: Traversal::Complex,
+ Traversal::Element,
+ Context
{
- // complex and non_fund should initially be false. clash
+ // complex and poly should initially be false. clash
// should initially be true.
//
- HasComplexNonFundNonOptArgs (Context& c,
- Boolean including_base,
- Boolean& complex,
- Boolean& non_fund,
- Boolean& clash);
+ HasComplexPolyNonOptArgs (Context& c,
+ Boolean including_base,
+ Boolean& complex,
+ Boolean& poly,
+ Boolean& clash);
virtual Void
traverse (SemanticGraph::Complex&);
@@ -1460,7 +1473,7 @@ namespace CXX
private:
Boolean& complex_;
- Boolean& non_fund_;
+ Boolean& poly_;
Boolean& clash_;
Traversal::Inherits inherits_;
@@ -1479,7 +1492,7 @@ namespace CXX
{
arg_type,
arg_complex_auto_ptr,
- arg_non_fund_auto_ptr
+ arg_poly_auto_ptr
};
FromBaseCtorArg (Context& c, ArgType, Boolean arg);
@@ -1513,7 +1526,7 @@ namespace CXX
{
arg_type,
arg_complex_auto_ptr,
- arg_non_fund_auto_ptr
+ arg_poly_auto_ptr
};
// The second version outputs the argument name and stores
@@ -1680,7 +1693,7 @@ namespace CXX
{
arg_type,
arg_complex_auto_ptr,
- arg_non_fund_auto_ptr
+ arg_poly_auto_ptr
};
CtorArgsWithoutBase (Context& c, ArgType, Boolean arg, Boolean first);
diff --git a/xsd/cxx/tree/generator.cxx b/xsd/cxx/tree/generator.cxx
index 012a1fd..a70214c 100644
--- a/xsd/cxx/tree/generator.cxx
+++ b/xsd/cxx/tree/generator.cxx
@@ -10,6 +10,7 @@
#include <cxx/tree/counter.hxx>
#include <cxx/tree/validator.hxx>
#include <cxx/tree/name-processor.hxx>
+#include <cxx/tree/polymorphism-processor.hxx>
#include <cxx/tree/tree-forward.hxx>
#include <cxx/tree/tree-header.hxx>
@@ -119,6 +120,8 @@ namespace CXX
extern Key char_encoding = "char-encoding";
extern Key output_dir = "output-dir";
extern Key generate_polymorphic = "generate-polymorphic";
+ extern Key polymorphic_type = "polymorphic-type";
+ extern Key polymorphic_type_all = "polymorphic-type-all";
extern Key generate_serialization = "generate-serialization";
extern Key generate_inline = "generate-inline";
extern Key generate_ostream = "generate-ostream";
@@ -239,6 +242,16 @@ namespace CXX
<< " option if you use substitution groups or xsi:type."
<< endl;
+ e << "--polymorphic-type <type>" << endl
+ << " Indicate that <type> is a root of a polymorphic\n"
+ << " type hierarchy."
+ << endl;
+
+ e << "--polymorphic-type-all" << endl
+ << " Indicate that all types should be treated as\n"
+ << " polymorphic."
+ << endl;
+
e << "--generate-serialization" << endl
<< " Generate serialization functions. They convert an\n"
<< " in-memory representation back to XML."
@@ -878,6 +891,16 @@ namespace CXX
throw Failed ();
}
+ // Process polymorphic types.
+ //
+ if (ops.value<CLI::generate_polymorphic> () &&
+ !ops.value<CLI::polymorphic_type_all> ())
+ {
+ PolymorphismProcessor proc;
+ if (!proc.process (ops, schema, file_path, disabled_warnings))
+ throw Failed ();
+ }
+
// Parts.
//
UnsignedLong parts (ops.value<CLI::parts> ());
diff --git a/xsd/cxx/tree/parser-source.cxx b/xsd/cxx/tree/parser-source.cxx
index 66abf96..94d0b91 100644
--- a/xsd/cxx/tree/parser-source.cxx
+++ b/xsd/cxx/tree/parser-source.cxx
@@ -295,18 +295,16 @@ namespace CXX
//
Boolean fund (false);
-
{
IsFundamentalType test (fund);
test.dispatch (t);
}
// Check if we need to handle xsi:type and substitution groups.
- // If this element's type is anonymous or mapped to a fundamental
- // C++ type then we don't need to do anything.
+ // If this element's type is anonymous then we don't need to do
+ // anything.
//
- Boolean poly (!fund && polymorphic &&
- !t.context ().count ("anonymous"));
+ Boolean poly (polymorphic && polymorphic_p (t) && !anonymous_p (t));
// const DOMDocument&
//
diff --git a/xsd/cxx/tree/polymorphism-processor.cxx b/xsd/cxx/tree/polymorphism-processor.cxx
new file mode 100644
index 0000000..2d12a75
--- /dev/null
+++ b/xsd/cxx/tree/polymorphism-processor.cxx
@@ -0,0 +1,791 @@
+// file : xsde/cxx/tree/polymorphism-processor.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/elements.hxx>
+#include <cxx/tree/polymorphism-processor.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/set.hxx>
+
+#include <iostream>
+
+using std::wcerr;
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ struct TypeSet
+ {
+ template <typename I>
+ TypeSet (I begin, I end)
+ {
+ for (; begin != end; ++begin)
+ insert (*begin);
+ }
+
+ Void
+ insert (String const& name)
+ {
+ Size p (name.rfind ('#'));
+
+ if (p == String::npos)
+ unames_.insert (name);
+ else
+ qnames_.insert (name);
+ }
+
+ Boolean
+ find (SemanticGraph::Type& t)
+ {
+ if (!unames_.empty ())
+ {
+ if (unames_.find (t.name ()) != unames_.end ())
+ return true;
+ }
+
+ if (!qnames_.empty ())
+ {
+ if (qnames_.find (t.scope ().name () + L"#" + t.name ()) !=
+ qnames_.end ())
+ return true;
+ }
+
+ return false;
+ }
+
+ private:
+ typedef Cult::Containers::Set<String> StringSet;
+
+ StringSet unames_;
+ StringSet qnames_;
+ };
+
+
+ //
+ //
+ struct Type: Traversal::Type,
+ Traversal::Complex
+ {
+ Type (TypeSet& poly_types)
+ : poly_types_ (poly_types)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& t)
+ {
+ SemanticGraph::Context& ctx (t.context ());
+
+ if (!ctx.count ("polymorphic"))
+ ctx.set ("polymorphic", poly_types_.find (t));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ SemanticGraph::Context& ctx (c.context ());
+
+ if (!ctx.count ("polymorphic"))
+ {
+ // First check our base.
+ //
+ Boolean pb (false);
+ if (c.inherits_p ())
+ {
+ SemanticGraph::Type& b (c.inherits ().base ());
+
+ if (!b.context ().count ("polymorphic"))
+ dispatch (b);
+
+ pb = b.context ().get<Boolean> ("polymorphic");
+ }
+
+ ctx.set ("polymorphic", pb || poly_types_.find (c));
+ }
+ }
+
+ private:
+ TypeSet& poly_types_;
+ };
+
+ struct FundType: Traversal::AnyType,
+ Traversal::AnySimpleType,
+
+ Traversal::Fundamental::Byte,
+ Traversal::Fundamental::UnsignedByte,
+ Traversal::Fundamental::Short,
+ Traversal::Fundamental::UnsignedShort,
+ Traversal::Fundamental::Int,
+ Traversal::Fundamental::UnsignedInt,
+ Traversal::Fundamental::Long,
+ Traversal::Fundamental::UnsignedLong,
+ Traversal::Fundamental::Integer,
+ Traversal::Fundamental::NonPositiveInteger,
+ Traversal::Fundamental::NonNegativeInteger,
+ Traversal::Fundamental::PositiveInteger,
+ Traversal::Fundamental::NegativeInteger,
+
+ Traversal::Fundamental::Boolean,
+
+ Traversal::Fundamental::Float,
+ Traversal::Fundamental::Double,
+ Traversal::Fundamental::Decimal,
+
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NameTokens,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language,
+
+ Traversal::Fundamental::QName,
+
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::IdRefs,
+
+ Traversal::Fundamental::AnyURI,
+
+ Traversal::Fundamental::Base64Binary,
+ Traversal::Fundamental::HexBinary,
+
+ Traversal::Fundamental::Date,
+ Traversal::Fundamental::DateTime,
+ Traversal::Fundamental::Duration,
+ Traversal::Fundamental::Day,
+ Traversal::Fundamental::Month,
+ Traversal::Fundamental::MonthDay,
+ Traversal::Fundamental::Year,
+ Traversal::Fundamental::YearMonth,
+ Traversal::Fundamental::Time,
+
+ Traversal::Fundamental::Entity,
+ Traversal::Fundamental::Entities
+ {
+ FundType (TypeSet& poly_types, Boolean& valid)
+ : poly_types_ (poly_types), valid_ (valid)
+ {
+ }
+
+ Void
+ check (SemanticGraph::Type& t, Boolean fund)
+ {
+ SemanticGraph::Context& ctx (t.context ());
+
+ if (poly_types_.find (t))
+ {
+ if (!fund)
+ ctx.set ("polymorphic", true);
+ else
+ {
+ wcerr << "error: built-in type '" << t.name () << "' cannot "
+ << "be polymorphic because it is mapped to a fundamental "
+ << "C++ type"
+ << endl;
+
+ valid_ = false;
+ }
+ }
+ else
+ ctx.set ("polymorphic", false);
+ }
+
+ // anyType & anySimpleType.
+ //
+ virtual Void
+ traverse (SemanticGraph::AnyType& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnySimpleType& t)
+ {
+ check (t, true);
+ }
+
+ // Boolean.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Boolean& t)
+ {
+ check (t, false);
+ }
+
+ // Integral types.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Byte& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedByte& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Short& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedShort& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Int& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedInt& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Long& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedLong& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Integer& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::PositiveInteger& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NegativeInteger& t)
+ {
+ check (t, false);
+ }
+
+ // Floats.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Float& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Double& t)
+ {
+ check (t, false);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Decimal& t)
+ {
+ check (t, false);
+ }
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameTokens& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language& t)
+ {
+ check (t, true);
+ }
+
+
+ // Qualified name.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::QName& t)
+ {
+ check (t, true);
+ }
+
+
+ // ID/IDREF.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRefs& t)
+ {
+ check (t, true);
+ }
+
+ // URI.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::AnyURI& t)
+ {
+ check (t, true);
+ }
+
+ // Binary.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Base64Binary& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::HexBinary& t)
+ {
+ check (t, true);
+ }
+
+
+ // Date/time.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Date& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::DateTime& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Duration& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Day& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Month& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::MonthDay& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Year& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::YearMonth& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Time& t)
+ {
+ check (t, true);
+ }
+
+ // Entity.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entity& t)
+ {
+ check (t, true);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entities& t)
+ {
+ check (t, true);
+ }
+
+ private:
+ TypeSet& poly_types_;
+ Boolean& valid_;
+ };
+
+ 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 ("T005") != 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 ());
+
+ // We may need to override the previous value.
+ //
+ if (ctx.count ("polymorphic") && ctx.get<Boolean> ("polymorphic"))
+ return;
+
+ // Built-in types that are mapped to fundamental types cannot
+ // be declared polymorphic.
+ //
+ Boolean fund (false);
+ IsFundamentalType test (fund);
+ test.dispatch (rt);
+
+ if (fund)
+ {
+ wcerr << r.file () << ":" << r.line () << ":" << r.column ()
+ << ": error: built-in type '" << rt.name () << "' "
+ << "is mapped to a fundamental C++ type and 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;
+
+ valid_ = false;
+ return;
+ }
+
+ ctx.set ("polymorphic", true);
+
+ if (!warning_)
+ return;
+
+ Schema& es (dynamic_cast<Schema&> (e.scope ().scope ()));
+ Schema& rts (dynamic_cast<Schema&> (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))
+ {
+ wcerr << rt.file () << ":" << rt.line () << ":" << rt.column ()
+ << ": warning T005: 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<Sources> ())
+ {
+ 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
+ // we don't process the same stuff more than once.
+ //
+ struct Uses: Traversal::Sources,
+ 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 (seen_key_))
+ {
+ s.context ().set (seen_key_, true);
+ Traversal::Sources::traverse (sr);
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Includes& i)
+ {
+ SemanticGraph::Schema& s (i.schema ());
+
+ if (!s.context ().count (seen_key_))
+ {
+ s.context ().set (seen_key_, true);
+ Traversal::Includes::traverse (i);
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Imports& i)
+ {
+ SemanticGraph::Schema& s (i.schema ());
+
+ if (!s.context ().count (seen_key_))
+ {
+ s.context ().set (seen_key_, true);
+ Traversal::Imports::traverse (i);
+ }
+ }
+
+ private:
+ Char const* seen_key_;
+ };
+
+ Char const* pass_one_key = "cxx-tree-polymorphism-processor-seen-one";
+ Char const* pass_two_key = "cxx-tree-polymorphism-processor-seen-two";
+
+ Boolean
+ process_impl (CLI::Options const& ops,
+ SemanticGraph::Schema& tu,
+ SemanticGraph::Path const&,
+ const WarningSet& disabled_warnings)
+ {
+ Boolean valid (true);
+
+ // Prepare a set of polymorphic types.
+ //
+
+ TypeSet poly_types (ops.value<CLI::polymorphic_type> ().begin (),
+ ops.value<CLI::polymorphic_type> ().end ());
+
+ // Root schema in the file-per-type mode is just a bunch
+ // of includes without a namespace.
+ //
+ SemanticGraph::Schema::NamesIterator i (tu.names_begin ());
+
+ if (i != tu.names_end () &&
+ i->named ().name () == L"http://www.w3.org/2001/XMLSchema")
+ {
+ // XML Schema namespace.
+ //
+ Traversal::Schema schema;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ FundType fund_type (poly_types, valid);
+
+ schema >> schema_names >> ns >> ns_names >> fund_type;
+
+ schema.dispatch (tu);
+ }
+ else
+ {
+ // First handle fundamental types.
+ //
+ {
+ Traversal::Schema schema;
+ Traversal::Implies implies;
+ Traversal::Schema xs_schema;
+
+ schema >> implies >> xs_schema;
+
+ Traversal::Names xs_schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ FundType fund_type (poly_types, valid);
+
+ xs_schema >> xs_schema_names >> ns >> ns_names >> fund_type;
+
+ schema.dispatch (tu);
+ }
+
+ // Note that we check first if this schema has already been
+ // processed which may happen in the file-per-type compilation
+ // mode.
+ //
+ if (!tu.context ().count (pass_two_key))
+ {
+ // Pass one - check substitution groups.
+ //
+ if (valid)
+ {
+ 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 (pass_two_key);
+
+ schema >> uses >> schema;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ Type type (poly_types);
+
+ schema >> schema_names >> ns >> ns_names >> type;
+
+ // Some twisted schemas do recusive self-inclusion.
+ //
+ tu.context ().set (pass_two_key, true);
+
+ schema.dispatch (tu);
+ }
+ }
+ }
+
+ return valid;
+ }
+ }
+
+ Boolean PolymorphismProcessor::
+ process (CLI::Options const& ops,
+ SemanticGraph::Schema& tu,
+ SemanticGraph::Path const& file,
+ const WarningSet& disabled_warnings)
+ {
+ return process_impl (ops, tu, file, disabled_warnings);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/polymorphism-processor.hxx b/xsd/cxx/tree/polymorphism-processor.hxx
new file mode 100644
index 0000000..3fbeca8
--- /dev/null
+++ b/xsd/cxx/tree/polymorphism-processor.hxx
@@ -0,0 +1,35 @@
+// file : xsde/cxx/tree/polymorphism-processor.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_POLYMORPHISM_PROCESSOR_HXX
+#define CXX_TREE_POLYMORPHISM_PROCESSOR_HXX
+
+#include <cult/types.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+
+#include <cxx/tree/cli.hxx>
+
+#include <xsd.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ using namespace Cult::Types;
+
+ class PolymorphismProcessor
+ {
+ public:
+ Boolean
+ process (CLI::Options const& options,
+ XSDFrontend::SemanticGraph::Schema&,
+ XSDFrontend::SemanticGraph::Path const& file,
+ const WarningSet& disabled_warnings);
+ };
+ }
+}
+
+#endif // CXX_TREE_POLYMORPHISM_PROCESSOR_HXX
diff --git a/xsd/cxx/tree/serialization-source.cxx b/xsd/cxx/tree/serialization-source.cxx
index 69f66c0..410b59a 100644
--- a/xsd/cxx/tree/serialization-source.cxx
+++ b/xsd/cxx/tree/serialization-source.cxx
@@ -93,7 +93,7 @@ namespace CXX
// Register with type factory map.
//
- if (polymorphic && !l.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (l) && !anonymous_p (l))
{
// Note that we are using the original type name.
//
@@ -173,7 +173,7 @@ namespace CXX
// Register with type factory map.
//
- if (polymorphic && !u.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (u) && !anonymous_p (u))
{
// Note that we are using the original type name.
//
@@ -255,7 +255,7 @@ namespace CXX
// Register with type factory map.
//
- if (polymorphic && !e.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (e) && !anonymous_p (e))
{
// Note that we are using the original type name.
//
@@ -295,21 +295,13 @@ namespace CXX
String type (scope + L"::" + etype (e));
// Check if we need to handle xsi:type and substitution groups.
- // If this element's type is anonymous or mapped to a fundamental
- // C++ type then we don't need to do anything. Note that if the
- // type is anonymous then it can't be derived from which makes it
- // impossible to substitute or dynamically-type with xsi:type.
+ // If this element's type is anonymous then we don't need to do
+ // anything. Note that if the type is anonymous then it can't be
+ // derived from which makes it impossible to substitute or
+ // dynamically-type with xsi:type.
//
SemanticGraph::Type& t (e.type ());
- Boolean poly (polymorphic && !t.context ().count ("anonymous"));
-
- if (poly)
- {
- Boolean fund (false);
- IsFundamentalType traverser (fund);
- traverser.dispatch (t);
- poly = !fund;
- }
+ Boolean poly (polymorphic && polymorphic_p (t) && !anonymous_p (t));
os << "// " << comment (e.name ()) << endl
<< "//" << endl;
@@ -815,7 +807,7 @@ namespace CXX
// Register with type factory map.
//
- if (polymorphic && !c.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (c) && !anonymous_p (c))
{
// Note that we are using the original type name.
//
@@ -958,18 +950,13 @@ namespace CXX
// confused if the name is 'type'. (see tests/schema/anonymous)
//
- Boolean fund (false);
- {
- IsFundamentalType t (fund);
- t.dispatch (type);
- }
-
// Check if we need to handle xsi:type and substitution groups.
- // If this element's type is anonymous or mapped to a fundamental
- // C++ type then we don't need to do anything.
+ // If this element's type is anonymous then we don't need to do
+ // anything.
//
- Boolean poly (!fund && polymorphic &&
- !type.context ().count ("anonymous"));
+ Boolean poly (polymorphic &&
+ polymorphic_p (type) &&
+ !anonymous_p (type));
// To std::ostream.
//
diff --git a/xsd/cxx/tree/stream-extraction-source.cxx b/xsd/cxx/tree/stream-extraction-source.cxx
index c777f30..fe9e31f 100644
--- a/xsd/cxx/tree/stream-extraction-source.cxx
+++ b/xsd/cxx/tree/stream-extraction-source.cxx
@@ -61,7 +61,7 @@ namespace CXX
// Register with type map.
//
- if (polymorphic && !l.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (l) && !anonymous_p (l))
{
// Note that we are using the original type name.
//
@@ -129,7 +129,7 @@ namespace CXX
// Register with type map.
//
- if (polymorphic && !u.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (u) && !anonymous_p (u))
{
// Note that we are using the original type name.
//
@@ -198,7 +198,7 @@ namespace CXX
// Register with type map.
//
- if (polymorphic && !e.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (e) && !anonymous_p (e))
{
// Note that we are using the original type name.
//
@@ -299,13 +299,12 @@ namespace CXX
}
// Figure out if we need to generate polymorphic code. If this
- // elemen's type is anonymous or mapped to a fundamental C++
- // type then we don't need to do anything. Note that if the type
- // is anonymous then it can't be derived from which makes it
- // impossible to substitute or dynamically-type with xsi:type.
+ // elemen's type is anonymous then we don't need to do anything.
+ // Note that if the type is anonymous then it can't be derived
+ // from which makes it impossible to substitute or dynamically-
+ // type with xsi:type.
//
- Boolean poly (!fund && polymorphic &&
- !t.context ().count ("anonymous"));
+ Boolean poly (polymorphic && polymorphic_p (t) && !anonymous_p (t));
if (max (e) != 1)
{
@@ -632,7 +631,7 @@ namespace CXX
// Register with type map.
//
- if (polymorphic && !c.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (c) && !anonymous_p (c))
{
// Note that we are using the original type name.
//
diff --git a/xsd/cxx/tree/stream-insertion-source.cxx b/xsd/cxx/tree/stream-insertion-source.cxx
index d7e721d..ae58dcc 100644
--- a/xsd/cxx/tree/stream-insertion-source.cxx
+++ b/xsd/cxx/tree/stream-insertion-source.cxx
@@ -60,7 +60,7 @@ namespace CXX
// Register with type map.
//
- if (polymorphic && !l.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (l) && !anonymous_p (l))
{
// Note that we are using the original type name.
//
@@ -128,7 +128,7 @@ namespace CXX
// Register with type map.
//
- if (polymorphic && !u.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (u) && !anonymous_p (u))
{
// Note that we are using the original type name.
//
@@ -187,7 +187,7 @@ namespace CXX
// Register with type map.
//
- if (polymorphic && !e.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (e) && !anonymous_p (e))
{
// Note that we are using the original type name.
//
@@ -228,20 +228,12 @@ namespace CXX
String type (scope + L"::" + etype (e));
// Figure out if we need to generate polymorphic code. If this
- // elemen's type is anonymous or mapped to a fundamental C++
- // type then we don't need to do anything. Note that if the type
- // is anonymous then it can't be derived from which makes it
- // impossible to substitute or dynamically-type with xsi:type.
+ // elemen's type is anonymous then we don't need to do anything.
+ // Note that if the type is anonymous then it can't be derived
+ // from which makes it impossible to substitute or dynamically-
+ // type with xsi:type.
//
- Boolean poly (polymorphic && !t.context ().count ("anonymous"));
-
- if (poly)
- {
- Boolean fund (false);
- IsFundamentalType traverser (fund);
- traverser.dispatch (t);
- poly = !fund;
- }
+ Boolean poly (polymorphic && polymorphic_p (t) && !anonymous_p (t));
if (max (e) != 1)
{
@@ -416,7 +408,7 @@ namespace CXX
// Register with type map.
//
- if (polymorphic && !c.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (c) && !anonymous_p (c))
{
// Note that we are using the original type name.
//
diff --git a/xsd/cxx/tree/stream-source.cxx b/xsd/cxx/tree/stream-source.cxx
index a93d49e..c663158 100644
--- a/xsd/cxx/tree/stream-source.cxx
+++ b/xsd/cxx/tree/stream-source.cxx
@@ -52,7 +52,7 @@ namespace CXX
// Register with ostream map.
//
- if (polymorphic && !l.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (l) && !anonymous_p (l))
{
// Note that we are using the original type name.
//
@@ -107,7 +107,7 @@ namespace CXX
// Register with ostream map.
//
- if (polymorphic && !u.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (u) && !anonymous_p (u))
{
// Note that we are using the original type name.
//
@@ -185,7 +185,7 @@ namespace CXX
// Register with ostream map.
//
- if (polymorphic && !e.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (e) && !anonymous_p (e))
{
// Note that we are using the original type name.
//
@@ -220,21 +220,13 @@ namespace CXX
String const& aname (eaname (e));
// Check if we need to handle xsi:type and substitution groups.
- // If this element's type is anonymous or mapped to a fundamental
- // C++ type then we don't need to do anything. Note that if the
- // type is anonymous then it can't be derived from which makes it
- // impossible to substitute or dynamically-type with xsi:type.
+ // If this element's type is anonymous then we don't need to do
+ // anything. Note that if the type is anonymous then it can't be
+ // derived from which makes it impossible to substitute or
+ // dynamically-type with xsi:type.
//
SemanticGraph::Type& t (e.type ());
- Boolean poly (polymorphic && !t.context ().count ("anonymous"));
-
- if (poly)
- {
- Boolean fund (false);
- IsFundamentalType traverser (fund);
- traverser.dispatch (t);
- poly = !fund;
- }
+ Boolean poly (polymorphic && polymorphic_p (t) && !anonymous_p (t));
// aCC cannot handle an inline call to std_ostream_map_instance.
//
@@ -388,7 +380,7 @@ namespace CXX
// Register with ostream map.
//
- if (polymorphic && !c.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (c) && !anonymous_p (c))
{
// Note that we are using the original type name.
//
diff --git a/xsd/cxx/tree/tree-header.cxx b/xsd/cxx/tree/tree-header.cxx
index fa5820d..7e884c8 100644
--- a/xsd/cxx/tree/tree-header.cxx
+++ b/xsd/cxx/tree/tree-header.cxx
@@ -2389,13 +2389,13 @@ namespace CXX
}
Boolean has_complex_non_op_args (false);
- Boolean has_non_fund_non_op_args (false);
- Boolean complex_non_fund_args_clash (true);
+ Boolean has_poly_non_op_args (false);
+ Boolean complex_poly_args_clash (true);
{
- HasComplexNonFundNonOptArgs t (*this, true,
- has_complex_non_op_args,
- has_non_fund_non_op_args,
- complex_non_fund_args_clash);
+ HasComplexPolyNonOptArgs t (*this, true,
+ has_complex_non_op_args,
+ has_poly_non_op_args,
+ complex_poly_args_clash);
t.traverse (c);
}
@@ -2450,13 +2450,13 @@ namespace CXX
if (generate)
{
Boolean has_complex_non_op_args (false);
- Boolean has_non_fund_non_op_args (false);
- Boolean complex_non_fund_args_clash (true);
+ Boolean has_poly_non_op_args (false);
+ Boolean complex_poly_args_clash (true);
{
- HasComplexNonFundNonOptArgs t (*this, false,
- has_complex_non_op_args,
- has_non_fund_non_op_args,
- complex_non_fund_args_clash);
+ HasComplexPolyNonOptArgs t (*this, false,
+ has_complex_non_op_args,
+ has_poly_non_op_args,
+ complex_poly_args_clash);
t.traverse (c);
}
@@ -2517,10 +2517,10 @@ namespace CXX
}
// If we are generating polymorphic code then we also need to
- // provide auto_ptr version for every non-fundamental type.
+ // provide auto_ptr version for every polymorphic type.
//
if (polymorphic &&
- has_non_fund_non_op_args && !complex_non_fund_args_clash)
+ has_poly_non_op_args && !complex_poly_args_clash)
{
if (doxygen)
{
@@ -2542,7 +2542,7 @@ namespace CXX
os << "&";
{
FromBaseCtorArg args (
- *this, FromBaseCtorArg::arg_non_fund_auto_ptr, false);
+ *this, FromBaseCtorArg::arg_poly_auto_ptr, false);
Traversal::Names args_names (args);
names (c, args_names);
}
@@ -2605,10 +2605,10 @@ namespace CXX
}
// If we are generating polymorphic code then we also need to
- // provide auto_ptr version for every non-fundamental type.
+ // provide auto_ptr version for every polymorphic type.
//
if (polymorphic &&
- has_non_fund_non_op_args && !complex_non_fund_args_clash)
+ has_poly_non_op_args && !complex_poly_args_clash)
{
if (doxygen)
{
@@ -2626,7 +2626,7 @@ namespace CXX
os << name << " (";
{
CtorArgsWithoutBase ctor_args (
- *this, CtorArgsWithoutBase::arg_non_fund_auto_ptr, false, true);
+ *this, CtorArgsWithoutBase::arg_poly_auto_ptr, false, true);
ctor_args.dispatch (c);
}
os << ");"
@@ -2763,10 +2763,9 @@ namespace CXX
}
// If we are generating polymorphic code then we also need to
- // provide auto_ptr version for every non-fundamental type.
+ // provide auto_ptr version for every polymorphic type.
//
- if (polymorphic &&
- has_non_fund_non_op_args && !complex_non_fund_args_clash)
+ if (polymorphic && has_poly_non_op_args && !complex_poly_args_clash)
{
if (doxygen)
{
@@ -2786,7 +2785,7 @@ namespace CXX
os << name << " (";
{
- CtorArgs ctor_args (*this, CtorArgs::arg_non_fund_auto_ptr);
+ CtorArgs ctor_args (*this, CtorArgs::arg_poly_auto_ptr);
ctor_args.dispatch (c);
}
@@ -3341,11 +3340,9 @@ namespace CXX
// If the element value is a complex type (has elements,
// attributes, or wildcards) then also generate the auto_ptr
// version. If we are generating polymorphic code then we
- // also need to provide auto_ptr version for simple, non-
- // fundamental values.
+ // also need to provide auto_ptr version for simple types.
//
- //
- if (!simple || (polymorphic && !fund))
+ if (!simple || (polymorphic && polymorphic_p (t)))
{
if (doxygen)
{
diff --git a/xsd/cxx/tree/tree-source.cxx b/xsd/cxx/tree/tree-source.cxx
index 8c70f23..3f902e7 100644
--- a/xsd/cxx/tree/tree-source.cxx
+++ b/xsd/cxx/tree/tree-source.cxx
@@ -105,7 +105,7 @@ namespace CXX
// Register with type factory map.
//
- if (polymorphic && !l.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (l) && !anonymous_p (l))
{
// Note that we are using the original type name.
//
@@ -212,7 +212,7 @@ namespace CXX
// Register with type factory map.
//
- if (polymorphic && !u.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (u) && !anonymous_p (u))
{
// Note that we are using the original type name.
//
@@ -504,7 +504,7 @@ namespace CXX
// Register with type factory map.
//
- if (polymorphic && !e.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (e) && !anonymous_p (e))
{
// Note that we are using the original type name.
//
@@ -672,23 +672,21 @@ namespace CXX
String tr (etraits (e)); // traits type name
String type (etype (e));
- // Check if we need to handle xsi:type and substitution groups.
- // If this element's type is anonymous or mapped to a fundamental
- // C++ type then we don't need to do anything. Note that if the
- // type is anonymous then it can't be derived from which makes it
- // impossible to substitute or dynamically-type with xsi:type.
- //
SemanticGraph::Type& t (e.type ());
-
Boolean fund (false);
{
IsFundamentalType traverser (fund);
traverser.dispatch (t);
}
- Boolean poly (
- !fund && polymorphic && !t.context ().count ("anonymous"));
+ // Check if we need to handle xsi:type and substitution groups.
+ // If this element's type is anonymous then we don't need to do
+ // anything. Note that if the type is anonymous then it can't be
+ // derived from which makes it impossible to substitute or
+ // dynamically-type with xsi:type.
+ //
+ Boolean poly (polymorphic && polymorphic_p (t) && !anonymous_p (t));
os << "// " << comment (e.name ()) << endl
<< "//" << endl;
@@ -1802,21 +1800,13 @@ namespace CXX
String const& aname (eaname (e));
// Check if we need to handle xsi:type and substitution groups.
- // If this element's type is anonymous or mapped to a fundamental
- // C++ type then we don't need to do anything. Note that if the
- // type is anonymous then it can't be derived from which makes it
- // impossible to substitute or dynamically-type with xsi:type.
+ // If this element's type is anonymous then we don't need to do
+ // anything. Note that if the type is anonymous then it can't be
+ // derived from which makes it impossible to substitute or
+ // dynamically-type with xsi:type.
//
SemanticGraph::Type& t (e.type ());
- Boolean poly (polymorphic && !t.context ().count ("anonymous"));
-
- if (poly)
- {
- Boolean fund (false);
- IsFundamentalType traverser (fund);
- traverser.dispatch (t);
- poly = !fund;
- }
+ Boolean poly (polymorphic && polymorphic_p (t) && !anonymous_p (t));
if (!poly)
{
@@ -2221,13 +2211,13 @@ namespace CXX
}
Boolean has_complex_non_op_args (false);
- Boolean has_non_fund_non_op_args (false);
- Boolean complex_non_fund_args_clash (true);
+ Boolean has_poly_non_op_args (false);
+ Boolean complex_poly_args_clash (true);
{
- HasComplexNonFundNonOptArgs t (*this, true,
- has_complex_non_op_args,
- has_non_fund_non_op_args,
- complex_non_fund_args_clash);
+ HasComplexPolyNonOptArgs t (*this, true,
+ has_complex_non_op_args,
+ has_poly_non_op_args,
+ complex_poly_args_clash);
t.traverse (c);
}
@@ -2277,13 +2267,13 @@ namespace CXX
if (generate)
{
Boolean has_complex_non_op_args (false);
- Boolean has_non_fund_non_op_args (false);
- Boolean complex_non_fund_args_clash (true);
+ Boolean has_poly_non_op_args (false);
+ Boolean complex_poly_args_clash (true);
{
- HasComplexNonFundNonOptArgs t (*this, false,
- has_complex_non_op_args,
- has_non_fund_non_op_args,
- complex_non_fund_args_clash);
+ HasComplexPolyNonOptArgs t (*this, false,
+ has_complex_non_op_args,
+ has_poly_non_op_args,
+ complex_poly_args_clash);
t.traverse (c);
}
@@ -2352,11 +2342,10 @@ namespace CXX
}
// If we are generating polymorphic code then we also need to
- // provide auto_ptr version for every non-fundamental type.
+ // provide auto_ptr version for every polymorphic type.
//
- if (has_non_fund_non_op_args &&
- !complex_non_fund_args_clash &&
- polymorphic)
+ if (polymorphic &&
+ has_poly_non_op_args && !complex_poly_args_clash)
{
os << name << "::" << endl
<< name << " (const ";
@@ -2364,7 +2353,7 @@ namespace CXX
os << "& " << base_arg;
{
FromBaseCtorArg args (
- *this, FromBaseCtorArg::arg_non_fund_auto_ptr, true);
+ *this, FromBaseCtorArg::arg_poly_auto_ptr, true);
Traversal::Names args_names (args);
names (c, args_names);
}
@@ -2465,17 +2454,16 @@ namespace CXX
}
// If we are generating polymorphic code then we also need to
- // provide auto_ptr version for every non-fundamental type.
+ // provide auto_ptr version for every polymorphic type.
//
- if (has_non_fund_non_op_args &&
- !complex_non_fund_args_clash &&
- polymorphic)
+ if (polymorphic &&
+ has_poly_non_op_args && !complex_poly_args_clash)
{
os << name << "::" << endl
<< name << " (";
{
CtorArgsWithoutBase ctor_args (
- *this, CtorArgsWithoutBase::arg_non_fund_auto_ptr, true, true);
+ *this, CtorArgsWithoutBase::arg_poly_auto_ptr, true, true);
ctor_args.dispatch (c);
}
os << ")" << endl
@@ -2716,11 +2704,10 @@ namespace CXX
}
// If we are generating polymorphic code then we also need to
- // provide auto_ptr version for every non-fundamental type.
+ // provide auto_ptr version for every polymorphic type.
//
- if (has_non_fund_non_op_args &&
- !complex_non_fund_args_clash &&
- polymorphic)
+ if (polymorphic &&
+ has_poly_non_op_args && !complex_poly_args_clash)
{
os << name << "::" << endl
<< name << " (";
@@ -2729,7 +2716,7 @@ namespace CXX
{
CtorArgs ctor_args (
- *this, CtorArgs::arg_non_fund_auto_ptr, base_arg);
+ *this, CtorArgs::arg_poly_auto_ptr, base_arg);
ctor_args.dispatch (c);
}
@@ -3001,7 +2988,7 @@ namespace CXX
// Register with type factory map.
//
- if (polymorphic && !c.context ().count ("anonymous"))
+ if (polymorphic && polymorphic_p (c) && !anonymous_p (c))
{
// Note that we are using the original type name.
//
@@ -3201,7 +3188,7 @@ namespace CXX
// c-tor (auto_ptr<value>)
//
- if (!simple || (polymorphic && !fund))
+ if (!simple || (polymorphic && polymorphic_p (t)))
{
os << name << "::" << endl
<< name << " (::std::auto_ptr< " << type << " > p)" << endl
diff --git a/xsd/cxx/tree/validator.cxx b/xsd/cxx/tree/validator.cxx
index 1f05e65..32dee69 100644
--- a/xsd/cxx/tree/validator.cxx
+++ b/xsd/cxx/tree/validator.cxx
@@ -672,6 +672,9 @@ namespace CXX
}
return valid;
+
+ // T005 is used in polymorphism-processor.cxx.
+ //
}
}
}
diff --git a/xsd/makefile b/xsd/makefile
index 8ff41ed..cc04568 100644
--- a/xsd/makefile
+++ b/xsd/makefile
@@ -31,6 +31,7 @@ cxx_tun += cxx/tree/elements.cxx \
cxx/tree/validator.cxx \
cxx/tree/counter.cxx \
cxx/tree/name-processor.cxx \
+ cxx/tree/polymorphism-processor.cxx \
cxx/tree/default-value.cxx \
cxx/tree/generator.cxx \
cxx/tree/tree-forward.cxx \