35 TProtoClass::TProtoClass(TClass* cl):
36 TNamed(*cl), fBase(cl->GetListOfBases()),
37 fEnums(cl->GetListOfEnums()), fSizeof(cl->Size()), fCheckSum(cl->fCheckSum),
38 fCanSplit(cl->fCanSplit), fStreamerType(cl->fStreamerType), fProperty(cl->fProperty),
39 fClassProperty(cl->fClassProperty)
41 if (cl->Property() & kIsNamespace){
48 TListOfEnums *enums =
dynamic_cast<TListOfEnums*
>(fEnums);
49 if (enums && !enums->fIsLoaded) {
54 TList * dataMembers = cl->GetListOfDataMembers();
55 if (dataMembers && dataMembers->GetSize() > 0) {
56 fData.reserve(dataMembers->GetSize() );
57 for (
auto * obj : *dataMembers) {
58 TDataMember * dm =
dynamic_cast<TDataMember*
>(obj);
63 fPRealData.reserve(100);
65 if (!cl->GetCollectionProxy()) {
67 cl->BuildRealData(0,
true );
73 TClass* clCurrent = cl;
74 fDepClasses.push_back(cl->GetName() );
75 TRealData* precRd =
nullptr;
76 for (
auto realDataObj: *cl->GetListOfRealData()) {
77 TRealData *rd = (TRealData*)realDataObj;
78 if (!precRd) precRd = rd;
79 TClass* clRD = rd->GetDataMember()->GetClass();
80 TProtoRealData protoRealData(rd);
81 if (clRD != clCurrent) {
83 fDepClasses.push_back(clRD->GetName() );
85 protoRealData.fClassIndex = fDepClasses.size()-1;
88 if (rd->TestBit(TRealData::kTransient)) {
90 protoRealData.SetFlag(TProtoRealData::kIsTransient,
true);
93 protoRealData.SetFlag(TProtoRealData::kIsTransient,
false);
99 fPRealData.push_back(protoRealData);
120 cl->CalculateStreamerOffset();
121 fOffsetStreamer = cl->fOffsetStreamer;
180 TProtoClass::~TProtoClass()
190 void TProtoClass::Delete(Option_t* opt ) {
191 if (fBase) fBase->Delete(opt);
192 delete fBase; fBase = 0;
194 for (
auto dm: fData) {
198 if (fEnums) fEnums->Delete(opt);
199 delete fEnums; fEnums = 0;
201 if (gErrorIgnoreLevel==-2) printf(
"Delete the protoClass %s \n",GetName());
210 Bool_t TProtoClass::FillTClass(TClass* cl) {
211 if (cl->fRealData || cl->fBase.load() || cl->fData || cl->fEnums.load() || cl->fSizeof != -1 || cl->fCanSplit >= 0 ||
212 cl->fProperty != (-1)) {
214 if (cl->GetCollectionType() != ROOT::kNotSTL) {
222 Info(
"FillTClass",
"Returning w/o doing anything. %s is a STL collection.",cl->GetName());
225 if (cl->Property() & kIsNamespace) {
227 Info(
"FillTClass",
"Returning w/o doing anything. %s is a namespace.",cl->GetName());
230 Error(
"FillTClass",
"TClass %s already initialized!", cl->GetName());
233 if (gDebug > 1) Info(
"FillTClass",
"Loading TProtoClass for %s - %s",cl->GetName(),GetName());
235 if (fPRealData.size() > 0) {
242 for (
auto element: fPRealData) {
244 if (element.IsAClass() ) {
245 if (gDebug > 1) Info(
"",
"Treating beforehand mother class %s",GetClassName(element.fClassIndex));
246 TInterpreter::SuspendAutoParsing autoParseRaii(gInterpreter);
248 TClass::GetClass(GetClassName(element.fClassIndex));
258 UInt_t newbits = TestBits(0x00ffc000);
259 cl->ResetBit(0x00ffc000);
262 cl->fName = this->fName;
263 cl->fTitle = this->fTitle;
268 cl->fData =
new TListOfDataMembers(fData);
284 auto temp =
new TListOfEnums();
286 for (TObject* enumAsTObj : *fEnums){
287 temp->Add((TEnum*) enumAsTObj);
297 cl->fSizeof = fSizeof;
298 cl->fCheckSum = fCheckSum;
299 cl->fCanSplit = fCanSplit;
300 cl->fProperty = fProperty;
301 cl->fClassProperty = fClassProperty;
302 cl->fStreamerType = fStreamerType;
305 if (cl->fBase.load()) {
306 for (
auto base: *cl->fBase) {
307 ((TBaseClass*)base)->SetClass(cl);
311 for (
auto dm: *cl->fData) {
312 ((TDataMember*)dm)->SetClass(cl);
314 ((TListOfDataMembers*)cl->fData)->SetClass(cl);
316 if (cl->fEnums.load()) {
317 for (
auto en: *cl->fEnums) {
318 ((TEnum*)en)->SetClass(cl);
320 ((TListOfEnums*)cl->fEnums)->SetClass(cl);
324 TClass* currentRDClass = cl;
325 TRealData * prevRealData = 0;
328 if (fPRealData.size() > 0) {
329 for (
auto element: fPRealData) {
331 if (element.IsAClass() ) {
337 TInterpreter::SuspendAutoParsing autoParseRaii(gInterpreter);
341 currentRDClass = TClass::GetClass(GetClassName(element.fClassIndex),
false );
343 if (!currentRDClass && !element.TestFlag(TProtoRealData::kIsTransient)) {
346 "Cannot find TClass for %s; Creating an empty one in the kForwardDeclared state.",
347 GetClassName(element.fClassIndex));
348 currentRDClass =
new TClass(GetClassName(element.fClassIndex),1,TClass::kForwardDeclared,
true );
352 if (!currentRDClass)
continue;
356 if (TRealData* rd = element.CreateRealData(currentRDClass, cl,prevRealData, prevLevel)) {
360 Info(
"FillTClass",
"Real data for class %s is not empty - make a new one",cl->GetName() );
361 delete cl->fRealData;
363 cl->fRealData =
new TList();
367 cl->fRealData->AddLast(rd);
369 prevLevel = element.fLevel;
377 Info(
"FillTClas",
"Real data for class %s is not empty - make a new one. Class has no Proto-realdata",cl->GetName() );
378 delete cl->fRealData;
380 cl->fRealData =
new TList();
383 cl->SetStreamerImpl();
391 fPRealData.shrink_to_fit();
402 TProtoClass::TProtoRealData::TProtoRealData(
const TRealData* rd):
407 fOffset(rd->GetThisOffset()),
413 TDataMember * dm = rd->GetDataMember();
414 TClass * cl = dm->GetClass();
416 fDMIndex = DataMemberIndex(cl,dm->GetName());
418 TString fullDataMemberName = rd->GetName();
419 fLevel = fullDataMemberName.CountChar(
'.');
421 if (fullDataMemberName.Contains(
"*") ) SetFlag(kIsPointer);
424 SetFlag(kIsObject, rd->IsObject());
425 SetFlag(kIsTransient, rd->TestBit(TRealData::kTransient) );
432 TProtoClass::TProtoRealData::~TProtoRealData()
440 TRealData* TProtoClass::TProtoRealData::CreateRealData(TClass* dmClass,
441 TClass* parent, TRealData *prevData,
int prevLevel)
const
445 TDataMember* dm = TProtoClass::FindDataMember(dmClass, fDMIndex);
447 if (!dm && dmClass->GetState()!=TClass::kForwardDeclared) {
448 ::Error(
"CreateRealData",
449 "Cannot find data member # %d of class %s for parent %s!", fDMIndex, dmClass->GetName(),
456 TString realMemberName;
458 if (dm) realMemberName = dm->GetName();
459 if (TestFlag(kIsPointer) )
460 realMemberName = TString(
"*")+realMemberName;
462 if (dm->GetArrayDim() > 0) {
465 for (
int idim = 0; idim < dm->GetArrayDim(); ++idim)
466 realMemberName += TString::Format(
"[%d]",dm->GetMaxIndex(idim) );
467 }
else if (TClassEdit::IsStdArray(dm->GetTypeName())) {
468 std::string typeNameBuf;
469 Int_t ndim = dm->GetArrayDim();
470 std::array<Int_t, 5> maxIndices;
471 TClassEdit::GetStdArrayProperties(dm->GetTypeName(),
475 for (Int_t idim = 0; idim < ndim; ++idim) {
476 realMemberName += TString::Format(
"[%d]",maxIndices[idim] );
481 if (prevData && fLevel > 0 ) {
482 if (fLevel-prevLevel == 1)
483 realMemberName = TString::Format(
"%s.%s",prevData->GetName(), realMemberName.Data() );
484 else if (fLevel <= prevLevel) {
486 std::string prevName = prevData->GetName();
488 std::string parentName;
489 for (
int i = 0; i < prevLevel-fLevel+1; ++i) {
490 parentName = prevName.substr(0, prevName.find_last_of(
".") );
491 prevName = parentName;
495 realMemberName = TString::Format(
"%s.%s",parentName.c_str(), realMemberName.Data() );
501 TRealData* rd =
new TRealData(realMemberName, fOffset, dm);
502 if (TestFlag(kIsTransient)) {
503 rd->SetBit(TRealData::kTransient);
505 rd->SetIsObject(TestFlag(kIsObject) );
511 Int_t TProtoClass::DataMemberIndex(TClass * cl,
const char * name)
513 TList * dmList = cl->GetListOfDataMembers();
517 for (
auto * obj : *dmList) {
518 TDataMember * dm = (TDataMember *) obj;
520 if (dm->Property() & kIsStatic)
continue;
521 if ( TString(dm->GetName()) == TString(name) )
525 ::Error(
"TProtoClass::DataMemberIndex",
"data member %s is not found in class %s",name, cl->GetName());
531 TDataMember * TProtoClass::FindDataMember(TClass * cl, Int_t index)
533 TList * dmList = cl->GetListOfDataMembers(
false);
537 for (
auto * obj : *dmList) {
538 TDataMember * dm = (TDataMember *) obj;
540 if (dm->Property() & kIsStatic)
continue;
545 if (cl->GetState()!=TClass::kForwardDeclared)
546 ::Error(
"TProtoClass::FindDataMember",
"data member with index %d is not found in class %s",index,cl->GetName());