ATLAS Offline Software
RootType.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
7 
8 // ROOT
9 #include "TBaseClass.h"
10 #include "TClass.h"
11 #include "TClassEdit.h"
12 #include "TClassTable.h"
13 #include "TDataType.h"
14 #include "TDataMember.h"
15 #include "TDictAttributeMap.h"
16 #include "TError.h"
17 #include "TFunction.h"
18 #include "TInterpreter.h"
19 #include "TMethod.h"
20 #include "TMethodArg.h"
21 #include "TROOT.h"
22 #include "TEnum.h"
23 
24 // Standard
25 #include <assert.h>
26 #include <cxxabi.h>
27 #include <iostream>
28 using namespace std;
29 
30 
31 //= helpers ==================================================================
32 static const std::string ResolveTypedef( const std::string& tname )
33 {
34 // Helper; captures common code needed to find the real class name underlying
35 // a typedef (if any).
36  std::string tclean;
37  {
38  // Protect against data race inside TClassEdit.
39  // https://github.com/root-project/root/issues/10353
40  // Should be fixed in root 6.26.02.
41  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
42  tclean = TClassEdit::CleanType( tname.c_str() );
43  }
44 
45  TDataType* dt = gROOT->GetType( tclean.c_str() );
46  if ( dt ) return dt->GetFullTypeName();
47 
48  // Protect against data race inside TClassEdit.
49  // https://github.com/root-project/root/issues/10353
50  // Should be fixed in root 6.26.02.
51  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
52  return TClassEdit::ResolveTypedef( tclean.c_str(), true );
53 }
54 
55 static inline const std::string UnqualifiedTypeName( const std::string& name )
56 {
57  // Protect against data race inside TClassEdit.
58  // https://github.com/root-project/root/issues/10353
59  // Should be fixed in root 6.26.02.
60  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
61  return TClassEdit::ShortType(
62  TClassEdit::CleanType( name.c_str(), 1 ).c_str(), 5 );
63 }
64 
65 
66 //= TPropertListAdapter ======================================================
67 static std::string map_property( const std::string& key )
68 {
69  if ( key == "ClassID" ) return "id";
70  return key;
71 }
72 
73 //____________________________________________________________________________
74 Bool_t TPropertyListAdapter::HasProperty( const std::string& key ) const
75 {
76  if ( fAttributes )
77  return fAttributes->HasKey( map_property( key ).c_str() );
78  return kFALSE;
79 }
80 
81 
82 //____________________________________________________________________________
83 std::string TPropertyListAdapter::PropertyAsString( const std::string& key ) const
84 {
85  if ( fAttributes )
86  return fAttributes->GetPropertyAsString( map_property( key ).c_str() );
87  return "";
88 }
89 
90 
91 //= TReturnTypeAdapter =======================================================
92 std::string TReturnTypeAdapter::Name( unsigned int mod ) const
93 {
94 // get the name of the return type that is being adapted
95  std::string name = fName;
96 
97  if ( mod & Reflex::FINAL )
98  name = ResolveTypedef( name );
99 
100  if ( ! ( mod & Reflex::QUALIFIED ) )
101  name = UnqualifiedTypeName( fName );
102 
103  return name;
104 }
105 
106 
107 //= TMemberAdapter ===========================================================
108 TMemberAdapter::TMemberAdapter( TMethod* meth ) : fMember( meth )
109 {
110  /* empty */
111 }
112 
113 //____________________________________________________________________________
114 TMemberAdapter::operator TMethod*() const
115 {
116 // cast the adapter to a TMethod* being adapted, returns 0 on failure
117  return dynamic_cast< TMethod* >( const_cast< TDictionary* >( fMember ) );
118 }
119 
120 //____________________________________________________________________________
121 TMemberAdapter::TMemberAdapter( TFunction* func ) : fMember( func )
122 {
123  /* empty */
124 }
125 
126 //____________________________________________________________________________
127 TMemberAdapter::operator TFunction*() const
128 {
129 // cast the adapter to a TFunction* being adapted, returns 0 on failure
130  return dynamic_cast< TFunction* >( const_cast< TDictionary* >( fMember ) );
131 }
132 
133 //____________________________________________________________________________
134 TMemberAdapter::TMemberAdapter( TDataMember* mb ) : fMember( mb )
135 {
136  /* empty */
137 }
138 
139 //____________________________________________________________________________
140 TMemberAdapter::operator TDataMember*() const
141 {
142 // cast the adapter to a TDataMember* being adapted, returns 0 on failure
143  return dynamic_cast< TDataMember* >( const_cast< TDictionary* >( fMember ) );
144 }
145 
146 //____________________________________________________________________________
147 TMemberAdapter::TMemberAdapter( TMethodArg* ma ) : fMember( ma )
148 {
149  /* empty */
150 }
151 
152 //____________________________________________________________________________
153 TMemberAdapter::operator TMethodArg*() const
154 {
155 // cast the adapter to a TMethodArg* being adapted, returns 0 on failure
156  return dynamic_cast< TMethodArg* >( const_cast< TDictionary* >( fMember ) );
157 }
158 
159 //____________________________________________________________________________
161 {
162  // get the type of the data member
163  TDataMember* dataMember = (TDataMember*)*this;
164  if ( dataMember ) {
165  // MN: the only way to get the type is through the type name
166  TClass *tc = TClass::GetClass( dataMember->GetTypeName() );
167  //cout << "--- TMemberAdapter name=" << Name() << endl;
168  if( tc ) {
169  //cout << " type = " << tc->GetName() << endl;
170  return TTypeAdapter(tc);
171  } else {
172  //cout << " typename = " << dataMember->GetTypeName() << endl;
173  return TTypeAdapter(dataMember->GetTypeName());
174  }
175  }
176 
177  // get type of the function/method
178  TMethod* method = (TMethod*)*this;
179  if ( method )
180  return method->GetClass();
181 
182  return TTypeAdapter();
183 }
184 
185 
186 //____________________________________________________________________________
187 std::string TMemberAdapter::Name( unsigned int mod ) const
188 {
189 // return name of the type described by fMember
190  TMethodArg* arg = (TMethodArg*)*this;
191 
192  if ( arg ) {
193 
194  std::string name = arg->GetTypeNormalizedName();
195  if ( mod & Reflex::FINAL )
196  name = ResolveTypedef( name );
197 
198  if ( ! ( mod & Reflex::QUALIFIED ) )
199  name = UnqualifiedTypeName( name );
200 
201  return name;
202 
203  } else if ( mod & Reflex::FINAL )
204  return ResolveTypedef( fMember->GetName() );
205 
206  if ( fMember )
207  return fMember->GetName();
208  return "<unknown>"; // happens for classes w/o dictionary
209 }
210 
211 //____________________________________________________________________________
212 const char* TMemberAdapter::GetSharedLibs() const
213 {
214 // return the shared libs corresponding to this classes (should be 'lib'?)
215  return gInterpreter->GetClassSharedLibs( Name().c_str() );
216 }
217 
218 //____________________________________________________________________________
220 {
221 // relative offset (instance data) or global pointer (static/global data
222  TDataMember* dm = (TDataMember*)*this;
223  return dm ? dm->GetOffsetCint() : 0;
224 }
225 
226 //____________________________________________________________________________
228 {
229 // test if the adapted member is a const method
230  return fMember->Property() & kIsConstMethod;
231 }
232 
233 //____________________________________________________________________________
235 {
236 // test if the adapted member is a const method
237  return ((TFunction*)fMember) ? (((TFunction*)fMember)->ExtraProperty() & kIsConstructor) : kFALSE;
238 }
239 
240 //____________________________________________________________________________
242 {
243 // test if the adapted member is of an enum type
244  return fMember->Property() & kIsEnum;
245 }
246 
247 //____________________________________________________________________________
249 {
250 // test if the adapted member represents an public (data) member
251  return fMember->Property() & kIsPublic;
252 }
253 
254 //____________________________________________________________________________
256 {
257 // test if the adapted member represents a class (data) member
258  return fMember->Property() & kIsStatic;
259 }
260 
261 //____________________________________________________________________________
263 {
264 // test if the adapted member represents transient data
265  TDataMember* dm = (TDataMember*)*this;
266  return dm ? ! dm->IsPersistent() : kTRUE;
267 }
268 
269 
270 //____________________________________________________________________________
272 {
273 // get the total number of parameters that the adapted function/method takes
274  TFunction* func = (TFunction*)fMember;
275  if ( ! func )
276  return 0;
277 
278  if ( required == true )
279  return func->GetNargs() - func->GetNargsOpt();
280 
281  return func->GetNargs();
282 }
283 
284 //____________________________________________________________________________
286 {
287 // get the type info of the function parameter at position nth
288  return (TMethodArg*)((TFunction*)fMember)->GetListOfMethodArgs()->At( nth );
289 }
290 
291 //____________________________________________________________________________
293 {
294 // get the formal name, if available, of the function parameter at position nth
295  const char* name =
296  ((TMethodArg*)((TFunction*)fMember)->GetListOfMethodArgs()->At( nth ))->GetName();
297 
298  if ( name )
299  return name;
300  return "";
301 }
302 
303 //____________________________________________________________________________
305 {
306 // get the default value, if available, of the function parameter at position nth
307  TMethodArg* arg = (TMethodArg*)((TFunction*)fMember)->GetListOfMethodArgs()->At( nth );
308  const char* def = arg->GetDefault();
309 
310  if ( ! def )
311  return "";
312 
313 // special case for strings: "some value" -> ""some value"
314  if ( strstr( ResolveTypedef( arg->GetTypeNormalizedName() ).c_str(), "char*" ) ) {
315  std::string sdef = "\"";
316  sdef += def;
317  sdef += "\"";
318  return sdef;
319  }
320 
321  return def;
322 }
323 
324 //____________________________________________________________________________
326 {
327 // get the return type of the wrapped function/method
328  return TReturnTypeAdapter( ((TFunction*)fMember)->GetReturnTypeNormalizedName() );
329 }
330 
331 //____________________________________________________________________________
332 TScopeAdapter TMemberAdapter::DeclaringScope() const
333 {
334 // get the declaring scope (class) of the wrapped function/method
335  TMethod* method = (TMethod*)*this;
336  if ( method )
337  return method->GetClass();
338 
339 // get the declaring scope (class) of the wrapped data member
340  TDataMember* dataMember = (TDataMember*)*this;
341  if ( dataMember )
342  return dataMember->GetClass();
343 
344 // happens for free-standing functions (i.e. global scope)
345  return std::string( "" );
346 }
347 
348 TTypeAdapter TMemberAdapter::DeclaringType ATLAS_NOT_THREAD_SAFE () const
349 {
350 // no distinction between scope/type
351  return DeclaringScope();
352 }
353 
354 
355 //= TBaseAdapter =============================================================
356 std::string TBaseAdapter::Name() const
357 {
358 // get the name of the base class that is being adapted
359  return fBase->GetName();
360 }
361 
362 //____________________________________________________________________________
363 TScopeAdapter TBaseAdapter::ToType ATLAS_NOT_THREAD_SAFE () const
364 {
365 // wrap the actual class representing this base
366  return TScopeAdapter( fBase->GetClassPointer() );
367 }
368 
369 
370 //= TScopeAdapter ============================================================
371 //============================================================================
373 {
374  /* empty */
375 }
376 
378 {
379 // wrap a class (scope)
380  if ( fClass.GetClass() != 0 )
381  fName = fClass->GetName();
382 }
383 
384 
385 bool is_fundamental_type(const std::string& name)
386 {
387  const char* typname = name.c_str();
388  switch(typname[0]) {
389  case 'b':
390  if ( strcmp(typname,"bool") ==0 ) return true;
391  break;
392  case 'c':
393  if ( strcmp(typname,"char") ==0 ) return true;
394  break;
395  case 'l':
396  if ( strncmp(typname,"lib",3) ==0 ) return true;
397  if ( strcmp(typname,"long") ==0 ) return true;
398  if ( strcmp(typname,"long long") ==0 ) return true;
399  if ( strcmp(typname,"long long int") ==0 ) return true;
400  break;
401  case 'L':
402  if ( strcmp(typname,"Long_t") ==0 ) return true;
403  if ( strcmp(typname,"Long64_t") ==0 ) return true;
404  break;
405  case 'i':
406  if ( strcmp(typname,"int") ==0 ) return true;
407  if ( strcmp(typname,"__int64") ==0 ) return true;
408  break;
409  case 'I':
410  if ( strcmp(typname,"Int_t") ==0 ) return true;
411  break;
412  case 'e':
413  if ( strncmp(typname,"enum ",5) ==0 ) return true;
414  break;
415  case 'd':
416  if ( strcmp(typname,"double") ==0 ) return true;
417  break;
418  case 'D':
419  if ( strcmp(typname,"Double_t") ==0 ) return true;
420  break;
421  case 'f':
422  if ( strcmp(typname,"float") ==0 ) return true;
423  break;
424  case 'F':
425  if ( strcmp(typname,"Float_t") ==0 ) return true;
426  break;
427  case 's':
428  if( strcmp(typname,"short") ==0 ) return true;
429  if( strcmp(typname,"short int") ==0 ) return true;
430  break;
431  case 'S':
432  if ( strcmp(typname,"Short_t") ==0 ) return true;
433  break;
434  case 'u':
435  if ( strncmp(typname,"unknown",7) ==0 ) return true;
436  if ( strcmp(typname,"unsigned int") ==0 ) return true;
437  if ( strcmp(typname,"unsigned short") ==0 ) return true;
438  if ( strcmp(typname,"unsigned long") ==0 ) return true;
439  if ( strcmp(typname,"unsigned char") ==0 ) return true;
440  if ( strcmp(typname,"unsigned long long") ==0 ) return true;
441  if ( strcmp(typname,"unsigned long long int") ==0 ) return true;
442  break;
443  }
444  return false;
445 }
446 
447 
448 const std::type_info& fundamental_type(const std::string& name)
449 {
450  const char* typname = name.c_str();
451  switch(typname[0]) {
452  case 'b':
453  if ( strcmp(typname,"bool") ==0 ) return typeid(bool);
454  break;
455  case 'c':
456  if ( strcmp(typname,"char") ==0 ) return typeid(char);
457  break;
458  case 'l':
459  if ( strcmp(typname,"long") ==0 ) return typeid(long);
460  if ( strcmp(typname,"long long") ==0 ) return typeid(long long);
461  if ( strcmp(typname,"long long int") ==0 ) return typeid(long long int);
462  break;
463  case 'i':
464  if ( strcmp(typname,"int") ==0 ) return typeid(int);
465  break;
466  case 'd':
467  if ( strcmp(typname,"double") ==0 ) return typeid(double);
468  break;
469  case 'f':
470  if ( strcmp(typname,"float") ==0 ) return typeid(float);
471  break;
472  case 's':
473  if( strcmp(typname,"short") ==0 ) return typeid(short);
474  if( strcmp(typname,"short int") ==0 ) return typeid(short int);
475  break;
476  case 'u':
477  if ( strcmp(typname,"unsigned char") ==0 ) return typeid(unsigned char);
478  if ( strcmp(typname,"unsigned long") ==0 ) return typeid(unsigned long);
479  if ( strcmp(typname,"unsigned long long") ==0 ) return typeid(unsigned long long);
480  if ( strcmp(typname,"unsigned long long int") ==0 ) return typeid(unsigned long long int);
481  if ( strcmp(typname,"unsigned int") ==0 ) return typeid(unsigned int);
482  if ( strcmp(typname,"unsigned short") ==0 ) return typeid(unsigned short);
483  if ( strcmp(typname,"unsigned short int") ==0 ) return typeid(unsigned short int);
484  break;
485  case 'v':
486  if ( strcmp(typname,"void") ==0 ) return typeid(void);
487  break;
488  }
489  cerr << "WARNING! RootType getting typeinfo failed for: " << typname << endl;
490  return typeid(void);
491 }
492 
493 
494 //____________________________________________________________________________
495 TScopeAdapter::TScopeAdapter( const std::string& name, Bool_t load ) :
496  fName( name )
497 {
498  Init (name, load, false);
499 }
500 
501 
502 //____________________________________________________________________________
503 TScopeAdapter::TScopeAdapter( const std::string& name, Bool_t load, Bool_t quiet ) :
504  fName( name )
505 {
506  Int_t oldEIL = gErrorIgnoreLevel;
507  if( quiet ) gErrorIgnoreLevel = 3000;
508  Init (name, load, quiet);
509  gErrorIgnoreLevel = oldEIL;
510 }
511 
512 
513 //____________________________________________________________________________
514 void TScopeAdapter::Init( const std::string& name, Bool_t load, Bool_t quiet )
515 {
516  const string anonnmsp("(anonymous)");
517 
518  if( !load ) {
519  // let GetClass() have a crack at it first, to prevent accidental loading
520  TClass* klass = TClass::GetClass( name.c_str(), load, quiet );
521  if( klass ) {
522  fClass = klass;
523  return;
524  }
525  } else {
526  // load
527  const string scoped_name = Name( Reflex::SCOPED );
528  fClass = TClassRef( scoped_name.c_str() );
529  if( fClass.GetClass() ) {
530  return;
531  }
532  }
533 
534  // now check if GetClass failed because of lack of dictionary or it is maybe not a class at all
535  if( gROOT->GetType(name.c_str()) ) {
536  fIsFundamental = true;
537  } else if( TEnum::GetEnum(name.c_str(), load ? TEnum::kALoadAndInterpLookup : TEnum::kNone) ) {
538  // MN: enum, or anonymous type that could be an enum. for the moment mark it as fundamental
539  fIsFundamental = true;
540  }
541 }
542 
543 
544 //____________________________________________________________________________
545 TScopeAdapter::TScopeAdapter( const std::type_info &typeinfo )
546  : fClass (TClassRef( TClass::GetClass(typeinfo) ) ) // MN: is that right?
547 {
548  if( fClass.GetClass() ) {
549  // We apparently see this sometimes due to races in TClass.
550  // In that case, try retrieving it again.
551  // (See ATEAM-697.)
552  if (!fClass.GetClass()->HasDictionary()) {
553  fClass = TClassRef( TClass::GetClass(typeinfo) );
554  }
555  fName = fClass->GetName();
556  } else {
557  char buff[1024];
558  size_t len = sizeof(buff);
559  int status = 0;
560  fName = __cxxabiv1::__cxa_demangle(typeinfo.name(), buff, &len, &status);
561  fIsFundamental = true;
562  }
563 }
564 
565 //____________________________________________________________________________
568  fClass( mb.Name( Reflex::SCOPED ).c_str() )
569 {
570  /* empty */
571 }
572 
573 //____________________________________________________________________________
574 TScopeAdapter TScopeAdapter::ByName ATLAS_NOT_THREAD_SAFE (
575  const std::string& name, Bool_t load, Bool_t quiet )
576 {
577  return TScopeAdapter (name, load, quiet);
578 }
579 
580 //____________________________________________________________________________
582  const std::string& name, Bool_t load )
583 {
584  return TScopeAdapter (name, load);
585 }
586 
587 //____________________________________________________________________________
589 {
590  R__READ_LOCKGUARD (ROOT::gCoreMutex);
591  const char *class_name = gClassTable->At( nth );
592  // prevent autoloading, as it could change gClassTable
593  return class_name? TScopeAdapter( string(class_name), false ) : TScopeAdapter();
594 }
595 
596 //____________________________________________________________________________
598 {
599 // return total number of types in the system (this is stupid, as the number
600 // of types is dynamic ...)
601  R__READ_LOCKGUARD (ROOT::gCoreMutex);
602  TClassTable* tab ATLAS_THREAD_SAFE = gClassTable;
603  return tab ? tab->Classes() : 0;
604 }
605 
606 //____________________________________________________________________________
607 std::string TScopeAdapter::Name( unsigned int mod ) const
608 {
609 // Return name of type described by fClass
610  if ( ! fClass.GetClass() || ! fClass->Property() ) {
611  // fundamental types have no class, and unknown classes have no property
612  std::string name = fName;
613 
614  if ( mod & Reflex::FINAL )
615  name = ResolveTypedef( name );
616 
617  if ( ! ( mod & Reflex::QUALIFIED ) )
618  name = UnqualifiedTypeName( fName );
619 
620  return name;
621  }
622 
623  std::string name = fClass->GetName();
624  if ( mod & Reflex::FINAL )
625  name = ResolveTypedef( name );
626 
627  if ( ! (mod & Reflex::SCOPED) ) {
628  // remove scope from the name
629  Int_t tpl_open = 0;
630  for ( std::string::size_type pos = name.size() - 1; 0 < pos; --pos ) {
631  std::string::value_type c = name[ pos ];
632 
633  // count '<' and '>' to be able to skip template contents
634  if ( c == '>' )
635  ++tpl_open;
636  else if ( c == '<' )
637  --tpl_open;
638  else if ( tpl_open == 0 && c == ':' && 0 < pos && name[ pos-1 ] == ':' ) {
639  // found scope, strip name from it
640  name = name.substr( pos+1, std::string::npos );
641  break;
642  }
643  }
644  }
645 
646  return name;
647 }
648 
649 //____________________________________________________________________________
651 {
652  std::string name = Name( Reflex::FINAL | Reflex::SCOPED );
653  std::string::size_type pos = name.rfind( "::" );
654  if ( pos == std::string::npos )
655  return TScopeAdapter( /* wrap global scope */
656  TClass::GetClass( gInterpreter->ClassInfo_Factory( "" ) ) );
657  return TScopeAdapter( name.substr( 0, pos ) );
658 }
659 
660 //____________________________________________________________________________
662 {
663  return fClass.GetClass()? fClass.GetClass()->New() : 0;
664 }
665 
666 //____________________________________________________________________________
667 void *RootType::Construct(void *place) const {
668  return (place && fClass.GetClass())? fClass.GetClass()->New(place) : 0;
669 }
670 
671 //____________________________________________________________________________
672 void TScopeAdapter::Destruct(void *place) const
673 {
674  if (place && fClass.GetClass()) fClass.GetClass()->Destructor(place);
675 }
676 
677 
678 //____________________________________________________________________________
679 const type_info& TScopeAdapter::TypeInfo() const
680 {
681  if (fIsFundamental) { // Fundamentals have no fClass.GetClass()
682  return fundamental_type(fName);
683  }
684  return *fClass.GetClass()->GetTypeInfo();
685 }
686 
687 
688 //____________________________________________________________________________
690 {
691 // Reflex properties are more or less related to ROOT attributes: the names
692 // may be different (see map_property() above)
693  return fIsFundamental? TPropertyListAdapter(0) : fClass->GetAttributeMap();
694 }
695 
696 //____________________________________________________________________________
698 {
699 // the assumption here is that the adapter can be initialized with a sugared
700 // name, e.g. for function arguments
701  return *fName.rbegin() == '*';
702 }
703 
704 //____________________________________________________________________________
706 {
707 // this concept differs quite a bit between ROOT/meta and Reflex; this code
708 // supports both, with the addendum that the ROOT/meta idea of templates will
709 // not have template arguments
710  if ( Name( Reflex::FINAL ).find('<') != std::string::npos )
711  return kTRUE; // Reflex notion of templates
712 
713  if ( gInterpreter->CheckClassTemplate( Name( Reflex::SCOPED ).c_str() ) )
714  return kTRUE;
715 
716  return kFALSE;
717 }
718 
719 //____________________________________________________________________________
721 {
722 // check whether this corresponds to the global scope
723  return fClass->GetClassInfo() == gInterpreter->ClassInfo_Factory( "" );
724 }
725 
727 {
728  return fIsFundamental;
729 // return fClass.GetClass()? fClass.GetClass()->Property() & kIsFundamental : false;
730 }
731 
732 //____________________________________________________________________________
733 Bool_t TScopeAdapter::IsEnum() const
734 {
735  return fClass.GetClass()? fClass.GetClass()->Property() & kIsEnum : false;
736 }
737 //____________________________________________________________________________
739 {
740  return fClass.GetClass()? fClass.GetClass()->Property() & kIsTypedef : false;
741 }
742 //____________________________________________________________________________
744 {
745  return fClass.GetClass()? fClass.GetClass()->Property() & kIsArray : false;
746 }
747 
748 //____________________________________________________________________________
750 {
751 // get the total number of base classes that this class has
752  if ( fClass.GetClass() && fClass->GetListOfBases() != 0 )
753  return fClass->GetListOfBases()->GetSize();
754 
755  return 0;
756 }
757 
758 
759 //____________________________________________________________________________
760 size_t TScopeAdapter::SizeOf() const
761 {
762  if (fClass.GetClass()) {
763  return fClass.GetClass()->Size();
764  } else {
765  const TDataType* fundType = gROOT->GetType(fName.c_str());
766  if ( fundType )
767  return fundType->Size();
768  }
769  return 0;
770 }
771 
772 //____________________________________________________________________________
774 {
775 // get the nth base of this class
776  return (TBaseClass*)fClass->GetListOfBases()->At( nth );
777 }
778 
779 //____________________________________________________________________________
781 {
782 // get the total number of methods that this class has
783  if ( fClass.GetClass() )
784  return fClass->GetListOfMethods()->GetSize();
785 
786  return 0;
787 }
788 
789 //____________________________________________________________________________
791 {
792 // get the nth method of this class
793  return (TMethod*)fClass->GetListOfMethods()->At( nth );
794 }
795 
796 //____________________________________________________________________________
798 {
799 // get the total number of data members that this class has
800  if ( fClass.GetClass() )
801  return fClass->GetListOfDataMembers()->GetSize();
802 
803  return 0;
804 }
805 
806 //____________________________________________________________________________
808 {
809 // get the nth data member of this class
810  return (TDataMember*)fClass->GetListOfDataMembers()->At( nth );
811 }
812 
813 //____________________________________________________________________________
815 {
816 // this is stupid, but highly likely never called, and if it is, only once, so
817 // I don't see a reason for caching to prevent the extra loops
818  std::string name = Name( Reflex::FINAL );
819  size_t tpl_open = 0, argcount = 0;
820  std::string::size_type last = 0;
821  for ( std::string::size_type pos = 0; pos < name.size(); ++pos ) {
822  std::string::value_type c = name[pos];
823 
824  // count '<' and '>' to be able to keep templated args intact
825  if ( c == '<' ) {
826  ++tpl_open;
827  if (tpl_open == 1) last = pos+1;
828  continue;
829  } else if (c == '>') {
830  --tpl_open;
831  }
832  if ((c == ',' && tpl_open == 1) || (c == '>' && tpl_open == 0)) {
833  if ( argcount++ == nth ) {
834  // Protect against data race inside TClassEdit.
835  // https://github.com/root-project/root/issues/10353
836  // Should be fixed in root 6.26.02.
837  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
838  std::string part =
839  TClassEdit::CleanType( name.substr(last, pos-last).c_str(), 1 );
840  return part;
841  }
842  last = pos+1; // done with part
843  }
844  }
845 
846  // should never be called
847  assert( !"miscount between TemplateArgumentSize() and TemplateArgumentAt()" );
848  return TScopeAdapter();
849 }
850 
851 //____________________________________________________________________________
853 {
854 // this is stupid, too, see TemplateArgumentAt() above
855  std::string name = Name( Reflex::FINAL );
856  size_t tpl_open = 0, argcount = 0;
857  for ( std::string::size_type pos = 0; pos < name.size(); ++pos ) {
858  std::string::value_type c = name[pos];
859 
860  // count '<' and '>' to be able to keep templated args intact
861  if ( c == '<' ) {
862  ++tpl_open;
863  continue;
864  } else if ( c == '>' )
865  --tpl_open;
866 
867  if ((c == ',' && tpl_open == 1) || (c == '>' && tpl_open == 0))
868  ++argcount;
869  }
870  return argcount;
871 }
872 
873 //____________________________________________________________________________
874 TScopeAdapter::operator Bool_t() const
875 {
876  // check the validity of this scope (class)
877  if( fName.empty() ) return false;
878  if( fIsFundamental ) return true;
879 
880  // MN: rewriting this method to avoid premature header parsing
881  TClass* klass = fClass.GetClass();
882  if( !klass ) return false;
883  if( klass->HasDictionary() ) return true;
884 
885  // cout << "RootType: (Debug warning) Type " << fName << " has no dictionary!" << endl;
886  return false;
887 }
888 
889 //____________________________________________________________________________
891 {
892  // verify whether the dictionary of this class is fully available
893  Bool_t b = kFALSE;
894  std::string scname = Name( Reflex::SCOPED );
895  TClass* klass = TClass::GetClass( scname.c_str(), true, true );
896 
897  if ( klass) {// works for normal case w/ dict
898  b = klass->HasDictionary();
899  }
900  else { // special case for forward declared classes
901  ClassInfo_t* ci = gInterpreter->ClassInfo_Factory( scname.c_str() );
902  if ( ci ) {
903  b = gInterpreter->ClassInfo_IsLoaded( ci );
904  gInterpreter->ClassInfo_Delete( ci ); // we own the fresh class info
905  }
906  }
907  return b;
908 }
909 
910 //____________________________________________________________________________
912 {
913 // test if this scope represents a class
914  if ( fClass.GetClass() ) {
915  // some inverted logic: we don't have a TClass, but a builtin will be recognized, so
916  // if it is NOT a builtin, it is a class or struct (but may be missing dictionary)
917  return (fClass->Property() & kIsClass) || ! (fClass->Property() & kIsFundamental);
918  }
919 
920  // no class can mean either is no class (i.e. builtin), or no dict or interpreted(?)
921  // as a workaround, use TDataTypes that has a full enumeration of builtin types
922  return TDataType( Name( Reflex::FINAL | Reflex::SCOPED ).c_str() ).GetType() == kOther_t;
923 }
924 
925 //____________________________________________________________________________
927 {
928 // test if this scope represents a struct
929  if ( fClass.GetClass() ) {
930  // same logic as for IsClass() above ...
931  return (fClass->Property() & kIsStruct) || ! (fClass->Property() & kIsFundamental);
932  }
933 
934 // same logic as for IsClass() above ...
935  return TDataType( Name( Reflex::FINAL | Reflex::SCOPED ).c_str() ).GetType() == kOther_t;
936 }
937 
938 //____________________________________________________________________________
940 {
941 // test if this scope represents a namespace
942  if ( fClass.GetClass() )
943  return fClass->Property() & kIsNamespace;
944 
945  return kFALSE;
946 }
947 
948 //____________________________________________________________________________
950 {
951 // test if this scope represents an abstract class
952  if ( fClass.GetClass() )
953  return fClass->Property() & kIsAbstract; // assume set only for classes
954 
955  return kFALSE;
956 }
957 
958 //____________________________________________________________________________
960 {
961 // comparison operator, used for STL containers (implementation debatable)
962  return fClass.GetClass() == rh.fClass.GetClass();
963 }
964 
965 //____________________________________________________________________________
967 {
968 // less-than operator, used for STL containers (makes little sense conceptually,
969 // but this class is used as a key in std::map<>s for some reason; choosing to
970 // compare on name here, as any simple comparison (e.g. GetClassInfo()) is bound
971 // to fall apart if classes are unloaded/updated/replaced).
972  return Name( Reflex::FINAL | Reflex::SCOPED )
974 }
975 
RunTileTBRec.method
method
Definition: RunTileTBRec.py:73
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
TScopeAdapter::TemplateArgumentAt
TScopeAdapter TemplateArgumentAt(size_t nth) const
Definition: RootType.cxx:814
TScopeAdapter::DataMemberSize
size_t DataMemberSize() const
Definition: RootType.cxx:797
get_hdefs.buff
buff
Definition: get_hdefs.py:64
TScopeAdapter::IsStruct
Bool_t IsStruct() const
Definition: RootType.cxx:926
TScopeAdapter::TScopeAdapter
TScopeAdapter()
Definition: RootType.cxx:372
TScopeAdapter::IsTemplateInstance
Bool_t IsTemplateInstance() const
Definition: RootType.cxx:705
TMemberAdapter::TMemberAdapter
TMemberAdapter(TMethod *meth)
Definition: RootType.cxx:108
TScopeAdapter::ByNameNoQuiet
static TScopeAdapter ByNameNoQuiet(const std::string &name, Bool_t load=kTRUE)
Definition: RootType.cxx:581
TScopeAdapter::IsTopScope
Bool_t IsTopScope() const
Definition: RootType.cxx:720
TPropertyListAdapter::HasProperty
Bool_t HasProperty(const std::string &key) const
Definition: RootType.cxx:74
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
Reflex
Definition: RootType.h:21
TMemberAdapter::FunctionParameterNameAt
std::string FunctionParameterNameAt(size_t nth)
Definition: RootType.cxx:292
rootconvert.fName
string fName
Definition: rootconvert.py:5
quiet
bool quiet
Definition: TrigGlobEffCorrValidation.cxx:190
TScopeAdapter::Properties
TPropertyListAdapter Properties() const
Definition: RootType.cxx:689
python.PyAthena.klass
klass
Definition: PyAthena.py:136
TScopeAdapter::fIsFundamental
bool fIsFundamental
Definition: RootType.h:203
TMemberAdapter::IsConstructor
Bool_t IsConstructor() const
Definition: RootType.cxx:234
TScopeAdapter::fName
std::string fName
Definition: RootType.h:201
TBaseAdapter
Definition: RootType.h:104
TMemberAdapter::IsStatic
Bool_t IsStatic() const
Definition: RootType.cxx:255
TScopeAdapter::DeclaringScope
TScopeAdapter DeclaringScope() const
Definition: RootType.cxx:650
TMemberAdapter::FunctionParameterDefaultAt
std::string FunctionParameterDefaultAt(size_t nth)
Definition: RootType.cxx:304
TScopeAdapter::IsClass
Bool_t IsClass() const
Definition: RootType.cxx:911
fundamental_type
const std::type_info & fundamental_type(const std::string &name)
Definition: RootType.cxx:448
klass
TScopeAdapter::TypeInfo
const std::type_info & TypeInfo() const
Definition: RootType.cxx:679
TMemberAdapter::IsConstant
Bool_t IsConstant() const
Definition: RootType.cxx:227
TScopeAdapter::operator==
bool operator==(const TScopeAdapter &rh) const
Definition: RootType.cxx:959
TMemberAdapter::TypeOf
TTypeAdapter TypeOf() const
Definition: RootType.cxx:160
TMemberAdapter
Definition: RootType.h:60
TMemberAdapter::ReturnType
TReturnTypeAdapter ReturnType() const
Definition: RootType.cxx:325
maskDeadModules.mod
mod
Definition: maskDeadModules.py:36
TScopeAdapter::TypeSize
static size_t TypeSize()
Definition: RootType.cxx:597
TReturnTypeAdapter
Definition: RootType.h:49
TMemberAdapter::IsPublic
Bool_t IsPublic() const
Definition: RootType.cxx:248
Reflex::SCOPED
@ SCOPED
Definition: RootType.h:27
TScopeAdapter::TypeAt
static TScopeAdapter TypeAt(size_t nth)
Definition: RootType.cxx:588
CaloNoise_fillDB.dt
dt
Definition: CaloNoise_fillDB.py:58
TMemberAdapter::IsEnum
Bool_t IsEnum() const
Definition: RootType.cxx:241
TScopeAdapter::IsPointer
Bool_t IsPointer() const
Definition: RootType.cxx:697
TScopeAdapter::operator<
bool operator<(const TScopeAdapter &rh) const
Definition: RootType.cxx:966
TScopeAdapter::Construct
void * Construct() const
Definition: RootType.cxx:661
TScopeAdapter::Name
std::string Name(unsigned int mod=Reflex::SCOPED) const
Definition: RootType.cxx:607
ReadCellNoiseFromCool.dm
dm
Definition: ReadCellNoiseFromCool.py:235
perfmonmt-printer.required
required
Definition: perfmonmt-printer.py:184
create_dcsc_inputs_sqlite.arg
list arg
Definition: create_dcsc_inputs_sqlite.py:48
TScopeAdapter::FunctionMemberAt
TMemberAdapter FunctionMemberAt(size_t nth) const
Definition: RootType.cxx:790
Reflex::FINAL
@ FINAL
Definition: RootType.h:25
TBaseAdapter::fBase
TBaseClass * fBase
Definition: RootType.h:115
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
TPropertyListAdapter
Definition: RootType.h:37
TScopeAdapter::FunctionMemberSize
size_t FunctionMemberSize() const
Definition: RootType.cxx:780
gErrorIgnoreLevel
int gErrorIgnoreLevel
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
TMemberAdapter::fMember
TDictionary * fMember
Definition: RootType.h:100
is_fundamental_type
bool is_fundamental_type(const std::string &name)
Definition: RootType.cxx:385
TMemberAdapter::Name
std::string Name(unsigned int mod=0) const
Definition: RootType.cxx:187
TScopeAdapter::IsFundamental
Bool_t IsFundamental() const
Definition: RootType.cxx:726
Name
JetDumper::Name Name
Definition: JetDumper.cxx:19
TMemberAdapter::IsTransient
Bool_t IsTransient() const
Definition: RootType.cxx:262
TPropertyListAdapter::PropertyAsString
std::string PropertyAsString(const std::string &key) const
Definition: RootType.cxx:83
TScopeAdapter::Init
void Init(const std::string &name, Bool_t load, Bool_t quiet)
Definition: RootType.cxx:514
PowhegPythia8EvtGen_H2a4X_ctauY.ma
int ma
Definition: PowhegPythia8EvtGen_H2a4X_ctauY.py:26
TBaseAdapter::Name
std::string Name() const
Definition: RootType.cxx:356
TMemberAdapter::FunctionParameterSize
size_t FunctionParameterSize(Bool_t required=false) const
Definition: RootType.cxx:271
TRT_PAI_physicsConstants::mb
const double mb
1mb to cm2
Definition: TRT_PAI_physicsConstants.h:15
TTypeAdapter
TScopeAdapter TTypeAdapter
Definition: RootType.h:33
TScopeAdapter::Destruct
void Destruct(void *place) const
Definition: RootType.cxx:672
TMemberAdapter::FunctionParameterAt
TMemberAdapter FunctionParameterAt(size_t nth)
Definition: RootType.cxx:285
Reflex::QUALIFIED
@ QUALIFIED
Definition: RootType.h:26
TScopeAdapter::IsAbstract
Bool_t IsAbstract() const
Definition: RootType.cxx:949
RootType.h
TScopeAdapter::IsEnum
Bool_t IsEnum() const
Definition: RootType.cxx:733
TScopeAdapter::TemplateArgumentSize
size_t TemplateArgumentSize() const
Definition: RootType.cxx:852
TScopeAdapter::BaseSize
size_t BaseSize() const
Definition: RootType.cxx:749
merge.status
status
Definition: merge.py:17
TScopeAdapter::IsArray
Bool_t IsArray() const
Definition: RootType.cxx:743
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
python.root_pickle.load
def load(f, use_proxy=1, key=None)
Definition: root_pickle.py:476
TScopeAdapter::DataMemberAt
TMemberAdapter DataMemberAt(size_t nth) const
Definition: RootType.cxx:807
python.DetectStreamerInfoChanges.class_name
class_name
Definition: DetectStreamerInfoChanges.py:57
TScopeAdapter::IsComplete
Bool_t IsComplete() const
Definition: RootType.cxx:890
TScopeAdapter::SizeOf
size_t SizeOf() const
Definition: RootType.cxx:760
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
ATLAS_NOT_THREAD_SAFE
TTypeAdapter TMemberAdapter::DeclaringType ATLAS_NOT_THREAD_SAFE() const
Definition: RootType.cxx:348
TScopeAdapter::fClass
TClassRef fClass
Definition: RootType.h:202
python.compressB64.c
def c
Definition: compressB64.py:93
TMemberAdapter::Offset
size_t Offset() const
Definition: RootType.cxx:219
TScopeAdapter::IsTypedef
Bool_t IsTypedef() const
Definition: RootType.cxx:738
TMemberAdapter::GetSharedLibs
const char * GetSharedLibs() const
Definition: RootType.cxx:212
TReturnTypeAdapter::Name
std::string Name(unsigned int mod=0) const
Definition: RootType.cxx:92
TScopeAdapter::IsNamespace
Bool_t IsNamespace() const
Definition: RootType.cxx:939
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
TScopeAdapter
Definition: RootType.h:119
TScopeAdapter::BaseAt
TBaseAdapter BaseAt(size_t nth) const
Definition: RootType.cxx:773