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