From a987d0bf51c15a61cc1c458a514d1fbd8478ca2d Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Thu, 19 Oct 2023 17:19:38 -0500 Subject: [PATCH 1/4] Add test for https://github.com/root-project/root/issues/13574 --- root/io/uniquePointer/CMakeLists.txt | 20 ++++++++++ root/io/uniquePointer/ns_privacy.hh | 50 ++++++++++++++++++++++++ root/io/uniquePointer/privacy.hh | 45 +++++++++++++++++++++ root/io/uniquePointer/privacyDict.eref | 0 root/io/uniquePointer/privacyDict.oref | 0 root/io/uniquePointer/privacyInterp.C | 32 +++++++++++++++ root/io/uniquePointer/privacyInterp.eref | 7 ++++ root/io/uniquePointer/privacyInterp.oref | 18 +++++++++ root/io/uniquePointer/privacyLinkDef.h | 15 +++++++ root/io/uniquePointer/privacyLoad.C | 31 +++++++++++++++ root/io/uniquePointer/privacyLoad.eref | 6 +++ root/io/uniquePointer/privacyLoad.oref | 18 +++++++++ 12 files changed, 242 insertions(+) create mode 100644 root/io/uniquePointer/ns_privacy.hh create mode 100644 root/io/uniquePointer/privacy.hh create mode 100644 root/io/uniquePointer/privacyDict.eref create mode 100644 root/io/uniquePointer/privacyDict.oref create mode 100644 root/io/uniquePointer/privacyInterp.C create mode 100644 root/io/uniquePointer/privacyInterp.eref create mode 100644 root/io/uniquePointer/privacyInterp.oref create mode 100644 root/io/uniquePointer/privacyLinkDef.h create mode 100644 root/io/uniquePointer/privacyLoad.C create mode 100644 root/io/uniquePointer/privacyLoad.eref create mode 100644 root/io/uniquePointer/privacyLoad.oref diff --git a/root/io/uniquePointer/CMakeLists.txt b/root/io/uniquePointer/CMakeLists.txt index ace79827ae..cf160f64a5 100644 --- a/root/io/uniquePointer/CMakeLists.txt +++ b/root/io/uniquePointer/CMakeLists.txt @@ -65,6 +65,26 @@ ROOTTEST_ADD_TEST(simpleRead OUTREF simpleRead.ref DEPENDS simpleWriteRead) +ROOTTEST_ADD_TEST(privacy-dict + COMMAND ${ROOT_rootcling_CMD} -f privacy.dict.cc + ${CMAKE_CURRENT_SOURCE_DIR}/privacy.hh + ${CMAKE_CURRENT_SOURCE_DIR}/privacyLinkDef.h + OUTREF privacyDict.oref + ERRREF privacyDict.eref) + +ROOTTEST_GENERATE_DICTIONARY(privacy privacy.hh LINKDEF privacyLinkDef.h) + +ROOTTEST_ADD_TEST(privacy-load + MACRO privacyLoad.C + OUTREF privacyLoad.oref + ERRREF privacyLoad.eref + DEPENDS ${GENERATE_DICTIONARY_TEST}) + +ROOTTEST_ADD_TEST(privacy-interp + MACRO privacyInterp.C + OUTREF privacyInterp.oref + ERRREF privacyInterp.eref) + ROOTTEST_GENERATE_REFLEX_DICTIONARY(classes classes.h SELECTION sel.xml) ROOTTEST_ADD_TEST(simpleWriteRead diff --git a/root/io/uniquePointer/ns_privacy.hh b/root/io/uniquePointer/ns_privacy.hh new file mode 100644 index 0000000000..720364d295 --- /dev/null +++ b/root/io/uniquePointer/ns_privacy.hh @@ -0,0 +1,50 @@ +#ifndef ns_privacy_hh +#define ns_privacy_hh +#include +#include +#include + +namespace fs = std::filesystem; + +namespace privacy +{ + +class test +{ +public: + test() = default; + ~test() = default; + +private: + fs::path path; /// unique_data; + Inner *ptr_data; +}; + +class test2 { +private: + test1 transient_data; /// persistent_data; + std::tuple transient_data; /// +#include +#include + +namespace fs = std::filesystem; + +class test +{ +public: + test() = default; + ~test() = default; + +private: + fs::path path; /// unique_data; + Inner *ptr_data; +}; + +class test2 { +private: + test1 transient_data; /// persistent_data; + std::tuple transient_data; ///GetStreamerInfo()->GetElements()) { + if (auto el = dynamic_cast(member)) { + std::cout << " " << el->GetTypeName(); + if (el->IsaPointer() && !TString(el->GetTypeName()).Contains("*")) + std::cout << "*"; + std::cout << " " << el->GetName() << '\n'; + } + } + std::cout << '\n'; + } + + return 0; +} diff --git a/root/io/uniquePointer/privacyInterp.eref b/root/io/uniquePointer/privacyInterp.eref new file mode 100644 index 0000000000..2e92ed96ca --- /dev/null +++ b/root/io/uniquePointer/privacyInterp.eref @@ -0,0 +1,7 @@ +Warning in : privacy::test: filesystem::path has no streamer or dictionary, data member "persistent_path" will not be saved +Error in : privacy::test1: privacy::test1::Inner has no streamer or dictionary, data member unique_data will not be saved +Error in : privacy::test1: privacy::test1::Inner* has no streamer or dictionary, data member ptr_data will not be saved +Warning in : privacy::test2: privacy::test1 has no streamer or dictionary, data member "persistent_data" will not be saved +Error in : Could not declare alternate type for tuple since privacy::test3::Inner (or one of its context) is private or protected +Warning in : no dictionary for class tuple is available +Warning in : privacy::test3: tuple has no streamer or dictionary, data member "persistent_data" will not be saved diff --git a/root/io/uniquePointer/privacyInterp.oref b/root/io/uniquePointer/privacyInterp.oref new file mode 100644 index 0000000000..f3c921aed3 --- /dev/null +++ b/root/io/uniquePointer/privacyInterp.oref @@ -0,0 +1,18 @@ + +Processing /home/pcanal/root_working/code/root/roottest/root/io/uniquePointer/privacyInterp.C... +Data member list for privacy::test + filesystem::path persistent_path + +Data member list for privacy::test1 + privacy::test1::Inner* unique_data + privacy::test1::Inner* ptr_data + +Data member list for privacy::test2 + privacy::test1 persistent_data + +Data member list for privacy::test3 + tuple persistent_data + +Data member list for privacy::test4 + +(int) 0 diff --git a/root/io/uniquePointer/privacyLinkDef.h b/root/io/uniquePointer/privacyLinkDef.h new file mode 100644 index 0000000000..bfbbeb7cea --- /dev/null +++ b/root/io/uniquePointer/privacyLinkDef.h @@ -0,0 +1,15 @@ +#pragma link C++ class test+; + +// We can generate the dictionary for this class even-though it has +// data members whose types is private. There will be a clear error +// message if the user request the StreamerInfo for this class. +#pragma link C++ class test1+; + +// Dictionary of private classes is not supported, uncommented this leads +// to the expected warning message explaining this. +// #pragma link C++ class test1::Inner+; + +#pragma link C++ class test2+; +#pragma link C++ class test3+; +#pragma link C++ class test4+; + diff --git a/root/io/uniquePointer/privacyLoad.C b/root/io/uniquePointer/privacyLoad.C new file mode 100644 index 0000000000..b67fe39222 --- /dev/null +++ b/root/io/uniquePointer/privacyLoad.C @@ -0,0 +1,31 @@ +int privacyLoad() { + gSystem->Load("privacy"); + + const char *names[] = { + "test", + "test1", + "test2", + "test3", + "test4" + }; + + for(auto name : names) { + auto cl = TClass::GetClass(name); + if (!cl) { + std::cout << "Could not find class " << name << '\n'; + return 1; + } + std::cout << "Data member list for " << name << '\n'; + for(auto member : *cl->GetStreamerInfo()->GetElements()) { + if (auto el = dynamic_cast(member)) { + std::cout << " " << el->GetTypeName(); + if (el->IsaPointer() && !TString(el->GetTypeName()).Contains("*")) + std::cout << "*"; + std::cout << " " << el->GetName() << '\n'; + } + } + std::cout << '\n'; + } + + return 0; +} diff --git a/root/io/uniquePointer/privacyLoad.eref b/root/io/uniquePointer/privacyLoad.eref new file mode 100644 index 0000000000..e1590f137e --- /dev/null +++ b/root/io/uniquePointer/privacyLoad.eref @@ -0,0 +1,6 @@ +Warning in : test: filesystem::path has no streamer or dictionary, data member "persistent_path" will not be saved +Error in : test1: test1::Inner has no streamer or dictionary, data member unique_data will not be saved +Error in : test1: test1::Inner* has no streamer or dictionary, data member ptr_data will not be saved +Error in : Could not declare alternate type for tuple since test3::Inner (or one of its context) is private or protected +Warning in : no dictionary for class tuple is available +Warning in : test3: tuple has no streamer or dictionary, data member "persistent_data" will not be saved diff --git a/root/io/uniquePointer/privacyLoad.oref b/root/io/uniquePointer/privacyLoad.oref new file mode 100644 index 0000000000..c62df3f2b4 --- /dev/null +++ b/root/io/uniquePointer/privacyLoad.oref @@ -0,0 +1,18 @@ + +Processing /home/pcanal/root_working/code/root/roottest/root/io/uniquePointer/privacyLoad.C... +Data member list for test + filesystem::path persistent_path + +Data member list for test1 + test1::Inner* unique_data + test1::Inner* ptr_data + +Data member list for test2 + test1 persistent_data + +Data member list for test3 + tuple persistent_data + +Data member list for test4 + +(int) 0 From 52aa9c3d92df727922617574c92f6822bfc326be Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Tue, 31 Oct 2023 14:55:08 -0500 Subject: [PATCH 2/4] Make the output of #12783 test the same on Windows --- root/io/uniquePointer/privacyLoad.C | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/root/io/uniquePointer/privacyLoad.C b/root/io/uniquePointer/privacyLoad.C index b67fe39222..f1e93741d5 100644 --- a/root/io/uniquePointer/privacyLoad.C +++ b/root/io/uniquePointer/privacyLoad.C @@ -1,6 +1,15 @@ int privacyLoad() { gSystem->Load("privacy"); + // On Windows leads to a forward declaration of + // std::filesystem::path and since we do not generate a dictonary for that + // class, there is also no autoparsing. This leads to a state that is + // different from the state in other platform and incurred an additional + // spurrious: + // ```Warning in : no dictionary for class filesystem::path is available``` + // (due to the forward declaration only state). + gInterpreter->Declare("#include "); + const char *names[] = { "test", "test1", From 0da2aa6d2ebc66a595a1134241c16784d967829a Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Wed, 29 Nov 2023 14:45:16 -0600 Subject: [PATCH 3/4] Correct spelling of version tag in pragma read. It needs to be 'version' without a trailing s --- root/io/issue-7754/read_cmssw_class_v3.cxx | 8 ++++---- root/io/issue-9899/read_cmssw_class_v3.cxx | 6 +++--- root/io/issue-9899/write_cmssw_class_v2.cxx | 4 ++-- root/io/transient/execAtomTransient.cxx | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/root/io/issue-7754/read_cmssw_class_v3.cxx b/root/io/issue-7754/read_cmssw_class_v3.cxx index 2b33872d52..b11cc38d94 100644 --- a/root/io/issue-7754/read_cmssw_class_v3.cxx +++ b/root/io/issue-7754/read_cmssw_class_v3.cxx @@ -59,10 +59,10 @@ void Print(const Holder &h) } #ifdef __ROOTCLING__ -#pragma read sourceClass="SubContent" targetClass="SubContent" versions="[2]" source="int fValue" target="fValue" code="{ fValue = 100 * onfile.fValue; }" -#pragma read sourceClass="SubContent" targetClass="SubContent" versions="[2]" source="int fValue" target="fNewValue" code="{ fNewValue = 3000 * onfile.fValue; }" -#pragma read sourceClass="Content" targetClass="Content" versions="[2]" source="float fAfter" target="fAfter" code="{ fAfter = 10 * onfile.fAfter; }" -#pragma read sourceClass="Content" targetClass="Content" versions="[2]" source="float fAfter" target="fNewData" code="{ fNewData = 20 * onfile.fAfter; }" +#pragma read sourceClass="SubContent" targetClass="SubContent" version="[2]" source="int fValue" target="fValue" code="{ fValue = 100 * onfile.fValue; }" +#pragma read sourceClass="SubContent" targetClass="SubContent" version="[2]" source="int fValue" target="fNewValue" code="{ fNewValue = 3000 * onfile.fValue; }" +#pragma read sourceClass="Content" targetClass="Content" version="[2]" source="float fAfter" target="fAfter" code="{ fAfter = 10 * onfile.fAfter; }" +#pragma read sourceClass="Content" targetClass="Content" version="[2]" source="float fAfter" target="fNewData" code="{ fNewData = 20 * onfile.fAfter; }" #endif diff --git a/root/io/issue-9899/read_cmssw_class_v3.cxx b/root/io/issue-9899/read_cmssw_class_v3.cxx index e8012ffd53..c2c7c34fe8 100644 --- a/root/io/issue-9899/read_cmssw_class_v3.cxx +++ b/root/io/issue-9899/read_cmssw_class_v3.cxx @@ -43,11 +43,11 @@ struct Values { #ifdef __ROOTCLING__ #pragma read sourceClass="RefVectorBase" targetClass="RefVectorBase" source="" \ - versions="1-" target="fTransient" code="{ fTransient.clear(); }" + version="1-" target="fTransient" code="{ fTransient.clear(); }" #pragma read sourceClass="RefVectorMemberPointersHolder" targetClass="RefVectorMemberPointersHolder" source="" \ - versions="1-" target="fTransient" code="{ fTransient.clear(); }" + version="1-" target="fTransient" code="{ fTransient.clear(); }" #pragma read sourceClass="LowData" targetClass="LowData" source="Values fValues" \ - versions="1-" target="fNewValues" code="{ fNewValues = onfile.fValues; }" + version="1-" target="fNewValues" code="{ fNewValues = onfile.fValues; }" #endif struct LowData { diff --git a/root/io/issue-9899/write_cmssw_class_v2.cxx b/root/io/issue-9899/write_cmssw_class_v2.cxx index 314f911e5a..809256d708 100644 --- a/root/io/issue-9899/write_cmssw_class_v2.cxx +++ b/root/io/issue-9899/write_cmssw_class_v2.cxx @@ -45,9 +45,9 @@ struct Values { #ifdef __ROOTCLING__ #pragma read sourceClass="RefVectorBase" targetClass="RefVectorBase" source="" \ - versions="1-" target="fTransient" code="{ fTransient.clear(); }" + version="1-" target="fTransient" code="{ fTransient.clear(); }" #pragma read sourceClass="RefVectorMemberPointersHolder" targetClass="RefVectorMemberPointersHolder" source="" \ - versions="1-" target="fTransient" code="{ fTransient.clear(); }" + version="1-" target="fTransient" code="{ fTransient.clear(); }" #endif struct LowData { diff --git a/root/io/transient/execAtomTransient.cxx b/root/io/transient/execAtomTransient.cxx index 6dac20566a..e01c538182 100644 --- a/root/io/transient/execAtomTransient.cxx +++ b/root/io/transient/execAtomTransient.cxx @@ -12,7 +12,7 @@ class Holder { #ifdef __ROOTCLING__ #pragma link C++ class Holder+; -#pragma read sourceClass="Holder" targetClass="Holder" versions="[1-]" source="" target="fCache" code="{ fCache = nullptr; }" +#pragma read sourceClass="Holder" targetClass="Holder" version="[1-]" source="" target="fCache" code="{ fCache = nullptr; }" #endif From a131f973f3ea8e90439ca7dd072acc0dfe7dad9e Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Thu, 21 Dec 2023 11:46:32 -0600 Subject: [PATCH 4/4] Correct pragma read version syntax. Need to have a comma separated list of version specifiers or a version range (eg `4-`) enclosed in *square brackets*. --- root/io/issue-9899/read_cmssw_class_v3.cxx | 6 +++--- root/io/issue-9899/write_cmssw_class_v2.cxx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/root/io/issue-9899/read_cmssw_class_v3.cxx b/root/io/issue-9899/read_cmssw_class_v3.cxx index c2c7c34fe8..34df177650 100644 --- a/root/io/issue-9899/read_cmssw_class_v3.cxx +++ b/root/io/issue-9899/read_cmssw_class_v3.cxx @@ -43,11 +43,11 @@ struct Values { #ifdef __ROOTCLING__ #pragma read sourceClass="RefVectorBase" targetClass="RefVectorBase" source="" \ - version="1-" target="fTransient" code="{ fTransient.clear(); }" + version="[1-]" target="fTransient" code="{ fTransient.clear(); }" #pragma read sourceClass="RefVectorMemberPointersHolder" targetClass="RefVectorMemberPointersHolder" source="" \ - version="1-" target="fTransient" code="{ fTransient.clear(); }" + version="[1-]" target="fTransient" code="{ fTransient.clear(); }" #pragma read sourceClass="LowData" targetClass="LowData" source="Values fValues" \ - version="1-" target="fNewValues" code="{ fNewValues = onfile.fValues; }" + version="[1-]" target="fNewValues" code="{ fNewValues = onfile.fValues; }" #endif struct LowData { diff --git a/root/io/issue-9899/write_cmssw_class_v2.cxx b/root/io/issue-9899/write_cmssw_class_v2.cxx index 809256d708..2efd95615f 100644 --- a/root/io/issue-9899/write_cmssw_class_v2.cxx +++ b/root/io/issue-9899/write_cmssw_class_v2.cxx @@ -45,9 +45,9 @@ struct Values { #ifdef __ROOTCLING__ #pragma read sourceClass="RefVectorBase" targetClass="RefVectorBase" source="" \ - version="1-" target="fTransient" code="{ fTransient.clear(); }" + version="[1-]" target="fTransient" code="{ fTransient.clear(); }" #pragma read sourceClass="RefVectorMemberPointersHolder" targetClass="RefVectorMemberPointersHolder" source="" \ - version="1-" target="fTransient" code="{ fTransient.clear(); }" + version="[1-]" target="fTransient" code="{ fTransient.clear(); }" #endif struct LowData {