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