Logo ROOT   6.16/01
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 "TEnumConstant.h"
29#include "TClassEdit.h"
30
31#include <sstream>
32
33const unsigned int idsSize=19;
34
36
37////////////////////////////////////////////////////////////////////////////////
38/// Constructor.
39
41 fClass(cl),fIds(0),fUnloaded(0),fIsLoaded(kFALSE), fLastLoadMarker(0)
42{
43}
44
45////////////////////////////////////////////////////////////////////////////////
46/// Destructor.
47
49{
51 delete fIds;
53 delete fUnloaded;
54}
55
56////////////////////////////////////////////////////////////////////////////////
57/// Add a pair<id, object> to the map of data members and their ids.
58
60{
61 if (!fIds) fIds = new TExMap(idsSize);
62
63 if (fClass) {
64 TDataMember *d = dynamic_cast<TDataMember*>(obj);
65 if (d) {
66 fIds->Add((Long64_t)d->GetDeclId(),(Long64_t)d);
67 }
68 } else {
69 TGlobal *g = dynamic_cast<TGlobal*>(obj);
70 if (g && g->GetDeclId()) {
71 fIds->Add((Long64_t)g->GetDeclId(),(Long64_t)g);
72 }
73 }
74}
75
76////////////////////////////////////////////////////////////////////////////////
77/// Add object at the beginning of the list.
78
80{
82 MapObject(obj);
83}
84
85////////////////////////////////////////////////////////////////////////////////
86/// Add object at the beginning of the list and also store option.
87/// Storing an option is useful when one wants to change the behaviour
88/// of an object a little without having to create a complete new
89/// copy of the object. This feature is used, for example, by the Draw()
90/// method. It allows the same object to be drawn in different ways.
91
93{
94 THashList::AddFirst(obj,opt);
95 MapObject(obj);
96}
97
98////////////////////////////////////////////////////////////////////////////////
99/// Add object at the end of the list.
100
102{
104 MapObject(obj);
105}
106
107////////////////////////////////////////////////////////////////////////////////
108/// Add object at the end of the list and also store option.
109/// Storing an option is useful when one wants to change the behaviour
110/// of an object a little without having to create a complete new
111/// copy of the object. This feature is used, for example, by the Draw()
112/// method. It allows the same object to be drawn in different ways.
113
115{
116 THashList::AddLast(obj, opt);
117 MapObject(obj);
118}
119
120////////////////////////////////////////////////////////////////////////////////
121/// Insert object at location idx in the list.
122
124{
125 THashList::AddAt(obj, idx);
126 MapObject(obj);
127}
128
129////////////////////////////////////////////////////////////////////////////////
130/// Insert object after object after in the list.
131
133{
134 THashList::AddAfter(after, obj);
135 MapObject(obj);
136}
137
138////////////////////////////////////////////////////////////////////////////////
139/// Insert object after object after in the list.
140
142{
143 THashList::AddAfter(after, obj);
144 MapObject(obj);
145}
146
147////////////////////////////////////////////////////////////////////////////////
148/// Insert object before object before in the list.
149
151{
152 THashList::AddBefore(before, obj);
153 MapObject(obj);
154}
155
156////////////////////////////////////////////////////////////////////////////////
157/// Insert object before object before in the list.
158
160{
161 THashList::AddBefore(before, obj);
162 MapObject(obj);
163}
164
165////////////////////////////////////////////////////////////////////////////////
166/// Remove all objects from the list. Does not delete the objects unless
167/// the THashList is the owner (set via SetOwner()).
168
170{
171 if (fUnloaded) fUnloaded->Clear(option);
172 if (fIds) fIds->Clear();
173 THashList::Clear(option);
175}
176
177////////////////////////////////////////////////////////////////////////////////
178/// Delete all TDataMember object files.
179
181{
182 if (fUnloaded) fUnloaded->Delete(option);
183 THashList::Delete(option);
185}
186
187////////////////////////////////////////////////////////////////////////////////
188/// Specialize FindObject to do search for the
189/// a data member just by name or create it if its not already in the list
190
192{
194 if (!result) {
196 // We already have all the information, no need to search more
197 return 0;
198 }
199
201
203 if (fClass) decl = gInterpreter->GetDataMember(fClass->GetClassInfo(),name);
204 else decl = gInterpreter->GetDataMember(0,name);
205 if (decl) result = const_cast<TListOfDataMembers*>(this)->Get(decl);
206 }
207 return result;
208}
209
210////////////////////////////////////////////////////////////////////////////////
211/// Return (after creating it if necessary) the TDataMember
212/// describing the data member corresponding to the Decl 'id'.
213
215{
216 if (!id) return 0;
217
218 return fIds ? (TDataMember*)fIds->GetValue((Long64_t)id) : 0;
219}
220
221////////////////////////////////////////////////////////////////////////////////
222/// Return (after creating it if necessary) the TDataMember
223/// describing the data member corresponding to the Decl 'id'.
224
226{
227 if (!id) return 0;
228
229 TDictionary *dm = Find(id);
230 if (dm) return dm;
231
232 if (fClass) {
234 // The interpreter does not know about this class yet (or a problem
235 // occurred that prevented the proper updating of fClassInfo).
236 // So this decl can not possibly be part of this class.
237 // [In addition calling GetClassInfo would trigger a late parsing
238 // of the header which we want to avoid].
239 return 0;
240 }
241 if (!gInterpreter->ClassInfo_Contains(fClass->GetClassInfo(),id)) return 0;
242 } else {
243 if (!gInterpreter->ClassInfo_Contains(0,id)) return 0;
244 }
245
247
248 DataMemberInfo_t *info = gInterpreter->DataMemberInfo_Factory(id,fClass ? fClass->GetClassInfo() : 0);
249
250 // Let's see if this is a reload ...
251 const char *name = gInterpreter->DataMemberInfo_Name(info);
252
254 if (update) {
255 if (fClass) {
256 ((TDataMember*)update)->Update(info);
257 } else {
258 ((TGlobal*)update)->Update(info);
259 }
260 dm = update;
261 }
262 if (!dm) {
263 if (fClass) dm = new TDataMember(info, fClass);
264 else dm = new TGlobal(info);
265 }
266 // Calling 'just' THahList::Add would turn around and call
267 // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
269 if (!fIds) fIds = new TExMap(idsSize);
270 fIds->Add((Long64_t)id,(Long64_t)dm);
271
272 return dm;
273}
274
275////////////////////////////////////////////////////////////////////////////////
276/// Return (after creating it if necessary) the TDataMember
277/// describing the data member corresponding to the Decl 'id'.
278/// The skipChecks flag controls the consistency checks performed inspecting
279/// the AST. In some cases, we explicitly alter the datamembers in the
280/// typesystem with respect to the AST and therefore we must not enforce
281/// consistency.
282
283TDictionary *TListOfDataMembers::Get(DataMemberInfo_t *info, bool skipChecks)
284{
285 if (!info) return 0;
286
287 TDictionary::DeclId_t id = gInterpreter->GetDeclId(info);
288 R__ASSERT( id != 0 && "DeclId should not be null");
289 TDictionary *dm = fIds ? (TDataMember*)fIds->GetValue((Long64_t)id) : 0;
290 if (!dm) {
291 if (fClass) {
293 // The interpreter does not know about this class yet (or a problem
294 // occurred that prevented the proper updating of fClassInfo).
295 // So this decl can not possibly be part of this class.
296 // [In addition calling GetClassInfo would trigger a late parsing
297 // of the header which we want to avoid].
298 return 0;
299 }
300 if (!skipChecks && !gInterpreter->ClassInfo_Contains(fClass->GetClassInfo(),id)) return 0;
301 } else {
302 if (!skipChecks && !gInterpreter->ClassInfo_Contains(0,id)) return 0;
303 }
304
306
307 DataMemberInfo_t *dm_info = gInterpreter->DataMemberInfo_FactoryCopy(info);
308
309 // Let's see if this is a reload ...
310 const char *name = gInterpreter->DataMemberInfo_Name(info);
312 if (update) {
313 update->Update(dm_info);
314 dm = update;
315 }
316 if (!dm) {
317 if (fClass) dm = new TDataMember(dm_info, fClass);
318 else dm = new TGlobal(dm_info);
319 }
320 // Calling 'just' THahList::Add would turn around and call
321 // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
323 if (!fIds) fIds = new TExMap(idsSize);
324 fIds->Add((Long64_t)id,(Long64_t)dm);
325 }
326 return dm;
327}
328
329////////////////////////////////////////////////////////////////////////////////
330/// Remove a pair<id, object> from the map of data members and their ids.
331
333{
334 if (!fIds) return;
335 if (fClass) {
336 TDataMember *d = dynamic_cast<TDataMember*>(obj);
337 if (d) {
338 if (d->GetDeclId()) {
339 fIds->Remove((Long64_t)d->GetDeclId());
340 }
341 d->Update(0);
342 }
343 } else {
344 TGlobal *g = dynamic_cast<TGlobal*>(obj);
345 if (g) {
346 if (g->GetDeclId()) {
347 fIds->Remove((Long64_t)g->GetDeclId());
348 }
349 g->Update(0);
350 }
351 }
352}
353
354////////////////////////////////////////////////////////////////////////////////
355/// Remove object from this collection and recursively remove the object
356/// from all other objects (and collections).
357/// This function overrides TCollection::RecursiveRemove that calls
358/// the Remove function. THashList::Remove cannot be called because
359/// it uses the hash value of the hash table. This hash value
360/// is not available anymore when RecursiveRemove is called from
361/// the TObject destructor.
362
364{
365 if (!obj) return;
366
369 UnmapObject(obj);
370
371}
372
373////////////////////////////////////////////////////////////////////////////////
374/// Remove object from the list.
375
377{
378 Bool_t found;
379
380 found = THashList::Remove(obj);
381 if (!found && fUnloaded) {
382 found = fUnloaded->Remove(obj);
383 }
384 UnmapObject(obj);
385 if (found) return obj;
386 else return 0;
387}
388
389////////////////////////////////////////////////////////////////////////////////
390/// Remove object via its objlink from the list.
391
393{
394 if (!lnk) return 0;
395
396 TObject *obj = lnk->GetObject();
397
399 if (fUnloaded) fUnloaded->Remove(obj);
400
401 UnmapObject(obj);
402 return obj;
403}
404
405////////////////////////////////////////////////////////////////////////////////
406/// Load all the DataMembers known to the interpreter for the scope 'fClass'
407/// into this collection.
408
410{
412 // Class and union are not extendable, if we already
413 // loaded all the data member there is no need to recheck
414 if (fIsLoaded) return;
415 }
416
417 // This will provoke the parsing of the headers if need be.
418 if (fClass && fClass->GetClassInfo() == 0) return;
419
421
422 ULong64_t currentTransaction = gInterpreter->GetInterpreterStateMarker();
423 if (currentTransaction == fLastLoadMarker) {
424 return;
425 }
426 fLastLoadMarker = currentTransaction;
427
428 // In the case of namespace, even if we have loaded before we need to
429 // load again in case there was new data member added.
430
431 // Mark the list as loaded to avoid an infinite recursion in the case
432 // where we have a data member that is a variable size array. In that
433 // case TDataMember::Init needs to get/load the list to find the data
434 // member used as the array size.
436
437 ClassInfo_t *info;
438 if (fClass) info = fClass->GetClassInfo();
439 else info = gInterpreter->ClassInfo_Factory();
440
441 // Treat the complex<float>, complex<double> in a special way, i.e. replacing
442 // the datamembers with the ones of _root_std_complex<T>
443 bool skipChecks = false;
444 if (fClass) {
445 auto complexType = TClassEdit::GetComplexType(fClass->GetName());
446 switch(complexType) {
448 {
449 break;
450 }
452 {
453 skipChecks = true;
454 info = TClass::GetClass("_root_std_complex<float>")->GetClassInfo();
455 break;
456 }
458 {
459 skipChecks = true;
460 info = TClass::GetClass("_root_std_complex<double>")->GetClassInfo();
461 break;
462 }
464 {
465 skipChecks = true;
466 info = TClass::GetClass("_root_std_complex<int>")->GetClassInfo();
467 break;
468 }
470 {
471 skipChecks = true;
472 info = TClass::GetClass("_root_std_complex<long>")->GetClassInfo();
473 break;
474 }
475 }
476 }
477
478 // Now we follow the ordinary pattern
479 DataMemberInfo_t *t = gInterpreter->DataMemberInfo_Factory(info);
480 while (gInterpreter->DataMemberInfo_Next(t)) {
481 if (gInterpreter->DataMemberInfo_IsValid(t)) {
482 // Get will check if there is already there or create a new one
483 // (or re-use a previously unloaded version).
484 Get(t,skipChecks);
485 }
486 }
487 gInterpreter->DataMemberInfo_Delete(t);
488 if (!fClass) gInterpreter->ClassInfo_Delete(info);
489}
490
491////////////////////////////////////////////////////////////////////////////////
492/// Stream an object of class TListOfDataMembers.
493
494void TListOfDataMembers::Streamer(TBuffer &R__b)
495{
496 if (R__b.IsReading()) {
499 } else {
501 }
502}
503
504////////////////////////////////////////////////////////////////////////////////
505/// Move the member or data member to the expect set of list.
506
508 if (fClass) {
509 TDataMember *d = dynamic_cast<TDataMember*>(member);
510 if (d) {
511 if (d->GetDeclId()) {
512 if (!fIds) fIds = new TExMap(idsSize);
513 fIds->Add((Long64_t)d->GetDeclId(),(Long64_t)d);
514 }
517
518 if (! THashList::FindObject(d) ) {
519 // Calling 'just' THahList::Add would turn around and call
520 // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
522 }
523 }
524 } else {
525 TGlobal *g = dynamic_cast<TGlobal*>(member);
526 if (g) {
527 if (g->GetDeclId()) {
528 if (!fIds) fIds = new TExMap(idsSize);
529 fIds->Add((Long64_t)g->GetDeclId(),(Long64_t)g);
530
533
534 if (! THashList::FindObject(g) ) {
535 // Calling 'just' THahList::Add would turn around and call
536 // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
538 }
539 }
540 }
541 }
542
543
544}
545
546////////////////////////////////////////////////////////////////////////////////
547/// Mark 'all func' as being unloaded.
548/// After the unload, the data member can no longer be found directly,
549/// until the decl can be found again in the interpreter (in which
550/// the func object will be reused.
551
553{
554 TObjLink *lnk = FirstLink();
555 while (lnk) {
558 if (!fUnloaded) fUnloaded = new THashList;
560
561 lnk = lnk->Next();
562 }
563
566}
567
568////////////////////////////////////////////////////////////////////////////////
569/// Mark 'func' as being unloaded.
570/// After the unload, the data member can no longer be found directly,
571/// until the decl can be found again in the interpreter (in which
572/// the func object will be reused.
573
575{
576 if (THashList::Remove(mem)) {
577 // We contains the object, let remove it from the other internal
578 // list and move it to the list of unloaded objects.
579
580 UnmapObject(mem);
581 if (!fUnloaded) fUnloaded = new THashList;
582 fUnloaded->Add(mem);
583 }
584}
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:363
@ kIsClass
Definition: TDictionary.h:65
@ kIsStruct
Definition: TDictionary.h:66
@ kIsUnion
Definition: TDictionary.h:67
#define R__ASSERT(e)
Definition: TError.h:96
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:40
#define gInterpreter
Definition: TInterpreter.h:538
const unsigned int idsSize
#define R__LOCKGUARD(mutex)
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
Bool_t IsReading() const
Definition: TBuffer.h:83
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
The ROOT global object gROOT contains a list of all defined classes.
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:5800
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:2885
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:159
const void * DeclId_t
Definition: TDictionary.h:206
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:268
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:99