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
 {