From ddc780bf6f1e1bccd94f1d1b1e77bcdfff2f005d Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Tue, 17 Oct 2023 10:24:59 -0500 Subject: [PATCH 01/15] [meta] AlternateTuple fix code comments. --- core/metacling/src/TCling.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index b04b117473bc9..6bcfb2f4ba86c 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -3972,7 +3972,7 @@ static std::string AlternateTuple(const char *classname, const cling::LookupHelp switch(IsTupleAscending()) { case ETupleOrdering::kAscending: { unsigned int nMember = 0; - auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple) + auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple). auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'. while (iter != theEnd) { alternateTuple << " " << *iter << " _" << nMember << ";\n"; @@ -3983,8 +3983,8 @@ static std::string AlternateTuple(const char *classname, const cling::LookupHelp } case ETupleOrdering::kDescending: { unsigned int nMember = tupleContent.fElements.size() - 3; - auto iter = tupleContent.fElements.rbegin() + 1; // Skip the template name (tuple) - auto theEnd = tupleContent.fElements.rend() - 1; // skip the 'stars'. + auto iter = tupleContent.fElements.rbegin() + 1; // skip the 'stars'. + auto theEnd = tupleContent.fElements.rend() - 1; // Skip the template name (tuple). while (iter != theEnd) { alternateTuple << " " << *iter << " _" << nMember << ";\n"; ++iter; From d7f8dd5d79023b005640f12490df9336f16c64f5 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Mon, 23 Oct 2023 14:50:06 -0500 Subject: [PATCH 02/15] [meta] TDataMember properly combine the access property. We need to keep only the strictest access information between the member and its type. --- core/meta/src/TDataMember.cxx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/meta/src/TDataMember.cxx b/core/meta/src/TDataMember.cxx index 8e1aa99e75cec..45be8cd359b8e 100644 --- a/core/meta/src/TDataMember.cxx +++ b/core/meta/src/TDataMember.cxx @@ -595,7 +595,14 @@ Long_t TDataMember::Property() const if (!fInfo || !gCling->DataMemberInfo_IsValid(fInfo)) return 0; int prop = gCling->DataMemberInfo_Property(fInfo); int propt = gCling->DataMemberInfo_TypeProperty(fInfo); - t->fProperty = prop|propt; + t->fProperty = (prop | propt) & ~(kIsPublic | kIsProtected | kIsPrivate); + // Set to the strictest access of the member and the type + if ((prop | propt) & kIsPrivate) + t->fProperty |= kIsPrivate; + else if ((prop | propt) & kIsProtected) + t->fProperty |= kIsProtected; + else + t->fProperty |= kIsPublic; t->fFullTypeName = TClassEdit::GetLong64_Name(gCling->DataMemberInfo_TypeName(fInfo)); t->fTrueTypeName = TClassEdit::GetLong64_Name(gCling->DataMemberInfo_TypeTrueName(fInfo)); From e875e66be810f37438afa8dcdbd5fd3d5361ee05 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Tue, 17 Oct 2023 11:20:50 -0500 Subject: [PATCH 03/15] [meta] TClingTypeInfo add access information to Property --- core/metacling/src/TClingTypeInfo.cxx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/core/metacling/src/TClingTypeInfo.cxx b/core/metacling/src/TClingTypeInfo.cxx index f0d387ba9faea..cd9bea805b656 100644 --- a/core/metacling/src/TClingTypeInfo.cxx +++ b/core/metacling/src/TClingTypeInfo.cxx @@ -132,6 +132,24 @@ long TClingTypeInfo::Property() const const clang::TagDecl *TD = llvm::dyn_cast(tagQT->getDecl()); if (!TD) return property; + switch (TD->getAccess()) { + case clang::AS_public: + property |= kIsPublic; + break; + case clang::AS_protected: + property |= kIsProtected; + break; + case clang::AS_private: + property |= kIsPrivate; + break; + case clang::AS_none: + if (TD->getDeclContext()->isNamespace()) + property |= kIsPublic; + break; + default: + // IMPOSSIBLE + break; + } if (TD->isEnum()) { property |= kIsEnum; } else { From 13141862687dcae87a2d84d81f8b3fe8f98bdcb2 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Tue, 17 Oct 2023 11:21:20 -0500 Subject: [PATCH 04/15] [meta] AlternateTuple fail explicitly if one of the member is not accessible --- core/metacling/src/TCling.cxx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index 6bcfb2f4ba86c..4141654968d03 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -3955,6 +3955,25 @@ static std::string AlternateTuple(const char *classname, const cling::LookupHelp /*resultType*/nullptr, /* intantiateTemplate= */ false)) return fullname; + { + // Check if we can produce the tuple + auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple). + auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'. + auto deleter = [](TypeInfo_t *type) { + gInterpreter->TypeInfo_Delete(type); + }; + std::unique_ptr type{ gInterpreter->TypeInfo_Factory(), deleter }; + while (iter != theEnd) { + gInterpreter->TypeInfo_Init(type.get(), iter->c_str()); + if (gInterpreter->TypeInfo_Property(type.get()) & (kIsProtected | kIsPrivate)) { + Error("Load","Could not declare alternate type for %s since %s is private or protected", + classname, iter->c_str()); + return ""; + } + ++iter; + } + } + std::string guard_name; ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str()); std::ostringstream guard; From f06004385e764e3842890fed9e3cec08807aacde Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Tue, 17 Oct 2023 12:59:30 -0500 Subject: [PATCH 05/15] [meta] Allow SetClassInfo to be silent (for transient members) --- core/meta/inc/TInterpreter.h | 2 +- core/meta/src/TClass.cxx | 2 +- core/metacling/src/TCling.cxx | 2 +- core/metacling/src/TCling.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/meta/inc/TInterpreter.h b/core/meta/inc/TInterpreter.h index 165ce9079bc05..55494ee72af64 100644 --- a/core/meta/inc/TInterpreter.h +++ b/core/meta/inc/TInterpreter.h @@ -208,7 +208,7 @@ class TInterpreter : public TNamed { virtual void UpdateListOfGlobals() = 0; virtual void UpdateListOfGlobalFunctions() = 0; virtual void UpdateListOfTypes() = 0; - virtual void SetClassInfo(TClass *cl, Bool_t reload = kFALSE) = 0; + virtual void SetClassInfo(TClass *cl, Bool_t reload = kFALSE, Bool_t silent = kFALSE) = 0; enum ECheckClassInfo { kUnknown = 0, // backward compatible with false diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx index ff3611b8805dd..05572273c86dc 100644 --- a/core/meta/src/TClass.cxx +++ b/core/meta/src/TClass.cxx @@ -1514,7 +1514,7 @@ void TClass::Init(const char *name, Version_t cversion, proto->FillTClass(this); } if (!fHasRootPcmInfo && gInterpreter->CheckClassInfo(fName, /* autoload = */ kTRUE)) { - gInterpreter->SetClassInfo(this); // sets fClassInfo pointer + gInterpreter->SetClassInfo(this, kFALSE, silent); // sets fClassInfo pointer if (fClassInfo) { // This should be moved out of GetCheckSum itself however the last time // we tried this cause problem, in particular in the end-of-process operation. diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index 4141654968d03..6d0de90fe704b 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -4034,7 +4034,7 @@ static std::string AlternateTuple(const char *classname, const cling::LookupHelp /// If 'reload' is true, (attempt to) generate a new ClassInfo even if we /// already have one. -void TCling::SetClassInfo(TClass* cl, Bool_t reload) +void TCling::SetClassInfo(TClass* cl, Bool_t reload, Bool_t silent) { // We are shutting down, there is no point in reloading, it only triggers // redundant deserializations. diff --git a/core/metacling/src/TCling.h b/core/metacling/src/TCling.h index 8c728b71db8f1..1f7d5ace54b76 100644 --- a/core/metacling/src/TCling.h +++ b/core/metacling/src/TCling.h @@ -270,7 +270,7 @@ class TCling final : public TInterpreter { void UpdateListOfGlobals() final; void UpdateListOfGlobalFunctions() final; void UpdateListOfTypes() final; - void SetClassInfo(TClass* cl, Bool_t reload = kFALSE) final; + void SetClassInfo(TClass* cl, Bool_t reload = kFALSE, Bool_t silent = kFALSE) final; ECheckClassInfo CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly = kFALSE) final; From 004f1e95a840308b183d618357071e3e761c95f0 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Tue, 17 Oct 2023 12:59:59 -0500 Subject: [PATCH 06/15] [meta] Allow AlternateTuple to be silent (for transient members) --- core/metacling/src/TCling.cxx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index 6d0de90fe704b..c9d70156bc3d3 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -3944,7 +3944,7 @@ static ETupleOrdering IsTupleAscending() } } -static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh) +static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh, Bool_t silent) { TClassEdit::TSplitType tupleContent(classname); std::string alternateName = "TEmulatedTuple"; @@ -3966,8 +3966,9 @@ static std::string AlternateTuple(const char *classname, const cling::LookupHelp while (iter != theEnd) { gInterpreter->TypeInfo_Init(type.get(), iter->c_str()); if (gInterpreter->TypeInfo_Property(type.get()) & (kIsProtected | kIsPrivate)) { - Error("Load","Could not declare alternate type for %s since %s is private or protected", - classname, iter->c_str()); + if (!silent) + Error("Load","Could not declare alternate type for %s since %s is private or protected", + classname, iter->c_str()); return ""; } ++iter; @@ -4021,7 +4022,10 @@ static std::string AlternateTuple(const char *classname, const cling::LookupHelp alternateTuple << "};\n"; alternateTuple << "}}\n"; alternateTuple << "#endif\n"; - if (!gCling->Declare(alternateTuple.str().c_str())) { + if (!gCling->Declare(alternateTuple.str().c_str())) + { + // Declare is not silent (yet?), so add an explicit error message + // to indicate the consequence of the syntax errors. Error("Load","Could not declare %s",alternateName.c_str()); return ""; } @@ -4081,7 +4085,7 @@ void TCling::SetClassInfo(TClass* cl, Bool_t reload, Bool_t silent) // for the I/O to understand and handle. if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) { if (!reload) - name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper()); + name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent); if (reload || name.empty()) { // We could not generate the alternate SetWithoutClassInfoState(cl); From 34d4ccd33c8b2e7c2ab941441da60325e4a0c5ae Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Tue, 17 Oct 2023 13:06:02 -0500 Subject: [PATCH 07/15] [dict] Make IsUnsupportedUniquePointer silent. This addresses in part #13574 --- io/rootpcm/src/rootclingIO.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/io/rootpcm/src/rootclingIO.cxx b/io/rootpcm/src/rootclingIO.cxx index cd24918a66bb0..b10b466e18d82 100644 --- a/io/rootpcm/src/rootclingIO.cxx +++ b/io/rootpcm/src/rootclingIO.cxx @@ -82,7 +82,9 @@ static bool IsUnsupportedUniquePointer(const char *normName, TDataMember *dm) return true; } - clm->BuildRealData(); + // TODO: Is it not clear what situation we are checking for by checking if + // the unique_ptr class has any data members. + clm->BuildRealData(nullptr, /* istransient = */ true); auto upDms = clm->GetListOfRealData(); if (!upDms) { Error("CloseStreamerInfoROOTFile", "Cannot determine unique pointer %s data members.", dmTypeName); From 983fd284ac1793e820400b51c60f34e0533b703e Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Tue, 17 Oct 2023 19:28:28 -0500 Subject: [PATCH 08/15] [meta] Add routine to calculate decl accessiblity from global ctxt. //______________________________________________________________________________ // Return true if the DeclContext is representing an entity reacheable from the // global namespace bool IsCtxtReacheable(const clang::DeclContext &ctxt); //______________________________________________________________________________ // Return true if the decl is representing an entity reacheable from the // global namespace bool IsDeclReacheable(const clang::TagDecl &decl); --- core/clingutils/res/TClingUtils.h | 10 ++++++++ core/clingutils/src/TClingUtils.cxx | 37 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/core/clingutils/res/TClingUtils.h b/core/clingutils/res/TClingUtils.h index 7968ba98fec83..9f8cf872729bb 100644 --- a/core/clingutils/res/TClingUtils.h +++ b/core/clingutils/res/TClingUtils.h @@ -676,6 +676,16 @@ const clang::TypedefNameDecl* GetAnnotatedRedeclarable(const clang::TypedefNameD // Overload the template for tags, because we only check definitions. const clang::TagDecl* GetAnnotatedRedeclarable(const clang::TagDecl* TND); +//______________________________________________________________________________ +// Return true if the DeclContext is representing an entity reacheable from the +// global namespace +bool IsCtxtReacheable(const clang::DeclContext &ctxt); + +//______________________________________________________________________________ +// Return true if the decl is representing an entity reacheable from the +// global namespace +bool IsDeclReacheable(const clang::Decl &decl); + //______________________________________________________________________________ // Return true if the decl is part of the std namespace. bool IsStdClass(const clang::RecordDecl &cl); diff --git a/core/clingutils/src/TClingUtils.cxx b/core/clingutils/src/TClingUtils.cxx index d904c0dc15d6d..1ae348c9621aa 100644 --- a/core/clingutils/src/TClingUtils.cxx +++ b/core/clingutils/src/TClingUtils.cxx @@ -4363,6 +4363,43 @@ const clang::Type *ROOT::TMetaUtils::GetUnderlyingType(clang::QualType type) return rawtype; } +//////////////////////////////////////////////////////////////////////////////// +/// Return true if the DeclContext is representing an entity reacheable from the +/// global namespace + +bool ROOT::TMetaUtils::IsCtxtReacheable(const clang::DeclContext &ctxt) +{ + if (ctxt.isNamespace() || ctxt.isTranslationUnit()) + return true; + else if(const auto parentdecl = llvm::dyn_cast(&ctxt)) + return ROOT::TMetaUtils::IsDeclReacheable(*parentdecl); + else + // For example "extern C" context. + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +/// Return true if the decl is representing an entity reacheable from the +/// global namespace + +bool ROOT::TMetaUtils::IsDeclReacheable(const clang::Decl &decl) +{ + const clang::DeclContext *ctxt = decl.getDeclContext(); + switch (decl.getAccess()) { + case clang::AS_public: + return !ctxt || IsCtxtReacheable(*ctxt); + case clang::AS_protected: + return false; + case clang::AS_private: + return false; + case clang::AS_none: + return !ctxt || IsCtxtReacheable(*ctxt); + default: + // IMPOSSIBLE + return false; + } +} + //////////////////////////////////////////////////////////////////////////////// /// Return true, if the decl is part of the std namespace. From 6bf0801dd9a1c1079873960dd5ea90a58a85dacf Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Tue, 17 Oct 2023 19:29:40 -0500 Subject: [PATCH 09/15] [meta] Add kIsUnreachable property (first to TClingTypeInfo) --- core/meta/inc/TDictionary.h | 2 +- core/metacling/src/TClingTypeInfo.cxx | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/core/meta/inc/TDictionary.h b/core/meta/inc/TDictionary.h index facf5c31a6513..5abff1011a5c7 100644 --- a/core/meta/inc/TDictionary.h +++ b/core/meta/inc/TDictionary.h @@ -84,7 +84,7 @@ enum EProperty { kIsCCompiled = 0x00040000, kIsCPPCompiled = kIsCCompiled, kIsCompiled = kIsCCompiled, - // 0x00080000 is available + kIsNotReacheable = 0x00080000, // Indicate that the entity can not be used from the Global Namespace kIsConstant = 0x00100000, kIsVirtualBase = 0x00200000, kIsConstPointer = 0x00400000, diff --git a/core/metacling/src/TClingTypeInfo.cxx b/core/metacling/src/TClingTypeInfo.cxx index cd9bea805b656..00016b4f367f9 100644 --- a/core/metacling/src/TClingTypeInfo.cxx +++ b/core/metacling/src/TClingTypeInfo.cxx @@ -137,10 +137,10 @@ long TClingTypeInfo::Property() const property |= kIsPublic; break; case clang::AS_protected: - property |= kIsProtected; + property |= kIsProtected | kIsNotReacheable; break; case clang::AS_private: - property |= kIsPrivate; + property |= kIsPrivate | kIsNotReacheable; break; case clang::AS_none: if (TD->getDeclContext()->isNamespace()) @@ -150,6 +150,10 @@ long TClingTypeInfo::Property() const // IMPOSSIBLE break; } + if (!(property & kIsNotReacheable)) { + if (! ROOT::TMetaUtils::IsDeclReacheable(*TD)) + property |= kIsNotReacheable; + } if (TD->isEnum()) { property |= kIsEnum; } else { From d9ff4819d721e301cc08754c40a0cb1d1a2fd16f Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Tue, 17 Oct 2023 19:30:17 -0500 Subject: [PATCH 10/15] [meta] AlternateTuple take scope accessibility in consideration to reject code generation --- core/metacling/src/TCling.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index c9d70156bc3d3..263f4663d3dae 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -3965,9 +3965,9 @@ static std::string AlternateTuple(const char *classname, const cling::LookupHelp std::unique_ptr type{ gInterpreter->TypeInfo_Factory(), deleter }; while (iter != theEnd) { gInterpreter->TypeInfo_Init(type.get(), iter->c_str()); - if (gInterpreter->TypeInfo_Property(type.get()) & (kIsProtected | kIsPrivate)) { + if (gInterpreter->TypeInfo_Property(type.get()) & kIsNotReacheable) { if (!silent) - Error("Load","Could not declare alternate type for %s since %s is private or protected", + Error("Load","Could not declare alternate type for %s since %s (or one of its context) is private or protected", classname, iter->c_str()); return ""; } From 0842c93786ab1e55b6e742020a471f5cdb7ff299 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Wed, 18 Oct 2023 11:42:47 -0500 Subject: [PATCH 11/15] [meta] Apply kIsNotReacheable to DataMember and Functions --- core/metacling/src/TClingDataMemberInfo.cxx | 8 +++++--- core/metacling/src/TClingMethodInfo.cxx | 9 +++++++-- core/metacling/test/TClingDataMemberInfoTests.cxx | 4 ++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/core/metacling/src/TClingDataMemberInfo.cxx b/core/metacling/src/TClingDataMemberInfo.cxx index f90cbe7e2e9e0..8cdfd0ad779b3 100644 --- a/core/metacling/src/TClingDataMemberInfo.cxx +++ b/core/metacling/src/TClingDataMemberInfo.cxx @@ -453,16 +453,18 @@ long TClingDataMemberInfo::Property() const }; getParentAccessAndNonTransparentDC(); - + // TODO: Now that we have the kIsNotReacheable we could return the property + // to be reflecting the local information. However it is unclear if the + // information is used as-is (it appears to not be used in ROOT proper) switch (strictestAccess) { case clang::AS_public: property |= kIsPublic; break; case clang::AS_protected: - property |= kIsProtected; + property |= kIsProtected | kIsNotReacheable; break; case clang::AS_private: - property |= kIsPrivate; + property |= kIsPrivate | kIsNotReacheable; break; case clang::AS_none: //? property |= kIsPublic; diff --git a/core/metacling/src/TClingMethodInfo.cxx b/core/metacling/src/TClingMethodInfo.cxx index 87bc858dcbe3c..97bb3bbf6a92a 100644 --- a/core/metacling/src/TClingMethodInfo.cxx +++ b/core/metacling/src/TClingMethodInfo.cxx @@ -482,10 +482,10 @@ long TClingMethodInfo::Property() const property |= kIsPublic; break; case clang::AS_protected: - property |= kIsProtected; + property |= kIsProtected | kIsNotReacheable; break; case clang::AS_private: - property |= kIsPrivate; + property |= kIsPrivate | kIsNotReacheable; break; case clang::AS_none: if (declAccess->getDeclContext()->isNamespace()) @@ -496,6 +496,11 @@ long TClingMethodInfo::Property() const break; } + if (!(property & kIsNotReacheable)) { + if (! ROOT::TMetaUtils::IsDeclReacheable(*fd)) + property |= kIsNotReacheable; + } + if (fd->isConstexpr()) property |= kIsConstexpr; if (fd->getStorageClass() == clang::SC_Static) { diff --git a/core/metacling/test/TClingDataMemberInfoTests.cxx b/core/metacling/test/TClingDataMemberInfoTests.cxx index 4a97836fd8e7e..5fc9d93b3effa 100644 --- a/core/metacling/test/TClingDataMemberInfoTests.cxx +++ b/core/metacling/test/TClingDataMemberInfoTests.cxx @@ -214,11 +214,11 @@ class Outer { ASSERT_TRUE(TClass::GetClass("DMLookup::Outer")->GetListOfDataMembers()->FindObject("InnerPrivate")); auto *dmInnerPrivate = (TDataMember*)TClass::GetClass("DMLookup::Outer")->GetListOfDataMembers()->FindObject("InnerPrivate"); - EXPECT_EQ(dmInnerPrivate->Property(), kIsPrivate | kIsClass); + EXPECT_EQ(dmInnerPrivate->Property(), kIsPrivate | kIsClass | kIsNotReacheable); ASSERT_TRUE(TClass::GetClass("DMLookup::Outer")->GetListOfDataMembers()->FindObject("InnerProtected")); auto *dmInnerProtected = (TDataMember*)TClass::GetClass("DMLookup::Outer")->GetListOfDataMembers()->FindObject("InnerProtected"); - EXPECT_EQ(dmInnerProtected->Property(), kIsProtected | kIsClass); + EXPECT_EQ(dmInnerProtected->Property(), kIsProtected | kIsClass | kIsNotReacheable); } TEST(TClingDataMemberInfo, Offset) From 8c9391ed97bfe2267b4df9ba9ba2baf08ef5e572 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Thu, 19 Oct 2023 16:45:18 -0500 Subject: [PATCH 12/15] [meta] TMemberInspector::GenericShowMembers pass isSilent to GetClass --- core/base/src/TMemberInspector.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/base/src/TMemberInspector.cxx b/core/base/src/TMemberInspector.cxx index 174d9e22d21a1..cbd70eb208f27 100644 --- a/core/base/src/TMemberInspector.cxx +++ b/core/base/src/TMemberInspector.cxx @@ -121,7 +121,7 @@ void TMemberInspector::GenericShowMembers(const char *topClassName, const void * } } - TClass *top = TClass::GetClass(topClassName); + TClass *top = TClass::GetClass(topClassName, true, isTransient); if (top) { top->CallShowMembers(obj, *this, isTransient); } else { From ada6a93d86ff39deb151baced5a7ef081a3535d3 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Thu, 26 Oct 2023 14:14:28 -0500 Subject: [PATCH 13/15] [meta] TCling::InspectMembers be silent about errors within unique_ptr --- core/metacling/src/TCling.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index 263f4663d3dae..5f5d05b76a52b 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -2716,6 +2716,14 @@ void TCling::InspectMembers(TMemberInspector& insp, const void* obj, return; } + if (TClassEdit::IsUniquePtr(cl->GetName())) { + // Ignore error caused by the inside of std::unique_ptr + // This is needed solely because of rootclingIO's IsUnsupportedUniquePointer + // which check the numbers of data members. + // If this usage is remove, this can be replace with a return statement. + isTransient = true; + } + const char* cobj = (const char*) obj; // for ptr arithmetics // Treat the case of std::complex in a special manner. We want to enforce From 88933ff8987ce90a91edb3c4b53b2bff14648696 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Tue, 21 Nov 2023 15:35:39 -0600 Subject: [PATCH 14/15] [meta] Assert in case of unexpected access property --- core/clingutils/src/TClingUtils.cxx | 1 + core/metacling/src/TCling.cxx | 1 + core/metacling/src/TClingBaseClassInfo.cxx | 4 ++++ core/metacling/src/TClingDataMemberInfo.cxx | 1 + core/metacling/src/TClingMethodInfo.cxx | 1 + core/metacling/src/TClingTypeInfo.cxx | 1 + 6 files changed, 9 insertions(+) diff --git a/core/clingutils/src/TClingUtils.cxx b/core/clingutils/src/TClingUtils.cxx index 1ae348c9621aa..4aab64b4be4c8 100644 --- a/core/clingutils/src/TClingUtils.cxx +++ b/core/clingutils/src/TClingUtils.cxx @@ -4396,6 +4396,7 @@ bool ROOT::TMetaUtils::IsDeclReacheable(const clang::Decl &decl) return !ctxt || IsCtxtReacheable(*ctxt); default: // IMPOSSIBLE + assert(false && "Unexpected value for the access property value in Clang"); return false; } } diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index 5f5d05b76a52b..7d13ce8e7644a 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -8899,6 +8899,7 @@ Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const break; default: // IMPOSSIBLE + assert(false && "Unexpected value for the access property value in Clang"); break; } diff --git a/core/metacling/src/TClingBaseClassInfo.cxx b/core/metacling/src/TClingBaseClassInfo.cxx index 46ef9fc5d3156..39c6484aaa58e 100644 --- a/core/metacling/src/TClingBaseClassInfo.cxx +++ b/core/metacling/src/TClingBaseClassInfo.cxx @@ -541,6 +541,10 @@ long TClingBaseClassInfo::Property() const break; case clang::AS_none: // IMPOSSIBLE + assert(false && "Unexpected value for the access property value in Clang"); + break; + default: + assert(false && "Unexpected value for the access property value in Clang"); break; } return property; diff --git a/core/metacling/src/TClingDataMemberInfo.cxx b/core/metacling/src/TClingDataMemberInfo.cxx index 8cdfd0ad779b3..57d64ef3c7c32 100644 --- a/core/metacling/src/TClingDataMemberInfo.cxx +++ b/core/metacling/src/TClingDataMemberInfo.cxx @@ -471,6 +471,7 @@ long TClingDataMemberInfo::Property() const break; default: // IMPOSSIBLE + assert(false && "Unexpected value for the access property value in Clang"); break; } if (llvm::isa(thisDecl)) diff --git a/core/metacling/src/TClingMethodInfo.cxx b/core/metacling/src/TClingMethodInfo.cxx index 97bb3bbf6a92a..baee85922eee5 100644 --- a/core/metacling/src/TClingMethodInfo.cxx +++ b/core/metacling/src/TClingMethodInfo.cxx @@ -493,6 +493,7 @@ long TClingMethodInfo::Property() const break; default: // IMPOSSIBLE + assert(false && "Unexpected value for the access property value in Clang"); break; } diff --git a/core/metacling/src/TClingTypeInfo.cxx b/core/metacling/src/TClingTypeInfo.cxx index 00016b4f367f9..e5bb88fda7468 100644 --- a/core/metacling/src/TClingTypeInfo.cxx +++ b/core/metacling/src/TClingTypeInfo.cxx @@ -148,6 +148,7 @@ long TClingTypeInfo::Property() const break; default: // IMPOSSIBLE + assert(false && "Unexpected value for the access property value in Clang"); break; } if (!(property & kIsNotReacheable)) { From 2f2c69e14b86a1df3f4d9086dd2873fa2ed63da7 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Tue, 21 Nov 2023 15:59:26 -0600 Subject: [PATCH 15/15] [meta] Clarify comment in TCling::InspectMembers --- core/metacling/src/TCling.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index 7d13ce8e7644a..d23dcedeab1d4 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -2719,8 +2719,9 @@ void TCling::InspectMembers(TMemberInspector& insp, const void* obj, if (TClassEdit::IsUniquePtr(cl->GetName())) { // Ignore error caused by the inside of std::unique_ptr // This is needed solely because of rootclingIO's IsUnsupportedUniquePointer - // which check the numbers of data members. - // If this usage is remove, this can be replace with a return statement. + // which checks the number of elements in the GetListOfRealData. + // If this usage is removed, this can be replaced with a return statement. + // See https://github.com/root-project/root/issues/13574 isTransient = true; }