Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/base/inc/TMemberInspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class TMemberInspector {
class TParentBuf;
TParentBuf* fParent; // current inspection "path"
EObjectPointerState fObjectPointerState; // whether the address is valid or only an offset
UInt_t fNestedTransient;

TMemberInspector(const TMemberInspector &) = delete;
TMemberInspector &operator=(const TMemberInspector &) = delete;
Expand Down Expand Up @@ -76,6 +77,10 @@ class TMemberInspector {
void GenericShowMembers(const char *topClassName, const void *obj,
Bool_t transientMember);

void DecrementNestedTransient() { --fNestedTransient; }
void IncrementNestedTransient() { ++fNestedTransient; }
bool IsNestedTransient() { return fNestedTransient != 0; }

ClassDef(TMemberInspector,0) //ABC for inspecting class data members
};

Expand Down
2 changes: 1 addition & 1 deletion core/base/src/TMemberInspector.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void TMemberInspector::TParentBuf::Remove(Ssiz_t startingAt)
ClassImp(TMemberInspector);

TMemberInspector::TMemberInspector():
fObjectPointerState(kUnset)
fObjectPointerState(kUnset), fNestedTransient(0)
{
// Construct a member inspector

Expand Down
4 changes: 2 additions & 2 deletions core/meta/inc/TProtoClass.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class TProtoClass: public TNamed {
TProtoRealData() : fOffset(0), fDMIndex(-1), fLevel(0), fClassIndex(-1), fStatusFlag(0) {}
TProtoRealData(const TRealData *rd);
virtual ~TProtoRealData();
TRealData *CreateRealData(TClass *currentClass, TClass *parent, TRealData * parentData, int prevLevel) const;
TRealData *CreateRealData(TClass *currentClass, TClass *parent, TRealData * parentData, int prevLevel, bool quiet) const;

Bool_t TestFlag(UInt_t f) const { return (Bool_t) ((fStatusFlag & f) != 0); }
void SetFlag(UInt_t f, Bool_t on = kTRUE) {
Expand Down Expand Up @@ -91,7 +91,7 @@ class TProtoClass: public TNamed {
// compute index of data member in the list
static Int_t DataMemberIndex(TClass * cl, const char * name);
// find data member given an index
static TDataMember * FindDataMember(TClass * cl, Int_t index);
static TDataMember * FindDataMember(TClass * cl, Int_t index, bool quiet);

public:
TProtoClass():
Expand Down
8 changes: 6 additions & 2 deletions core/meta/src/TClass.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,8 @@ void TBuildRealData::Inspect(TClass* cl, const char* pname, const char* mname, c
TRealData::GetName(rdName,dm);
rname += rdName;
TRealData* rd = new TRealData(rname.Data(), offset, dm);
if (isTransientMember || IsNestedTransient())
rd->SetBit(TRealData::kTransient);
fRealDataClass->GetListOfRealData()->Add(rd);
return;
}
Expand All @@ -833,12 +835,14 @@ void TBuildRealData::Inspect(TClass* cl, const char* pname, const char* mname, c
if (dm->IsaPointer()) {
// Data member is a pointer.
TRealData* rd = new TRealData(rname, offset, dm);
if (isTransientMember) { rd->SetBit(TRealData::kTransient); };
if (isTransientMember || IsNestedTransient())
rd->SetBit(TRealData::kTransient);
fRealDataClass->GetListOfRealData()->Add(rd);
} else {
// Data Member is a basic data type.
TRealData* rd = new TRealData(rname, offset, dm);
if (isTransientMember) { rd->SetBit(TRealData::kTransient); };
if (isTransientMember || IsNestedTransient())
rd->SetBit(TRealData::kTransient);
if (!dm->IsBasic()) {
rd->SetIsObject(kTRUE);

Expand Down
30 changes: 23 additions & 7 deletions core/meta/src/TProtoClass.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ Bool_t TProtoClass::FillTClass(TClass* cl) {
//TProtoRealData* prd = (TProtoRealData*)element;
// pass a previous real data only if depth

if (TRealData* rd = element.CreateRealData(currentRDClass, cl,prevRealData, prevLevel)) {
if (TRealData* rd = element.CreateRealData(currentRDClass, cl,prevRealData, prevLevel, element.TestFlag(TProtoRealData::kIsTransient))) {
if (first) {
//LM: need to do here because somehow fRealData is destroyed when calling TClass::GetListOfDataMembers()
if (cl->fRealData) {
Expand Down Expand Up @@ -461,15 +461,23 @@ TProtoClass::TProtoRealData::~TProtoRealData()
}

////////////////////////////////////////////////////////////////////////////////
/// Create a TRealData from this, with its data member coming from dmClass.
/// \brief Create a TRealData from this, with its data member coming from dmClass.
/// find data member from protoclass
///
/// \return the created TRealData
///
/// \param [in] dmClass Class where the data member is declared
/// \param [in] parent Parent class
/// \param [in] prevData the previous 'real' data member (might be part of another class)
/// \param [in] prevLevel nesting level
/// \param [in] quiet Whether we should not warn about missing information (usually set to true for transient members)

TRealData* TProtoClass::TProtoRealData::CreateRealData(TClass* dmClass,
TClass* parent, TRealData *prevData, int prevLevel) const
TClass* parent, TRealData *prevData, int prevLevel, bool quiet) const
{

//TDataMember* dm = (TDataMember*)dmClass->GetListOfDataMembers()->FindObject(fName);
TDataMember* dm = TProtoClass::FindDataMember(dmClass, fDMIndex);
TDataMember* dm = TProtoClass::FindDataMember(dmClass, fDMIndex, quiet);

if (!dm && dmClass->GetState()!=TClass::kForwardDeclared && !dmClass->fIsSyntheticPair) {
::Error("CreateRealData",
Expand Down Expand Up @@ -557,8 +565,16 @@ Int_t TProtoClass::DataMemberIndex(TClass * cl, const char * name)
return -1;
}
////////////////////////////////////////////////////////////////////////////////

TDataMember * TProtoClass::FindDataMember(TClass * cl, Int_t index)
////////////////////////////////////////////////////////////////////////////////
/// \brief Find the requested TDataMember
///
/// \return the requested TDataMember if found
///
/// \param [in] cl TClass to search for the data member
/// \param [in] index Numerical index of the object's data member
/// \param [in] quiet Whether we should not warn about missing information (usually set to true for transient members)

TDataMember * TProtoClass::FindDataMember(TClass * cl, Int_t index, bool quiet)
{
TList * dmList = cl->GetListOfDataMembers(false);

Expand All @@ -572,7 +588,7 @@ TDataMember * TProtoClass::FindDataMember(TClass * cl, Int_t index)
return dm;
i++;
}
if (cl->GetState()!=TClass::kForwardDeclared && !cl->fIsSyntheticPair)
if (cl->GetState()!=TClass::kForwardDeclared && !cl->fIsSyntheticPair && !quiet)
::Error("TProtoClass::FindDataMember","data member with index %d is not found in class %s",index,cl->GetName());
return nullptr;
}
17 changes: 16 additions & 1 deletion core/metacling/src/TCling.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2980,9 +2980,12 @@ void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
// if we can not find the member (which should not really happen),
// let's consider it transient.
Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();

if (!mbr || !mbr->IsPersistent())
insp.IncrementNestedTransient();
insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
(fieldName + '.').c_str(), transient);
if (!mbr || !mbr->IsPersistent())
insp.DecrementNestedTransient();

}
}
Expand Down Expand Up @@ -6660,6 +6663,18 @@ void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alia
}
} else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
cl->ResetCaches();
if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
// We need to use the Emulated Tuple but we should not trigger parsing
// yet, so delay the creation of the ClassInfo
delete ((TClingClassInfo *)cl->fClassInfo);
cl->fClassInfo = nullptr;
cl->fCanLoadClassInfo = true;
cl->RemoveStreamerInfo(cl->fClassVersion);
if (cl->fState != TClass::kHasTClassInit) {
cl->fState = TClass::kInterpreted;
}
return;
}
// yes, this is almost a waste of time, but we do need to lookup
// the 'type' corresponding to the TClass anyway in order to
// preserve the opaque typedefs (Double32_t)
Expand Down
Loading