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