diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2010-01-19 11:44:48 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2010-01-19 11:44:48 +0200 |
commit | 3bf42ed8ccc93a3ff5fdabb9153b887018075acc (patch) | |
tree | 19608b70275324a6e49f7f013ddff912b26128d4 | |
parent | 4257e28e3bbb92042f5a1db05eba17d7b2a3b151 (diff) |
Add support for selective polymorphic in C++/Tree
New options: --polymorphic-type, --polymorphic-type-all.
35 files changed, 1183 insertions, 263 deletions
@@ -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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --generate-inline --generate-forward --generate-polymorphic --polymorphic-type person --generate-intellisense --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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 "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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" people.xsd"
+ CommandLine="xsd cxx-tree --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" --fwd-prologue "#include \"people-custom-fwd.hxx\"" --hxx-prologue "#include \"people-custom.hxx\"" 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& 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"> +<!-- base.xsd --> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <xs:complexType name="base"> + <xs:sequence> + <xs:element name="b" type="xs:int"/> + </xs:sequence> + </xs:complexType> + + <!-- substitution group root --> + <xs:element name="base" type="base"/> + +</xs:schema> + </pre> + + <pre class="xml"> +<!-- derived.xsd --> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <include schemaLocation="base.xsd"/> + + <xs:complexType name="derived"> + <xs:complexContent> + <xs:extension base="base"> + <xs:sequence> + <xs:element name="d" type="xs:string"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:element name="derived" type="derived" substitutionGroup="base"/> + +</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 \ |