ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TListOfDataMembers.cxx
Go to the documentation of this file.
1 // @(#)root/cont
2 // Author: Philippe Canal Aug 2013
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TListOfDataMembers
13 A collection of TDataMember objects designed for fast access given a
14 DeclId_t and for keep track of TDataMember that were described
15 unloaded data member.
16 */
17 
18 #include "TListOfDataMembers.h"
19 #include "TBuffer.h"
20 #include "TClass.h"
21 #include "TClassRef.h"
22 #include "TExMap.h"
23 #include "TDataMember.h"
24 #include "TGlobal.h"
25 #include "TInterpreter.h"
26 #include "TVirtualMutex.h"
27 #include "TError.h"
28 #include "TEnumConstant.h"
29 #include "TClassEdit.h"
30 
31 const unsigned int idsSize=19;
32 
34 
35 ////////////////////////////////////////////////////////////////////////////////
36 /// Constructor.
37 
39  fClass(cl),fIds(0),fUnloaded(0),fIsLoaded(kFALSE), fLastLoadMarker(0)
40 {
41 }
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// Destructor.
45 
47 {
49  delete fIds;
50  if (fUnloaded) fUnloaded->Delete();
51  delete fUnloaded;
52 }
53 
54 ////////////////////////////////////////////////////////////////////////////////
55 /// Add a pair<id, object> to the map of data members and their ids.
56 
58 {
59  if (!fIds) fIds = new TExMap(idsSize);
60 
61  if (fClass) {
62  TDataMember *d = dynamic_cast<TDataMember*>(obj);
63  if (d) {
64  fIds->Add((Long64_t)d->GetDeclId(),(Long64_t)d);
65  }
66  } else {
67  TGlobal *g = dynamic_cast<TGlobal*>(obj);
68  if (g && g->GetDeclId()) {
69  fIds->Add((Long64_t)g->GetDeclId(),(Long64_t)g);
70  }
71  }
72 }
73 
74 ////////////////////////////////////////////////////////////////////////////////
75 /// Add object at the beginning of the list.
76 
78 {
80  MapObject(obj);
81 }
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 /// Add object at the beginning of the list and also store option.
85 /// Storing an option is useful when one wants to change the behaviour
86 /// of an object a little without having to create a complete new
87 /// copy of the object. This feature is used, for example, by the Draw()
88 /// method. It allows the same object to be drawn in different ways.
89 
91 {
92  THashList::AddFirst(obj,opt);
93  MapObject(obj);
94 }
95 
96 ////////////////////////////////////////////////////////////////////////////////
97 /// Add object at the end of the list.
98 
100 {
101  THashList::AddLast(obj);
102  MapObject(obj);
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 /// Add object at the end of the list and also store option.
107 /// Storing an option is useful when one wants to change the behaviour
108 /// of an object a little without having to create a complete new
109 /// copy of the object. This feature is used, for example, by the Draw()
110 /// method. It allows the same object to be drawn in different ways.
111 
113 {
114  THashList::AddLast(obj, opt);
115  MapObject(obj);
116 }
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 /// Insert object at location idx in the list.
120 
122 {
123  THashList::AddAt(obj, idx);
124  MapObject(obj);
125 }
126 
127 ////////////////////////////////////////////////////////////////////////////////
128 /// Insert object after object after in the list.
129 
131 {
132  THashList::AddAfter(after, obj);
133  MapObject(obj);
134 }
135 
136 ////////////////////////////////////////////////////////////////////////////////
137 /// Insert object after object after in the list.
138 
140 {
141  THashList::AddAfter(after, obj);
142  MapObject(obj);
143 }
144 
145 ////////////////////////////////////////////////////////////////////////////////
146 /// Insert object before object before in the list.
147 
149 {
150  THashList::AddBefore(before, obj);
151  MapObject(obj);
152 }
153 
154 ////////////////////////////////////////////////////////////////////////////////
155 /// Insert object before object before in the list.
156 
158 {
159  THashList::AddBefore(before, obj);
160  MapObject(obj);
161 }
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 /// Remove all objects from the list. Does not delete the objects unless
165 /// the THashList is the owner (set via SetOwner()).
166 
168 {
169  if (fUnloaded) fUnloaded->Clear(option);
170  if (fIds) fIds->Clear();
171  THashList::Clear(option);
172  fIsLoaded = kFALSE;
173 }
174 
175 ////////////////////////////////////////////////////////////////////////////////
176 /// Delete all TDataMember object files.
177 
178 void TListOfDataMembers::Delete(Option_t *option /* ="" */)
179 {
180  if (fUnloaded) fUnloaded->Delete(option);
181  THashList::Delete(option);
182  fIsLoaded = kFALSE;
183 }
184 
185 ////////////////////////////////////////////////////////////////////////////////
186 /// Specialize FindObject to do search for the
187 /// a data member just by name or create it if its not already in the list
188 
190 {
192  if (!result) {
194  // We already have all the information, no need to search more
195  return 0;
196  }
197 
199 
201  if (fClass) decl = gInterpreter->GetDataMember(fClass->GetClassInfo(),name);
202  else decl = gInterpreter->GetDataMember(0,name);
203  if (decl) result = const_cast<TListOfDataMembers*>(this)->Get(decl);
204  }
205  return result;
206 }
207 
208 ////////////////////////////////////////////////////////////////////////////////
209 /// Return (after creating it if necessary) the TDataMember
210 /// describing the data member corresponding to the Decl 'id'.
211 
213 {
214  if (!id) return 0;
215 
216  return fIds ? (TDataMember*)fIds->GetValue((Long64_t)id) : 0;
217 }
218 
219 ////////////////////////////////////////////////////////////////////////////////
220 /// Return (after creating it if necessary) the TDataMember
221 /// describing the data member corresponding to the Decl 'id'.
222 
224 {
225  if (!id) return 0;
226 
227  TDictionary *dm = Find(id);
228  if (dm) return dm;
229 
230  if (fClass) {
232  // The interpreter does not know about this class yet (or a problem
233  // occurred that prevented the proper updating of fClassInfo).
234  // So this decl can not possibly be part of this class.
235  // [In addition calling GetClassInfo would trigger a late parsing
236  // of the header which we want to avoid].
237  return 0;
238  }
239  if (!gInterpreter->ClassInfo_Contains(fClass->GetClassInfo(),id)) return 0;
240  } else {
241  if (!gInterpreter->ClassInfo_Contains(0,id)) return 0;
242  }
243 
245 
246  DataMemberInfo_t *info = gInterpreter->DataMemberInfo_Factory(id,fClass ? fClass->GetClassInfo() : 0);
247 
248  // Let's see if this is a reload ...
249  const char *name = gInterpreter->DataMemberInfo_Name(info);
250 
252  if (update) {
253  if (fClass) {
254  ((TDataMember*)update)->Update(info);
255  } else {
256  ((TGlobal*)update)->Update(info);
257  }
258  dm = update;
259  }
260  if (!dm) {
261  if (fClass) dm = new TDataMember(info, fClass);
262  else dm = new TGlobal(info);
263  }
264  // Calling 'just' THahList::Add would turn around and call
265  // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
266  THashList::AddLast(dm);
267  if (!fIds) fIds = new TExMap(idsSize);
268  fIds->Add((Long64_t)id,(Long64_t)dm);
269 
270  return dm;
271 }
272 
273 ////////////////////////////////////////////////////////////////////////////////
274 /// Return (after creating it if necessary) the TDataMember
275 /// describing the data member corresponding to the Decl 'id'.
276 /// The skipChecks flag controls the consistency checks performed inspecting
277 /// the AST. In some cases, we explicitly alter the datamembers in the
278 /// typesystem with respect to the AST and therefore we must not enforce
279 /// consistency.
280 
281 TDictionary *TListOfDataMembers::Get(DataMemberInfo_t *info, bool skipChecks)
282 {
283  if (!info) return 0;
284 
285  TDictionary::DeclId_t id = gInterpreter->GetDeclId(info);
286  R__ASSERT( id != 0 && "DeclId should not be null");
287  TDictionary *dm = fIds ? (TDataMember*)fIds->GetValue((Long64_t)id) : 0;
288  if (!dm) {
289  if (fClass) {
291  // The interpreter does not know about this class yet (or a problem
292  // occurred that prevented the proper updating of fClassInfo).
293  // So this decl can not possibly be part of this class.
294  // [In addition calling GetClassInfo would trigger a late parsing
295  // of the header which we want to avoid].
296  return 0;
297  }
298  if (!skipChecks && !gInterpreter->ClassInfo_Contains(fClass->GetClassInfo(),id)) return 0;
299  } else {
300  if (!skipChecks && !gInterpreter->ClassInfo_Contains(0,id)) return 0;
301  }
302 
304 
305  DataMemberInfo_t *dm_info = gInterpreter->DataMemberInfo_FactoryCopy(info);
306 
307  // Let's see if this is a reload ...
308  const char *name = gInterpreter->DataMemberInfo_Name(info);
310  if (update) {
311  update->Update(dm_info);
312  dm = update;
313  }
314  if (!dm) {
315  if (fClass) dm = new TDataMember(dm_info, fClass);
316  else dm = new TGlobal(dm_info);
317  }
318  // Calling 'just' THahList::Add would turn around and call
319  // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
320  THashList::AddLast(dm);
321  if (!fIds) fIds = new TExMap(idsSize);
322  fIds->Add((Long64_t)id,(Long64_t)dm);
323  }
324  return dm;
325 }
326 
327 ////////////////////////////////////////////////////////////////////////////////
328 /// Remove a pair<id, object> from the map of data members and their ids.
329 
331 {
332  if (!fIds) return;
333  if (fClass) {
334  TDataMember *d = dynamic_cast<TDataMember*>(obj);
335  if (d) {
336  if (d->GetDeclId()) {
337  fIds->Remove((Long64_t)d->GetDeclId());
338  }
339  d->Update(0);
340  }
341  } else {
342  TGlobal *g = dynamic_cast<TGlobal*>(obj);
343  if (g) {
344  if (g->GetDeclId()) {
345  fIds->Remove((Long64_t)g->GetDeclId());
346  }
347  g->Update(0);
348  }
349  }
350 }
351 
352 ////////////////////////////////////////////////////////////////////////////////
353 /// Remove object from this collection and recursively remove the object
354 /// from all other objects (and collections).
355 /// This function overrides TCollection::RecursiveRemove that calls
356 /// the Remove function. THashList::Remove cannot be called because
357 /// it uses the hash value of the hash table. This hash value
358 /// is not available anymore when RecursiveRemove is called from
359 /// the TObject destructor.
360 
362 {
363  if (!obj) return;
364 
367  UnmapObject(obj);
368 
369 }
370 
371 ////////////////////////////////////////////////////////////////////////////////
372 /// Remove object from the list.
373 
375 {
376  Bool_t found;
377 
378  found = THashList::Remove(obj);
379  if (!found && fUnloaded) {
380  found = fUnloaded->Remove(obj);
381  }
382  UnmapObject(obj);
383  if (found) return obj;
384  else return 0;
385 }
386 
387 ////////////////////////////////////////////////////////////////////////////////
388 /// Remove object via its objlink from the list.
389 
391 {
392  if (!lnk) return 0;
393 
394  TObject *obj = lnk->GetObject();
395 
396  THashList::Remove(lnk);
397  if (fUnloaded) fUnloaded->Remove(obj);
398 
399  UnmapObject(obj);
400  return obj;
401 }
402 
403 ////////////////////////////////////////////////////////////////////////////////
404 /// Load all the DataMembers known to the interpreter for the scope 'fClass'
405 /// into this collection.
406 
408 {
410  // Class and union are not extendable, if we already
411  // loaded all the data member there is no need to recheck
412  if (fIsLoaded) return;
413  }
414 
415  // This will provoke the parsing of the headers if need be.
416  if (fClass && fClass->GetClassInfo() == 0) return;
417 
419 
420  ULong64_t currentTransaction = gInterpreter->GetInterpreterStateMarker();
421  if (currentTransaction == fLastLoadMarker) {
422  return;
423  }
424  fLastLoadMarker = currentTransaction;
425 
426  // In the case of namespace, even if we have loaded before we need to
427  // load again in case there was new data member added.
428 
429  // Mark the list as loaded to avoid an infinite recursion in the case
430  // where we have a data member that is a variable size array. In that
431  // case TDataMember::Init needs to get/load the list to find the data
432  // member used as the array size.
433  fIsLoaded = kTRUE;
434 
435  ClassInfo_t *info;
436  if (fClass) info = fClass->GetClassInfo();
437  else info = gInterpreter->ClassInfo_Factory();
438 
439  // Treat the complex<float>, complex<double> in a special way, i.e. replacing
440  // the datamembers with the ones of _root_std_complex<T>
441  bool skipChecks = false;
442  if (fClass){
443  auto complexType = TClassEdit::GetComplexType(fClass->GetName());
444  switch(complexType) {
446  {
447  break;
448  }
450  {
451  skipChecks = true;
452  info = TClass::GetClass("_root_std_complex<float>")->GetClassInfo();
453  break;
454  }
456  {
457  skipChecks = true;
458  info = TClass::GetClass("_root_std_complex<double>")->GetClassInfo();
459  break;
460  }
462  {
463  skipChecks = true;
464  info = TClass::GetClass("_root_std_complex<int>")->GetClassInfo();
465  break;
466  }
468  {
469  skipChecks = true;
470  info = TClass::GetClass("_root_std_complex<long>")->GetClassInfo();
471  break;
472  }
473  }
474  }
475 
476  // Now we follow the ordinary pattern
477  DataMemberInfo_t *t = gInterpreter->DataMemberInfo_Factory(info);
478  while (gInterpreter->DataMemberInfo_Next(t)) {
479  if (gInterpreter->DataMemberInfo_IsValid(t)) {
480  // Get will check if there is already there or create a new one
481  // (or re-use a previously unloaded version).
482  Get(t,skipChecks);
483  }
484  }
485  gInterpreter->DataMemberInfo_Delete(t);
486  if (!fClass) gInterpreter->ClassInfo_Delete(info);
487 }
488 
489 ////////////////////////////////////////////////////////////////////////////////
490 /// Stream an object of class TListOfDataMembers.
491 
492 void TListOfDataMembers::Streamer(TBuffer &R__b)
493 {
494  if (R__b.IsReading()) {
496  fIsLoaded = kTRUE;
497  } else {
499  }
500 }
501 
502 ////////////////////////////////////////////////////////////////////////////////
503 /// Move the member or data member to the expect set of list.
504 
506  if (fClass) {
507  TDataMember *d = dynamic_cast<TDataMember*>(member);
508  if (d) {
509  if (d->GetDeclId()) {
510  if (!fIds) fIds = new TExMap(idsSize);
511  fIds->Add((Long64_t)d->GetDeclId(),(Long64_t)d);
512  }
514  if (update) fUnloaded->Remove(update);
515 
516  if (! THashList::FindObject(d) ) {
517  // Calling 'just' THahList::Add would turn around and call
518  // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
520  }
521  }
522  } else {
523  TGlobal *g = dynamic_cast<TGlobal*>(member);
524  if (g) {
525  if (g->GetDeclId()) {
526  if (!fIds) fIds = new TExMap(idsSize);
527  fIds->Add((Long64_t)g->GetDeclId(),(Long64_t)g);
528 
530  if (update) fUnloaded->Remove(update);
531 
532  if (! THashList::FindObject(g) ) {
533  // Calling 'just' THahList::Add would turn around and call
534  // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
536  }
537  }
538  }
539  }
540 
541 
542 }
543 
544 ////////////////////////////////////////////////////////////////////////////////
545 /// Mark 'all func' as being unloaded.
546 /// After the unload, the data member can no longer be found directly,
547 /// until the decl can be found again in the interpreter (in which
548 /// the func object will be reused.
549 
551 {
552  TObjLink *lnk = FirstLink();
553  while (lnk) {
554  TDictionary *data = (TDictionary *)lnk->GetObject();
555  UnmapObject(data);
556  fUnloaded = new THashList;
557  fUnloaded->Add(data);
558 
559  lnk = lnk->Next();
560  }
561 
563  fIsLoaded = kFALSE;
564 }
565 
566 ////////////////////////////////////////////////////////////////////////////////
567 /// Mark 'func' as being unloaded.
568 /// After the unload, the data member can no longer be found directly,
569 /// until the decl can be found again in the interpreter (in which
570 /// the func object will be reused.
571 
573 {
574  if (THashList::Remove(mem)) {
575  // We contains the object, let remove it from the other internal
576  // list and move it to the list of unloaded objects.
577 
578  UnmapObject(mem);
579  fUnloaded = new THashList;
580  fUnloaded->Add(mem);
581  }
582 }
virtual void Clear(Option_t *="")
Definition: TObject.h:110
void Add(ULong64_t hash, Long64_t key, Long64_t value)
Add an (key,value) pair to the table. The key should be unique.
Definition: TExMap.cxx:87
void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: THashList.cxx:68
void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
void Remove(ULong64_t hash, Long64_t key)
Remove entry with specified key from the TExMap.
Definition: TExMap.cxx:216
void AddAt(TObject *obj, Int_t idx)
Insert object at location idx in the list.
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
void AddLast(TObject *obj)
Add object at the end of the list.
Definition: THashList.cxx:90
long long Long64_t
Definition: RtypesCore.h:69
Bool_t IsReading() const
Definition: TBuffer.h:83
TDictionary::DeclId_t DeclId_t
Definition: TInterpreter.h:236
const char Option_t
Definition: RtypesCore.h:62
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:33
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:213
THashList * fUnloaded
Map from DeclId_t to TDataMember*.
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:46
ULong64_t fLastLoadMarker
Mark whether Load was executed.
Long_t Property() const
Set TObject::fBits and fStreamerType to cache information about the class.
Definition: TClass.cxx:5560
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
const unsigned int idsSize
#define R__ASSERT(e)
Definition: TError.h:98
void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: THashList.cxx:184
int Int_t
Definition: RtypesCore.h:41
virtual void Clear(Option_t *option)
Remove all objects from the list.
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
#define gInterpreter
Definition: TInterpreter.h:502
void Load()
Load all the DataMembers known to the interpreter for the scope 'fClass' into this collection...
void AddLast(TObject *obj)
Add object at the end of the list.
void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: THashList.cxx:253
void AddBefore(const TObject *before, TObject *obj)
Insert object before object before in the list.
Bool_t IsLoaded() const
const void * DeclId_t
Definition: TDictionary.h:209
TDictionary * Find(DeclId_t id) const
Return (after creating it if necessary) the TDataMember describing the data member corresponding to t...
ClassImp(TListOfDataMembers) TListOfDataMembers
Constructor.
void UnmapObject(TObject *obj)
Remove a pair<id, object> from the map of data members and their ids.
Bool_t HasInterpreterInfoInMemory() const
Definition: TClass.h:372
void Class()
Definition: Class.C:29
int d
Definition: tornado.py:11
void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
virtual DeclId_t GetDeclId() const
Definition: TGlobal.cxx:93
TClass * fClass
pointer to the foreign object
virtual bool Update(DataMemberInfo_t *info)
Update the TFunction to reflect the new info.
XFontStruct * id
Definition: TGX11.cxx:108
EComplexType GetComplexType(const char *)
Definition: TClassEdit.cxx:96
~TListOfDataMembers()
Destructor.
THashList(const THashList &)
TThread * t[5]
Definition: threadsh1.C:13
void Clear(Option_t *option="")
Remove all objects from the list.
Definition: THashList.cxx:168
TExMap * fIds
Context of this list. Not owned.
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Definition: TExMap.cxx:173
void AddAt(TObject *obj, Int_t idx)
Insert object at location idx in the list.
Definition: THashList.cxx:148
This class defines an abstract interface that must be implemented by all classes that contain diction...
Definition: TDictionary.h:162
void Update(TDictionary *member)
Move the member or data member to the expect set of list.
ClassInfo_t * GetClassInfo() const
Definition: TClass.h:390
TObject * Remove(TObject *obj)
Remove object from the list.
Definition: THashList.cxx:285
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
Definition: THashList.cxx:130
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
DeclId_t GetDeclId() const
Global variables class (global variables are obtained from CINT).
Definition: TGlobal.h:29
virtual TObjLink * FirstLink() const
Definition: TList.h:101
void MapObject(TObject *obj)
Add a pair<id, object> to the map of data members and their ids.
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
TDictionary::DeclId_t DeclId_t
unsigned long long ULong64_t
Definition: RtypesCore.h:70
#define R__LOCKGUARD(mutex)
void AddBefore(const TObject *before, TObject *obj)
Insert object before object before in the list.
Definition: THashList.cxx:112
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2801
virtual bool Update(DataMemberInfo_t *info)
Update the TFunction to reflect the new info.
Definition: TGlobal.cxx:160
virtual TObject * FindObject(const char *name) const
Specialize FindObject to do search for the a data member just by name or create it if its not already...
virtual void Delete(Option_t *option="")
Delete all TDataMember object files.
#define name(a, b)
Definition: linkTestLib0.cpp:5
Mother of all ROOT objects.
Definition: TObject.h:58
void Unload()
Mark 'all func' as being unloaded.
virtual void Add(TObject *obj)
Definition: TList.h:81
void AddFirst(TObject *obj)
Add object at the beginning of the list.
TObject * Remove(TObject *obj)
Remove object from the list.
double result[121]
Bool_t fIsLoaded
Holder of TDataMember for unloaded DataMembers.
const Bool_t kTRUE
Definition: Rtypes.h:91
TObject * obj
This class stores a (key,value) pair using an external hash.
Definition: TExMap.h:35
TDictionary * Get(DeclId_t id)
Return (after creating it if necessary) the TDataMember describing the data member corresponding to t...