From 3242dc49ef311d7240d932cde93a5f1e32df82fd Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 15 Nov 2020 12:36:14 +0000 Subject: Fix cross library MP creation --- slicer/slicer/modelParts.h | 6 +++++- slicer/slicer/modelPartsTypes.h | 3 ++- slicer/slicer/modelPartsTypes.impl.h | 39 ++++++++++++++++++++++++++---------- slicer/test/conversions.cpp | 8 ++++++++ slicer/test/included/Jamfile.jam | 7 +++++++ slicer/test/preprocessor.cpp | 4 ++-- slicer/test/serializers.cpp | 6 +++--- slicer/test/types.ice | 3 +++ slicer/tool/parser.cpp | 26 +++++++++++++++++++++--- 9 files changed, 81 insertions(+), 21 deletions(-) diff --git a/slicer/slicer/modelParts.h b/slicer/slicer/modelParts.h index 97b1623..b0de888 100644 --- a/slicer/slicer/modelParts.h +++ b/slicer/slicer/modelParts.h @@ -122,6 +122,9 @@ namespace Slicer { const std::string * nameStr; }; + template struct DLL_PUBLIC Default { + }; + class DLL_PUBLIC ModelPart : public std::enable_shared_from_this { public: ModelPart() = default; @@ -133,8 +136,9 @@ namespace Slicer { ModelPart & operator=(const ModelPart &) = delete; ModelPart & operator=(ModelPart &&) = delete; - template static ModelPartPtr CreateFor(); + template static ModelPartPtr Make(typename MP::element_type * t); template static ModelPartPtr CreateFor(T & t); + template static ModelPartPtr CreateFor(Default &&); template static ModelPartForRootPtr CreateRootFor(T & t); virtual void OnEachChild(const ChildHandler &) = 0; diff --git a/slicer/slicer/modelPartsTypes.h b/slicer/slicer/modelPartsTypes.h index 28054a8..de0bc29 100644 --- a/slicer/slicer/modelPartsTypes.h +++ b/slicer/slicer/modelPartsTypes.h @@ -114,7 +114,8 @@ namespace Slicer { public ModelPartForOptionalBase, protected ModelPartModel> { public: - explicit ModelPartForOptional(Ice::optional * h); + using element_type = Ice::optional; + explicit ModelPartForOptional(element_type * h); void Create() override; bool GetValue(ValueTarget && s) override; ModelPartType GetType() const override; diff --git a/slicer/slicer/modelPartsTypes.impl.h b/slicer/slicer/modelPartsTypes.impl.h index a008e02..be23e1f 100644 --- a/slicer/slicer/modelPartsTypes.impl.h +++ b/slicer/slicer/modelPartsTypes.impl.h @@ -12,13 +12,27 @@ #include #define CUSTOMMODELPARTFOR(Type, BaseModelPart, ModelPartType) \ - template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor() \ + template<> DLL_PUBLIC ModelPartPtr ModelPart::Make(typename ModelPartType::element_type * t) \ { \ - return std::make_shared(nullptr); \ + return std::make_shared(t); \ + } \ + template<> \ + DLL_PUBLIC ModelPartPtr ModelPart::Make>( \ + Ice::optional * t) \ + { \ + return std::make_shared>(t); \ + } \ + template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor(Default &&) \ + { \ + return Make(nullptr); \ + } \ + template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor(Default> &&) \ + { \ + return Make>(nullptr); \ } \ template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor(Type & s) \ { \ - return std::make_shared(&s); \ + return Make(&s); \ } \ template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor(const Type & s) \ { \ @@ -26,7 +40,7 @@ } \ template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor(Ice::optional & s) \ { \ - return std::make_shared>(&s); \ + return Make>(&s); \ } \ template<> DLL_PUBLIC ModelPartPtr ModelPart::CreateFor(const Ice::optional & s) \ { \ @@ -375,12 +389,15 @@ namespace Slicer { ModelPartPtr Get(T * t) const override { - return std::make_shared( - t ? const_cast::type *>(&(t->*member)) : nullptr); + if (t) { + return Make(&(t->*member)); + } + return Make(nullptr); } private: - const MT T::*member; + using MemPtr = MT T::*; + const MemPtr member; const MetaDataImpl hookMetadata; }; @@ -432,7 +449,7 @@ namespace Slicer { ModelPartPtr ModelPartForClass::CreateModelPart(void * p) { - return std::make_shared>(static_cast(p)); + return ::Slicer::ModelPart::CreateFor(*static_cast(p)); } template @@ -591,7 +608,7 @@ namespace Slicer { ModelPartPtr ModelPartForSequence::GetContainedModelPart() { - return ModelPart::CreateFor(); + return ModelPart::CreateFor(Default {}); } // ModelPartForDictionaryElementInserter @@ -615,7 +632,7 @@ namespace Slicer { { BOOST_ASSERT(this->Model); for (auto & pair : *this->Model) { - ch(pairName, std::make_shared>(&pair), NULL); + ch(pairName, std::make_shared>(&pair), nullptr); } } @@ -657,7 +674,7 @@ namespace Slicer { ModelPartPtr ModelPartForStream::GetContainedModelPart() { - return ModelPart::CreateFor(); + return ModelPart::CreateFor(Default {}); } template diff --git a/slicer/test/conversions.cpp b/slicer/test/conversions.cpp index 8b0f0ab..502975e 100644 --- a/slicer/test/conversions.cpp +++ b/slicer/test/conversions.cpp @@ -155,3 +155,11 @@ namespace TestModule { completions += 1; } } +namespace Slicer { + template<> + DLL_PUBLIC ModelPartPtr + ModelPart::Make(::Ice::Short * m) + { + return std::make_shared(m); + } +} diff --git a/slicer/test/included/Jamfile.jam b/slicer/test/included/Jamfile.jam index 081810a..9871aeb 100644 --- a/slicer/test/included/Jamfile.jam +++ b/slicer/test/included/Jamfile.jam @@ -5,6 +5,13 @@ lib included : : ../..//Ice tidy:none + gcc:../../tool//slicer/gcc + clang:../../tool//slicer/clang + tidy:../../tool//slicer/gcc + yes + gcc:../../tool//slicer/gcc + clang:../../tool//slicer/clang + tidy:../../tool//slicer/gcc : : ../..//Ice . diff --git a/slicer/test/preprocessor.cpp b/slicer/test/preprocessor.cpp index 21ed5f1..72afa63 100644 --- a/slicer/test/preprocessor.cpp +++ b/slicer/test/preprocessor.cpp @@ -12,7 +12,7 @@ using ComponentsCount = std::map; 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", 5}, {"types.ice", 3}, {"xml.ice", 5}}; + {"optionals.ice", 2}, {"structs.ice", 5}, {"types.ice", 4}, {"xml.ice", 5}}; unsigned int total() @@ -21,7 +21,7 @@ total() COMPONENTS_IN_TEST_ICE.begin(), COMPONENTS_IN_TEST_ICE.end(), 0U, [](auto & t, auto && c) { return t += c.second; }); - BOOST_CHECK_EQUAL(48, t); + BOOST_CHECK_EQUAL(49, t); return t; } diff --git a/slicer/test/serializers.cpp b/slicer/test/serializers.cpp index 26e4ad8..a22fd39 100644 --- a/slicer/test/serializers.cpp +++ b/slicer/test/serializers.cpp @@ -726,7 +726,7 @@ BOOST_AUTO_TEST_CASE(DeserializeXmlIncorrectSeqElementName) BOOST_AUTO_TEST_CASE(customerModelPartCounters) { - BOOST_REQUIRE_EQUAL(21, TestModule::completions); + BOOST_REQUIRE_EQUAL(35, TestModule::completions); } BOOST_AUTO_TEST_CASE(enum_lookups) @@ -738,6 +738,6 @@ BOOST_AUTO_TEST_CASE(enum_lookups) BOOST_AUTO_TEST_CASE(sequence_element_in_same_slice_link_bug) { // Link error when sequence element type defined in same slice. - // Slicer::ModelPartForSequence mpClasses(nullptr); - // Slicer::ModelPartForSequence mpDates(nullptr); + BOOST_CHECK(Slicer::ModelPart::Make>(nullptr)); + BOOST_CHECK(Slicer::ModelPart::Make>(nullptr)); } diff --git a/slicer/test/types.ice b/slicer/test/types.ice index ac050b4..ac3a706 100644 --- a/slicer/test/types.ice +++ b/slicer/test/types.ice @@ -19,6 +19,9 @@ module TestModule { int someFunction(); DontCountMe otherFileReference(); }; + class CrossLibrary { + DontCountMe otherFileReference; + }; }; module TestModule2 { diff --git a/slicer/tool/parser.cpp b/slicer/tool/parser.cpp index 595cff4..797944d 100644 --- a/slicer/tool/parser.cpp +++ b/slicer/tool/parser.cpp @@ -190,6 +190,14 @@ namespace Slicer { // Failed to convert fprintbf(cpp, "\tconversion_fail(\"%s\");\n", Slice::typeToString(type)); fprintbf(cpp, "}\n\n"); + + fprintbf(cpp, "\ttemplate<> DLL_PUBLIC ModelPartPtr ModelPart::Make<"); + createModelPartForConverted(type, c->scoped(), dm); + fprintbf(cpp, ">(typename "); + createModelPartForConverted(type, c->scoped(), dm); + fprintbf(cpp, "::element_type * t) { return std::make_shared<"); + createModelPartForConverted(type, c->scoped(), dm); + fprintbf(cpp, ">(t); } \n"); } } @@ -288,6 +296,9 @@ namespace Slicer { if (definedTypes.count(type->typeId())) { return; } + if (Slice::ClassDeclPtr::dynamicCast(type)) { + fprintbf(cpp, "extern template class ModelPartForComplex< %s >;\n", type->typeId()); + } fprintbf(cpp, "extern template class %s< %s >;\n", getBasicModelPart(type), Slice::ClassDeclPtr::dynamicCast(type) ? type->typeId() : Slice::typeToString(type)); } @@ -349,6 +360,9 @@ namespace Slicer { if (auto cmp = md.value("slicer:custommodelpart:")) { fprintbf(cpp, "CUSTOMMODELPARTFOR(%s, %s< %s >, %s);\n\n", Slice::typeToString(decl), getBasicModelPart(decl), c->scoped(), CppName {*cmp}); + fprintbf(cpp, "\ttemplate<> DLL_PUBLIC ModelPartPtr ModelPart::Make<%s<%s> >(%s * t)", + getBasicModelPart(decl), c->scoped(), Slice::typeToString(decl)); + fprintbf(cpp, "{ return std::make_shared<%s>(t); } \n", CppName {*cmp}); } else { fprintbf(cpp, "CUSTOMMODELPARTFOR(%s, ModelPartForClass<%s>, ModelPartForClass<%s>);\n\n", @@ -529,10 +543,13 @@ namespace Slicer { auto lname = std::string {name}; boost::algorithm::to_lower(lname); fprintbf(cpp, "\tconst std::string hstr_C%d_%d { \"%s\" };\n", components, element, name); - fprintbf(cpp, "\tconstexpr C%d::Hook< const %s, ", components, Slice::typeToString(t)); + fprintbf(cpp, "\tconstexpr C%d::Hook< %s, ", components, Slice::typeToString(t)); createNewModelPartPtrFor(t); - fprintbf(cpp, ", 0 > hook%d_%s {&%s::value_type::%s, \"%s\", \"%s\", &hstr_C%d_%s};\n", components, element, - d->scoped(), element, name, lname, components, element); + fprintbf(cpp, + ", 0 > hook%d_%s {const_cast<%s (%s::value_type::*)>(&%s::value_type::%s), \"%s\", \"%s\", " + "&hstr_C%d_%s};\n", + components, element, Slice::typeToString(t), d->scoped(), d->scoped(), element, name, lname, + components, element); }; addHook(md.value("slicer:key:").value_or("key"), "first", d->keyType()); addHook(md.value("slicer:value:").value_or("value"), "second", d->valueType()); @@ -662,6 +679,9 @@ namespace Slicer { if (auto cmp = metadata.value("slicer:custommodelpart:")) { fprintbf(cpp, "CUSTOMMODELPARTFOR(%s, %s< %s >, %s);\n\n", type, getBasicModelPart(stype), type, CppName {*cmp}); + fprintbf(cpp, "\ttemplate<> DLL_PUBLIC ModelPartPtr ModelPart::Make<%s>(%s * t)", getBasicModelPart(stype), + type); + fprintbf(cpp, "{ return std::make_shared<%s>(t); } \n", CppName {*cmp}); } else { fprintbf(cpp, "MODELPARTFOR(%s, %s);\n\n", type, getBasicModelPart(stype)); -- cgit v1.2.3