summaryrefslogtreecommitdiff
path: root/slicer
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2020-07-05 18:55:25 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2020-07-05 18:55:25 +0100
commit7377afe2be381ea748b8eea930d14b77cdc02191 (patch)
tree588b7f18dd30917232f4f50ac0db09c41e1f69d9 /slicer
parentAdd support for a slicer post-processor (diff)
downloadslicer-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.
Diffstat (limited to 'slicer')
-rw-r--r--slicer/test/classtype.ice1
-rw-r--r--slicer/test/collections.ice1
-rw-r--r--slicer/test/preprocessor.cpp2
-rw-r--r--slicer/test/serializers.cpp6
-rw-r--r--slicer/tool/parser.cpp30
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())) {