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 
12 #include "boost/algorithm/string.hpp"
13 #include "boost/thread/tss.hpp"
14 
15 #include <algorithm>
16 #include <sstream>
17 
18 namespace edm {
19 
21  static std::string const prefix("LCGReflex/");
22  return prefix;
23  }
24 
27 
28  bool
29  find_nested_type_named(std::string const& nested_type,
30  TypeWithDict const& typeToSearch,
31  TypeWithDict& found_type) {
32  // Look for a sub-type named 'nested_type'
33  TypeWithDict foundType = typeToSearch.nestedType(nested_type);
34  if(bool(foundType)) {
35  found_type = foundType;
36  return true;
37  }
38  return false;
39  }
40 
41  bool
42  is_RefVector(TypeWithDict const& possibleRefVector,
44 
45  static std::string const template_name("edm::RefVector");
46  static std::string const member_type("member_type");
47  if(template_name == possibleRefVector.templateName()) {
48  return find_nested_type_named(member_type, possibleRefVector, value_type);
49  }
50  return false;
51  }
52 
53  bool
54  is_PtrVector(TypeWithDict const& possibleRefVector,
56 
57  static std::string const template_name("edm::PtrVector");
58  static std::string const member_type("member_type");
59  static std::string const val_type("value_type");
60  if(template_name == possibleRefVector.templateName()) {
61  TypeWithDict ptrType;
62  if(find_nested_type_named(val_type, possibleRefVector, ptrType)) {
63  return find_nested_type_named(val_type, ptrType, value_type);
64  }
65  }
66  return false;
67  }
68 
69  bool
70  is_RefToBaseVector(TypeWithDict const& possibleRefVector,
72 
73  static std::string const template_name("edm::RefToBaseVector");
74  static std::string const member_type("member_type");
75  if(template_name == possibleRefVector.templateName()) {
76  return find_nested_type_named(member_type, possibleRefVector, value_type);
77  }
78  return false;
79  }
80 
81  namespace {
82 
83  int const oneParamArraySize = 6;
84  std::string const oneParam[oneParamArraySize] = {
85  "vector",
86  "basic_string",
87  "set",
88  "list",
89  "deque",
90  "multiset"
91  };
92  int const twoParamArraySize = 3;
93  std::string const twoParam[twoParamArraySize] = {
94  "map",
95  "pair",
96  "multimap"
97  };
98 
99 
100  bool
101  hasCintDictionary(std::string const& name) {
102  std::auto_ptr<G__ClassInfo> ci(new G__ClassInfo(name.c_str()));
103  return(ci.get() && ci->IsLoaded());
104  }
105 
106  // Checks if there is a dictionary for the Type t.
107  // If noComponents is false, checks members and base classes recursively.
108  // If noComponents is true, checks Type t only.
109  void
110  checkType(TypeWithDict t, bool noComponents = false) {
111 
112  // ToType strips const, volatile, array, pointer, reference, etc.,
113  // and also translates typedefs.
114  // To be safe, we do this recursively until we either get a void type or the same type.
115  for(TypeWithDict x(t.toType()); x != t && x.typeInfo() != typeid(void); t = x, x = t.toType()) {}
116 
117  std::string name(t.name());
118  boost::trim(name);
119 
120  if(foundTypes().end() != foundTypes().find(name) || missingTypes().end() != missingTypes().find(name)) {
121  // Already been processed. Prevents infinite loop.
122  return;
123  }
124 
125  if(name.empty() || t.isFundamental() || t.isEnum() || t.typeInfo() == typeid(void)) {
126  foundTypes().insert(name);
127  return;
128  }
129 
130  if(!bool(t)) {
131  if(hasCintDictionary(name)) {
132  foundTypes().insert(name);
133  } else {
134  missingTypes().insert(name);
135  }
136  return;
137  }
138 
139  foundTypes().insert(name);
140  if(noComponents) return;
141 
142  if(name.find("std::") == 0) {
143  if(t.isTemplateInstance()) {
144  std::string::size_type n = name.find('<');
145  int cnt = 0;
146  if(std::find(oneParam, oneParam + oneParamArraySize, name.substr(5, n - 5)) != oneParam + oneParamArraySize) {
147  cnt = 1;
148  } else if(std::find(twoParam, twoParam + twoParamArraySize, name.substr(5, n - 5)) != twoParam + twoParamArraySize) {
149  cnt = 2;
150  }
151  for(int i = 0; i < cnt; ++i) {
152  checkType(t.templateArgumentAt(i));
153  }
154  }
155  } else {
156  TypeDataMembers members(t);
157  for(auto const& member : members) {
158  MemberWithDict m(member);
159  if(!m.isTransient() && !m.isStatic()) {
160  checkType(m.typeOf());
161  }
162  }
163  TypeBases bases(t);
164  for(auto const& base : bases) {
165  BaseWithDict b(base);
166  checkType(b.typeOf());
167  }
168  }
169  }
170  } // end unnamed namespace
171 
173  return missingTypes_;
174  }
175 
177  // The only purpose of this cache is to stop infinite recursion.
178  // ROOT maintains its own internal cache.
179  return foundTypes_;
180  }
181 
182  void checkDictionaries(std::string const& name, bool noComponents) {
183  TypeWithDict null;
185  if(t == null) {
186  if(name == std::string("void")) {
187  foundTypes().insert(name);
188  } else {
189  missingTypes().insert(name);
190  }
191  return;
192  }
193  checkType(t, noComponents);
194  }
195 
197  if(!missingTypes().empty()) {
198  std::ostringstream ostr;
199  for (StringSet::const_iterator it = missingTypes().begin(), itEnd = missingTypes().end();
200  it != itEnd; ++it) {
201  ostr << *it << "\n\n";
202  }
204  << "No REFLEX data dictionary found for the following classes:\n\n"
205  << ostr.str()
206  << "Most likely each dictionary was never generated,\n"
207  << "but it may be that it was generated in the wrong package.\n"
208  << "Please add (or move) the specification\n"
209  << "<class name=\"whatever\"/>\n"
210  << "to the appropriate classes_def.xml file.\n"
211  << "If the class is a template instance, you may need\n"
212  << "to define a dummy variable of this type in classes.h.\n"
213  << "Also, if this class has any transient members,\n"
214  << "you need to specify them in classes_def.xml.";
215  }
216  }
217 
219  while (!missingTypes().empty()) {
221  for (StringSet::const_iterator it = missing.begin(), itEnd = missing.end();
222  it != itEnd; ++it) {
223  try {
224  gROOT->GetClass(it->c_str(), kTRUE);
225  }
226  // We don't want to fail if we can't load a plug-in.
227  catch(...) {}
228  }
229  missingTypes().clear();
230  for (StringSet::const_iterator it = missing.begin(), itEnd = missing.end();
231  it != itEnd; ++it) {
232  checkDictionaries(*it);
233  }
234  if (missingTypes() == missing) {
235  break;
236  }
237  }
238  if (missingTypes().empty()) {
239  return;
240  }
242  }
243 
244  void public_base_classes(TypeWithDict const& typeID,
245  std::vector<TypeWithDict>& baseTypes) {
246 
247  TypeWithDict type(typeID.typeInfo());
248  if(type.isClass()) {
249 
250  TypeBases bases(type);
251  for(auto const& basex : bases) {
252  BaseWithDict base(basex);
253  if(base.isPublic()) {
254 
255  TypeWithDict baseRflxType = base.typeOf();
256  if(bool(baseRflxType)) {
257  TypeWithDict baseType(baseRflxType.typeInfo());
258 
259  // Check to make sure this base appears only once in the
260  // inheritance heirarchy.
261  if(!search_all(baseTypes, baseType)) {
262  // Save the type and recursive look for its base types
263  baseTypes.push_back(baseType);
264  public_base_classes(baseType, baseTypes);
265  }
266  // For now just ignore it if the class appears twice,
267  // After some more testing we may decide to uncomment the following
268  // exception.
269  /*
270  else {
271  throw Exception(errors::UnimplementedFeature)
272  << "DataFormats/Common/src/DictionaryTools.cc in function public_base_classes.\n"
273  << "Encountered class that has a public base class that appears\n"
274  << "multiple times in its inheritance heirarchy.\n"
275  << "Please contact the EDM Framework group with details about\n"
276  << "this exception. It was our hope that this complicated situation\n"
277  << "would not occur. There are three possible solutions. 1. Change\n"
278  << "the class design so the public base class does not appear multiple\n"
279  << "times in the inheritance heirarchy. In many cases, this is a\n"
280  << "sign of bad design. 2. Modify the code that supports Views to\n"
281  << "ignore these base classes, but not supply support for creating a\n"
282  << "View of this base class. 3. Improve the View infrastructure to\n"
283  << "deal with this case. Class name of base class: " << baseType.Name() << "\n\n";
284  }
285  */
286  }
287  }
288  }
289  }
290  }
291 }
bool find_nested_type_named(std::string const &nested_type, TypeWithDict const &type_to_search, TypeWithDict &found_type)
tuple base
Main Program
Definition: newFWLiteAna.py:92
type
Definition: HCALResponse.h:21
dictionary missing
Definition: combine.py:4
bool is_RefToBaseVector(TypeWithDict const &possible_ref_vector, TypeWithDict &value_type)
int i
Definition: DBlmapReader.cc:9
static TypeWithDict byName(std::string const &className)
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
void public_base_classes(TypeWithDict const &type, std::vector< TypeWithDict > &baseTypes)
bool is_RefVector(TypeWithDict const &possible_ref_vector, TypeWithDict &value_type)
std::string templateName() const
TypeWithDict nestedType(char const *name) const
StringSet & missingTypes()
std::set< std::string > StringSet
void checkDictionaries(std::string const &name, bool noComponents=false)
std::type_info const & typeInfo() const
TypeWithDict typeOf() const
Definition: BaseWithDict.cc:15
#define end
Definition: vmac.h:37
StringSet & foundTypes()
Container::value_type value_type
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()
#define begin
Definition: vmac.h:30
Definition: DDAxes.h:10
static StringSet missingTypes_
bool is_PtrVector(TypeWithDict const &possible_ref_vector, TypeWithDict &value_type)
bool isPublic() const
Definition: BaseWithDict.cc:25