CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
findMethod.cc
Go to the documentation of this file.
6 #include "TInterpreter.h"
7 #include "TVirtualMutex.h"
8 #include <cassert>
9 
10 using namespace std;
12 
13 //Checks for errors which show we got the correct function be we just can't use it
14 static bool fatalErrorCondition(int iError)
15 {
16  return (reco::parser::kIsNotPublic==iError ||
17  reco::parser::kIsStatic==iError ||
22 
23 }
24 namespace reco {
26  const edm::TypeWithDict & type,
27  const std::vector<AnyMethodArgument> &args, std::vector<AnyMethodArgument> &fixuppedArgs) {
28  int casts = 0;
29  if (mem.isConstructor()) return -1*parser::kIsConstructor;
30  if (mem.isDestructor()) return -1*parser::kIsDestructor;
31  //if (mem.isOperator()) return -1*parser::kIsOperator; // no, some operators are allowed, e.g. operator[]
32  if (! mem.isPublic()) return -1*parser::kIsNotPublic;
33  if (mem.isStatic()) return -1*parser::kIsStatic;
34  if ( ! mem.isConst() ) return -1*parser::kIsNotConst;
35  if (mem.name().substr(0, 2) == "__") return -1*parser::kIsFunctionAddedByROOT;
36  if (mem.declaringType().id() != type.id()) {
37  /*std::cerr << "\nMETHOD OVERLOAD " << mem.name() <<
38  " by " << type.Name(QUALITIED|SCOPED) <<
39  " from " << mem.declaringTy[e().Name(QUALIFIED|SCOPED) << std::endl; */
40  return -1*parser::kOverloaded;
41  }
42  size_t minArgs = mem.functionParameterSize(true), maxArgs = mem.functionParameterSize(false);
43  if ((args.size() < minArgs) || (args.size() > maxArgs)) return -1*parser::kWrongNumberOfArguments;
44  /*std::cerr << "\nMETHOD " << mem.name() << " of " << mem.declaringType().name()
45  << ", min #args = " << minArgs << ", max #args = " << maxArgs
46  << ", args = " << args.size() << std::endl;*/
47  if (!args.empty()) {
48  std::vector<AnyMethodArgument> tmpFixups;
49  size_t i = 0;
50  for (auto const& param : mem) {
52  std::pair<AnyMethodArgument,int> fixup = boost::apply_visitor( reco::parser::AnyMethodArgumentFixup(parameter), args[i] );
53  //std::cerr << "\t ARG " << i << " type is " << parameter.name() << " conversion = " << fixup.second << std::endl;
54  if (fixup.second >= 0) {
55  tmpFixups.push_back(fixup.first);
56  casts += fixup.second;
57  } else {
59  }
60  if(++i == args.size()) {
61  break;
62  }
63  }
64  fixuppedArgs.swap(tmpFixups);
65  }
66  /*std::cerr << "\nMETHOD " << mem.name() << " of " << mem.declaringType().name()
67  << ", min #args = " << minArgs << ", max #args = " << maxArgs
68  << ", args = " << args.size() << " fixupped args = " << fixuppedArgs.size() << "(" << casts << " implicit casts)" << std::endl; */
69  return casts;
70  }
71 
72  typedef pair<int,edm::FunctionWithDict> OK;
73  bool nCasts(OK const& a, OK const& b) {
74  return a.first < b.first;
75  }
76 
77 
78  pair<edm::FunctionWithDict, bool> findMethod(const edm::TypeWithDict & t,
79  const string & name,
80  const std::vector<AnyMethodArgument> &args,
81  std::vector<AnyMethodArgument> &fixuppedArgs,
82  const char* iIterator,
83  int& oError) {
86  if (! type)
87  throw parser::Exception(iIterator)
88  << "No dictionary for class \"" << type.name() << "\".";
89  while(type.isPointer() || type.isTypedef()) type = type.toType();
90  type = edm::TypeWithDict(type, 0L); // strip const, volatile, c++ ref, ..
91 
92  pair<edm::FunctionWithDict, bool> mem; mem.second = false;
93  int err_fatal = 0;
94 
95  // suitable members and number of integer->real casts required to get them
96  vector<pair<int,edm::FunctionWithDict> > oks;
97 
98  // first look in base scope
99  edm::TypeFunctionMembers functions(type);
100  for(auto const& function : functions) {
101  edm::FunctionWithDict m(function);
102  if(m.name()==name) {
103  int casts = checkMethod(m, type, args, fixuppedArgs);
104  if (casts > -1) {
105  oks.push_back( make_pair(casts,m) );
106  } else {
107  oError = -1*casts;
108  //is this a show stopper error?
109  if(fatalErrorCondition(oError) && err_fatal == 0) {
110  err_fatal = oError;
111  }
112  }
113  }
114  }
115  //std::cout << "At base scope (type " << (type.name()) << ") found " << oks.size() << " methods." << std::endl;
116 
117  if (oks.empty() && err_fatal)
118  {
119  oError = err_fatal;
120  return mem;
121  }
122 
123  // found at least one method
124  if (!oks.empty()) {
125  if (oks.size() > 1) {
126  // sort by number of conversions needed
127  sort(oks.begin(), oks.end(), nCasts);
128 
129  if (oks[0].first == oks[1].first) { // two methods with same ambiguity
130  throw parser::Exception(iIterator)
131  << "Can't resolve method \"" << name << "\" for class \"" << type.name() << "\", the two candidates "
132  << oks[0].second.name() << " and " << oks[1].second.name()
133  << " require the same number of integer->real conversions (" << oks[0].first << ").";
134  }
135 
136  // I should fixup again the args, as both good methods have pushed them on fixuppedArgs
137  fixuppedArgs.clear();
138  checkMethod(oks.front().second, type, args, fixuppedArgs);
139  }
140  mem.first = oks.front().second;
141  }
142 
143  // if nothing was found, look in parent scopes (without checking for cross-scope overloading, as it's not allowed)
144  int baseError=parser::kNameDoesNotExist;
145  if(! mem.first) {
146  R__LOCKGUARD(gCINTMutex);
147  edm::TypeBases bases(type);
148  for(auto const& base : bases) {
149  if((mem = findMethod(edm::BaseWithDict(base).typeOf(), name, args, fixuppedArgs,iIterator,baseError)).first) break;
150  if(fatalErrorCondition(baseError)) {
151  oError = baseError;
152  return mem;
153  }
154  }
155  }
156 
157  // otherwise see if this object is just a Ref or Ptr and we should pop it out
158  if(!mem.first) {
159  // check for edm::Ref or edm::RefToBase or edm::Ptr
160  // std::cout << "Mem.first is null, so looking for templates from type " << type.name() << std::endl;
161  if(type.isTemplateInstance()) {
162  std::string name = type.templateName();
163  if(name.compare("edm::Ref") == 0 ||
164  name.compare("edm::RefToBase") == 0 ||
165  name.compare("edm::Ptr") == 0) {
166  // in this case i think 'get' should be taken with no arguments!
167  std::vector<AnyMethodArgument> empty, empty2;
168  int error;
169  mem = findMethod(type, "get", empty, empty2,iIterator,error);
170  if(!mem.first) {
171  throw parser::Exception(iIterator)
172  << "No member \"get\" in reference of type \"" << type.name() << "\".";
173  }
174  mem.second = true;
175  }
176  }
177  }
178  /*
179  if(!mem.first) {
180  throw edm::Exception(edm::errors::Configuration)
181  << "member \""" << name << "\"" not found in class \"" << type.name() << "\"";
182  }
183  */
184  if(mem.first) {
185  oError = parser::kNoError;
186  } else {
187  //use error from base check if we never found function in primary class
188  if(oError == parser::kNameDoesNotExist) {
189  oError = baseError;
190  }
191  }
192  return mem;
193  }
194 }
tuple base
Main Program
Definition: newFWLiteAna.py:92
type
Definition: HCALResponse.h:21
int i
Definition: DBlmapReader.cc:9
pair< int, edm::FunctionWithDict > OK
Definition: findMethod.cc:72
bool isConstructor() const
bool isTypedef() const
pair< edm::FunctionWithDict, bool > findMethod(const edm::TypeWithDict &t, const string &name, const std::vector< AnyMethodArgument > &args, std::vector< AnyMethodArgument > &fixuppedArgs, const char *iIterator, int &oError)
Definition: findMethod.cc:78
TypeWithDict declaringType() const
bool nCasts(OK const &a, OK const &b)
Definition: findMethod.cc:73
std::string name() const
static bool fatalErrorCondition(int iError)
Definition: findMethod.cc:14
TypeWithDict toType() const
std::string templateName() const
bool isTemplateInstance() const
std::string name() const
uint16_t mem[nChs][nEvts]
bool first
Definition: L1TdeRCT.cc:75
boost::mpl::if_< matches_another_integral_type< unsigned long >, boost::variant< int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, double, float, std::string >, boost::variant< int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, unsigned long, double, float, std::string > >::type AnyMethodArgument
int checkMethod(const edm::FunctionWithDict &mem, const edm::TypeWithDict &type, const std::vector< AnyMethodArgument > &args, std::vector< AnyMethodArgument > &fixuppedArgs)
Definition: findMethod.cc:25
double b
Definition: hdecay.h:120
std::type_info const & id() const
size_t functionParameterSize(bool required=false) const
double a
Definition: hdecay.h:121
bool isDestructor() const
bool isPointer() const