From 9fed1ebf7abf0105752b836ed61b461b12566263 Mon Sep 17 00:00:00 2001 From: Philippe Canal <pcanal@fnal.gov> Date: Tue, 20 Jul 2010 15:10:49 +0000 Subject: [PATCH] From Axel: * Implement a ShowMembers function for interpreted classes, by querying the interpreter for the data member information. * Implement Class() and Class_Name() in the interpreted (i.e. CINT's) ClassDef() version, now that #name works in CINT * Forward interpreted ShowMembers() in CINT's ClassDef() to TClass::InterpretedShowMembers() * For CINT, re-use ClassDef for ClassDefT; they are identical. git-svn-id: http://root.cern.ch/svn/root/trunk@34513 27541ba8-7e3a-0410-8455-c3a389f83636 --- core/base/inc/RtypesCint.h | 24 +++---------- core/meta/inc/TClass.h | 1 + core/meta/src/TClass.cxx | 69 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 19 deletions(-) diff --git a/core/base/inc/RtypesCint.h b/core/base/inc/RtypesCint.h index d8b21e99203..bbd7e8fdc6f 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 7506b15dab7..f0b8fdb4dea 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 16665c42cd2..38b217cdbb4 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 { -- GitLab