ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TClass.cxx
Go to the documentation of this file.
1 // @(#)root/meta:$Id: 7109cb45f1219c2aae6be19906ae5a63e31972ef $
2 // Author: Rene Brun 07/01/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TClass
13 The ROOT global object gROOT contains a list of all defined
14 classes. This list is build when a reference to a class dictionary
15 is made. When this happens, the static "class"::Dictionary()
16 function is called to create a TClass object describing the
17 class. The Dictionary() function is defined in the ClassDef
18 macro and stored (at program startup or library load time) together
19 with the class name in the TClassTable singleton object.
20 For a description of all dictionary classes see TDictionary.
21 
22 The name of the class as registered in the TClass object and in the
23 list of class is the "normalized name" and is defined as:
24 
25 The name of the type as accessible from the global scope to which
26 a 'using namespace std;' has been applied to and with:
27  - all typedefs disagreed except for Double32_t, Float16_t,
28  Long64_t, ULong64_t and std::string.
29  - default template parameters removed for STL collections and
30  added for any other class templates instances.
31  - Fully qualified both for the class name itself and all of its
32  component, except that, at least for moment, all 'std::' are
33  stripped.
34 */
35 
36 //*-*x7.5 macros/layout_class
37 
38 #include "TClass.h"
39 
40 #include "Riostream.h"
41 #include "TBaseClass.h"
42 #include "TBrowser.h"
43 #include "TBuffer.h"
44 #include "TClassGenerator.h"
45 #include "TClassEdit.h"
46 #include "TClassMenuItem.h"
47 #include "TClassRef.h"
48 #include "TClassTable.h"
49 #include "TDataMember.h"
50 #include "TDataType.h"
51 #include "TEnum.h"
52 #include "TError.h"
53 #include "TExMap.h"
54 #include "TFunctionTemplate.h"
55 #include "THashList.h"
56 #include "TInterpreter.h"
57 #include "TMemberInspector.h"
58 #include "TMethod.h"
59 #include "TMethodArg.h"
60 #include "TMethodCall.h"
61 #include "TObjArray.h"
62 #include "TProtoClass.h"
63 #include "TROOT.h"
64 #include "TRealData.h"
65 #include "TStreamer.h"
66 #include "TStreamerElement.h"
67 #include "TVirtualStreamerInfo.h"
69 #include "TVirtualIsAProxy.h"
70 #include "TVirtualRefProxy.h"
71 #include "TVirtualMutex.h"
72 #include "TVirtualPad.h"
73 #include "THashTable.h"
74 #include "TSchemaRuleSet.h"
75 #include "TGenericClassInfo.h"
76 #include "TIsAProxy.h"
77 #include "TSchemaRule.h"
78 #include "TSystem.h"
79 #include "TThreadSlots.h"
80 
81 #include <cstdio>
82 #include <cctype>
83 #include <set>
84 #include <sstream>
85 #include <string>
86 #include <map>
87 #include <typeinfo>
88 #include <cmath>
89 #include <assert.h>
90 #include <vector>
91 #include <memory>
92 
93 #include "TListOfDataMembers.h"
94 #include "TListOfFunctions.h"
96 #include "TListOfEnums.h"
97 #include "TListOfEnumsWithLock.h"
98 #include "TViewPubDataMembers.h"
99 #include "TViewPubFunctions.h"
100 
101 using namespace std;
102 
103 // Mutex to protect CINT and META operations
104 // (exported to be used for similar cases in related classes)
105 
107 
108 void *gMmallocDesc = 0; //is used and set in TMapFile
109 namespace {
110  class TMmallocDescTemp {
111  private:
112  void *fSave;
113  public:
114  TMmallocDescTemp(void *value = 0) : fSave(gMmallocDesc) { gMmallocDesc = value; }
115  ~TMmallocDescTemp() { gMmallocDesc = fSave; }
116  };
117 }
118 
119 std::atomic<Int_t> TClass::fgClassCount;
120 
121 // Implementation of the TDeclNameRegistry
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// TDeclNameRegistry class constructor.
125 
126 TClass::TDeclNameRegistry::TDeclNameRegistry(Int_t verbLevel): fVerbLevel(verbLevel)
127 {
128  // MSVC doesn't support fSpinLock=ATOMIC_FLAG_INIT; in the class definition
129  std::atomic_flag_clear( &fSpinLock );
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 /// Extract this part of the name
134 /// 1. Templates ns::ns2::,,,::THISPART<...
135 /// 2. Namespaces,classes ns::ns2::,,,::THISPART
136 
138 {
139  // Sanity check
140  auto strLen = strlen(name);
141  if (strLen == 0) return;
142  // find <. If none, put end of string
143  const char* endCharPtr = strchr(name, '<');
144  endCharPtr = !endCharPtr ? &name[strLen] : endCharPtr;
145  // find last : before the <. If not found, put begin of string
146  const char* beginCharPtr = endCharPtr;
147  while (beginCharPtr!=name){
148  if (*beginCharPtr==':'){
149  beginCharPtr++;
150  break;
151  }
152  beginCharPtr--;
153  }
154  beginCharPtr = beginCharPtr!=endCharPtr ? beginCharPtr : name;
155  std::string s(beginCharPtr, endCharPtr);
156  if (fVerbLevel>1)
157  printf("TDeclNameRegistry::AddQualifiedName Adding key %s for class/namespace %s\n", s.c_str(), name);
158  TClass::TSpinLockGuard slg(fSpinLock);
159  fClassNamesSet.insert(s);
160 }
161 
162 ////////////////////////////////////////////////////////////////////////////////
163 
165 {
166  Bool_t found = false;
167  {
168  TClass::TSpinLockGuard slg(fSpinLock);
169  found = fClassNamesSet.find(name) != fClassNamesSet.end();
170  }
171  return found;
172 }
173 
174 ////////////////////////////////////////////////////////////////////////////////
175 
177 {
178  if (fVerbLevel>1){
179  printf("TDeclNameRegistry Destructor. List of %lu names:\n",fClassNamesSet.size());
180  for(auto const & key:fClassNamesSet){
181  printf(" - %s\n",key.c_str());
182  }
183  }
184 }
185 
186 // Implementation of the spinlock guard in the registry
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 
190 TClass::TSpinLockGuard::TSpinLockGuard(std::atomic_flag& aflag):fAFlag(aflag)
191 {
192  while (fAFlag.test_and_set(std::memory_order_acquire));
193 }
194 
195 ////////////////////////////////////////////////////////////////////////////////
196 
198 {
199  fAFlag.clear(std::memory_order_release);
200 }
201 
202 ////////////////////////////////////////////////////////////////////////////////
203 
205  const char *name,
206  TDeclNameRegistry &emuRegistry): fState(state),fName(name), fNoInfoOrEmuOrFwdDeclNameRegistry(emuRegistry) {}
207 
208 ////////////////////////////////////////////////////////////////////////////////
209 
211  if (fState == TClass::kNoInfo ||
215  }
216  }
217 
218 // Initialise the global member of TClass
220 
221 //Intent of why/how TClass::New() is called
222 //[Not a static data member because MacOS does not support static thread local data member ... who knows why]
224  TTHREAD_TLS(TClass::ENewType) fgCallingNew = TClass::kRealNew;
225  return fgCallingNew;
226 }
227 
228 struct ObjRepoValue {
229  ObjRepoValue(const TClass *what, Version_t version) : fClass(what),fVersion(version) {}
230  const TClass *fClass;
231  Version_t fVersion;
232 };
233 
235 typedef std::multimap<void*, ObjRepoValue> RepoCont_t;
237 
238 static void RegisterAddressInRepository(const char * /*where*/, void *location, const TClass *what)
239 {
240  // Register the object for special handling in the destructor.
241 
242  Version_t version = what->GetClassVersion();
243 // if (!gObjectVersionRepository.count(location)) {
244 // Info(where, "Registering address %p of class '%s' version %d", location, what->GetName(), version);
245 // } else {
246 // Warning(where, "Registering address %p again of class '%s' version %d", location, what->GetName(), version);
247 // }
248  {
250  gObjectVersionRepository.insert(RepoCont_t::value_type(location, RepoCont_t::mapped_type(what,version)));
251  }
252 #if 0
253  // This code could be used to prevent an address to be registered twice.
254  std::pair<RepoCont_t::iterator, Bool_t> tmp = gObjectVersionRepository.insert(RepoCont_t::value_type>(location, RepoCont_t::mapped_type(what,version)));
255  if (!tmp.second) {
256  Warning(where, "Reregistering an object of class '%s' version %d at address %p", what->GetName(), version, p);
257  gObjectVersionRepository.erase(tmp.first);
258  tmp = gObjectVersionRepository.insert(RepoCont_t::value_type>(location, RepoCont_t::mapped_type(what,version)));
259  if (!tmp.second) {
260  Warning(where, "Failed to reregister an object of class '%s' version %d at address %p", what->GetName(), version, location);
261  }
262  }
263 #endif
264 }
265 
266 static void UnregisterAddressInRepository(const char * /*where*/, void *location, const TClass *what)
267 {
268  // Remove an address from the repository of address/object.
269 
271  RepoCont_t::iterator cur = gObjectVersionRepository.find(location);
272  for (; cur != gObjectVersionRepository.end();) {
273  RepoCont_t::iterator tmp = cur++;
274  if ((tmp->first == location) && (tmp->second.fVersion == what->GetClassVersion())) {
275  // -- We still have an address, version match.
276  // Info(where, "Unregistering address %p of class '%s' version %d", location, what->GetName(), what->GetClassVersion());
277  gObjectVersionRepository.erase(tmp);
278  } else {
279  // -- No address, version match, we've reached the end.
280  break;
281  }
282  }
283 }
284 
285 static void MoveAddressInRepository(const char * /*where*/, void *oldadd, void *newadd, const TClass *what)
286 {
287  // Register in the repository that an object has moved.
288 
289  // Move not only the object itself but also any base classes or sub-objects.
290  size_t objsize = what->Size();
291  long delta = (char*)newadd - (char*)oldadd;
293  RepoCont_t::iterator cur = gObjectVersionRepository.find(oldadd);
294  for (; cur != gObjectVersionRepository.end();) {
295  RepoCont_t::iterator tmp = cur++;
296  if (oldadd <= tmp->first && tmp->first < ( ((char*)oldadd) + objsize) ) {
297  // The location is within the object, let's move it.
298 
299  gObjectVersionRepository.insert(RepoCont_t::value_type(((char*)tmp->first)+delta, RepoCont_t::mapped_type(tmp->second.fClass,tmp->second.fVersion)));
300  gObjectVersionRepository.erase(tmp);
301 
302  } else {
303  // -- No address, version match, we've reached the end.
304  break;
305  }
306  }
307 }
308 
309 //______________________________________________________________________________
310 //______________________________________________________________________________
311 namespace ROOT {
312 #define R__USE_STD_MAP
313  class TMapTypeToTClass {
314 #if defined R__USE_STD_MAP
315  // This wrapper class allow to avoid putting #include <map> in the
316  // TROOT.h header file.
317  public:
318 #ifdef R__GLOBALSTL
319  typedef map<string,TClass*> IdMap_t;
320 #else
321  typedef std::map<std::string,TClass*> IdMap_t;
322 #endif
323  typedef IdMap_t::key_type key_type;
324  typedef IdMap_t::const_iterator const_iterator;
325  typedef IdMap_t::size_type size_type;
326 #ifdef R__WIN32
327  // Window's std::map does NOT defined mapped_type
328  typedef TClass* mapped_type;
329 #else
330  typedef IdMap_t::mapped_type mapped_type;
331 #endif
332 
333  private:
334  IdMap_t fMap;
335 
336  public:
337  void Add(const key_type &key, mapped_type &obj)
338  {
339  // Add the <key,obj> pair to the map.
340  fMap[key] = obj;
341  }
342  mapped_type Find(const key_type &key) const
343  {
344  // Find the type corresponding to the key.
345  IdMap_t::const_iterator iter = fMap.find(key);
346  mapped_type cl = 0;
347  if (iter != fMap.end()) cl = iter->second;
348  return cl;
349  }
350  void Remove(const key_type &key) {
351  // Remove the type corresponding to the key.
352  fMap.erase(key);
353  }
354 #else
355  private:
356  TMap fMap;
357 
358  public:
359 #ifdef R__COMPLETE_MEM_TERMINATION
360  TMapTypeToTClass() {
361  TIter next(&fMap);
362  TObjString *key;
363  while((key = (TObjString*)next())) {
364  delete key;
365  }
366  }
367 #endif
368  void Add(const char *key, TClass *&obj) {
369  TObjString *realkey = new TObjString(key);
370  fMap.Add(realkey, obj);
371  }
372  TClass* Find(const char *key) const {
373  const TPair *a = (const TPair *)fMap.FindObject(key);
374  if (a) return (TClass*) a->Value();
375  return 0;
376  }
377  void Remove(const char *key) {
378  TObjString realkey(key);
379  TObject *actual = fMap.Remove(&realkey);
380  delete actual;
381  }
382 #endif
383  };
384 
385  class TMapDeclIdToTClass {
386  // Wrapper class for the multimap of DeclId_t and TClass.
387  public:
388  typedef multimap<TDictionary::DeclId_t, TClass*> DeclIdMap_t;
389  typedef DeclIdMap_t::key_type key_type;
390  typedef DeclIdMap_t::mapped_type mapped_type;
391  typedef DeclIdMap_t::const_iterator const_iterator;
392  typedef std::pair <const_iterator, const_iterator> equal_range;
393  typedef DeclIdMap_t::size_type size_type;
394 
395  private:
396  DeclIdMap_t fMap;
397 
398  public:
399  void Add(const key_type &key, mapped_type obj)
400  {
401  // Add the <key,obj> pair to the map.
402  std::pair<const key_type, mapped_type> pair = make_pair(key, obj);
403  fMap.insert(pair);
404  }
405  size_type CountElementsWithKey(const key_type &key)
406  {
407  return fMap.count(key);
408  }
409  equal_range Find(const key_type &key) const
410  {
411  // Find the type corresponding to the key.
412  return fMap.equal_range(key);
413  }
414  void Remove(const key_type &key) {
415  // Remove the type corresponding to the key.
416  fMap.erase(key);
417  }
418  };
419 }
420 
422 
423 #ifdef R__COMPLETE_MEM_TERMINATION
424  static IdMap_t gIdMapObject;
425  return &gIdMap;
426 #else
427  static IdMap_t *gIdMap = new IdMap_t;
428  return gIdMap;
429 #endif
430 }
431 
433 
434 #ifdef R__COMPLETE_MEM_TERMINATION
435  static DeclIdMap_t gDeclIdMapObject;
436  return &gIdMap;
437 #else
438  static DeclIdMap_t *gDeclIdMap = new DeclIdMap_t;
439  return gDeclIdMap;
440 #endif
441 }
442 
443 ////////////////////////////////////////////////////////////////////////////////
444 /// static: Add a class to the list and map of classes.
445 
447 {
448  if (!cl) return;
449 
451  gROOT->GetListOfClasses()->Add(cl);
452  if (cl->GetTypeInfo()) {
453  GetIdMap()->Add(cl->GetTypeInfo()->name(),cl);
454  }
455  if (cl->fClassInfo) {
456  GetDeclIdMap()->Add((void*)(cl->fClassInfo), cl);
457  }
458 }
459 
460 ////////////////////////////////////////////////////////////////////////////////
461 /// static: Add a TClass* to the map of classes.
462 
464 {
465  if (!cl || !id) return;
466  GetDeclIdMap()->Add(id, cl);
467 }
468 
469 ////////////////////////////////////////////////////////////////////////////////
470 /// static: Remove a class from the list and map of classes
471 
473 {
474  if (!oldcl) return;
475 
477  gROOT->GetListOfClasses()->Remove(oldcl);
478  if (oldcl->GetTypeInfo()) {
479  GetIdMap()->Remove(oldcl->GetTypeInfo()->name());
480  }
481  if (oldcl->fClassInfo) {
482  //GetDeclIdMap()->Remove((void*)(oldcl->fClassInfo));
483  }
484 }
485 
486 ////////////////////////////////////////////////////////////////////////////////
487 
489 {
490  if (!id) return;
491  GetDeclIdMap()->Remove(id);
492 }
493 
494 ////////////////////////////////////////////////////////////////////////////////
495 /// Indirect call to the implementation of ShowMember allowing [forward]
496 /// declaration with out a full definition of the TClass class.
497 
498 void ROOT::Class_ShowMembers(TClass *cl, const void *obj, TMemberInspector&insp)
499 {
500  gInterpreter->InspectMembers(insp, obj, cl, kFALSE);
501 }
502 
503 //______________________________________________________________________________
504 //______________________________________________________________________________
505 
506 class TDumpMembers : public TMemberInspector {
507  bool fNoAddr;
508 public:
509  TDumpMembers(bool noAddr): fNoAddr(noAddr) { }
510 
512  void Inspect(TClass *cl, const char *parent, const char *name, const void *addr, Bool_t isTransient);
513 };
514 
515 ////////////////////////////////////////////////////////////////////////////////
516 /// Print value of member mname.
517 ///
518 /// This method is called by the ShowMembers() method for each
519 /// data member when object.Dump() is invoked.
520 ///
521 /// - cl is the pointer to the current class
522 /// - pname is the parent name (in case of composed objects)
523 /// - mname is the data member name
524 /// - add is the data member address
525 
526 void TDumpMembers::Inspect(TClass *cl, const char *pname, const char *mname, const void *add, Bool_t /* isTransient */)
527 {
528  const Int_t kvalue = 30;
529 #ifdef R__B64
530  const Int_t ktitle = 50;
531 #else
532  const Int_t ktitle = 42;
533 #endif
534  const Int_t kline = 1024;
535  Int_t cdate = 0;
536  Int_t ctime = 0;
537  UInt_t *cdatime = 0;
538  char line[kline];
539 
540  TDataType *membertype;
541  EDataType memberDataType = kNoType_t;
542  const char *memberName;
543  const char *memberFullTypeName;
544  const char *memberTitle;
545  Bool_t isapointer;
546  Bool_t isbasic;
547 
548  if (TDataMember *member = cl->GetDataMember(mname)) {
549  if (member->GetDataType()) {
550  memberDataType = (EDataType)member->GetDataType()->GetType();
551  }
552  memberName = member->GetName();
553  memberFullTypeName = member->GetFullTypeName();
554  memberTitle = member->GetTitle();
555  isapointer = member->IsaPointer();
556  isbasic = member->IsBasic();
557  membertype = member->GetDataType();
558  } else if (!cl->IsLoaded()) {
559  // The class is not loaded, hence it is 'emulated' and the main source of
560  // information is the StreamerInfo.
562  if (!info) return;
563  const char *cursor = mname;
564  while ( (*cursor)=='*' ) ++cursor;
565  TString elname( cursor );
566  Ssiz_t pos = elname.Index("[");
567  if ( pos != kNPOS ) {
568  elname.Remove( pos );
569  }
570  TStreamerElement *element = (TStreamerElement*)info->GetElements()->FindObject(elname.Data());
571  if (!element) return;
572  memberFullTypeName = element->GetTypeName();
573 
574  memberDataType = (EDataType)element->GetType();
575 
576  memberName = element->GetName();
577  memberTitle = element->GetTitle();
578  isapointer = element->IsaPointer() || element->GetType() == TVirtualStreamerInfo::kCharStar;
579  membertype = gROOT->GetType(memberFullTypeName);
580 
581  isbasic = membertype !=0;
582  } else {
583  return;
584  }
585 
586 
587  Bool_t isdate = kFALSE;
588  if (strcmp(memberName,"fDatime") == 0 && memberDataType == kUInt_t) {
589  isdate = kTRUE;
590  }
591  Bool_t isbits = kFALSE;
592  if (strcmp(memberName,"fBits") == 0 && memberDataType == kUInt_t) {
593  isbits = kTRUE;
594  }
595  TClass * dataClass = TClass::GetClass(memberFullTypeName);
596  Bool_t isTString = (dataClass == TString::Class());
597  static TClassRef stdClass("std::string");
598  Bool_t isStdString = (dataClass == stdClass);
599 
600  Int_t i;
601  for (i = 0;i < kline; i++) line[i] = ' ';
602  line[kline-1] = 0;
603  snprintf(line,kline,"%s%s ",pname,mname);
604  i = strlen(line); line[i] = ' ';
605 
606  // Encode data value or pointer value
607  char *pointer = (char*)add;
608  char **ppointer = (char**)(pointer);
609 
610  if (isapointer) {
611  char **p3pointer = (char**)(*ppointer);
612  if (!p3pointer)
613  snprintf(&line[kvalue],kline-kvalue,"->0");
614  else if (!isbasic) {
615  if (!fNoAddr) {
616  snprintf(&line[kvalue],kline-kvalue,"->%lx ", (Long_t)p3pointer);
617  }
618  } else if (membertype) {
619  if (!strcmp(membertype->GetTypeName(), "char")) {
620  i = strlen(*ppointer);
621  if (kvalue+i > kline) i=kline-1-kvalue;
622  Bool_t isPrintable = kTRUE;
623  for (Int_t j = 0; j < i; j++) {
624  if (!std::isprint((*ppointer)[j])) {
625  isPrintable = kFALSE;
626  break;
627  }
628  }
629  if (isPrintable) {
630  strncpy(line + kvalue, *ppointer, i);
631  line[kvalue+i] = 0;
632  } else {
633  line[kvalue] = 0;
634  }
635  } else {
636  strncpy(&line[kvalue], membertype->AsString(p3pointer), TMath::Min(kline-1-kvalue,(int)strlen(membertype->AsString(p3pointer))));
637  }
638  } else if (!strcmp(memberFullTypeName, "char*") ||
639  !strcmp(memberFullTypeName, "const char*")) {
640  i = strlen(*ppointer);
641  if (kvalue+i >= kline) i=kline-1-kvalue;
642  Bool_t isPrintable = kTRUE;
643  for (Int_t j = 0; j < i; j++) {
644  if (!std::isprint((*ppointer)[j])) {
645  isPrintable = kFALSE;
646  break;
647  }
648  }
649  if (isPrintable) {
650  strncpy(line + kvalue, *ppointer, i);
651  line[kvalue+i] = 0;
652  } else {
653  line[kvalue] = 0;
654  }
655  } else {
656  if (!fNoAddr) {
657  snprintf(&line[kvalue],kline-kvalue,"->%lx ", (Long_t)p3pointer);
658  }
659  }
660  } else if (membertype) {
661  if (isdate) {
662  cdatime = (UInt_t*)pointer;
663  TDatime::GetDateTime(cdatime[0],cdate,ctime);
664  snprintf(&line[kvalue],kline-kvalue,"%d/%d",cdate,ctime);
665  } else if (isbits) {
666  snprintf(&line[kvalue],kline-kvalue,"0x%08x", *(UInt_t*)pointer);
667  } else {
668  strncpy(&line[kvalue], membertype->AsString(pointer), TMath::Min(kline-1-kvalue,(int)strlen(membertype->AsString(pointer))));
669  }
670  } else {
671  if (isStdString) {
672  std::string *str = (std::string*)pointer;
673  snprintf(&line[kvalue],kline-kvalue,"%s",str->c_str());
674  } else if (isTString) {
675  TString *str = (TString*)pointer;
676  snprintf(&line[kvalue],kline-kvalue,"%s",str->Data());
677  } else {
678  if (!fNoAddr) {
679  snprintf(&line[kvalue],kline-kvalue,"->%lx ", (Long_t)pointer);
680  }
681  }
682  }
683  // Encode data member title
684  if (isdate == kFALSE && strcmp(memberFullTypeName, "char*") && strcmp(memberFullTypeName, "const char*")) {
685  i = strlen(&line[0]); line[i] = ' ';
686  Int_t lentit = strlen(memberTitle);
687  if (lentit > 250-ktitle) lentit = 250-ktitle;
688  strncpy(&line[ktitle],memberTitle,lentit);
689  line[ktitle+lentit] = 0;
690  }
691  Printf("%s", line);
692 }
693 
695 
696 //______________________________________________________________________________
697 //______________________________________________________________________________
698 ////////////////////////////////////////////////////////////////////////////////
699 
700 TClass::TNameMapNode::TNameMapNode (const char* typedf, const char* orig)
701  : TObjString (typedf),
702  fOrigName (orig)
703 {
704 }
705 
706 //______________________________________________________________________________
707 
708 class TBuildRealData : public TMemberInspector {
709 
710 private:
711  void *fRealDataObject;
712  TClass *fRealDataClass;
713 
714 public:
715  TBuildRealData(void *obj, TClass *cl) {
716  // Main constructor.
717  fRealDataObject = obj;
718  fRealDataClass = cl;
719  }
721  void Inspect(TClass *cl, const char *parent, const char *name, const void *addr, Bool_t isTransient);
722 
723 };
724 
725 ////////////////////////////////////////////////////////////////////////////////
726 /// This method is called from ShowMembers() via BuildRealdata().
727 
728 void TBuildRealData::Inspect(TClass* cl, const char* pname, const char* mname, const void* add, Bool_t isTransient)
729 {
730  TDataMember* dm = cl->GetDataMember(mname);
731  if (!dm) {
732  return;
733  }
734 
735  Bool_t isTransientMember = kFALSE;
736 
737  if (!dm->IsPersistent()) {
738  // For the DataModelEvolution we need access to the transient member.
739  // so we now record them in the list of RealData.
740  isTransientMember = kTRUE;
741  isTransient = kTRUE;
742  }
743 
744  TString rname( pname );
745  // Take into account cases like TPaveStats->TPaveText->TPave->TBox.
746  // Check that member is in a derived class or an object in the class.
747  if (cl != fRealDataClass) {
748  if (!fRealDataClass->InheritsFrom(cl)) {
749  Ssiz_t dot = rname.Index('.');
750  if (dot == kNPOS) {
751  return;
752  }
753  rname[dot] = '\0';
754  if (!fRealDataClass->GetDataMember(rname)) {
755  //could be a data member in a base class like in this example
756  // class Event : public Data {
757  // class Data : public TObject {
758  // EventHeader fEvtHdr;
759  // class EventHeader {
760  // Int_t fEvtNum;
761  // Int_t fRun;
762  // Int_t fDate;
763  // EventVertex fVertex;
764  // class EventVertex {
765  // EventTime fTime;
766  // class EventTime {
767  // Int_t fSec;
768  // Int_t fNanoSec;
769  if (!fRealDataClass->GetBaseDataMember(rname)) {
770  return;
771  }
772  }
773  rname[dot] = '.';
774  }
775  }
776  rname += mname;
777  Long_t offset = Long_t(((Long_t) add) - ((Long_t) fRealDataObject));
778 
779  if (dm->IsaPointer()) {
780  // Data member is a pointer.
781  if (!dm->IsBasic()) {
782  // Pointer to class object.
783  TRealData* rd = new TRealData(rname, offset, dm);
784  if (isTransientMember) { rd->SetBit(TRealData::kTransient); };
785  fRealDataClass->GetListOfRealData()->Add(rd);
786  } else {
787  // Pointer to basic data type.
788  TRealData* rd = new TRealData(rname, offset, dm);
789  if (isTransientMember) { rd->SetBit(TRealData::kTransient); };
790  fRealDataClass->GetListOfRealData()->Add(rd);
791  }
792  } else {
793  // Data Member is a basic data type.
794  TRealData* rd = new TRealData(rname, offset, dm);
795  if (isTransientMember) { rd->SetBit(TRealData::kTransient); };
796  if (!dm->IsBasic()) {
797  rd->SetIsObject(kTRUE);
798 
799  // Make sure that BuildReadData is called for any abstract
800  // bases classes involved in this object, i.e for all the
801  // classes composing this object (base classes, type of
802  // embedded object and same for their data members).
803  //
804  TClass* dmclass = TClass::GetClass(dm->GetTypeName(), kTRUE, isTransient);
805  if (!dmclass) {
806  dmclass = TClass::GetClass(dm->GetTrueTypeName(), kTRUE, isTransient);
807  }
808  if (dmclass) {
809  if ((dmclass != cl) && !dm->IsaPointer()) {
810  if (dmclass->GetCollectionProxy()) {
811  TClass* valcl = dmclass->GetCollectionProxy()->GetValueClass();
812  // We create the real data for the content of the collection to help the case
813  // of split branches in a TTree (where the node for the data member itself
814  // might have been elided). However, in some cases, like transient members
815  // and/or classes, the content might not be create-able. An example is the
816  // case of a map<A,B> where either A or B does not have default constructor
817  // and thus the compilation of the default constructor for pair<A,B> will
818  // fail (noisily) [This could also apply to any template instance, where it
819  // might have a default constructor definition that can not be compiled due
820  // to the template parameter]
821  if (valcl) {
822  Bool_t wantBuild = kTRUE;
823  if (valcl->Property() & kIsAbstract) wantBuild = kFALSE;
824  if ( (isTransient)
826  && (!valcl->IsLoaded()) ) {
827  // Case where the collection dictionary was not requested and
828  // the content's dictionary was also not requested.
829  // [This is a super set of what we need, but we can't really detect it :(]
830  wantBuild = kFALSE;
831  }
832 
833  if (wantBuild) valcl->BuildRealData(0, isTransient);
834  }
835  } else {
836  void* addrForRecursion = 0;
837  if (GetObjectValidity() == kValidObjectGiven)
838  addrForRecursion = const_cast<void*>(add);
839 
840  dmclass->BuildRealData(addrForRecursion, isTransient);
841  }
842  }
843  }
844  }
845  fRealDataClass->GetListOfRealData()->Add(rd);
846  }
847 }
848 
849 //______________________________________________________________________________
850 //______________________________________________________________________________
851 //______________________________________________________________________________
852 
853 ////////////////////////////////////////////////////////////////////////////////
854 
855 class TAutoInspector : public TMemberInspector {
856 public:
857  Int_t fCount;
858  TBrowser *fBrowser;
859 
860  TAutoInspector(TBrowser *b) {
861  // main constructor.
862  fBrowser = b; fCount = 0; }
863  virtual ~TAutoInspector() { }
865  virtual void Inspect(TClass *cl, const char *parent, const char *name, const void *addr, Bool_t isTransient);
866  virtual Bool_t IsTreatingNonAccessibleTypes() {return kFALSE;}
867 };
868 
869 ////////////////////////////////////////////////////////////////////////////////
870 /// This method is called from ShowMembers() via AutoBrowse().
871 
872 void TAutoInspector::Inspect(TClass *cl, const char *tit, const char *name,
873  const void *addr, Bool_t /* isTransient */)
874 {
875  if(tit && strchr(tit,'.')) return ;
876  if (fCount && !fBrowser) return;
877 
878  TString ts;
879 
880  if (!cl) return;
881  //if (*(cl->GetName()) == 'T') return;
882  if (*name == '*') name++;
883  int ln = strcspn(name,"[ ");
884  TString iname(name,ln);
885 
886  ClassInfo_t *classInfo = cl->GetClassInfo();
887  if (!classInfo) return;
888 
889  // Browse data members
890  DataMemberInfo_t *m = gCling->DataMemberInfo_Factory(classInfo);
891  TString mname;
892 
893  int found=0;
894  while (gCling->DataMemberInfo_Next(m)) { // MemberLoop
895  mname = gCling->DataMemberInfo_Name(m);
896  mname.ReplaceAll("*","");
897  if ((found = (iname==mname))) break;
898  }
899  assert(found);
900 
901  // we skip: non static members and non objects
902  // - the member G__virtualinfo inserted by the CINT RTTI system
903 
904  //Long_t prop = m.Property() | m.Type()->Property();
906  if (prop & kIsStatic) return;
907  if (prop & kIsFundamental) return;
908  if (prop & kIsEnum) return;
909  if (mname == "G__virtualinfo") return;
910 
911  int size = sizeof(void*);
912 
913  int nmax = 1;
914  if (prop & kIsArray) {
915  for (int dim = 0; dim < gCling->DataMemberInfo_ArrayDim(m); dim++) nmax *= gCling->DataMemberInfo_MaxIndex(m,dim);
916  }
917 
918  std::string clmName(TClassEdit::ShortType(gCling->DataMemberInfo_TypeName(m),
920  TClass * clm = TClass::GetClass(clmName.c_str());
921  R__ASSERT(clm);
922  if (!(prop & kIsPointer)) {
923  size = clm->Size();
924  if (size==0) size = gCling->DataMemberInfo_TypeSize(m);
925  }
926 
927 
930 
931  for(int i=0; i<nmax; i++) {
932 
933  char *ptr = (char*)addr + i*size;
934 
935  void *obj = (prop & kIsPointer) ? *((void**)ptr) : (TObject*)ptr;
936 
937  if (!obj) continue;
938 
939  fCount++;
940  if (!fBrowser) return;
941 
942  TString bwname;
943  TClass *actualClass = clm->GetActualClass(obj);
944  if (clm->IsTObject()) {
945  TObject *tobj = (TObject*)clm->DynamicCast(TObject::Class(),obj);
946  bwname = tobj->GetName();
947  } else {
948  bwname = actualClass->GetName();
949  bwname += "::";
950  bwname += mname;
951  }
952 
953  if (!clm->IsTObject() ||
954  bwname.Length()==0 ||
955  strcmp(bwname.Data(),actualClass->GetName())==0) {
956  bwname = name;
957  int l = strcspn(bwname.Data(),"[ ");
958  if (l<bwname.Length() && bwname[l]=='[') {
959  char cbuf[12]; snprintf(cbuf,12,"[%02d]",i);
960  ts.Replace(0,999,bwname,l);
961  ts += cbuf;
962  bwname = (const char*)ts;
963  }
964  }
965 
966  if (proxy==0) {
967 
968  fBrowser->Add(obj,clm,bwname);
969 
970  } else {
971  TClass *valueCl = proxy->GetValueClass();
972 
973  if (valueCl==0) {
974 
975  fBrowser->Add( obj, clm, bwname );
976 
977  } else {
978  TVirtualCollectionProxy::TPushPop env(proxy, obj);
979  TClass *actualCl = 0;
980 
981  int sz = proxy->Size();
982 
983  char fmt[] = {"#%09d"};
984  fmt[3] = '0'+(int)log10(double(sz))+1;
985  char buf[20];
986  for (int ii=0;ii<sz;ii++) {
987  void *p = proxy->At(ii);
988 
989  if (proxy->HasPointers()) {
990  p = *((void**)p);
991  if(!p) continue;
992  actualCl = valueCl->GetActualClass(p);
993  p = actualCl->DynamicCast(valueCl,p,0);
994  }
995  fCount++;
996  snprintf(buf,20,fmt,ii);
997  ts = bwname;
998  ts += buf;
999  fBrowser->Add( p, actualCl, ts );
1000  }
1001  }
1002  }
1003  }
1004 }
1005 
1006 //______________________________________________________________________________
1007 //______________________________________________________________________________
1008 //______________________________________________________________________________
1009 
1011 
1012 ////////////////////////////////////////////////////////////////////////////////
1013 
1014 TClass::TClass() :
1015  TDictionary(),
1016  fPersistentRef(0),
1018  fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1021  fInstanceCount(0), fOnHeap(0),
1023  fTypeInfo(0), fShowMembers(0),
1024  fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1025  fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1029  fState(kNoInfo),
1032 
1033 {
1034  // Default ctor.
1035 
1037  {
1038  TMmallocDescTemp setreset;
1039  fStreamerInfo = new TObjArray(1, -2);
1040  }
1041  fDeclFileLine = -2; // -2 for standalone TClass (checked in dtor)
1042 }
1043 
1044 ////////////////////////////////////////////////////////////////////////////////
1045 /// Create a TClass object. This object contains the full dictionary
1046 /// of a class. It has list to baseclasses, datamembers and methods.
1047 /// Use this ctor to create a standalone TClass object. Most useful
1048 /// to get a TClass interface to an interpreted class. Used by TTabCom.
1049 /// Normally you would use TClass::GetClass("class") to get access to a
1050 /// TClass object for a certain class.
1051 
1052 TClass::TClass(const char *name, Bool_t silent) :
1053  TDictionary(name),
1054  fPersistentRef(0),
1056  fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1059  fInstanceCount(0), fOnHeap(0),
1061  fTypeInfo(0), fShowMembers(0),
1062  fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1063  fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1067  fState(kNoInfo),
1070 {
1072 
1073  if (!gROOT)
1074  ::Fatal("TClass::TClass", "ROOT system not initialized");
1075 
1076  {
1077  TMmallocDescTemp setreset;
1078  fStreamerInfo = new TObjArray(1, -2);
1079  }
1080  fDeclFileLine = -2; // -2 for standalone TClass (checked in dtor)
1081 
1082  SetBit(kLoading);
1083  if (!gInterpreter)
1084  ::Fatal("TClass::TClass", "gInterpreter not initialized");
1085 
1086  gInterpreter->SetClassInfo(this); // sets fClassInfo pointer
1087  if (!silent && !fClassInfo && fName.First('@')==kNPOS)
1088  ::Warning("TClass::TClass", "no dictionary for class %s is available", name);
1089  ResetBit(kLoading);
1090 
1093 }
1094 
1095 ////////////////////////////////////////////////////////////////////////////////
1096 /// Create a TClass object. This object contains the full dictionary
1097 /// of a class. It has list to baseclasses, datamembers and methods.
1098 
1099 TClass::TClass(const char *name, Version_t cversion, Bool_t silent) :
1100  TDictionary(name),
1101  fPersistentRef(0),
1102  fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
1103  fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1104  fAllPubMethod(0), fClassMenuList(0),
1105  fDeclFileName(""), fImplFileName(""), fDeclFileLine(0), fImplFileLine(0),
1106  fInstanceCount(0), fOnHeap(0),
1107  fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
1108  fTypeInfo(0), fShowMembers(0),
1109  fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1110  fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1111  fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fConvStreamerFunc(0), fSizeof(-1),
1112  fCanSplit(-1), fProperty(0), fClassProperty(0), fHasRootPcmInfo(kFALSE), fCanLoadClassInfo(kFALSE),
1113  fIsOffsetStreamerSet(kFALSE), fVersionUsed(kFALSE), fOffsetStreamer(0), fStreamerType(TClass::kDefault),
1114  fState(kNoInfo),
1115  fCurrentInfo(0), fLastReadInfo(0), fRefProxy(0),
1116  fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
1117 {
1119  Init(name, cversion, 0, 0, 0, 0, -1, -1, 0, silent);
1120 }
1121 
1122 ////////////////////////////////////////////////////////////////////////////////
1123 /// Create a TClass object. This object does not contain anything. We mimic
1124 /// the case of a class fwd declared in the interpreter.
1125 
1126 TClass::TClass(const char *name, Version_t cversion, EState theState, Bool_t silent) :
1127  TDictionary(name),
1128  fPersistentRef(0),
1129  fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
1130  fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1131  fAllPubMethod(0), fClassMenuList(0),
1132  fDeclFileName(""), fImplFileName(""), fDeclFileLine(0), fImplFileLine(0),
1133  fInstanceCount(0), fOnHeap(0),
1134  fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
1135  fTypeInfo(0), fShowMembers(0),
1136  fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1137  fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1138  fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fConvStreamerFunc(0), fSizeof(-1),
1139  fCanSplit(-1), fProperty(0), fClassProperty(0), fHasRootPcmInfo(kFALSE), fCanLoadClassInfo(kFALSE),
1140  fIsOffsetStreamerSet(kFALSE), fVersionUsed(kFALSE), fOffsetStreamer(0), fStreamerType(TClass::kDefault),
1141  fState(theState),
1142  fCurrentInfo(0), fLastReadInfo(0), fRefProxy(0),
1143  fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
1144 {
1146 
1147  // Treat the case in which a TClass instance is created for a namespace
1148  if (theState == kNamespaceForMeta){
1150  theState = kForwardDeclared; // it immediately decays in kForwardDeclared
1151  }
1152 
1153  if (theState != kForwardDeclared && theState != kEmulated)
1154  ::Fatal("TClass::TClass",
1155  "A TClass entry cannot be initialized in a state different from kForwardDeclared or kEmulated.");
1156  Init(name, cversion, 0, 0, 0, 0, -1, -1, 0, silent);
1157 }
1158 
1159 ////////////////////////////////////////////////////////////////////////////////
1160 /// Create a TClass object. This object contains the full dictionary
1161 /// of a class. It has list to baseclasses, datamembers and methods.
1162 /// Use this ctor to create a standalone TClass object. Most useful
1163 /// to get a TClass interface to an interpreted class. Used by TTabCom.
1164 /// Normally you would use TClass::GetClass("class") to get access to a
1165 /// TClass object for a certain class.
1166 ///
1167 /// This copies the ClassInfo (i.e. does *not* take ownership of it).
1168 
1169 TClass::TClass(ClassInfo_t *classInfo, Version_t cversion,
1170  const char *dfil, const char *ifil, Int_t dl, Int_t il, Bool_t silent) :
1171  TDictionary(""),
1172  fPersistentRef(0),
1173  fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
1174  fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1175  fAllPubMethod(0), fClassMenuList(0),
1176  fDeclFileName(""), fImplFileName(""), fDeclFileLine(0), fImplFileLine(0),
1177  fInstanceCount(0), fOnHeap(0),
1178  fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
1179  fTypeInfo(0), fShowMembers(0),
1180  fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1181  fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1182  fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fConvStreamerFunc(0), fSizeof(-1),
1183  fCanSplit(-1), fProperty(0), fClassProperty(0), fHasRootPcmInfo(kFALSE), fCanLoadClassInfo(kFALSE),
1184  fIsOffsetStreamerSet(kFALSE), fVersionUsed(kFALSE), fOffsetStreamer(0), fStreamerType(TClass::kDefault),
1185  fState(kNoInfo),
1186  fCurrentInfo(0), fLastReadInfo(0), fRefProxy(0),
1187  fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
1188 {
1190 
1191  if (!gROOT)
1192  ::Fatal("TClass::TClass", "ROOT system not initialized");
1193 
1194  fDeclFileLine = -2; // -2 for standalone TClass (checked in dtor)
1195 
1196  SetBit(kLoading);
1197  if (!gInterpreter)
1198  ::Fatal("TClass::TClass", "gInterpreter not initialized");
1199 
1200  if (!classInfo || !gInterpreter->ClassInfo_IsValid(classInfo)) {
1201  MakeZombie();
1202  fState = kNoInfo;
1203  } else {
1204  fName = gInterpreter->ClassInfo_FullName(classInfo);
1205 
1207  Init(fName, cversion, 0, 0, dfil, ifil, dl, il, classInfo, silent);
1208  }
1209  ResetBit(kLoading);
1210 
1212 }
1213 
1214 
1215 ////////////////////////////////////////////////////////////////////////////////
1216 /// Create a TClass object. This object contains the full dictionary
1217 /// of a class. It has list to baseclasses, datamembers and methods.
1218 
1219 TClass::TClass(const char *name, Version_t cversion,
1220  const char *dfil, const char *ifil, Int_t dl, Int_t il, Bool_t silent) :
1221  TDictionary(name),
1222  fPersistentRef(0),
1223  fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
1224  fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1225  fAllPubMethod(0), fClassMenuList(0),
1226  fDeclFileName(""), fImplFileName(""), fDeclFileLine(0), fImplFileLine(0),
1227  fInstanceCount(0), fOnHeap(0),
1228  fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
1229  fTypeInfo(0), fShowMembers(0),
1230  fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1231  fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1232  fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fConvStreamerFunc(0), fSizeof(-1),
1233  fCanSplit(-1), fProperty(0), fClassProperty(0), fHasRootPcmInfo(kFALSE), fCanLoadClassInfo(kFALSE),
1234  fIsOffsetStreamerSet(kFALSE), fVersionUsed(kFALSE), fOffsetStreamer(0), fStreamerType(TClass::kDefault),
1235  fState(kNoInfo),
1236  fCurrentInfo(0), fLastReadInfo(0), fRefProxy(0),
1237  fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
1238 {
1240  Init(name,cversion, 0, 0, dfil, ifil, dl, il, 0, silent);
1241 }
1242 
1243 ////////////////////////////////////////////////////////////////////////////////
1244 /// Create a TClass object. This object contains the full dictionary
1245 /// of a class. It has list to baseclasses, datamembers and methods.
1246 
1247 TClass::TClass(const char *name, Version_t cversion,
1248  const type_info &info, TVirtualIsAProxy *isa,
1249  const char *dfil, const char *ifil, Int_t dl, Int_t il,
1250  Bool_t silent) :
1251  TDictionary(name),
1252  fPersistentRef(0),
1253  fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
1254  fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1255  fAllPubMethod(0),
1256  fClassMenuList(0),
1257  fDeclFileName(""), fImplFileName(""), fDeclFileLine(0), fImplFileLine(0),
1258  fInstanceCount(0), fOnHeap(0),
1259  fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
1260  fTypeInfo(0), fShowMembers(0),
1261  fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1262  fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1263  fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fConvStreamerFunc(0), fSizeof(-1),
1264  fCanSplit(-1), fProperty(0), fClassProperty(0), fHasRootPcmInfo(kFALSE), fCanLoadClassInfo(kFALSE),
1265  fIsOffsetStreamerSet(kFALSE), fVersionUsed(kFALSE), fOffsetStreamer(0), fStreamerType(TClass::kDefault),
1266  fState(kHasTClassInit),
1267  fCurrentInfo(0), fLastReadInfo(0), fRefProxy(0),
1268  fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
1269 {
1271  // use info
1272  Init(name, cversion, &info, isa, dfil, ifil, dl, il, 0, silent);
1273 }
1274 
1275 ////////////////////////////////////////////////////////////////////////////////
1276 /// we found at least one equivalent.
1277 /// let's force a reload
1278 
1280 {
1281  TClass::RemoveClass(oldcl);
1282 
1283  if (oldcl->CanIgnoreTObjectStreamer()) {
1285  }
1286 
1287  TVirtualStreamerInfo *info;
1288  TIter next(oldcl->GetStreamerInfos());
1289  while ((info = (TVirtualStreamerInfo*)next())) {
1290  info->Clear("build");
1291  info->SetClass(this);
1293  }
1294  oldcl->fStreamerInfo->Clear();
1295 
1296  oldcl->ReplaceWith(this);
1297  delete oldcl;
1298 }
1299 
1300 ////////////////////////////////////////////////////////////////////////////////
1301 /// Initialize a TClass object. This object contains the full dictionary
1302 /// of a class. It has list to baseclasses, datamembers and methods.
1303 
1304 void TClass::Init(const char *name, Version_t cversion,
1305  const type_info *typeinfo, TVirtualIsAProxy *isa,
1306  const char *dfil, const char *ifil, Int_t dl, Int_t il,
1307  ClassInfo_t *givenInfo,
1308  Bool_t silent)
1309 {
1310  if (!gROOT)
1311  ::Fatal("TClass::TClass", "ROOT system not initialized");
1312 
1313  // Always strip the default STL template arguments (from any template argument or the class name)
1315  fClassVersion = cversion;
1316  fDeclFileName = dfil ? dfil : "";
1317  fImplFileName = ifil ? ifil : "";
1318  fDeclFileLine = dl;
1319  fImplFileLine = il;
1320  fTypeInfo = typeinfo;
1321  fIsA = isa;
1322  if ( fIsA ) fIsA->SetClass(this);
1323  // See also TCling::GenerateTClass() which will update fClassVersion after creation!
1324  fStreamerInfo = new TObjArray(fClassVersion+2+10,-1); // +10 to read new data by old
1325  fProperty = -1;
1326  fClassProperty = 0;
1327 
1329 
1330  TClass *oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(fName.Data());
1331 
1333 
1334  if (oldcl && oldcl->TestBit(kLoading)) {
1335  // Do not recreate a class while it is already being created!
1336 
1337  // We can no longer reproduce this case, to check whether we are, we use
1338  // this code:
1339  // Fatal("Init","A bad replacement for %s was requested\n",name);
1340  return;
1341  }
1342 
1343  TClass **persistentRef = 0;
1344  if (oldcl) {
1345 
1346  persistentRef = oldcl->fPersistentRef.exchange(0);
1347 
1348  // The code from here is also in ForceReload.
1349  TClass::RemoveClass(oldcl);
1350  // move the StreamerInfo immediately so that there are
1351  // properly updated!
1352 
1353  if (oldcl->CanIgnoreTObjectStreamer()) {
1355  }
1356  TVirtualStreamerInfo *info;
1357 
1358  TIter next(oldcl->GetStreamerInfos());
1359  while ((info = (TVirtualStreamerInfo*)next())) {
1360  // We need to force a call to BuildOld
1361  info->Clear("build");
1362  info->SetClass(this);
1364  }
1365  oldcl->fStreamerInfo->Clear();
1366  // The code diverges here from ForceReload.
1367 
1368  // Move the Schema Rules too.
1369  fSchemaRules = oldcl->fSchemaRules;
1370  oldcl->fSchemaRules = 0;
1371  }
1372 
1373  SetBit(kLoading);
1374  // Advertise ourself as the loading class for this class name
1375  TClass::AddClass(this);
1376 
1378 
1379  if (!gInterpreter) {
1380  ::Fatal("TClass::Init", "gInterpreter not initialized");
1381  }
1382 
1383  if (givenInfo) {
1384  if (!gInterpreter->ClassInfo_IsValid(givenInfo) ||
1385  !(gInterpreter->ClassInfo_Property(givenInfo) & (kIsClass | kIsStruct | kIsNamespace)) ||
1386  (!gInterpreter->ClassInfo_IsLoaded(givenInfo) && (gInterpreter->ClassInfo_Property(givenInfo) & (kIsNamespace))) )
1387  {
1388  if (!TClassEdit::IsSTLCont(fName.Data())) {
1389  MakeZombie();
1390  fState = kNoInfo;
1391  TClass::RemoveClass(this);
1392  return;
1393  }
1394  }
1395  fClassInfo = gInterpreter->ClassInfo_Factory(givenInfo);
1396  }
1397  // We need to check if the class it is not fwd declared for the cases where we
1398  // created a TClass directly in the kForwardDeclared state. Indeed in those cases
1399  // fClassInfo will always be nullptr.
1400  if (fState!=kForwardDeclared && !fClassInfo) {
1401 
1402  if (fState == kHasTClassInit) {
1403  // If the TClass is being generated from a ROOT dictionary,
1404  // even though we do not seem to have a CINT dictionary for
1405  // the class, we will will try to load it anyway UNLESS
1406  // the class is an STL container (or string).
1407  // This is because we do not expect the CINT dictionary
1408  // to be present for all STL classes (and we can handle
1409  // the lack of CINT dictionary in that cases).
1410  // However, we cling the dictionary no longer carries
1411  // an instantiation with it, unless we request the loading
1412  // here *or* the user explicitly instantiate the template
1413  // we would not have a ClassInfo for the template
1414  // instantiation.
1416  // Here we check and grab the info from the rootpcm.
1418  if (proto && proto->FillTClass(this)) {
1420  }
1421  }
1422  if (!fHasRootPcmInfo && gInterpreter->CheckClassInfo(fName, /* autoload = */ kTRUE)) {
1423  gInterpreter->SetClassInfo(this); // sets fClassInfo pointer
1424  if (fClassInfo) {
1425  // This should be moved out of GetCheckSum itself however the last time
1426  // we tried this cause problem, in particular in the end-of-process operation.
1427  // fCheckSum = GetCheckSum(kLatestCheckSum);
1428  } else {
1429  if (!fClassInfo) {
1430  if (IsZombie()) {
1431  TClass::RemoveClass(this);
1432  return;
1433  }
1434  }
1435  }
1436  }
1437  }
1438  if (!silent && (!fClassInfo && !fCanLoadClassInfo) && !isStl && fName.First('@')==kNPOS &&
1440  if (fState == kHasTClassInit) {
1441  ::Error("TClass::Init", "no interpreter information for class %s is available even though it has a TClass initialization routine.", fName.Data());
1442  } else {
1443  // In this case we initialised this TClass instance starting from the fwd declared state
1444  // and we know we have no dictionary: no need to warn
1445  ::Warning("TClass::Init", "no dictionary for class %s is available", fName.Data());
1446  }
1447  }
1448 
1449  fgClassCount++;
1451 
1452  // Make the typedef-expanded -> original hash table entries.
1453  // There may be several entries for any given key.
1454  // We only make entries if the typedef-expanded name
1455  // is different from the original name.
1456  TString resolvedThis;
1457  if (!givenInfo && strchr (name, '<')) {
1458  if ( fName != name) {
1459  if (!fgClassTypedefHash) {
1460  fgClassTypedefHash = new THashTable (100, 5);
1462  }
1463 
1464  fgClassTypedefHash->Add (new TNameMapNode (name, fName));
1466 
1467  }
1468  resolvedThis = TClassEdit::ResolveTypedef (name, kTRUE);
1469  if (resolvedThis != name) {
1470  if (!fgClassTypedefHash) {
1471  fgClassTypedefHash = new THashTable (100, 5);
1473  }
1474 
1475  fgClassTypedefHash->Add (new TNameMapNode (resolvedThis, fName));
1477  }
1478 
1479  }
1480 
1481  //In case a class with the same name had been created by TVirtualStreamerInfo
1482  //we must delete the old class, importing only the StreamerInfo structure
1483  //from the old dummy class.
1484  if (oldcl) {
1485 
1486  oldcl->ReplaceWith(this);
1487  delete oldcl;
1488 
1489  } else if (!givenInfo && resolvedThis.Length() > 0 && fgClassTypedefHash) {
1490 
1491  // Check for existing equivalent.
1492 
1493  if (resolvedThis != fName) {
1494  oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(resolvedThis);
1495  if (oldcl && oldcl != this) {
1496  persistentRef = oldcl->fPersistentRef.exchange(0);
1497  ForceReload (oldcl);
1498  }
1499  }
1500  TIter next( fgClassTypedefHash->GetListForObject(resolvedThis) );
1501  while ( TNameMapNode* htmp = static_cast<TNameMapNode*> (next()) ) {
1502  if (resolvedThis != htmp->String()) continue;
1503  oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(htmp->fOrigName); // gROOT->GetClass (htmp->fOrigName, kFALSE);
1504  if (oldcl && oldcl != this) {
1505  persistentRef = oldcl->fPersistentRef.exchange(0);
1506  ForceReload (oldcl);
1507  }
1508  }
1509  }
1510  if (fClassInfo) {
1512  if ( fDeclFileName == 0 || fDeclFileName[0] == '\0' ) {
1513  fDeclFileName = gInterpreter->ClassInfo_FileName( fClassInfo );
1514  // Missing interface:
1515  // fDeclFileLine = gInterpreter->ClassInfo_FileLine( fClassInfo );
1516 
1517  // But really do not want to set ImplFileLine as it is currently the
1518  // marker of being 'loaded' or not (reminder loaded == has a TClass bootstrap).
1519  }
1520  }
1521 
1522  if (persistentRef) {
1523  fPersistentRef = persistentRef;
1524  } else {
1525  fPersistentRef = new TClass*;
1526  }
1527  *fPersistentRef = this;
1528 
1529  if ( isStl || !strncmp(GetName(),"stdext::hash_",13) || !strncmp(GetName(),"__gnu_cxx::hash_",16) ) {
1530  if (fState != kHasTClassInit) {
1531  // If we have a TClass compiled initialization, we can safely assume that
1532  // there will also be a collection proxy.
1534  if (fCollectionProxy) {
1536 
1537  // Numeric Collections have implicit conversions:
1539 
1540  } else if (!silent) {
1541  Warning("Init","Collection proxy for %s was not properly initialized!",GetName());
1542  }
1543  if (fStreamer==0) {
1545  }
1546  }
1547  } else if (!strncmp(GetName(),"std::pair<",10) || !strncmp(GetName(),"pair<",5) ) {
1548  // std::pairs have implicit conversions
1550  }
1551 
1552  ResetBit(kLoading);
1553 }
1554 
1555 ////////////////////////////////////////////////////////////////////////////////
1556 /// TClass dtor. Deletes all list that might have been created.
1557 
1559 {
1561 
1562  // Remove from the typedef hashtables.
1564  TString resolvedThis = TClassEdit::ResolveTypedef (GetName(), kTRUE);
1565  TIter next (fgClassTypedefHash->GetListForObject (resolvedThis));
1566  while ( TNameMapNode* htmp = static_cast<TNameMapNode*> (next()) ) {
1567  if (resolvedThis == htmp->String() && htmp->fOrigName == GetName()) {
1568  fgClassTypedefHash->Remove (htmp);
1569  delete htmp;
1570  break;
1571  }
1572  }
1573  }
1574 
1575  // Not owning lists, don't call Delete()
1576  // But this still need to be done first because the TList destructor
1577  // does access the object contained (via GetObject()->TestBit(kCanDelete))
1578  delete fStreamer; fStreamer =0;
1579  delete fAllPubData; fAllPubData =0;
1580  delete fAllPubMethod; fAllPubMethod=0;
1581 
1582  delete fPersistentRef.load();
1583 
1584  if (fBase)
1585  fBase->Delete();
1586  delete fBase; fBase=0;
1587 
1588  if (fData)
1589  fData->Delete();
1590  delete fData; fData = 0;
1591 
1592  if (fEnums.load())
1593  (*fEnums).Delete();
1594  delete fEnums.load(); fEnums = 0;
1595 
1596  if (fFuncTemplate)
1597  fFuncTemplate->Delete();
1598  delete fFuncTemplate; fFuncTemplate = 0;
1599 
1600  if (fMethod.load())
1601  (*fMethod).Delete();
1602  delete fMethod.load(); fMethod=0;
1603 
1604  if (fRealData)
1605  fRealData->Delete();
1606  delete fRealData; fRealData=0;
1607 
1608  if (fStreamerInfo)
1609  fStreamerInfo->Delete();
1610  delete fStreamerInfo; fStreamerInfo = nullptr;
1611 
1612  if (fDeclFileLine >= -1)
1613  TClass::RemoveClass(this);
1614 
1616  fClassInfo=0;
1617 
1618  if (fClassMenuList)
1620  delete fClassMenuList; fClassMenuList=0;
1621 
1623 
1624  if ( fIsA ) delete fIsA;
1625 
1626  if ( fRefProxy ) fRefProxy->Release();
1627  fRefProxy = 0;
1628 
1629  delete fStreamer;
1630  delete fCollectionProxy;
1631  delete fIsAMethod.load();
1632  delete fSchemaRules;
1633  if (fConversionStreamerInfo.load()) {
1634  std::map<std::string, TObjArray*>::iterator it;
1635  std::map<std::string, TObjArray*>::iterator end = (*fConversionStreamerInfo).end();
1636  for( it = (*fConversionStreamerInfo).begin(); it != end; ++it ) {
1637  delete it->second;
1638  }
1639  delete fConversionStreamerInfo.load();
1640  }
1641 }
1642 
1643 ////////////////////////////////////////////////////////////////////////////////
1644 
1645 namespace {
1646  Int_t ReadRulesContent(FILE *f)
1647  {
1648  // Read a class.rules file which contains one rule per line with comment
1649  // starting with a #
1650  // Returns the number of rules loaded.
1651  // Returns -1 in case of error.
1652 
1653  R__ASSERT(f!=0);
1654  TString rule(1024);
1655  int c, state = 0;
1656  Int_t count = 0;
1657 
1658  while ((c = fgetc(f)) != EOF) {
1659  if (c == 13) // ignore CR
1660  continue;
1661  if (c == '\n') {
1662  if (state != 3) {
1663  state = 0;
1664  if (rule.Length() > 0) {
1665  if (TClass::AddRule(rule)) {
1666  ++count;
1667  }
1668  rule.Clear();
1669  }
1670  }
1671  continue;
1672  }
1673  switch (state) {
1674  case 0: // start of line
1675  switch (c) {
1676  case ' ':
1677  case '\t':
1678  break;
1679  case '#':
1680  state = 1;
1681  break;
1682  default:
1683  state = 2;
1684  break;
1685  }
1686  break;
1687 
1688  case 1: // comment
1689  break;
1690 
1691  case 2: // rule
1692  switch (c) {
1693  case '\\':
1694  state = 3; // Continuation request
1695  default:
1696  break;
1697  }
1698  break;
1699  }
1700  switch (state) {
1701  case 2:
1702  rule.Append(c);
1703  break;
1704  }
1705  }
1706  return count;
1707  }
1708 }
1709 
1710 ////////////////////////////////////////////////////////////////////////////////
1711 /// Read the class.rules files from the default location:.
1712 /// $ROOTSYS/etc/class.rules (or ROOTETCDIR/class.rules)
1713 
1715 {
1716  static const char *suffix = "class.rules";
1717  TString sname = suffix;
1718 #ifdef ROOTETCDIR
1719  gSystem->PrependPathName(ROOTETCDIR, sname);
1720 #else
1721  TString etc = gRootDir;
1722 #ifdef WIN32
1723  etc += "\\etc";
1724 #else
1725  etc += "/etc";
1726 #endif
1727  gSystem->PrependPathName(etc, sname);
1728 #endif
1729 
1730  Int_t res = -1;
1731 
1732  FILE * f = fopen(sname,"r");
1733  if (f != 0) {
1734  res = ReadRulesContent(f);
1735  fclose(f);
1736  }
1737  return res;
1738 }
1739 
1740 ////////////////////////////////////////////////////////////////////////////////
1741 /// Read a class.rules file which contains one rule per line with comment
1742 /// starting with a #
1743 /// - Returns the number of rules loaded.
1744 /// - Returns -1 in case of error.
1745 
1747 {
1748  if (!filename || !filename[0]) {
1749  ::Error("TClass::ReadRules", "no file name specified");
1750  return -1;
1751  }
1752 
1753  FILE * f = fopen(filename,"r");
1754  if (f == 0) {
1755  ::Error("TClass::ReadRules","Failed to open %s\n",filename);
1756  return -1;
1757  }
1758  Int_t count = ReadRulesContent(f);
1759 
1760  fclose(f);
1761  return count;
1762 
1763 }
1764 
1765 ////////////////////////////////////////////////////////////////////////////////
1766 /// Add a schema evolution customization rule.
1767 /// The syntax of the rule can be either the short form:
1768 /// ~~~ {.cpp}
1769 /// [type=Read] classname membername [attributes=... ] [version=[...] ] [checksum=[...] ] [oldtype=...] [code={...}]
1770 /// ~~~
1771 /// or the long form
1772 /// ~~~ {.cpp}
1773 /// [type=Read] sourceClass=classname [targetclass=newClassname] [ source="type membername; [type2 membername2]" ]
1774 /// [target="membername3;membername4"] [attributes=... ] [version=...] [checksum=...] [code={...}|functionname]
1775 /// ~~~
1776 ///
1777 /// For example to set HepMC::GenVertex::m_event to _not_ owned the object it is pointing to:
1778 /// HepMC::GenVertex m_event attributes=NotOwner
1779 ///
1780 /// Semantic of the tags:
1781 /// - type : the type of the rule, valid values: Read, ReadRaw, Write, WriteRaw, the default is 'Read'.
1782 /// - sourceClass : the name of the class as it is on the rule file
1783 /// - targetClass : the name of the class as it is in the current code ; defaults to the value of sourceClass
1784 /// - source : the types and names of the data members from the class on file that are needed, the list is separated by semi-colons ';'
1785 /// - oldtype: in the short form only, indicates the type on disk of the data member.
1786 /// - target : the names of the data members updated by this rule, the list is separated by semi-colons ';'
1787 /// - attributes : list of possible qualifiers among: Owner, NotOwner
1788 /// - version : list of the version of the class layout that this rule applies to. The syntax can be [1,4,5] or [2-] or [1-3] or [-3]
1789 /// - checksum : comma delimited list of the checksums of the class layout that this rule applies to.
1790 /// - code={...} : code to be executed for the rule or name of the function implementing it.
1791 
1792 Bool_t TClass::AddRule( const char *rule )
1793 {
1794  ROOT::TSchemaRule *ruleobj = new ROOT::TSchemaRule();
1795  if (! ruleobj->SetFromRule( rule ) ) {
1796  delete ruleobj;
1797  return kFALSE;
1798  }
1799 
1801 
1802  TClass *cl = TClass::GetClass( ruleobj->GetTargetClass() );
1803  if (!cl) {
1804  // Create an empty emulated class for now.
1805  cl = gInterpreter->GenerateTClass(ruleobj->GetTargetClass(), /* emulation = */ kTRUE, /*silent = */ kTRUE);
1806  }
1808 
1809  TString errmsg;
1810  if( !rset->AddRule( ruleobj, ROOT::Detail::TSchemaRuleSet::kCheckConflict, &errmsg ) ) {
1811  ::Warning( "TClass::AddRule", "The rule for class: \"%s\": version, \"%s\" and data members: \"%s\" has been skipped because it conflicts with one of the other rules (%s).",
1812  ruleobj->GetTargetClass(), ruleobj->GetVersion(), ruleobj->GetTargetString(), errmsg.Data() );
1813  delete ruleobj;
1814  return kFALSE;
1815  }
1816  return kTRUE;
1817 }
1818 
1819 ////////////////////////////////////////////////////////////////////////////////
1820 /// Adopt a new set of Data Model Evolution rules.
1821 
1823 {
1825 
1826  delete fSchemaRules;
1827  fSchemaRules = rules;
1828  fSchemaRules->SetClass( this );
1829 }
1830 
1831 ////////////////////////////////////////////////////////////////////////////////
1832 /// Return the set of the schema rules if any.
1833 
1835 {
1836  return fSchemaRules;
1837 }
1838 
1839 ////////////////////////////////////////////////////////////////////////////////
1840 /// Return the set of the schema rules if any.
1841 /// If create is true, create an empty set
1842 
1844 {
1845  if (create && fSchemaRules == 0) {
1847  fSchemaRules->SetClass( this );
1848  }
1849  return fSchemaRules;
1850 }
1851 
1852 ////////////////////////////////////////////////////////////////////////////////
1853 
1854 void TClass::AddImplFile(const char* filename, int line) {
1855  // Currently reset the implementation file and line.
1856  // In the close future, it will actually add this file and line
1857  // to a "list" of implementation files.
1858 
1860  fImplFileLine = line;
1861 }
1862 
1863 ////////////////////////////////////////////////////////////////////////////////
1864 /// Browse external object inherited from TObject.
1865 /// It passes through inheritance tree and calls TBrowser::Add
1866 /// in appropriate cases. Static function.
1867 
1869 {
1870  if (!obj) return 0;
1871 
1872  TAutoInspector insp(b);
1873  obj->ShowMembers(insp);
1874  return insp.fCount;
1875 }
1876 
1877 ////////////////////////////////////////////////////////////////////////////////
1878 /// Browse objects of of the class described by this TClass object.
1879 
1880 Int_t TClass::Browse(void *obj, TBrowser *b) const
1881 {
1882  if (!obj) return 0;
1883 
1884  TClass *actual = GetActualClass(obj);
1885  if (IsTObject()) {
1886  // Call TObject::Browse.
1887 
1888  if (!fIsOffsetStreamerSet) {
1890  }
1891  TObject* realTObject = (TObject*)((size_t)obj + fOffsetStreamer);
1892  realTObject->Browse(b);
1893  return 1;
1894  } else if (actual != this) {
1895  return actual->Browse(obj, b);
1896  } else if (GetCollectionProxy()) {
1897 
1898  // do something useful.
1899 
1900  } else {
1901  TAutoInspector insp(b);
1902  CallShowMembers(obj,insp,kFALSE);
1903  return insp.fCount;
1904  }
1905 
1906  return 0;
1907 }
1908 
1909 ////////////////////////////////////////////////////////////////////////////////
1910 /// This method is called by a browser to get the class information.
1911 
1913 {
1914  if (!HasInterpreterInfo()) return;
1915 
1916  if (b) {
1917  if (!fRealData) BuildRealData();
1918 
1919  b->Add(GetListOfDataMembers(), "Data Members");
1920  b->Add(GetListOfRealData(), "Real Data Members");
1921  b->Add(GetListOfMethods(), "Methods");
1922  b->Add(GetListOfBases(), "Base Classes");
1923  }
1924 }
1925 
1926 ////////////////////////////////////////////////////////////////////////////////
1927 /// Build a full list of persistent data members.
1928 /// Scans the list of all data members in the class itself and also
1929 /// in all base classes. For each persistent data member, inserts a
1930 /// TRealData object in the list fRealData.
1931 ///
1932 
1933 void TClass::BuildRealData(void* pointer, Bool_t isTransient)
1934 {
1935 
1937 
1938  // Only do this once.
1939  if (fRealData) {
1940  return;
1941  }
1942 
1943  if (fClassVersion == 0) {
1944  isTransient = kTRUE;
1945  }
1946 
1947  // When called via TMapFile (e.g. Update()) make sure that the dictionary
1948  // gets allocated on the heap and not in the mapped file.
1949  TMmallocDescTemp setreset;
1950 
1951  // Handle emulated classes and STL containers specially.
1953  // We are an emulated class or an STL container.
1954  fRealData = new TList;
1955  BuildEmulatedRealData("", 0, this);
1956  return;
1957  }
1958 
1959  // return early on string
1960  static TClassRef clRefString("std::string");
1961  if (clRefString == this) {
1962  return;
1963  }
1964 
1965  // Complain about stl classes ending up here (unique_ptr etc) - except for
1966  // pair where we will build .first, .second just fine
1967  // and those for which the user explicitly requested a dictionary.
1968  if (!isTransient && GetState() != kHasTClassInit
1970  && strncmp(GetName(), "pair<", 5) != 0) {
1971  Error("BuildRealData", "Inspection for %s not supported!", GetName());
1972  }
1973 
1974  // The following statement will recursively call
1975  // all the subclasses of this class.
1976  fRealData = new TList;
1977  TBuildRealData brd(pointer, this);
1978 
1979  // CallShowMember will force a call to InheritsFrom, which indirectly
1980  // calls TClass::GetClass. It forces the loading of new typedefs in
1981  // case some of them were not yet loaded.
1982  if ( ! CallShowMembers(pointer, brd, isTransient) ) {
1983  if ( isTransient ) {
1984  // This is a transient data member, so it is probably fine to not have
1985  // access to its content. However let's no mark it as definitively setup,
1986  // since another class might use this class for a persistent data member and
1987  // in this case we really want the error message.
1988  delete fRealData;
1989  fRealData = 0;
1990  } else {
1991  Error("BuildRealData", "Cannot find any ShowMembers function for %s!", GetName());
1992  }
1993  }
1994 
1995  // Take this opportunity to build the real data for base classes.
1996  // In case one base class is abstract, it would not be possible later
1997  // to create the list of real data for this abstract class.
1998  TBaseClass* base = 0;
2000  while ((base = (TBaseClass*) next())) {
2001  if (base->IsSTLContainer()) {
2002  continue;
2003  }
2004  TClass* c = base->GetClassPointer();
2005  if (c) {
2006  c->BuildRealData(0, isTransient);
2007  }
2008  }
2009 }
2010 
2011 ////////////////////////////////////////////////////////////////////////////////
2012 /// Build the list of real data for an emulated class
2013 
2014 void TClass::BuildEmulatedRealData(const char *name, Long_t offset, TClass *cl)
2015 {
2017 
2018  TVirtualStreamerInfo *info;
2019  if (Property() & kIsAbstract) {
2021  } else {
2022  info = GetStreamerInfo();
2023  }
2024  if (!info) {
2025  // This class is abstract, but we don't yet have a SteamerInfo for it ...
2026  Error("BuildEmulatedRealData","Missing StreamerInfo for %s",GetName());
2027  // Humm .. no information ... let's bail out
2028  return;
2029  }
2030 
2031  TIter next(info->GetElements());
2032  TStreamerElement *element;
2033  while ((element = (TStreamerElement*)next())) {
2034  Int_t etype = element->GetType();
2035  Long_t eoffset = element->GetOffset();
2036  TClass *cle = element->GetClassPointer();
2037  if (element->IsBase() || etype == TVirtualStreamerInfo::kBase) {
2038  //base class are skipped in this loop, they will be added at the end.
2039  continue;
2040  } else if (etype == TVirtualStreamerInfo::kTObject ||
2041  etype == TVirtualStreamerInfo::kTNamed ||
2042  etype == TVirtualStreamerInfo::kObject ||
2043  etype == TVirtualStreamerInfo::kAny) {
2044  //member class
2045  TString rdname; rdname.Form("%s%s",name,element->GetFullName());
2046  TRealData *rd = new TRealData(rdname,offset+eoffset,0);
2047  if (gDebug > 0) printf(" Class: %s, adding TRealData=%s, offset=%ld\n",cl->GetName(),rd->GetName(),rd->GetThisOffset());
2048  cl->GetListOfRealData()->Add(rd);
2049  // Now we a dot
2050  rdname.Form("%s%s.",name,element->GetFullName());
2051  if (cle) cle->BuildEmulatedRealData(rdname,offset+eoffset,cl);
2052  } else {
2053  //others
2054  TString rdname; rdname.Form("%s%s",name,element->GetFullName());
2055  TRealData *rd = new TRealData(rdname,offset+eoffset,0);
2056  if (gDebug > 0) printf(" Class: %s, adding TRealData=%s, offset=%ld\n",cl->GetName(),rd->GetName(),rd->GetThisOffset());
2057  cl->GetListOfRealData()->Add(rd);
2058  }
2059  //if (fClassInfo==0 && element->IsBase()) {
2060  // if (fBase==0) fBase = new TList;
2061  // TClass *base = element->GetClassPointer();
2062  // fBase->Add(new TBaseClass(this, cl, eoffset));
2063  //}
2064  }
2065  // The base classes must added last on the list of real data (to help with ambiguous data member names)
2066  next.Reset();
2067  while ((element = (TStreamerElement*)next())) {
2068  Int_t etype = element->GetType();
2069  if (element->IsBase() || etype == TVirtualStreamerInfo::kBase) {
2070  //base class
2071  Long_t eoffset = element->GetOffset();
2072  TClass *cle = element->GetClassPointer();
2073  if (cle) cle->BuildEmulatedRealData(name,offset+eoffset,cl);
2074  }
2075  }
2076 }
2077 
2078 
2079 ////////////////////////////////////////////////////////////////////////////////
2080 /// Calculate the offset between an object of this class to
2081 /// its base class TObject. The pointer can be adjusted by
2082 /// that offset to access any virtual method of TObject like
2083 /// Streamer() and ShowMembers().
2084 
2086 {
2089  // When called via TMapFile (e.g. Update()) make sure that the dictionary
2090  // gets allocated on the heap and not in the mapped file.
2091 
2092  TMmallocDescTemp setreset;
2094  if (fStreamerType == kTObject) {
2096  }
2098  }
2099 }
2100 
2101 
2102 ////////////////////////////////////////////////////////////////////////////////
2103 /// Call ShowMembers() on the obj of this class type, passing insp and parent.
2104 /// isATObject is -1 if unknown, 0 if it is not a TObject, and 1 if it is a TObject.
2105 /// The function returns whether it was able to call ShowMembers().
2106 
2107 Bool_t TClass::CallShowMembers(const void* obj, TMemberInspector &insp, Bool_t isTransient) const
2108 {
2109  if (fShowMembers) {
2110  // This should always works since 'pointer' should be pointing
2111  // to an object of the actual type of this TClass object.
2112  fShowMembers(obj, insp, isTransient);
2113  return kTRUE;
2114  } else {
2115 
2117  if (fClassInfo) {
2118 
2119  if (strcmp(GetName(), "string") == 0) {
2120  // For std::string we know that we do not have a ShowMembers
2121  // function and that it's okay.
2122  return kTRUE;
2123  }
2124  // Since we do have some dictionary information, let's
2125  // call the interpreter's ShowMember.
2126  // This works with Cling to support interpreted classes.
2127  gInterpreter->InspectMembers(insp, obj, this, isTransient);
2128  return kTRUE;
2129 
2130  } else if (TVirtualStreamerInfo* sinfo = GetStreamerInfo()) {
2131  sinfo->CallShowMembers(obj, insp, isTransient);
2132  return kTRUE;
2133  } // isATObject
2134  } // fShowMembers is set
2135 
2136  return kFALSE;
2137 }
2138 
2139 ////////////////////////////////////////////////////////////////////////////////
2140 /// Do a ShowMembers() traversal of all members and base classes' members
2141 /// using the reflection information from the interpreter. Works also for
2142 /// interpreted objects.
2143 
2144 void TClass::InterpretedShowMembers(void* obj, TMemberInspector &insp, Bool_t isTransient)
2145 {
2146  return gInterpreter->InspectMembers(insp, obj, this, isTransient);
2147 }
2148 
2149 ////////////////////////////////////////////////////////////////////////////////
2150 /// Return true if the data member of this TClass can be saved separately.
2151 
2153 {
2154  // Note: add the possibility to set it for the class and the derived class.
2155  // save the info in TVirtualStreamerInfo
2156  // deal with the info in MakeProject
2157  if (fCanSplit >= 0) {
2158  // The user explicitly set the value
2159  return fCanSplit != 0;
2160  }
2161 
2163  TClass *This = const_cast<TClass*>(this);
2164 
2165  if (this == TObject::Class()) { This->fCanSplit = 1; return kTRUE; }
2166  if (fName == "TClonesArray") { This->fCanSplit = 1; return kTRUE; }
2167  if (fRefProxy) { This->fCanSplit = 0; return kFALSE; }
2168  if (fName.BeginsWith("TVectorT<")) { This->fCanSplit = 0; return kFALSE; }
2169  if (fName.BeginsWith("TMatrixT<")) { This->fCanSplit = 0; return kFALSE; }
2170  if (fName == "string") { This->fCanSplit = 0; return kFALSE; }
2171  if (fName == "std::string") { This->fCanSplit = 0; return kFALSE; }
2172 
2173  if (GetCollectionProxy()!=0) {
2174  // For STL collection we need to look inside.
2175 
2176  // However we do not split collections of collections
2177  // nor collections of strings
2178  // nor collections of pointers (unless explicit request (see TBranchSTL)).
2179 
2180  if (GetCollectionProxy()->HasPointers()) { This->fCanSplit = 0; return kFALSE; }
2181 
2182  TClass *valueClass = GetCollectionProxy()->GetValueClass();
2183  if (valueClass == 0) { This->fCanSplit = 0; return kFALSE; }
2184  static TClassRef stdStringClass("std::string");
2185  if (valueClass==TString::Class() || valueClass==stdStringClass)
2186  { This->fCanSplit = 0; return kFALSE; }
2187  if (!valueClass->CanSplit()) { This->fCanSplit = 0; return kFALSE; }
2188  if (valueClass->GetCollectionProxy() != 0) { This->fCanSplit = 0; return kFALSE; }
2189 
2190  Int_t stl = -TClassEdit::IsSTLCont(GetName(), 0);
2191  if ((stl==ROOT::kSTLmap || stl==ROOT::kSTLmultimap)
2192  && !valueClass->HasDataMemberInfo()==0)
2193  {
2194  This->fCanSplit = 0;
2195  return kFALSE;
2196  }
2197 
2198  This->fCanSplit = 1;
2199  return kTRUE;
2200 
2201  }
2202 
2203  if (GetStreamer()!=0) {
2204 
2205  // We have an external custom streamer provided by the user, we must not
2206  // split it.
2207  This->fCanSplit = 0;
2208  return kFALSE;
2209 
2210  } else if ( TestBit(TClass::kHasCustomStreamerMember) ) {
2211 
2212  // We have a custom member function streamer or
2213  // an older (not StreamerInfo based) automatic streamer.
2214  This->fCanSplit = 0;
2215  return kFALSE;
2216  }
2217 
2218  if (Size()==1) {
2219  // 'Empty' class there is nothing to split!.
2220  This->fCanSplit = 0;
2221  return kFALSE;
2222  }
2223 
2224  // Calls to InheritsFrom for STL collection might cause unnecessary autoparsing.
2225  if (InheritsFrom("TRef")) { This->fCanSplit = 0; return kFALSE; }
2226  if (InheritsFrom("TRefArray")) { This->fCanSplit = 0; return kFALSE; }
2227  if (InheritsFrom("TArray")) { This->fCanSplit = 0; return kFALSE; }
2228  if (InheritsFrom("TCollection") && !InheritsFrom("TClonesArray")) { This->fCanSplit = 0; return kFALSE; }
2229  if (InheritsFrom("TTree")) { This->fCanSplit = 0; return kFALSE; }
2230 
2231  TClass *ncThis = const_cast<TClass*>(this);
2232  TIter nextb(ncThis->GetListOfBases());
2233  TBaseClass *base;
2234  while((base = (TBaseClass*)nextb())) {
2235  if (!base->GetClassPointer()) { This->fCanSplit = 0; return kFALSE; }
2236  }
2237 
2238  This->fCanSplit = 1;
2239  return kTRUE;
2240 }
2241 
2242 ////////////////////////////////////////////////////////////////////////////////
2243 /// Return the C++ property of this class, eg. is abstract, has virtual base
2244 /// class, see EClassProperty in TDictionary.h
2245 
2247 {
2248  if (fProperty == -1) Property();
2249  return fClassProperty;
2250 }
2251 
2252 ////////////////////////////////////////////////////////////////////////////////
2253 /// Create a Clone of this TClass object using a different name but using the same 'dictionary'.
2254 /// This effectively creates a hard alias for the class name.
2255 
2256 TObject *TClass::Clone(const char *new_name) const
2257 {
2258  if (new_name == 0 || new_name[0]=='\0' || fName == new_name) {
2259  Error("Clone","The name of the class must be changed when cloning a TClass object.");
2260  return 0;
2261  }
2262 
2263  // Need to lock access to TROOT::GetListOfClasses so the cloning happens atomically
2265  // Temporarily remove the original from the list of classes.
2266  TClass::RemoveClass(const_cast<TClass*>(this));
2267 
2268  TClass *copy;
2269  if (fTypeInfo) {
2270  copy = new TClass(GetName(),
2271  fClassVersion,
2272  *fTypeInfo,
2273  new TIsAProxy(*fTypeInfo),
2274  GetDeclFileName(),
2275  GetImplFileName(),
2276  GetDeclFileLine(),
2277  GetImplFileLine());
2278  } else {
2279  copy = new TClass(GetName(),
2280  fClassVersion,
2281  GetDeclFileName(),
2282  GetImplFileName(),
2283  GetDeclFileLine(),
2284  GetImplFileLine());
2285  }
2286  copy->fShowMembers = fShowMembers;
2287  // Remove the copy before renaming it
2288  TClass::RemoveClass(copy);
2289  copy->fName = new_name;
2290  TClass::AddClass(copy);
2291 
2292  copy->SetNew(fNew);
2293  copy->SetNewArray(fNewArray);
2294  copy->SetDelete(fDelete);
2296  copy->SetDestructor(fDestructor);
2298  copy->fStreamerFunc = fStreamerFunc;
2300  if (fStreamer) {
2301  copy->AdoptStreamer(fStreamer->Generate());
2302  }
2303  // If IsZombie is true, something went wrong and we will not be
2304  // able to properly copy the collection proxy
2305  if (fCollectionProxy && !copy->IsZombie()) {
2307  }
2308  copy->SetClassSize(fSizeof);
2309  if (fRefProxy) {
2310  copy->AdoptReferenceProxy( fRefProxy->Clone() );
2311  }
2312  TClass::AddClass(const_cast<TClass*>(this));
2313  return copy;
2314 }
2315 
2316 ////////////////////////////////////////////////////////////////////////////////
2317 /// Copy the argument.
2318 
2320 {
2321 // // This code was used too quickly test the STL Emulation layer
2322 // Int_t k = TClassEdit::IsSTLCont(GetName());
2323 // if (k==1||k==-1) return;
2324 
2325  delete fCollectionProxy;
2326  fCollectionProxy = orig.Generate();
2327 }
2328 
2329 ////////////////////////////////////////////////////////////////////////////////
2330 /// Draw detailed class inheritance structure.
2331 /// If a class B inherits from a class A, the description of B is drawn
2332 /// on the right side of the description of A.
2333 /// Member functions overridden by B are shown in class A with a blue line
2334 /// erasing the corresponding member function
2335 
2336 void TClass::Draw(Option_t *option)
2337 {
2338  if (!HasInterpreterInfo()) return;
2339 
2340  TVirtualPad *padsav = gPad;
2341 
2342  // Should we create a new canvas?
2343  TString opt=option;
2344  if (!padsav || !opt.Contains("same")) {
2345  TVirtualPad *padclass = (TVirtualPad*)(gROOT->GetListOfCanvases())->FindObject("R__class");
2346  if (!padclass) {
2347  gROOT->ProcessLine("new TCanvas(\"R__class\",\"class\",20,20,1000,750);");
2348  } else {
2349  padclass->cd();
2350  }
2351  }
2352 
2353  if (gPad) gPad->DrawClassObject(this,option);
2354 
2355  if (padsav) padsav->cd();
2356 }
2357 
2358 ////////////////////////////////////////////////////////////////////////////////
2359 /// Dump contents of object on stdout.
2360 /// Using the information in the object dictionary
2361 /// each data member is interpreted.
2362 /// If a data member is a pointer, the pointer value is printed
2363 /// 'obj' is assume to point to an object of the class describe by this TClass
2364 ///
2365 /// The following output is the Dump of a TArrow object:
2366 /// ~~~ {.cpp}
2367 /// fAngle 0 Arrow opening angle (degrees)
2368 /// fArrowSize 0.2 Arrow Size
2369 /// fOption.*fData
2370 /// fX1 0.1 X of 1st point
2371 /// fY1 0.15 Y of 1st point
2372 /// fX2 0.67 X of 2nd point
2373 /// fY2 0.83 Y of 2nd point
2374 /// fUniqueID 0 object unique identifier
2375 /// fBits 50331648 bit field status word
2376 /// fLineColor 1 line color
2377 /// fLineStyle 1 line style
2378 /// fLineWidth 1 line width
2379 /// fFillColor 19 fill area color
2380 /// fFillStyle 1001 fill area style
2381 /// ~~~
2382 ///
2383 /// If noAddr is true, printout of all pointer values is skipped.
2384 
2385 void TClass::Dump(const void *obj, Bool_t noAddr /*=kFALSE*/) const
2386 {
2387 
2388  Long_t prObj = noAddr ? 0 : (Long_t)obj;
2389  if (IsTObject()) {
2390  if (!fIsOffsetStreamerSet) {
2392  }
2393  TObject *tobj = (TObject*)((Long_t)obj + fOffsetStreamer);
2394 
2395 
2396  if (sizeof(this) == 4)
2397  Printf("==> Dumping object at: 0x%08lx, name=%s, class=%s\n",prObj,tobj->GetName(),GetName());
2398  else
2399  Printf("==> Dumping object at: 0x%016lx, name=%s, class=%s\n",prObj,tobj->GetName(),GetName());
2400  } else {
2401 
2402  if (sizeof(this) == 4)
2403  Printf("==> Dumping object at: 0x%08lx, class=%s\n",prObj,GetName());
2404  else
2405  Printf("==> Dumping object at: 0x%016lx, class=%s\n",prObj,GetName());
2406  }
2407 
2408  TDumpMembers dm(noAddr);
2409  if (!CallShowMembers(obj, dm, kFALSE)) {
2410  Info("Dump", "No ShowMembers function, dumping disabled");
2411  }
2412 }
2413 
2414 ////////////////////////////////////////////////////////////////////////////////
2415 /// Introduce an escape character (@) in front of a special chars.
2416 /// You need to use the result immediately before it is being overwritten.
2417 
2418 char *TClass::EscapeChars(const char *text) const
2419 {
2420  static const UInt_t maxsize = 255;
2421  static char name[maxsize+2]; //One extra if last char needs to be escaped
2422 
2423  UInt_t nch = strlen(text);
2424  UInt_t icur = 0;
2425  for (UInt_t i = 0; i < nch && icur < maxsize; ++i, ++icur) {
2426  if (text[i] == '\"' || text[i] == '[' || text[i] == '~' ||
2427  text[i] == ']' || text[i] == '&' || text[i] == '#' ||
2428  text[i] == '!' || text[i] == '^' || text[i] == '<' ||
2429  text[i] == '?' || text[i] == '>') {
2430  name[icur] = '@';
2431  ++icur;
2432  }
2433  name[icur] = text[i];
2434  }
2435  name[icur] = 0;
2436  return name;
2437 }
2438 
2439 ////////////////////////////////////////////////////////////////////////////////
2440 /// Return a pointer the the real class of the object.
2441 /// This is equivalent to object->IsA() when the class has a ClassDef.
2442 /// It is REQUIRED that object is coming from a proper pointer to the
2443 /// class represented by 'this'.
2444 /// Example: Special case:
2445 /// ~~~ {.cpp}
2446 /// class MyClass : public AnotherClass, public TObject
2447 /// ~~~
2448 /// then on return, one must do:
2449 /// ~~~ {.cpp}
2450 /// TObject *obj = (TObject*)((void*)myobject)directory->Get("some object of MyClass");
2451 /// MyClass::Class()->GetActualClass(obj); // this would be wrong!!!
2452 /// ~~~
2453 /// Also if the class represented by 'this' and NONE of its parents classes
2454 /// have a virtual ptr table, the result will be 'this' and NOT the actual
2455 /// class.
2456 
2457 TClass *TClass::GetActualClass(const void *object) const
2458 {
2459  if (object==0) return (TClass*)this;
2460  if (fIsA) {
2461  return (*fIsA)(object); // ROOT::IsA((ThisClass*)object);
2462  } else if (fGlobalIsA) {
2463  return fGlobalIsA(this,object);
2464  } else {
2465  if (IsTObject()) {
2466 
2467  if (!fIsOffsetStreamerSet) {
2469  }
2470  TObject* realTObject = (TObject*)((size_t)object + fOffsetStreamer);
2471 
2472  return realTObject->IsA();
2473  }
2474 
2475  if (HasInterpreterInfo()) {
2476 
2477  TVirtualIsAProxy *isa = 0;
2479  isa = (TVirtualIsAProxy*)gROOT->ProcessLineFast(TString::Format("new ::TInstrumentedIsAProxy<%s>(0);",GetName()));
2480  }
2481  else {
2482  isa = (TVirtualIsAProxy*)gROOT->ProcessLineFast(TString::Format("new ::TIsAProxy(typeid(%s));",GetName()));
2483  }
2484  if (isa) {
2486  const_cast<TClass*>(this)->fIsA = isa;
2487  }
2488  if (fIsA) {
2489  return (*fIsA)(object); // ROOT::IsA((ThisClass*)object);
2490  }
2491  }
2493  if (sinfo) {
2494  return sinfo->GetActualClass(object);
2495  }
2496  return (TClass*)this;
2497  }
2498 }
2499 
2500 ////////////////////////////////////////////////////////////////////////////////
2501 /// Return pointer to the base class "classname". Returns 0 in case
2502 /// "classname" is not a base class. Takes care of multiple inheritance.
2503 
2504 TClass *TClass::GetBaseClass(const char *classname)
2505 {
2506  // check if class name itself is equal to classname
2507  if (strcmp(GetName(), classname) == 0) return this;
2508 
2509  if (!HasDataMemberInfo()) return 0;
2510 
2511  // Make sure we deal with possible aliases, we could also have normalized
2512  // the name.
2513  TClass *search = TClass::GetClass(classname,kTRUE,kTRUE);
2514 
2515  if (search) return GetBaseClass(search);
2516  else return 0;
2517 }
2518 
2519 ////////////////////////////////////////////////////////////////////////////////
2520 /// Return pointer to the base class "cl". Returns 0 in case "cl"
2521 /// is not a base class. Takes care of multiple inheritance.
2522 
2524 {
2525  // check if class name itself is equal to classname
2526  if (cl == this) return this;
2527 
2528  if (!HasDataMemberInfo()) return 0;
2529 
2530  TObjLink *lnk = GetListOfBases() ? fBase->FirstLink() : 0;
2531 
2532  // otherwise look at inheritance tree
2533  while (lnk) {
2534  TClass *c, *c1;
2535  TBaseClass *base = (TBaseClass*) lnk->GetObject();
2536  c = base->GetClassPointer();
2537  if (c) {
2538  if (cl == c) return c;
2539  c1 = c->GetBaseClass(cl);
2540  if (c1) return c1;
2541  }
2542  lnk = lnk->Next();
2543  }
2544  return 0;
2545 }
2546 
2547 ////////////////////////////////////////////////////////////////////////////////
2548 /// Return data member offset to the base class "cl".
2549 /// - Returns -1 in case "cl" is not a base class.
2550 /// - Returns -2 if cl is a base class, but we can't find the offset
2551 /// because it's virtual.
2552 /// Takes care of multiple inheritance.
2553 
2555 {
2556  // check if class name itself is equal to classname
2557  if (cl == this) return 0;
2558 
2559  if (!fBase) {
2561  // If the information was not provided by the root pcm files and
2562  // if we can not find the ClassInfo, we have to fall back to the
2563  // StreamerInfo
2564  if (!fClassInfo) {
2566  if (!sinfo) return -1;
2567  TStreamerElement *element;
2568  Int_t offset = 0;
2569 
2570  TObjArray &elems = *(sinfo->GetElements());
2571  Int_t size = elems.GetLast()+1;
2572  for(Int_t i=0; i<size; i++) {
2573  element = (TStreamerElement*)elems[i];
2574  if (element->IsA() == TStreamerBase::Class()) {
2575  TStreamerBase *base = (TStreamerBase*)element;
2576  TClass *baseclass = base->GetClassPointer();
2577  if (!baseclass) return -1;
2578  Int_t subOffset = baseclass->GetBaseClassOffsetRecurse(cl);
2579  if (subOffset == -2) return -2;
2580  if (subOffset != -1) return offset+subOffset;
2581  offset += baseclass->Size();
2582  }
2583  }
2584  return -1;
2585  }
2586  }
2587 
2588  TClass *c;
2589  Int_t off;
2590  TBaseClass *inh;
2591  TObjLink *lnk = 0;
2592  if (fBase==0) lnk = GetListOfBases()->FirstLink();
2593  else lnk = fBase->FirstLink();
2594 
2595  // otherwise look at inheritance tree
2596  while (lnk) {
2597  inh = (TBaseClass *)lnk->GetObject();
2598  //use option load=kFALSE to avoid a warning like:
2599  //"Warning in <TClass::TClass>: no dictionary for class TRefCnt is available"
2600  //We can not afford to not have the class if it exist, so we
2601  //use kTRUE.
2602  c = inh->GetClassPointer(kTRUE); // kFALSE);
2603  if (c) {
2604  if (cl == c) {
2605  if ((inh->Property() & kIsVirtualBase) != 0)
2606  return -2;
2607  return inh->GetDelta();
2608  }
2609  off = c->GetBaseClassOffsetRecurse(cl);
2610  if (off == -2) return -2;
2611  if (off != -1) {
2612  return off + inh->GetDelta();
2613  }
2614  }
2615  lnk = lnk->Next();
2616  }
2617  return -1;
2618 }
2619 
2620 ////////////////////////////////////////////////////////////////////////////////
2621 /// - Return data member offset to the base class "cl".
2622 /// - Returns -1 in case "cl" is not a base class.
2623 /// Takes care of multiple inheritance.
2624 
2625 Int_t TClass::GetBaseClassOffset(const TClass *toBase, void *address, bool isDerivedObject)
2626 {
2627  // Warning("GetBaseClassOffset","Requires the use of fClassInfo for %s to %s",GetName(),toBase->GetName());
2628 
2629  if (this == toBase) return 0;
2630 
2631  if ((!address /* || !has_virtual_base */) &&
2633  // At least of the ClassInfo have not been loaded in memory yet and
2634  // since there is no virtual base class (or we don't have enough so it
2635  // would not make a difference) we can use the 'static' information
2636  Int_t offset = GetBaseClassOffsetRecurse (toBase);
2637  if (offset != -2) {
2638  return offset;
2639  }
2640  return offset;
2641  }
2642 
2643  ClassInfo_t* derived = GetClassInfo();
2644  ClassInfo_t* base = toBase->GetClassInfo();
2645  if(derived && base) {
2646  return gCling->ClassInfo_GetBaseOffset(derived, base, address, isDerivedObject);
2647  }
2648  else {
2649  Int_t offset = GetBaseClassOffsetRecurse (toBase);
2650  if (offset != -2) {
2651  return offset;
2652  }
2653  }
2654  return -1;
2655 }
2656 
2657 ////////////////////////////////////////////////////////////////////////////////
2658 /// Return pointer to (base) class that contains datamember.
2659 
2660 TClass *TClass::GetBaseDataMember(const char *datamember)
2661 {
2662  if (!HasDataMemberInfo()) return 0;
2663 
2664  // Check if data member exists in class itself
2665  TDataMember *dm = GetDataMember(datamember);
2666  if (dm) return this;
2667 
2668  // if datamember not found in class, search in next base classes
2669  TBaseClass *inh;
2671  while ((inh = (TBaseClass *) next())) {
2672  TClass *c = inh->GetClassPointer();
2673  if (c) {
2674  TClass *cdm = c->GetBaseDataMember(datamember);
2675  if (cdm) return cdm;
2676  }
2677  }
2678 
2679  return 0;
2680 }
2681 
2682 namespace {
2683  // A local Helper class used to keep 2 pointer (the collection proxy
2684  // and the class streamer) in the thread local storage.
2685 
2686  struct TClassLocalStorage {
2687  TClassLocalStorage() : fCollectionProxy(0), fStreamer(0) {};
2688 
2689  TVirtualCollectionProxy *fCollectionProxy;
2690  TClassStreamer *fStreamer;
2691 
2692  static TClassLocalStorage *GetStorage(const TClass *cl)
2693  {
2694  // Return the thread storage for the TClass.
2695 
2696  void **thread_ptr = (*gThreadTsd)(0,ROOT::kClassThreadSlot);
2697  if (thread_ptr) {
2698  if (*thread_ptr==0) *thread_ptr = new TExMap();
2699  TExMap *lmap = (TExMap*)(*thread_ptr);
2700  ULong_t hash = TString::Hash(&cl, sizeof(void*));
2701  ULong_t local = 0;
2702  UInt_t slot;
2703  if ((local = (ULong_t)lmap->GetValue(hash, (Long_t)cl, slot)) != 0) {
2704  } else {
2705  local = (ULong_t) new TClassLocalStorage();
2706  lmap->AddAt(slot, hash, (Long_t)cl, local);
2707  }
2708  return (TClassLocalStorage*)local;
2709  }
2710  return 0;
2711  }
2712  };
2713 }
2714 
2715 ////////////////////////////////////////////////////////////////////////////////
2716 /// Return the 'type' of the STL the TClass is representing.
2717 /// and return ROOT::kNotSTL if it is not representing an STL collection.
2718 
2720 {
2721  auto proxy = GetCollectionProxy();
2722  if (proxy) return (ROOT::ESTLType)proxy->GetCollectionType();
2723  return ROOT::kNotSTL;
2724 }
2725 
2726 
2727 ////////////////////////////////////////////////////////////////////////////////
2728 /// Return the proxy describing the collection (if any).
2729 
2731 {
2732  // Use assert, so that this line (slow because of the TClassEdit) is completely
2733  // removed in optimized code.
2734  assert(TestBit(kLoading) || !TClassEdit::IsSTLCont(fName) || fCollectionProxy || 0 == "The TClass for the STL collection has no collection proxy!");
2735  if (gThreadTsd && fCollectionProxy) {
2736  TClassLocalStorage *local = TClassLocalStorage::GetStorage(this);
2737  if (local == 0) return fCollectionProxy;
2738  if (local->fCollectionProxy==0) local->fCollectionProxy = fCollectionProxy->Generate();
2739  return local->fCollectionProxy;
2740  }
2741  return fCollectionProxy;
2742 }
2743 
2744 ////////////////////////////////////////////////////////////////////////////////
2745 /// Return the Streamer Class allowing streaming (if any).
2746 
2748 {
2749  if (gThreadTsd && fStreamer) {
2750  TClassLocalStorage *local = TClassLocalStorage::GetStorage(this);
2751  if (local==0) return fStreamer;
2752  if (local->fStreamer==0) {
2753  local->fStreamer = fStreamer->Generate();
2754  const type_info &orig = ( typeid(*fStreamer) );
2755  if (!local->fStreamer) {
2756  Warning("GetStreamer","For %s, the TClassStreamer (%s) passed's call to Generate failed!",GetName(),orig.name());
2757  } else {
2758  const type_info &copy = ( typeid(*local->fStreamer) );
2759  if (strcmp(orig.name(),copy.name())!=0) {
2760  Warning("GetStreamer","For %s, the TClassStreamer passed does not properly implement the Generate method (%s vs %s)\n",GetName(),orig.name(),copy.name());
2761  }
2762  }
2763  }
2764  return local->fStreamer;
2765  }
2766  return fStreamer;
2767 }
2768 
2769 ////////////////////////////////////////////////////////////////////////////////
2770 /// Get a wrapper/accessor function around this class custom streamer (member function).
2771 
2773 {
2774  return fStreamerFunc;
2775 }
2776 
2777 ////////////////////////////////////////////////////////////////////////////////
2778 /// Get a wrapper/accessor function around this class custom conversion streamer (member function).
2779 
2781 {
2782  return fConvStreamerFunc;
2783 }
2784 
2785 ////////////////////////////////////////////////////////////////////////////////
2786 /// Return the proxy implementing the IsA functionality.
2787 
2789 {
2790  return fIsA;
2791 }
2792 
2793 ////////////////////////////////////////////////////////////////////////////////
2794 /// Static method returning pointer to TClass of the specified class name.
2795 /// If load is true an attempt is made to obtain the class by loading
2796 /// the appropriate shared library (directed by the rootmap file).
2797 /// If silent is 'true', do not warn about missing dictionary for the class.
2798 /// (typically used for class that are used only for transient members)
2799 /// Returns 0 in case class is not found.
2800 
2801 TClass *TClass::GetClass(const char *name, Bool_t load, Bool_t silent)
2802 {
2803  if (!name || !name[0]) return 0;
2804 
2805  if (strstr(name, "(anonymous)")) return 0;
2806  if (strncmp(name,"class ",6)==0) name += 6;
2807  if (strncmp(name,"struct ",7)==0) name += 7;
2808 
2810 
2811  if (!gROOT->GetListOfClasses()) return 0;
2812 
2813  TClass *cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name);
2814 
2815  // Early return to release the lock without having to execute the
2816  // long-ish normalization.
2817  if (cl) {
2818  if (cl->IsLoaded() || cl->TestBit(kUnloading)) return cl;
2819 
2820  // We could speed-up some of the search by adding (the equivalent of)
2821  //
2822  // if (cl->GetState() == kInterpreter) return cl
2823  //
2824  // In this case, if a ROOT dictionary was available when the TClass
2825  // was first request it would have been used and if a ROOT dictionary is
2826  // loaded later on TClassTable::Add will take care of updating the TClass.
2827  // So as far as ROOT dictionary are concerned, if the current TClass is
2828  // in interpreted state, we are sure there is nothing to load.
2829  //
2830  // However (see TROOT::LoadClass), the TClass can also be loaded/provided
2831  // by a user provided TClassGenerator. We have no way of knowing whether
2832  // those do (or even can) behave the same way as the ROOT dictionary and
2833  // have the 'dictionary is now available for use' step informa the existing
2834  // TClass that their dictionary is now available.
2835 
2836  //we may pass here in case of a dummy class created by TVirtualStreamerInfo
2837  load = kTRUE;
2838  }
2839 
2840  // To avoid spurious auto parsing, let's check if the name as-is is
2841  // known in the TClassTable.
2843  if (dict) {
2844  // The name is normalized, so the result of the first search is
2845  // authoritative.
2846  if (!cl && !load) return 0;
2847 
2848  TClass *loadedcl = (dict)();
2849  if (loadedcl) {
2850  loadedcl->PostLoadCheck();
2851  return loadedcl;
2852  }
2853 
2854  // We should really not fall through to here, but if we do, let's just
2855  // continue as before ...
2856  }
2857 
2858  std::string normalizedName;
2859  Bool_t checkTable = kFALSE;
2860 
2861  if (!cl) {
2862  int oldAutoloadVal = gCling->SetClassAutoloading(false);
2863  TClassEdit::GetNormalizedName(normalizedName, name);
2864  gCling->SetClassAutoloading(oldAutoloadVal);
2865  // Try the normalized name.
2866  if (normalizedName != name) {
2867  cl = (TClass*)gROOT->GetListOfClasses()->FindObject(normalizedName.c_str());
2868 
2869  if (cl) {
2870  if (cl->IsLoaded() || cl->TestBit(kUnloading)) return cl;
2871 
2872  //we may pass here in case of a dummy class created by TVirtualStreamerInfo
2873  load = kTRUE;
2874  }
2875  checkTable = kTRUE;
2876  }
2877  } else {
2878  normalizedName = cl->GetName(); // Use the fact that all TClass names are normalized.
2879  checkTable = load && (normalizedName != name);
2880  }
2881 
2882  if (!load) return 0;
2883 
2884 // This assertion currently fails because of
2885 // TClass *c1 = TClass::GetClass("basic_iostream<char,char_traits<char> >");
2886 // TClass *c2 = TClass::GetClass("std::iostream");
2887 // where the TClassEdit normalized name of iostream is basic_iostream<char>
2888 // i.e missing the addition of the default parameter. This is because TClingLookupHelper
2889 // uses only 'part' of TMetaUtils::GetNormalizedName.
2890 
2891 // if (!cl) {
2892 // TDataType* dataType = (TDataType*)gROOT->GetListOfTypes()->FindObject(name);
2893 // TClass *altcl = dataType ? (TClass*)gROOT->GetListOfClasses()->FindObject(dataType->GetFullTypeName()) : 0;
2894 // if (altcl && normalizedName != altcl->GetName())
2895 // ::Fatal("TClass::GetClass","The existing name (%s) for %s is different from the normalized name: %s\n",
2896 // altcl->GetName(), name, normalizedName.c_str());
2897 // }
2898 
2899  TClass *loadedcl = 0;
2900  if (checkTable) {
2901  loadedcl = LoadClassDefault(normalizedName.c_str(),silent);
2902  } else {
2903  if (gInterpreter->AutoLoad(normalizedName.c_str(),kTRUE)) {
2904  loadedcl = LoadClassDefault(normalizedName.c_str(),silent);
2905  }
2906  // Maybe this was a typedef: let's try to see if this is the case
2907  if (!loadedcl){
2908  if (TDataType* theDataType = gROOT->GetType(normalizedName.c_str())){
2909  // We have a typedef: we get the name of the underlying type
2910  auto underlyingTypeName = theDataType->GetTypeName();
2911  // We see if we can bootstrap a class with it
2912  auto underlyingTypeDict = TClassTable::GetDictNorm(underlyingTypeName.Data());
2913  if (underlyingTypeDict){
2914  loadedcl = underlyingTypeDict();
2915  }
2916 
2917  }
2918  }
2919  }
2920  if (loadedcl) return loadedcl;
2921 
2922  // See if the TClassGenerator can produce the TClass we need.
2923  loadedcl = LoadClassCustom(normalizedName.c_str(),silent);
2924  if (loadedcl) return loadedcl;
2925 
2926  // We have not been able to find a loaded TClass, return the Emulated
2927  // TClass if we have one.
2928  if (cl) return cl;
2929 
2930  if (TClassEdit::IsSTLCont( normalizedName.c_str() )) {
2931 
2932  return gInterpreter->GenerateTClass(normalizedName.c_str(), kTRUE, silent);
2933  }
2934 
2935  // Check the interpreter only after autoparsing the template if any.
2936  {
2937  std::string::size_type posLess = normalizedName.find('<');
2938  if (posLess != std::string::npos) {
2939  gCling->AutoParse(normalizedName.substr(0, posLess).c_str());
2940  }
2941  }
2942 
2943  //last attempt. Look in CINT list of all (compiled+interpreted) classes
2944  if (gDebug>0){
2945  printf("TClass::GetClass: Header Parsing - The representation of %s was not found in the type system. A lookup in the interpreter is about to be tried: this can cause parsing. This can be avoided selecting %s in the linkdef/selection file.\n",normalizedName.c_str(), normalizedName.c_str());
2946  }
2947  if (normalizedName.length() &&
2948  gInterpreter->CheckClassInfo(normalizedName.c_str(), kTRUE /* autoload */, kTRUE /*Only class, structs and ns*/)) {
2949  // Get the normalized name based on the decl (currently the only way
2950  // to get the part to add or drop the default arguments as requested by the user)
2951  std::string alternative;
2952  gInterpreter->GetInterpreterTypeName(normalizedName.c_str(),alternative,kTRUE);
2953  const char *altname = alternative.c_str();
2954  if ( strncmp(altname,"std::",5)==0 ) {
2955  // For namespace (for example std::__1), GetInterpreterTypeName does
2956  // not strip std::, so we must do it explicitly here.
2957  altname += 5;
2958  }
2959  if (altname != normalizedName && strcmp(altname,name) != 0) {
2960  // altname now contains the full name of the class including a possible
2961  // namespace if there has been a using namespace statement.
2962 
2963  // At least in the case C<string [2]> (normalized) vs C<string[2]> (altname)
2964  // the TClassEdit normalization and the TMetaUtils normalization leads to
2965  // two different space layout. To avoid an infinite recursion, we also
2966  // add the test on (altname != name)
2967 
2968  return GetClass(altname,load);
2969  }
2970  TClass *ncl = gInterpreter->GenerateTClass(normalizedName.c_str(), /* emulation = */ kFALSE, silent);
2971  if (!ncl->IsZombie()) {
2972  return ncl;
2973  }
2974  delete ncl;
2975  }
2976  return 0;
2977 }
2978 
2979 ////////////////////////////////////////////////////////////////////////////////
2980 /// Return pointer to class with name.
2981 
2982 TClass *TClass::GetClass(const type_info& typeinfo, Bool_t load, Bool_t /* silent */)
2983 {
2984  //protect access to TROOT::GetListOfClasses
2986 
2987  if (!gROOT->GetListOfClasses()) return 0;
2988 
2989  TClass* cl = GetIdMap()->Find(typeinfo.name());
2990 
2991  if (cl) {
2992  if (cl->IsLoaded()) return cl;
2993  //we may pass here in case of a dummy class created by TVirtualStreamerInfo
2994  load = kTRUE;
2995  } else {
2996  // Note we might need support for typedefs and simple types!
2997 
2998  // TDataType *objType = GetType(name, load);
2999  //if (objType) {
3000  // const char *typdfName = objType->GetTypeName();
3001  // if (typdfName && strcmp(typdfName, name)) {
3002  // cl = GetClass(typdfName, load);
3003  // return cl;
3004  // }
3005  // }
3006  }
3007 
3008  if (!load) return 0;
3009 
3011  if (dict) {
3012  cl = (dict)();
3013  if (cl) cl->PostLoadCheck();
3014  return cl;
3015  }
3016  if (cl) return cl;
3017 
3018  TIter next(gROOT->GetListOfClassGenerators());
3020  while( (gen = (TClassGenerator*) next()) ) {
3021  cl = gen->GetClass(typeinfo,load);
3022  if (cl) {
3023  cl->PostLoadCheck();
3024  return cl;
3025  }
3026  }
3027 
3028  // try autoloading the typeinfo
3029  int autoload_old = gCling->SetClassAutoloading(1);
3030  if (!autoload_old) {
3031  // Re-disable, we just meant to test
3033  }
3034  if (autoload_old && gInterpreter->AutoLoad(typeinfo,kTRUE)) {
3035  // Disable autoload to avoid potential infinite recursion
3037  cl = GetClass(typeinfo, load);
3039  if (cl) {
3040  return cl;
3041  }
3042  }
3043 
3044  // last attempt. Look in the interpreter list of all (compiled+interpreted)
3045  // classes
3046  cl = gInterpreter->GetClass(typeinfo, load);
3047 
3048  return cl; // Can be zero.
3049 }
3050 
3051 ////////////////////////////////////////////////////////////////////////////////
3052 /// Static method returning pointer to TClass of the specified ClassInfo.
3053 /// If load is true an attempt is made to obtain the class by loading
3054 /// the appropriate shared library (directed by the rootmap file).
3055 /// If silent is 'true', do not warn about missing dictionary for the class.
3056 /// (typically used for class that are used only for transient members)
3057 /// Returns 0 in case class is not found.
3058 
3059 TClass *TClass::GetClass(ClassInfo_t *info, Bool_t load, Bool_t silent)
3060 {
3061  if (!info || !gCling->ClassInfo_IsValid(info)) return 0;
3062  if (!gROOT->GetListOfClasses()) return 0;
3063 
3064  // Get the normalized name.
3066 
3067  TClass *cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name);
3068 
3069  if (cl) {
3070  if (cl->IsLoaded()) return cl;
3071 
3072  //we may pass here in case of a dummy class created by TVirtualStreamerInfo
3073  load = kTRUE;
3074 
3075  }
3076 
3077  if (!load) return 0;
3078 
3079  TClass *loadedcl = 0;
3080  if (cl) loadedcl = gROOT->LoadClass(cl->GetName(),silent);
3081  else loadedcl = gROOT->LoadClass(name,silent);
3082 
3083  if (loadedcl) return loadedcl;
3084 
3085  if (cl) return cl; // If we found the class but we already have a dummy class use it.
3086 
3087  // We did not find a proper TClass but we do know (we have a valid
3088  // ClassInfo) that the class is known to the interpreter.
3089  TClass *ncl = gInterpreter->GenerateTClass(info, silent);
3090  if (!ncl->IsZombie()) {
3091  return ncl;
3092  } else {
3093  delete ncl;
3094  return 0;
3095  }
3096 }
3097 
3098 ////////////////////////////////////////////////////////////////////////////////
3099 
3102 }
3103 
3104 ////////////////////////////////////////////////////////////////////////////////
3105 
3106 Bool_t TClass::GetClass(DeclId_t id, std::vector<TClass*> &classes)
3107 {
3108  if (!gROOT->GetListOfClasses()) return 0;
3109 
3110  DeclIdMap_t* map = GetDeclIdMap();
3111  // Get all the TClass pointer that have the same DeclId.
3112  DeclIdMap_t::equal_range iter = map->Find(id);
3113  if (iter.first == iter.second) return false;
3114  std::vector<TClass*>::iterator vectIt = classes.begin();
3115  for (DeclIdMap_t::const_iterator it = iter.first; it != iter.second; ++it)
3116  vectIt = classes.insert(vectIt, it->second);
3117  return true;
3118 }
3119 
3120 ////////////////////////////////////////////////////////////////////////////////
3121 /// Return a pointer to the dictionary loading function generated by
3122 /// rootcint
3123 
3124 DictFuncPtr_t TClass::GetDict (const char *cname)
3125 {
3126  return TClassTable::GetDict(cname);
3127 }
3128 
3129 ////////////////////////////////////////////////////////////////////////////////
3130 /// Return a pointer to the dictionary loading function generated by
3131 /// rootcint
3132 
3133 DictFuncPtr_t TClass::GetDict (const type_info& info)
3134 {
3135  return TClassTable::GetDict(info);
3136 }
3137 
3138 ////////////////////////////////////////////////////////////////////////////////
3139 /// Return pointer to datamember object with name "datamember".
3140 
3141 TDataMember *TClass::GetDataMember(const char *datamember) const
3142 {
3143  if ((!(fData && fData->IsLoaded()) && !HasInterpreterInfo())
3144  || datamember == 0) return 0;
3145 
3146  // Strip off leading *'s and trailing [
3147  const char *start_name = datamember;
3148  while (*start_name == '*') ++start_name;
3149 
3150  // Empty name are 'legal', they represent anonymous unions.
3151  // if (*start_name == 0) return 0;
3152 
3153  if (const char *s = strchr(start_name, '[')){
3154  UInt_t len = s-start_name;
3155  TString name(start_name,len);
3156  return (TDataMember *)((TClass*)this)->GetListOfDataMembers(kFALSE)->FindObject(name.Data());
3157  } else {
3158  return (TDataMember *)((TClass*)this)->GetListOfDataMembers(kFALSE)->FindObject(start_name);
3159  }
3160 }
3161 
3162 ////////////////////////////////////////////////////////////////////////////////
3163 /// return offset for member name. name can be a data member in
3164 /// the class itself, one of its base classes, or one member in
3165 /// one of the aggregated classes.
3166 ///
3167 /// In case of an emulated class, the list of emulated TRealData is built
3168 
3169 Long_t TClass::GetDataMemberOffset(const char *name) const
3170 {
3171  TRealData *rd = GetRealData(name);
3172  if (rd) return rd->GetThisOffset();
3173  if (strchr(name,'[')==0) {
3174  // If this is a simple name there is a chance to find it in the
3175  // StreamerInfo even if we did not find it in the RealData.
3176  // For example an array name would be fArray[3] in RealData but
3177  // just fArray in the streamerInfo.
3178  TVirtualStreamerInfo *info = const_cast<TClass*>(this)->GetCurrentStreamerInfo();
3179  if (info) {
3180  return info->GetOffset(name);
3181  }
3182  }
3183  return 0;
3184 }
3185 
3186 ////////////////////////////////////////////////////////////////////////////////
3187 /// Return pointer to TRealData element with name "name".
3188 ///
3189 /// Name can be a data member in the class itself,
3190 /// one of its base classes, or a member in
3191 /// one of the aggregated classes.
3192 ///
3193 /// In case of an emulated class, the list of emulated TRealData is built.
3194 
3195 TRealData* TClass::GetRealData(const char* name) const
3196 {
3197  if (!fRealData) {
3198  const_cast<TClass*>(this)->BuildRealData();
3199  }
3200 
3201  if (!fRealData) {
3202  return 0;
3203  }
3204 
3205  if (!name) {
3206  return 0;
3207  }
3208 
3209  // First try just the whole name.
3210  TRealData* rd = (TRealData*) fRealData->FindObject(name);
3211  if (rd) {
3212  return rd;
3213  }
3214 
3215  std::string givenName(name);
3216 
3217  // Try ignoring the array dimensions.
3218  std::string::size_type firstBracket = givenName.find_first_of("[");
3219  if (firstBracket != std::string::npos) {
3220  // -- We are looking for an array data member.
3221  std::string nameNoDim(givenName.substr(0, firstBracket));
3222  TObjLink* lnk = fRealData->FirstLink();
3223  while (lnk) {
3224  TObject* obj = lnk->GetObject();
3225  std::string objName(obj->GetName());
3226  std::string::size_type pos = objName.find_first_of("[");
3227  // Only match arrays to arrays for now.
3228  if (pos != std::string::npos) {
3229  objName.erase(pos);
3230  if (objName == nameNoDim) {
3231  return static_cast<TRealData*>(obj);
3232  }
3233  }
3234  lnk = lnk->Next();
3235  }
3236  }
3237 
3238  // Now try it as a pointer.
3239  std::ostringstream ptrname;
3240  ptrname << "*" << givenName;
3241  rd = (TRealData*) fRealData->FindObject(ptrname.str().c_str());
3242  if (rd) {
3243  return rd;
3244  }
3245 
3246  // Check for a dot in the name.
3247  std::string::size_type firstDot = givenName.find_first_of(".");
3248  if (firstDot == std::string::npos) {
3249  // -- Not found, a simple name, all done.
3250  return 0;
3251  }
3252 
3253  //
3254  // At this point the name has a dot in it, so it is the name
3255  // of some contained sub-object.
3256  //
3257 
3258  // May be a pointer like in TH1: fXaxis.fLabels (in TRealdata is named fXaxis.*fLabels)
3259  std::string::size_type lastDot = givenName.find_last_of(".");
3260  std::ostringstream starname;
3261  starname << givenName.substr(0, lastDot) << ".*" << givenName.substr(lastDot + 1);
3262  rd = (TRealData*) fRealData->FindObject(starname.str().c_str());
3263  if (rd) {
3264  return rd;
3265  }
3266 
3267  // Strip the first component, it may be the name of
3268  // the branch (old TBranchElement code), and try again.
3269  std::string firstDotName(givenName.substr(firstDot + 1));
3270 
3271  // New attempt starting after the first "." if any,
3272  // this allows for the case that the first component
3273  // may have been a branch name (for TBranchElement).
3274  rd = (TRealData*) fRealData->FindObject(firstDotName.c_str());
3275  if (rd) {
3276  return rd;
3277  }
3278 
3279  // New attempt starting after the first "." if any,
3280  // but this time try ignoring the array dimensions.
3281  // Again, we are allowing for the case that the first
3282  // component may have been a branch name (for TBranchElement).
3283  std::string::size_type firstDotBracket = firstDotName.find_first_of("[");
3284  if (firstDotBracket != std::string::npos) {
3285  // -- We are looking for an array data member.
3286  std::string nameNoDim(firstDotName.substr(0, firstDotBracket));
3287  TObjLink* lnk = fRealData->FirstLink();
3288  while (lnk) {
3289  TObject* obj = lnk->GetObject();
3290  std::string objName(obj->GetName());
3291  std::string::size_type pos = objName.find_first_of("[");
3292  // Only match arrays to arrays for now.
3293  if (pos != std::string::npos) {
3294  objName.erase(pos);
3295  if (objName == nameNoDim) {
3296  return static_cast<TRealData*>(obj);
3297  }
3298  }
3299  lnk = lnk->Next();
3300  }
3301  }
3302 
3303  // New attempt starting after the first "." if any,
3304  // but this time check for a pointer type. Again, we
3305  // are allowing for the case that the first component
3306  // may have been a branch name (for TBranchElement).
3307  ptrname.str("");
3308  ptrname << "*" << firstDotName;
3309  rd = (TRealData*) fRealData->FindObject(ptrname.str().c_str());
3310  if (rd) {
3311  return rd;
3312  }
3313 
3314  // Last attempt in case a member has been changed from
3315  // a static array to a pointer, for example the member
3316  // was arr[20] and is now *arr.
3317  //
3318  // Note: In principle, one could also take into account
3319  // the opposite situation where a member like *arr has
3320  // been converted to arr[20].
3321  //
3322  // FIXME: What about checking after the first dot as well?
3323  //
3324  std::string::size_type bracket = starname.str().find_first_of("[");
3325  if (bracket == std::string::npos) {
3326  return 0;
3327  }
3328  rd = (TRealData*) fRealData->FindObject(starname.str().substr(0, bracket).c_str());
3329  if (rd) {
3330  return rd;
3331  }
3332 
3333  // Not found;
3334  return 0;
3335 }
3336 
3337 ////////////////////////////////////////////////////////////////////////////////
3338 
3340 {
3341  if (!gInterpreter || !HasInterpreterInfo()) return 0;
3342 
3343  // The following
3345 
3346  return (TFunctionTemplate*)fFuncTemplate->FindObject(name);
3347 }
3348 
3349 ////////////////////////////////////////////////////////////////////////////////
3350 /// Get the list of shared libraries containing the code for class cls.
3351 /// The first library in the list is the one containing the class, the
3352 /// others are the libraries the first one depends on. Returns 0
3353 /// in case the library is not found.
3354 
3356 {
3357  if (!gInterpreter) return 0;
3358 
3359  if (fSharedLibs.IsNull())
3360  fSharedLibs = gInterpreter->GetClassSharedLibs(fName);
3361 
3362  return !fSharedLibs.IsNull() ? fSharedLibs.Data() : 0;
3363 }
3364 
3365 ////////////////////////////////////////////////////////////////////////////////
3366 /// Return list containing the TBaseClass(es) of a class.
3367 
3369 {
3370  if (!fBase) {
3371  if (fCanLoadClassInfo) {
3372  if (fState == kHasTClassInit) {
3373 
3375  // NOTE: Add test to prevent redo if another thread has already done the work.
3376  // if (!fHasRootPcmInfo) {
3377 
3378  // The bases are in our ProtoClass; we don't need the class info.
3380  if (proto && proto->FillTClass(this)) {
3381  // Not sure this code is still needed
3382  // R__ASSERT(kFALSE);
3383 
3385  }
3386  }
3387  // We test again on fCanLoadClassInfo has another thread may have executed it.
3389  LoadClassInfo();
3390  }
3391  }
3392  if (!fClassInfo) return 0;
3393 
3394  if (!gInterpreter)
3395  Fatal("GetListOfBases", "gInterpreter not initialized");
3396 
3398  if(!fBase) {
3399  gInterpreter->CreateListOfBaseClasses(this);
3400  }
3401  }
3402  return fBase;
3403 }
3404 
3405 ////////////////////////////////////////////////////////////////////////////////
3406 /// Return list containing the TEnums of a class.
3407 
3409 {
3410  auto temp = fEnums.load();
3411  if (temp) {
3412  if (load) {
3413  if (fProperty == -1) Property();
3414  if (! ((kIsClass | kIsStruct | kIsUnion) & fProperty) ) {
3416  temp->Load();
3417  }
3418  }
3419  return temp;
3420  }
3421 
3422  if (!load) {
3423  if (fProperty == -1) Property();
3424  if (! ((kIsClass | kIsStruct | kIsUnion) & fProperty) ) {
3426  if (fEnums.load()) {
3427  return fEnums.load();
3428  }
3429  //namespaces can have enums added to them
3430  fEnums = new TListOfEnumsWithLock(this);
3431  return fEnums;
3432  }
3433  // no one is supposed to modify the returned results
3434  static TListOfEnums s_list;
3435  return &s_list;
3436  }
3437 
3439  if (fEnums.load()) {
3440  if (load) (*fEnums).Load();
3441  return fEnums.load();
3442  }
3443  if (fProperty == -1) Property();
3444  if ( (kIsClass | kIsStruct | kIsUnion) & fProperty) {
3445  // For this case, the list will be immutable
3446  temp = new TListOfEnums(this);
3447  } else {
3448  //namespaces can have enums added to them
3449  temp = new TListOfEnumsWithLock(this);
3450  }
3451  temp->Load();
3452  fEnums = temp;
3453  return temp;
3454 }
3455 
3456 ////////////////////////////////////////////////////////////////////////////////
3457 /// Return list containing the TDataMembers of a class.
3458 
3460 {
3462 
3463  if (!fData) {
3465  // NOTE: Add test to prevent redo if another thread has already done the work.
3466  // if (!fHasRootPcmInfo) {
3467 
3468  // The members are in our ProtoClass; we don't need the class info.
3470  if (proto && proto->FillTClass(this)) {
3471  // Not sure this code is still needed
3472  // R__ASSERT(kFALSE);
3473 
3475  return fData;
3476  }
3477  }
3478  fData = new TListOfDataMembers(this);
3479  }
3480  if (Property() & (kIsClass|kIsStruct|kIsUnion)) {
3481  // If the we have a class or struct or union, the order
3482  // of data members is the list is essential since it determines their
3483  // order on file. So we must always load. Also, the list is fixed
3484  // since the language does not allow to add members.
3485  if (!fData->IsLoaded()) fData->Load();
3486 
3487  } else if (load) fData->Load();
3488  return fData;
3489 }
3490 
3491 ////////////////////////////////////////////////////////////////////////////////
3492 /// Return list containing the TEnums of a class.
3493 
3495 {
3497 
3499  if (load) fFuncTemplate->Load();
3500  return fFuncTemplate;
3501 }
3502 
3503 ////////////////////////////////////////////////////////////////////////////////
3504 /// Return list containing the TMethods of a class.
3505 /// If load is true, the list is populated with all the defined function
3506 /// and currently instantiated function template.
3507 
3509 {
3511 
3512  if (!fMethod.load()) GetMethodList();
3513  if (load) {
3514  if (gDebug>0) Info("GetListOfMethods","Header Parsing - Asking for all the methods of class %s: this can involve parsing.",GetName());
3515  (*fMethod).Load();
3516  }
3517  return fMethod;
3518 }
3519 
3520 ////////////////////////////////////////////////////////////////////////////////
3521 /// Return the collection of functions named "name".
3522 
3524 {
3525  return const_cast<TClass*>(this)->GetMethodList()->GetListForObject(name);
3526 }
3527 
3528 
3529 ////////////////////////////////////////////////////////////////////////////////
3530 /// Returns a list of all public methods of this class and its base classes.
3531 /// Refers to a subset of the methods in GetListOfMethods() so don't do
3532 /// GetListOfAllPublicMethods()->Delete().
3533 /// Algorithm used to get the list is:
3534 /// - put all methods of the class in the list (also protected and private
3535 /// ones).
3536 /// - loop over all base classes and add only those methods not already in the
3537 /// list (also protected and private ones).
3538 /// - once finished, loop over resulting list and remove all private and
3539 /// protected methods.
3540 
3542 {
3544 
3545  if (!fAllPubMethod) fAllPubMethod = new TViewPubFunctions(this);
3546  if (load) {
3547  if (gDebug>0) Info("GetListOfAllPublicMethods","Header Parsing - Asking for all the methods of class %s: this can involve parsing.",GetName());
3548  fAllPubMethod->Load();
3549  }
3550  return fAllPubMethod;
3551 }
3552 
3553 ////////////////////////////////////////////////////////////////////////////////
3554 /// Returns a list of all public data members of this class and its base
3555 /// classes. Refers to a subset of the data members in GetListOfDatamembers()
3556 /// so don't do GetListOfAllPublicDataMembers()->Delete().
3557 
3559 {
3561 
3562  if (!fAllPubData) fAllPubData = new TViewPubDataMembers(this);
3563  if (load) fAllPubData->Load();
3564  return fAllPubData;
3565 }
3566 
3567 ////////////////////////////////////////////////////////////////////////////////
3568 /// Returns list of methods accessible by context menu.
3569 
3571 {
3572  if (!HasInterpreterInfo()) return;
3573 
3574  // get the base class
3575  TIter nextBase(GetListOfBases(), kIterBackward);
3576  TBaseClass *baseClass;
3577  while ((baseClass = (TBaseClass *) nextBase())) {
3578  TClass *base = baseClass->GetClassPointer();
3579  if (base) base->GetMenuItems(list);
3580  }
3581 
3582  // remove methods redefined in this class with no menu
3583  TMethod *method, *m;
3585  while ((method = (TMethod*)next())) {
3586  m = (TMethod*)list->FindObject(method->GetName());
3587  if (method->IsMenuItem() != kMenuNoMenu) {
3588  if (!m)
3589  list->AddFirst(method);
3590  } else {
3591  if (m && m->GetNargs() == method->GetNargs())
3592  list->Remove(m);
3593  }
3594  }
3595 }
3596 
3597 ////////////////////////////////////////////////////////////////////////////////
3598 /// Check whether a class has a dictionary or not.
3599 /// This is equivalent to ask if a class is coming from a bootstrapping
3600 /// procedure initiated during the loading of a library.
3601 
3603 {
3604  return IsLoaded();
3605 }
3606 
3607 ////////////////////////////////////////////////////////////////////////////////
3608 /// Check whether a class has a dictionary or ROOT can load one.
3609 /// This is equivalent to ask HasDictionary() or whether a library is known
3610 /// where it can be loaded from, or whether a Dictionary function is
3611 /// available because the class's dictionary library was already loaded.
3612 
3614 {
3615  if (TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(clname))
3616  return cl->IsLoaded();
3617  return gClassTable->GetDict(clname) || gInterpreter->GetClassSharedLibs(clname);
3618 }
3619 
3620 ////////////////////////////////////////////////////////////////////////////////
3621 /// Verify the base classes always.
3622 
3624 {
3625  TList* lb = GetListOfBases();
3626  if (!lb) return;
3627  TIter nextBase(lb);
3628  TBaseClass* base = 0;
3629  while ((base = (TBaseClass*)nextBase())) {
3630  TClass* baseCl = base->Class();
3631  if (baseCl) {
3632  baseCl->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
3633  }
3634  }
3635 }
3636 
3637 ////////////////////////////////////////////////////////////////////////////////
3638 /// Verify the Data Members.
3639 
3641 {
3643  if (!ldm) return ;
3644  TIter nextMemb(ldm);
3645  TDataMember * dm = 0;
3646  while ((dm = (TDataMember*)nextMemb())) {
3647  // If it is a transient
3648  if(!dm->IsPersistent()) {
3649  continue;
3650  }
3651  if (dm->Property() & kIsStatic) {
3652  continue;
3653  }
3654  // If it is a built-in data type.
3655  TClass* dmTClass = 0;
3656  if (dm->GetDataType()) {
3657  dmTClass = dm->GetDataType()->Class();
3658  // Otherwise get the string representing the type.
3659  } else if (dm->GetTypeName()) {
3660  dmTClass = TClass::GetClass(dm->GetTypeName());
3661  }
3662  if (dmTClass) {
3663  dmTClass->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
3664  }
3665  }
3666 }
3667 
3669 {
3670  // Pair is a special case and we have to check its elements for missing dictionaries
3671  // Pair is a transparent container so we should always look at its.
3672 
3674  for (int i = 0; i < 2; i++) {
3675  TClass* pairElement = ((TStreamerElement*)SI->GetElements()->At(i))->GetClass();
3676  if (pairElement) {
3677  pairElement->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
3678  }
3679  }
3680 }
3681 
3682 ////////////////////////////////////////////////////////////////////////////////
3683 /// From the second level of recursion onwards it is different state check.
3684 
3686 {
3687  if (result.FindObject(this) || visited.FindObject(this)) return;
3688 
3689  static TClassRef sCIString("string");
3690  if (this == sCIString) return;
3691 
3692  // Special treatment for pair.
3693  if (strncmp(fName, "pair<", 5) == 0) {
3694  GetMissingDictionariesForPairElements(result, visited, recurse);
3695  return;
3696  }
3697 
3698  if (!HasDictionary()) {
3699  result.Add(this);
3700  }
3701 
3702  visited.Add(this);
3703  //Check whether a custom streamer
3705  if (GetCollectionProxy()) {
3706  // We need to look at the collection's content
3707  // The collection has different kind of elements the check would be required.
3708  TClass* t = 0;
3709  if ((t = GetCollectionProxy()->GetValueClass())) {
3710  if (!t->HasDictionary()) {
3711  t->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
3712  }
3713  }
3714  } else {
3715  if (recurse) {
3716  GetMissingDictionariesForMembers(result, visited, recurse);
3717  }
3718  GetMissingDictionariesForBaseClasses(result, visited, recurse);
3719  }
3720  }
3721 }
3722 
3723 ////////////////////////////////////////////////////////////////////////////////
3724 /// Get the classes that have a missing dictionary starting from this one.
3725 /// - With recurse = false the classes checked for missing dictionaries are:
3726 /// the class itself, all base classes, direct data members,
3727 /// and for collection proxies the container's
3728 /// elements without iterating over the element's data members;
3729 /// - With recurse = true the classes checked for missing dictionaries are:
3730 /// the class itself, all base classes, recursing on the data members,
3731 /// and for the collection proxies recursion on the elements of the
3732 /// collection and iterating over the element's data members.
3733 
3735 {
3736  // Top level recursion it different from the following levels of recursion.
3737 
3738  if (result.FindObject(this)) return;
3739 
3740  static TClassRef sCIString("string");
3741  if (this == sCIString) return;
3742 
3743  THashTable visited;
3744 
3745  if (strncmp(fName, "pair<", 5) == 0) {
3746  GetMissingDictionariesForPairElements(result, visited, recurse);
3747  return;
3748  }
3749 
3750  if (!HasDictionary()) {
3751  result.Add(this);
3752  }
3753 
3754  visited.Add(this);
3755 
3756  //Check whether a custom streamer
3758  if (GetCollectionProxy()) {
3759  // We need to look at the collection's content
3760  // The collection has different kind of elements the check would be required.
3761  TClass* t = 0;
3762  if ((t = GetCollectionProxy()->GetValueClass())) {
3763  if (!t->HasDictionary()) {
3764  t->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
3765  }
3766  }
3767  } else {
3768  GetMissingDictionariesForMembers(result, visited, recurse);
3769  GetMissingDictionariesForBaseClasses(result, visited, recurse);
3770  }
3771  }
3772 }
3773 
3774 ////////////////////////////////////////////////////////////////////////////////
3775 /// Return kTRUE if the class has elements.
3776 
3777 Bool_t TClass::IsFolder(void *obj) const
3778 {
3779  return Browse(obj,(TBrowser*)0);
3780 }
3781 
3782 //______________________________________________________________________________
3783 //______________________________________________________________________________
3784 void TClass::ReplaceWith(TClass *newcl) const
3785 {
3786  // Inform the other objects to replace this object by the new TClass (newcl)
3787 
3789  //we must update the class pointers pointing to 'this' in all TStreamerElements
3790  TIter nextClass(gROOT->GetListOfClasses());
3791  TClass *acl;
3792  TVirtualStreamerInfo *info;
3793  TList tobedeleted;
3794 
3795  // Since we are in the process of replacing a TClass by a TClass
3796  // coming from a dictionary, there is no point in loading any
3797  // libraries during this search.
3798  Bool_t autoload = gInterpreter->SetClassAutoloading(kFALSE);
3799 
3800  while ((acl = (TClass*)nextClass())) {
3801  if (acl == newcl) continue;
3802 
3803  TIter nextInfo(acl->GetStreamerInfos());
3804  while ((info = (TVirtualStreamerInfo*)nextInfo())) {
3805 
3806  info->Update(this, newcl);
3807  }
3808 
3809  if (acl->GetCollectionProxy()) {
3810  acl->GetCollectionProxy()->UpdateValueClass(this, newcl);
3811  }
3812  // We should also inform all the TBranchElement :( but we do not have a master list :(
3813  }
3814 
3815  TIter delIter( &tobedeleted );
3816  while ((acl = (TClass*)delIter())) {
3817  delete acl;
3818  }
3819  gInterpreter->UnRegisterTClassUpdate(this);
3820 
3821  gInterpreter->SetClassAutoloading(autoload);
3822 }
3823 
3824 ////////////////////////////////////////////////////////////////////////////////
3825 /// Make sure that the current ClassInfo is up to date.
3826 
3827 void TClass::ResetClassInfo(Long_t /* tagnum */)
3828 {
3829  Warning("ResetClassInfo(Long_t tagnum)","Call to deprecated interface (does nothing)");
3830 }
3831 
3832 ////////////////////////////////////////////////////////////////////////////////
3833 /// Make sure that the current ClassInfo is up to date.
3834 
3836 {
3838 
3840 
3841  if (fClassInfo) {
3843  gInterpreter->ClassInfo_Delete(fClassInfo);
3844  fClassInfo = 0;
3845  }
3846  // We can not check at this point whether after the unload there will
3847  // still be interpreter information about this class (as v5 was doing),
3848  // instead this function must only be called if the definition is (about)
3849  // to be unloaded.
3850 
3851  ResetCaches();
3852 
3853  // We got here because the definition Decl is about to be unloaded.
3854  if (fState != TClass::kHasTClassInit) {
3855  if (fStreamerInfo->GetEntries() != 0) {
3857  } else {
3859  }
3860  } else {
3861  // if the ClassInfo was loaded for a class with a TClass Init and it
3862  // gets unloaded, should we guess it can be reloaded?
3864  }
3865 }
3866 
3867 ////////////////////////////////////////////////////////////////////////////////
3868 /// To clean out all caches.
3869 
3871 {
3872  R__ASSERT(!TestBit(kLoading) && "Resetting the caches does not make sense during loading!" );
3873 
3874  // Not owning lists, don't call Delete(), but unload
3875  if (fData)
3876  fData->Unload();
3877  if (fEnums.load())
3878  (*fEnums).Unload();
3879  if (fMethod.load())
3880  (*fMethod).Unload();
3881 
3882  delete fAllPubData; fAllPubData = 0;
3883 
3884  if (fBase)
3885  fBase->Delete();
3886  delete fBase; fBase = 0;
3887 
3888  if (fRealData)
3889  fRealData->Delete();
3890  delete fRealData; fRealData=0;
3891 }
3892 
3893 ////////////////////////////////////////////////////////////////////////////////
3894 /// Resets the menu list to it's standard value.
3895 
3897 {
3898  if (fClassMenuList)
3900  else
3901  fClassMenuList = new TList();
3903 }
3904 
3905 ////////////////////////////////////////////////////////////////////////////////
3906 /// The ls function lists the contents of a class on stdout. Ls output
3907 /// is typically much less verbose then Dump().
3908 /// If options contains 'streamerinfo', run ls on the list of streamerInfos
3909 /// and the list of conversion streamerInfos.
3910 
3911 void TClass::ls(Option_t *options) const
3912 {
3913  TNamed::ls(options);
3914  if (options==0 || options[0]==0) return;
3915 
3916  if (strstr(options,"streamerinfo")!=0) {
3917  GetStreamerInfos()->ls(options);
3918 
3919  if (fConversionStreamerInfo.load()) {
3920  std::map<std::string, TObjArray*>::iterator it;
3921  std::map<std::string, TObjArray*>::iterator end = (*fConversionStreamerInfo).end();
3922  for( it = (*fConversionStreamerInfo).begin(); it != end; ++it ) {
3923  it->second->ls(options);
3924  }
3925  }
3926  }
3927 }
3928 
3929 ////////////////////////////////////////////////////////////////////////////////
3930 /// Makes a customizable version of the popup menu list, i.e. makes a list
3931 /// of TClassMenuItem objects of methods accessible by context menu.
3932 /// The standard (and different) way consists in having just one element
3933 /// in this list, corresponding to the whole standard list.
3934 /// Once the customizable version is done, one can remove or add elements.
3935 
3937 {
3939  TClassMenuItem *menuItem;
3940 
3941  // Make sure fClassMenuList is initialized and empty.
3942  GetMenuList()->Delete();
3943 
3944  TList* methodList = new TList;
3945  GetMenuItems(methodList);
3946 
3947  TMethod *method;
3948  TMethodArg *methodArg;
3949  TClass *classPtr = 0;
3950  TIter next(methodList);
3951 
3952  while ((method = (TMethod*) next())) {
3953  // if go to a mother class method, add separator
3954  if (classPtr != method->GetClass()) {
3955  menuItem = new TClassMenuItem(TClassMenuItem::kPopupSeparator, this);
3956  fClassMenuList->AddLast(menuItem);
3957  classPtr = method->GetClass();
3958  }
3959  // Build the signature of the method
3960  TString sig;
3961  TList* margsList = method->GetListOfMethodArgs();
3962  TIter nextarg(margsList);
3963  while ((methodArg = (TMethodArg*)nextarg())) {
3964  sig = sig+","+methodArg->GetFullTypeName();
3965  }
3966  if (sig.Length()!=0) sig.Remove(0,1); // remove first comma
3968  method->GetName(), method->GetName(),0,
3969  sig.Data(),-1,TClassMenuItem::kIsSelf);
3970  if (method->IsMenuItem() == kMenuToggle) menuItem->SetToggle();
3971  fClassMenuList->Add(menuItem);
3972  }
3973  delete methodList;
3974 }
3975 
3976 ////////////////////////////////////////////////////////////////////////////////
3977 /// Register the fact that an object was moved from the memory location
3978 /// 'arenaFrom' to the memory location 'arenaTo'.
3979 
3980 void TClass::Move(void *arenaFrom, void *arenaTo) const
3981 {
3982  // If/when we have access to a copy constructor (or better to a move
3983  // constructor), this function should also perform the data move.
3984  // For now we just information the repository.
3985 
3986  if ((GetState() <= kEmulated) && !fCollectionProxy) {
3987  MoveAddressInRepository("TClass::Move",arenaFrom,arenaTo,this);
3988  }
3989 }
3990 
3991 ////////////////////////////////////////////////////////////////////////////////
3992 /// Return the list of menu items associated with the class.
3993 
3995  if (!fClassMenuList) {
3996  fClassMenuList = new TList();
3997  fClassMenuList->Add(new TClassMenuItem(TClassMenuItem::kPopupStandardList, const_cast<TClass*>(this)));
3998  }
3999  return fClassMenuList;
4000 }
4001 
4002 ////////////////////////////////////////////////////////////////////////////////
4003 /// Return (create an empty one if needed) the list of functions.
4004 /// The major difference with GetListOfMethod is that this returns
4005 /// the internal type of fMethod and thus can not be made public.
4006 /// It also never 'loads' the content of the list.
4007 
4009 {
4010  if (!fMethod.load()) {
4011  std::unique_ptr<TListOfFunctions> temp{ new TListOfFunctions(this) };
4012  TListOfFunctions* expected = nullptr;
4013  if(fMethod.compare_exchange_strong(expected, temp.get()) ) {
4014  temp.release();
4015  }
4016  }
4017  return fMethod;
4018 }
4019 
4020 
4021 ////////////////////////////////////////////////////////////////////////////////
4022 /// Return pointer to method without looking at parameters.
4023 /// Does not look in (possible) base classes.
4024 /// Has the side effect of loading all the TMethod object in the list
4025 /// of the class.
4026 
4027 TMethod *TClass::GetMethodAny(const char *method)
4028 {
4029  if (!HasInterpreterInfo()) return 0;
4030  return (TMethod*) GetMethodList()->FindObject(method);
4031 }
4032 
4033 ////////////////////////////////////////////////////////////////////////////////
4034 /// Return pointer to method without looking at parameters.
4035 /// Does look in all base classes.
4036 
4037 TMethod *TClass::GetMethodAllAny(const char *method)
4038 {
4039  if (!HasInterpreterInfo()) return 0;
4040 
4041  TMethod* m = GetMethodAny(method);
4042  if (m) return m;
4043 
4044  TBaseClass *base;
4045  TIter nextb(GetListOfBases());
4046  while ((base = (TBaseClass *) nextb())) {
4047  TClass *c = base->GetClassPointer();
4048  if (c) {
4049  m = c->GetMethodAllAny(method);
4050  if (m) return m;
4051  }
4052  }
4053 
4054  return 0;
4055 }
4056 
4057 ////////////////////////////////////////////////////////////////////////////////
4058 /// Find the best method (if there is one) matching the parameters.
4059 /// The params string must contain argument values, like "3189, \"aap\", 1.3".
4060 /// The function invokes GetClassMethod to search for a possible method
4061 /// in the class itself or in its base classes. Returns 0 in case method
4062 /// is not found.
4063 
4064 TMethod *TClass::GetMethod(const char *method, const char *params,
4065  Bool_t objectIsConst /* = kFALSE */)
4066 {
4068  if (!fClassInfo) return 0;
4069 
4070  if (!gInterpreter)
4071  Fatal("GetMethod", "gInterpreter not initialized");
4072 
4073  TInterpreter::DeclId_t decl = gInterpreter->GetFunctionWithValues(fClassInfo,
4074  method, params,
4075  objectIsConst);
4076 
4077  if (!decl) return 0;
4078 
4079  // search recursively in this class or its base classes
4081  if (f) return f;
4082 
4083  Error("GetMethod",
4084  "\nDid not find matching TMethod <%s> with \"%s\" %sfor %s",
4085  method,params,objectIsConst ? "const " : "", GetName());
4086  return 0;
4087 }
4088 
4089 
4090 ////////////////////////////////////////////////////////////////////////////////
4091 /// Find a method with decl id in this class or its bases.
4092 
4094  TFunction *f = GetMethodList()->Get(declId);
4095  if (f) return (TMethod*)f;
4096 
4097  TBaseClass *base;
4099  while ((base = (TBaseClass *) next())) {
4100  TClass *clBase = base->GetClassPointer();
4101  if (clBase) {
4102  f = clBase->FindClassOrBaseMethodWithId(declId);
4103  if (f) return (TMethod*)f;
4104  }
4105  }
4106  return 0;
4107 }
4108 
4109 ////////////////////////////////////////////////////////////////////////////////
4110 /// Find the method with a given prototype. The proto string must be of the
4111 /// form: "char*,int,double". Returns 0 in case method is not found.
4112 
4113 TMethod *TClass::GetMethodWithPrototype(const char *method, const char *proto,
4114  Bool_t objectIsConst /* = kFALSE */,
4115  ROOT::EFunctionMatchMode mode /* = ROOT::kConversionMatch */)
4116 {
4118  if (!fClassInfo) return 0;
4119 
4120  if (!gInterpreter)
4121  Fatal("GetMethodWithPrototype", "gInterpreter not initialized");
4122 
4123  TInterpreter::DeclId_t decl = gInterpreter->GetFunctionWithPrototype(fClassInfo,
4124  method, proto,
4125  objectIsConst, mode);
4126 
4127  if (!decl) return 0;
4129  if (f) return f;
4130  Error("GetMethodWithPrototype",
4131  "\nDid not find matching TMethod <%s> with \"%s\" %sfor %s",
4132  method,proto,objectIsConst ? "const " : "", GetName());
4133  return 0;
4134 }
4135 
4136 ////////////////////////////////////////////////////////////////////////////////
4137 /// Look for a method in this class that has the interface function
4138 /// address faddr.
4139 
4141 {
4142  if (!HasInterpreterInfo()) return 0;
4143 
4144  TMethod *m;
4146  while ((m = (TMethod *) next())) {
4147  if (faddr == (Long_t)m->InterfaceMethod())
4148  return m;
4149  }
4150  return 0;
4151 }
4152 
4153 ////////////////////////////////////////////////////////////////////////////////
4154 /// Look for a method in this class that has the name and matches the parameters.
4155 /// The params string must contain argument values, like "3189, \"aap\", 1.3".
4156 /// Returns 0 in case method is not found.
4157 /// See TClass::GetMethod to also search the base classes.
4158 
4159 TMethod *TClass::GetClassMethod(const char *name, const char* params,
4160  Bool_t objectIsConst /* = kFALSE */)
4161 {
4163  if (!fClassInfo) return 0;
4164 
4165  if (!gInterpreter)
4166  Fatal("GetClassMethod", "gInterpreter not initialized");
4167 
4168  TInterpreter::DeclId_t decl = gInterpreter->GetFunctionWithValues(fClassInfo,
4169  name, params,
4170  objectIsConst);
4171 
4172  if (!decl) return 0;
4173 
4174  TFunction *f = GetMethodList()->Get(decl);
4175 
4176  return (TMethod*)f; // Could be zero if the decl is actually in a base class.
4177 }
4178 
4179 ////////////////////////////////////////////////////////////////////////////////
4180 /// Find the method with a given prototype. The proto string must be of the
4181 /// form: "char*,int,double". Returns 0 in case method is not found.
4182 /// See TClass::GetMethodWithPrototype to also search the base classes.
4183 
4184 TMethod *TClass::GetClassMethodWithPrototype(const char *name, const char* proto,
4185  Bool_t objectIsConst /* = kFALSE */,
4186  ROOT::EFunctionMatchMode mode /* = ROOT::kConversionMatch */)
4187 {
4189  if (!fClassInfo) return 0;
4190 
4191  if (!gInterpreter)
4192  Fatal("GetClassMethodWithPrototype", "gInterpreter not initialized");
4193 
4194  TInterpreter::DeclId_t decl = gInterpreter->GetFunctionWithPrototype(fClassInfo,
4195  name, proto,
4196  objectIsConst,
4197  mode);
4198 
4199  if (!decl) return 0;
4200 
4201  TFunction *f = GetMethodList()->Get(decl);
4202 
4203  return (TMethod*)f; // Could be zero if the decl is actually in a base class.
4204 }
4205 
4206 ////////////////////////////////////////////////////////////////////////////////
4207 /// Return the number of data members of this class
4208 /// Note that in case the list of data members is not yet created, it will be done
4209 /// by GetListOfDataMembers().
4210 
4212 {
4213  if (!HasDataMemberInfo()) return 0;
4214 
4215  TList *lm = GetListOfDataMembers();
4216  if (lm)
4217  return lm->GetSize();
4218  else
4219  return 0;
4220 }
4221 
4222 ////////////////////////////////////////////////////////////////////////////////
4223 /// Return the number of methods of this class
4224 /// Note that in case the list of methods is not yet created, it will be done
4225 /// by GetListOfMethods().
4226 /// This will also load/populate the list of methods, to get 'just' the
4227 /// number of currently loaded methods use:
4228 /// cl->GetListOfMethods(false)->GetSize();
4229 
4231 {
4232  if (!HasInterpreterInfo()) return 0;
4233 
4234  TList *lm = GetListOfMethods();
4235  if (lm)
4236  return lm->GetSize();
4237  else
4238  return 0;
4239 }
4240 
4241 ////////////////////////////////////////////////////////////////////////////////
4242 /// returns a pointer to the TVirtualStreamerInfo object for version
4243 /// If the object does not exist, it is created
4244 ///
4245 /// Note: There are two special version numbers:
4246 ///
4247 /// - 0: Use the class version from the currently loaded class library.
4248 /// - -1: Assume no class library loaded (emulated class).
4249 ///
4250 /// Warning: If we create a new streamer info, whether or not the build
4251 /// optimizes is controlled externally to us by a global variable!
4252 /// Don't call us unless you have set that variable properly
4253 /// with TStreamer::Optimize()!
4254 ///
4255 
4257 {
4259  if (guess && guess->GetClassVersion() == version) {
4260  // If the StreamerInfo is assigned to the fLastReadInfo, we are
4261  // guaranteed it was built and compiled.
4262  return guess;
4263  }
4264 
4266 
4267  // Handle special version, 0 means currently loaded version.
4268  // Warning: This may be -1 for an emulated class.
4269  // If version == -2, the user is requested the emulated streamerInfo
4270  // for an abstract base class even though we have a dictionary for it.
4271  if (version == 0) {
4272  version = fClassVersion;
4273  }
4274  Int_t ninfos = fStreamerInfo->GetSize();
4275  if ((version < -1) || (version >= ninfos)) {
4276  Error("GetStreamerInfo", "class: %s, attempting to access a wrong version: %d", GetName(), version);
4277  // FIXME: Shouldn't we go to -1 here, or better just abort?
4278  version = 0;
4279  }
4281  if (!sinfo && (version != fClassVersion)) {
4282  // When the requested version does not exist we return
4283  // the TVirtualStreamerInfo for the currently loaded class version.
4284  // FIXME: This arguably makes no sense, we should warn and return nothing instead.
4285  // Note: This is done for STL collections
4286  // Note: fClassVersion could be -1 here (for an emulated class).
4287  // This is also the code path take for unversioned classes.
4289  }
4290  if (!sinfo) {
4291  // We just were not able to find a streamer info, we have to make a new one.
4292  TMmallocDescTemp setreset;
4293  sinfo = TVirtualStreamerInfo::Factory()->NewInfo(const_cast<TClass*>(this));
4295  if (gDebug > 0) {
4296  printf("Creating StreamerInfo for class: %s, version: %d\n", GetName(), fClassVersion);
4297  }
4299  // If we do not have a StreamerInfo for this version and we do not
4300  // have dictionary information nor a proxy, there is nothing to build!
4301  //
4302  sinfo->Build();
4303  }
4304  } else {
4305  if (!sinfo->IsCompiled()) {
4306  // Streamer info has not been compiled, but exists.
4307  // Therefore it was read in from a file and we have to do schema evolution?
4308  // Or it didn't have a dictionary before, but does now?
4309  sinfo->BuildOld();
4310  }
4311  }
4312  // Cache the current info if we now have it.
4313  if (version == fClassVersion) {
4314  fCurrentInfo = sinfo;
4315  }
4316  // If the compilation succeeded, remember this StreamerInfo.
4317  if (sinfo->IsCompiled()) fLastReadInfo = sinfo;
4318  return sinfo;
4319 }
4320 
4321 ////////////////////////////////////////////////////////////////////////////////
4322 /// For the case where the requestor class is emulated and this class is abstract,
4323 /// returns a pointer to the TVirtualStreamerInfo object for version with an emulated
4324 /// representation whether or not the class is loaded.
4325 ///
4326 /// If the object does not exist, it is created
4327 ///
4328 /// Note: There are two special version numbers:
4329 ///
4330 /// - 0: Use the class version from the currently loaded class library.
4331 /// - -1: Assume no class library loaded (emulated class).
4332 ///
4333 /// Warning: If we create a new streamer info, whether or not the build
4334 /// optimizes is controlled externally to us by a global variable!
4335 /// Don't call us unless you have set that variable properly
4336 /// with TStreamer::Optimize()!
4337 ///
4338 
4340 {
4342 
4343  TString newname( GetName() );
4344  newname += "@@emulated";
4345 
4346  TClass *emulated = TClass::GetClass(newname);
4347 
4348  TVirtualStreamerInfo* sinfo = 0;
4349 
4350  if (emulated) {
4351  sinfo = emulated->GetStreamerInfo(version);
4352  }
4353  if (!sinfo) {
4354  // The emulated version of the streamerInfo is explicitly requested and has
4355  // not been built yet.
4356 
4357  sinfo = (TVirtualStreamerInfo*) fStreamerInfo->At(version);
4358  if (!sinfo && (version != fClassVersion)) {
4359  // When the requested version does not exist we return
4360  // the TVirtualStreamerInfo for the currently loaded class version.
4361  // FIXME: This arguably makes no sense, we should warn and return nothing instead.
4363  }
4364  if (!sinfo) {
4365  // Let's take the first available StreamerInfo as a start
4366  Int_t ninfos = fStreamerInfo->GetEntriesFast() - 1;
4367  for (Int_t i = -1; sinfo == 0 && i < ninfos; ++i) {
4369  }
4370  }
4371  if (sinfo) {
4372  sinfo = dynamic_cast<TVirtualStreamerInfo*>( sinfo->Clone() );
4373  if (sinfo) {
4374  sinfo->SetClass(0);
4375  sinfo->SetName( newname );
4376  sinfo->BuildCheck();
4377  sinfo->BuildOld();
4378  sinfo->GetClass()->AddRule(TString::Format("sourceClass=%s targetClass=%s",GetName(),newname.Data()));
4379  } else
4380  Error("GetStreamerInfoAbstractEmulated", "could not create TVirtualStreamerInfo");
4381  }
4382  }
4383  return sinfo;
4384 }
4385 
4386 ////////////////////////////////////////////////////////////////////////////////
4387 /// For the case where the requestor class is emulated and this class is abstract,
4388 /// returns a pointer to the TVirtualStreamerInfo object for version with an emulated
4389 /// representation whether or not the class is loaded.
4390 ///
4391 /// If the object does not exist, it is created
4392 ///
4393 /// Warning: If we create a new streamer info, whether or not the build
4394 /// optimizes is controlled externally to us by a global variable!
4395 /// Don't call us unless you have set that variable properly
4396 /// with TStreamer::Optimize()!
4397 ///
4398 
4400 {
4402 
4403  TString newname( GetName() );
4404  newname += "@@emulated";
4405 
4406  TClass *emulated = TClass::GetClass(newname);
4407 
4408  TVirtualStreamerInfo* sinfo = 0;
4409 
4410  if (emulated) {
4411  sinfo = emulated->FindStreamerInfo(checksum);
4412  }
4413  if (!sinfo) {
4414  // The emulated version of the streamerInfo is explicitly requested and has
4415  // not been built yet.
4416 
4417  sinfo = (TVirtualStreamerInfo*) FindStreamerInfo(checksum);
4418  if (!sinfo && (checksum != fCheckSum)) {
4419  // When the requested version does not exist we return
4420  // the TVirtualStreamerInfo for the currently loaded class version.
4421  // FIXME: This arguably makes no sense, we should warn and return nothing instead.
4423  }
4424  if (!sinfo) {
4425  // Let's take the first available StreamerInfo as a start
4426  Int_t ninfos = fStreamerInfo->GetEntriesFast() - 1;
4427  for (Int_t i = -1; sinfo == 0 && i < ninfos; ++i) {
4429  }
4430  }
4431  if (sinfo) {
4432  sinfo = dynamic_cast<TVirtualStreamerInfo*>( sinfo->Clone() );
4433  if (sinfo) {
4434  sinfo->SetClass(0);
4435  sinfo->SetName( newname );
4436  sinfo->BuildCheck();
4437  sinfo->BuildOld();
4438  sinfo->GetClass()->AddRule(TString::Format("sourceClass=%s targetClass=%s",GetName(),newname.Data()));
4439  } else
4440  Error("GetStreamerInfoAbstractEmulated", "could not create TVirtualStreamerInfo");
4441  }
4442  }
4443  return sinfo;
4444 }
4445 
4446 ////////////////////////////////////////////////////////////////////////////////
4447 /// When the class kIgnoreTObjectStreamer bit is set, the automatically
4448 /// generated Streamer will not call TObject::Streamer.
4449 /// This option saves the TObject space overhead on the file.
4450 /// However, the information (fBits, fUniqueID) of TObject is lost.
4451 ///
4452 /// Note that to be effective for objects streamed object-wise this function
4453 /// must be called for the class deriving directly from TObject, eg, assuming
4454 /// that BigTrack derives from Track and Track derives from TObject, one must do:
4455 /// ~~~ {.cpp}
4456 /// Track::Class()->IgnoreTObjectStreamer();
4457 /// ~~~
4458 /// and not:
4459 /// ~~~ {.cpp}
4460 /// BigTrack::Class()->IgnoreTObjectStreamer();
4461 /// ~~~
4462 /// To be effective for object streamed member-wise or split in a TTree,
4463 /// this function must be called for the most derived class (i.e. BigTrack).
4464 
4466 {
4467  // We need to tak the lock since we are test and then setting fBits
4468  // and TStreamerInfo::fBits (and the StreamerInfo state in general)
4469  // which can also be modified by another thread.
4471 
4472  if ( doIgnore && TestBit(kIgnoreTObjectStreamer)) return;
4473  if (!doIgnore && !TestBit(kIgnoreTObjectStreamer)) return;
4475  if (sinfo) {
4476  if (sinfo->IsCompiled()) {
4477  // -- Warn the user that what they are doing cannot work.
4478  // Note: The reason is that TVirtualStreamerInfo::Build() examines
4479  // the kIgnoreTObjectStreamer bit and sets the TStreamerElement
4480  // type for the TObject base class streamer element it creates
4481  // to -1 as a flag. Later on the TStreamerInfo::Compile()
4482  // member function sees the flag and does not insert the base
4483  // class element into the compiled streamer info. None of this
4484  // machinery works correctly if we are called after the streamer
4485  // info has already been built and compiled.
4486  Error("IgnoreTObjectStreamer","Must be called before the creation of StreamerInfo");
4487  return;
4488  }
4489  }
4490  if (doIgnore) SetBit (kIgnoreTObjectStreamer);
4492 }
4493 
4494 ////////////////////////////////////////////////////////////////////////////////
4495 /// Return kTRUE if this class inherits from a class with name "classname".
4496 /// note that the function returns kTRUE in case classname is the class itself
4497 
4498 Bool_t TClass::InheritsFrom(const char *classname) const
4499 {
4500  if (strcmp(GetName(), classname) == 0) return kTRUE;
4501 
4502  return InheritsFrom(TClass::GetClass(classname,kTRUE,kTRUE));
4503 }
4504 
4505 ////////////////////////////////////////////////////////////////////////////////
4506 /// Return kTRUE if this class inherits from class cl.
4507 /// note that the function returns KTRUE in case cl is the class itself
4508 
4510 {
4511  if (!cl) return kFALSE;
4512  if (cl == this) return kTRUE;
4513 
4514  if (!HasDataMemberInfo()) {
4515  TVirtualStreamerInfo *sinfo = ((TClass *)this)->GetCurrentStreamerInfo();
4516  if (sinfo==0) sinfo = GetStreamerInfo();
4517  TIter next(sinfo->GetElements());
4518  TStreamerElement *element;
4519  while ((element = (TStreamerElement*)next())) {
4520  if (element->IsA() == TStreamerBase::Class()) {
4521  TClass *clbase = element->GetClassPointer();
4522  if (!clbase) return kFALSE; //missing class
4523  if (clbase->InheritsFrom(cl)) return kTRUE;
4524  }
4525  }
4526  return kFALSE;
4527  }
4528  // cast const away (only for member fBase which can be set in GetListOfBases())
4529  if (((TClass *)this)->GetBaseClass(cl)) return kTRUE;
4530  return kFALSE;
4531 }
4532 
4533 ////////////////////////////////////////////////////////////////////////////////
4534 /// Cast obj of this class type up to baseclass cl if up is true.
4535 /// Cast obj of this class type down from baseclass cl if up is false.
4536 /// If this class is not a baseclass of cl return 0, else the pointer
4537 /// to the cl part of this (up) or to this (down).
4538 
4539 void *TClass::DynamicCast(const TClass *cl, void *obj, Bool_t up)
4540 {
4541  if (cl == this) return obj;
4542 
4543  if (!HasDataMemberInfo()) return 0;
4544 
4545  Int_t off;
4546  if ((off = GetBaseClassOffset(cl, obj)) != -1) {
4547  if (up)
4548  return (void*)((Long_t)obj+off);
4549  else
4550  return (void*)((Long_t)obj-off);
4551  }
4552  return 0;
4553 }
4554 
4555 ////////////////////////////////////////////////////////////////////////////////
4556 /// Cast obj of this class type up to baseclass cl if up is true.
4557 /// Cast obj of this class type down from baseclass cl if up is false.
4558 /// If this class is not a baseclass of cl return 0, else the pointer
4559 /// to the cl part of this (up) or to this (down).
4560 
4561 const void *TClass::DynamicCast(const TClass *cl, const void *obj, Bool_t up)
4562 {
4563  return DynamicCast(cl,const_cast<void*>(obj),up);
4564 }
4565 
4566 ////////////////////////////////////////////////////////////////////////////////
4567 /// Return a pointer to a newly allocated object of this class.
4568 /// The class must have a default constructor. For meaning of
4569 /// defConstructor, see TClass::IsCallingNew().
4570 ///
4571 /// If quiet is true, do no issue a message via Error on case
4572 /// of problems, just return 0.
4573 ///
4574 /// The constructor actually called here can be customized by
4575 /// using the rootcint pragma:
4576 /// ~~~ {.cpp}
4577 /// #pragma link C++ ioctortype UserClass;
4578 /// ~~~
4579 /// For example, with this pragma and a class named MyClass,
4580 /// this method will called the first of the following 3
4581 /// constructors which exists and is public:
4582 /// ~~~ {.cpp}
4583 /// MyClass(UserClass*);
4584 /// MyClass(TRootIOCtor*);
4585 /// MyClass(); // Or a constructor with all its arguments defaulted.
4586 /// ~~~
4587 ///
4588 /// When more than one pragma ioctortype is used, the first seen as priority
4589 /// For example with:
4590 /// ~~~ {.cpp}
4591 /// #pragma link C++ ioctortype UserClass1;
4592 /// #pragma link C++ ioctortype UserClass2;
4593 /// ~~~
4594 /// We look in the following order:
4595 /// ~~~ {.cpp}
4596 /// MyClass(UserClass1*);
4597 /// MyClass(UserClass2*);
4598 /// MyClass(TRootIOCtor*);
4599 /// MyClass(); // Or a constructor with all its arguments defaulted.
4600 /// ~~~
4601 
4602 void *TClass::New(ENewType defConstructor, Bool_t quiet) const
4603 {
4604  void* p = 0;
4605 
4606  if (fNew) {
4607  // We have the new operator wrapper function,
4608  // so there is a dictionary and it was generated
4609  // by rootcint, so there should be a default
4610  // constructor we can call through the wrapper.
4611  TClass__GetCallingNew() = defConstructor;
4612  p = fNew(0);
4614  if (!p && !quiet) {
4615  //Error("New", "cannot create object of class %s version %d", GetName(), fClassVersion);
4616  Error("New", "cannot create object of class %s", GetName());
4617  }
4618  } else if (HasInterpreterInfo()) {
4619  // We have the dictionary but do not have the
4620  // constructor wrapper, so the dictionary was
4621  // not generated by rootcint. Let's try to
4622  // create the object by having the interpreter
4623  // call the new operator, hopefully the class
4624  // library is loaded and there will be a default
4625  // constructor we can call.
4626  // [This is very unlikely to work, but who knows!]
4627  TClass__GetCallingNew() = defConstructor;
4630  if (!p && !quiet) {
4631  //Error("New", "cannot create object of class %s version %d", GetName(), fClassVersion);
4632  Error("New", "cannot create object of class %s", GetName());
4633  }
4634  } else if (!HasInterpreterInfo() && fCollectionProxy) {
4635  // There is no dictionary at all, so this is an emulated
4636  // class; however we do have the services of a collection proxy,
4637  // so this is an emulated STL class.
4638  TClass__GetCallingNew() = defConstructor;
4639  p = fCollectionProxy->New();
4641  if (!p && !quiet) {
4642  //Error("New", "cannot create object of class %s version %d", GetName(), fClassVersion);
4643  Error("New", "cannot create object of class %s", GetName());
4644  }
4645  } else if (!HasInterpreterInfo() && !fCollectionProxy) {
4646  // There is no dictionary at all and we do not have
4647  // the services of a collection proxy available, so
4648  // use the streamer info to approximate calling a
4649  // constructor (basically we just make sure that the
4650  // pointer data members are null, unless they are marked
4651  // as preallocated with the "->" comment, in which case
4652  // we default-construct an object to point at).
4653 
4654  // Do not register any TObject's that we create
4655  // as a result of creating this object.
4656  // FIXME: Why do we do this?
4657  // FIXME: Partial Answer: Is this because we may never actually deregister them???
4658 
4659  Bool_t statsave = GetObjectStat();
4660  if(statsave) {
4662  }
4664  if (!sinfo && !quiet) {
4665  Error("New", "Cannot construct class '%s' version %d, no streamer info available!", GetName(), fClassVersion);
4666  return 0;
4667  }
4668 
4669  TClass__GetCallingNew() = defConstructor;
4670  p = sinfo->New();
4672 
4673  // FIXME: Mistake? See note above at the GetObjectStat() call.
4674  // Allow TObject's to be registered again.
4675  if(statsave) {
4676  SetObjectStat(statsave);
4677  }
4678 
4679  // Register the object for special handling in the destructor.
4680  if (p) {
4681  RegisterAddressInRepository("New",p,this);
4682  } else {
4683  Error("New", "Failed to construct class '%s' using streamer info", GetName());
4684  }
4685  } else {
4686  Fatal("New", "This cannot happen!");
4687  }
4688 
4689  return p;
4690 }
4691 
4692 ////////////////////////////////////////////////////////////////////////////////
4693 /// Return a pointer to a newly allocated object of this class.
4694 /// The class must have a default constructor. For meaning of
4695 /// defConstructor, see TClass::IsCallingNew().
4696 
4697 void *TClass::New(void *arena, ENewType defConstructor) const
4698 {
4699  void* p = 0;
4700 
4701  if (fNew) {
4702  // We have the new operator wrapper function,
4703  // so there is a dictionary and it was generated
4704  // by rootcint, so there should be a default
4705  // constructor we can call through the wrapper.
4706  TClass__GetCallingNew() = defConstructor;
4707  p = fNew(arena);
4709  if (!p) {
4710  Error("New with placement", "cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
4711  }
4712  } else if (HasInterpreterInfo()) {
4713  // We have the dictionary but do not have the
4714  // constructor wrapper, so the dictionary was
4715  // not generated by rootcint. Let's try to
4716  // create the object by having the interpreter
4717  // call the new operator, hopefully the class
4718  // library is loaded and there will be a default
4719  // constructor we can call.
4720  // [This is very unlikely to work, but who knows!]
4721  TClass__GetCallingNew() = defConstructor;
4722  p = gCling->ClassInfo_New(GetClassInfo(),arena);
4724  if (!p) {
4725  Error("New with placement", "cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
4726  }
4727  } else if (!HasInterpreterInfo() && fCollectionProxy) {
4728  // There is no dictionary at all, so this is an emulated
4729  // class; however we do have the services of a collection proxy,
4730  // so this is an emulated STL class.
4731  TClass__GetCallingNew() = defConstructor;
4732  p = fCollectionProxy->New(arena);
4734  } else if (!HasInterpreterInfo() && !fCollectionProxy) {
4735  // There is no dictionary at all and we do not have
4736  // the services of a collection proxy available, so
4737  // use the streamer info to approximate calling a
4738  // constructor (basically we just make sure that the
4739  // pointer data members are null, unless they are marked
4740  // as preallocated with the "->" comment, in which case
4741  // we default-construct an object to point at).
4742 
4743  // ???BUG??? ???WHY???
4744  // Do not register any TObject's that we create
4745  // as a result of creating this object.
4746  Bool_t statsave = GetObjectStat();
4747  if(statsave) {
4749  }
4750 
4752  if (!sinfo) {
4753  Error("New with placement", "Cannot construct class '%s' version %d at address %p, no streamer info available!", GetName(), fClassVersion, arena);
4754  return 0;
4755  }
4756 
4757  TClass__GetCallingNew() = defConstructor;
4758  p = sinfo->New(arena);
4760 
4761  // ???BUG???
4762  // Allow TObject's to be registered again.
4763  if(statsave) {
4764  SetObjectStat(statsave);
4765  }
4766 
4767  // Register the object for special handling in the destructor.
4768  if (p) {
4769  RegisterAddressInRepository("TClass::New with placement",p,this);
4770  }
4771  } else {
4772  Error("New with placement", "This cannot happen!");
4773  }
4774 
4775  return p;
4776 }
4777 
4778 ////////////////////////////////////////////////////////////////////////////////
4779 /// Return a pointer to a newly allocated array of objects
4780 /// of this class.
4781 /// The class must have a default constructor. For meaning of
4782 /// defConstructor, see TClass::IsCallingNew().
4783 
4784 void *TClass::NewArray(Long_t nElements, ENewType defConstructor) const
4785 {
4786  void* p = 0;
4787 
4788  if (fNewArray) {
4789  // We have the new operator wrapper function,
4790  // so there is a dictionary and it was generated
4791  // by rootcint, so there should be a default
4792  // constructor we can call through the wrapper.
4793  TClass__GetCallingNew() = defConstructor;
4794  p = fNewArray(nElements, 0);
4796  if (!p) {
4797  Error("NewArray", "cannot create object of class %s version %d", GetName(), fClassVersion);
4798  }
4799  } else if (HasInterpreterInfo()) {
4800  // We have the dictionary but do not have the
4801  // constructor wrapper, so the dictionary was
4802  // not generated by rootcint. Let's try to
4803  // create the object by having the interpreter
4804  // call the new operator, hopefully the class
4805  // library is loaded and there will be a default
4806  // constructor we can call.
4807  // [This is very unlikely to work, but who knows!]
4808  TClass__GetCallingNew() = defConstructor;
4809  p = gCling->ClassInfo_New(GetClassInfo(),nElements);
4811  if (!p) {
4812  Error("NewArray", "cannot create object of class %s version %d", GetName(), fClassVersion);
4813  }
4814  } else if (!HasInterpreterInfo() && fCollectionProxy) {
4815  // There is no dictionary at all, so this is an emulated
4816  // class; however we do have the services of a collection proxy,
4817  // so this is an emulated STL class.
4818  TClass__GetCallingNew() = defConstructor;
4819  p = fCollectionProxy->NewArray(nElements);
4821  } else if (!HasInterpreterInfo() && !fCollectionProxy) {
4822  // There is no dictionary at all and we do not have
4823  // the services of a collection proxy available, so
4824  // use the streamer info to approximate calling a
4825  // constructor (basically we just make sure that the
4826  // pointer data members are null, unless they are marked
4827  // as preallocated with the "->" comment, in which case
4828  // we default-construct an object to point at).
4829 
4830  // ???BUG??? ???WHY???
4831  // Do not register any TObject's that we create
4832  // as a result of creating this object.
4833  Bool_t statsave = GetObjectStat();
4834  if(statsave) {
4836  }
4837 
4839  if (!sinfo) {
4840  Error("NewArray", "Cannot construct class '%s' version %d, no streamer info available!", GetName(), fClassVersion);
4841  return 0;
4842  }
4843 
4844  TClass__GetCallingNew() = defConstructor;
4845  p = sinfo->NewArray(nElements);
4847 
4848  // ???BUG???
4849  // Allow TObject's to be registered again.
4850  if(statsave) {
4851  SetObjectStat(statsave);
4852  }
4853 
4854  // Register the object for special handling in the destructor.
4855  if (p) {
4856  RegisterAddressInRepository("TClass::NewArray",p,this);
4857  }
4858  } else {
4859  Error("NewArray", "This cannot happen!");
4860  }
4861 
4862  return p;
4863 }
4864 
4865 ////////////////////////////////////////////////////////////////////////////////
4866 /// Return a pointer to a newly allocated object of this class.
4867 /// The class must have a default constructor. For meaning of
4868 /// defConstructor, see TClass::IsCallingNew().
4869 
4870 void *TClass::NewArray(Long_t nElements, void *arena, ENewType defConstructor) const
4871 {
4872  void* p = 0;
4873 
4874  if (fNewArray) {
4875  // We have the new operator wrapper function,
4876  // so there is a dictionary and it was generated
4877  // by rootcint, so there should be a default
4878  // constructor we can call through the wrapper.
4879  TClass__GetCallingNew() = defConstructor;
4880  p = fNewArray(nElements, arena);
4882  if (!p) {
4883  Error("NewArray with placement", "cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
4884  }
4885  } else if (HasInterpreterInfo()) {
4886  // We have the dictionary but do not have the constructor wrapper,
4887  // so the dictionary was not generated by rootcint (it was made either
4888  // by cint or by some external mechanism). Let's try to create the
4889  // object by having the interpreter call the new operator, either the
4890  // class library is loaded and there is a default constructor we can
4891  // call, or the class is interpreted and we will call the default
4892  // constructor that way, or no default constructor is available and
4893  // we fail.
4894  TClass__GetCallingNew() = defConstructor;
4895  p = gCling->ClassInfo_New(GetClassInfo(),nElements, arena);
4897  if (!p) {
4898  Error("NewArray with placement", "cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
4899  }
4900  } else if (!HasInterpreterInfo() && fCollectionProxy) {
4901  // There is no dictionary at all, so this is an emulated
4902  // class; however we do have the services of a collection proxy,
4903  // so this is an emulated STL class.
4904  TClass__GetCallingNew() = defConstructor;
4905  p = fCollectionProxy->NewArray(nElements, arena);
4907  } else if (!HasInterpreterInfo() && !fCollectionProxy) {
4908  // There is no dictionary at all and we do not have
4909  // the services of a collection proxy available, so
4910  // use the streamer info to approximate calling a
4911  // constructor (basically we just make sure that the
4912  // pointer data members are null, unless they are marked
4913  // as preallocated with the "->" comment, in which case
4914  // we default-construct an object to point at).
4915 
4916  // ???BUG??? ???WHY???
4917  // Do not register any TObject's that we create
4918  // as a result of creating this object.
4919  Bool_t statsave = GetObjectStat();
4920  if(statsave) {
4922  }
4923 
4925  if (!sinfo) {
4926  Error("NewArray with placement", "Cannot construct class '%s' version %d at address %p, no streamer info available!", GetName(), fClassVersion, arena);
4927  return 0;
4928  }
4929 
4930  TClass__GetCallingNew() = defConstructor;
4931  p = sinfo->NewArray(nElements, arena);
4933 
4934  // ???BUG???
4935  // Allow TObject's to be registered again.
4936  if(statsave) {
4937  SetObjectStat(statsave);
4938  }
4939 
4941  // We always register emulated objects, we need to always
4942  // use the streamer info to destroy them.
4943  }
4944 
4945  // Register the object for special handling in the destructor.
4946  if (p) {
4947  RegisterAddressInRepository("TClass::NewArray with placement",p,this);
4948  }
4949  } else {
4950  Error("NewArray with placement", "This cannot happen!");
4951  }
4952 
4953  return p;
4954 }
4955 
4956 ////////////////////////////////////////////////////////////////////////////////
4957 /// Explicitly call destructor for object.
4958 
4959 void TClass::Destructor(void *obj, Bool_t dtorOnly)
4960 {
4961  // Do nothing if passed a null pointer.
4962  if (obj == 0) return;
4963 
4964  void* p = obj;
4965 
4966  if (dtorOnly && fDestructor) {
4967  // We have the destructor wrapper, use it.
4968  fDestructor(p);
4969  } else if ((!dtorOnly) && fDelete) {
4970  // We have the delete wrapper, use it.
4971  fDelete(p);
4972  } else if (HasInterpreterInfo()) {
4973  // We have the dictionary but do not have the
4974  // destruct/delete wrapper, so the dictionary was
4975  // not generated by rootcint (it could have been
4976  // created by cint or by some external mechanism).
4977  // Let's have the interpreter call the destructor,
4978  // either the code will be in a loaded library,
4979  // or it will be interpreted, otherwise we fail
4980  // because there is no destructor code at all.
4981  if (dtorOnly) {
4983  } else {
4985  }
4986  } else if (!HasInterpreterInfo() && fCollectionProxy) {
4987  // There is no dictionary at all, so this is an emulated
4988  // class; however we do have the services of a collection proxy,
4989  // so this is an emulated STL class.
4990  fCollectionProxy->Destructor(p, dtorOnly);
4991  } else if (!HasInterpreterInfo() && !fCollectionProxy) {
4992  // There is no dictionary at all and we do not have
4993  // the services of a collection proxy available, so
4994  // use the streamer info to approximate calling a
4995  // destructor.
4996 
4997  Bool_t inRepo = kTRUE;
4998  Bool_t verFound = kFALSE;
4999 
5000  // Was this object allocated through TClass?
5001  std::multiset<Version_t> knownVersions;
5003 
5004  {
5005  RepoCont_t::iterator iter = gObjectVersionRepository.find(p);
5006  if (iter == gObjectVersionRepository.end()) {
5007  // No, it wasn't, skip special version handling.
5008  //Error("Destructor2", "Attempt to delete unregistered object of class '%s' at address %p!", GetName(), p);
5009  inRepo = kFALSE;
5010  } else {
5011  //objVer = iter->second;
5012  for (; (iter != gObjectVersionRepository.end()) && (iter->first == p); ++iter) {
5013  Version_t ver = iter->second.fVersion;
5014  knownVersions.insert(ver);
5015  if (ver == fClassVersion && this == iter->second.fClass) {
5016  verFound = kTRUE;
5017  }
5018  }
5019  }
5020  }
5021 
5022  if (!inRepo || verFound) {
5023  // The object was allocated using code for the same class version
5024  // as is loaded now. We may proceed without worry.
5026  if (si) {
5027  si->Destructor(p, dtorOnly);
5028  } else {
5029  Error("Destructor", "No streamer info available for class '%s' version %d at address %p, cannot destruct emulated object!", GetName(), fClassVersion, p);
5030  Error("Destructor", "length of fStreamerInfo is %d", fStreamerInfo->GetSize());
5032  for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
5033  Error("Destructor", "fStreamerInfo->At(%d): %p", i, fStreamerInfo->At(i));
5034  if (fStreamerInfo->At(i) != 0) {
5035  Error("Destructor", "Doing Dump() ...");
5037  }
5038  }
5039  }
5040  } else {
5041  // The loaded class version is not the same as the version of the code
5042  // which was used to allocate this object. The best we can do is use
5043  // the TVirtualStreamerInfo to try to free up some of the allocated memory.
5044  Error("Destructor", "Loaded class %s version %d is not registered for addr %p", GetName(), fClassVersion, p);
5045 #if 0
5047  if (si) {
5048  si->Destructor(p, dtorOnly);
5049  } else {
5050  Error("Destructor2", "No streamer info available for class '%s' version %d, cannot destruct object at addr: %p", GetName(), objVer, p);
5051  Error("Destructor2", "length of fStreamerInfo is %d", fStreamerInfo->GetSize());
5053  for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
5054  Error("Destructor2", "fStreamerInfo->At(%d): %p", i, fStreamerInfo->At(i));
5055  if (fStreamerInfo->At(i) != 0) {
5056  // Do some debugging output.
5057  Error("Destructor2", "Doing Dump() ...");
5059  }
5060  }
5061  }
5062 #endif
5063  }
5064 
5065  if (inRepo && verFound && p) {
5066  UnregisterAddressInRepository("TClass::Destructor",p,this);
5067  }
5068  } else {
5069  Error("Destructor", "This cannot happen! (class %s)", GetName());
5070  }
5071 }
5072 
5073 ////////////////////////////////////////////////////////////////////////////////
5074 /// Explicitly call operator delete[] for an array.
5075 
5076 void TClass::DeleteArray(void *ary, Bool_t dtorOnly)
5077 {
5078  // Do nothing if passed a null pointer.
5079  if (ary == 0) return;
5080 
5081  // Make a copy of the address.
5082  void* p = ary;
5083 
5084  if (fDeleteArray) {
5085  if (dtorOnly) {
5086  Error("DeleteArray", "Destructor only is not supported!");
5087  } else {
5088  // We have the array delete wrapper, use it.
5089  fDeleteArray(ary);
5090  }
5091  } else if (HasInterpreterInfo()) {
5092  // We have the dictionary but do not have the
5093  // array delete wrapper, so the dictionary was
5094  // not generated by rootcint. Let's try to
5095  // delete the array by having the interpreter
5096  // call the array delete operator, hopefully
5097  // the class library is loaded and there will be
5098  // a destructor we can call.
5099  gCling->ClassInfo_DeleteArray(GetClassInfo(),ary, dtorOnly);
5100  } else if (!HasInterpreterInfo() && fCollectionProxy) {
5101  // There is no dictionary at all, so this is an emulated
5102  // class; however we do have the services of a collection proxy,
5103  // so this is an emulated STL class.
5104  fCollectionProxy->DeleteArray(ary, dtorOnly);
5105  } else if (!HasInterpreterInfo() && !fCollectionProxy) {
5106  // There is no dictionary at all and we do not have
5107  // the services of a collection proxy available, so
5108  // use the streamer info to approximate calling the
5109  // array destructor.
5110 
5111  Bool_t inRepo = kTRUE;
5112  Bool_t verFound = kFALSE;
5113 
5114  // Was this array object allocated through TClass?
5115  std::multiset<Version_t> knownVersions;
5116  {
5118  RepoCont_t::iterator iter = gObjectVersionRepository.find(p);
5119  if (iter == gObjectVersionRepository.end()) {
5120  // No, it wasn't, we cannot know what to do.
5121  //Error("DeleteArray", "Attempt to delete unregistered array object, element type '%s', at address %p!", GetName(), p);
5122  inRepo = kFALSE;
5123  } else {
5124  for (; (iter != gObjectVersionRepository.end()) && (iter->first == p); ++iter) {
5125  Version_t ver = iter->second.fVersion;
5126  knownVersions.insert(ver);
5127  if (ver == fClassVersion && this == iter->second.fClass ) {
5128  verFound = kTRUE;
5129  }
5130  }
5131  }
5132  }
5133 
5134  if (!inRepo || verFound) {
5135  // The object was allocated using code for the same class version
5136  // as is loaded now. We may proceed without worry.
5138  if (si) {
5139  si->DeleteArray(ary, dtorOnly);
5140  } else {
5141  Error("DeleteArray", "No streamer info available for class '%s' version %d at address %p, cannot destruct object!", GetName(), fClassVersion, ary);
5142  Error("DeleteArray", "length of fStreamerInfo is %d", fStreamerInfo->GetSize());
5144  for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
5145  Error("DeleteArray", "fStreamerInfo->At(%d): %p", v, fStreamerInfo->At(i));
5146  if (fStreamerInfo->At(i)) {
5147  Error("DeleteArray", "Doing Dump() ...");
5149  }
5150  }
5151  }
5152  } else {
5153  // The loaded class version is not the same as the version of the code
5154  // which was used to allocate this array. The best we can do is use
5155  // the TVirtualStreamerInfo to try to free up some of the allocated memory.
5156  Error("DeleteArray", "Loaded class version %d is not registered for addr %p", fClassVersion, p);
5157 
5158 
5159 
5160 #if 0
5162  if (si) {
5163  si->DeleteArray(ary, dtorOnly);
5164  } else {
5165  Error("DeleteArray", "No streamer info available for class '%s' version %d at address %p, cannot destruct object!", GetName(), objVer, ary);
5166  Error("DeleteArray", "length of fStreamerInfo is %d", fStreamerInfo->GetSize());
5168  for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
5169  Error("DeleteArray", "fStreamerInfo->At(%d): %p", v, fStreamerInfo->At(i));
5170  if (fStreamerInfo->At(i)) {
5171  // Print some debugging info.
5172  Error("DeleteArray", "Doing Dump() ...");
5174  }
5175  }
5176  }
5177 #endif
5178 
5179 
5180  }
5181 
5182  // Deregister the object for special handling in the destructor.
5183  if (inRepo && verFound && p) {
5184  UnregisterAddressInRepository("TClass::DeleteArray",p,this);
5185  }
5186  } else {
5187  Error("DeleteArray", "This cannot happen! (class '%s')", GetName());
5188  }
5189 }
5190 
5191 ////////////////////////////////////////////////////////////////////////////////
5192 /// Set the splitability of this class:
5193 /// -1: Use the default calculation
5194 /// 0: Disallow splitting
5195 /// 1: Always allow splitting.
5196 
5198 {
5199  fCanSplit = splitmode;
5200 }
5201 
5202 ////////////////////////////////////////////////////////////////////////////////
5203 /// Private function. Set the class version for the 'class' represented by
5204 /// this TClass object. See the public interface:
5205 /// ROOT::ResetClassVersion
5206 /// defined in TClassTable.cxx
5207 ///
5208 /// Note on class version numbers:
5209 /// - If no class number has been specified, TClass::GetVersion will return -1
5210 /// - The Class Version 0 request the whole object to be transient
5211 /// - The Class Version 1, unless specified via ClassDef indicates that the
5212 /// I/O should use the TClass checksum to distinguish the layout of the class
5213 
5215 {
5216  fClassVersion = version;
5217  fCurrentInfo = 0;
5218 }
5219 
5220 ////////////////////////////////////////////////////////////////////////////////
5221 /// Determine and set pointer to current TVirtualStreamerInfo
5222 
5224 {
5226  if(!fCurrentInfo.load()) {
5228  }
5229  return fCurrentInfo;
5230 }
5231 
5232 ////////////////////////////////////////////////////////////////////////////////
5233 /// Set pointer to current TVirtualStreamerInfo
5234 
5236 {
5237  fCurrentInfo = info;
5238 }
5239 
5240 ////////////////////////////////////////////////////////////////////////////////
5241 /// Return size of object of this class.
5242 
5244 {
5245  if (fSizeof!=-1) return fSizeof;
5246  if (fCollectionProxy) return fCollectionProxy->Sizeof();
5248  return GetStreamerInfo()->GetSize();
5249 }
5250 
5251 ////////////////////////////////////////////////////////////////////////////////
5252 /// Load class description from I/O buffer and return class object.
5253 
5255 {
5256  UInt_t maxsize = 256;
5257  char *s = new char[maxsize];
5258 
5259  Int_t pos = b.Length();
5260 
5261  b.ReadString(s, maxsize); // Reads at most maxsize - 1 characters, plus null at end.
5262  while (strlen(s) == (maxsize - 1)) {
5263  // The classname is too large, try again with a large buffer.
5264  b.SetBufferOffset(pos);
5265  maxsize = 2*maxsize;
5266  delete [] s;
5267  s = new char[maxsize];
5268  b.ReadString(s, maxsize); // Reads at most maxsize - 1 characters, plus null at end.
5269  }
5270 
5271  TClass *cl = TClass::GetClass(s, kTRUE);
5272  if (!cl)
5273  ::Error("TClass::Load", "dictionary of class %s not found", s);
5274 
5275  delete [] s;
5276  return cl;
5277 }
5278 
5279 ////////////////////////////////////////////////////////////////////////////////
5280 /// Helper function used by TClass::GetClass().
5281 /// This function attempts to load the dictionary for 'classname'
5282 /// either from the TClassTable or from the list of generator.
5283 /// If silent is 'true', do not warn about missing dictionary for the class.
5284 /// (typically used for class that are used only for transient members)
5285 ///
5286 /// The 'requestedname' is expected to be already normalized.
5287 
5288 TClass *TClass::LoadClass(const char *requestedname, Bool_t silent)
5289 {
5290  // This function does not (and should not) attempt to check in the
5291  // list of loaded classes or in the typedef.
5292 
5294 
5295  TClass *result = LoadClassDefault(requestedname, silent);
5296 
5297  if (result) return result;
5298  else return LoadClassCustom(requestedname,silent);
5299 }
5300 
5301 ////////////////////////////////////////////////////////////////////////////////
5302 /// Helper function used by TClass::GetClass().
5303 /// This function attempts to load the dictionary for 'classname' from
5304 /// the TClassTable or the autoloader.
5305 /// If silent is 'true', do not warn about missing dictionary for the class.
5306 /// (typically used for class that are used only for transient members)
5307 ///
5308 /// The 'requestedname' is expected to be already normalized.
5309 
5310 TClass *TClass::LoadClassDefault(const char *requestedname, Bool_t /* silent */)
5311 {
5312  // This function does not (and should not) attempt to check in the
5313  // list of loaded classes or in the typedef.
5314 
5315  DictFuncPtr_t dict = TClassTable::GetDictNorm(requestedname);
5316 
5317  if (!dict) {
5318  if (gInterpreter->AutoLoad(requestedname,kTRUE)) {
5319  dict = TClassTable::GetDictNorm(requestedname);
5320  }
5321  }
5322 
5323  if (dict) {
5324  TClass *ncl = (dict)();
5325  if (ncl) ncl->PostLoadCheck();
5326  return ncl;
5327  }
5328  return 0;
5329 }
5330 
5331 ////////////////////////////////////////////////////////////////////////////////
5332 /// Helper function used by TClass::GetClass().
5333 /// This function attempts to load the dictionary for 'classname'
5334 /// from the list of generator.
5335 /// If silent is 'true', do not warn about missing dictionary for the class.
5336 /// (typically used for class that are used only for transient members)
5337 ///
5338 /// The 'requestedname' is expected to be already normalized.
5339 
5340 TClass *TClass::LoadClassCustom(const char *requestedname, Bool_t silent)
5341 {
5342  // This function does not (and should not) attempt to check in the
5343  // list of loaded classes or in the typedef.
5344 
5345  TIter next(gROOT->GetListOfClassGenerators());
5347  while ((gen = (TClassGenerator*) next())) {
5348  TClass *cl = gen->GetClass(requestedname, kTRUE, silent);
5349  if (cl) {
5350  cl->PostLoadCheck();
5351  return cl;
5352  }
5353  }
5354  return 0;
5355 }
5356 
5357 ////////////////////////////////////////////////////////////////////////////////
5358 /// Try to load the classInfo (it may require parsing the header file
5359 /// and/or loading data from the clang pcm).
5360 
5362 {
5364 
5365  // If another thread executed LoadClassInfo at about the same time
5366  // as this thread return early since the work was done.
5367  if (!fCanLoadClassInfo) return;
5368 
5369  gInterpreter->AutoParse(GetName());
5370  if (!fClassInfo) gInterpreter->SetClassInfo(const_cast<TClass*>(this)); // sets fClassInfo pointer
5371  if (!gInterpreter->IsAutoParsingSuspended()) {
5372  if (!fClassInfo) {
5373  ::Error("TClass::LoadClassInfo",
5374  "no interpreter information for class %s is available even though it has a TClass initialization routine.",
5375  fName.Data());
5376  }
5378  }
5379 }
5380 
5381 ////////////////////////////////////////////////////////////////////////////////
5382 /// Store class description on I/O buffer.
5383 
5384 void TClass::Store(TBuffer &b) const
5385 {
5386  b.WriteString(GetName());
5387 }
5388 
5389 ////////////////////////////////////////////////////////////////////////////////
5390 /// Global function called by a class' static Dictionary() method
5391 /// (see the ClassDef macro).
5392 
5393 TClass *ROOT::CreateClass(const char *cname, Version_t id,
5394  const type_info &info, TVirtualIsAProxy *isa,
5395  const char *dfil, const char *ifil,
5396  Int_t dl, Int_t il)
5397 {
5398  // When called via TMapFile (e.g. Update()) make sure that the dictionary
5399  // gets allocated on the heap and not in the mapped file.
5400  TMmallocDescTemp setreset;
5401  return new TClass(cname, id, info, isa, dfil, ifil, dl, il);
5402 }
5403 
5404 ////////////////////////////////////////////////////////////////////////////////
5405 /// Global function called by a class' static Dictionary() method
5406 /// (see the ClassDef macro).
5407 
5408 TClass *ROOT::CreateClass(const char *cname, Version_t id,
5409  const char *dfil, const char *ifil,
5410  Int_t dl, Int_t il)
5411 {
5412  // When called via TMapFile (e.g. Update()) make sure that the dictionary
5413  // gets allocated on the heap and not in the mapped file.
5414  TMmallocDescTemp setreset;
5415  return new TClass(cname, id, dfil, ifil, dl, il);
5416 }
5417 
5418 ////////////////////////////////////////////////////////////////////////////////
5419 /// Static method returning the defConstructor flag passed to TClass::New().
5420 /// New type is either:
5421 /// - TClass::kRealNew - when called via plain new
5422 /// - TClass::kClassNew - when called via TClass::New()
5423 /// - TClass::kDummyNew - when called via TClass::New() but object is a dummy,
5424 /// in which case the object ctor might take short cuts
5425 
5427 {
5428  return TClass__GetCallingNew();
5429 }
5430 
5431 ////////////////////////////////////////////////////////////////////////////////
5432 /// Return true if the shared library of this class is currently in the a
5433 /// process's memory. Return false, after the shared library has been
5434 /// unloaded or if this is an 'emulated' class created from a file's StreamerInfo.
5435 
5437 {
5438  return fState == kHasTClassInit;
5439 }
5440 
5441 ////////////////////////////////////////////////////////////////////////////////
5442 /// Returns true if this class inherits from TObject and if the start of
5443 /// the TObject parts is at the very beginning of the objects.
5444 /// Concretely this means that the following code is proper for this class:
5445 /// ~~~ {.cpp}
5446 /// ThisClass *ptr;
5447 /// void *void_ptr = (void)ptr;
5448 /// TObject *obj = (TObject*)void_ptr;
5449 /// ~~~
5450 /// This code would be wrong if 'ThisClass' did not inherit 'first' from
5451 /// TObject.
5452 
5454 {
5455  if (fProperty==(-1)) Property();
5456  return TestBit(kStartWithTObject);
5457 }
5458 
5459 ////////////////////////////////////////////////////////////////////////////////
5460 /// Return kTRUE is the class inherits from TObject.
5461 
5463 {
5464  if (fProperty==(-1)) Property();
5465  return TestBit(kIsTObject);
5466 }
5467 
5468 ////////////////////////////////////////////////////////////////////////////////
5469 /// Return kTRUE is the class is Foreign (the class does not have a Streamer method).
5470 
5472 {
5473  if (fProperty==(-1)) Property();
5474  return TestBit(kIsForeign);
5475 }
5476 
5477 ////////////////////////////////////////////////////////////////////////////////
5478 /// Do the initialization that can only be done after the CINT dictionary has
5479 /// been fully populated and can not be delayed efficiently.
5480 
5482 {
5483  // In the case of a Foreign class (loaded class without a Streamer function)
5484  // we reset fClassVersion to be -1 so that the current TVirtualStreamerInfo will not
5485  // be confused with a previously loaded streamerInfo.
5486 
5487  if (IsLoaded() && HasInterpreterInfo() && fClassVersion==1 /*&& fStreamerInfo
5488  && fStreamerInfo->At(1)*/ && IsForeign() )
5489  {
5490  SetClassVersion(-1);
5491  }
5492  else if (IsLoaded() && HasDataMemberInfo() && fStreamerInfo && (!IsForeign()||fClassVersion>1) )
5493  {
5495 
5497  // Here we need to check whether this TVirtualStreamerInfo (which presumably has been
5498  // loaded from a file) is consistent with the definition in the library we just loaded.
5499  // BuildCheck is not appropriate here since it check a streamerinfo against the
5500  // 'current streamerinfo' which, at time point, would be the same as 'info'!
5501  if (info && GetListOfDataMembers() && !GetCollectionProxy()
5502  && (info->GetCheckSum()!=GetCheckSum() && !info->CompareContent(this,0,kFALSE,kFALSE, 0) && !(MatchLegacyCheckSum(info->GetCheckSum()))))
5503  {
5504  Bool_t warn = ! TestBit(kWarned);
5505  if (warn && info->GetOldVersion()<=2) {
5506  // Names of STL base classes was modified in vers==3. Allocators removed
5507  //
5508  TIter nextBC(GetListOfBases());
5509  TBaseClass *bc;
5510  while ((bc=(TBaseClass*)nextBC()))
5511  {if (TClassEdit::IsSTLCont(bc->GetName())) warn = kFALSE;}
5512  }
5513 
5514  if (warn) {
5515  if (info->GetOnFileClassVersion()==1 && fClassVersion>1) {
5516  Warning("PostLoadCheck","\n\
5517  The class %s transitioned from not having a specified class version\n\
5518  to having a specified class version (the current class version is %d).\n\
5519  However too many different non-versioned layouts of the class have\n\
5520  already been loaded so far. To work around this problem you can\n\
5521  load fewer 'old' file in the same ROOT session or load the C++ library\n\
5522  describing the class %s before opening the files or increase the version\n\
5523  number of the class for example ClassDef(%s,%d).\n\
5524  Do not try to write objects with the current class definition,\n\
5525  the files might not be readable.\n",
5527  } else {
5528  Warning("PostLoadCheck","\n\
5529  The StreamerInfo version %d for the class %s which was read\n\
5530  from a file previously opened has the same version as the active class\n\
5531  but a different checksum. You should update the version to ClassDef(%s,%d).\n\
5532  Do not try to write objects with the current class definition,\n\
5533  the files will not be readable.\n"
5535  }
5536  info->CompareContent(this,0,kTRUE,kTRUE,0);
5537  SetBit(kWarned);
5538  }
5539  }
5540  }
5541 }
5542 
5543 ////////////////////////////////////////////////////////////////////////////////
5544 /// Set TObject::fBits and fStreamerType to cache information about the
5545 /// class. The bits are
5546 /// ~~~ {.cpp}
5547 /// kIsTObject : the class inherits from TObject
5548 /// kStartWithTObject: TObject is the left-most class in the inheritance tree
5549 /// kIsForeign : the class doe not have a Streamer method
5550 /// ~~~
5551 /// The value of fStreamerType are
5552 /// ~~~ {.cpp}
5553 /// kTObject : the class inherits from TObject
5554 /// kForeign : the class does not have a Streamer method
5555 /// kInstrumented: the class does have a Streamer method
5556 /// kExternal: the class has a free standing way of streaming itself
5557 /// kEmulatedStreamer: the class is missing its shared library.
5558 /// ~~~
5559 
5561 {
5562  // Check if we can return without taking the lock,
5563  // this is valid since fProperty is atomic and set as
5564  // the last operation before return.
5565  if (fProperty!=(-1)) return fProperty;
5566 
5568 
5569  // Check if another thread set fProperty while we
5570  // were waiting.
5571  if (fProperty!=(-1)) return fProperty;
5572 
5573  // Avoid asking about the class when it is still building
5574  if (TestBit(kLoading)) return fProperty;
5575 
5576  // When called via TMapFile (e.g. Update()) make sure that the dictionary
5577  // gets allocated on the heap and not in the mapped file.
5578  TMmallocDescTemp setreset;
5579 
5580  TClass *kl = const_cast<TClass*>(this);
5581 
5584 
5585  if (InheritsFrom(TObject::Class())) {
5586  kl->SetBit(kIsTObject);
5587 
5588  // Is it DIRECT inheritance from TObject?
5590  if (delta==0) kl->SetBit(kStartWithTObject);
5591 
5592  kl->fStreamerType = kTObject;
5594  }
5595 
5596  if (HasInterpreterInfo()) {
5597 
5598  // This code used to use ClassInfo_Has|IsValidMethod but since v6
5599  // they return true if the routine is defined in the class or any of
5600  // its parent. We explicitly want to know whether the function is
5601  // defined locally.
5602  if (!const_cast<TClass*>(this)->GetClassMethodWithPrototype("Streamer","TBuffer&",kFALSE)) {
5603 
5604  kl->SetBit(kIsForeign);
5605  kl->fStreamerType = kForeign;
5607 
5608  } else if ( kl->fStreamerType == TClass::kDefault ) {
5609  if (kl->fConvStreamerFunc) {
5612  } else if (kl->fStreamerFunc) {
5615  } else {
5616  // We have an automatic streamer using the StreamerInfo .. no need to go through the
5617  // Streamer method function itself.
5620  }
5621  }
5622 
5623  if (fStreamer) {
5624  kl->fStreamerType = kExternal;
5626  }
5627  if (GetClassInfo()) {
5628  // In the case where the TClass for one of ROOT's core class
5629  // (eg TClonesArray for map<int,TClonesArray*>) is requesting
5630  // during the execution of rootcling, we could end up in a situation
5631  // where we should have the information (since TClonesArray has
5632  // a dictionary as part of libCore) but do not because the user
5633  // only include a forward declaration of TClonesArray and we do not
5634  // forcefully load the header file either (because the autoparsing
5635  // is intentionally disabled).
5637  // Must set this last since other threads may read fProperty
5638  // and think all test bits have been properly set.
5640  }
5641  } else {
5642 
5643  if (fStreamer) {
5644  kl->fStreamerType = kExternal;
5646  }
5647 
5649  kl->SetStreamerImpl();
5650  // fProperty was *not* set so that it can be forced to be recalculated
5651  // next time.
5652  return 0;
5653  }
5654 
5655  return fProperty;
5656 }
5657 
5658 ////////////////////////////////////////////////////////////////////////////////
5659 /// Internal routine to set fStreamerImpl based on the value of
5660 /// fStreamerType.
5661 
5663 {
5664  switch (fStreamerType) {
5668  case kInstrumented: {
5672  break;
5673  }
5674 
5675  case kEmulatedStreamer: // intentional fall through
5676  case kForeign|kEmulatedStreamer: // intentional fall through
5681  default:
5682  Error("SetStreamerImpl","Unexpected value of fStreamerType: %d",fStreamerType);
5683  }
5684 }
5685 
5686 
5687 ////////////////////////////////////////////////////////////////////////////////
5688 /// Create the collection proxy object (and the streamer object) from
5689 /// using the information in the TCollectionProxyInfo.
5690 
5692 {
5694 
5695  delete fCollectionProxy;
5696 
5697  // We can not use GetStreamerInfo() instead of TVirtualStreamerInfo::Factory()
5698  // because GetStreamerInfo call TStreamerInfo::Build which need to have fCollectionProxy
5699  // set correctly.
5700 
5702  fCollectionProxy = p;
5703 
5704  AdoptStreamer(TVirtualStreamerInfo::Factory()->GenExplicitClassStreamer(info,this));
5705 
5706  if (fCollectionProxy && !fSchemaRules) {
5707  // Numeric Collections have implicit conversions:
5709  }
5710  fCanSplit = -1;
5711 }
5712 
5713 ////////////////////////////////////////////////////////////////////////////////
5714 /// Change (i.e. set) the title of the TNamed.
5715 
5717 {
5719 }
5720 
5721 ////////////////////////////////////////////////////////////////////////////////
5722 /// This function installs a global IsA function for this class.
5723 /// The global IsA function will be used if there is no local IsA function (fIsA)
5724 ///
5725 /// A global IsA function has the signature:
5726 ///
5727 /// ~~~ {.cpp}
5728 /// TClass *func( TClass *cl, const void *obj);
5729 /// ~~~
5730 ///
5731 /// 'cl' is a pointer to the TClass object that corresponds to the
5732 /// 'pointer type' used to retrieve the value 'obj'
5733 ///
5734 /// For example with:
5735 /// ~~~ {.cpp}
5736 /// TNamed * m = new TNamed("example","test");
5737 /// TObject* o = m
5738 /// ~~~
5739 /// and
5740 /// the global IsA function would be called with TObject::Class() as
5741 /// the first parameter and the exact numerical value in the pointer
5742 /// 'o'.
5743 ///
5744 /// In other word, inside the global IsA function. it is safe to C-style
5745 /// cast the value of 'obj' into a pointer to the class described by 'cl'.
5746 
5748 {
5749  fGlobalIsA = func;
5750 }
5751 
5752 ////////////////////////////////////////////////////////////////////////////////
5753 /// Call this method to indicate that the shared library containing this
5754 /// class's code has been removed (unloaded) from the process's memory
5755 
5757 {
5758  if (TestBit(kUnloaded) && !TestBit(kUnloading)) {
5759  // Don't redo the work.
5760  return;
5761  }
5762  SetBit(kUnloading);
5763 
5764  //R__ASSERT(fState == kLoaded);
5765  if (fState != kLoaded) {
5766  Fatal("SetUnloaded","The TClass for %s is being unloaded when in state %d\n",
5767  GetName(),(int)fState);
5768  }
5769 
5770  // Make sure SetClassInfo, re-calculated the state.
5772 
5773  delete fIsA; fIsA = 0;
5774  // Disable the autoloader while calling SetClassInfo, to prevent
5775  // the library from being reloaded!
5776  {
5777  int autoload_old = gCling->SetClassAutoloading(0);
5779 
5780  gInterpreter->SetClassInfo(this,kTRUE);
5781 
5782  gCling->SetClassAutoloading(autoload_old);
5783  }
5784  fDeclFileName = 0;
5785  fDeclFileLine = 0;
5786  fImplFileName = 0;
5787  fImplFileLine = 0;
5788  fTypeInfo = 0;
5789 
5790  if (fMethod.load()) {
5791  (*fMethod).Unload();
5792  }
5793  if (fData) {
5794  fData->Unload();
5795  }
5796  if (fEnums.load()) {
5797  (*fEnums).Unload();
5798  }
5799 
5800  if (fState <= kForwardDeclared && fStreamerInfo->GetEntries() != 0) {
5801  fState = kEmulated;
5802  }
5803 
5805  SetBit(kUnloaded);
5806 }
5807 
5808 ////////////////////////////////////////////////////////////////////////////////
5809 /// Info is a string describing the names and types of attributes
5810 /// written by the class Streamer function.
5811 /// If info is an empty string (when called by TObject::StreamerInfo)
5812 /// the default Streamer info string is build. This corresponds to
5813 /// the case of an automatically generated Streamer.
5814 /// In case of user defined Streamer function, it is the user responsibility
5815 /// to implement a StreamerInfo function (override TObject::StreamerInfo).
5816 /// The user must call IsA()->SetStreamerInfo(info) from this function.
5817 
5818 TVirtualStreamerInfo *TClass::SetStreamerInfo(Int_t /*version*/, const char * /*info*/)
5819 {
5820  // info is specified, nothing to do, except that we should verify
5821  // that it contains a valid descriptor.
5822 
5823 /*
5824  TDataMember *dm;
5825  Int_t nch = strlen(info);
5826  Bool_t update = kTRUE;
5827  if (nch != 0) {
5828  //decode strings like "TObject;TAttLine;fA;fB;Int_t i,j,k;"
5829  char *save, *temp, *blank, *colon, *comma;
5830  save = new char[10000];
5831  temp = save;
5832  strlcpy(temp,info,10000);
5833  //remove heading and trailing blanks
5834  while (*temp == ' ') temp++;
5835  while (save[nch-1] == ' ') {nch--; save[nch] = 0;}
5836  if (nch == 0) {delete [] save; return;}
5837  if (save[nch-1] != ';') {save[nch] = ';'; save[nch+1] = 0;}
5838  //remove blanks around , or ;
5839  while ((blank = strstr(temp,"; "))) strcpy(blank+1,blank+2);
5840  while ((blank = strstr(temp," ;"))) strcpy(blank, blank+1);
5841  while ((blank = strstr(temp,", "))) strcpy(blank+1,blank+2);
5842  while ((blank = strstr(temp," ,"))) strcpy(blank, blank+1);
5843  while ((blank = strstr(temp," "))) strcpy(blank, blank+1);
5844  //loop on tokens separated by ;
5845  char *final = new char[1000];
5846  char token[100];
5847  while ((colon=strchr(temp,';'))) {
5848  *colon = 0;
5849  strlcpy(token,temp,100);
5850  blank = strchr(token,' ');
5851  if (blank) {
5852  *blank = 0;
5853  if (!gROOT->GetType(token)) {
5854  Error("SetStreamerInfo","Illegal type: %s in %s",token,info);
5855  return;
5856  }
5857  while (blank) {
5858  strlcat(final,token,1000);
5859  strlcat(final," ",1000);
5860  comma = strchr(blank+1,','); if (comma) *comma=0;
5861  strlcat(final,blank+1,1000);
5862  strlcat(final,";",1000);
5863  blank = comma;
5864  }
5865 
5866  } else {
5867  if (TClass::GetClass(token,update)) {
5868  //a class name
5869  strlcat(final,token,1000); strlcat(final,";",1000);
5870  } else {
5871  //a data member name
5872  dm = (TDataMember*)GetListOfDataMembers()->FindObject(token);
5873  if (dm) {
5874  strlcat(final,dm->GetFullTypeName(),1000);
5875  strlcat(final," ",1000);
5876  strlcat(final,token,1000); strlcat(final,";",1000);
5877  } else {
5878  Error("SetStreamerInfo","Illegal name: %s in %s",token,info);
5879  return;
5880  }
5881  }
5882  update = kFALSE;
5883  }
5884  temp = colon+1;
5885  if (*temp == 0) break;
5886  }
5887  //// fStreamerInfo = final;
5888  delete [] final;
5889  delete [] save;
5890  return;
5891  }
5892 
5893  //info is empty. Let's build the default Streamer descriptor
5894 
5895  char *temp = new char[10000];
5896  temp[0] = 0;
5897  char local[100];
5898 
5899  //add list of base classes
5900  TIter nextb(GetListOfBases());
5901  TBaseClass *base;
5902  while ((base = (TBaseClass*) nextb())) {
5903  snprintf(local,100,"%s;",base->GetName());
5904  strlcat(temp,local,10000);
5905  }
5906 
5907  //add list of data members and types
5908  TIter nextd(GetListOfDataMembers());
5909  while ((dm = (TDataMember *) nextd())) {
5910  if (dm->IsEnum()) continue;
5911  if (!dm->IsPersistent()) continue;
5912  Long_t property = dm->Property();
5913  if (property & kIsStatic) continue;
5914  TClass *acl = TClass::GetClass(dm->GetTypeName(),update);
5915  update = kFALSE;
5916  if (acl) {
5917  if (acl->GetClassVersion() == 0) continue;
5918  }
5919 
5920  // dm->GetArrayIndex() returns an empty string if it does not
5921  // applies
5922  const char * index = dm->GetArrayIndex();
5923  if (strlen(index)==0)
5924  snprintf(local,100,"%s %s;",dm->GetFullTypeName(),dm->GetName());
5925  else
5926  snprintf(local,100,"%s %s[%s];",dm->GetFullTypeName(),dm->GetName(),index);
5927  strlcat(temp,local,10000);
5928  }
5929  //fStreamerInfo = temp;
5930  delete [] temp;
5931 */
5932  return 0;
5933 }
5934 
5935 ////////////////////////////////////////////////////////////////////////////////
5936 /// Return true if the checksum passed as argument is one of the checksum
5937 /// value produced by the older checksum calculation algorithm.
5938 
5940 {
5941  for(UInt_t i = 1; i < kLatestCheckSum; ++i) {
5942  if ( checksum == GetCheckSum( (ECheckSum) i ) ) return kTRUE;
5943  }
5944  return kFALSE;
5945 }
5946 
5947 ////////////////////////////////////////////////////////////////////////////////
5948 /// Call GetCheckSum with validity check.
5949 
5951 {
5952  bool isvalid;
5953  return GetCheckSum(code,isvalid);
5954 }
5955 
5956 ////////////////////////////////////////////////////////////////////////////////
5957 /// Return GetCheckSum(kCurrentCheckSum,isvalid);
5958 
5960 {
5961  return GetCheckSum(kCurrentCheckSum,isvalid);
5962 }
5963 
5964 ////////////////////////////////////////////////////////////////////////////////
5965 /// Compute and/or return the class check sum.
5966 ///
5967 /// isvalid is set to false, if the function is unable to calculate the
5968 /// checksum.
5969 ///
5970 /// The class ckecksum is used by the automatic schema evolution algorithm
5971 /// to uniquely identify a class version.
5972 /// The check sum is built from the names/types of base classes and
5973 /// data members.
5974 /// Original algorithm from Victor Perevovchikov (perev@bnl.gov).
5975 ///
5976 /// The valid range of code is determined by ECheckSum.
5977 ///
5978 /// - kNoEnum: data members of type enum are not counted in the checksum
5979 /// - kNoRange: return the checksum of data members and base classes, not including the ranges and array size found in comments.
5980 /// - kWithTypeDef: use the sugared type name in the calculation.
5981 ///
5982 /// This is needed for backward compatibility.
5983 ///
5984 /// WARNING: this function must be kept in sync with TStreamerInfo::GetCheckSum.
5985 /// They are both used to handle backward compatibility and should both return the same values.
5986 /// TStreamerInfo uses the information in TStreamerElement while TClass uses the information
5987 /// from TClass::GetListOfBases and TClass::GetListOfDataMembers.
5988 
5990 {
5991  // fCheckSum is an atomic variable. Also once it has
5992  // transition from a zero Value it never changes. If two
5993  // thread reach past this if statement and calculated the
5994  // 'kLastestCheckSum', they will by definition obtain the
5995  // same value, so technically we could simply have:
5996  // if (fCheckSum && code == kCurrentCheckSum) return fCheckSum;
5997  // However save a little bit of barrier time by calling load()
5998  // only once.
5999 
6000  isvalid = kTRUE;
6001 
6002  UInt_t currentChecksum = fCheckSum.load();
6003  if (currentChecksum && code == kCurrentCheckSum) return currentChecksum;
6004 
6006 
6007  // kCurrentCheckSum (0) is the default parameter value and should be kept
6008  // for backward compatibility, too be able to use the inequality checks,
6009  // we need to set the code to the largest value.
6010  if (code == kCurrentCheckSum) code = kLatestCheckSum;
6011 
6012  UInt_t id = 0;
6013 
6014  int il;
6015  TString name = GetName();
6016  TString type;
6017  il = name.Length();
6018  for (int i=0; i<il; i++) id = id*3+name[i];
6019 
6020  TList *tlb = ((TClass*)this)->GetListOfBases();
6021  if (tlb && !GetCollectionProxy()) { // Loop over bases if not a proxied collection
6022 
6023  TIter nextBase(tlb);
6024 
6025  TBaseClass *tbc=0;
6026  while((tbc=(TBaseClass*)nextBase())) {
6027  name = tbc->GetName();
6028  Bool_t isSTL = TClassEdit::IsSTLCont(name);
6029  if (isSTL)
6031  il = name.Length();
6032  for (int i=0; i<il; i++) id = id*3+name[i];
6033  if (code > kNoBaseCheckSum && !isSTL) {
6034  if (tbc->GetClassPointer() == 0) {
6035  Error("GetCheckSum","Calculating the checksum for (%s) requires the base class (%s) meta information to be available!",
6036  GetName(),tbc->GetName());
6037  isvalid = kFALSE;
6038  return 0;
6039  } else
6040  id = id*3 + tbc->GetClassPointer()->GetCheckSum();
6041  }
6042  }/*EndBaseLoop*/
6043  }
6044  TList *tlm = ((TClass*)this)->GetListOfDataMembers();
6045  if (tlm) { // Loop over members
6046  TIter nextMemb(tlm);
6047  TDataMember *tdm=0;
6048  Long_t prop = 0;
6049  while((tdm=(TDataMember*)nextMemb())) {
6050  if (!tdm->IsPersistent()) continue;
6051  // combine properties
6052  prop = (tdm->Property());
6053  TDataType* tdt = tdm->GetDataType();
6054  if (tdt) prop |= tdt->Property();
6055 
6056  if ( prop&kIsStatic) continue;
6057  name = tdm->GetName(); il = name.Length();
6058  if ( (code > kNoEnum) && code != kReflex && code != kReflexNoComment && prop&kIsEnum)
6059  id = id*3 + 1;
6060 
6061  int i;
6062  for (i=0; i<il; i++) id = id*3+name[i];
6063 
6064  if (code > kWithTypeDef || code == kReflexNoComment) {
6065  type = tdm->GetTrueTypeName();
6066  // GetTrueTypeName uses GetFullyQualifiedName which already drops
6067  // the default template parameter, so we no longer need to do this.
6068  //if (TClassEdit::IsSTLCont(type))
6069  // type = TClassEdit::ShortType( type, TClassEdit::kDropStlDefault );
6070  if (code == kReflex || code == kReflexNoComment) {
6071  if (prop&kIsEnum) {
6072  type = "int";
6073  } else {
6074  type.ReplaceAll("ULong64_t","unsigned long long");
6075  type.ReplaceAll("Long64_t","long long");
6076  type.ReplaceAll("<signed char","<char");
6077  type.ReplaceAll(",signed char",",char");
6078  if (type=="signed char") type = "char";
6079  }
6080  }
6081  } else {
6082  type = tdm->GetFullTypeName();
6083  // GetFullTypeName uses GetFullyQualifiedName which already drops
6084  // the default template parameter, so we no longer need to do this.
6085  //if (TClassEdit::IsSTLCont(type))
6086  // type = TClassEdit::ShortType( type, TClassEdit::kDropStlDefault );
6087  }
6088 
6089  il = type.Length();
6090  for (i=0; i<il; i++) id = id*3+type[i];
6091 
6092  int dim = tdm->GetArrayDim();
6093  if (prop&kIsArray) {
6094  for (int ii=0;ii<dim;ii++) id = id*3+tdm->GetMaxIndex(ii);
6095  }
6096  if (code > kNoRange) {
6097  const char *left;
6098  if (code > TClass::kNoRangeCheck)
6100  else
6101  left = strstr(tdm->GetTitle(),"[");
6102  if (left) {
6103  const char *right = strstr(left,"]");
6104  if (right) {
6105  ++left;
6106  while (left != right) {
6107  id = id*3 + *left;
6108  ++left;
6109  }
6110  }
6111  }
6112  }
6113  }/*EndMembLoop*/
6114  }
6115  // This should be moved to Initialization time however the last time
6116  // we tried this cause problem, in particular in the end-of-process operation.
6117  if (code==kLatestCheckSum) fCheckSum = id;
6118  return id;
6119 }
6120 
6121 ////////////////////////////////////////////////////////////////////////////////
6122 /// Adopt the Reference proxy pointer to indicate that this class
6123 /// represents a reference.
6124 /// When a new proxy is adopted, the old one is deleted.
6125 
6127 {
6129 
6130  if ( fRefProxy ) {
6131  fRefProxy->Release();
6132  }
6133  fRefProxy = proxy;
6134  if ( fRefProxy ) {
6135  fRefProxy->SetClass(this);
6136  }
6137  fCanSplit = -1;
6138 }
6139 
6140 ////////////////////////////////////////////////////////////////////////////////
6141 /// Adopt the TMemberStreamer pointer to by p and use it to Stream non basic
6142 /// member name.
6143 
6145 {
6146  if (!fRealData) return;
6147 
6149 
6150  TIter next(fRealData);
6151  TRealData *rd;
6152  while ((rd = (TRealData*)next())) {
6153  if (strcmp(rd->GetName(),name) == 0) {
6154  // If there is a TStreamerElement that took a pointer to the
6155  // streamer we should inform it!
6156  rd->AdoptStreamer(p);
6157  break;
6158  }
6159  }
6160 
6161 // NOTE: This alternative was proposed but not is not used for now,
6162 // One of the major difference with the code above is that the code below
6163 // did not require the RealData to have been built
6164 // if (!fData) return;
6165 // const char *n = name;
6166 // while (*n=='*') n++;
6167 // TString ts(n);
6168 // int i = ts.Index("[");
6169 // if (i>=0) ts.Remove(i,999);
6170 // TDataMember *dm = (TDataMember*)fData->FindObject(ts.Data());
6171 // if (!dm) {
6172 // Warning("SetStreamer","Can not find member %s::%s",GetName(),name);
6173 // return;
6174 // }
6175 // dm->SetStreamer(p);
6176  return;
6177 }
6178 
6179 ////////////////////////////////////////////////////////////////////////////////
6180 /// Install a new member streamer (p will be copied).
6181 
6183 {
6184  AdoptMemberStreamer(name,new TMemberStreamer(p));
6185 }
6186 
6187 ////////////////////////////////////////////////////////////////////////////////
6188 /// Function called by the Streamer functions to deserialize information
6189 /// from buffer b into object at p.
6190 /// This function assumes that the class version and the byte count information
6191 /// have been read.
6192 /// - version is the version number of the class
6193 /// - start is the starting position in the buffer b
6194 /// - count is the number of bytes for this object in the buffer
6195 
6196 Int_t TClass::ReadBuffer(TBuffer &b, void *pointer, Int_t version, UInt_t start, UInt_t count)
6197 {
6198  return b.ReadClassBuffer(this,pointer,version,start,count);
6199 }
6200 
6201 ////////////////////////////////////////////////////////////////////////////////
6202 /// Function called by the Streamer functions to deserialize information
6203 /// from buffer b into object at p.
6204 
6206 {
6207  return b.ReadClassBuffer(this,pointer);
6208 }
6209 
6210 ////////////////////////////////////////////////////////////////////////////////
6211 /// Function called by the Streamer functions to serialize object at p
6212 /// to buffer b. The optional argument info may be specified to give an
6213 /// alternative StreamerInfo instead of using the default StreamerInfo
6214 /// automatically built from the class definition.
6215 /// For more information, see class TVirtualStreamerInfo.
6216 
6217 Int_t TClass::WriteBuffer(TBuffer &b, void *pointer, const char * /*info*/)
6218 {
6219  b.WriteClassBuffer(this,pointer);
6220  return 0;
6221 }
6222 
6223 ////////////////////////////////////////////////////////////////////////////////
6224 ///There is special streamer for the class
6225 
6226 void TClass::StreamerExternal(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class)
6227 {
6228  // case kExternal:
6229  // case kExternal|kEmulatedStreamer:
6230 
6231  TClassStreamer *streamer = gThreadTsd ? pThis->GetStreamer() : pThis->fStreamer;
6232  streamer->Stream(b,object,onfile_class);
6233 }
6234 
6235 ////////////////////////////////////////////////////////////////////////////////
6236 /// Case of TObjects
6237 
6238 void TClass::StreamerTObject(const TClass* pThis, void *object, TBuffer &b, const TClass * /* onfile_class */)
6239 {
6240  // case kTObject:
6241 
6242  if (!pThis->fIsOffsetStreamerSet) {
6243  pThis->CalculateStreamerOffset();
6244  }
6245  TObject *tobj = (TObject*)((Long_t)object + pThis->fOffsetStreamer);
6246  tobj->Streamer(b);
6247 }
6248 
6249 ////////////////////////////////////////////////////////////////////////////////
6250 /// Case of TObjects when fIsOffsetStreamerSet is known to have been set.
6251 
6252 void TClass::StreamerTObjectInitialized(const TClass* pThis, void *object, TBuffer &b, const TClass * /* onfile_class */)
6253 {
6254  TObject *tobj = (TObject*)((Long_t)object + pThis->fOffsetStreamer);
6255  tobj->Streamer(b);
6256 }
6257 
6258 ////////////////////////////////////////////////////////////////////////////////
6259 /// Case of TObjects when we do not have the library defining the class.
6260 
6261 void TClass::StreamerTObjectEmulated(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class)
6262 {
6263  // case kTObject|kEmulatedStreamer :
6264  if (b.IsReading()) {
6265  b.ReadClassEmulated(pThis, object, onfile_class);
6266  } else {
6267  b.WriteClassBuffer(pThis, object);
6268  }
6269 }
6270 
6271 ////////////////////////////////////////////////////////////////////////////////
6272 /// Case of instrumented class with a library
6273 
6274 void TClass::StreamerInstrumented(const TClass* pThis, void *object, TBuffer &b, const TClass * /* onfile_class */)
6275 {
6276  // case kInstrumented:
6277  pThis->fStreamerFunc(b,object);
6278 }
6279 
6280 ////////////////////////////////////////////////////////////////////////////////
6281 /// Case of instrumented class with a library
6282 
6283 void TClass::ConvStreamerInstrumented(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class)
6284 {
6285  // case kInstrumented:
6286  pThis->fConvStreamerFunc(b,object,onfile_class);
6287 }
6288 
6289 ////////////////////////////////////////////////////////////////////////////////
6290 /// Case of where we should directly use the StreamerInfo.
6291 /// - case kForeign:
6292 /// - case kForeign|kEmulatedStreamer:
6293 /// - case kInstrumented|kEmulatedStreamer:
6294 /// - case kEmulatedStreamer:
6295 
6296 void TClass::StreamerStreamerInfo(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class)
6297 {
6298  if (b.IsReading()) {
6299  b.ReadClassBuffer(pThis, object, onfile_class);
6300  //ReadBuffer (b, object);
6301  } else {
6302  //WriteBuffer(b, object);
6303  b.WriteClassBuffer(pThis, object);
6304  }
6305 }
6306 
6307 ////////////////////////////////////////////////////////////////////////////////
6308 /// Default streaming in cases where either we have no way to know what to do
6309 /// or if Property() has not yet been called.
6310 
6311 void TClass::StreamerDefault(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class)
6312 {
6313  if (pThis->fProperty==(-1)) {
6314  pThis->Property();
6315  }
6316 
6317  // We could get here because after this thread started StreamerDefault
6318  // *and* before check fProperty, another thread might have call Property
6319  // and this fProperty when we read it, is not -1 and fStreamerImpl is
6320  // supposed to be set properly (no longer pointing to the default).
6321  if (pThis->fStreamerImpl == &TClass::StreamerDefault) {
6322  pThis->Fatal("StreamerDefault", "fStreamerImpl not properly initialized (%d)", pThis->fStreamerType);
6323  } else {
6324  (*pThis->fStreamerImpl)(pThis,object,b,onfile_class);
6325  }
6326 }
6327 
6328 ////////////////////////////////////////////////////////////////////////////////
6329 /// Adopt a TClassStreamer object. Ownership is transfered to this TClass
6330 /// object.
6331 
6333 {
6334 // // This code can be used to quickly test the STL Emulation layer
6335 // Int_t k = TClassEdit::IsSTLCont(GetName());
6336 // if (k==1||k==-1) { delete str; return; }
6337 
6339 
6340  if (fStreamer) delete fStreamer;
6341  if (str) {
6343  fStreamer = str;
6345  } else if (fStreamer) {
6346  // Case where there was a custom streamer and it is hereby removed,
6347  // we need to reset fStreamerType
6348  fStreamer = str;
6350  if (fProperty != -1) {
6351  fProperty = -1;
6352  Property();
6353  }
6354  }
6355 }
6356 
6357 ////////////////////////////////////////////////////////////////////////////////
6358 /// Set a wrapper/accessor function around this class custom streamer.
6359 
6361 {
6363  if (fProperty != -1 && !fConvStreamerFunc &&
6364  ( (fStreamerFunc == 0 && strm != 0) || (fStreamerFunc != 0 && strm == 0) ) )
6365  {
6366  fStreamerFunc = strm;
6367 
6368  // Since initialization has already been done, make sure to tweak it
6369  // for the new state.
6373  }
6374  } else {
6375  fStreamerFunc = strm;
6376  }
6377  fCanSplit = -1;
6378 }
6379 
6380 ////////////////////////////////////////////////////////////////////////////////
6381 /// Set a wrapper/accessor function around this class custom conversion streamer.
6382 
6384 {
6386  if (fProperty != -1 &&
6387  ( (fConvStreamerFunc == 0 && strm != 0) || (fConvStreamerFunc != 0 && strm == 0) ) )
6388  {
6389  fConvStreamerFunc = strm;
6390 
6391  // Since initialization has already been done, make sure to tweak it
6392  // for the new state.
6396  }
6397  } else {
6398  fConvStreamerFunc = strm;
6399  }
6400  fCanSplit = -1;
6401 }
6402 
6403 
6404 ////////////////////////////////////////////////////////////////////////////////
6405 /// Install a new wrapper around 'Merge'.
6406 
6408 {
6409  fMerge = newMerge;
6410 }
6411 
6412 ////////////////////////////////////////////////////////////////////////////////
6413 /// Install a new wrapper around 'ResetAfterMerge'.
6414 
6416 {
6417  fResetAfterMerge = newReset;
6418 }
6419 
6420 ////////////////////////////////////////////////////////////////////////////////
6421 /// Install a new wrapper around 'new'.
6422 
6424 {
6425  fNew = newFunc;
6426 }
6427 
6428 ////////////////////////////////////////////////////////////////////////////////
6429 /// Install a new wrapper around 'new []'.
6430 
6432 {
6433  fNewArray = newArrayFunc;
6434 }
6435 
6436 ////////////////////////////////////////////////////////////////////////////////
6437 /// Install a new wrapper around 'delete'.
6438 
6440 {
6441  fDelete = deleteFunc;
6442 }
6443 
6444 ////////////////////////////////////////////////////////////////////////////////
6445 /// Install a new wrapper around 'delete []'.
6446 
6448 {
6449  fDeleteArray = deleteArrayFunc;
6450 }
6451 
6452 ////////////////////////////////////////////////////////////////////////////////
6453 /// Install a new wrapper around the destructor.
6454 
6456 {
6457  fDestructor = destructorFunc;
6458 }
6459 
6460 ////////////////////////////////////////////////////////////////////////////////
6461 /// Install a new wrapper around the directory auto add function..
6462 /// The function autoAddFunc has the signature void (*)(void *obj, TDirectory dir)
6463 /// and should register 'obj' to the directory if dir is not null
6464 /// and unregister 'obj' from its current directory if dir is null
6465 
6467 {
6468  fDirAutoAdd = autoAddFunc;
6469 }
6470 
6471 ////////////////////////////////////////////////////////////////////////////////
6472 /// Find the TVirtualStreamerInfo in the StreamerInfos corresponding to checksum
6473 
6475 {
6477  if (guess && guess->GetCheckSum() == checksum) {
6478  return guess;
6479  } else {
6480  if (fCheckSum == checksum) return GetStreamerInfo();
6481 
6483  Int_t ninfos = fStreamerInfo->GetEntriesFast()-1;
6484  for (Int_t i=-1;i<ninfos;++i) {
6485  // TClass::fStreamerInfos has a lower bound not equal to 0,
6486  // so we have to use At and should not use UncheckedAt
6488  if (info && info->GetCheckSum() == checksum) {
6489  // R__ASSERT(i==info->GetClassVersion() || (i==-1&&info->GetClassVersion()==1));
6490  info->BuildOld();
6491  if (info->IsCompiled()) fLastReadInfo = info;
6492  return info;
6493  }
6494  }
6495  return 0;
6496  }
6497 }
6498 
6499 ////////////////////////////////////////////////////////////////////////////////
6500 /// Find the TVirtualStreamerInfo in the StreamerInfos corresponding to checksum
6501 
6503 {
6505  Int_t ninfos = arr->GetEntriesFast()-1;
6506  for (Int_t i=-1;i<ninfos;i++) {
6507  // TClass::fStreamerInfos has a lower bound not equal to 0,
6508  // so we have to use At and should not use UncheckedAt
6510  if (!info) continue;
6511  if (info->GetCheckSum() == checksum) {
6512  R__ASSERT(i==info->GetClassVersion() || (i==-1&&info->GetClassVersion()==1));
6513  return info;
6514  }
6515  }
6516  return 0;
6517 }
6518 
6519 ////////////////////////////////////////////////////////////////////////////////
6520 /// Return a Conversion StreamerInfo from the class 'classname' for version number 'version' to this class, if any.
6521 
6522 TVirtualStreamerInfo *TClass::GetConversionStreamerInfo( const char* classname, Int_t version ) const
6523 {
6524  TClass *cl = TClass::GetClass( classname );
6525  if( !cl )
6526  return 0;
6527  return GetConversionStreamerInfo( cl, version );
6528 }
6529 
6530 ////////////////////////////////////////////////////////////////////////////////
6531 /// Return a Conversion StreamerInfo from the class represented by cl for version number 'version' to this class, if any.
6532 
6534 {
6535  //----------------------------------------------------------------------------
6536  // Check if the classname was specified correctly
6537  /////////////////////////////////////////////////////////////////////////////
6538 
6539  if( !cl )
6540  return 0;
6541 
6542  if( cl == this )
6543  return GetStreamerInfo( version );
6544 
6545  //----------------------------------------------------------------------------
6546  // Check if we already have it
6547  /////////////////////////////////////////////////////////////////////////////
6548 
6549  TObjArray* arr = 0;
6550  if (fConversionStreamerInfo.load()) {
6551  std::map<std::string, TObjArray*>::iterator it;
6553 
6554  it = (*fConversionStreamerInfo).find( cl->GetName() );
6555 
6556  if( it != (*fConversionStreamerInfo).end() ) {
6557  arr = it->second;
6558  }
6559 
6560  if( arr && version > -1 && version < arr->GetSize() && arr->At( version ) )
6561  return (TVirtualStreamerInfo*) arr->At( version );
6562  }
6563 
6565 
6566  //----------------------------------------------------------------------------
6567  // We don't have the streamer info so find it in other class
6568  /////////////////////////////////////////////////////////////////////////////
6569 
6570  const TObjArray *clSI = cl->GetStreamerInfos();
6571  TVirtualStreamerInfo* info = 0;
6572  if( version >= -1 && version < clSI->GetSize() )
6573  info = (TVirtualStreamerInfo*)clSI->At( version );
6574 
6575  if (!info && cl->GetCollectionProxy()) {
6576  info = cl->GetStreamerInfo(); // instantiate the StreamerInfo for STL collections.
6577  }
6578 
6579  if( !info )
6580  return 0;
6581 
6582  //----------------------------------------------------------------------------
6583  // We have the right info so we need to clone it to create new object with
6584  // non artificial streamer elements and we should build it for current class
6585  /////////////////////////////////////////////////////////////////////////////
6586 
6587  info = (TVirtualStreamerInfo*)info->Clone();
6588 
6589  if( !info->BuildFor( this ) ) {
6590  delete info;
6591  return 0;
6592  }
6593 
6594  if (!info->IsCompiled()) {
6595  // Streamer info has not been compiled, but exists.
6596  // Therefore it was read in from a file and we have to do schema evolution?
6597  // Or it didn't have a dictionary before, but does now?
6598  info->BuildOld();
6599  }
6600 
6601  //----------------------------------------------------------------------------
6602  // Cache this streamer info
6603  /////////////////////////////////////////////////////////////////////////////
6604 
6605  if (!arr) {
6606  arr = new TObjArray(version+10, -1);
6607  if (!fConversionStreamerInfo.load()) {
6608  fConversionStreamerInfo = new std::map<std::string, TObjArray*>();
6609  }
6610  (*fConversionStreamerInfo)[cl->GetName()] = arr;
6611  }
6612  arr->AddAtAndExpand( info, info->GetClassVersion() );
6613  return info;
6614 }
6615 
6616 ////////////////////////////////////////////////////////////////////////////////
6617 /// Return a Conversion StreamerInfo from the class 'classname' for the layout represented by 'checksum' to this class, if any.
6618 
6619 TVirtualStreamerInfo *TClass::FindConversionStreamerInfo( const char* classname, UInt_t checksum ) const
6620 {
6621  TClass *cl = TClass::GetClass( classname );
6622  if( !cl )
6623  return 0;
6624  return FindConversionStreamerInfo( cl, checksum );
6625 }
6626 
6627 ////////////////////////////////////////////////////////////////////////////////
6628 /// Return a Conversion StreamerInfo from the class represented by cl for the layout represented by 'checksum' to this class, if any.
6629 
6631 {
6632  //---------------------------------------------------------------------------
6633  // Check if the classname was specified correctly
6634  /////////////////////////////////////////////////////////////////////////////
6635 
6636  if( !cl )
6637  return 0;
6638 
6639  if( cl == this )
6640  return FindStreamerInfo( checksum );
6641 
6642  //----------------------------------------------------------------------------
6643  // Check if we already have it
6644  /////////////////////////////////////////////////////////////////////////////
6645 
6646  TObjArray* arr = 0;
6647  TVirtualStreamerInfo* info = 0;
6648  if (fConversionStreamerInfo.load()) {
6649  std::map<std::string, TObjArray*>::iterator it;
6650 
6652 
6653  it = (*fConversionStreamerInfo).find( cl->GetName() );
6654 
6655  if( it != (*fConversionStreamerInfo).end() ) {
6656  arr = it->second;
6657  }
6658  if (arr) {
6659  info = FindStreamerInfo( arr, checksum );
6660  }
6661  }
6662 
6663  if( info )
6664  return info;
6665 
6667 
6668  //----------------------------------------------------------------------------
6669  // Get it from the foreign class
6670  /////////////////////////////////////////////////////////////////////////////
6671 
6672  info = cl->FindStreamerInfo( checksum );
6673 
6674  if( !info )
6675  return 0;
6676 
6677  //----------------------------------------------------------------------------
6678  // We have the right info so we need to clone it to create new object with
6679  // non artificial streamer elements and we should build it for current class
6680  /////////////////////////////////////////////////////////////////////////////
6681 
6682  info = (TVirtualStreamerInfo*)info->Clone();
6683  if( !info->BuildFor( this ) ) {
6684  delete info;
6685  return 0;
6686  }
6687 
6688  if (!info->IsCompiled()) {
6689  // Streamer info has not been compiled, but exists.
6690  // Therefore it was read in from a file and we have to do schema evolution?
6691  // Or it didn't have a dictionary before, but does now?
6692  info->BuildOld();
6693  }
6694 
6695  //----------------------------------------------------------------------------
6696  // Cache this streamer info
6697  /////////////////////////////////////////////////////////////////////////////
6698 
6699  if (!arr) {
6700  arr = new TObjArray(16, -2);
6701  if (!fConversionStreamerInfo.load()) {
6702  fConversionStreamerInfo = new std::map<std::string, TObjArray*>();
6703  }
6704  (*fConversionStreamerInfo)[cl->GetName()] = arr;
6705  }
6706  arr->AddAtAndExpand( info, info->GetClassVersion() );
6707 
6708  return info;
6709 }
6710 
6711 ////////////////////////////////////////////////////////////////////////////////
6712 /// Register the StreamerInfo in the given slot, change the State of the
6713 /// TClass as appropriate.
6714 
6716 {
6717  if (info) {
6719  Int_t slot = info->GetClassVersion();
6720  if (fStreamerInfo->GetSize() > (slot-fStreamerInfo->LowerBound())
6721  && fStreamerInfo->At(slot) != 0
6722  && fStreamerInfo->At(slot) != info) {
6723  Error("RegisterStreamerInfo",
6724  "Register StreamerInfo for %s on non-empty slot (%d).",
6725  GetName(),slot);
6726  }
6727  fStreamerInfo->AddAtAndExpand(info, slot);
6728  if (fState <= kForwardDeclared) {
6729  fState = kEmulated;
6730  if (fCheckSum==0 && slot==fClassVersion) fCheckSum = info->GetCheckSum();
6731  }
6732  }
6733 }
6734 
6735 ////////////////////////////////////////////////////////////////////////////////
6736 /// Remove and delete the StreamerInfo in the given slot.
6737 /// Update the slot accordingly.
6738 
6740 {
6741  if (fStreamerInfo->GetSize() >= slot) {
6745  delete info;
6746  if (fState == kEmulated && fStreamerInfo->GetEntries() == 0) {
6748  }
6749  }
6750 }
6751 
6752 ////////////////////////////////////////////////////////////////////////////////
6753 /// Return true if we have access to a default constructor.
6754 
6756 {
6757 
6758  if (fNew) return kTRUE;
6759 
6760  if (HasInterpreterInfo()) {
6763  }
6764  if (fCollectionProxy) {
6765  return kTRUE;
6766  }
6767  if (fCurrentInfo.load()) {
6768  // Emulated class, we know how to construct them via the TStreamerInfo
6769  return kTRUE;
6770  }
6771  return kFALSE;
6772 }
6773 
6774 ////////////////////////////////////////////////////////////////////////////////
6775 /// Return the wrapper around Merge.
6776 
6778 {
6779  return fMerge;
6780 }
6781 
6782 ////////////////////////////////////////////////////////////////////////////////
6783 /// Return the wrapper around Merge.
6784 
6786 {
6787  return fResetAfterMerge;
6788 }
6789 
6790 ////////////////////////////////////////////////////////////////////////////////
6791 /// Return the wrapper around new ThisClass().
6792 
6794 {
6795  return fNew;
6796 }
6797 
6798 ////////////////////////////////////////////////////////////////////////////////
6799 /// Return the wrapper around new ThisClass[].
6800 
6802 {
6803  return fNewArray;
6804 }
6805 
6806 ////////////////////////////////////////////////////////////////////////////////
6807 /// Return the wrapper around delete ThiObject.
6808 
6810 {
6811  return fDelete;
6812 }
6813 
6814 ////////////////////////////////////////////////////////////////////////////////
6815 /// Return the wrapper around delete [] ThiObject.
6816 
6818 {
6819  return fDeleteArray;
6820 }
6821 
6822 ////////////////////////////////////////////////////////////////////////////////
6823 /// Return the wrapper around the destructor
6824 
6826 {
6827  return fDestructor;
6828 }
6829 
6830 ////////////////////////////////////////////////////////////////////////////////
6831 /// Return the wrapper around the directory auto add function.
6832 
6834 {
6835  return fDirAutoAdd;
6836 }
TObject * Clone(const char *newname="") const
Create a Clone of this TClass object using a different name but using the same 'dictionary'.
Definition: TClass.cxx:2256
EState GetState() const
Definition: TClass.h:442
virtual TObject * FindObject(const TObject *obj) const
Find object using its hash value (returned by its Hash() member).
void ReplaceWith(TClass *newcl) const
Definition: TClass.cxx:3784
void Add(TObject *obj, const char *name=0, Int_t check=-1)
Add object with name to browser.
Definition: TBrowser.cxx:259
void AddQualifiedName(const char *name)
Extract this part of the name.
Definition: TClass.cxx:137
void ResetCaches()
To clean out all caches.
Definition: TClass.cxx:3870
Describes one element of the context menu associated to a class The menu item may describe...
R__EXTERN void **(* gThreadTsd)(void *, Int_t)
Definition: TThreadSlots.h:42
virtual void SetClass(TClass *cl)=0
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
virtual void * New(void *obj=0)=0
Int_t GetNdata()
Return the number of data members of this class Note that in case the list of data members is not yet...
Definition: TClass.cxx:4211
void SetBufferOffset(Int_t offset=0)
Definition: TBuffer.h:90
virtual Int_t GetCollectionType() const =0
TList * GetMenuList() const
Return the list of menu items associated with the class.
Definition: TClass.cxx:3994
Bool_t AddRule(TSchemaRule *rule, EConsistencyCheck checkConsistency=kCheckAll, TString *errmsg=0)
The consistency check always fails if the TClass object was not set! if checkConsistency is: kNoCheck...
static TClass * LoadClassCustom(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition: TClass.cxx:5340
ShowMembersFunc_t fShowMembers
Definition: TClass.h:205
virtual TClassStreamer * GenEmulatedClassStreamer(const char *class_name, Bool_t silent)=0
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
TClass *(* DictFuncPtr_t)()
Definition: Rtypes.h:75
virtual void SetClass(TClass *cl)=0
Bool_t HasDefaultConstructor() const
Return true if we have access to a default constructor.
Definition: TClass.cxx:6755
TList * GetListOfBases()
Return list containing the TBaseClass(es) of a class.
Definition: TClass.cxx:3368
void(* MemberStreamerFunc_t)(TBuffer &, void *, Int_t)
Definition: Rtypes.h:69
void SetIsObject(Bool_t isObject)
Definition: TRealData.h:61
ESTLType
Definition: ESTLType.h:28
An array of TObjects.
Definition: TObjArray.h:39
static TDataType * GetDataType(EDataType type)
Given a EDataType type, get the TDataType* that represents it.
Definition: TDataType.cxx:436
ROOT::NewArrFunc_t fNewArray
Definition: TClass.h:216
virtual Int_t GetProperties() const
ROOT::MergeFunc_t GetMerge() const
Return the wrapper around Merge.
Definition: TClass.cxx:6777
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:405
std::atomic< TMethodCall * > fIsAMethod
Definition: TClass.h:211
Bool_t CanSplit() const
Return true if the data member of this TClass can be saved separately.
Definition: TClass.cxx:2152
TClass *(* IsAGlobalFunc_t)(const TClass *, const void *obj)
Definition: Rtypes.h:135
TString GetTypeName()
Get basic type of typedef, e,g.
Definition: TDataType.cxx:149
const char * GetVersion() const
Get the version string.
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
static Bool_t AddRule(const char *rule)
Add a schema evolution customization rule.
Definition: TClass.cxx:1792
virtual int DataMemberInfo_TypeSize(DataMemberInfo_t *) const
Definition: TInterpreter.h:409
ROOT::DelArrFunc_t GetDeleteArray() const
Return the wrapper around delete [] ThiObject.
Definition: TClass.cxx:6817
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition: TClass.cxx:5481
void GetMissingDictionariesForBaseClasses(TCollection &result, TCollection &visited, bool recurse)
Verify the base classes always.
Definition: TClass.cxx:3623
const char * GetTypeName() const
Bool_t IsReading() const
Definition: TBuffer.h:83
short Version_t
Definition: RtypesCore.h:61
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
virtual Bool_t CompareContent(TClass *cl, TVirtualStreamerInfo *info, Bool_t warn, Bool_t complete, TFile *file)=0
void AdoptReferenceProxy(TVirtualRefProxy *proxy)
Adopt the Reference proxy pointer to indicate that this class represents a reference.
Definition: TClass.cxx:6126
virtual void ClassInfo_Delete(ClassInfo_t *) const
Definition: TInterpreter.h:347
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
Int_t GetNmethods()
Return the number of methods of this class Note that in case the list of methods is not yet created...
Definition: TClass.cxx:4230
Ssiz_t Length() const
Definition: TString.h:390
TLine * line
virtual TClass * GetClass() const =0
const TList * GetListForObject(const char *name) const
Return the TList corresponding to object's name based hash value.
Definition: THashTable.cxx:234
Collectable string class.
Definition: TObjString.h:32
virtual void Clear(Option_t *option="")
Remove all objects from the array.
Definition: TObjArray.cxx:298
virtual void ls(Option_t *option="") const
List (ls) all objects in this collection.
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition: TClass.cxx:463
TMatrixT< Element > & Add(TMatrixT< Element > &target, Element scalar, const TMatrixT< Element > &source)
Modify addition: target += scalar * source.
Definition: TMatrixT.cxx:2925
virtual TVirtualCollectionProxy * GenExplicitProxy(const ::ROOT::Detail::TCollectionProxyInfo &info, TClass *cl)=0
R__EXTERN TClassTable * gClassTable
Definition: TClassTable.h:97
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:528
ConvSIMap_t fConversionStreamerInfo
Definition: TClass.h:180
TDictionary::DeclId_t DeclId_t
Definition: TInterpreter.h:236
void SetDelete(ROOT::DelFunc_t deleteFunc)
Install a new wrapper around 'delete'.
Definition: TClass.cxx:6439
return c
virtual Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *) const
Definition: TInterpreter.h:408
const char Option_t
Definition: RtypesCore.h:62
ROOT::DesFunc_t GetDestructor() const
Return the wrapper around the destructor.
Definition: TClass.cxx:6825
Dictionary for function template This class describes one single function template.
virtual TClass * GetValueClass() const =0
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:329
TCanvas * c1
Definition: legend1.C:2
tuple offset
Definition: tree.py:93
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:33
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
void SetMemberStreamer(const char *name, MemberStreamerFunc_t strm)
Install a new member streamer (p will be copied).
Definition: TClass.cxx:6182
void SetConvStreamerFunc(ClassConvStreamerFunc_t strm)
Set a wrapper/accessor function around this class custom conversion streamer.
Definition: TClass.cxx:6383
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
ENewType
Definition: TClass.h:101
void ls(Option_t *opt="") const
The ls function lists the contents of a class on stdout.
Definition: TClass.cxx:3911
TList * GetListOfEnums(Bool_t load=kTRUE)
Return list containing the TEnums of a class.
Definition: TClass.cxx:3408
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
#define assert(cond)
Definition: unittest.h:542
std::atomic< TListOfEnums * > fEnums
Definition: TClass.h:185
TClass * GetClassPointer(Bool_t load=kTRUE)
Get pointer to the base class TClass.
Definition: TBaseClass.cxx:63
static void StreamerExternal(const TClass *pThis, void *object, TBuffer &b, const TClass *onfile_class)
There is special streamer for the class.
Definition: TClass.cxx:6226
void BuildEmulatedRealData(const char *name, Long_t offset, TClass *cl)
Build the list of real data for an emulated class.
Definition: TClass.cxx:2014
void SetClassVersion(Version_t version)
Private function.
Definition: TClass.cxx:5214
Int_t GetNargs() const
Number of function arguments.
Definition: TFunction.cxx:164
TViewPubFunctions * fAllPubMethod
Definition: TClass.h:190
virtual void SetName(const char *name)
Change (i.e.
Definition: TNamed.cxx:128
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
ClassImp(TClass) TClass
Definition: TClass.cxx:1010
Persistent version of a TClass.
Definition: TProtoClass.h:37
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition: TClass.cxx:5462
TCollection * GetListOfMethodOverloads(const char *name) const
Return the collection of functions named "name".
Definition: TClass.cxx:3523
void ResetMenuList()
Resets the menu list to it's standard value.
Definition: TClass.cxx:3896
std::atomic< Bool_t > fHasRootPcmInfo
C++ Property of the class (is abstract, has virtual table, etc.)
Definition: TClass.h:230
virtual const char * ClassInfo_Title(ClassInfo_t *) const
Definition: TInterpreter.h:378
static THashTable * fgClassTypedefHash
Definition: TClass.h:315
void * InterfaceMethod() const
Return pointer to the interface method.
Definition: TFunction.cxx:208
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
virtual void DataMemberInfo_Delete(DataMemberInfo_t *) const
Definition: TInterpreter.h:399
void SetDeleteArray(ROOT::DelArrFunc_t deleteArrayFunc)
Install a new wrapper around 'delete []'.
Definition: TClass.cxx:6447
TMethod * GetClassMethodWithPrototype(const char *name, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Find the method with a given prototype.
Definition: TClass.cxx:4184
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:93
ROOT::DirAutoAdd_t fDirAutoAdd
Definition: TClass.h:220
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition: TClass.cxx:488
virtual void * ClassInfo_New(ClassInfo_t *) const
Definition: TInterpreter.h:368
Long_t Property() const
Set TObject::fBits and fStreamerType to cache information about the class.
Definition: TClass.cxx:5560
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
static void SetObjectStat(Bool_t stat)
Turn on/off tracking of objects in the TObjectTable.
Definition: TObject.cxx:999
static void StreamerInstrumented(const TClass *pThis, void *object, TBuffer &b, const TClass *onfile_class)
Case of instrumented class with a library.
Definition: TClass.cxx:6274
virtual int SetClassAutoloading(int) const
Definition: TInterpreter.h:222
This class implements a mutex interface.
Definition: TVirtualMutex.h:34
virtual TObject * FindObject(const char *name) const
Specialize FindObject to do search for the a function just by name or create it if its not already in...
static const char * filename()
Bool_t IsPersistent() const
Definition: TDataMember.h:89
#define R__ASSERT(e)
Definition: TError.h:98
#define gROOT
Definition: TROOT.h:344
TList * GetListOfDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of a class.
Definition: TClass.cxx:3459
const char * GetSharedLibs()
Get the list of shared libraries containing the code for class cls.
Definition: TClass.cxx:3355
virtual TVirtualStreamerInfo * NewInfo(TClass *cl)=0
virtual TClassStreamer * Generate() const
virtual Bool_t ClassInfo_HasMethod(ClassInfo_t *, const char *) const
Definition: TInterpreter.h:358
Bool_t IsZombie() const
Definition: TObject.h:141
virtual void Browse(TBrowser *b)
Browse object. May be overridden for another default action.
Definition: TObject.cxx:178
Basic string class.
Definition: TString.h:137
void GetMissingDictionariesWithRecursionCheck(TCollection &result, TCollection &visited, bool recurse)
From the second level of recursion onwards it is different state check.
Definition: TClass.cxx:3685
Bool_t IsForeign() const
Return kTRUE is the class is Foreign (the class does not have a Streamer method). ...
Definition: TClass.cxx:5471
TString fContextMenuTitle
Definition: TClass.h:203
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition: TClass.cxx:3100
TVirtualStreamerInfo * GetCurrentStreamerInfo()
Definition: TClass.h:392
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
int Int_t
Definition: RtypesCore.h:41
ROOT::NewFunc_t GetNew() const
Return the wrapper around new ThisClass().
Definition: TClass.cxx:6793
bool Bool_t
Definition: RtypesCore.h:59
TDataType * GetDataType() const
Definition: TDataMember.h:74
void *(* NewArrFunc_t)(Long_t size, void *arena)
Definition: Rtypes.h:148
TArc * a
Definition: textangle.C:12
Bool_t IsaPointer() const
Return true if data member is a pointer.
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
const Bool_t kFALSE
Definition: Rtypes.h:92
const TList * GetListOfAllPublicMethods(Bool_t load=kTRUE)
Returns a list of all public methods of this class and its base classes.
Definition: TClass.cxx:3541
virtual void ClassInfo_Destruct(ClassInfo_t *, void *) const
Definition: TInterpreter.h:350
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:497
#define gInterpreter
Definition: TInterpreter.h:502
void SetContextMenuTitle(const char *title)
Change (i.e. set) the title of the TNamed.
Definition: TClass.cxx:5716
TVirtualRefProxy * fRefProxy
cached streamer info used in the last read.
Definition: TClass.h:240
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition: TMethodArg.h:33
virtual Int_t GetSize() const =0
static void StreamerTObjectInitialized(const TClass *pThis, void *object, TBuffer &b, const TClass *onfile_class)
Case of TObjects when fIsOffsetStreamerSet is known to have been set.
Definition: TClass.cxx:6252
void Load()
Load all the DataMembers known to the interpreter for the scope 'fClass' into this collection...
static const char * GetElementCounterStart(const char *dmTitle)
Given a comment/title declaring an array counter, for example: //[fArraySize] array of size fArraySiz...
TVirtualStreamerInfo * FindStreamerInfoAbstractEmulated(UInt_t checksum) const
For the case where the requestor class is emulated and this class is abstract, returns a pointer to t...
Definition: TClass.cxx:4399
Int_t fStreamerType
saved info to call Streamer
Definition: TClass.h:236
bool IsSTLBitset(const char *type)
Return true is the name is std::bitset<number> or bitset<number>
TFunction * Get(DeclId_t id)
Return (after creating it if necessary) the TMethod or TFunction describing the function correspondin...
Int_t GetEntriesFast() const
Definition: TObjArray.h:66
virtual void Stream(TBuffer &b, void *objp, const TClass *onfileClass)
Abstract base class for accessing the data-members of a class.
static void MoveAddressInRepository(const char *, void *oldadd, void *newadd, const TClass *what)
Definition: TClass.cxx:285
static void StreamerStreamerInfo(const TClass *pThis, void *object, TBuffer &b, const TClass *onfile_class)
Case of where we should directly use the StreamerInfo.
Definition: TClass.cxx:6296
void AdoptStreamer(TClassStreamer *strm)
Adopt a TClassStreamer object.
Definition: TClass.cxx:6332
Bool_t IsLoaded() const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:558
Int_t GetMaxIndex(Int_t dim) const
Return maximum index for array dimension "dim".
virtual void Clear(Option_t *)=0
Set name and title to empty strings ("").
const void * DeclId_t
Definition: TDictionary.h:209
std::atomic< Bool_t > fIsOffsetStreamerSet
Indicates whether the ClassInfo is supposed to be available.
Definition: TClass.h:232
TMethod * GetMethodAllAny(const char *method)
Return pointer to method without looking at parameters.
Definition: TClass.cxx:4037
std::atomic< TVirtualStreamerInfo * > fLastReadInfo
cached current streamer info.
Definition: TClass.h:239
void SetClassSize(Int_t sizof)
Definition: TClass.h:267
Short_t fImplFileLine
Definition: TClass.h:196
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
void LoadClassInfo() const
Try to load the classInfo (it may require parsing the header file and/or loading data from the clang ...
Definition: TClass.cxx:5361
const char * GetFullTypeName() const
Get full type description of data member, e,g.: "class TDirectory*".
TFile * f
void(* DirAutoAdd_t)(void *, TDirectory *)
Definition: Rtypes.h:152
virtual void AddLast(TObject *obj)
Add object at the end of the list.
Definition: TList.cxx:137
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
void DeleteArray(void *ary, Bool_t dtorOnly=kFALSE)
Explicitly call operator delete[] for an array.
Definition: TClass.cxx:5076
ROOT::NewFunc_t fNew
Definition: TClass.h:215
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:625
virtual void SetToggle(Bool_t toggle=kTRUE)
TList * GetListOfRealData() const
Definition: TClass.h:404
void ResetInstanceCount()
Definition: TClass.h:483
Int_t ReadBuffer(TBuffer &b, void *pointer, Int_t version, UInt_t start, UInt_t count)
Function called by the Streamer functions to deserialize information from buffer b into object at p...
Definition: TClass.cxx:6196
const char * Data() const
Definition: TString.h:349
static IdMap_t * GetIdMap()
Definition: TClass.cxx:421
static void StreamerTObjectEmulated(const TClass *pThis, void *object, TBuffer &b, const TClass *onfile_class)
Case of TObjects when we do not have the library defining the class.
Definition: TClass.cxx:6261
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:396
Int_t GetBaseClassOffset(const TClass *toBase, void *address=0, bool isDerivedObject=true)
Definition: TClass.cxx:2625
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:946
Bool_t MatchLegacyCheckSum(UInt_t checksum) const
Return true if the checksum passed as argument is one of the checksum value produced by the older che...
Definition: TClass.cxx:5939
Int_t GetBaseClassOffsetRecurse(const TClass *toBase)
Return data member offset to the base class "cl".
Definition: TClass.cxx:2554
TIsAProxy implementation class.
Definition: TIsAProxy.h:30
virtual Int_t GetClassVersion() const =0
ClassConvStreamerFunc_t GetConvStreamerFunc() const
Get a wrapper/accessor function around this class custom conversion streamer (member function)...
Definition: TClass.cxx:2780
const char * GetTrueTypeName() const
Get full type description of data member, e,g.: "class TDirectory*".
Double_t dot(const TVector2 &v1, const TVector2 &v2)
Definition: CsgOps.cxx:333
THashTable implements a hash table to store TObject's.
Definition: THashTable.h:39
TMethod * FindClassOrBaseMethodWithId(DeclId_t faddr)
Find a method with decl id in this class or its bases.
Definition: TClass.cxx:4093
Bool_t HasInterpreterInfoInMemory() const
Definition: TClass.h:372
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2321
void Move(void *arenaFrom, void *arenaTo) const
Register the fact that an object was moved from the memory location 'arenaFrom' to the memory locatio...
Definition: TClass.cxx:3980
void Inspect() const
Bool_t FillTClass(TClass *pcl)
Move data from this TProtoClass into cl.
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition: TClass.cxx:1714
ClassStreamerFunc_t fStreamerFunc
Definition: TClass.h:221
void Class()
Definition: Class.C:29
Long64_t(* MergeFunc_t)(void *, TCollection *, TFileMergeInfo *)
Definition: Rtypes.h:153
ECheckSum
Definition: TClass.h:102
double log10(double)
static DeclIdMap_t * GetDeclIdMap()
Definition: TClass.cxx:432
UChar_t mod R__LOCKGUARD2(gSrvAuthenticateMutex)
virtual Int_t GetOffset(const char *) const =0
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4602
virtual TVirtualCollectionProxy * GenEmulatedProxy(const char *class_name, Bool_t silent)=0
ROOT::ResetAfterMergeFunc_t fResetAfterMerge
Definition: TClass.h:214
Int_t GetDelta()
Get offset from "this" to part of base class.
Definition: TBaseClass.cxx:75
TClass * GetActualClass(const void *object) const
Return a pointer the the real class of the object.
Definition: TClass.cxx:2457
virtual const char * DataMemberInfo_TypeName(DataMemberInfo_t *) const
Definition: TInterpreter.h:410
std::map< std::string, std::string >::const_iterator iter
Definition: TAlienJob.cxx:54
virtual void BuildOld()=0
void InterpretedShowMembers(void *obj, TMemberInspector &insp, Bool_t isTransient)
Do a ShowMembers() traversal of all members and base classes' members using the reflection informatio...
Definition: TClass.cxx:2144
void ResetClassInfo()
Make sure that the current ClassInfo is up to date.
Definition: TClass.cxx:3835
static void GetDateTime(UInt_t datetime, Int_t &date, Int_t &time)
Static function that returns the date and time.
Definition: TDatime.cxx:432
void SetStreamerFunc(ClassStreamerFunc_t strm)
Set a wrapper/accessor function around this class custom streamer.
Definition: TClass.cxx:6360
std::string ResolveTypedef(const char *tname, bool resolveAll=false)
ROOT::NewArrFunc_t GetNewArray() const
Return the wrapper around new ThisClass[].
Definition: TClass.cxx:6801
void(* ResetAfterMergeFunc_t)(void *, TFileMergeInfo *)
Definition: Rtypes.h:154
virtual void Inspect() const
Dump contents of this object in a graphics canvas.
Definition: TObject.cxx:508
void AdoptStreamer(TMemberStreamer *p)
Definition: TRealData.cxx:66
EFunctionMatchMode
Definition: TDictionary.h:155
virtual Bool_t IsaPointer() const
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition: TSystem.cxx:1038
virtual Long_t ClassInfo_GetBaseOffset(ClassInfo_t *, ClassInfo_t *, void *=0, bool=true) const
Definition: TInterpreter.h:354
const char * GetImplFileName() const
Definition: TClass.h:407
TClass * fClass
pointer to the foreign object
const int maxsize
TList * fBase
Definition: TClass.h:182
virtual TClass * GetActualClass(const void *obj) const =0
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:63
virtual void * NewArray(Long_t nElements, void *ary=0)=0
XFontStruct * id
Definition: TGX11.cxx:108
void RegisterStreamerInfo(TVirtualStreamerInfo *info)
Register the StreamerInfo in the given slot, change the State of the TClass as appropriate.
Definition: TClass.cxx:6715
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
std::atomic< Bool_t > fVersionUsed
saved remember if fOffsetStreamer has been set.
Definition: TClass.h:233
TListOfFunctionTemplates * fFuncTemplate
Definition: TClass.h:186
static ENewType IsCallingNew()
Static method returning the defConstructor flag passed to TClass::New().
Definition: TClass.cxx:5426
Int_t WriteBuffer(TBuffer &b, void *pointer, const char *info="")
Function called by the Streamer functions to serialize object at p to buffer b.
Definition: TClass.cxx:6217
bool IsInterpreterDetail(const char *type)
Return true if the type is one the interpreter details which are only forward declared (ClassInfo_t e...
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:59
virtual int DataMemberInfo_MaxIndex(DataMemberInfo_t *, Int_t) const
Definition: TInterpreter.h:404
TViewPubDataMembers * fAllPubData
Definition: TClass.h:189
virtual Bool_t ClassInfo_IsValid(ClassInfo_t *) const
Definition: TInterpreter.h:364
TList * fClassMenuList
Definition: TClass.h:191
Long_t Property() const
Get property description word. For meaning of bits see EProperty.
Definition: TDataType.cxx:283
TVirtualStreamerInfo * SetStreamerInfo(Int_t version, const char *info="")
Info is a string describing the names and types of attributes written by the class Streamer function...
Definition: TClass.cxx:5818
ROOT::Detail::TSchemaRuleSet * fSchemaRules
Pointer to reference proxy if this class represents a reference.
Definition: TClass.h:241
virtual void ls(Option_t *option="") const
List TNamed name and title.
Definition: TNamed.cxx:102
TVirtualStreamerInfo * FindStreamerInfo(TObjArray *arr, UInt_t checksum) const
Find the TVirtualStreamerInfo in the StreamerInfos corresponding to checksum.
Definition: TClass.cxx:6502
UInt_t GetCheckSum(ECheckSum code=kCurrentCheckSum) const
Call GetCheckSum with validity check.
Definition: TClass.cxx:5950
std::atomic< StreamerImpl_t > fStreamerImpl
Definition: TClass.h:247
TList * fRealData
Definition: TClass.h:181
ROOT::DelFunc_t GetDelete() const
Return the wrapper around delete ThiObject.
Definition: TClass.cxx:6809
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:743
A doubly linked list.
Definition: TList.h:47
static const char * what
Definition: stlLoader.cc:6
View implementing the TList interface and giving access all the TDictionary describing public data me...
virtual void Destructor(void *p, Bool_t dtorOnly=kFALSE) const
TClass * GetBaseClass(const char *classname)
Return pointer to the base class "classname".
Definition: TClass.cxx:2504
const char * fImplFileName
Definition: TClass.h:194
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:91
virtual void BuildCheck(TFile *file=0)=0
TRealData * GetRealData(const char *name) const
Return pointer to TRealData element with name "name".
Definition: TClass.cxx:3195
virtual const char * ClassInfo_FullName(ClassInfo_t *) const
Definition: TInterpreter.h:376
virtual void Delete(Option_t *option="")
Delete all TFunction object files.
void BuildRealData(void *pointer=0, Bool_t isTransient=kFALSE)
Build a full list of persistent data members.
Definition: TClass.cxx:1933
TClass * CreateClass(const char *cname, Version_t id, const type_info &info, TVirtualIsAProxy *isa, const char *dfil, const char *ifil, Int_t dl, Int_t il)
Global function called by a class' static Dictionary() method (see the ClassDef macro).
Definition: TClass.cxx:5393
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:41
std::atomic_flag & fAFlag
Definition: TClass.h:136
Int_t fCanSplit
Definition: TClass.h:225
static void RegisterAddressInRepository(const char *, void *location, const TClass *what)
Definition: TClass.cxx:238
void SetNew(ROOT::NewFunc_t newFunc)
Install a new wrapper around 'new'.
Definition: TClass.cxx:6423
static DictFuncPtr_t GetDict(const char *cname)
Return a pointer to the dictionary loading function generated by rootcint.
Definition: TClass.cxx:3124
const type_info * fTypeInfo
Definition: TClass.h:204
std::atomic< TVirtualStreamerInfo * > fCurrentInfo
Current 'state' of the class (Emulated,Interpreted,Loaded)
Definition: TClass.h:238
TThread * t[5]
Definition: threadsh1.C:13
const char * GetTypeName() const
Get type of data member, e,g.: "class TDirectory*" -> "TDirectory".
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();...
Definition: TMethod.cxx:305
virtual char * ReadString(char *s, Int_t max)=0
Int_t LowerBound() const
Definition: TObjArray.h:98
TVirtualStreamerInfo * FindConversionStreamerInfo(const char *onfile_classname, UInt_t checksum) const
Return a Conversion StreamerInfo from the class 'classname' for the layout represented by 'checksum' ...
Definition: TClass.cxx:6619
virtual Bool_t BuildFor(const TClass *cl)=0
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Definition: TExMap.cxx:173
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
Definition: TObjArray.cxx:222
R__EXTERN TSystem * gSystem
Definition: TSystem.h:545
return
Definition: TBase64.cxx:62
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist...
Definition: TClass.cxx:4256
SVector< double, 2 > v
Definition: Dict.h:5
void AdoptMemberStreamer(const char *name, TMemberStreamer *strm)
Adopt the TMemberStreamer pointer to by p and use it to Stream non basic member name.
Definition: TClass.cxx:6144
TPaveLabel title(3, 27.1, 15, 28.7,"ROOT Environment and Tools")
void MakeCustomMenuList()
Makes a customizable version of the popup menu list, i.e.
Definition: TClass.cxx:3936
void GetNormalizedName(std::string &norm_name, std::string_view name)
Return the normalized name.
Definition: TClassEdit.cxx:777
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:46
This class defines an abstract interface that must be implemented by all classes that contain diction...
Definition: TDictionary.h:162
void GetMissingDictionariesForPairElements(TCollection &result, TCollection &visited, bool recurse)
Definition: TClass.cxx:3668
void Init(const char *name, Version_t cversion, const type_info *info, TVirtualIsAProxy *isa, const char *dfil, const char *ifil, Int_t dl, Int_t il, ClassInfo_t *classInfo, Bool_t silent)
Initialize a TClass object.
Definition: TClass.cxx:1304
void Store(TBuffer &b) const
Store class description on I/O buffer.
Definition: TClass.cxx:5384
virtual const char * DataMemberInfo_Name(DataMemberInfo_t *) const
Definition: TInterpreter.h:412
void SetDestructor(ROOT::DesFunc_t destructorFunc)
Install a new wrapper around the destructor.
Definition: TClass.cxx:6455
virtual TObject * RemoveAt(Int_t idx)
Remove object at index idx.
Definition: TObjArray.cxx:630
TVirtualStreamerInfo * GetConversionStreamerInfo(const char *onfile_classname, Int_t version) const
Return a Conversion StreamerInfo from the class 'classname' for version number 'version' to this clas...
Definition: TClass.cxx:6522
virtual Long_t ClassInfo_Property(ClassInfo_t *) const
Definition: TInterpreter.h:372
ClassInfo_t * GetClassInfo() const
Definition: TClass.h:390
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:675
void GetMissingDictionariesForMembers(TCollection &result, TCollection &visited, bool recurse)
Verify the Data Members.
Definition: TClass.cxx:3640
virtual Bool_t HasPointers() const =0
void SetGlobalIsA(IsAGlobalFunc_t)
This function installs a global IsA function for this class.
Definition: TClass.cxx:5747
void SetUnloaded()
Call this method to indicate that the shared library containing this class's code has been removed (u...
Definition: TClass.cxx:5756
Collection abstract base class.
Definition: TCollection.h:48
virtual Int_t AutoParse(const char *cls)=0
void SetDirectoryAutoAdd(ROOT::DirAutoAdd_t dirAutoAddFunc)
Install a new wrapper around the directory auto add function.
Definition: TClass.cxx:6466
void Destructor(void *obj, Bool_t dtorOnly=kFALSE)
Explicitly call destructor for object.
Definition: TClass.cxx:4959
void IgnoreTObjectStreamer(Bool_t ignore=kTRUE)
When the class kIgnoreTObjectStreamer bit is set, the automatically generated Streamer will not call ...
Definition: TClass.cxx:4465
TObject * Value() const
Definition: TMap.h:125
void SetClass(TClass *cls)
Set the TClass associated with this rule set.
Bool_t HasInterpreterInfo() const
Definition: TClass.h:373
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2308
static void StreamerTObject(const TClass *pThis, void *object, TBuffer &b, const TClass *onfile_class)
Case of TObjects.
Definition: TClass.cxx:6238
virtual void Release()=0
unsigned int UInt_t
Definition: RtypesCore.h:42
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
TMarker * m
Definition: textangle.C:8
Bool_t IsStartingWithTObject() const
Returns true if this class inherits from TObject and if the start of the TObject parts is at the very...
Definition: TClass.cxx:5453
void Draw(Option_t *option="")
Draw detailed class inheritance structure.
Definition: TClass.cxx:2336
Short_t GetDeclFileLine() const
Definition: TClass.h:386
bool first
Definition: line3Dfit.C:48
static void UnregisterAddressInRepository(const char *, void *location, const TClass *what)
Definition: TClass.cxx:266
virtual int DataMemberInfo_ArrayDim(DataMemberInfo_t *) const
Definition: TInterpreter.h:398
void GetMissingDictionaries(THashTable &result, bool recurse=false)
Get the classes that have a missing dictionary starting from this one.
Definition: TClass.cxx:3734
virtual void * New() const
TLine * l
Definition: textangle.C:4
The TRealData class manages the effective list of all data members for a given class.
Definition: TRealData.h:34
virtual void Browse(TBrowser *b)
This method is called by a browser to get the class information.
Definition: TClass.cxx:1912
Bool_t CanIgnoreTObjectStreamer()
Definition: TClass.h:357
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
InsertTClassInRegistryRAII(TClass::EState &state, const char *name, TDeclNameRegistry &emuRegistry)
Definition: TClass.cxx:204
Objects following this interface can be passed onto the TROOT object to implement a user customized w...
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
TVirtualCollectionProxy * fCollectionProxy
Definition: TClass.h:200
const std::string sname
Definition: testIO.cxx:45
TClass * GetBaseDataMember(const char *datamember)
Return pointer to (base) class that contains datamember.
Definition: TClass.cxx:2660
ClassStreamerFunc_t GetStreamerFunc() const
Get a wrapper/accessor function around this class custom streamer (member function).
Definition: TClass.cxx:2772
ROOT::TMapTypeToTClass IdMap_t
Definition: TClass.h:78
void CalculateStreamerOffset() const
Calculate the offset between an object of this class to its base class TObject.
Definition: TClass.cxx:2085
Version_t GetClassVersion() const
Definition: TClass.h:381
Bool_t IsNull() const
Definition: TString.h:387
virtual TObjLink * FirstLink() const
Definition: TList.h:101
UInt_t fInstanceCount
Definition: TClass.h:197
static Bool_t GetObjectStat()
Get status of object stat flag.
Definition: TObject.cxx:992
TString fName
Definition: TNamed.h:36
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
TVirtualIsAProxy * GetIsAProxy() const
Return the proxy implementing the IsA functionality.
Definition: TClass.cxx:2788
virtual void * NewArray(Int_t nElements) const
static TVirtualMutex * gOVRMutex
Definition: TClass.cxx:234
UInt_t fOnHeap
Definition: TClass.h:198
Each class (see TClass) has a linked list of its base class(es).
Definition: TBaseClass.h:35
#define Printf
Definition: TGeoToOCC.h:18
Bool_t HasDictionary()
Check whether a class has a dictionary or not.
Definition: TClass.cxx:3602
void SetCollectionProxy(const ROOT::Detail::TCollectionProxyInfo &)
Create the collection proxy object (and the streamer object) from using the information in the TColle...
Definition: TClass.cxx:5691
TListOfFunctions * GetMethodList()
Pointer to the function implementing the right streaming behavior for the class represented by this o...
Definition: TClass.cxx:4008
View implementing the TList interface and giving access all the TFunction describing public methods i...
const char * GetTargetClass() const
Get the targte class of this rule (i.e. the in memory class).
static void StreamerDefault(const TClass *pThis, void *object, TBuffer &b, const TClass *onfile_class)
Default streaming in cases where either we have no way to know what to do or if Property() has not ye...
Definition: TClass.cxx:6311
Bool_t CallShowMembers(const void *obj, TMemberInspector &insp, Bool_t isTransient=kFALSE) const
Call ShowMembers() on the obj of this class type, passing insp and parent.
Definition: TClass.cxx:2107
static void RemoveClass(TClass *cl)
static: Remove a class from the list and map of classes
Definition: TClass.cxx:472
TEllipse dict(9, 20, 3, 1.5)
TList * GetListOfAllPublicDataMembers(Bool_t load=kTRUE)
Returns a list of all public data members of this class and its base classes.
Definition: TClass.cxx:3558
virtual void SetClass(TClass *classptr)=0
void(* DesFunc_t)(void *)
Definition: Rtypes.h:151
void Load()
Load all the functions known to the interpreter for the scope 'fClass' and all its bases classes...
virtual void Destructor(void *p, Bool_t dtorOnly=kFALSE)=0
TMethod * GetClassMethod(Long_t faddr)
Look for a method in this class that has the interface function address faddr.
Definition: TClass.cxx:4140
ROOT::DesFunc_t fDestructor
Definition: TClass.h:219
std::atomic_flag fSpinLock
Definition: TClass.h:151
Int_t fSizeof
Definition: TClass.h:223
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
long Long_t
Definition: RtypesCore.h:50
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition: TClass.cxx:5436
void ForceReload(TClass *oldcl)
we found at least one equivalent.
Definition: TClass.cxx:1279
int Ssiz_t
Definition: RtypesCore.h:63
void SetCanSplit(Int_t splitmode)
Set the splitability of this class: -1: Use the default calculation 0: Disallow splitting 1: Always a...
Definition: TClass.cxx:5197
std::atomic< TListOfFunctions * > fMethod
Definition: TClass.h:187
Short_t GetImplFileLine() const
Definition: TClass.h:408
ROOT::DelArrFunc_t fDeleteArray
Definition: TClass.h:218
TClass * GetClass() const
Definition: TMethod.h:57
Class used by TMap to store (key,value) pairs.
Definition: TMap.h:106
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
virtual int DataMemberInfo_Next(DataMemberInfo_t *) const
Definition: TInterpreter.h:405
virtual Int_t GetSize() const
Definition: TCollection.h:95
void *(* NewFunc_t)(void *)
Definition: Rtypes.h:147
TObjArray * fStreamerInfo
Definition: TClass.h:179
EMenuItemKind IsMenuItem() const
Definition: TMethod.h:58
std::atomic< TClass ** > fPersistentRef
Definition: TClass.h:175
virtual UInt_t Sizeof() const =0
Long_t fOffsetStreamer
Indicates whether GetClassVersion has been called.
Definition: TClass.h:235
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
EState fState
cached of the streaming method to use
Definition: TClass.h:237
virtual TObjArray * GetElements() const =0
char * EscapeChars(const char *text) const
Introduce an escape character (@) in front of a special chars.
Definition: TClass.cxx:2418
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
TText * text
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
ROOT::DelFunc_t fDelete
Definition: TClass.h:217
void RemoveStreamerInfo(Int_t slot)
Remove and delete the StreamerInfo in the given slot.
Definition: TClass.cxx:6739
virtual int ClassInfo_Size(ClassInfo_t *) const
Definition: TInterpreter.h:373
void(* ClassStreamerFunc_t)(TBuffer &, void *)
Definition: Rtypes.h:67
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:44
TClass::ENewType & TClass__GetCallingNew()
Definition: TClass.cxx:223
int type
Definition: TGX11.cxx:120
static void AddClass(TClass *cl)
static: Add a class to the list and map of classes.
Definition: TClass.cxx:446
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
virtual Long_t DataMemberInfo_Property(DataMemberInfo_t *) const
Definition: TInterpreter.h:407
unsigned long ULong_t
Definition: RtypesCore.h:51
virtual ~TClass()
TClass dtor. Deletes all list that might have been created.
Definition: TClass.cxx:1558
void(* DelArrFunc_t)(void *)
Definition: Rtypes.h:150
double func(double *x, double *p)
Definition: stressTF1.cxx:213
void SetStreamerImpl()
Internal routine to set fStreamerImpl based on the value of fStreamerType.
Definition: TClass.cxx:5662
EDataType
Definition: TDataType.h:30
TMethod * GetMethod(const char *method, const char *params, Bool_t objectIsConst=kFALSE)
Find the best method (if there is one) matching the parameters.
Definition: TClass.cxx:4064
void Add(TObject *obj)
Add object to the hash table.
Definition: THashTable.cxx:76
virtual void * At(UInt_t idx)=0
TClassStreamer * GetStreamer() const
Return the Streamer Class allowing streaming (if any).
Definition: TClass.cxx:2747
static TDeclNameRegistry fNoInfoOrEmuOrFwdDeclNameRegistry
Definition: TClass.h:286
#define R__LOCKGUARD(mutex)
Long_t Property() const
Get property description word. For meaning of bits see EProperty.
Definition: TBaseClass.cxx:134
Long_t GetDataMemberOffset(const char *membername) const
return offset for member name.
Definition: TClass.cxx:3169
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
virtual void Add(TObject *obj)=0
void Dump() const
Dump contents of object on stdout.
Definition: TClass.h:362
TVirtualStreamerInfo * DetermineCurrentStreamerInfo()
Determine and set pointer to current TVirtualStreamerInfo.
Definition: TClass.cxx:5223
virtual Version_t GetOldVersion() const =0
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2801
TVirtualIsAProxy * fIsA
Definition: TClass.h:209
std::atomic< Long_t > fProperty
Indicates whether this class can be split or not.
Definition: TClass.h:226
virtual void ClassInfo_DeleteArray(ClassInfo_t *, void *, bool) const
Definition: TInterpreter.h:349
ROOT::DirAutoAdd_t GetDirectoryAutoAdd() const
Return the wrapper around the directory auto add function.
Definition: TClass.cxx:6833
UInt_t Find(std::list< std::pair< const Node< T > *, Float_t > > &nlist, const Node< T > *node, const T &event, UInt_t nfind)
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition: TClass.cxx:5288
virtual void Update(const TClass *oldClass, TClass *newClass)=0
virtual void Delete(Option_t *option="")
Delete all TDataMember object files.
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2730
#define name(a, b)
Definition: linkTestLib0.cpp:5
IsAGlobalFunc_t fGlobalIsA
pointer to the class's IsA proxy.
Definition: TClass.h:210
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition: TClass.cxx:3141
ROOT::TMapDeclIdToTClass DeclIdMap_t
Definition: TClass.h:79
Long_t fClassProperty
Property.
Definition: TClass.h:227
TDeclNameRegistry(Int_t verbLevel=0)
TDeclNameRegistry class constructor.
Definition: TClass.cxx:126
virtual TList * GetListForObject(const char *name) const
Return the set of overloads for this name, collecting all available ones.
Mother of all ROOT objects.
Definition: TObject.h:58
Short_t fDeclFileLine
Definition: TClass.h:195
Global functions class (global functions are obtained from CINT).
Definition: TFunction.h:30
Int_t GetArrayDim() const
Return number of array dimensions.
virtual void Inspect(TClass *cl, const char *parent, const char *name, const void *addr)
TFunctionTemplate * GetFunctionTemplate(const char *name)
Definition: TClass.cxx:3339
static TVirtualStreamerInfo * Factory()
Static function returning a pointer to a new TVirtualStreamerInfo object.
void Load()
Load all the functions known to the interpreter for the scope 'fClass' into this collection.
virtual UInt_t Size() const =0
TClassRef is used to implement a permanent reference to a TClass object.
Definition: TClassRef.h:33
static std::atomic< Int_t > fgClassCount
Definition: TClass.h:284
void(* ClassConvStreamerFunc_t)(TBuffer &, void *, const TClass *)
Definition: Rtypes.h:68
TNameMapNode(const char *typedf, const char *orig)
Definition: TClass.cxx:700
Version_t fClassVersion
Definition: TClass.h:201
TString fSharedLibs
Definition: TClass.h:207
void Unload()
Mark 'all func' as being unloaded.
const char * GetDeclFileName() const
Definition: TClass.h:385
virtual void Build()=0
void AddImplFile(const char *filename, int line)
Definition: TClass.cxx:1854
TVirtualMutex * gInterpreterMutex
Definition: TClass.cxx:106
std::atomic< UInt_t > fCheckSum
Definition: TClass.h:199
Bool_t IsFolder() const
Returns kTRUE in case object contains browsable objects (like containers or lists of other objects)...
Definition: TClass.h:458
TListOfDataMembers * fData
Definition: TClass.h:183
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
Definition: TMethodArg.cxx:75
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
Definition: TListOfEnums.h:36
virtual Long_t ClassInfo_ClassProperty(ClassInfo_t *) const
Definition: TInterpreter.h:346
ROOT::ESTLType IsSTLContainer()
Return which type (if any) of STL container the data member is.
Definition: TBaseClass.cxx:101
ClassInfo_t * fClassInfo
Definition: TClass.h:202
virtual Int_t GetOnFileClassVersion() const =0
virtual void Add(TObject *obj)
Definition: TList.h:81
const Ssiz_t kNPOS
Definition: Rtypes.h:115
Int_t Length() const
Definition: TBuffer.h:96
virtual void DeleteArray(void *p, Bool_t dtorOnly=kFALSE)=0
R__EXTERN const char * gRootDir
Definition: TSystem.h:233
static TClass * LoadClassDefault(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition: TClass.cxx:5310
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
void MakeZombie()
Definition: TObject.h:68
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:40
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
void GetMenuItems(TList *listitems)
Returns list of methods accessible by context menu.
Definition: TClass.cxx:3570
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashTable.cxx:210
static TClass * Load(TBuffer &b)
Load class description from I/O buffer and return class object.
Definition: TClass.cxx:5254
const char * GetTargetString() const
Get the target data members of this rule as a simple string (i.e. the in memory data member)...
ClassConvStreamerFunc_t fConvStreamerFunc
Definition: TClass.h:222
const ROOT::Detail::TSchemaRuleSet * GetSchemaRules() const
Return the set of the schema rules if any.
Definition: TClass.cxx:1834
void * gMmallocDesc
Definition: TClass.cxx:108
#define gPad
Definition: TVirtualPad.h:288
ClassImp(TSlaveInfo) Int_t TSlaveInfo const TSlaveInfo * si
Used to sort slaveinfos by ordinal.
Definition: TProof.cxx:183
Int_t GetType() const
void Load()
Load all the DataMembers known to the interpreter for the scope 'fClass' and all its bases classes...
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
const char * fDeclFileName
Definition: TClass.h:193
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition: TClass.cxx:2719
Bool_t IsBasic() const
Return true if data member is a basic type, e.g. char, int, long...
const TObjArray * GetStreamerInfos() const
Definition: TClass.h:446
Long_t Property() const
Get property description word. For meaning of bits see EProperty.
TClassStreamer * fStreamer
Definition: TClass.h:206
void SetMerge(ROOT::MergeFunc_t mergeFunc)
Install a new wrapper around 'Merge'.
Definition: TClass.cxx:6407
void SetCurrentStreamerInfo(TVirtualStreamerInfo *info)
Set pointer to current TVirtualStreamerInfo.
Definition: TClass.cxx:5235
std::atomic< Bool_t > fCanLoadClassInfo
Whether info was loaded from a root pcm.
Definition: TClass.h:231
static void ConvStreamerInstrumented(const TClass *pThis, void *object, TBuffer &b, const TClass *onfile_class)
Case of instrumented class with a library.
Definition: TClass.cxx:6283
double result[121]
virtual Int_t ReadClassEmulated(const TClass *cl, void *object, const TClass *onfile_class=0)=0
void * DynamicCast(const TClass *base, void *obj, Bool_t up=kTRUE)
Cast obj of this class type up to baseclass cl if up is true.
Definition: TClass.cxx:4539
void ResetBit(UInt_t f)
Definition: TObject.h:172
void SetResetAfterMerge(ROOT::ResetAfterMergeFunc_t resetFunc)
Install a new wrapper around 'ResetAfterMerge'.
Definition: TClass.cxx:6415
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4498
Bool_t HasDeclName(const char *name) const
Definition: TClass.cxx:164
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TMethod * GetMethodAny(const char *method)
Return pointer to method without looking at parameters.
Definition: TClass.cxx:4027
Bool_t HasDataMemberInfo() const
Definition: TClass.h:370
ROOT::ResetAfterMergeFunc_t GetResetAfterMerge() const
Return the wrapper around Merge.
Definition: TClass.cxx:6785
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
const Bool_t kIterBackward
Definition: TCollection.h:44
virtual void DeleteArray(void *p, Bool_t dtorOnly=kFALSE) const
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:504
Long_t ClassProperty() const
Return the C++ property of this class, eg.
Definition: TClass.cxx:2246
Abstract Interface class describing Streamer information for one class.
const Bool_t kTRUE
Definition: Rtypes.h:91
static Bool_t HasDictionarySelection(const char *clname)
Check whether a class has a dictionary or ROOT can load one.
Definition: TClass.cxx:3613
Long_t GetThisOffset() const
Definition: TRealData.h:59
virtual const char * GetName() const
Returns name of object.
Definition: TRealData.h:56
TMethod * GetMethodWithPrototype(const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Find the method with a given prototype.
Definition: TClass.cxx:4113
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
TObject * obj
TList * GetListOfMethods(Bool_t load=kTRUE)
Return list containing the TMethods of a class.
Definition: TClass.cxx:3508
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:379
float value
Definition: math.cpp:443
void SetNewArray(ROOT::NewArrFunc_t newArrayFunc)
Install a new wrapper around 'new []'.
Definition: TClass.cxx:6431
virtual TVirtualRefProxy * Clone() const =0
const char * AsString(void *buf) const
Return string containing value in buffer formatted according to the basic data type.
Definition: TDataType.cxx:235
virtual Bool_t ClassInfo_HasDefaultConstructor(ClassInfo_t *) const
Definition: TInterpreter.h:357
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name)...
virtual DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *=0) const
Definition: TInterpreter.h:400
TSpinLockGuard(std::atomic_flag &aflag)
Definition: TClass.cxx:190
void CopyCollectionProxy(const TVirtualCollectionProxy &)
Copy the argument.
Definition: TClass.cxx:2319
std::multimap< void *, ObjRepoValue > RepoCont_t
Definition: TClass.cxx:235
static Int_t AutoBrowse(TObject *obj, TBrowser *browser)
Browse external object inherited from TObject.
Definition: TClass.cxx:1868
const type_info * GetTypeInfo() const
Definition: TClass.h:450
void(* DelFunc_t)(void *)
Definition: Rtypes.h:149
void * NewArray(Long_t nElements, ENewType defConstructor=kClassNew) const
Return a pointer to a newly allocated array of objects of this class.
Definition: TClass.cxx:4784
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5243
This class stores a (key,value) pair using an external hash.
Definition: TExMap.h:35
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:453
ROOT::MergeFunc_t fMerge
saved info to call a IsA member function
Definition: TClass.h:213
void AddAt(UInt_t slot, ULong64_t hash, Long64_t key, Long64_t value)
Add an (key,value) pair to the table.
Definition: TExMap.cxx:116
void Class_ShowMembers(TClass *cl, const void *obj, TMemberInspector &)
Indirect call to the implementation of ShowMember allowing [forward] declaration with out a full defi...
Definition: TClass.cxx:498
TText gen(9, 20.7,"rootcint")
void AdoptSchemaRules(ROOT::Detail::TSchemaRuleSet *rules)
Adopt a new set of Data Model Evolution rules.
Definition: TClass.cxx:1822
TVirtualStreamerInfo * GetStreamerInfoAbstractEmulated(Int_t version=0) const
For the case where the requestor class is emulated and this class is abstract, returns a pointer to t...
Definition: TClass.cxx:4339
Bool_t SetFromRule(const char *rule)
Set the content fot this object from the rule See TClass::AddRule for details on the syntax...
TObject * Remove(TObject *obj)
Remove object from the hashtable.
Definition: THashTable.cxx:315
virtual TVirtualCollectionProxy * Generate() const =0
static RepoCont_t gObjectVersionRepository
Definition: TClass.cxx:236
virtual void WriteString(const char *s)=0
EState
Definition: TClass.h:115
virtual UInt_t GetCheckSum() const =0
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return list containing the TEnums of a class.
Definition: TClass.cxx:3494
int ii
Definition: hprod.C:34
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
Definition: TString.cxx:592
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904