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