diff --git a/core/base/inc/RtypesCint.h b/core/base/inc/RtypesCint.h index d8b21e99203f36ac1bba50b87ea3864cf40cf5f2..bbd7e8fdc6f961fb847931e1dccbe59d3b33c3a7 100644 --- a/core/base/inc/RtypesCint.h +++ b/core/base/inc/RtypesCint.h @@ -21,12 +21,13 @@ private: \ static TClass *fgIsA; \ public: \ - static TClass *Class(); \ - static const char *Class_Name(); \ + static TClass *Class() { return fgIsA ? fgIsA : (fgIsA = TClass::GetClass(#name)); } \ + static const char *Class_Name() { return #name; } \ static Version_t Class_Version() { return id; } \ static void Dictionary(); \ virtual TClass *IsA() const { return name::Class(); } \ - virtual void ShowMembers(TMemberInspector &insp, char *parent); \ + virtual void ShowMembers(TMemberInspector &insp, char *parent) { \ + Class()->InterpretedShowMembers(this, insp, parent); } \ virtual void Streamer(TBuffer &b); \ void StreamerNVirtual(TBuffer &b) { name::Streamer(b); } \ static const char *DeclFileName() { return __FILE__; } \ @@ -34,22 +35,7 @@ public: \ static int ImplFileLine(); \ static int DeclFileLine() { return __LINE__; } -#define ClassDefT(name,id) \ -private: \ - static TClass *fgIsA; \ -public: \ - static TClass *Class(); \ - static const char *Class_Name(); \ - static Version_t Class_Version() { return id; } \ - static void Dictionary(); \ - virtual TClass *IsA() const { return name::Class(); } \ - virtual void ShowMembers(TMemberInspector &insp, char *parent); \ - virtual void Streamer(TBuffer &b); \ - void StreamerNVirtual(TBuffer &b) { name::Streamer(b); } \ - static const char *DeclFileName() { return __FILE__; } \ - static const char *ImplFileName(); \ - static int ImplFileLine(); \ - static int DeclFileLine() { return __LINE__; } +#define ClassDefT(name,id) ClassDef(name,id) // Obsolete macros #define ClassDefT2(name,Tmpl) diff --git a/core/meta/inc/TClass.h b/core/meta/inc/TClass.h index 7506b15dab74c87b3a8d634d059a080ec693c193..f0b8fdb4dea976f1235a34716f670ecb62ed28df 100644 --- a/core/meta/inc/TClass.h +++ b/core/meta/inc/TClass.h @@ -286,6 +286,7 @@ public: void IgnoreTObjectStreamer(Bool_t ignore=kTRUE); Bool_t InheritsFrom(const char *cl) const; Bool_t InheritsFrom(const TClass *cl) const; + void InterpretedShowMembers(void* obj, TMemberInspector &insp, char *parent); Bool_t IsFolder() const { return kTRUE; } Bool_t IsLoaded() const; Bool_t IsForeign() const; diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx index 16665c42cd2cd318450974ba6e3c0605a9ddc1ce..38b217cdbb43c148a4dc06f648824db3ea6a1d45 100644 --- a/core/meta/src/TClass.cxx +++ b/core/meta/src/TClass.cxx @@ -1758,6 +1758,75 @@ Bool_t TClass::CallShowMembers(void* obj, TMemberInspector &insp, char *parent, return kFALSE; } +//______________________________________________________________________________ +void TClass::InterpretedShowMembers(void* obj, TMemberInspector &insp, char *parent) +{ + // Do a ShowMembers() traversal of all members and base classes' members + // using the reflection information from the interpreter. Works also for + // ionterpreted objects. + + if (!fClassInfo) return; + + DataMemberInfo_t* dmi = gCint->DataMemberInfo_Factory(fClassInfo); + Int_t ncp = strlen(parent); + + TString name("*"); + while (gCint->DataMemberInfo_Next(dmi)) { + name.Remove(1); + name += gCint->DataMemberInfo_Name(dmi); + if (name == "*G__virtualinfo") continue; + + // skip static members and the member G__virtualinfo inserted by the + // CINT RTTI system + Long_t prop = gCint->DataMemberInfo_Property(dmi) | gCint->DataMemberInfo_TypeProperty(dmi); + if (prop & (G__BIT_ISSTATIC | G__BIT_ISENUM)) + continue; + Bool_t isPointer = gCint->DataMemberInfo_TypeProperty(dmi) & G__BIT_ISPOINTER; + + // Array handling + if (prop & G__BIT_ISARRAY) { + int arrdim = gCint->DataMemberInfo_ArrayDim(dmi); + for (int dim = 0; dim < arrdim; dim++) { + int nelem = gCint->DataMemberInfo_MaxIndex(dmi, dim); + name += TString::Format("[%d]", nelem); + } + } + + const char* inspname = name; + if (!isPointer) { + // no '*': + ++inspname; + } + void* maddr = ((char*)obj) + gCint->DataMemberInfo_Offset(dmi); + insp.Inspect(this, parent, inspname, maddr); + + // If struct member: recurse. + if (!isPointer && !(prop & G__BIT_ISFUNDAMENTAL)) { + std::string clmName(TClassEdit::ShortType(gCint->DataMemberInfo_TypeName(dmi), + TClassEdit::kDropTrailStar) ); + TClass* clm = TClass::GetClass(clmName.c_str()); + if (clm) { + clm->CallShowMembers(maddr, insp, strcat(parent, name + ".")); parent[ncp] = 0; + } + } + } // while next data member + gCint->DataMemberInfo_Delete(dmi); + + // Iterate over base classes + BaseClassInfo_t* bci = gCint->BaseClassInfo_Factory(fClassInfo); + while (gCint->BaseClassInfo_Next(bci)) { + const char* bclname = gCint->BaseClassInfo_Name(bci); + TClass* bcl = TClass::GetClass(bclname); + void* baddr = ((char*)obj) + gCint->BaseClassInfo_Offset(bci); + if (bcl) { + bcl->CallShowMembers(baddr, insp, parent); + } else { + Warning("InterpretedShowMembers()", "Unknown class %s", bclname); + } + } + gCint->BaseClassInfo_Delete(bci); +} + //______________________________________________________________________________ Bool_t TClass::CanSplit() const {