CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DictionaryTools.cc
Go to the documentation of this file.
7 
8 #include "Api.h" // for G__ClassInfo
9 
10 #include "TROOT.h"
11 #include "TInterpreter.h"
12 #include "TVirtualMutex.h"
13 
14 #include "boost/algorithm/string.hpp"
15 #include "boost/thread/tss.hpp"
16 
17 #include <algorithm>
18 #include <sstream>
19 
20 namespace edm {
21 
23  static std::string const prefix("LCGReflex/");
24  return prefix;
25  }
26 
29 
30  namespace {
31 
32  int const oneParamArraySize = 6;
33  std::string const oneParam[oneParamArraySize] = {
34  "vector",
35  "basic_string",
36  "set",
37  "list",
38  "deque",
39  "multiset"
40  };
41  int const twoParamArraySize = 3;
42  std::string const twoParam[twoParamArraySize] = {
43  "map",
44  "pair",
45  "multimap"
46  };
47 
48 
49  bool
50  hasCintDictionary(std::string const& name) {
51  std::auto_ptr<G__ClassInfo> ci(new G__ClassInfo(name.c_str()));
52  return(ci.get() && ci->IsLoaded());
53  }
54 
55  // Checks if there is a dictionary for the Type t.
56  // If noComponents is false, checks members and base classes recursively.
57  // If noComponents is true, checks Type t only.
58  void
59  checkType(TypeWithDict t, bool noComponents = false) {
60 
61  // ToType strips const, volatile, array, pointer, reference, etc.,
62  // and also translates typedefs.
63  // To be safe, we do this recursively until we either get a void type or the same type.
64  for(TypeWithDict x(t.toType()); x != t && x.typeInfo() != typeid(void); t = x, x = t.toType()) {}
65 
66  std::string name(t.name());
67  boost::trim(name);
68 
69  if(foundTypes().end() != foundTypes().find(name) || missingTypes().end() != missingTypes().find(name)) {
70  // Already been processed. Prevents infinite loop.
71  return;
72  }
73 
74  if(name.empty() || t.isFundamental() || t.isEnum() || t.typeInfo() == typeid(void)) {
75  foundTypes().insert(name);
76  return;
77  }
78 
79  if(!bool(t)) {
80  if(hasCintDictionary(name)) {
81  foundTypes().insert(name);
82  } else {
83  missingTypes().insert(name);
84  }
85  return;
86  }
87 
88  foundTypes().insert(name);
89  if(noComponents) return;
90 
91  if(name.find("std::") == 0) {
92  if(t.isTemplateInstance()) {
93  std::string::size_type n = name.find('<');
94  int cnt = 0;
95  if(std::find(oneParam, oneParam + oneParamArraySize, name.substr(5, n - 5)) != oneParam + oneParamArraySize) {
96  cnt = 1;
97  } else if(std::find(twoParam, twoParam + twoParamArraySize, name.substr(5, n - 5)) != twoParam + twoParamArraySize) {
98  cnt = 2;
99  }
100  for(int i = 0; i < cnt; ++i) {
102  }
103  }
104  } else {
105  TypeDataMembers members(t);
106  for(auto const& member : members) {
107  MemberWithDict m(member);
108  if(!m.isTransient() && !m.isStatic()) {
109  checkType(m.typeOf());
110  }
111  }
112  {
113  R__LOCKGUARD(gCINTMutex);
114  TypeBases bases(t);
115  for(auto const& base : bases) {
117  checkType(b.typeOf());
118  }
119  }
120  }
121  }
122  } // end unnamed namespace
123 
125  return missingTypes_;
126  }
127 
129  // The only purpose of this cache is to stop infinite recursion.
130  // ROOT maintains its own internal cache.
131  return foundTypes_;
132  }
133 
134  void checkDictionaries(std::string const& name, bool noComponents) {
135  TypeWithDict null;
137  if(t == null) {
138  if(name == std::string("void")) {
139  foundTypes().insert(name);
140  } else {
141  missingTypes().insert(name);
142  }
143  return;
144  }
145  checkType(t, noComponents);
146  }
147 
149  if(!missingTypes().empty()) {
150  std::ostringstream ostr;
151  for (StringSet::const_iterator it = missingTypes().begin(), itEnd = missingTypes().end();
152  it != itEnd; ++it) {
153  ostr << *it << "\n\n";
154  }
156  << "No REFLEX data dictionary found for the following classes:\n\n"
157  << ostr.str()
158  << "Most likely each dictionary was never generated,\n"
159  << "but it may be that it was generated in the wrong package.\n"
160  << "Please add (or move) the specification\n"
161  << "<class name=\"whatever\"/>\n"
162  << "to the appropriate classes_def.xml file.\n"
163  << "If the class is a template instance, you may need\n"
164  << "to define a dummy variable of this type in classes.h.\n"
165  << "Also, if this class has any transient members,\n"
166  << "you need to specify them in classes_def.xml.";
167  }
168  }
169 
171  while (!missingTypes().empty()) {
173  for (StringSet::const_iterator it = missing.begin(), itEnd = missing.end();
174  it != itEnd; ++it) {
175  try {
176  TClass::GetClass(it->c_str(), kTRUE);
177  }
178  // We don't want to fail if we can't load a plug-in.
179  catch(...) {}
180  }
181  missingTypes().clear();
182  for (StringSet::const_iterator it = missing.begin(), itEnd = missing.end();
183  it != itEnd; ++it) {
184  checkDictionaries(*it);
185  }
186  if (missingTypes() == missing) {
187  break;
188  }
189  }
190  if (missingTypes().empty()) {
191  return;
192  }
194  }
195 
196  void public_base_classes(TypeWithDict const& typeID,
197  std::vector<TypeWithDict>& baseTypes) {
198 
199  TypeWithDict type(typeID.typeInfo());
200  if(type.isClass()) {
201  R__LOCKGUARD(gCINTMutex);
202  TypeBases bases(type);
203  for(auto const& basex : bases) {
204  BaseWithDict base(basex);
205  if(base.isPublic()) {
206 
207  TypeWithDict baseRflxType = base.typeOf();
208  if(bool(baseRflxType)) {
209  TypeWithDict baseType(baseRflxType.typeInfo());
210 
211  // Check to make sure this base appears only once in the
212  // inheritance heirarchy.
213  if(!search_all(baseTypes, baseType)) {
214  // Save the type and recursive look for its base types
215  baseTypes.push_back(baseType);
216  public_base_classes(baseType, baseTypes);
217  }
218  // For now just ignore it if the class appears twice,
219  // After some more testing we may decide to uncomment the following
220  // exception.
221  /*
222  else {
223  throw Exception(errors::UnimplementedFeature)
224  << "DataFormats/Common/src/DictionaryTools.cc in function public_base_classes.\n"
225  << "Encountered class that has a public base class that appears\n"
226  << "multiple times in its inheritance heirarchy.\n"
227  << "Please contact the EDM Framework group with details about\n"
228  << "this exception. It was our hope that this complicated situation\n"
229  << "would not occur. There are three possible solutions. 1. Change\n"
230  << "the class design so the public base class does not appear multiple\n"
231  << "times in the inheritance heirarchy. In many cases, this is a\n"
232  << "sign of bad design. 2. Modify the code that supports Views to\n"
233  << "ignore these base classes, but not supply support for creating a\n"
234  << "View of this base class. 3. Improve the View infrastructure to\n"
235  << "deal with this case. Class name of base class: " << baseType.Name() << "\n\n";
236  }
237  */
238  }
239  }
240  }
241  }
242  }
243 }
tuple base
Main Program
Definition: newFWLiteAna.py:92
type
Definition: HCALResponse.h:21
bool isEnum() const
dictionary missing
Definition: combine.py:4
int i
Definition: DBlmapReader.cc:9
static TypeWithDict byName(std::string const &className)
bool isStatic() const
std::string const & dictionaryPlugInPrefix()
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
uint16_t size_type
TypeWithDict toType() const
void public_base_classes(TypeWithDict const &type, std::vector< TypeWithDict > &baseTypes)
TypeWithDict templateArgumentAt(size_t index) const
bool isTemplateInstance() const
std::string name() const
StringSet & missingTypes()
std::set< std::string > StringSet
void checkDictionaries(std::string const &name, bool noComponents=false)
TypeWithDict typeOf() const
bool isFundamental() const
std::type_info const & typeInfo() const
TypeWithDict typeOf() const
Definition: BaseWithDict.cc:15
#define end
Definition: vmac.h:37
StringSet & foundTypes()
void throwMissingDictionariesException()
static StringSet foundTypes_
bool search_all(ForwardSequence const &s, Datum const &d)
Definition: Algorithms.h:46
double b
Definition: hdecay.h:120
void loadMissingDictionaries()
bool isTransient() const
#define begin
Definition: vmac.h:30
Definition: DDAxes.h:10
static StringSet missingTypes_
bool isPublic() const
Definition: BaseWithDict.cc:25