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