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