Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
34
35////////////////////////////////////////////////////////////////////////////////
36/// Destructor.
37
45
46////////////////////////////////////////////////////////////////////////////////
47/// Add a pair<id, object> to the map of data members and their ids.
48
50{
51 if (!fIds) fIds = new TExMap(idsSize);
52
53 if (fClass) {
54 TDataMember *d = dynamic_cast<TDataMember*>(obj);
55 if (d) {
56 fIds->Add((Long64_t)d->GetDeclId(),(Long64_t)d);
57 }
58 } else {
59 TGlobal *g = dynamic_cast<TGlobal*>(obj);
60 if (g && g->GetDeclId()) {
61 fIds->Add((Long64_t)g->GetDeclId(),(Long64_t)g);
62 }
63 }
64}
65
66////////////////////////////////////////////////////////////////////////////////
67/// Add object at the beginning of the list.
68
74
75////////////////////////////////////////////////////////////////////////////////
76/// Add object at the beginning of the list and also store option.
77/// Storing an option is useful when one wants to change the behaviour
78/// of an object a little without having to create a complete new
79/// copy of the object. This feature is used, for example, by the Draw()
80/// method. It allows the same object to be drawn in different ways.
81
83{
84 THashList::AddFirst(obj,opt);
85 MapObject(obj);
86}
87
88////////////////////////////////////////////////////////////////////////////////
89/// Add object at the end of the list.
90
96
97////////////////////////////////////////////////////////////////////////////////
98/// Add object at the end of the list and also store option.
99/// Storing an option is useful when one wants to change the behaviour
100/// of an object a little without having to create a complete new
101/// copy of the object. This feature is used, for example, by the Draw()
102/// method. It allows the same object to be drawn in different ways.
103
105{
106 THashList::AddLast(obj, opt);
107 MapObject(obj);
108}
109
110////////////////////////////////////////////////////////////////////////////////
111/// Insert object at location idx in the list.
112
114{
115 THashList::AddAt(obj, idx);
116 MapObject(obj);
117}
118
119
120////////////////////////////////////////////////////////////////////////////////
121/// Insert object at location idx in the list, with options.
122
124{
125 THashList::AddAt(obj, idx, opt);
126 MapObject(obj);
127}
128
129////////////////////////////////////////////////////////////////////////////////
130/// Insert object after object after in the list.
131
133{
135 MapObject(obj);
136}
137
138////////////////////////////////////////////////////////////////////////////////
139/// Insert object after object after in the list.
140
146
147////////////////////////////////////////////////////////////////////////////////
148/// Insert object after object after in the list, with options.
149
151{
152 THashList::AddAfter(after, obj, opt);
153 MapObject(obj);
154}
155
156////////////////////////////////////////////////////////////////////////////////
157/// Insert object after object after in the list, with options.
158
160{
161 THashList::AddAfter(after, obj, opt);
162 MapObject(obj);
163}
164
165////////////////////////////////////////////////////////////////////////////////
166/// Insert object before object before in the list.
167
173
174////////////////////////////////////////////////////////////////////////////////
175/// Insert object before object before in the list.
176
182
183////////////////////////////////////////////////////////////////////////////////
184/// Insert object before object before in the list, with options.
185
187{
188 THashList::AddBefore(before, obj, opt);
189 MapObject(obj);
190}
191
192////////////////////////////////////////////////////////////////////////////////
193/// Insert object before object before in the list, with options.
194
200
201////////////////////////////////////////////////////////////////////////////////
202/// Remove all objects from the list. Does not delete the objects unless
203/// the THashList is the owner (set via SetOwner()).
204
212
213////////////////////////////////////////////////////////////////////////////////
214/// Delete all TDataMember object files.
215
222
223////////////////////////////////////////////////////////////////////////////////
224/// Specialize FindObject to do search for the
225/// a data member just by name or create it if its not already in the list
226
228{
230 if (!result) {
232 // We already have all the information, no need to search more
233 return nullptr;
234 }
235
237
239 if (fClass) decl = gInterpreter->GetDataMember(fClass->GetClassInfo(),name);
240 else decl = gInterpreter->GetDataMember(nullptr,name);
241 if (decl) result = const_cast<TListOfDataMembers*>(this)->Get(decl);
242 }
243 return result;
244}
245
246////////////////////////////////////////////////////////////////////////////////
247/// Return (after creating it if necessary) the TDataMember
248/// describing the data member corresponding to the Decl 'id'.
249
251{
252 if (!id) return nullptr;
253
254 return fIds ? (TDataMember*)fIds->GetValue((Long64_t)id) : nullptr;
255}
256
257////////////////////////////////////////////////////////////////////////////////
258/// Return (after creating it if necessary) the TDataMember
259/// describing the data member corresponding to the Decl 'id'.
260
262{
263 if (!id) return nullptr;
264
266 //need the Find and possible Add to be one atomic operation
267 TDictionary *dm = Find(id);
268 if (dm) return dm;
269
270 if (fClass) {
272 // The interpreter does not know about this class yet (or a problem
273 // occurred that prevented the proper updating of fClassInfo).
274 // So this decl can not possibly be part of this class.
275 // [In addition calling GetClassInfo would trigger a late parsing
276 // of the header which we want to avoid].
277 return nullptr;
278 }
279 if (!gInterpreter->ClassInfo_Contains(fClass->GetClassInfo(),id)) return nullptr;
280 } else {
281 if (!gInterpreter->ClassInfo_Contains(nullptr,id)) return nullptr;
282 }
283
284 DataMemberInfo_t *info = gInterpreter->DataMemberInfo_Factory(id,fClass ? fClass->GetClassInfo() : nullptr);
285
286 // Let's see if this is a reload ...
287 const char *name = gInterpreter->DataMemberInfo_Name(info);
289 if (update) {
290 if (fClass) {
291 ((TDataMember*)update)->Update(info);
292 } else {
293 ((TGlobal*)update)->Update(info);
294 }
295 dm = update;
296 }
297 if (!dm) {
298 if (fClass) dm = new TDataMember(info, fClass);
299 else dm = new TGlobal(info);
300 }
301 // Calling 'just' THahList::Add would turn around and call
302 // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
304 if (!fIds) fIds = new TExMap(idsSize);
305 fIds->Add((Long64_t)id,(Long64_t)dm);
306
307 return dm;
308}
309
310////////////////////////////////////////////////////////////////////////////////
311/// Return (after creating it if necessary) the TDataMember
312/// describing the data member corresponding to the Decl 'id'.
313/// The skipChecks flag controls the consistency checks performed inspecting
314/// the AST. In some cases, we explicitly alter the datamembers in the
315/// typesystem with respect to the AST and therefore we must not enforce
316/// consistency.
317
319{
320 if (!info) return nullptr;
321
322 TDictionary::DeclId_t id = gInterpreter->GetDeclId(info);
323 R__ASSERT( id != nullptr && "DeclId should not be null");
324 TDictionary *dm = fIds ? (TDataMember*)fIds->GetValue((Long64_t)id) : nullptr;
325 if (!dm) {
326 if (fClass) {
328 // The interpreter does not know about this class yet (or a problem
329 // occurred that prevented the proper updating of fClassInfo).
330 // So this decl can not possibly be part of this class.
331 // [In addition calling GetClassInfo would trigger a late parsing
332 // of the header which we want to avoid].
333 return nullptr;
334 }
335 if (!skipChecks && !gInterpreter->ClassInfo_Contains(fClass->GetClassInfo(),id)) return nullptr;
336 } else {
337 if (!skipChecks && !gInterpreter->ClassInfo_Contains(nullptr,id)) return nullptr;
338 }
339
341
342 DataMemberInfo_t *dm_info = gInterpreter->DataMemberInfo_FactoryCopy(info);
343
344 // Let's see if this is a reload ...
345 const char *name = gInterpreter->DataMemberInfo_Name(info);
347 if (update) {
348 update->Update(dm_info);
349 dm = update;
350 }
351 if (!dm) {
352 if (fClass) dm = new TDataMember(dm_info, fClass);
353 else dm = new TGlobal(dm_info);
354 }
355 // Calling 'just' THahList::Add would turn around and call
356 // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
358 if (!fIds) fIds = new TExMap(idsSize);
359 fIds->Add((Long64_t)id,(Long64_t)dm);
360 }
361 return dm;
362}
363
364////////////////////////////////////////////////////////////////////////////////
365/// Remove a pair<id, object> from the map of data members and their ids.
366
368{
369 if (!fIds) return;
370 if (fClass) {
371 TDataMember *d = dynamic_cast<TDataMember*>(obj);
372 if (d) {
373 if (d->GetDeclId()) {
374 fIds->Remove((Long64_t)d->GetDeclId());
375 }
376 d->Update(nullptr);
377 }
378 } else {
379 TGlobal *g = dynamic_cast<TGlobal*>(obj);
380 if (g) {
381 if (g->GetDeclId()) {
382 fIds->Remove((Long64_t)g->GetDeclId());
383 }
384 g->Update(nullptr);
385 }
386 }
387}
388
389////////////////////////////////////////////////////////////////////////////////
390/// Remove object from this collection and recursively remove the object
391/// from all other objects (and collections).
392/// This function overrides TCollection::RecursiveRemove that calls
393/// the Remove function. THashList::Remove cannot be called because
394/// it uses the hash value of the hash table. This hash value
395/// is not available anymore when RecursiveRemove is called from
396/// the TObject destructor.
397
399{
400 if (!obj) return;
401
404 UnmapObject(obj);
405
406}
407
408////////////////////////////////////////////////////////////////////////////////
409/// Remove object from the list.
410
412{
413 Bool_t found;
414
415 found = THashList::Remove(obj);
416 if (!found && fUnloaded) {
417 found = fUnloaded->Remove(obj);
418 }
419 UnmapObject(obj);
420 if (found) return obj;
421 else return nullptr;
422}
423
424////////////////////////////////////////////////////////////////////////////////
425/// Remove object via its objlink from the list.
426
428{
429 if (!lnk) return nullptr;
430
431 TObject *obj = lnk->GetObject();
432
434 if (fUnloaded) fUnloaded->Remove(obj);
435
436 UnmapObject(obj);
437 return obj;
438}
439
440////////////////////////////////////////////////////////////////////////////////
441/// Load all the DataMembers known to the interpreter for the scope 'fClass'
442/// into this collection.
443
445{
447 // Class and union are not extendable, if we already
448 // loaded all the data member there is no need to recheck
449 if (fIsLoaded) return;
450 }
451
452 // This will provoke the parsing of the headers if need be.
453 if (fClass && fClass->GetClassInfo() == nullptr) return;
454
456
457 ULong64_t currentTransaction = gInterpreter->GetInterpreterStateMarker();
459 return;
460 }
462
463 // In the case of namespace, even if we have loaded before we need to
464 // load again in case there was new data member added.
465
466 // Mark the list as loaded to avoid an infinite recursion in the case
467 // where we have a data member that is a variable size array. In that
468 // case TDataMember::Init needs to get/load the list to find the data
469 // member used as the array size.
471
473 if (fClass) info = fClass->GetClassInfo();
474 else info = gInterpreter->ClassInfo_Factory();
475
476 // Treat the complex<float>, complex<double> in a special way, i.e. replacing
477 // the datamembers with the ones of _root_std_complex<T>
478 bool skipChecks = false;
479 if (fClass) {
481 switch(complexType) {
483 {
484 break;
485 }
487 {
488 skipChecks = true;
489 info = TClass::GetClass("_root_std_complex<float>")->GetClassInfo();
490 break;
491 }
493 {
494 skipChecks = true;
495 info = TClass::GetClass("_root_std_complex<double>")->GetClassInfo();
496 break;
497 }
499 {
500 skipChecks = true;
501 info = TClass::GetClass("_root_std_complex<int>")->GetClassInfo();
502 break;
503 }
505 {
506 skipChecks = true;
507 info = TClass::GetClass("_root_std_complex<long>")->GetClassInfo();
508 break;
509 }
510 }
511 }
512
513 // Now we follow the ordinary pattern
514 DataMemberInfo_t *t = gInterpreter->DataMemberInfo_Factory(info, fSelection);
515 while (gInterpreter->DataMemberInfo_Next(t)) {
516 if (gInterpreter->DataMemberInfo_IsValid(t)) {
517 // Get will check if there is already there or create a new one
518 // (or re-use a previously unloaded version).
519 Get(t,skipChecks);
520 }
521 }
522 gInterpreter->DataMemberInfo_Delete(t);
523 if (!fClass) gInterpreter->ClassInfo_Delete(info);
524}
525
526////////////////////////////////////////////////////////////////////////////////
527/// Stream an object of class TListOfDataMembers.
528
530{
531 if (R__b.IsReading()) {
532 R__b.ReadClassBuffer(TListOfDataMembers::Class(),this);
534 } else {
535 R__b.WriteClassBuffer(TListOfDataMembers::Class(),this);
536 }
537}
538
539////////////////////////////////////////////////////////////////////////////////
540/// Move the member or data member to the expect set of list.
541
543 if (fClass) {
544 TDataMember *d = dynamic_cast<TDataMember*>(member);
545 if (d) {
546 if (d->GetDeclId()) {
547 if (!fIds) fIds = new TExMap(idsSize);
548 fIds->Add((Long64_t)d->GetDeclId(),(Long64_t)d);
549 }
550 TDictionary *update = fUnloaded ? (TDictionary *)fUnloaded->FindObject(d->GetName()) : nullptr;
552
553 if (! THashList::FindObject(d) ) {
554 // Calling 'just' THahList::Add would turn around and call
555 // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
557 }
558 }
559 } else {
560 TGlobal *g = dynamic_cast<TGlobal*>(member);
561 if (g) {
562 if (g->GetDeclId()) {
563 if (!fIds) fIds = new TExMap(idsSize);
564 fIds->Add((Long64_t)g->GetDeclId(),(Long64_t)g);
565
566 TDictionary *update = fUnloaded ? (TDictionary *)fUnloaded->FindObject(g->GetName()) : nullptr;
568
569 if (! THashList::FindObject(g) ) {
570 // Calling 'just' THahList::Add would turn around and call
571 // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
573 }
574 }
575 }
576 }
577
578
579}
580
581////////////////////////////////////////////////////////////////////////////////
582/// Mark 'all func' as being unloaded.
583/// After the unload, the data member can no longer be found directly,
584/// until the decl can be found again in the interpreter (in which
585/// the func object will be reused.
586
588{
590 while (lnk) {
591 TDictionary *data = (TDictionary *)lnk->GetObject();
593 if (!fUnloaded) fUnloaded = new THashList;
595
596 lnk = lnk->Next();
597 }
598
601}
602
603////////////////////////////////////////////////////////////////////////////////
604/// Mark 'func' as being unloaded.
605/// After the unload, the data member can no longer be found directly,
606/// until the decl can be found again in the interpreter (in which
607/// the func object will be reused.
608
610{
611 if (THashList::Remove(mem)) {
612 // We contains the object, let remove it from the other internal
613 // list and move it to the list of unloaded objects.
614
616 if (!fUnloaded) fUnloaded = new THashList;
617 fUnloaded->Add(mem);
618 }
619}
#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)
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
@ kIsClass
Definition TDictionary.h:65
@ kIsStruct
Definition TDictionary.h:66
@ kIsUnion
Definition TDictionary.h:67
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
char name[80]
Definition TGX11.cxx:110
R__EXTERN TVirtualMutex * gInterpreterMutex
#define gInterpreter
const unsigned int idsSize
#define R__LOCKGUARD(mutex)
Buffer base class used for serializing objects.
Definition TBuffer.h:43
Bool_t HasInterpreterInfoInMemory() const
Definition TClass.h:421
ClassInfo_t * GetClassInfo() const
Definition TClass.h:445
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6128
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:2973
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...
const void * DeclId_t
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
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
void AddBefore(const TObject *before, TObject *obj) override
Insert object before object before in the list.
void Clear(Option_t *option="") override
Remove all objects from the list.
void AddFirst(TObject *obj) override
Add object at the beginning of the list.
Definition THashList.cxx:68
void AddAfter(const TObject *after, TObject *obj) override
Insert object after object after in the list.
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
void AddAt(TObject *obj, Int_t idx) override
Insert object at location idx in the list.
THashList(const THashList &)=delete
TObject * Remove(TObject *obj) override
Remove object from the list.
TObject * FindObject(const char *name) const override
Find object using its name.
void AddLast(TObject *obj) override
Add object at the end of the list.
Definition THashList.cxx:94
TDictionary::DeclId_t DeclId_t
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
void Delete(Option_t *option="") override
Delete all TDataMember object files.
void AddAt(TObject *obj, Int_t idx) override
Insert object at location idx in the list.
TObject * FindObject(const char *name) const override
Specialize FindObject to do search for the a data member just by name or create it if its not already...
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
void AddAfter(const TObject *after, TObject *obj) override
Insert object after object after in the list.
TDictionary::DeclId_t DeclId_t
void Streamer(TBuffer &) override
Stream an object of class TListOfDataMembers.
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.
TDictionary::EMemberSelection fSelection
Mark whether Load was executed.
void Clear(Option_t *option="") override
Remove all objects from the list.
ULong64_t fLastLoadMarker
Holder of TDataMember for unloaded DataMembers.
~TListOfDataMembers()
Destructor.
std::atomic< bool > fIsLoaded
Represent interpreter state when we last did a full load.
TObject * Remove(TObject *obj) override
Remove object from the list.
TExMap * fIds
Context of this list. Not owned.
void AddBefore(const TObject *before, TObject *obj) override
Insert object before object before in the list.
void UnmapObject(TObject *obj)
Remove a pair<id, object> from the map of data members and their ids.
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*.
void AddLast(TObject *obj) override
Add object at the end of the list.
static TClass * Class()
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.
void AddFirst(TObject *obj) override
Add object at the beginning of the list.
void Add(TObject *obj) override
Definition TList.h:81
virtual TObjLink * FirstLink() const
Definition TList.h:107
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Clear(Option_t *="")
Definition TObject.h:125
EComplexType GetComplexType(const char *)