diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2020-07-05 18:55:25 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2020-07-05 18:55:25 +0100 |
commit | 7377afe2be381ea748b8eea930d14b77cdc02191 (patch) | |
tree | 588b7f18dd30917232f4f50ac0db09c41e1f69d9 | |
parent | Add support for a slicer post-processor (diff) | |
download | slicer-7377afe2be381ea748b8eea930d14b77cdc02191.tar.bz2 slicer-7377afe2be381ea748b8eea930d14b77cdc02191.tar.xz slicer-7377afe2be381ea748b8eea930d14b77cdc02191.zip |
Fix link error with containers defined in same slice as element
Adds forward declaration of classes with public visibility before
slice2cpp's default forward declaration is included.
-rw-r--r-- | slicer/test/classtype.ice | 1 | ||||
-rw-r--r-- | slicer/test/collections.ice | 1 | ||||
-rw-r--r-- | slicer/test/preprocessor.cpp | 2 | ||||
-rw-r--r-- | slicer/test/serializers.cpp | 6 | ||||
-rw-r--r-- | slicer/tool/parser.cpp | 30 |
5 files changed, 38 insertions, 2 deletions
diff --git a/slicer/test/classtype.ice b/slicer/test/classtype.ice index 98ec34a..54f4d45 100644 --- a/slicer/test/classtype.ice +++ b/slicer/test/classtype.ice @@ -8,6 +8,7 @@ module TestModule { int a; int b; }; + sequence<ClassType> Classes; }; #endif diff --git a/slicer/test/collections.ice b/slicer/test/collections.ice index c9845e0..60798cd 100644 --- a/slicer/test/collections.ice +++ b/slicer/test/collections.ice @@ -7,7 +7,6 @@ module TestModule { sequence<string> SimpleSeq; sequence<BuiltIns> BuiltInSeq; - sequence<ClassType> Classes; local sequence<StructType> Structs; dictionary<int, ClassType> ClassMap; local dictionary<int, StructType> StructMap; diff --git a/slicer/test/preprocessor.cpp b/slicer/test/preprocessor.cpp index 4f474ee..eddeb31 100644 --- a/slicer/test/preprocessor.cpp +++ b/slicer/test/preprocessor.cpp @@ -10,7 +10,7 @@ #include <tool/parser.h> using ComponentsCount = std::map<std::string, unsigned int>; -ComponentsCount COMPONENTS_IN_TEST_ICE = {{"classtype.ice", 1}, {"classes.ice", 3}, {"collections.ice", 6}, +ComponentsCount COMPONENTS_IN_TEST_ICE = {{"classtype.ice", 2}, {"classes.ice", 3}, {"collections.ice", 5}, {"enums.ice", 2}, {"inheritance.ice", 12}, {"interfaces.ice", 0}, {"json.ice", 2}, {"locals.ice", 7}, {"optionals.ice", 2}, {"structs.ice", 4}, {"types.ice", 3}, {"xml.ice", 5}}; diff --git a/slicer/test/serializers.cpp b/slicer/test/serializers.cpp index 3ab54e5..c8f8390 100644 --- a/slicer/test/serializers.cpp +++ b/slicer/test/serializers.cpp @@ -690,3 +690,9 @@ BOOST_AUTO_TEST_CASE(enum_lookups) BOOST_CHECK_EQUAL("One", Slicer::ModelPartForEnum<TestModule::SomeNumbers>::lookup(TestModule::SomeNumbers::One)); BOOST_CHECK_EQUAL(TestModule::SomeNumbers::One, Slicer::ModelPartForEnum<TestModule::SomeNumbers>::lookup("One")); } + +BOOST_AUTO_TEST_CASE(sequence_element_in_same_slice_link_bug) +{ + // Link error when sequence element type defined in same slice. + Slicer::ModelPartForSequence<TestModule::Classes> mp(nullptr); +} diff --git a/slicer/tool/parser.cpp b/slicer/tool/parser.cpp index 81bb10e..d2288ae 100644 --- a/slicer/tool/parser.cpp +++ b/slicer/tool/parser.cpp @@ -14,6 +14,32 @@ namespace fs = std::filesystem; namespace Slicer { + class ForwardDeclare : public Slice::ParserVisitor { + public: + ForwardDeclare(FILE * c) : cpp(c) { } + bool + visitModuleStart(const Slice::ModulePtr & m) override + { + fprintbf(cpp, "namespace %s {\n", m->name()); + return true; + } + + bool + visitClassDefStart(const Slice::ClassDefPtr & c) override + { + fprintbf(cpp, "class ICE_CLASS(JAM_DLL_PUBLIC) %s;\n", c->name()); + return false; + }; + + void + visitModuleEnd(const Slice::ModulePtr & m) override + { + fprintbf(cpp, "} // %s\n\n", m->name()); + } + + FILE * cpp; + }; + template<typename TPtr> bool ignoreType(const TPtr & t) @@ -102,6 +128,10 @@ namespace Slicer { fprintbf(cpp, "// Begin Slicer code\n\n"); fprintbf(cpp, "#include <%s>\n\n", (headerPrefix / "modelPartsTypes.impl.h").string()); + + ForwardDeclare fd {cpp}; + u->visit(&fd, true); + fprintbf(cpp, "#include <%s>\n", fs::path(topLevelFile.filename()).replace_extension(".h").string()); for (const auto & m : u->modules()) { for (const auto & i : metaDataValues("slicer:include:", m->getMetaData())) { |