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