Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TListOfTypes.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 TListOfTypes
13 \ingroup Base
14 
15 A collection of TDataType designed to hold the typedef information
16 and numerical type information. The collection is populated on demand.
17 
18 Besides the built-in types (int, float) a typedef is explicitly
19 added to the collection (and thus visible via ls or Print) only if
20 it is requested explicitly.
21 */
22 
23 
24 #include "TListOfTypes.h"
25 
26 #include "TInterpreter.h"
27 #include "TDataType.h"
28 #include "TVirtualMutex.h"
29 
30 #include "TClassTable.h"
31 #include "TROOT.h"
32 #include "TClass.h"
33 #include "TProtoClass.h"
34 #include "TListOfEnums.h"
35 
36 TListOfTypes::TListOfTypes() : THashTable(100, 3)
37 {
38  // Constructor
39  TDataType::AddBuiltins(this);
40 }
41 
42 TObject *TListOfTypes::FindObject(const char *name) const
43 {
44  // Specialize FindObject to do search for the
45  // typedef if its not already in the list
46 
47  return FindType(name);
48 }
49 
50 static bool NameExistsElsewhere(const char* name){
51 
52  // Is this a scope?
53  // We look into the list of classes available,
54  // the ones in the dictionaries and the protoclasses.
55  if (gROOT->GetListOfClasses()->FindObject(name) ||
56  TClassTable::GetDictNorm(name) ||
57  TClassTable::GetProtoNorm(name)) return true;
58 
59  // Is this an enum?
60  TObject* theEnum = nullptr;
61  const auto lastPos = strrchr(name, ':');
62  if (lastPos != nullptr) {
63  // We have a scope
64  const auto enName = lastPos + 1;
65  const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)name) / sizeof(decltype(*lastPos)) - 1;
66 #ifdef R__WIN32
67  char *scopeName = new char[scopeNameSize + 1];
68 #else
69  char scopeName[scopeNameSize + 1]; // on the stack, +1 for the terminating character '\0'
70 #endif
71  strncpy(scopeName, name, scopeNameSize);
72  scopeName[scopeNameSize] = '\0';
73  // We have now an enum name and a scope name
74  // We look first in the classes
75  if(auto scope = dynamic_cast<TClass*>(gROOT->GetListOfClasses()->FindObject(scopeName))){
76  theEnum = ((TListOfEnums*)scope->GetListOfEnums(false))->THashList::FindObject(enName);
77  }
78  // And then if not found in the protoclasses
79  if (!theEnum){
80  if (auto scope = TClassTable::GetProtoNorm(scopeName)){
81  if (auto listOfEnums = (TListOfEnums*)scope->GetListOfEnums())
82  theEnum = listOfEnums->THashList::FindObject(enName);
83  }
84  }
85 #ifdef R__WIN32
86  delete [] scopeName;
87 #endif
88  } else { // Here we look in the global scope
89  theEnum = ((TListOfEnums*)gROOT->GetListOfEnums())->THashList::FindObject(name);
90  }
91 
92  return nullptr != theEnum;
93 
94 }
95 
96 TDataType *TListOfTypes::FindType(const char *name) const
97 {
98  // Look for a type, first in the hast table
99  // then in the interpreter.
100 
101  R__COLLECTION_READ_GUARD();
102 
103  TDataType *result = static_cast<TDataType*>(THashTable::FindObject(name));
104  if (!result) {
105 
106  if (NameExistsElsewhere(name)) {
107  return nullptr;
108  }
109 
110  // We perform now a lookup
111 
112  R__LOCKGUARD(gInterpreterMutex);
113 
114  TypedefInfo_t *info = gInterpreter->TypedefInfo_Factory(name);
115  if (gInterpreter->TypedefInfo_IsValid(info)) {
116  result = new TDataType(info);
117  // Double check we did not get a different spelling of an
118  // already existing typedef.
119  if (strcmp(name,result->GetName()) != 0) {
120  TDataType *alt = static_cast<TDataType*>(THashTable::FindObject(result->GetName()));
121  if (!alt)
122  const_cast<TListOfTypes*>(this)->Add(result);
123  else {
124  delete result;
125  result = alt;
126  }
127  } else {
128  const_cast<TListOfTypes*>(this)->Add(result);
129  }
130  } else {
131  gInterpreter->TypedefInfo_Delete(info);
132  }
133  }
134  return result;
135 }