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