103 #define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
104 #define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
126 TVirtualMutex* gInterpreterMutex = 0;
130 static constexpr
const char kUndeterminedClassInfoName[] =
"<NOT YET DETERMINED FROM fClassInfo>";
132 class TMmallocDescTemp {
136 TMmallocDescTemp(
void *value = 0) :
137 fSave(ROOT::Internal::gMmallocDesc) { ROOT::Internal::gMmallocDesc = value; }
138 ~TMmallocDescTemp() { ROOT::Internal::gMmallocDesc = fSave; }
142 std::atomic<Int_t> TClass::fgClassCount;
149 TClass::TDeclNameRegistry::TDeclNameRegistry(Int_t verbLevel): fVerbLevel(verbLevel)
152 std::atomic_flag_clear( &fSpinLock );
160 void TClass::TDeclNameRegistry::AddQualifiedName(
const char *name)
163 auto strLen = strlen(name);
164 if (strLen == 0)
return;
166 const char* endCharPtr = strchr(name,
'<');
167 endCharPtr = !endCharPtr ? &name[strLen] : endCharPtr;
169 const char* beginCharPtr = endCharPtr;
170 while (beginCharPtr!=name){
171 if (*beginCharPtr==
':'){
177 beginCharPtr = beginCharPtr!=endCharPtr ? beginCharPtr : name;
178 std::string s(beginCharPtr, endCharPtr);
180 printf(
"TDeclNameRegistry::AddQualifiedName Adding key %s for class/namespace %s\n", s.c_str(), name);
181 ROOT::Internal::TSpinLockGuard slg(fSpinLock);
182 fClassNamesSet.insert(s);
187 Bool_t TClass::TDeclNameRegistry::HasDeclName(
const char *name)
const
189 Bool_t found =
false;
191 ROOT::Internal::TSpinLockGuard slg(fSpinLock);
192 found = fClassNamesSet.find(name) != fClassNamesSet.end();
199 TClass::TDeclNameRegistry::~TDeclNameRegistry()
201 if (fVerbLevel > 1) {
202 printf(
"TDeclNameRegistry Destructor. List of %lu names:\n",
203 (
long unsigned int)fClassNamesSet.size());
204 for (
auto const & key: fClassNamesSet) {
205 printf(
" - %s\n", key.c_str());
212 TClass::InsertTClassInRegistryRAII::InsertTClassInRegistryRAII(TClass::EState &state,
214 TDeclNameRegistry &emuRegistry): fState(state),fName(name), fNoInfoOrEmuOrFwdDeclNameRegistry(emuRegistry) {}
218 TClass::InsertTClassInRegistryRAII::~InsertTClassInRegistryRAII() {
219 if (fState == TClass::kNoInfo ||
220 fState == TClass::kEmulated ||
221 fState == TClass::kForwardDeclared){
222 fNoInfoOrEmuOrFwdDeclNameRegistry.AddQualifiedName(fName);
227 TClass::TDeclNameRegistry TClass::fNoInfoOrEmuOrFwdDeclNameRegistry;
231 TClass::ENewType &TClass__GetCallingNew() {
232 TTHREAD_TLS(TClass::ENewType) fgCallingNew = TClass::kRealNew;
236 struct ObjRepoValue {
237 ObjRepoValue(
const TClass *what, Version_t version) : fClass(what),fVersion(version) {}
238 const TClass *fClass;
242 static TVirtualMutex* gOVRMutex = 0;
243 typedef std::multimap<void*, ObjRepoValue> RepoCont_t;
244 static RepoCont_t gObjectVersionRepository;
246 static void RegisterAddressInRepository(
const char * ,
void *location,
const TClass *what)
250 Version_t version = what->GetClassVersion();
257 R__LOCKGUARD2(gOVRMutex);
258 gObjectVersionRepository.insert(RepoCont_t::value_type(location, RepoCont_t::mapped_type(what,version)));
262 std::pair<RepoCont_t::iterator, Bool_t> tmp = gObjectVersionRepository.insert(RepoCont_t::value_type>(location, RepoCont_t::mapped_type(what,version)));
264 Warning(where,
"Reregistering an object of class '%s' version %d at address %p", what->GetName(), version, p);
265 gObjectVersionRepository.erase(tmp.first);
266 tmp = gObjectVersionRepository.insert(RepoCont_t::value_type>(location, RepoCont_t::mapped_type(what,version)));
268 Warning(where,
"Failed to reregister an object of class '%s' version %d at address %p", what->GetName(), version, location);
274 static void UnregisterAddressInRepository(
const char * ,
void *location,
const TClass *what)
278 R__LOCKGUARD2(gOVRMutex);
279 RepoCont_t::iterator cur = gObjectVersionRepository.find(location);
280 for (; cur != gObjectVersionRepository.end();) {
281 RepoCont_t::iterator tmp = cur++;
282 if ((tmp->first == location) && (tmp->second.fVersion == what->GetClassVersion())) {
285 gObjectVersionRepository.erase(tmp);
293 static void MoveAddressInRepository(
const char * ,
void *oldadd,
void *newadd,
const TClass *what)
298 size_t objsize = what->Size();
299 long delta = (
char*)newadd - (
char*)oldadd;
300 R__LOCKGUARD2(gOVRMutex);
301 RepoCont_t::iterator cur = gObjectVersionRepository.find(oldadd);
302 for (; cur != gObjectVersionRepository.end();) {
303 RepoCont_t::iterator tmp = cur++;
304 if (oldadd <= tmp->first && tmp->first < ( ((
char*)oldadd) + objsize) ) {
307 gObjectVersionRepository.insert(RepoCont_t::value_type(((
char*)tmp->first)+delta, RepoCont_t::mapped_type(tmp->second.fClass,tmp->second.fVersion)));
308 gObjectVersionRepository.erase(tmp);
320 #define R__USE_STD_MAP
321 class TMapTypeToTClass {
322 #if defined R__USE_STD_MAP
326 typedef std::map<std::string,TClass*> IdMap_t;
327 typedef IdMap_t::key_type key_type;
328 typedef IdMap_t::const_iterator const_iterator;
329 typedef IdMap_t::size_type size_type;
332 typedef TClass* mapped_type;
334 typedef IdMap_t::mapped_type mapped_type;
341 void Add(
const key_type &key, mapped_type &obj)
346 mapped_type Find(
const key_type &key)
const
349 IdMap_t::const_iterator iter = fMap.find(key);
351 if (iter != fMap.end()) cl = iter->second;
354 void Remove(
const key_type &key) {
363 #ifdef R__COMPLETE_MEM_TERMINATION
367 while((key = (TObjString*)next())) {
372 void Add(
const char *key, TClass *&obj) {
373 TObjString *realkey =
new TObjString(key);
374 fMap.Add(realkey, obj);
376 TClass* Find(
const char *key)
const {
377 const TPair *a = (
const TPair *)fMap.FindObject(key);
378 if (a)
return (TClass*) a->Value();
381 void Remove(
const char *key) {
382 TObjString realkey(key);
383 TObject *actual = fMap.Remove(&realkey);
389 class TMapDeclIdToTClass {
392 typedef multimap<TDictionary::DeclId_t, TClass*> DeclIdMap_t;
393 typedef DeclIdMap_t::key_type key_type;
394 typedef DeclIdMap_t::mapped_type mapped_type;
395 typedef DeclIdMap_t::const_iterator const_iterator;
396 typedef std::pair <const_iterator, const_iterator> equal_range;
397 typedef DeclIdMap_t::size_type size_type;
403 void Add(
const key_type &key, mapped_type obj)
406 std::pair<const key_type, mapped_type> pair = make_pair(key, obj);
409 size_type CountElementsWithKey(
const key_type &key)
411 return fMap.count(key);
413 equal_range Find(
const key_type &key)
const
416 return fMap.equal_range(key);
418 void Remove(
const key_type &key) {
425 IdMap_t *TClass::GetIdMap() {
427 #ifdef R__COMPLETE_MEM_TERMINATION
428 static IdMap_t gIdMapObject;
429 return &gIdMapObject;
431 static IdMap_t *gIdMap =
new IdMap_t;
436 DeclIdMap_t *TClass::GetDeclIdMap() {
438 #ifdef R__COMPLETE_MEM_TERMINATION
439 static DeclIdMap_t gDeclIdMapObject;
440 return &gDeclIdMapObject;
442 static DeclIdMap_t *gDeclIdMap =
new DeclIdMap_t;
450 void TClass::AddClass(TClass *cl)
454 R__LOCKGUARD(gInterpreterMutex);
455 gROOT->GetListOfClasses()->Add(cl);
456 if (cl->GetTypeInfo()) {
457 GetIdMap()->Add(cl->GetTypeInfo()->name(),cl);
459 if (cl->fClassInfo) {
460 GetDeclIdMap()->Add((
void*)(cl->fClassInfo), cl);
467 void TClass::AddClassToDeclIdMap(TDictionary::DeclId_t
id, TClass* cl)
469 if (!cl || !
id)
return;
470 GetDeclIdMap()->Add(
id, cl);
476 void TClass::RemoveClass(TClass *oldcl)
480 R__LOCKGUARD(gInterpreterMutex);
481 gROOT->GetListOfClasses()->Remove(oldcl);
482 if (oldcl->GetTypeInfo()) {
483 GetIdMap()->Remove(oldcl->GetTypeInfo()->name());
485 if (oldcl->fClassInfo) {
492 void TClass::RemoveClassDeclId(TDictionary::DeclId_t
id)
495 GetDeclIdMap()->Remove(
id);
502 void ROOT::Class_ShowMembers(TClass *cl,
const void *obj, TMemberInspector&insp)
504 gInterpreter->InspectMembers(insp, obj, cl, kFALSE);
510 class TDumpMembers :
public TMemberInspector {
513 TDumpMembers(
bool noAddr): fNoAddr(noAddr) { }
515 using TMemberInspector::Inspect;
516 void Inspect(TClass *cl,
const char *parent,
const char *name,
const void *addr, Bool_t isTransient);
530 void TDumpMembers::Inspect(TClass *cl,
const char *pname,
const char *mname,
const void *add, Bool_t )
532 const Int_t kvalue = 30;
534 const Int_t ktitle = 50;
536 const Int_t ktitle = 42;
538 const Int_t kline = 1024;
544 TDataType *membertype;
545 EDataType memberDataType = kNoType_t;
546 const char *memberName;
547 const char *memberFullTypeName;
548 const char *memberTitle;
552 if (TDataMember *member = cl->GetDataMember(mname)) {
553 if (member->GetDataType()) {
554 memberDataType = (EDataType)member->GetDataType()->GetType();
556 memberName = member->GetName();
557 memberFullTypeName = member->GetFullTypeName();
558 memberTitle = member->GetTitle();
559 isapointer = member->IsaPointer();
560 isbasic = member->IsBasic();
561 membertype = member->GetDataType();
562 }
else if (!cl->IsLoaded()) {
565 TVirtualStreamerInfo *info = cl->GetStreamerInfo();
567 const char *cursor = mname;
568 while ( (*cursor)==
'*' ) ++cursor;
569 TString elname( cursor );
570 Ssiz_t pos = elname.Index(
"[");
571 if ( pos != kNPOS ) {
572 elname.Remove( pos );
574 TStreamerElement *element = (TStreamerElement*)info->GetElements()->FindObject(elname.Data());
575 if (!element)
return;
576 memberFullTypeName = element->GetTypeName();
578 memberDataType = (EDataType)element->GetType();
580 memberName = element->GetName();
581 memberTitle = element->GetTitle();
582 isapointer = element->IsaPointer() || element->GetType() == TVirtualStreamerInfo::kCharStar;
583 membertype = gROOT->GetType(memberFullTypeName);
585 isbasic = membertype !=0;
591 Bool_t isdate = kFALSE;
592 if (strcmp(memberName,
"fDatime") == 0 && memberDataType == kUInt_t) {
595 Bool_t isbits = kFALSE;
596 if (strcmp(memberName,
"fBits") == 0 && memberDataType == kUInt_t) {
599 TClass * dataClass = TClass::GetClass(memberFullTypeName);
600 Bool_t isTString = (dataClass == TString::Class());
601 static TClassRef stdClass(
"std::string");
602 Bool_t isStdString = (dataClass == stdClass);
605 for (i = 0;i < kline; i++) line[i] =
' ';
607 snprintf(line,kline,
"%s%s ",pname,mname);
608 i = strlen(line); line[i] =
' ';
611 char *pointer = (
char*)add;
612 char **ppointer = (
char**)(pointer);
615 char **p3pointer = (
char**)(*ppointer);
617 snprintf(&line[kvalue],kline-kvalue,
"->0");
620 snprintf(&line[kvalue],kline-kvalue,
"->%lx ", (Long_t)p3pointer);
622 }
else if (membertype) {
623 if (!strcmp(membertype->GetTypeName(),
"char")) {
624 i = strlen(*ppointer);
625 if (kvalue+i > kline) i=kline-1-kvalue;
626 Bool_t isPrintable = kTRUE;
627 for (Int_t j = 0; j < i; j++) {
628 if (!std::isprint((*ppointer)[j])) {
629 isPrintable = kFALSE;
634 strncpy(line + kvalue, *ppointer, i);
640 strncpy(&line[kvalue], membertype->AsString(p3pointer), TMath::Min(kline-1-kvalue,(
int)strlen(membertype->AsString(p3pointer))));
642 }
else if (!strcmp(memberFullTypeName,
"char*") ||
643 !strcmp(memberFullTypeName,
"const char*")) {
644 i = strlen(*ppointer);
645 if (kvalue+i >= kline) i=kline-1-kvalue;
646 Bool_t isPrintable = kTRUE;
647 for (Int_t j = 0; j < i; j++) {
648 if (!std::isprint((*ppointer)[j])) {
649 isPrintable = kFALSE;
654 strncpy(line + kvalue, *ppointer, std::min( i, kline - kvalue));
661 snprintf(&line[kvalue],kline-kvalue,
"->%lx ", (Long_t)p3pointer);
664 }
else if (membertype) {
666 cdatime = (UInt_t*)pointer;
667 TDatime::GetDateTime(cdatime[0],cdate,ctime);
668 snprintf(&line[kvalue],kline-kvalue,
"%d/%d",cdate,ctime);
670 snprintf(&line[kvalue],kline-kvalue,
"0x%08x", *(UInt_t*)pointer);
672 strncpy(&line[kvalue], membertype->AsString(pointer), TMath::Min(kline-1-kvalue,(
int)strlen(membertype->AsString(pointer))));
676 std::string *str = (std::string*)pointer;
677 snprintf(&line[kvalue],kline-kvalue,
"%s",str->c_str());
678 }
else if (isTString) {
679 TString *str = (TString*)pointer;
680 snprintf(&line[kvalue],kline-kvalue,
"%s",str->Data());
683 snprintf(&line[kvalue],kline-kvalue,
"->%lx ", (Long_t)pointer);
688 if (isdate == kFALSE && strcmp(memberFullTypeName,
"char*") && strcmp(memberFullTypeName,
"const char*")) {
689 i = strlen(&line[0]); line[i] =
' ';
690 assert(250 > ktitle);
691 strlcpy(&line[ktitle],memberTitle,250-ktitle+1);
696 THashTable* TClass::fgClassTypedefHash = 0;
702 TClass::TNameMapNode::TNameMapNode (
const char* typedf,
const char* orig)
703 : TObjString (typedf),
710 class TBuildRealData :
public TMemberInspector {
713 void *fRealDataObject;
714 TClass *fRealDataClass;
717 TBuildRealData(
void *obj, TClass *cl) {
719 fRealDataObject = obj;
722 using TMemberInspector::Inspect;
723 void Inspect(TClass *cl,
const char *parent,
const char *name,
const void *addr, Bool_t isTransient);
730 void TBuildRealData::Inspect(TClass* cl,
const char* pname,
const char* mname,
const void* add, Bool_t isTransient)
732 TDataMember* dm = cl->GetDataMember(mname);
737 Bool_t isTransientMember = kFALSE;
739 if (!dm->IsPersistent()) {
742 isTransientMember = kTRUE;
746 TString rname( pname );
749 if (cl != fRealDataClass) {
750 if (!fRealDataClass->InheritsFrom(cl)) {
751 Ssiz_t dot = rname.Index(
'.');
756 if (!fRealDataClass->GetDataMember(rname)) {
771 if (!fRealDataClass->GetBaseDataMember(rname)) {
779 Long_t offset = Long_t(((Long_t) add) - ((Long_t) fRealDataObject));
781 if (TClassEdit::IsStdArray(dm->GetTypeName())){
783 TRealData::GetName(rdName,dm);
785 TRealData* rd =
new TRealData(rname.Data(), offset, dm);
786 fRealDataClass->GetListOfRealData()->Add(rd);
792 if (dm->IsaPointer()) {
794 TRealData* rd =
new TRealData(rname, offset, dm);
795 if (isTransientMember) { rd->SetBit(TRealData::kTransient); };
796 fRealDataClass->GetListOfRealData()->Add(rd);
799 TRealData* rd =
new TRealData(rname, offset, dm);
800 if (isTransientMember) { rd->SetBit(TRealData::kTransient); };
801 if (!dm->IsBasic()) {
802 rd->SetIsObject(kTRUE);
809 TClass* dmclass = TClass::GetClass(dm->GetTypeName(), kTRUE, isTransient);
811 dmclass = TClass::GetClass(dm->GetTrueTypeName(), kTRUE, isTransient);
814 if ((dmclass != cl) && !dm->IsaPointer()) {
815 if (dmclass->GetCollectionProxy()) {
816 TClass* valcl = dmclass->GetCollectionProxy()->GetValueClass();
827 Bool_t wantBuild = kTRUE;
828 if (valcl->Property() & kIsAbstract) wantBuild = kFALSE;
830 && (dmclass->GetCollectionProxy()->GetProperties() & TVirtualCollectionProxy::kIsEmulated)
831 && (!valcl->IsLoaded()) ) {
838 if (wantBuild) valcl->BuildRealData(0, isTransient);
841 void* addrForRecursion = 0;
842 if (GetObjectValidity() == kValidObjectGiven)
843 addrForRecursion =
const_cast<void*
>(add);
845 dmclass->BuildRealData(addrForRecursion, isTransient);
850 fRealDataClass->GetListOfRealData()->Add(rd);
860 class TAutoInspector :
public TMemberInspector {
865 TAutoInspector(TBrowser *b) {
867 fBrowser = b; fCount = 0; }
868 virtual ~TAutoInspector() { }
869 using TMemberInspector::Inspect;
870 virtual void Inspect(TClass *cl,
const char *parent,
const char *name,
const void *addr, Bool_t isTransient);
871 virtual Bool_t IsTreatingNonAccessibleTypes() {
return kFALSE;}
877 void TAutoInspector::Inspect(TClass *cl,
const char *tit,
const char *name,
878 const void *addr, Bool_t )
880 if(tit && strchr(tit,
'.')) return ;
881 if (fCount && !fBrowser)
return;
887 if (*name ==
'*') name++;
888 int ln = strcspn(name,
"[ ");
889 TString iname(name,ln);
891 ClassInfo_t *classInfo = cl->GetClassInfo();
892 if (!classInfo)
return;
895 DataMemberInfo_t *m = gCling->DataMemberInfo_Factory(classInfo);
899 while (gCling->DataMemberInfo_Next(m)) {
900 mname = gCling->DataMemberInfo_Name(m);
901 mname.ReplaceAll(
"*",
"");
902 if ((found = (iname==mname)))
break;
910 Long_t prop = gCling->DataMemberInfo_Property(m) | gCling->DataMemberInfo_TypeProperty(m);
911 if (prop & kIsStatic)
return;
912 if (prop & kIsFundamental)
return;
913 if (prop & kIsEnum)
return;
914 if (mname ==
"G__virtualinfo")
return;
916 int size =
sizeof(
void*);
919 if (prop & kIsArray) {
920 for (
int dim = 0; dim < gCling->DataMemberInfo_ArrayDim(m); dim++) nmax *= gCling->DataMemberInfo_MaxIndex(m,dim);
923 std::string clmName(TClassEdit::ShortType(gCling->DataMemberInfo_TypeName(m),
924 TClassEdit::kDropTrailStar) );
925 TClass * clm = TClass::GetClass(clmName.c_str());
927 if (!(prop & kIsPointer)) {
929 if (size==0) size = gCling->DataMemberInfo_TypeSize(m);
933 gCling->DataMemberInfo_Delete(m);
934 TVirtualCollectionProxy *proxy = clm->GetCollectionProxy();
936 for(
int i=0; i<nmax; i++) {
938 char *ptr = (
char*)addr + i*size;
940 void *obj = (prop & kIsPointer) ? *((
void**)ptr) : (TObject*)ptr;
945 if (!fBrowser)
return;
948 TClass *actualClass = clm->GetActualClass(obj);
949 if (clm->IsTObject()) {
950 TObject *tobj = (TObject*)clm->DynamicCast(TObject::Class(),obj);
951 bwname = tobj->GetName();
953 bwname = actualClass->GetName();
958 if (!clm->IsTObject() ||
959 bwname.Length()==0 ||
960 strcmp(bwname.Data(),actualClass->GetName())==0) {
962 int l = strcspn(bwname.Data(),
"[ ");
963 if (l<bwname.Length() && bwname[l]==
'[') {
964 char cbuf[13]; snprintf(cbuf,13,
"[%02d]",i);
965 ts.Replace(0,999,bwname,l);
967 bwname = (
const char*)ts;
973 fBrowser->Add(obj,clm,bwname);
976 TClass *valueCl = proxy->GetValueClass();
980 fBrowser->Add( obj, clm, bwname );
983 TVirtualCollectionProxy::TPushPop env(proxy, obj);
984 TClass *actualCl = 0;
986 int sz = proxy->Size();
988 char fmt[] = {
"#%09d"};
989 fmt[3] =
'0'+(int)log10(
double(sz))+1;
991 for (
int ii=0;ii<sz;ii++) {
992 void *p = proxy->At(ii);
994 if (proxy->HasPointers()) {
997 actualCl = valueCl->GetActualClass(p);
998 p = actualCl->DynamicCast(valueCl,p,0);
1001 snprintf(buf,20,fmt,ii);
1004 fBrowser->Add( p, actualCl, ts );
1022 fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
1023 fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1024 fAllPubMethod(0), fClassMenuList(0),
1025 fDeclFileName(
""), fImplFileName(
""), fDeclFileLine(0), fImplFileLine(0),
1026 fInstanceCount(0), fOnHeap(0),
1027 fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
1028 fTypeInfo(0), fShowMembers(0),
1029 fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1030 fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1031 fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fConvStreamerFunc(0), fSizeof(-1),
1032 fCanSplit(-1), fProperty(0), fClassProperty(0), fHasRootPcmInfo(kFALSE), fCanLoadClassInfo(kFALSE),
1033 fIsOffsetStreamerSet(kFALSE), fVersionUsed(kFALSE), fRuntimeProperties(0), fOffsetStreamer(0), fStreamerType(TClass::kDefault),
1035 fCurrentInfo(0), fLastReadInfo(0), fRefProxy(0),
1036 fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
1041 R__LOCKGUARD(gInterpreterMutex);
1043 TMmallocDescTemp setreset;
1044 fStreamerInfo =
new TObjArray(1, -2);
1057 TClass::TClass(
const char *name, Bool_t silent) :
1060 fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
1061 fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1062 fAllPubMethod(0), fClassMenuList(0),
1063 fDeclFileName(
""), fImplFileName(
""), fDeclFileLine(0), fImplFileLine(0),
1064 fInstanceCount(0), fOnHeap(0),
1065 fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
1066 fTypeInfo(0), fShowMembers(0),
1067 fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1068 fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1069 fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fConvStreamerFunc(0), fSizeof(-1),
1070 fCanSplit(-1), fProperty(0), fClassProperty(0), fHasRootPcmInfo(kFALSE), fCanLoadClassInfo(kFALSE),
1071 fIsOffsetStreamerSet(kFALSE), fVersionUsed(kFALSE), fRuntimeProperties(0), fOffsetStreamer(0), fStreamerType(TClass::kDefault),
1073 fCurrentInfo(0), fLastReadInfo(0), fRefProxy(0),
1074 fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
1076 R__LOCKGUARD(gInterpreterMutex);
1079 ::Fatal(
"TClass::TClass",
"ROOT system not initialized");
1082 TMmallocDescTemp setreset;
1083 fStreamerInfo =
new TObjArray(1, -2);
1089 ::Fatal(
"TClass::TClass",
"gInterpreter not initialized");
1091 gInterpreter->SetClassInfo(
this);
1092 if (!silent && !fClassInfo && fName.First(
'@')==kNPOS)
1093 ::Warning(
"TClass::TClass",
"no dictionary for class %s is available", name);
1096 if (fClassInfo) SetTitle(gCling->ClassInfo_Title(fClassInfo));
1097 fConversionStreamerInfo = 0;
1104 TClass::TClass(
const char *name, Version_t cversion, Bool_t silent) :
1107 fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
1108 fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1109 fAllPubMethod(0), fClassMenuList(0),
1110 fDeclFileName(
""), fImplFileName(
""), fDeclFileLine(0), fImplFileLine(0),
1111 fInstanceCount(0), fOnHeap(0),
1112 fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
1113 fTypeInfo(0), fShowMembers(0),
1114 fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1115 fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1116 fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fConvStreamerFunc(0), fSizeof(-1),
1117 fCanSplit(-1), fProperty(0), fClassProperty(0), fHasRootPcmInfo(kFALSE), fCanLoadClassInfo(kFALSE),
1118 fIsOffsetStreamerSet(kFALSE), fVersionUsed(kFALSE), fRuntimeProperties(0), fOffsetStreamer(0), fStreamerType(TClass::kDefault),
1120 fCurrentInfo(0), fLastReadInfo(0), fRefProxy(0),
1121 fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
1123 R__LOCKGUARD(gInterpreterMutex);
1124 Init(name, cversion, 0, 0, 0, 0, -1, -1, 0, silent);
1131 TClass::TClass(
const char *name, Version_t cversion, EState theState, Bool_t silent) :
1134 fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
1135 fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1136 fAllPubMethod(0), fClassMenuList(0),
1137 fDeclFileName(
""), fImplFileName(
""), fDeclFileLine(0), fImplFileLine(0),
1138 fInstanceCount(0), fOnHeap(0),
1139 fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
1140 fTypeInfo(0), fShowMembers(0),
1141 fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1142 fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1143 fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fConvStreamerFunc(0), fSizeof(-1),
1144 fCanSplit(-1), fProperty(0), fClassProperty(0), fHasRootPcmInfo(kFALSE), fCanLoadClassInfo(kFALSE),
1145 fIsOffsetStreamerSet(kFALSE), fVersionUsed(kFALSE), fRuntimeProperties(0), fOffsetStreamer(0), fStreamerType(TClass::kDefault),
1147 fCurrentInfo(0), fLastReadInfo(0), fRefProxy(0),
1148 fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
1150 R__LOCKGUARD(gInterpreterMutex);
1153 if (theState == kNamespaceForMeta){
1154 fProperty = kIsNamespace;
1155 theState = kForwardDeclared;
1158 if (theState != kForwardDeclared && theState != kEmulated)
1159 ::Fatal(
"TClass::TClass",
1160 "A TClass entry cannot be initialized in a state different from kForwardDeclared or kEmulated.");
1161 Init(name, cversion, 0, 0, 0, 0, -1, -1, 0, silent);
1174 TClass::TClass(ClassInfo_t *classInfo, Version_t cversion,
1175 const char *dfil,
const char *ifil, Int_t dl, Int_t il, Bool_t silent) :
1178 fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
1179 fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1180 fAllPubMethod(0), fClassMenuList(0),
1181 fDeclFileName(
""), fImplFileName(
""), fDeclFileLine(0), fImplFileLine(0),
1182 fInstanceCount(0), fOnHeap(0),
1183 fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
1184 fTypeInfo(0), fShowMembers(0),
1185 fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1186 fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1187 fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fConvStreamerFunc(0), fSizeof(-1),
1188 fCanSplit(-1), fProperty(0), fClassProperty(0), fHasRootPcmInfo(kFALSE), fCanLoadClassInfo(kFALSE),
1189 fIsOffsetStreamerSet(kFALSE), fVersionUsed(kFALSE), fRuntimeProperties(0), fOffsetStreamer(0), fStreamerType(TClass::kDefault),
1191 fCurrentInfo(0), fLastReadInfo(0), fRefProxy(0),
1192 fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
1194 R__LOCKGUARD(gInterpreterMutex);
1197 ::Fatal(
"TClass::TClass",
"ROOT system not initialized");
1203 ::Fatal(
"TClass::TClass",
"gInterpreter not initialized");
1205 if (!classInfo || !gInterpreter->ClassInfo_IsValid(classInfo)) {
1209 fName = gInterpreter->ClassInfo_FullName(classInfo);
1211 R__LOCKGUARD(gInterpreterMutex);
1212 Init(fName, cversion, 0, 0, dfil, ifil, dl, il, classInfo, silent);
1216 fConversionStreamerInfo = 0;
1224 TClass::TClass(
const char *name, Version_t cversion,
1225 const char *dfil,
const char *ifil, Int_t dl, Int_t il, Bool_t silent) :
1228 fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
1229 fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1230 fAllPubMethod(0), fClassMenuList(0),
1231 fDeclFileName(
""), fImplFileName(
""), fDeclFileLine(0), fImplFileLine(0),
1232 fInstanceCount(0), fOnHeap(0),
1233 fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
1234 fTypeInfo(0), fShowMembers(0),
1235 fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1236 fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1237 fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fConvStreamerFunc(0), fSizeof(-1),
1238 fCanSplit(-1), fProperty(0), fClassProperty(0), fHasRootPcmInfo(kFALSE), fCanLoadClassInfo(kFALSE),
1239 fIsOffsetStreamerSet(kFALSE), fVersionUsed(kFALSE), fRuntimeProperties(0), fOffsetStreamer(0), fStreamerType(TClass::kDefault),
1241 fCurrentInfo(0), fLastReadInfo(0), fRefProxy(0),
1242 fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
1244 R__LOCKGUARD(gInterpreterMutex);
1245 Init(name,cversion, 0, 0, dfil, ifil, dl, il, 0, silent);
1252 TClass::TClass(
const char *name, Version_t cversion,
1253 const std::type_info &info, TVirtualIsAProxy *isa,
1254 const char *dfil,
const char *ifil, Int_t dl, Int_t il,
1258 fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
1259 fBase(0), fData(0), fEnums(0), fFuncTemplate(0), fMethod(0), fAllPubData(0),
1262 fDeclFileName(
""), fImplFileName(
""), fDeclFileLine(0), fImplFileLine(0),
1263 fInstanceCount(0), fOnHeap(0),
1264 fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
1265 fTypeInfo(0), fShowMembers(0),
1266 fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
1267 fMerge(0), fResetAfterMerge(0), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
1268 fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fConvStreamerFunc(0), fSizeof(-1),
1269 fCanSplit(-1), fProperty(0), fClassProperty(0), fHasRootPcmInfo(kFALSE), fCanLoadClassInfo(kFALSE),
1270 fIsOffsetStreamerSet(kFALSE), fVersionUsed(kFALSE), fRuntimeProperties(0), fOffsetStreamer(0), fStreamerType(TClass::kDefault),
1271 fState(kHasTClassInit),
1272 fCurrentInfo(0), fLastReadInfo(0), fRefProxy(0),
1273 fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
1275 R__LOCKGUARD(gInterpreterMutex);
1277 Init(name, cversion, &info, isa, dfil, ifil, dl, il, 0, silent);
1284 void TClass::ForceReload (TClass* oldcl)
1286 TClass::RemoveClass(oldcl);
1288 if (oldcl->CanIgnoreTObjectStreamer()) {
1289 IgnoreTObjectStreamer();
1292 TVirtualStreamerInfo *info;
1293 TIter next(oldcl->GetStreamerInfos());
1294 while ((info = (TVirtualStreamerInfo*)next())) {
1295 info->Clear(
"build");
1296 info->SetClass(
this);
1297 fStreamerInfo->AddAtAndExpand(info,info->GetClassVersion());
1299 oldcl->fStreamerInfo->Clear();
1301 oldcl->ReplaceWith(
this);
1309 void TClass::Init(
const char *name, Version_t cversion,
1310 const std::type_info *typeinfo, TVirtualIsAProxy *isa,
1311 const char *dfil,
const char *ifil, Int_t dl, Int_t il,
1312 ClassInfo_t *givenInfo,
1316 ::Fatal(
"TClass::TClass",
"ROOT system not initialized");
1317 if (!name || !name[0]) {
1318 ::Error(
"TClass::Init",
"The name parameter is invalid (null or empty)");
1323 fName = TClassEdit::ShortType(name, TClassEdit::kDropStlDefault).c_str();
1324 fClassVersion = cversion;
1325 fDeclFileName = dfil ? dfil :
"";
1326 fImplFileName = ifil ? ifil :
"";
1329 fTypeInfo = typeinfo;
1331 if ( fIsA ) fIsA->SetClass(
this);
1333 fStreamerInfo =
new TObjArray(fClassVersion+2+10,-1);
1337 ResetInstanceCount();
1339 TClass *oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(fName.Data());
1341 InsertTClassInRegistryRAII insertRAII(fState,fName,fNoInfoOrEmuOrFwdDeclNameRegistry);
1343 if (oldcl && oldcl->TestBit(kLoading)) {
1352 TClass **persistentRef = 0;
1355 persistentRef = oldcl->fPersistentRef.exchange(0);
1358 TClass::RemoveClass(oldcl);
1362 if (oldcl->CanIgnoreTObjectStreamer()) {
1363 IgnoreTObjectStreamer();
1365 TVirtualStreamerInfo *info;
1367 TIter next(oldcl->GetStreamerInfos());
1368 while ((info = (TVirtualStreamerInfo*)next())) {
1370 info->Clear(
"build");
1371 info->SetClass(
this);
1372 fStreamerInfo->AddAtAndExpand(info,info->GetClassVersion());
1374 oldcl->fStreamerInfo->Clear();
1378 fSchemaRules = oldcl->fSchemaRules;
1379 oldcl->fSchemaRules = 0;
1382 fFuncTemplate = oldcl->fFuncTemplate;
1384 fFuncTemplate->fClass =
this;
1385 oldcl->fFuncTemplate =
nullptr;
1386 fMethod.store( oldcl->fMethod );
1388 (*fMethod).fClass =
this;
1389 oldcl->fMethod =
nullptr;
1395 TClass::AddClass(
this);
1397 Bool_t isStl = TClassEdit::IsSTLCont(fName);
1400 ::Fatal(
"TClass::Init",
"gInterpreter not initialized");
1403 bool invalid = !gInterpreter->ClassInfo_IsValid(givenInfo);
1404 bool notloaded = !gInterpreter->ClassInfo_IsLoaded(givenInfo);
1405 auto property = gInterpreter->ClassInfo_Property(givenInfo);
1407 if (invalid || (notloaded && (property & kIsNamespace)) ||
1408 !(property & (kIsClass | kIsStruct | kIsNamespace))) {
1409 if (!TClassEdit::IsSTLCont(fName.Data())) {
1412 TClass::RemoveClass(
this);
1418 fClassInfo = gInterpreter->ClassInfo_Factory(givenInfo);
1419 fCanLoadClassInfo =
false;
1420 if (fState <= kEmulated)
1421 fState = kInterpreted;
1428 if (fState!=kForwardDeclared && !fClassInfo) {
1430 if (fState == kHasTClassInit) {
1443 fCanLoadClassInfo = kTRUE;
1445 TProtoClass *proto = TClassTable::GetProtoNorm(GetName());
1446 if (proto && proto->FillTClass(
this)) {
1447 fHasRootPcmInfo = kTRUE;
1450 if (!fHasRootPcmInfo && gInterpreter->CheckClassInfo(fName, kTRUE)) {
1451 gInterpreter->SetClassInfo(
this);
1459 TClass::RemoveClass(
this);
1466 if (!silent && (!fClassInfo && !fCanLoadClassInfo) && !isStl && fName.First(
'@')==kNPOS &&
1467 !TClassEdit::IsInterpreterDetail(fName.Data()) ) {
1468 if (fState == kHasTClassInit) {
1469 if (fImplFileLine == -1 && fClassVersion == 0) {
1474 ::Error(
"TClass::Init",
"no interpreter information for class %s is available even though it has a TClass "
1475 "initialization routine.",
1481 ::Warning(
"TClass::Init",
"no dictionary for class %s is available", fName.Data());
1486 SetUniqueID(fgClassCount);
1492 TString resolvedThis;
1493 if (!givenInfo && strchr (name,
'<')) {
1494 if ( fName != name) {
1495 if (!fgClassTypedefHash) {
1496 fgClassTypedefHash =
new THashTable (100, 5);
1497 fgClassTypedefHash->SetOwner (kTRUE);
1500 fgClassTypedefHash->Add (
new TNameMapNode (name, fName));
1501 SetBit (kHasNameMapNode);
1504 resolvedThis = TClassEdit::ResolveTypedef (name, kTRUE);
1505 if (resolvedThis != name) {
1506 if (!fgClassTypedefHash) {
1507 fgClassTypedefHash =
new THashTable (100, 5);
1508 fgClassTypedefHash->SetOwner (kTRUE);
1511 fgClassTypedefHash->Add (
new TNameMapNode (resolvedThis, fName));
1512 SetBit (kHasNameMapNode);
1522 oldcl->ReplaceWith(
this);
1525 }
else if (!givenInfo && resolvedThis.Length() > 0 && fgClassTypedefHash) {
1529 if (resolvedThis != fName) {
1530 oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(resolvedThis);
1531 if (oldcl && oldcl !=
this) {
1532 persistentRef = oldcl->fPersistentRef.exchange(0);
1533 ForceReload (oldcl);
1536 TIter next( fgClassTypedefHash->GetListForObject(resolvedThis) );
1537 while ( TNameMapNode* htmp = static_cast<TNameMapNode*> (next()) ) {
1538 if (resolvedThis != htmp->String())
continue;
1539 oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(htmp->fOrigName);
1540 if (oldcl && oldcl !=
this) {
1541 persistentRef = oldcl->fPersistentRef.exchange(0);
1542 ForceReload (oldcl);
1547 SetTitle(gCling->ClassInfo_Title(fClassInfo));
1548 if ( fDeclFileName == 0 || fDeclFileName[0] ==
'\0' ) {
1549 fDeclFileName = kUndeterminedClassInfoName;
1558 if (persistentRef) {
1559 fPersistentRef = persistentRef;
1561 fPersistentRef =
new TClass*;
1563 *fPersistentRef =
this;
1565 if ( isStl || !strncmp(GetName(),
"stdext::hash_",13) || !strncmp(GetName(),
"__gnu_cxx::hash_",16) ) {
1566 if (fState != kHasTClassInit) {
1569 fCollectionProxy = TVirtualStreamerInfo::Factory()->GenEmulatedProxy( GetName(), silent );
1570 if (fCollectionProxy) {
1571 fSizeof = fCollectionProxy->Sizeof();
1574 GetSchemaRules(kTRUE);
1576 }
else if (!silent) {
1577 Warning(
"Init",
"Collection proxy for %s was not properly initialized!",GetName());
1580 fStreamer = TVirtualStreamerInfo::Factory()->GenEmulatedClassStreamer( GetName(), silent );
1583 }
else if (!strncmp(GetName(),
"std::pair<",10) || !strncmp(GetName(),
"pair<",5) ) {
1585 GetSchemaRules(kTRUE);
1596 R__LOCKGUARD(gInterpreterMutex);
1599 if (fgClassTypedefHash && TestBit (kHasNameMapNode)) {
1600 TString resolvedThis = TClassEdit::ResolveTypedef (GetName(), kTRUE);
1601 TIter next (fgClassTypedefHash->GetListForObject (resolvedThis));
1602 while ( TNameMapNode* htmp = static_cast<TNameMapNode*> (next()) ) {
1603 if (resolvedThis == htmp->String() && htmp->fOrigName == GetName()) {
1604 fgClassTypedefHash->Remove (htmp);
1614 delete fStreamer; fStreamer =0;
1615 delete fAllPubData; fAllPubData =0;
1616 delete fAllPubMethod; fAllPubMethod=0;
1618 delete fPersistentRef.load();
1622 delete fBase.load(); fBase = 0;
1626 delete fData; fData = 0;
1630 delete fEnums.load(); fEnums = 0;
1633 fFuncTemplate->Delete();
1634 delete fFuncTemplate; fFuncTemplate = 0;
1637 (*fMethod).Delete();
1638 delete fMethod.load(); fMethod=0;
1641 fRealData->Delete();
1642 delete fRealData; fRealData=0;
1645 fStreamerInfo->Delete();
1646 delete fStreamerInfo; fStreamerInfo =
nullptr;
1648 if (fDeclFileLine >= -1)
1649 TClass::RemoveClass(
this);
1651 gCling->ClassInfo_Delete(fClassInfo);
1655 fClassMenuList->Delete();
1656 delete fClassMenuList; fClassMenuList=0;
1658 fIsOffsetStreamerSet=kFALSE;
1660 if ( fIsA )
delete fIsA;
1662 if ( fRefProxy ) fRefProxy->Release();
1666 delete fCollectionProxy;
1667 delete fIsAMethod.load();
1668 delete fSchemaRules;
1669 if (fConversionStreamerInfo.load()) {
1670 std::map<std::string, TObjArray*>::iterator it;
1671 std::map<std::string, TObjArray*>::iterator end = (*fConversionStreamerInfo).end();
1672 for( it = (*fConversionStreamerInfo).begin(); it != end; ++it ) {
1675 delete fConversionStreamerInfo.load();
1682 Int_t ReadRulesContent(FILE *f)
1694 while ((c = fgetc(f)) != EOF) {
1700 if (rule.Length() > 0) {
1701 if (TClass::AddRule(rule)) {
1750 Int_t TClass::ReadRules()
1752 static const char *suffix =
"class.rules";
1753 TString sname = suffix;
1754 gSystem->PrependPathName(TROOT::GetEtcDir(), sname);
1758 FILE * f = fopen(sname,
"r");
1760 res = ReadRulesContent(f);
1763 ::Error(
"TClass::ReadRules()",
"Cannot find rules file %s", sname.Data());
1774 Int_t TClass::ReadRules(
const char *filename )
1776 if (!filename || !filename[0]) {
1777 ::Error(
"TClass::ReadRules",
"no file name specified");
1781 FILE * f = fopen(filename,
"r");
1783 ::Error(
"TClass::ReadRules",
"Failed to open %s\n",filename);
1786 Int_t count = ReadRulesContent(f);
1820 Bool_t TClass::AddRule(
const char *rule )
1822 ROOT::TSchemaRule *ruleobj =
new ROOT::TSchemaRule();
1823 if (! ruleobj->SetFromRule( rule ) ) {
1828 R__LOCKGUARD(gInterpreterMutex);
1830 TClass *cl = TClass::GetClass( ruleobj->GetTargetClass() );
1833 cl = gInterpreter->GenerateTClass(ruleobj->GetTargetClass(), kTRUE, kTRUE);
1835 ROOT::Detail::TSchemaRuleSet* rset = cl->GetSchemaRules( kTRUE );
1838 if( !rset->AddRule( ruleobj, ROOT::Detail::TSchemaRuleSet::kCheckConflict, &errmsg ) ) {
1839 ::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).",
1840 ruleobj->GetTargetClass(), ruleobj->GetVersion(), ruleobj->GetTargetString(), errmsg.Data() );
1850 void TClass::AdoptSchemaRules( ROOT::Detail::TSchemaRuleSet *rules )
1852 R__LOCKGUARD(gInterpreterMutex);
1854 delete fSchemaRules;
1855 fSchemaRules = rules;
1856 fSchemaRules->SetClass(
this );
1862 const ROOT::Detail::TSchemaRuleSet* TClass::GetSchemaRules()
const
1864 return fSchemaRules;
1871 ROOT::Detail::TSchemaRuleSet* TClass::GetSchemaRules(Bool_t create)
1873 if (create && fSchemaRules == 0) {
1874 fSchemaRules =
new ROOT::Detail::TSchemaRuleSet();
1875 fSchemaRules->SetClass(
this );
1877 return fSchemaRules;
1882 void TClass::AddImplFile(
const char* filename,
int line) {
1887 fImplFileName = filename;
1888 fImplFileLine = line;
1896 Int_t TClass::AutoBrowse(TObject *obj, TBrowser *b)
1900 TAutoInspector insp(b);
1901 obj->ShowMembers(insp);
1908 Int_t TClass::Browse(
void *obj, TBrowser *b)
const
1912 TClass *actual = GetActualClass(obj);
1916 if (!fIsOffsetStreamerSet) {
1917 CalculateStreamerOffset();
1919 TObject* realTObject = (TObject*)((
size_t)obj + fOffsetStreamer);
1920 realTObject->Browse(b);
1922 }
else if (actual !=
this) {
1923 return actual->Browse(obj, b);
1924 }
else if (GetCollectionProxy()) {
1929 TAutoInspector insp(b);
1930 CallShowMembers(obj,insp,kFALSE);
1940 void TClass::Browse(TBrowser *b)
1942 if (!HasInterpreterInfo())
return;
1945 if (!fRealData) BuildRealData();
1947 b->Add(GetListOfDataMembers(),
"Data Members");
1948 b->Add(GetListOfRealData(),
"Real Data Members");
1949 b->Add(GetListOfMethods(),
"Methods");
1950 b->Add(GetListOfBases(),
"Base Classes");
1961 void TClass::BuildRealData(
void* pointer, Bool_t isTransient)
1964 R__LOCKGUARD(gInterpreterMutex);
1971 if (fClassVersion == 0) {
1972 isTransient = kTRUE;
1977 TMmallocDescTemp setreset;
1980 if (!HasInterpreterInfo() || TClassEdit::IsSTLCont(GetName(), 0) || TClassEdit::IsSTLBitset(GetName())) {
1982 fRealData =
new TList;
1983 BuildEmulatedRealData(
"", 0,
this);
1988 static TClassRef clRefString(
"std::string");
1989 if (clRefString ==
this) {
1996 if (!isTransient && GetState() != kHasTClassInit
1997 && TClassEdit::IsStdClass(GetName())
1998 && strncmp(GetName(),
"pair<", 5) != 0) {
1999 Error(
"BuildRealData",
"Inspection for %s not supported!", GetName());
2004 fRealData =
new TList;
2005 TBuildRealData brd(pointer,
this);
2010 if ( ! CallShowMembers(pointer, brd, isTransient) ) {
2011 if ( isTransient ) {
2019 Error(
"BuildRealData",
"Cannot find any ShowMembers function for %s!", GetName());
2026 TBaseClass* base = 0;
2027 TIter next(GetListOfBases());
2028 while ((base = (TBaseClass*) next())) {
2029 if (base->IsSTLContainer()) {
2032 TClass* c = base->GetClassPointer();
2034 c->BuildRealData(0, isTransient);
2042 void TClass::BuildEmulatedRealData(
const char *name, Long_t offset, TClass *cl)
2044 R__LOCKGUARD(gInterpreterMutex);
2046 TVirtualStreamerInfo *info;
2047 if (Property() & kIsAbstract) {
2048 info = GetStreamerInfoAbstractEmulated();
2050 info = GetStreamerInfo();
2054 Error(
"BuildEmulatedRealData",
"Missing StreamerInfo for %s",GetName());
2059 TIter next(info->GetElements());
2060 TStreamerElement *element;
2061 while ((element = (TStreamerElement*)next())) {
2062 Int_t etype = element->GetType();
2063 Long_t eoffset = element->GetOffset();
2064 TClass *cle = element->GetClassPointer();
2065 if (element->IsBase() || etype == TVirtualStreamerInfo::kBase) {
2068 }
else if (etype == TVirtualStreamerInfo::kTObject ||
2069 etype == TVirtualStreamerInfo::kTNamed ||
2070 etype == TVirtualStreamerInfo::kObject ||
2071 etype == TVirtualStreamerInfo::kAny) {
2073 TString rdname; rdname.Form(
"%s%s",name,element->GetFullName());
2074 TRealData *rd =
new TRealData(rdname,offset+eoffset,0);
2075 if (gDebug > 0) printf(
" Class: %s, adding TRealData=%s, offset=%ld\n",cl->GetName(),rd->GetName(),rd->GetThisOffset());
2076 cl->GetListOfRealData()->Add(rd);
2078 rdname.Form(
"%s%s.",name,element->GetFullName());
2079 if (cle) cle->BuildEmulatedRealData(rdname,offset+eoffset,cl);
2082 TString rdname; rdname.Form(
"%s%s",name,element->GetFullName());
2083 TRealData *rd =
new TRealData(rdname,offset+eoffset,0);
2084 if (gDebug > 0) printf(
" Class: %s, adding TRealData=%s, offset=%ld\n",cl->GetName(),rd->GetName(),rd->GetThisOffset());
2085 cl->GetListOfRealData()->Add(rd);
2095 while ((element = (TStreamerElement*)next())) {
2096 Int_t etype = element->GetType();
2097 if (element->IsBase() || etype == TVirtualStreamerInfo::kBase) {
2099 Long_t eoffset = element->GetOffset();
2100 TClass *cle = element->GetClassPointer();
2101 if (cle) cle->BuildEmulatedRealData(name,offset+eoffset,cl);
2113 void TClass::CalculateStreamerOffset()
const
2115 R__LOCKGUARD(gInterpreterMutex);
2116 if (!fIsOffsetStreamerSet && HasInterpreterInfo()) {
2120 TMmallocDescTemp setreset;
2121 fOffsetStreamer =
const_cast<TClass*
>(
this)->GetBaseClassOffsetRecurse(TObject::Class());
2122 if (fStreamerType == kTObject) {
2123 fStreamerImpl = &TClass::StreamerTObjectInitialized;
2125 fIsOffsetStreamerSet = kTRUE;
2135 Bool_t TClass::CallShowMembers(
const void* obj, TMemberInspector &insp, Bool_t isTransient)
const
2140 fShowMembers(obj, insp, isTransient);
2144 if (fCanLoadClassInfo) LoadClassInfo();
2147 if (strcmp(GetName(),
"string") == 0) {
2155 gInterpreter->InspectMembers(insp, obj,
this, isTransient);
2158 }
else if (TVirtualStreamerInfo* sinfo = GetStreamerInfo()) {
2159 sinfo->CallShowMembers(obj, insp, isTransient);
2172 void TClass::InterpretedShowMembers(
void* obj, TMemberInspector &insp, Bool_t isTransient)
2174 return gInterpreter->InspectMembers(insp, obj,
this, isTransient);
2177 Bool_t TClass::CanSplitBaseAllow()
2179 if (fCanSplit >= 0) {
2180 return ! ( fCanSplit & 0x2 );
2183 R__LOCKGUARD(gInterpreterMutex);
2185 if (GetCollectionProxy() !=
nullptr) {
2190 if (
this == TRef::Class()) { fCanSplit = 2;
return kFALSE; }
2191 if (
this == TRefArray::Class()) { fCanSplit = 2;
return kFALSE; }
2192 if (
this == TArray::Class()) { fCanSplit = 2;
return kFALSE; }
2193 if (
this == TClonesArray::Class()) { fCanSplit = 1;
return kTRUE; }
2194 if (
this == TCollection::Class()) { fCanSplit = 2;
return kFALSE; }
2198 auto refTreeClass( TClass::GetClass(
"TTree",kTRUE,kTRUE) );
2199 if (
this == refTreeClass) { fCanSplit = 2;
return kFALSE; }
2201 if (!HasDataMemberInfo()) {
2202 TVirtualStreamerInfo *sinfo = ((TClass *)
this)->GetCurrentStreamerInfo();
2203 if (sinfo==0) sinfo = GetStreamerInfo();
2204 TIter next(sinfo->GetElements());
2205 TStreamerElement *element;
2206 while ((element = (TStreamerElement*)next())) {
2207 if (element->IsA() == TStreamerBase::Class()) {
2208 TClass *clbase = element->GetClassPointer();
2214 }
else if (!clbase->CanSplitBaseAllow()) {
2224 if (!HasDataMemberInfo())
return kTRUE;
2226 TObjLink *lnk = GetListOfBases() ? fBase.load()->FirstLink() : 0;
2231 TBaseClass *base = (TBaseClass*) lnk->GetObject();
2232 c = base->GetClassPointer();
2238 }
else if (!c->CanSplitBaseAllow()) {
2250 Bool_t TClass::CanSplit()
const
2255 if (fCanSplit >= 0) {
2257 return (fCanSplit & 0x1) == 1;
2260 R__LOCKGUARD(gInterpreterMutex);
2261 TClass *This =
const_cast<TClass*
>(
this);
2263 if (
this == TObject::Class()) { This->fCanSplit = 1;
return kTRUE; }
2264 if (fName ==
"TClonesArray") { This->fCanSplit = 1;
return kTRUE; }
2265 if (fRefProxy) { This->fCanSplit = 0;
return kFALSE; }
2266 if (fName.BeginsWith(
"TVectorT<")) { This->fCanSplit = 0;
return kFALSE; }
2267 if (fName.BeginsWith(
"TMatrixT<")) { This->fCanSplit = 0;
return kFALSE; }
2268 if (fName ==
"string") { This->fCanSplit = 0;
return kFALSE; }
2269 if (fName ==
"std::string") { This->fCanSplit = 0;
return kFALSE; }
2271 if (GetCollectionProxy()!=0) {
2278 if (GetCollectionProxy()->HasPointers()) { This->fCanSplit = 0;
return kFALSE; }
2280 TClass *valueClass = GetCollectionProxy()->GetValueClass();
2281 if (valueClass == 0) { This->fCanSplit = 0;
return kFALSE; }
2282 static TClassRef stdStringClass(
"std::string");
2283 if (valueClass==TString::Class() || valueClass==stdStringClass)
2284 { This->fCanSplit = 0;
return kFALSE; }
2285 if (!valueClass->CanSplit()) { This->fCanSplit = 0;
return kFALSE; }
2286 if (valueClass->GetCollectionProxy() != 0) { This->fCanSplit = 0;
return kFALSE; }
2288 Int_t stl = -TClassEdit::IsSTLCont(GetName(), 0);
2289 if ((stl==ROOT::kSTLmap || stl==ROOT::kSTLmultimap)
2290 && !valueClass->HasDataMemberInfo())
2292 This->fCanSplit = 0;
2296 This->fCanSplit = 1;
2301 if (GetStreamer() !=
nullptr || fStreamerFunc !=
nullptr) {
2305 This->fCanSplit = 0;
2308 }
else if ( TestBit(TClass::kHasCustomStreamerMember) ) {
2312 This->fCanSplit = 0;
2318 This->fCanSplit = 0;
2323 if ( !This->CanSplitBaseAllow() ) {
2327 This->fCanSplit = 1;
2335 Long_t TClass::ClassProperty()
const
2337 if (fProperty == -1) Property();
2338 return fClassProperty;
2345 TObject *TClass::Clone(
const char *new_name)
const
2347 if (new_name == 0 || new_name[0]==
'\0' || fName == new_name) {
2348 Error(
"Clone",
"The name of the class must be changed when cloning a TClass object.");
2353 R__LOCKGUARD(gInterpreterMutex);
2355 TClass::RemoveClass(const_cast<TClass*>(
this));
2359 copy =
new TClass(GetName(),
2362 new TIsAProxy(*fTypeInfo),
2368 copy =
new TClass(GetName(),
2375 copy->fShowMembers = fShowMembers;
2377 TClass::RemoveClass(copy);
2378 copy->fName = new_name;
2379 TClass::AddClass(copy);
2382 copy->SetNewArray(fNewArray);
2383 copy->SetDelete(fDelete);
2384 copy->SetDeleteArray(fDeleteArray);
2385 copy->SetDestructor(fDestructor);
2386 copy->SetDirectoryAutoAdd(fDirAutoAdd);
2387 copy->fStreamerFunc = fStreamerFunc;
2388 copy->fConvStreamerFunc = fConvStreamerFunc;
2390 copy->AdoptStreamer(fStreamer->Generate());
2394 if (fCollectionProxy && !copy->IsZombie()) {
2395 copy->CopyCollectionProxy(*fCollectionProxy);
2397 copy->SetClassSize(fSizeof);
2399 copy->AdoptReferenceProxy( fRefProxy->Clone() );
2401 TClass::AddClass(const_cast<TClass*>(
this));
2408 void TClass::CopyCollectionProxy(
const TVirtualCollectionProxy &orig)
2414 delete fCollectionProxy;
2415 fCollectionProxy = orig.Generate();
2425 void TClass::Draw(Option_t *option)
2427 if (!HasInterpreterInfo())
return;
2429 TVirtualPad *padsav = gPad;
2433 if (!padsav || !opt.Contains(
"same")) {
2434 TVirtualPad *padclass = (TVirtualPad*)(gROOT->GetListOfCanvases())->FindObject(
"R__class");
2436 gROOT->ProcessLine(
"new TCanvas(\"R__class\",\"class\",20,20,1000,750);");
2442 if (gPad) gPad->DrawClassObject(
this,option);
2444 if (padsav) padsav->cd();
2474 void TClass::Dump(
const void *obj, Bool_t noAddr )
const
2477 Long_t prObj = noAddr ? 0 : (Long_t)obj;
2479 if (!fIsOffsetStreamerSet) {
2480 CalculateStreamerOffset();
2482 TObject *tobj = (TObject*)((Long_t)obj + fOffsetStreamer);
2485 if (
sizeof(
this) == 4)
2486 Printf(
"==> Dumping object at: 0x%08lx, name=%s, class=%s\n",prObj,tobj->GetName(),GetName());
2488 Printf(
"==> Dumping object at: 0x%016lx, name=%s, class=%s\n",prObj,tobj->GetName(),GetName());
2491 if (
sizeof(
this) == 4)
2492 Printf(
"==> Dumping object at: 0x%08lx, class=%s\n",prObj,GetName());
2494 Printf(
"==> Dumping object at: 0x%016lx, class=%s\n",prObj,GetName());
2497 TDumpMembers dm(noAddr);
2498 if (!CallShowMembers(obj, dm, kFALSE)) {
2499 Info(
"Dump",
"No ShowMembers function, dumping disabled");
2507 char *TClass::EscapeChars(
const char *text)
const
2509 static const UInt_t maxsize = 255;
2510 static char name[maxsize+2];
2512 UInt_t nch = strlen(text);
2514 for (UInt_t i = 0; i < nch && icur < maxsize; ++i, ++icur) {
2515 if (text[i] ==
'\"' || text[i] ==
'[' || text[i] ==
'~' ||
2516 text[i] ==
']' || text[i] ==
'&' || text[i] ==
'#' ||
2517 text[i] ==
'!' || text[i] ==
'^' || text[i] ==
'<' ||
2518 text[i] ==
'?' || text[i] ==
'>') {
2522 name[icur] = text[i];
2546 TClass *TClass::GetActualClass(
const void *
object)
const
2548 if (
object==0)
return (TClass*)
this;
2550 return (*fIsA)(object);
2551 }
else if (fGlobalIsA) {
2552 return fGlobalIsA(
this,
object);
2556 if (!fIsOffsetStreamerSet) {
2557 CalculateStreamerOffset();
2559 TObject* realTObject = (TObject*)((
size_t)
object + fOffsetStreamer);
2561 return realTObject->IsA();
2564 if (HasInterpreterInfo()) {
2566 TVirtualIsAProxy *isa = 0;
2567 if (GetClassInfo() && gCling->ClassInfo_HasMethod(fClassInfo,
"IsA")) {
2568 isa = (TVirtualIsAProxy*)gROOT->ProcessLineFast(TString::Format(
"new ::TInstrumentedIsAProxy<%s>(0);",GetName()));
2571 isa = (TVirtualIsAProxy*)gROOT->ProcessLineFast(TString::Format(
"new ::TIsAProxy(typeid(%s));",GetName()));
2574 R__LOCKGUARD(gInterpreterMutex);
2575 const_cast<TClass*
>(
this)->fIsA = isa;
2578 return (*fIsA)(object);
2581 TVirtualStreamerInfo* sinfo = GetStreamerInfo();
2583 return sinfo->GetActualClass(
object);
2585 return (TClass*)
this;
2593 TClass *TClass::GetBaseClass(
const char *classname)
2596 if (strcmp(GetName(), classname) == 0)
return this;
2598 if (!HasDataMemberInfo())
return 0;
2602 TClass *search = TClass::GetClass(classname,kTRUE,kTRUE);
2604 if (search)
return GetBaseClass(search);
2612 TClass *TClass::GetBaseClass(
const TClass *cl)
2615 if (cl ==
this)
return this;
2617 if (!HasDataMemberInfo())
return 0;
2619 TObjLink *lnk = GetListOfBases() ? fBase.load()->FirstLink() : 0;
2624 TBaseClass *base = (TBaseClass*) lnk->GetObject();
2625 c = base->GetClassPointer();
2627 if (cl == c)
return c;
2628 c1 = c->GetBaseClass(cl);
2643 Int_t TClass::GetBaseClassOffsetRecurse(
const TClass *cl)
2646 if (cl ==
this)
return 0;
2648 if (!fBase.load()) {
2649 if (fCanLoadClassInfo) LoadClassInfo();
2654 TVirtualStreamerInfo *sinfo = GetCurrentStreamerInfo();
2655 if (!sinfo)
return -1;
2656 TStreamerElement *element;
2659 TObjArray &elems = *(sinfo->GetElements());
2660 Int_t size = elems.GetLast()+1;
2661 for(Int_t i=0; i<size; i++) {
2662 element = (TStreamerElement*)elems[i];
2663 if (element->IsBase()) {
2664 if (element->IsA() == TStreamerBase::Class()) {
2665 TStreamerBase *base = (TStreamerBase*)element;
2666 TClass *baseclass = base->GetClassPointer();
2667 if (!baseclass)
return -1;
2668 Int_t subOffset = baseclass->GetBaseClassOffsetRecurse(cl);
2669 if (subOffset == -2)
return -2;
2670 if (subOffset != -1)
return offset+subOffset;
2671 offset += baseclass->Size();
2672 }
else if (element->IsA() == TStreamerSTL::Class()) {
2673 TStreamerSTL *base = (TStreamerSTL*)element;
2674 TClass *baseclass = base->GetClassPointer();
2675 if (!baseclass)
return -1;
2676 Int_t subOffset = baseclass->GetBaseClassOffsetRecurse(cl);
2677 if (subOffset == -2)
return -2;
2678 if (subOffset != -1)
return offset+subOffset;
2679 offset += baseclass->Size();
2682 Error(
"GetBaseClassOffsetRecurse",
"Unexpected element type for base class: %s\n",element->IsA()->GetName());
2694 if (fBase.load() == 0)
2695 lnk = GetListOfBases()->FirstLink();
2697 lnk = fBase.load()->FirstLink();
2701 inh = (TBaseClass *)lnk->GetObject();
2706 c = inh->GetClassPointer(kTRUE);
2709 if ((inh->Property() & kIsVirtualBase) != 0)
2711 return inh->GetDelta();
2713 off = c->GetBaseClassOffsetRecurse(cl);
2714 if (off == -2)
return -2;
2716 return off + inh->GetDelta();
2729 Int_t TClass::GetBaseClassOffset(
const TClass *toBase,
void *address,
bool isDerivedObject)
2733 if (
this == toBase)
return 0;
2736 (!HasInterpreterInfoInMemory() || !toBase->HasInterpreterInfoInMemory())) {
2740 Int_t offset = GetBaseClassOffsetRecurse (toBase);
2747 ClassInfo_t* derived = GetClassInfo();
2748 ClassInfo_t* base = toBase->GetClassInfo();
2749 if(derived && base) {
2751 return gCling->ClassInfo_GetBaseOffset(derived, base, address, isDerivedObject);
2754 Int_t offset = GetBaseClassOffsetRecurse (toBase);
2765 TClass *TClass::GetBaseDataMember(
const char *datamember)
2767 if (!HasDataMemberInfo())
return 0;
2770 TDataMember *dm = GetDataMember(datamember);
2771 if (dm)
return this;
2775 TIter next(GetListOfBases());
2776 while ((inh = (TBaseClass *) next())) {
2777 TClass *c = inh->GetClassPointer();
2779 TClass *cdm = c->GetBaseDataMember(datamember);
2780 if (cdm)
return cdm;
2791 struct TClassLocalStorage {
2792 TClassLocalStorage() : fCollectionProxy(0), fStreamer(0) {};
2794 TVirtualCollectionProxy *fCollectionProxy;
2795 TClassStreamer *fStreamer;
2797 static TClassLocalStorage *GetStorage(
const TClass *cl)
2801 void **thread_ptr = (*gThreadTsd)(0,ROOT::kClassThreadSlot);
2803 if (*thread_ptr==0) *thread_ptr =
new TExMap();
2804 TExMap *lmap = (TExMap*)(*thread_ptr);
2805 ULong_t hash = TString::Hash(&cl,
sizeof(
void*));
2808 if ((local = (ULong_t)lmap->GetValue(hash, (Long_t)cl, slot)) != 0) {
2810 local = (ULong_t)
new TClassLocalStorage();
2811 lmap->AddAt(slot, hash, (Long_t)cl, local);
2813 return (TClassLocalStorage*)local;
2824 ROOT::ESTLType TClass::GetCollectionType()
const
2826 auto proxy = GetCollectionProxy();
2827 if (proxy)
return (ROOT::ESTLType)proxy->GetCollectionType();
2828 return ROOT::kNotSTL;
2835 TVirtualCollectionProxy *TClass::GetCollectionProxy()
const
2839 assert(TestBit(kLoading) || !TClassEdit::IsSTLCont(fName) || fCollectionProxy || 0 ==
"The TClass for the STL collection has no collection proxy!");
2840 if (gThreadTsd && fCollectionProxy) {
2841 TClassLocalStorage *local = TClassLocalStorage::GetStorage(
this);
2842 if (local == 0)
return fCollectionProxy;
2843 if (local->fCollectionProxy==0) local->fCollectionProxy = fCollectionProxy->Generate();
2844 return local->fCollectionProxy;
2846 return fCollectionProxy;
2852 TClassStreamer *TClass::GetStreamer()
const
2854 if (gThreadTsd && fStreamer) {
2855 TClassLocalStorage *local = TClassLocalStorage::GetStorage(
this);
2856 if (local==0)
return fStreamer;
2857 if (local->fStreamer==0) {
2858 local->fStreamer = fStreamer->Generate();
2859 const std::type_info &orig = (
typeid(*fStreamer) );
2860 if (!local->fStreamer) {
2861 Warning(
"GetStreamer",
"For %s, the TClassStreamer (%s) passed's call to Generate failed!",GetName(),orig.name());
2863 const std::type_info © = (
typeid(*local->fStreamer) );
2864 if (strcmp(orig.name(),copy.name())!=0) {
2865 Warning(
"GetStreamer",
"For %s, the TClassStreamer passed does not properly implement the Generate method (%s vs %s)\n",GetName(),orig.name(),copy.name());
2869 return local->fStreamer;
2877 ClassStreamerFunc_t TClass::GetStreamerFunc()
const
2879 return fStreamerFunc;
2885 ClassConvStreamerFunc_t TClass::GetConvStreamerFunc()
const
2887 return fConvStreamerFunc;
2893 TVirtualIsAProxy* TClass::GetIsAProxy()
const
2906 TClass *TClass::GetClass(
const char *name, Bool_t load, Bool_t silent)
2908 if (!name || !name[0])
return 0;
2910 if (strstr(name,
"(anonymous)"))
return 0;
2911 if (strncmp(name,
"class ",6)==0) name += 6;
2912 if (strncmp(name,
"struct ",7)==0) name += 7;
2914 if (!gROOT->GetListOfClasses())
return 0;
2919 TClass *cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name);
2923 if (cl && (cl->IsLoaded() || cl->TestBit(kUnloading)))
return cl;
2925 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
2930 cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name);
2932 if (cl->IsLoaded() || cl->TestBit(kUnloading))
return cl;
2956 DictFuncPtr_t dict = TClassTable::GetDictNorm(name);
2960 if (!cl && !load)
return 0;
2962 TClass *loadedcl = (dict)();
2964 loadedcl->PostLoadCheck();
2972 std::string normalizedName;
2973 Bool_t checkTable = kFALSE;
2977 TInterpreter::SuspendAutoloadingRAII autoloadOff(gInterpreter);
2978 TClassEdit::GetNormalizedName(normalizedName, name);
2981 if (normalizedName != name) {
2982 cl = (TClass*)gROOT->GetListOfClasses()->FindObject(normalizedName.c_str());
2985 if (cl->IsLoaded() || cl->TestBit(kUnloading))
return cl;
2993 normalizedName = cl->GetName();
2994 checkTable = load && (normalizedName != name);
2997 if (!load)
return 0;
3014 TClass *loadedcl = 0;
3016 loadedcl = LoadClassDefault(normalizedName.c_str(),silent);
3018 if (gInterpreter->AutoLoad(normalizedName.c_str(),kTRUE)) {
3019 loadedcl = LoadClassDefault(normalizedName.c_str(),silent);
3023 if (TDataType* theDataType = gROOT->GetType(normalizedName.c_str())){
3025 auto underlyingTypeName = theDataType->GetTypeName();
3027 auto underlyingTypeDict = TClassTable::GetDictNorm(underlyingTypeName.Data());
3028 if (underlyingTypeDict){
3029 loadedcl = underlyingTypeDict();
3035 if (loadedcl)
return loadedcl;
3038 loadedcl = LoadClassCustom(normalizedName.c_str(),silent);
3039 if (loadedcl)
return loadedcl;
3045 if (TClassEdit::IsSTLCont( normalizedName.c_str() )) {
3047 return gInterpreter->GenerateTClass(normalizedName.c_str(), kTRUE, silent);
3052 std::string::size_type posLess = normalizedName.find(
'<');
3053 if (posLess != std::string::npos) {
3054 gCling->AutoParse(normalizedName.substr(0, posLess).c_str());
3060 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());
3062 if (normalizedName.length()) {
3063 auto cci = gInterpreter->CheckClassInfo(normalizedName.c_str(), kTRUE ,
3071 if (cci == TInterpreter::kWithClassDefInline) {
3072 auto ci = gInterpreter->ClassInfo_Factory(normalizedName.c_str());
3073 auto funcDecl = gInterpreter->GetFunctionWithPrototype(ci,
"Dictionary",
"",
false, ROOT::kExactMatch);
3074 auto method = gInterpreter->MethodInfo_Factory(funcDecl);
3075 typedef void (*tcling_callfunc_Wrapper_t)(
void *, int,
void **,
void *);
3076 auto funcPtr = (tcling_callfunc_Wrapper_t)gInterpreter->MethodInfo_InterfaceMethod(method);
3078 TClass *res =
nullptr;
3080 funcPtr(0, 0,
nullptr, &res);
3085 gInterpreter->MethodInfo_Delete(method);
3086 gInterpreter->ClassInfo_Delete(ci);
3092 std::string alternative;
3093 gInterpreter->GetInterpreterTypeName(normalizedName.c_str(), alternative, kTRUE);
3094 const char *altname = alternative.c_str();
3095 if (strncmp(altname,
"std::", 5) == 0) {
3100 if (altname != normalizedName && strcmp(altname, name) != 0) {
3109 return GetClass(altname, load);
3112 TClass *ncl = gInterpreter->GenerateTClass(normalizedName.c_str(), kFALSE, silent);
3113 if (!ncl->IsZombie()) {
3125 TClass *TClass::GetClass(
const std::type_info& typeinfo, Bool_t load, Bool_t )
3127 if (!gROOT->GetListOfClasses())
3131 R__READ_LOCKGUARD(ROOT::gCoreMutex);
3133 TClass* cl = GetIdMap()->Find(typeinfo.name());
3135 if (cl && cl->IsLoaded())
return cl;
3137 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
3142 cl = GetIdMap()->Find(typeinfo.name());
3145 if (cl->IsLoaded())
return cl;
3161 if (!load)
return 0;
3163 DictFuncPtr_t dict = TClassTable::GetDict(typeinfo);
3166 if (cl) cl->PostLoadCheck();
3171 TIter next(gROOT->GetListOfClassGenerators());
3172 TClassGenerator *gen;
3173 while( (gen = (TClassGenerator*) next()) ) {
3174 cl = gen->GetClass(typeinfo,load);
3176 cl->PostLoadCheck();
3182 int autoload_old = gCling->SetClassAutoloading(1);
3183 if (!autoload_old) {
3185 gCling->SetClassAutoloading(0);
3187 if (autoload_old && gInterpreter->AutoLoad(typeinfo,kTRUE)) {
3189 TInterpreter::SuspendAutoloadingRAII autoloadOff(gInterpreter);
3190 cl = GetClass(typeinfo, load);
3198 cl = gInterpreter->GetClass(typeinfo, load);
3211 TClass *TClass::GetClass(ClassInfo_t *info, Bool_t load, Bool_t silent)
3213 if (!info || !gCling->ClassInfo_IsValid(info))
return 0;
3214 if (!gROOT->GetListOfClasses())
return 0;
3220 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
3223 TString name( gCling->ClassInfo_FullName(info) );
3225 TClass *cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name);
3228 if (cl->IsLoaded())
return cl;
3235 if (!load)
return 0;
3237 TClass *loadedcl = 0;
3238 if (cl) loadedcl = gROOT->LoadClass(cl->GetName(),silent);
3239 else loadedcl = gROOT->LoadClass(name,silent);
3241 if (loadedcl)
return loadedcl;
3247 TClass *ncl = gInterpreter->GenerateTClass(info, silent);
3248 if (!ncl->IsZombie()) {
3258 Bool_t TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(
const char* name){
3259 return fNoInfoOrEmuOrFwdDeclNameRegistry.HasDeclName(name);
3264 Bool_t TClass::GetClass(DeclId_t
id, std::vector<TClass*> &classes)
3266 if (!gROOT->GetListOfClasses())
return 0;
3268 DeclIdMap_t* map = GetDeclIdMap();
3270 DeclIdMap_t::equal_range iter = map->Find(
id);
3271 if (iter.first == iter.second)
return false;
3272 std::vector<TClass*>::iterator vectIt = classes.begin();
3273 for (DeclIdMap_t::const_iterator it = iter.first; it != iter.second; ++it)
3274 vectIt = classes.insert(vectIt, it->second);
3282 DictFuncPtr_t TClass::GetDict (
const char *cname)
3284 return TClassTable::GetDict(cname);
3291 DictFuncPtr_t TClass::GetDict (
const std::type_info& info)
3293 return TClassTable::GetDict(info);
3299 TDataMember *TClass::GetDataMember(
const char *datamember)
const
3301 if ((!(fData && fData->IsLoaded()) && !HasInterpreterInfo())
3302 || datamember == 0)
return 0;
3305 const char *start_name = datamember;
3306 while (*start_name ==
'*') ++start_name;
3311 if (
const char *s = strchr(start_name,
'[')){
3312 UInt_t len = s-start_name;
3313 TString name(start_name,len);
3314 return (TDataMember *)((TClass*)
this)->GetListOfDataMembers(kFALSE)->FindObject(name.Data());
3316 return (TDataMember *)((TClass*)
this)->GetListOfDataMembers(kFALSE)->FindObject(start_name);
3323 const char *TClass::GetDeclFileName()
const
3325 if (fDeclFileName == kUndeterminedClassInfoName)
3326 return gInterpreter->ClassInfo_FileName( fClassInfo );
3327 return fDeclFileName;
3337 Long_t TClass::GetDataMemberOffset(
const char *name)
const
3339 TRealData *rd = GetRealData(name);
3340 if (rd)
return rd->GetThisOffset();
3341 if (strchr(name,
'[')==0) {
3346 TVirtualStreamerInfo *info =
const_cast<TClass*
>(
this)->GetCurrentStreamerInfo();
3348 return info->GetOffset(name);
3363 TRealData* TClass::GetRealData(
const char* name)
const
3366 const_cast<TClass*
>(
this)->BuildRealData();
3378 TRealData* rd = (TRealData*) fRealData->FindObject(name);
3383 std::string givenName(name);
3386 std::string::size_type firstBracket = givenName.find_first_of(
"[");
3387 if (firstBracket != std::string::npos) {
3389 std::string nameNoDim(givenName.substr(0, firstBracket));
3390 TObjLink* lnk = fRealData->FirstLink();
3392 TObject* obj = lnk->GetObject();
3393 std::string objName(obj->GetName());
3394 std::string::size_type pos = objName.find_first_of(
"[");
3396 if (pos != std::string::npos) {
3398 if (objName == nameNoDim) {
3399 return static_cast<TRealData*
>(obj);
3407 std::ostringstream ptrname;
3408 ptrname <<
"*" << givenName;
3409 rd = (TRealData*) fRealData->FindObject(ptrname.str().c_str());
3415 std::string::size_type firstDot = givenName.find_first_of(
".");
3416 if (firstDot == std::string::npos) {
3427 std::string::size_type lastDot = givenName.find_last_of(
".");
3428 std::ostringstream starname;
3429 starname << givenName.substr(0, lastDot) <<
".*" << givenName.substr(lastDot + 1);
3430 rd = (TRealData*) fRealData->FindObject(starname.str().c_str());
3437 std::string firstDotName(givenName.substr(firstDot + 1));
3442 rd = (TRealData*) fRealData->FindObject(firstDotName.c_str());
3451 std::string::size_type firstDotBracket = firstDotName.find_first_of(
"[");
3452 if (firstDotBracket != std::string::npos) {
3454 std::string nameNoDim(firstDotName.substr(0, firstDotBracket));
3455 TObjLink* lnk = fRealData->FirstLink();
3457 TObject* obj = lnk->GetObject();
3458 std::string objName(obj->GetName());
3459 std::string::size_type pos = objName.find_first_of(
"[");
3461 if (pos != std::string::npos) {
3463 if (objName == nameNoDim) {
3464 return static_cast<TRealData*
>(obj);
3476 ptrname <<
"*" << firstDotName;
3477 rd = (TRealData*) fRealData->FindObject(ptrname.str().c_str());
3492 std::string::size_type bracket = starname.str().find_first_of(
"[");
3493 if (bracket == std::string::npos) {
3496 rd = (TRealData*) fRealData->FindObject(starname.str().substr(0, bracket).c_str());
3507 TFunctionTemplate *TClass::GetFunctionTemplate(
const char *name)
3509 if (!gInterpreter || !HasInterpreterInfo())
return 0;
3512 if (!fFuncTemplate) fFuncTemplate =
new TListOfFunctionTemplates(
this);
3514 return (TFunctionTemplate*)fFuncTemplate->FindObject(name);
3523 const char *TClass::GetSharedLibs()
3525 if (!gInterpreter)
return 0;
3527 if (fSharedLibs.IsNull())
3528 fSharedLibs = gInterpreter->GetClassSharedLibs(fName);
3530 return !fSharedLibs.IsNull() ? fSharedLibs.Data() : 0;
3536 TList *TClass::GetListOfBases()
3538 if (!fBase.load()) {
3539 if (fCanLoadClassInfo) {
3540 if (fState == kHasTClassInit) {
3542 R__LOCKGUARD(gInterpreterMutex);
3547 TProtoClass *proto = TClassTable::GetProtoNorm(GetName());
3548 if (proto && proto->FillTClass(
this)) {
3552 fHasRootPcmInfo = kTRUE;
3556 if (!fHasRootPcmInfo && !fCanLoadClassInfo) {
3560 if (!fClassInfo)
return 0;
3563 Fatal(
"GetListOfBases",
"gInterpreter not initialized");
3565 R__LOCKGUARD(gInterpreterMutex);
3566 if (!fBase.load()) {
3567 gInterpreter->CreateListOfBaseClasses(
this);
3590 TList *TClass::GetListOfEnums(Bool_t requestListLoading )
3592 auto temp = fEnums.load();
3594 if (requestListLoading) {
3595 if (fProperty == -1) Property();
3596 if (! ((kIsClass | kIsStruct | kIsUnion) & fProperty) ) {
3597 R__LOCKGUARD(gROOTMutex);
3599 }
else if ( temp->IsA() == TListOfEnumsWithLock::Class() ) {
3602 R__LOCKGUARD(gROOTMutex);
3609 if (!requestListLoading) {
3610 if (fProperty == -1) Property();
3611 R__LOCKGUARD(gInterpreterMutex);
3612 if (fEnums.load()) {
3613 return fEnums.load();
3616 static bool fromRootCling = dlsym(RTLD_DEFAULT,
"usedToIdentifyRootClingByDlSym");
3619 fEnums =
new TListOfEnums(
this);
3621 fEnums =
new TListOfEnumsWithLock(
this);
3625 R__LOCKGUARD(gInterpreterMutex);
3626 if (fEnums.load()) {
3628 return fEnums.load();
3630 if (fProperty == -1) Property();
3631 if ( (kIsClass | kIsStruct | kIsUnion) & fProperty) {
3633 temp =
new TListOfEnums(
this);
3636 temp =
new TListOfEnumsWithLock(
this);
3646 TList *TClass::GetListOfDataMembers(Bool_t load )
3648 R__LOCKGUARD(gInterpreterMutex);
3651 if (fCanLoadClassInfo && fState == kHasTClassInit) {
3656 TProtoClass *proto = TClassTable::GetProtoNorm(GetName());
3657 if (proto && proto->FillTClass(
this)) {
3661 fHasRootPcmInfo = kTRUE;
3665 fData =
new TListOfDataMembers(
this);
3667 if (Property() & (kIsClass|kIsStruct|kIsUnion)) {
3672 if (!fData->IsLoaded()) fData->Load();
3674 }
else if (load) fData->Load();
3681 TList *TClass::GetListOfFunctionTemplates(Bool_t load )
3683 R__LOCKGUARD(gInterpreterMutex);
3685 if (!fFuncTemplate) fFuncTemplate =
new TListOfFunctionTemplates(
this);
3686 if (load) fFuncTemplate->Load();
3687 return fFuncTemplate;
3695 TList *TClass::GetListOfMethods(Bool_t load )
3697 R__LOCKGUARD(gInterpreterMutex);
3699 if (!fMethod.load()) GetMethodList();
3701 if (gDebug>0) Info(
"GetListOfMethods",
"Header Parsing - Asking for all the methods of class %s: this can involve parsing.",GetName());
3710 TCollection *TClass::GetListOfMethodOverloads(
const char* name)
const
3712 return const_cast<TClass*
>(
this)->GetMethodList()->GetListForObject(name);
3728 const TList *TClass::GetListOfAllPublicMethods(Bool_t load )
3730 R__LOCKGUARD(gInterpreterMutex);
3732 if (!fAllPubMethod) fAllPubMethod =
new TViewPubFunctions(
this);
3734 if (gDebug>0) Info(
"GetListOfAllPublicMethods",
"Header Parsing - Asking for all the methods of class %s: this can involve parsing.",GetName());
3735 fAllPubMethod->Load();
3737 return fAllPubMethod;
3745 TList *TClass::GetListOfAllPublicDataMembers(Bool_t load )
3747 R__LOCKGUARD(gInterpreterMutex);
3749 if (!fAllPubData) fAllPubData =
new TViewPubDataMembers(
this);
3750 if (load) fAllPubData->Load();
3757 void TClass::GetMenuItems(TList *list)
3759 if (!HasInterpreterInfo())
return;
3762 TIter nextBase(GetListOfBases(), kIterBackward);
3763 TBaseClass *baseClass;
3764 while ((baseClass = (TBaseClass *) nextBase())) {
3765 TClass *base = baseClass->GetClassPointer();
3766 if (base) base->GetMenuItems(list);
3770 TMethod *method, *m;
3771 TIter next(GetListOfMethods(), kIterBackward);
3772 while ((method = (TMethod*)next())) {
3773 m = (TMethod*)list->FindObject(method->GetName());
3774 if (method->IsMenuItem() != kMenuNoMenu) {
3776 list->AddFirst(method);
3778 if (m && m->GetNargs() == method->GetNargs())
3789 Bool_t TClass::HasDictionary()
const
3800 Bool_t TClass::HasDictionarySelection(
const char* clname)
3802 if (TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(clname))
3803 return cl->IsLoaded();
3804 return gClassTable->GetDict(clname) || gInterpreter->GetClassSharedLibs(clname);
3810 void TClass::GetMissingDictionariesForBaseClasses(TCollection& result, TCollection& visited,
bool recurse)
3812 TList* lb = GetListOfBases();
3815 TBaseClass* base = 0;
3816 while ((base = (TBaseClass*)nextBase())) {
3817 TClass* baseCl = base->GetClassPointer();
3819 baseCl->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
3827 void TClass::GetMissingDictionariesForMembers(TCollection& result, TCollection& visited,
bool recurse)
3829 TListOfDataMembers* ldm = (TListOfDataMembers*)GetListOfDataMembers();
3831 TIter nextMemb(ldm);
3832 TDataMember * dm = 0;
3833 while ((dm = (TDataMember*)nextMemb())) {
3835 if(!dm->IsPersistent()) {
3838 if (dm->Property() & kIsStatic) {
3842 TClass* dmTClass = 0;
3843 if (dm->GetDataType()) {
3847 }
else if (dm->GetTypeName()) {
3848 dmTClass = TClass::GetClass(dm->GetTypeName());
3851 dmTClass->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
3856 void TClass::GetMissingDictionariesForPairElements(TCollection& result, TCollection& visited,
bool recurse)
3861 TVirtualStreamerInfo *SI = (TVirtualStreamerInfo*)this->GetStreamerInfo();
3862 for (
int i = 0; i < 2; i++) {
3863 TClass* pairElement = ((TStreamerElement*)SI->GetElements()->At(i))->GetClass();
3865 pairElement->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
3873 void TClass::GetMissingDictionariesWithRecursionCheck(TCollection& result, TCollection& visited,
bool recurse)
3875 if (result.FindObject(
this) || visited.FindObject(
this))
return;
3877 static TClassRef sCIString(
"string");
3878 if (
this == sCIString)
return;
3880 TClassEdit::TSplitType splitType(fName);
3881 if (splitType.IsTemplate()) {
3890 auto checkDicts = [&](
const string &clName){
3891 auto cl = TClass::GetClass(clName.c_str());
3894 const auto clNameShortType = TClassEdit::ShortType(clName.c_str(), 1);
3895 cl = TClass::GetClass(clNameShortType.c_str());
3897 if (cl && !cl->HasDictionary()) {
3898 cl->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
3902 const auto &elements = splitType.fElements;
3903 const auto &templName = elements[0];
3906 if (templName ==
"pair") {
3907 GetMissingDictionariesForPairElements(result, visited, recurse);
3914 if (templName ==
"unique_ptr" || templName ==
"array") {
3915 checkDicts(elements[1]);
3922 if (templName ==
"tuple") {
3925 const auto nTemplArgs = elements.size() - 1;
3927 for (
auto iTemplArg = 1U; iTemplArg < nTemplArgs; ++iTemplArg) {
3928 checkDicts(elements[iTemplArg]);
3934 if (!HasDictionary()) {
3940 if (!TestBit(TClass::kHasCustomStreamerMember)) {
3941 if (GetCollectionProxy()) {
3945 if ((t = GetCollectionProxy()->GetValueClass())) {
3946 if (!t->HasDictionary()) {
3947 t->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
3952 GetMissingDictionariesForMembers(result, visited, recurse);
3954 GetMissingDictionariesForBaseClasses(result, visited, recurse);
3970 void TClass::GetMissingDictionaries(THashTable& result,
bool recurse)
3974 if (result.FindObject(
this))
return;
3976 static TClassRef sCIString(
"string");
3977 if (
this == sCIString)
return;
3981 if (strncmp(fName,
"pair<", 5) == 0) {
3982 GetMissingDictionariesForPairElements(result, visited, recurse);
3986 if (!HasDictionary()) {
3993 if (!TestBit(TClass::kHasCustomStreamerMember)) {
3994 if (GetCollectionProxy()) {
3998 if ((t = GetCollectionProxy()->GetValueClass())) {
3999 if (!t->HasDictionary()) {
4000 t->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
4004 GetMissingDictionariesForMembers(result, visited, recurse);
4005 GetMissingDictionariesForBaseClasses(result, visited, recurse);
4013 Bool_t TClass::IsFolder(
void *obj)
const
4015 return Browse(obj,(TBrowser*)0);
4020 void TClass::ReplaceWith(TClass *newcl)
const
4024 R__LOCKGUARD(gInterpreterMutex);
4026 TIter nextClass(gROOT->GetListOfClasses());
4028 TVirtualStreamerInfo *info;
4034 TInterpreter::SuspendAutoloadingRAII autoloadOff(gInterpreter);
4035 while ((acl = (TClass*)nextClass())) {
4036 if (acl == newcl)
continue;
4038 TIter nextInfo(acl->GetStreamerInfos());
4039 while ((info = (TVirtualStreamerInfo*)nextInfo())) {
4041 info->Update(
this, newcl);
4044 if (acl->GetCollectionProxy()) {
4045 acl->GetCollectionProxy()->UpdateValueClass(
this, newcl);
4050 TIter delIter( &tobedeleted );
4051 while ((acl = (TClass*)delIter())) {
4054 gInterpreter->UnRegisterTClassUpdate(
this);
4060 void TClass::ResetClassInfo(Long_t )
4062 Warning(
"ResetClassInfo(Long_t tagnum)",
"Call to deprecated interface (does nothing)");
4068 void TClass::ResetClassInfo()
4070 R__LOCKGUARD(gInterpreterMutex);
4072 InsertTClassInRegistryRAII insertRAII(fState,fName,fNoInfoOrEmuOrFwdDeclNameRegistry);
4075 TClass::RemoveClassDeclId(gInterpreter->GetDeclId(fClassInfo));
4076 gInterpreter->ClassInfo_Delete(fClassInfo);
4087 if (fState != TClass::kHasTClassInit) {
4088 if (fStreamerInfo->GetEntries() != 0) {
4089 fState = TClass::kEmulated;
4091 fState = TClass::kForwardDeclared;
4096 fCanLoadClassInfo = kTRUE;
4103 void TClass::ResetCaches()
4105 R__ASSERT(!TestBit(kLoading) &&
"Resetting the caches does not make sense during loading!" );
4113 (*fMethod).Unload();
4115 delete fAllPubData; fAllPubData = 0;
4119 delete fBase.load(); fBase = 0;
4122 fRealData->Delete();
4123 delete fRealData; fRealData=0;
4129 void TClass::ResetMenuList()
4132 fClassMenuList->Delete();
4134 fClassMenuList =
new TList();
4135 fClassMenuList->Add(
new TClassMenuItem(TClassMenuItem::kPopupStandardList,
this));
4144 void TClass::ls(Option_t *options)
const
4146 TNamed::ls(options);
4147 if (options==0 || options[0]==0)
return;
4149 if (strstr(options,
"streamerinfo")!=0) {
4150 GetStreamerInfos()->ls(options);
4152 if (fConversionStreamerInfo.load()) {
4153 std::map<std::string, TObjArray*>::iterator it;
4154 std::map<std::string, TObjArray*>::iterator end = (*fConversionStreamerInfo).end();
4155 for( it = (*fConversionStreamerInfo).begin(); it != end; ++it ) {
4156 it->second->ls(options);
4169 void TClass::MakeCustomMenuList()
4171 R__LOCKGUARD(gInterpreterMutex);
4172 TClassMenuItem *menuItem;
4175 GetMenuList()->Delete();
4177 TList* methodList =
new TList;
4178 GetMenuItems(methodList);
4181 TMethodArg *methodArg;
4182 TClass *classPtr = 0;
4183 TIter next(methodList);
4185 while ((method = (TMethod*) next())) {
4187 if (classPtr != method->GetClass()) {
4188 menuItem =
new TClassMenuItem(TClassMenuItem::kPopupSeparator,
this);
4189 fClassMenuList->AddLast(menuItem);
4190 classPtr = method->GetClass();
4194 TList* margsList = method->GetListOfMethodArgs();
4195 TIter nextarg(margsList);
4196 while ((methodArg = (TMethodArg*)nextarg())) {
4197 sig = sig+
","+methodArg->GetFullTypeName();
4199 if (sig.Length()!=0) sig.Remove(0,1);
4200 menuItem =
new TClassMenuItem(TClassMenuItem::kPopupUserFunction,
this,
4201 method->GetName(), method->GetName(),0,
4202 sig.Data(),-1,TClassMenuItem::kIsSelf);
4203 if (method->IsMenuItem() == kMenuToggle) menuItem->SetToggle();
4204 fClassMenuList->Add(menuItem);
4213 void TClass::Move(
void *arenaFrom,
void *arenaTo)
const
4219 if ((GetState() <= kEmulated) && !fCollectionProxy) {
4220 MoveAddressInRepository(
"TClass::Move",arenaFrom,arenaTo,
this);
4227 TList *TClass::GetMenuList()
const {
4228 if (!fClassMenuList) {
4229 fClassMenuList =
new TList();
4230 fClassMenuList->Add(
new TClassMenuItem(TClassMenuItem::kPopupStandardList, const_cast<TClass*>(
this)));
4232 return fClassMenuList;
4241 TListOfFunctions *TClass::GetMethodList()
4243 if (!fMethod.load()) {
4244 std::unique_ptr<TListOfFunctions> temp{
new TListOfFunctions(
this) };
4245 TListOfFunctions* expected =
nullptr;
4246 if(fMethod.compare_exchange_strong(expected, temp.get()) ) {
4260 TMethod *TClass::GetMethodAny(
const char *method)
4262 if (!HasInterpreterInfo())
return 0;
4263 return (TMethod*) GetMethodList()->FindObject(method);
4270 TMethod *TClass::GetMethodAllAny(
const char *method)
4272 if (!HasInterpreterInfo())
return 0;
4274 TMethod* m = GetMethodAny(method);
4278 TIter nextb(GetListOfBases());
4279 while ((base = (TBaseClass *) nextb())) {
4280 TClass *c = base->GetClassPointer();
4282 m = c->GetMethodAllAny(method);
4297 TMethod *TClass::GetMethod(
const char *method,
const char *params,
4298 Bool_t objectIsConst )
4300 if (fCanLoadClassInfo) LoadClassInfo();
4301 if (!fClassInfo)
return 0;
4304 Fatal(
"GetMethod",
"gInterpreter not initialized");
4306 TInterpreter::DeclId_t decl = gInterpreter->GetFunctionWithValues(fClassInfo,
4310 if (!decl)
return 0;
4313 TMethod* f = FindClassOrBaseMethodWithId(decl);
4317 "\nDid not find matching TMethod <%s> with \"%s\" %sfor %s",
4318 method,params,objectIsConst ?
"const " :
"", GetName());
4326 TMethod* TClass::FindClassOrBaseMethodWithId(DeclId_t declId) {
4327 if (TFunction* method = GetMethodList()->Get(declId))
4328 return static_cast<TMethod *
>(method);
4330 for (
auto item : *GetListOfBases())
4331 if (
auto base = static_cast<TBaseClass *>(item)->GetClassPointer())
4332 if (TFunction* method = base->FindClassOrBaseMethodWithId(declId))
4333 return static_cast<TMethod *>(method);
4342 TMethod *TClass::GetMethodWithPrototype(
const char *method,
const char *proto,
4343 Bool_t objectIsConst ,
4344 ROOT::EFunctionMatchMode mode )
4346 if (fCanLoadClassInfo) LoadClassInfo();
4347 if (!fClassInfo)
return 0;
4350 Fatal(
"GetMethodWithPrototype",
"gInterpreter not initialized");
4352 TInterpreter::DeclId_t decl = gInterpreter->GetFunctionWithPrototype(fClassInfo,
4354 objectIsConst, mode);
4356 if (!decl)
return 0;
4357 TMethod* f = FindClassOrBaseMethodWithId(decl);
4359 Error(
"GetMethodWithPrototype",
4360 "\nDid not find matching TMethod <%s> with \"%s\" %sfor %s",
4361 method,proto,objectIsConst ?
"const " :
"", GetName());
4369 TMethod *TClass::GetClassMethod(Long_t faddr)
4371 if (!HasInterpreterInfo())
return 0;
4374 TIter next(GetListOfMethods());
4375 while ((m = (TMethod *) next())) {
4376 if (faddr == (Long_t)m->InterfaceMethod())
4388 TMethod *TClass::GetClassMethod(
const char *name,
const char* params,
4389 Bool_t objectIsConst )
4391 if (fCanLoadClassInfo) LoadClassInfo();
4392 if (!fClassInfo)
return 0;
4395 Fatal(
"GetClassMethod",
"gInterpreter not initialized");
4397 TInterpreter::DeclId_t decl = gInterpreter->GetFunctionWithValues(fClassInfo,
4401 if (!decl)
return 0;
4403 TFunction *f = GetMethodList()->Get(decl);
4413 TMethod *TClass::GetClassMethodWithPrototype(
const char *name,
const char* proto,
4414 Bool_t objectIsConst ,
4415 ROOT::EFunctionMatchMode mode )
4417 if (fCanLoadClassInfo) LoadClassInfo();
4418 if (!fClassInfo)
return 0;
4421 Fatal(
"GetClassMethodWithPrototype",
"gInterpreter not initialized");
4423 TInterpreter::DeclId_t decl = gInterpreter->GetFunctionWithPrototype(fClassInfo,
4428 if (!decl)
return 0;
4430 TFunction *f = GetMethodList()->Get(decl);
4440 Int_t TClass::GetNdata()
4442 if (!HasDataMemberInfo())
return 0;
4444 TList *lm = GetListOfDataMembers();
4446 return lm->GetSize();
4459 Int_t TClass::GetNmethods()
4461 if (!HasInterpreterInfo())
return 0;
4463 TList *lm = GetListOfMethods();
4465 return lm->GetSize();
4485 TVirtualStreamerInfo* TClass::GetStreamerInfo(Int_t version )
const
4487 TVirtualStreamerInfo *sinfo = fLastReadInfo;
4493 version = fClassVersion;
4497 if (sinfo && sinfo->GetClassVersion() == version)
4513 R__LOCKGUARD(gInterpreterMutex);
4519 if ((version < -1) || (version >= fStreamerInfo->GetSize())) {
4520 Error(
"GetStreamerInfo",
"class: %s, attempting to access a wrong version: %d", GetName(), version);
4522 version = fClassVersion;
4525 sinfo = (TVirtualStreamerInfo *)fStreamerInfo->At(version);
4527 if (!sinfo && (version != fClassVersion)) {
4534 sinfo = (TVirtualStreamerInfo*) fStreamerInfo->At(fClassVersion);
4539 TMmallocDescTemp setreset;
4540 sinfo = TVirtualStreamerInfo::Factory()->NewInfo(const_cast<TClass*>(
this));
4541 fStreamerInfo->AddAtAndExpand(sinfo, fClassVersion);
4543 printf(
"Creating StreamerInfo for class: %s, version: %d\n", GetName(), fClassVersion);
4545 if (HasDataMemberInfo() || fCollectionProxy) {
4551 if (!sinfo->IsCompiled()) {
4560 if (version == fClassVersion)
4561 fCurrentInfo = sinfo;
4564 if (sinfo->IsCompiled())
4565 fLastReadInfo = sinfo;
4588 TVirtualStreamerInfo* TClass::GetStreamerInfoAbstractEmulated(Int_t version )
const
4590 TVirtualStreamerInfo *sinfo =
nullptr;
4592 TString newname(GetName());
4593 newname +=
"@@emulated";
4595 R__LOCKGUARD(gInterpreterMutex);
4597 TClass *emulated = TClass::GetClass(newname);
4600 sinfo = emulated->GetStreamerInfo(version);
4606 sinfo = (TVirtualStreamerInfo*) fStreamerInfo->At(version);
4608 if (!sinfo && (version != fClassVersion)) {
4612 sinfo = (TVirtualStreamerInfo*) fStreamerInfo->At(fClassVersion);
4617 Int_t ninfos = fStreamerInfo->GetEntriesFast() - 1;
4618 for (Int_t i = -1; sinfo == 0 && i < ninfos; ++i)
4619 sinfo = (TVirtualStreamerInfo *)fStreamerInfo->UncheckedAt(i);
4623 sinfo =
dynamic_cast<TVirtualStreamerInfo *
>(sinfo->Clone());
4626 sinfo->SetName(newname);
4627 sinfo->BuildCheck();
4629 sinfo->GetClass()->AddRule(TString::Format(
"sourceClass=%s targetClass=%s",GetName(),newname.Data()));
4631 Error(
"GetStreamerInfoAbstractEmulated",
"could not create TVirtualStreamerInfo");
4651 TVirtualStreamerInfo* TClass::FindStreamerInfoAbstractEmulated(UInt_t checksum)
const
4653 TVirtualStreamerInfo *sinfo =
nullptr;
4655 TString newname(GetName());
4656 newname +=
"@@emulated";
4658 R__LOCKGUARD(gInterpreterMutex);
4660 TClass *emulated = TClass::GetClass(newname);
4663 sinfo = emulated->FindStreamerInfo(checksum);
4669 sinfo = (TVirtualStreamerInfo*) FindStreamerInfo(checksum);
4671 if (!sinfo && (checksum != fCheckSum)) {
4675 sinfo = (TVirtualStreamerInfo*) fStreamerInfo->At(fClassVersion);
4680 Int_t ninfos = fStreamerInfo->GetEntriesFast() - 1;
4681 for (Int_t i = -1; sinfo == 0 && i < ninfos; ++i)
4682 sinfo = (TVirtualStreamerInfo *)fStreamerInfo->UncheckedAt(i);
4686 sinfo =
dynamic_cast<TVirtualStreamerInfo*
>( sinfo->Clone() );
4689 sinfo->SetName( newname );
4690 sinfo->BuildCheck();
4692 sinfo->GetClass()->AddRule(TString::Format(
"sourceClass=%s targetClass=%s",GetName(),newname.Data()));
4694 Error(
"GetStreamerInfoAbstractEmulated",
"could not create TVirtualStreamerInfo");
4720 void TClass::IgnoreTObjectStreamer(Bool_t doIgnore)
4725 R__LOCKGUARD(gInterpreterMutex);
4727 if ( doIgnore && TestBit(kIgnoreTObjectStreamer))
return;
4728 if (!doIgnore && !TestBit(kIgnoreTObjectStreamer))
return;
4729 TVirtualStreamerInfo *sinfo = GetCurrentStreamerInfo();
4731 if (sinfo->IsCompiled()) {
4741 Error(
"IgnoreTObjectStreamer",
"Must be called before the creation of StreamerInfo");
4745 if (doIgnore) SetBit (kIgnoreTObjectStreamer);
4746 else ResetBit(kIgnoreTObjectStreamer);
4753 Bool_t TClass::InheritsFrom(
const char *classname)
const
4755 if (strcmp(GetName(), classname) == 0)
return kTRUE;
4757 return InheritsFrom(TClass::GetClass(classname,kTRUE,kTRUE));
4764 Bool_t TClass::InheritsFrom(
const TClass *cl)
const
4766 if (!cl)
return kFALSE;
4767 if (cl ==
this)
return kTRUE;
4769 if (!HasDataMemberInfo()) {
4770 TVirtualStreamerInfo *sinfo = ((TClass *)
this)->GetCurrentStreamerInfo();
4771 if (sinfo==0) sinfo = GetStreamerInfo();
4772 TIter next(sinfo->GetElements());
4773 TStreamerElement *element;
4774 while ((element = (TStreamerElement*)next())) {
4775 if (element->IsA() == TStreamerBase::Class()) {
4776 TClass *clbase = element->GetClassPointer();
4777 if (!clbase)
return kFALSE;
4778 if (clbase->InheritsFrom(cl))
return kTRUE;
4784 if (((TClass *)
this)->GetBaseClass(cl))
return kTRUE;
4794 void *TClass::DynamicCast(
const TClass *cl,
void *obj, Bool_t up)
4796 if (cl ==
this)
return obj;
4798 if (!HasDataMemberInfo())
return 0;
4801 if ((off = GetBaseClassOffset(cl, obj)) != -1) {
4803 return (
void*)((Long_t)obj+off);
4805 return (
void*)((Long_t)obj-off);
4816 const void *TClass::DynamicCast(
const TClass *cl,
const void *obj, Bool_t up)
4818 return DynamicCast(cl,const_cast<void*>(obj),up);
4857 void *TClass::New(ENewType defConstructor, Bool_t quiet)
const
4866 TClass__GetCallingNew() = defConstructor;
4868 TClass__GetCallingNew() = kRealNew;
4871 Error(
"New",
"cannot create object of class %s", GetName());
4873 }
else if (HasInterpreterInfo()) {
4882 TClass__GetCallingNew() = defConstructor;
4883 p = gCling->ClassInfo_New(GetClassInfo());
4884 TClass__GetCallingNew() = kRealNew;
4887 Error(
"New",
"cannot create object of class %s", GetName());
4889 }
else if (!HasInterpreterInfo() && fCollectionProxy) {
4893 TClass__GetCallingNew() = defConstructor;
4894 p = fCollectionProxy->New();
4895 TClass__GetCallingNew() = kRealNew;
4898 Error(
"New",
"cannot create object of class %s", GetName());
4900 }
else if (!HasInterpreterInfo() && !fCollectionProxy) {
4914 Bool_t statsave = GetObjectStat();
4916 SetObjectStat(kFALSE);
4918 TVirtualStreamerInfo* sinfo = GetStreamerInfo();
4919 if (!sinfo && !quiet) {
4920 Error(
"New",
"Cannot construct class '%s' version %d, no streamer info available!", GetName(), fClassVersion);
4924 TClass__GetCallingNew() = defConstructor;
4926 TClass__GetCallingNew() = kRealNew;
4931 SetObjectStat(statsave);
4936 RegisterAddressInRepository(
"New",p,
this);
4938 Error(
"New",
"Failed to construct class '%s' using streamer info", GetName());
4941 Fatal(
"New",
"This cannot happen!");
4952 void *TClass::New(
void *arena, ENewType defConstructor)
const
4961 TClass__GetCallingNew() = defConstructor;
4963 TClass__GetCallingNew() = kRealNew;
4965 Error(
"New with placement",
"cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
4967 }
else if (HasInterpreterInfo()) {
4976 TClass__GetCallingNew() = defConstructor;
4977 p = gCling->ClassInfo_New(GetClassInfo(),arena);
4978 TClass__GetCallingNew() = kRealNew;
4980 Error(
"New with placement",
"cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
4982 }
else if (!HasInterpreterInfo() && fCollectionProxy) {
4986 TClass__GetCallingNew() = defConstructor;
4987 p = fCollectionProxy->New(arena);
4988 TClass__GetCallingNew() = kRealNew;
4989 }
else if (!HasInterpreterInfo() && !fCollectionProxy) {
5001 Bool_t statsave = GetObjectStat();
5003 SetObjectStat(kFALSE);
5006 TVirtualStreamerInfo* sinfo = GetStreamerInfo();
5008 Error(
"New with placement",
"Cannot construct class '%s' version %d at address %p, no streamer info available!", GetName(), fClassVersion, arena);
5012 TClass__GetCallingNew() = defConstructor;
5013 p = sinfo->New(arena);
5014 TClass__GetCallingNew() = kRealNew;
5019 SetObjectStat(statsave);
5024 RegisterAddressInRepository(
"TClass::New with placement",p,
this);
5027 Error(
"New with placement",
"This cannot happen!");
5039 void *TClass::NewArray(Long_t nElements, ENewType defConstructor)
const
5048 TClass__GetCallingNew() = defConstructor;
5049 p = fNewArray(nElements, 0);
5050 TClass__GetCallingNew() = kRealNew;
5052 Error(
"NewArray",
"cannot create object of class %s version %d", GetName(), fClassVersion);
5054 }
else if (HasInterpreterInfo()) {
5063 TClass__GetCallingNew() = defConstructor;
5064 p = gCling->ClassInfo_New(GetClassInfo(),nElements);
5065 TClass__GetCallingNew() = kRealNew;
5067 Error(
"NewArray",
"cannot create object of class %s version %d", GetName(), fClassVersion);
5069 }
else if (!HasInterpreterInfo() && fCollectionProxy) {
5073 TClass__GetCallingNew() = defConstructor;
5074 p = fCollectionProxy->NewArray(nElements);
5075 TClass__GetCallingNew() = kRealNew;
5076 }
else if (!HasInterpreterInfo() && !fCollectionProxy) {
5088 Bool_t statsave = GetObjectStat();
5090 SetObjectStat(kFALSE);
5093 TVirtualStreamerInfo* sinfo = GetStreamerInfo();
5095 Error(
"NewArray",
"Cannot construct class '%s' version %d, no streamer info available!", GetName(), fClassVersion);
5099 TClass__GetCallingNew() = defConstructor;
5100 p = sinfo->NewArray(nElements);
5101 TClass__GetCallingNew() = kRealNew;
5106 SetObjectStat(statsave);
5111 RegisterAddressInRepository(
"TClass::NewArray",p,
this);
5114 Error(
"NewArray",
"This cannot happen!");
5125 void *TClass::NewArray(Long_t nElements,
void *arena, ENewType defConstructor)
const
5134 TClass__GetCallingNew() = defConstructor;
5135 p = fNewArray(nElements, arena);
5136 TClass__GetCallingNew() = kRealNew;
5138 Error(
"NewArray with placement",
"cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
5140 }
else if (HasInterpreterInfo()) {
5149 TClass__GetCallingNew() = defConstructor;
5150 p = gCling->ClassInfo_New(GetClassInfo(),nElements, arena);
5151 TClass__GetCallingNew() = kRealNew;
5153 Error(
"NewArray with placement",
"cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
5155 }
else if (!HasInterpreterInfo() && fCollectionProxy) {
5159 TClass__GetCallingNew() = defConstructor;
5160 p = fCollectionProxy->NewArray(nElements, arena);
5161 TClass__GetCallingNew() = kRealNew;
5162 }
else if (!HasInterpreterInfo() && !fCollectionProxy) {
5174 Bool_t statsave = GetObjectStat();
5176 SetObjectStat(kFALSE);
5179 TVirtualStreamerInfo* sinfo = GetStreamerInfo();
5181 Error(
"NewArray with placement",
"Cannot construct class '%s' version %d at address %p, no streamer info available!", GetName(), fClassVersion, arena);
5185 TClass__GetCallingNew() = defConstructor;
5186 p = sinfo->NewArray(nElements, arena);
5187 TClass__GetCallingNew() = kRealNew;
5192 SetObjectStat(statsave);
5195 if (fStreamerType & kEmulatedStreamer) {
5202 RegisterAddressInRepository(
"TClass::NewArray with placement",p,
this);
5205 Error(
"NewArray with placement",
"This cannot happen!");
5214 void TClass::Destructor(
void *obj, Bool_t dtorOnly)
5217 if (obj == 0)
return;
5221 if (dtorOnly && fDestructor) {
5224 }
else if ((!dtorOnly) && fDelete) {
5227 }
else if (HasInterpreterInfo()) {
5237 gCling->ClassInfo_Destruct(fClassInfo,p);
5239 gCling->ClassInfo_Delete(fClassInfo,p);
5241 }
else if (!HasInterpreterInfo() && fCollectionProxy) {
5245 fCollectionProxy->Destructor(p, dtorOnly);
5246 }
else if (!HasInterpreterInfo() && !fCollectionProxy) {
5252 Bool_t inRepo = kTRUE;
5253 Bool_t verFound = kFALSE;
5256 std::multiset<Version_t> knownVersions;
5257 R__LOCKGUARD2(gOVRMutex);
5260 RepoCont_t::iterator iter = gObjectVersionRepository.find(p);
5261 if (iter == gObjectVersionRepository.end()) {
5267 for (; (iter != gObjectVersionRepository.end()) && (iter->first == p); ++iter) {
5268 Version_t ver = iter->second.fVersion;
5269 knownVersions.insert(ver);
5270 if (ver == fClassVersion &&
this == iter->second.fClass) {
5277 if (!inRepo || verFound) {
5280 TVirtualStreamerInfo* si = GetStreamerInfo();
5282 si->Destructor(p, dtorOnly);
5284 Error(
"Destructor",
"No streamer info available for class '%s' version %d at address %p, cannot destruct emulated object!", GetName(), fClassVersion, p);
5285 Error(
"Destructor",
"length of fStreamerInfo is %d", fStreamerInfo->GetSize());
5286 Int_t i = fStreamerInfo->LowerBound();
5287 for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
5288 Error(
"Destructor",
"fStreamerInfo->At(%d): %p", i, fStreamerInfo->At(i));
5289 if (fStreamerInfo->At(i) != 0) {
5290 Error(
"Destructor",
"Doing Dump() ...");
5291 ((TVirtualStreamerInfo*)fStreamerInfo->At(i))->Dump();
5299 Error(
"Destructor",
"Loaded class %s version %d is not registered for addr %p", GetName(), fClassVersion, p);
5301 TVirtualStreamerInfo* si = (TVirtualStreamerInfo*) fStreamerInfo->At(objVer);
5303 si->Destructor(p, dtorOnly);
5305 Error(
"Destructor2",
"No streamer info available for class '%s' version %d, cannot destruct object at addr: %p", GetName(), objVer, p);
5306 Error(
"Destructor2",
"length of fStreamerInfo is %d", fStreamerInfo->GetSize());
5307 Int_t i = fStreamerInfo->LowerBound();
5308 for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
5309 Error(
"Destructor2",
"fStreamerInfo->At(%d): %p", i, fStreamerInfo->At(i));
5310 if (fStreamerInfo->At(i) != 0) {
5312 Error(
"Destructor2",
"Doing Dump() ...");
5313 ((TVirtualStreamerInfo*)fStreamerInfo->At(i))->Dump();
5320 if (inRepo && verFound && p) {
5321 UnregisterAddressInRepository(
"TClass::Destructor",p,
this);
5324 Error(
"Destructor",
"This cannot happen! (class %s)", GetName());
5331 void TClass::DeleteArray(
void *ary, Bool_t dtorOnly)
5334 if (ary == 0)
return;
5341 Error(
"DeleteArray",
"Destructor only is not supported!");
5346 }
else if (HasInterpreterInfo()) {
5354 gCling->ClassInfo_DeleteArray(GetClassInfo(),ary, dtorOnly);
5355 }
else if (!HasInterpreterInfo() && fCollectionProxy) {
5359 fCollectionProxy->DeleteArray(ary, dtorOnly);
5360 }
else if (!HasInterpreterInfo() && !fCollectionProxy) {
5366 Bool_t inRepo = kTRUE;
5367 Bool_t verFound = kFALSE;
5370 std::multiset<Version_t> knownVersions;
5372 R__LOCKGUARD2(gOVRMutex);
5373 RepoCont_t::iterator iter = gObjectVersionRepository.find(p);
5374 if (iter == gObjectVersionRepository.end()) {
5379 for (; (iter != gObjectVersionRepository.end()) && (iter->first == p); ++iter) {
5380 Version_t ver = iter->second.fVersion;
5381 knownVersions.insert(ver);
5382 if (ver == fClassVersion &&
this == iter->second.fClass ) {
5389 if (!inRepo || verFound) {
5392 TVirtualStreamerInfo* si = GetStreamerInfo();
5394 si->DeleteArray(ary, dtorOnly);
5396 Error(
"DeleteArray",
"No streamer info available for class '%s' version %d at address %p, cannot destruct object!", GetName(), fClassVersion, ary);
5397 Error(
"DeleteArray",
"length of fStreamerInfo is %d", fStreamerInfo->GetSize());
5398 Int_t i = fStreamerInfo->LowerBound();
5399 for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
5400 Error(
"DeleteArray",
"fStreamerInfo->At(%d): %p", v, fStreamerInfo->At(i));
5401 if (fStreamerInfo->At(i)) {
5402 Error(
"DeleteArray",
"Doing Dump() ...");
5403 ((TVirtualStreamerInfo*)fStreamerInfo->At(i))->Dump();
5411 Error(
"DeleteArray",
"Loaded class version %d is not registered for addr %p", fClassVersion, p);
5416 TVirtualStreamerInfo* si = (TVirtualStreamerInfo*) fStreamerInfo->At(objVer);
5418 si->DeleteArray(ary, dtorOnly);
5420 Error(
"DeleteArray",
"No streamer info available for class '%s' version %d at address %p, cannot destruct object!", GetName(), objVer, ary);
5421 Error(
"DeleteArray",
"length of fStreamerInfo is %d", fStreamerInfo->GetSize());
5422 Int_t i = fStreamerInfo->LowerBound();
5423 for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
5424 Error(
"DeleteArray",
"fStreamerInfo->At(%d): %p", v, fStreamerInfo->At(i));
5425 if (fStreamerInfo->At(i)) {
5427 Error(
"DeleteArray",
"Doing Dump() ...");
5428 ((TVirtualStreamerInfo*)fStreamerInfo->At(i))->Dump();
5438 if (inRepo && verFound && p) {
5439 UnregisterAddressInRepository(
"TClass::DeleteArray",p,
this);
5442 Error(
"DeleteArray",
"This cannot happen! (class '%s')", GetName());
5453 void TClass::SetCanSplit(Int_t splitmode)
5455 fCanSplit = splitmode;
5470 void TClass::SetClassVersion(Version_t version)
5472 fClassVersion = version;
5479 TVirtualStreamerInfo* TClass::DetermineCurrentStreamerInfo()
5481 if(!fCurrentInfo.load()) {
5482 R__READ_LOCKGUARD(ROOT::gCoreMutex);
5483 fCurrentInfo = (TVirtualStreamerInfo *)(fStreamerInfo->At(fClassVersion));
5485 return fCurrentInfo;
5491 void TClass::SetCurrentStreamerInfo(TVirtualStreamerInfo *info)
5493 fCurrentInfo = info;
5499 Int_t TClass::Size()
const
5501 if (fSizeof!=-1)
return fSizeof;
5502 if (fCollectionProxy)
return fCollectionProxy->Sizeof();
5503 if (HasInterpreterInfo())
return gCling->ClassInfo_Size(GetClassInfo());
5504 return GetStreamerInfo()->GetSize();
5510 TClass *TClass::Load(TBuffer &b)
5512 UInt_t maxsize = 256;
5513 char *s =
new char[maxsize];
5515 Int_t pos = b.Length();
5517 b.ReadString(s, maxsize);
5518 while (strlen(s) == (maxsize - 1)) {
5520 b.SetBufferOffset(pos);
5521 maxsize = 2*maxsize;
5523 s =
new char[maxsize];
5524 b.ReadString(s, maxsize);
5527 TClass *cl = TClass::GetClass(s, kTRUE);
5529 ::Error(
"TClass::Load",
"dictionary of class %s not found", s);
5544 TClass *TClass::LoadClass(
const char *requestedname, Bool_t silent)
5549 R__LOCKGUARD(gInterpreterMutex);
5551 TClass *result = LoadClassDefault(requestedname, silent);
5553 if (result)
return result;
5554 else return LoadClassCustom(requestedname,silent);
5566 TClass *TClass::LoadClassDefault(
const char *requestedname, Bool_t )
5571 DictFuncPtr_t dict = TClassTable::GetDictNorm(requestedname);
5574 if (gInterpreter->AutoLoad(requestedname,kTRUE)) {
5575 dict = TClassTable::GetDictNorm(requestedname);
5580 TClass *ncl = (dict)();
5581 if (ncl) ncl->PostLoadCheck();
5596 TClass *TClass::LoadClassCustom(
const char *requestedname, Bool_t silent)
5601 TIter next(gROOT->GetListOfClassGenerators());
5602 TClassGenerator *gen;
5603 while ((gen = (TClassGenerator*) next())) {
5604 TClass *cl = gen->GetClass(requestedname, kTRUE, silent);
5606 cl->PostLoadCheck();
5619 void TClass::LoadClassInfo()
const
5621 R__LOCKGUARD(gInterpreterMutex);
5625 if (!fCanLoadClassInfo)
5628 bool autoParse = !gInterpreter->IsAutoParsingSuspended();
5631 gInterpreter->AutoParse(GetName());
5634 gInterpreter->SetClassInfo(const_cast<TClass *>(
this));
5636 if (autoParse && !fClassInfo) {
5637 if (fImplFileLine == -1 && fClassVersion == 0) {
5642 ::Error(
"TClass::LoadClassInfo",
"no interpreter information for class %s is available"
5643 " even though it has a TClass initialization routine.",
5649 fCanLoadClassInfo =
false;
5655 void TClass::Store(TBuffer &b)
const
5657 b.WriteString(GetName());
5664 TClass *ROOT::CreateClass(
const char *cname, Version_t
id,
5665 const std::type_info &info, TVirtualIsAProxy *isa,
5666 const char *dfil,
const char *ifil,
5671 TMmallocDescTemp setreset;
5672 return new TClass(cname,
id, info, isa, dfil, ifil, dl, il);
5679 TClass *ROOT::CreateClass(
const char *cname, Version_t
id,
5680 const char *dfil,
const char *ifil,
5685 TMmallocDescTemp setreset;
5686 return new TClass(cname,
id, dfil, ifil, dl, il);
5697 TClass::ENewType TClass::IsCallingNew()
5699 return TClass__GetCallingNew();
5707 Bool_t TClass::IsLoaded()
const
5709 return fState == kHasTClassInit;
5724 Bool_t TClass::IsStartingWithTObject()
const
5726 if (fProperty==(-1)) Property();
5727 return TestBit(kStartWithTObject);
5733 Bool_t TClass::IsTObject()
const
5735 if (fProperty==(-1)) Property();
5736 return TestBit(kIsTObject);
5742 Bool_t TClass::IsForeign()
const
5744 if (fProperty==(-1)) Property();
5745 return TestBit(kIsForeign);
5752 void TClass::PostLoadCheck()
5758 if (IsLoaded() && HasInterpreterInfo() && fClassVersion==1
5761 SetClassVersion(-1);
5765 else if (IsLoaded() && HasDataMemberInfo() && fStreamerInfo && ((fClassVersion > 1) || !IsForeign()))
5767 R__LOCKGUARD(gInterpreterMutex);
5769 TVirtualStreamerInfo *info = (TVirtualStreamerInfo*)(fStreamerInfo->At(fClassVersion));
5774 if (info && GetListOfDataMembers() && !GetCollectionProxy()
5775 && (info->GetCheckSum()!=GetCheckSum() && !info->CompareContent(
this,0,kFALSE,kFALSE, 0) && !(MatchLegacyCheckSum(info->GetCheckSum()))))
5777 Bool_t warn = ! TestBit(kWarned);
5778 if (warn && info->GetOldVersion()<=2) {
5781 TIter nextBC(GetListOfBases());
5783 while ((bc=(TBaseClass*)nextBC()))
5784 {
if (TClassEdit::IsSTLCont(bc->GetName())) warn = kFALSE;}
5788 if (info->GetOnFileClassVersion()==1 && fClassVersion>1) {
5789 Warning(
"PostLoadCheck",
"\n\
5790 The class %s transitioned from not having a specified class version\n\
5791 to having a specified class version (the current class version is %d).\n\
5792 However too many different non-versioned layouts of the class have\n\
5793 already been loaded so far. To work around this problem you can\n\
5794 load fewer 'old' file in the same ROOT session or load the C++ library\n\
5795 describing the class %s before opening the files or increase the version\n\
5796 number of the class for example ClassDef(%s,%d).\n\
5797 Do not try to write objects with the current class definition,\n\
5798 the files might not be readable.\n",
5799 GetName(), fClassVersion, GetName(), GetName(), fStreamerInfo->GetLast()+1);
5801 Warning(
"PostLoadCheck",
"\n\
5802 The StreamerInfo version %d for the class %s which was read\n\
5803 from a file previously opened has the same version as the active class\n\
5804 but a different checksum. You should update the version to ClassDef(%s,%d).\n\
5805 Do not try to write objects with the current class definition,\n\
5806 the files will not be readable.\n"
5807 , fClassVersion, GetName(), GetName(), fStreamerInfo->GetLast()+1);
5809 info->CompareContent(
this,0,kTRUE,kTRUE,0);
5833 Long_t TClass::Property()
const
5838 if (fProperty!=(-1))
return fProperty;
5840 R__LOCKGUARD(gInterpreterMutex);
5844 if (fProperty!=(-1))
return fProperty;
5847 if (TestBit(kLoading))
return fProperty;
5851 TMmallocDescTemp setreset;
5853 TClass *kl =
const_cast<TClass*
>(
this);
5855 kl->fStreamerType = TClass::kDefault;
5856 kl->fStreamerImpl = &TClass::StreamerDefault;
5858 if (InheritsFrom(TObject::Class())) {
5859 kl->SetBit(kIsTObject);
5862 Int_t delta = kl->GetBaseClassOffsetRecurse(TObject::Class());
5863 if (delta==0) kl->SetBit(kStartWithTObject);
5865 kl->fStreamerType = kTObject;
5866 kl->fStreamerImpl = &TClass::StreamerTObject;
5869 if (HasInterpreterInfo()) {
5875 if (!const_cast<TClass*>(
this)->GetClassMethodWithPrototype(
"Streamer",
"TBuffer&",kFALSE)) {
5877 kl->SetBit(kIsForeign);
5878 kl->fStreamerType = kForeign;
5879 kl->fStreamerImpl = &TClass::StreamerStreamerInfo;
5881 }
else if ( kl->fStreamerType == TClass::kDefault ) {
5882 if (kl->fConvStreamerFunc) {
5883 kl->fStreamerType = kInstrumented;
5884 kl->fStreamerImpl = &TClass::ConvStreamerInstrumented;
5885 }
else if (kl->fStreamerFunc) {
5886 kl->fStreamerType = kInstrumented;
5887 kl->fStreamerImpl = &TClass::StreamerInstrumented;
5891 kl->fStreamerType = kInstrumented;
5892 kl->fStreamerImpl = &TClass::StreamerStreamerInfo;
5897 kl->fStreamerType = kExternal;
5898 kl->fStreamerImpl = &TClass::StreamerExternal;
5901 if (const_cast<TClass *>(
this)->GetClassMethodWithPrototype(
"Hash",
"", kTRUE)) {
5902 kl->SetBit(kHasLocalHashMember);
5905 if (GetClassInfo()) {
5914 kl->fClassProperty = gCling->ClassInfo_ClassProperty(fClassInfo);
5917 kl->fProperty = gCling->ClassInfo_Property(fClassInfo);
5922 kl->fStreamerType = kExternal;
5923 kl->fStreamerImpl = &TClass::StreamerExternal;
5926 kl->fStreamerType |= kEmulatedStreamer;
5927 kl->SetStreamerImpl();
5941 void TClass::SetRuntimeProperties()
5950 UChar_t properties =
static_cast<UChar_t
>(ERuntimeProperties::kSet);
5952 if (ROOT::Internal::TCheckHashRecursiveRemoveConsistency::Check(*
this))
5953 properties |= static_cast<UChar_t>(ERuntimeProperties::kConsistentHash);
5955 const_cast<TClass *
>(
this)->fRuntimeProperties = properties;
5962 void TClass::SetStreamerImpl()
5964 switch (fStreamerType) {
5965 case kTObject: fStreamerImpl = &TClass::StreamerTObject;
break;
5966 case kForeign: fStreamerImpl = &TClass::StreamerStreamerInfo;
break;
5967 case kExternal: fStreamerImpl = &TClass::StreamerExternal;
break;
5968 case kInstrumented: {
5969 if (fConvStreamerFunc) fStreamerImpl = &TClass::ConvStreamerInstrumented;
5970 else if (fStreamerFunc) fStreamerImpl = &TClass::StreamerInstrumented;
5971 else fStreamerImpl = &TClass::StreamerStreamerInfo;
5975 case kEmulatedStreamer:
5976 case kForeign|kEmulatedStreamer:
5977 case kInstrumented|kEmulatedStreamer: fStreamerImpl = &TClass::StreamerStreamerInfo;
break;
5978 case kExternal|kEmulatedStreamer: fStreamerImpl = &TClass::StreamerExternal;
break;
5979 case kTObject|kEmulatedStreamer: fStreamerImpl = &TClass::StreamerTObjectEmulated;
break;
5980 case TClass::kDefault: fStreamerImpl = &TClass::StreamerDefault;
break;
5982 Error(
"SetStreamerImpl",
"Unexpected value of fStreamerType: %d",fStreamerType);
5991 void TClass::SetCollectionProxy(
const ROOT::Detail::TCollectionProxyInfo &info)
5993 R__LOCKGUARD(gInterpreterMutex);
5995 delete fCollectionProxy;
6001 TVirtualCollectionProxy *p = TVirtualStreamerInfo::Factory()->GenExplicitProxy(info,
this);
6002 fCollectionProxy = p;
6004 AdoptStreamer(TVirtualStreamerInfo::Factory()->GenExplicitClassStreamer(info,
this));
6006 if (fCollectionProxy && !fSchemaRules) {
6008 GetSchemaRules(kTRUE);
6016 void TClass::SetContextMenuTitle(
const char *title)
6018 fContextMenuTitle = title;
6047 void TClass::SetGlobalIsA(IsAGlobalFunc_t func)
6056 void TClass::SetUnloaded()
6058 if (TestBit(kUnloaded) && !TestBit(kUnloading)) {
6065 if (fState != kLoaded) {
6066 Fatal(
"SetUnloaded",
"The TClass for %s is being unloaded when in state %d\n",
6067 GetName(),(
int)fState);
6070 InsertTClassInRegistryRAII insertRAII(fState, fName, fNoInfoOrEmuOrFwdDeclNameRegistry);
6073 fState = kForwardDeclared;
6075 delete fIsA; fIsA = 0;
6079 TInterpreter::SuspendAutoloadingRAII autoloadOff(gInterpreter);
6080 TInterpreter::SuspendAutoParsing autoParseRaii(gCling);
6081 gInterpreter->SetClassInfo(
this,kTRUE);
6089 if (fMethod.load()) {
6090 (*fMethod).Unload();
6095 if (fEnums.load()) {
6099 if (fState <= kForwardDeclared && fStreamerInfo->GetEntries() != 0) {
6103 ResetBit(kUnloading);
6117 TVirtualStreamerInfo *TClass::SetStreamerInfo(Int_t ,
const char * )
6192 //info is empty. Let's build the default Streamer descriptor
6194 char *temp = new char[10000];
6198 //add list of base classes
6199 TIter nextb(GetListOfBases());
6201 while ((base = (TBaseClass*) nextb())) {
6202 snprintf(local,100,"%s;",base->GetName());
6203 strlcat(temp,local,10000);
6206 //add list of data members and types
6207 TIter nextd(GetListOfDataMembers());
6208 while ((dm = (TDataMember *) nextd())) {
6209 if (dm->IsEnum()) continue;
6210 if (!dm->IsPersistent()) continue;
6211 Long_t property = dm->Property();
6212 if (property & kIsStatic) continue;
6213 TClass *acl = TClass::GetClass(dm->GetTypeName(),update);
6216 if (acl->GetClassVersion() == 0) continue;
6219 // dm->GetArrayIndex() returns an empty string if it does not
6221 const char * index = dm->GetArrayIndex();
6222 if (strlen(index)==0)
6223 snprintf(local,100,"%s %s;",dm->GetFullTypeName(),dm->GetName());
6225 snprintf(local,100,"%s %s[%s];",dm->GetFullTypeName(),dm->GetName(),index);
6226 strlcat(temp,local,10000);
6228 //fStreamerInfo = temp;
6238 Bool_t TClass::MatchLegacyCheckSum(UInt_t checksum)
const
6240 for(UInt_t i = 1; i < kLatestCheckSum; ++i) {
6241 if ( checksum == GetCheckSum( (ECheckSum) i ) )
return kTRUE;
6249 UInt_t TClass::GetCheckSum(ECheckSum code)
const
6252 return GetCheckSum(code,isvalid);
6258 UInt_t TClass::GetCheckSum(Bool_t &isvalid)
const
6260 return GetCheckSum(kCurrentCheckSum,isvalid);
6288 UInt_t TClass::GetCheckSum(ECheckSum code, Bool_t &isvalid)
const
6301 UInt_t currentChecksum = fCheckSum.load();
6302 if (currentChecksum && code == kCurrentCheckSum)
return currentChecksum;
6304 R__LOCKGUARD(gInterpreterMutex);
6309 if (code == kCurrentCheckSum) code = kLatestCheckSum;
6314 TString name = GetName();
6317 for (
int i=0; i<il; i++)
id =
id*3+name[i];
6322 TList *tlb = ((TClass*)
this)->GetListOfBases();
6323 if (tlb && !GetCollectionProxy() && strncmp(GetName(),
"pair<", 5)) {
6326 TIter nextBase(tlb);
6329 while((tbc=(TBaseClass*)nextBase())) {
6330 name = tbc->GetName();
6331 Bool_t isSTL = TClassEdit::IsSTLCont(name);
6333 name = TClassEdit::ShortType( name, TClassEdit::kDropStlDefault );
6335 for (
int i=0; i<il; i++)
id =
id*3+name[i];
6336 if (code > kNoBaseCheckSum && !isSTL) {
6337 if (tbc->GetClassPointer() == 0) {
6338 Error(
"GetCheckSum",
"Calculating the checksum for (%s) requires the base class (%s) meta information to be available!",
6339 GetName(),tbc->GetName());
6343 id =
id*3 + tbc->GetClassPointer()->GetCheckSum();
6347 TList *tlm = ((TClass*)
this)->GetListOfDataMembers();
6349 TIter nextMemb(tlm);
6352 while((tdm=(TDataMember*)nextMemb())) {
6353 if (!tdm->IsPersistent())
continue;
6355 prop = (tdm->Property());
6356 TDataType* tdt = tdm->GetDataType();
6357 if (tdt) prop |= tdt->Property();
6359 if ( prop&kIsStatic)
continue;
6360 name = tdm->GetName(); il = name.Length();
6361 if ( (code > kNoEnum) && code != kReflex && code != kReflexNoComment && prop&kIsEnum)
6365 for (i=0; i<il; i++)
id =
id*3+name[i];
6367 if (code > kWithTypeDef || code == kReflexNoComment) {
6368 type = tdm->GetTrueTypeName();
6373 if (code == kReflex || code == kReflexNoComment) {
6377 type.ReplaceAll(
"ULong64_t",
"unsigned long long");
6378 type.ReplaceAll(
"Long64_t",
"long long");
6379 type.ReplaceAll(
"<signed char",
"<char");
6380 type.ReplaceAll(
",signed char",
",char");
6381 if (type==
"signed char") type =
"char";
6385 type = tdm->GetFullTypeName();
6393 for (i=0; i<il; i++)
id =
id*3+type[i];
6395 int dim = tdm->GetArrayDim();
6396 if (prop&kIsArray) {
6397 for (
int ii=0;ii<dim;ii++)
id =
id*3+tdm->GetMaxIndex(ii);
6399 if (code > kNoRange) {
6401 if (code > TClass::kNoRangeCheck)
6402 left = TVirtualStreamerInfo::GetElementCounterStart(tdm->GetTitle());
6404 left = strstr(tdm->GetTitle(),
"[");
6406 const char *right = strstr(left,
"]");
6409 while (left != right) {
6420 if (code==kLatestCheckSum) fCheckSum = id;
6429 void TClass::AdoptReferenceProxy(TVirtualRefProxy* proxy)
6431 R__LOCKGUARD(gInterpreterMutex);
6434 fRefProxy->Release();
6438 fRefProxy->SetClass(
this);
6447 void TClass::AdoptMemberStreamer(
const char *name, TMemberStreamer *p)
6449 if (!fRealData)
return;
6451 R__LOCKGUARD(gInterpreterMutex);
6453 TIter next(fRealData);
6455 while ((rd = (TRealData*)next())) {
6456 if (strcmp(rd->GetName(),name) == 0) {
6459 rd->AdoptStreamer(p);
6485 void TClass::SetMemberStreamer(
const char *name, MemberStreamerFunc_t p)
6487 AdoptMemberStreamer(name,
new TMemberStreamer(p));
6499 Int_t TClass::ReadBuffer(TBuffer &b,
void *pointer, Int_t version, UInt_t start, UInt_t count)
6501 return b.ReadClassBuffer(
this,pointer,version,start,count);
6508 Int_t TClass::ReadBuffer(TBuffer &b,
void *pointer)
6510 return b.ReadClassBuffer(
this,pointer);
6520 Int_t TClass::WriteBuffer(TBuffer &b,
void *pointer,
const char * )
6522 b.WriteClassBuffer(
this,pointer);
6529 void TClass::StreamerExternal(
const TClass* pThis,
void *
object, TBuffer &b,
const TClass *onfile_class)
6534 TClassStreamer *streamer = gThreadTsd ? pThis->GetStreamer() : pThis->fStreamer;
6535 streamer->Stream(b,
object,onfile_class);
6541 void TClass::StreamerTObject(
const TClass* pThis,
void *
object, TBuffer &b,
const TClass * )
6545 if (!pThis->fIsOffsetStreamerSet) {
6546 pThis->CalculateStreamerOffset();
6548 TObject *tobj = (TObject*)((Long_t)
object + pThis->fOffsetStreamer);
6555 void TClass::StreamerTObjectInitialized(
const TClass* pThis,
void *
object, TBuffer &b,
const TClass * )
6557 TObject *tobj = (TObject*)((Long_t)
object + pThis->fOffsetStreamer);
6564 void TClass::StreamerTObjectEmulated(
const TClass* pThis,
void *
object, TBuffer &b,
const TClass *onfile_class)
6567 if (b.IsReading()) {
6568 b.ReadClassEmulated(pThis,
object, onfile_class);
6570 b.WriteClassBuffer(pThis,
object);
6577 void TClass::StreamerInstrumented(
const TClass* pThis,
void *
object, TBuffer &b,
const TClass * )
6580 pThis->fStreamerFunc(b,
object);
6586 void TClass::ConvStreamerInstrumented(
const TClass* pThis,
void *
object, TBuffer &b,
const TClass *onfile_class)
6589 pThis->fConvStreamerFunc(b,
object,onfile_class);
6599 void TClass::StreamerStreamerInfo(
const TClass* pThis,
void *
object, TBuffer &b,
const TClass *onfile_class)
6601 if (b.IsReading()) {
6602 b.ReadClassBuffer(pThis,
object, onfile_class);
6606 b.WriteClassBuffer(pThis,
object);
6614 void TClass::StreamerDefault(
const TClass* pThis,
void *
object, TBuffer &b,
const TClass *onfile_class)
6616 if (pThis->fProperty==(-1)) {
6624 if (pThis->fStreamerImpl.load() == &TClass::StreamerDefault) {
6625 pThis->Fatal(
"StreamerDefault",
"fStreamerImpl not properly initialized (%d)", pThis->fStreamerType);
6627 (*pThis->fStreamerImpl)(pThis,
object,b,onfile_class);
6635 void TClass::AdoptStreamer(TClassStreamer *str)
6641 R__LOCKGUARD(gInterpreterMutex);
6643 if (fStreamer)
delete fStreamer;
6645 fStreamerType = kExternal | ( fStreamerType&kEmulatedStreamer );
6647 fStreamerImpl = &TClass::StreamerExternal;
6648 }
else if (fStreamer) {
6652 fStreamerType = TClass::kDefault;
6653 if (fProperty != -1) {
6663 void TClass::SetStreamerFunc(ClassStreamerFunc_t strm)
6665 R__LOCKGUARD(gInterpreterMutex);
6666 if (fProperty != -1 && !fConvStreamerFunc &&
6667 ( (fStreamerFunc == 0 && strm != 0) || (fStreamerFunc != 0 && strm == 0) ) )
6669 fStreamerFunc = strm;
6673 if (HasInterpreterInfo() && fStreamerType != kTObject && !fStreamer) {
6674 fStreamerType = kInstrumented;
6675 fStreamerImpl = &TClass::StreamerInstrumented;
6678 fStreamerFunc = strm;
6686 void TClass::SetConvStreamerFunc(ClassConvStreamerFunc_t strm)
6688 R__LOCKGUARD(gInterpreterMutex);
6689 if (fProperty != -1 &&
6690 ( (fConvStreamerFunc == 0 && strm != 0) || (fConvStreamerFunc != 0 && strm == 0) ) )
6692 fConvStreamerFunc = strm;
6696 if (HasInterpreterInfo() && fStreamerType != kTObject && !fStreamer) {
6697 fStreamerType = kInstrumented;
6698 fStreamerImpl = &TClass::ConvStreamerInstrumented;
6701 fConvStreamerFunc = strm;
6710 void TClass::SetMerge(ROOT::MergeFunc_t newMerge)
6718 void TClass::SetResetAfterMerge(ROOT::ResetAfterMergeFunc_t newReset)
6720 fResetAfterMerge = newReset;
6726 void TClass::SetNew(ROOT::NewFunc_t newFunc)
6734 void TClass::SetNewArray(ROOT::NewArrFunc_t newArrayFunc)
6736 fNewArray = newArrayFunc;
6742 void TClass::SetDelete(ROOT::DelFunc_t deleteFunc)
6744 fDelete = deleteFunc;
6750 void TClass::SetDeleteArray(ROOT::DelArrFunc_t deleteArrayFunc)
6752 fDeleteArray = deleteArrayFunc;
6758 void TClass::SetDestructor(ROOT::DesFunc_t destructorFunc)
6760 fDestructor = destructorFunc;
6769 void TClass::SetDirectoryAutoAdd(ROOT::DirAutoAdd_t autoAddFunc)
6771 fDirAutoAdd = autoAddFunc;
6777 TVirtualStreamerInfo *TClass::FindStreamerInfo(UInt_t checksum)
const
6779 TVirtualStreamerInfo *guess = fLastReadInfo;
6780 if (guess && guess->GetCheckSum() == checksum) {
6783 if (fCheckSum == checksum)
return GetStreamerInfo();
6785 R__LOCKGUARD(gInterpreterMutex);
6786 Int_t ninfos = fStreamerInfo->GetEntriesFast()-1;
6787 for (Int_t i=-1;i<ninfos;++i) {
6790 TVirtualStreamerInfo *info = (TVirtualStreamerInfo*)fStreamerInfo->UncheckedAt(i);
6791 if (info && info->GetCheckSum() == checksum) {
6794 if (info->IsCompiled()) fLastReadInfo = info;
6805 TVirtualStreamerInfo *TClass::FindStreamerInfo(TObjArray* arr, UInt_t checksum)
const
6807 R__LOCKGUARD(gInterpreterMutex);
6808 Int_t ninfos = arr->GetEntriesFast()-1;
6809 for (Int_t i=-1;i<ninfos;i++) {
6812 TVirtualStreamerInfo *info = (TVirtualStreamerInfo*)arr->UncheckedAt(i);
6813 if (!info)
continue;
6814 if (info->GetCheckSum() == checksum) {
6815 R__ASSERT(i==info->GetClassVersion() || (i==-1&&info->GetClassVersion()==1));
6825 TVirtualStreamerInfo *TClass::GetConversionStreamerInfo(
const char* classname, Int_t version )
const
6827 TClass *cl = TClass::GetClass( classname );
6830 return GetConversionStreamerInfo( cl, version );
6836 TVirtualStreamerInfo *TClass::GetConversionStreamerInfo(
const TClass* cl, Int_t version )
const
6846 return GetStreamerInfo( version );
6853 if (fConversionStreamerInfo.load()) {
6854 std::map<std::string, TObjArray*>::iterator it;
6855 R__LOCKGUARD(gInterpreterMutex);
6857 it = (*fConversionStreamerInfo).find( cl->GetName() );
6859 if( it != (*fConversionStreamerInfo).end() ) {
6863 if( arr && version > -1 && version < arr->GetSize() && arr->At( version ) )
6864 return (TVirtualStreamerInfo*) arr->At( version );
6867 R__LOCKGUARD(gInterpreterMutex);
6873 const TObjArray *clSI = cl->GetStreamerInfos();
6874 TVirtualStreamerInfo* info = 0;
6875 if( version >= -1 && version < clSI->GetSize() )
6876 info = (TVirtualStreamerInfo*)clSI->At( version );
6878 if (!info && cl->GetCollectionProxy()) {
6879 info = cl->GetStreamerInfo();
6890 info = (TVirtualStreamerInfo*)info->Clone();
6892 if( !info->BuildFor(
this ) ) {
6897 if (!info->IsCompiled()) {
6909 arr =
new TObjArray(version+10, -1);
6910 if (!fConversionStreamerInfo.load()) {
6911 fConversionStreamerInfo =
new std::map<std::string, TObjArray*>();
6913 (*fConversionStreamerInfo)[cl->GetName()] = arr;
6915 arr->AddAtAndExpand( info, info->GetClassVersion() );
6922 TVirtualStreamerInfo *TClass::FindConversionStreamerInfo(
const char* classname, UInt_t checksum )
const
6924 TClass *cl = TClass::GetClass( classname );
6927 return FindConversionStreamerInfo( cl, checksum );
6933 TVirtualStreamerInfo *TClass::FindConversionStreamerInfo(
const TClass* cl, UInt_t checksum )
const
6943 return FindStreamerInfo( checksum );
6950 TVirtualStreamerInfo* info = 0;
6951 if (fConversionStreamerInfo.load()) {
6952 std::map<std::string, TObjArray*>::iterator it;
6954 R__LOCKGUARD(gInterpreterMutex);
6956 it = (*fConversionStreamerInfo).find( cl->GetName() );
6958 if( it != (*fConversionStreamerInfo).end() ) {
6962 info = FindStreamerInfo( arr, checksum );
6969 R__LOCKGUARD(gInterpreterMutex);
6975 info = cl->FindStreamerInfo( checksum );
6985 info = (TVirtualStreamerInfo*)info->Clone();
6986 if( !info->BuildFor(
this ) ) {
6991 if (!info->IsCompiled()) {
7003 arr =
new TObjArray(16, -2);
7004 if (!fConversionStreamerInfo.load()) {
7005 fConversionStreamerInfo =
new std::map<std::string, TObjArray*>();
7007 (*fConversionStreamerInfo)[cl->GetName()] = arr;
7009 arr->AddAtAndExpand( info, info->GetClassVersion() );
7018 void TClass::RegisterStreamerInfo(TVirtualStreamerInfo *info)
7021 R__LOCKGUARD(gInterpreterMutex);
7022 Int_t slot = info->GetClassVersion();
7023 if (fStreamerInfo->GetSize() > (slot-fStreamerInfo->LowerBound())
7024 && fStreamerInfo->At(slot) != 0
7025 && fStreamerInfo->At(slot) != info) {
7026 Error(
"RegisterStreamerInfo",
7027 "Register StreamerInfo for %s on non-empty slot (%d).",
7030 fStreamerInfo->AddAtAndExpand(info, slot);
7031 if (fState <= kForwardDeclared) {
7033 if (fCheckSum==0 && slot==fClassVersion) fCheckSum = info->GetCheckSum();
7042 void TClass::RemoveStreamerInfo(Int_t slot)
7044 if (fStreamerInfo->GetSize() >= slot) {
7045 R__LOCKGUARD(gInterpreterMutex);
7046 TVirtualStreamerInfo *info = (TVirtualStreamerInfo*)fStreamerInfo->At(slot);
7047 fStreamerInfo->RemoveAt(fClassVersion);
7049 if (fState == kEmulated && fStreamerInfo->GetEntries() == 0) {
7050 fState = kForwardDeclared;
7063 Bool_t ROOT::Internal::HasConsistentHashMember(
const char *cname)
7067 static const char *handVerified[] = {
7068 "TEnvRec",
"TDataType",
"TObjArray",
"TList",
"THashList",
7069 "TClass",
"TCling",
"TInterpreter",
"TMethod",
"ROOT::Internal::TCheckHashRecursiveRemoveConsistency",
7070 "TCheckHashRecursiveRemoveConsistency",
"TGWindow",
7071 "TDirectory",
"TDirectoryFile",
"TObject",
"TH1",
7072 "TQClass",
"TGlobal" };
7074 if (cname && cname[0]) {
7075 for (
auto cursor : handVerified) {
7076 if (strcmp(cname, cursor) == 0)
7089 Bool_t ROOT::Internal::HasConsistentHashMember(TClass &clRef)
7091 return clRef.HasConsistentHashMember();
7111 Bool_t TClass::HasDefaultConstructor()
const
7114 if (fNew)
return kTRUE;
7116 if (HasInterpreterInfo()) {
7117 R__LOCKGUARD(gInterpreterMutex);
7118 return gCling->ClassInfo_HasDefaultConstructor(GetClassInfo());
7120 if (fCollectionProxy) {
7123 if (fCurrentInfo.load()) {
7139 Bool_t TClass::HasLocalHashMember()
const
7141 if (fProperty == (-1))
7143 return TestBit(kHasLocalHashMember);
7149 ROOT::MergeFunc_t TClass::GetMerge()
const
7157 ROOT::ResetAfterMergeFunc_t TClass::GetResetAfterMerge()
const
7159 return fResetAfterMerge;
7165 ROOT::NewFunc_t TClass::GetNew()
const
7173 ROOT::NewArrFunc_t TClass::GetNewArray()
const
7181 ROOT::DelFunc_t TClass::GetDelete()
const
7189 ROOT::DelArrFunc_t TClass::GetDeleteArray()
const
7191 return fDeleteArray;
7197 ROOT::DesFunc_t TClass::GetDestructor()
const
7205 ROOT::DirAutoAdd_t TClass::GetDirectoryAutoAdd()
const