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 
92  // suitable members and number of integer->real casts required to get them
93  vector<pair<int,edm::FunctionWithDict> > oks;
94 
95  // first look in base scope
96  edm::TypeFunctionMembers functions(type);
97  for(auto const& function : functions) {
98  edm::FunctionWithDict m(function);
99  if(m.name()==name) {
100  int casts = checkMethod(m, type, args, fixuppedArgs);
101  if (casts > -1) {
102  oks.push_back( make_pair(casts,m) );
103  } else {
104  oError = -1*casts;
105  //is this a show stopper error?
106  if(fatalErrorCondition(oError)) {
107  return mem;
108  }
109  }
110  }
111  }
112  //std::cout << "At base scope (type " << (type.name()) << ") found " << oks.size() << " methods." << std::endl;
113  // found at least one method
114  if (!oks.empty()) {
115  if (oks.size() > 1) {
116  // sort by number of conversions needed
117  sort(oks.begin(), oks.end(), nCasts);
118 
119  if (oks[0].first == oks[1].first) { // two methods with same ambiguity
120  throw parser::Exception(iIterator)
121  << "Can't resolve method \"" << name << "\" for class \"" << type.name() << "\", the two candidates "
122  << oks[0].second.name() << " and " << oks[1].second.name()
123  << " require the same number of integer->real conversions (" << oks[0].first << ").";
124  }
125 
126  // I should fixup again the args, as both good methods have pushed them on fixuppedArgs
127  fixuppedArgs.clear();
128  checkMethod(oks.front().second, type, args, fixuppedArgs);
129  }
130  mem.first = oks.front().second;
131  }
132 
133  // if nothing was found, look in parent scopes (without checking for cross-scope overloading, as it's not allowed)
134  int baseError=parser::kNameDoesNotExist;
135  if(! mem.first) {
136  edm::TypeBases bases(type);
137  for(auto const& base : bases) {
138  if((mem = findMethod(edm::BaseWithDict(base).typeOf(), name, args, fixuppedArgs,iIterator,baseError)).first) break;
139  if(fatalErrorCondition(baseError)) {
140  oError = baseError;
141  return mem;
142  }
143  }
144  }
145 
146  // otherwise see if this object is just a Ref or Ptr and we should pop it out
147  if(!mem.first) {
148  // check for edm::Ref or edm::RefToBase or edm::Ptr
149  // std::cout << "Mem.first is null, so looking for templates from type " << type.name() << std::endl;
150  if(type.isTemplateInstance()) {
151  std::string name = type.templateName();
152  if(name.compare("edm::Ref") == 0 ||
153  name.compare("edm::RefToBase") == 0 ||
154  name.compare("edm::Ptr") == 0) {
155  // in this case i think 'get' should be taken with no arguments!
156  std::vector<AnyMethodArgument> empty, empty2;
157  int error;
158  mem = findMethod(type, "get", empty, empty2,iIterator,error);
159  if(!mem.first) {
160  throw parser::Exception(iIterator)
161  << "No member \"get\" in reference of type \"" << type.name() << "\".";
162  }
163  mem.second = true;
164  }
165  }
166  }
167  /*
168  if(!mem.first) {
169  throw edm::Exception(edm::errors::Configuration)
170  << "member \""" << name << "\"" not found in class \"" << type.name() << "\"";
171  }
172  */
173  if(mem.first) {
174  oError = parser::kNoError;
175  } else {
176  //use error from base check if we never found function in primary class
177  if(oError == parser::kNameDoesNotExist) {
178  oError = baseError;
179  }
180  }
181  return mem;
182  }
183 }
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:94
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