00001
00002
00003 #include "overload_resolver.h"
00004 #include "overload_resolver_i.h"
00005
00006
00007 #line 44 "overload_resolver.cpp"
00008
00009
00010
00011
00012 Overload_resolver::Overload_resolver(bool is_operator)
00013 : have_object(0), is_operator(is_operator)
00014 { }
00015
00016 #line 51 "overload_resolver.cpp"
00017
00018 void
00019 Overload_resolver::add_arg(const Expr_result& res)
00020 {
00021 args.push_back(res);
00022 }
00023
00024 #line 57 "overload_resolver.cpp"
00025
00026 void
00027 Overload_resolver::set_object(const Expr_result& res)
00028 {
00029 assert(!have_object);
00030 assert(args.empty());
00031 assert(!is_operator);
00032 args.push_back(res);
00033 have_object = true;
00034 }
00035
00036 #line 73 "overload_resolver.cpp"
00037
00041 void
00042 Overload_resolver::add_signature(Function_signature* sig)
00043 {
00044 add_signature_with_type(sig, sig->get_proto_type());
00045 }
00046
00047 #line 82 "overload_resolver.cpp"
00048
00049 void
00050 Overload_resolver::add_signature_with_type(Function_signature* sig, Type t)
00051 {
00052
00053 int nargs = t.get_num_function_args();
00054 bool is_ellipsis = nargs && t.get_function_arg(nargs-1).get_kind() == Type::k_Ellipsis;
00055 if (is_ellipsis)
00056 --nargs;
00057
00058 Candidate* cand = new Candidate(sig);
00059 if (is_operator) {
00060
00061
00062 if (is_ellipsis)
00063 return;
00064
00065
00066
00067 if (sig->get_storage_specifier() == s_Member) {
00068 if (nargs != args.size() - 1)
00069 return;
00070 if (Implicit_conversion* ics = generate_implicit_conversion(args[0],
00071 sig->get_this_type().make_reference_type(),
00072 0,
00073 false,
00074 true,
00075 true ))
00076 cand->args.push_back(ics);
00077 else
00078 return;
00079 } else {
00080 if (nargs != args.size())
00081 return;
00082 }
00083 int argindex = 0;
00084 for (unsigned i = cand->args.size(); i < args.size(); ++i) {
00085 Implicit_conversion* ics = generate_implicit_conversion(args[i], t.get_function_arg(argindex++),
00086 0,
00087 true,
00088 true,
00089 false );
00090 if (ics)
00091 cand->args.push_back(ics);
00092 else
00093 return;
00094 }
00095 } else {
00096
00097
00098
00099
00100
00101 if (have_object) {
00102 if (sig->get_storage_specifier() == s_Member) {
00103 Implicit_conversion* ics = generate_implicit_conversion(args[0],
00104 sig->get_this_type().make_reference_type(),
00105 0, false, true, true);
00106 if (ics)
00107 cand->args.push_back(ics);
00108 else
00109 return;
00110 } else {
00111 cand->args.push_back(0);
00112 }
00113 }
00114
00115 int need_args = args.size() - cand->args.size();
00116 if (nargs > need_args)
00117 return;
00118 if (nargs < need_args && !is_ellipsis)
00119 return;
00120
00121 int argptr = 0;
00122 for (int i = cand->args.size(); i < args.size(); ++i) {
00123 Type argtype = t.get_function_arg(argptr);
00124 if (argtype.get_kind() == Type::k_Ellipsis) {
00125
00126 if (!args[i].is_value())
00127 return;
00128 Implicit_conversion* ics = new Implicit_conversion(args[i], 0);
00129 ics->add_conversion(Implicit_conversion::a_Ellipsis, argtype);
00130 cand->args.push_back(ics);
00131 } else {
00132
00133 ++argptr;
00134 if (Implicit_conversion* ics = generate_implicit_conversion(args[i],
00135 argtype,
00136 0,
00137 true,
00138 true,
00139 false))
00140 {
00141 cand->args.push_back(ics);
00142 } else {
00143 return;
00144 }
00145 }
00146 }
00147 }
00148
00149
00150 candidates.push_back(cand);
00151 }
00152
00153 #line 186 "overload_resolver.cpp"
00154
00158 void
00159 Overload_resolver::add_builtin_incdec(bool is_increment)
00160 {
00161 assert(!have_object && (args.size() == 1 || args.size() == 2));
00162
00163 Conversion_op_map op_map;
00164 enumerate_conversion_ops(args[0], &op_map);
00165
00166 for (Conversion_op_map::iterator i = op_map.begin(); i != op_map.end(); ++i) {
00167 Function_signature* sig = i->first;
00168 Type t = sig->get_proto_type().get_return_type();
00169 if (t.get_kind() != Type::k_Reference)
00170 continue;
00171 t = t.get_basis_type();
00172
00173
00174 if (t.is_same_unqualified_type(bool_type) && !is_increment)
00175 continue;
00176
00177
00178 if (t.is_qualified(Type::q_Const))
00179 continue;
00180
00181
00182 if (t.is_arithmetic_type() || (t.get_kind() == Type::k_Pointer && t.get_basis_type().is_object_type())) {
00183 Function_type_maker ftm;
00184 ftm.add_parameter(t.make_reference_type());
00185 if (args.size() == 2) {
00186 ftm.add_parameter(int_type);
00187 add_signature(Function_signature::make_builtin(ftm.make_function_type(t.get_unqualified_type())));
00188 } else {
00189 add_signature(Function_signature::make_builtin(ftm.make_function_type(t.make_reference_type())));
00190 }
00191 }
00192 }
00193 }
00194
00195 #line 226 "overload_resolver.cpp"
00196
00202 void
00203 Overload_resolver::add_builtin_unary_ops(Type (*predicate)(Type t))
00204 {
00205 assert(args.size() == 1);
00206 Conversion_op_map op_map;
00207 enumerate_conversion_ops(args[0], &op_map);
00208 for (Conversion_op_map::iterator i = op_map.begin(); i != op_map.end(); ++i) {
00209 Type ft = predicate(i->first->get_proto_type().get_return_type().sans_reference());
00210 if (ft.is_valid())
00211 add_signature(Function_signature::make_builtin(ft));
00212 }
00213 }
00214
00215 #line 244 "overload_resolver.cpp"
00216
00224 void
00225 Overload_resolver::add_builtin_binary_ops(Type (*predicate)(Type t1, Type t2))
00226 {
00227 assert(args.size() == 2);
00228 Conversion_op_map lhs_map, rhs_map;
00229 enumerate_conversion_ops(args[0], &lhs_map);
00230 enumerate_conversion_ops(args[1], &rhs_map);
00231
00232 for (Conversion_op_map::iterator i = lhs_map.begin(); i != lhs_map.end(); ++i) {
00233 for (Conversion_op_map::iterator j = rhs_map.begin(); j != rhs_map.end(); ++j) {
00234 Type ft = predicate(i->first->get_return_type(), j->first->get_return_type());
00235 if (ft.is_valid())
00236 add_signature(Function_signature::make_builtin(ft));
00237 }
00238 }
00239
00240 Type lhs_type = args[0].get_type();
00241 if (args[0].is_lvalue())
00242 lhs_type = lhs_type.make_reference_type();
00243 for (Conversion_op_map::iterator i = rhs_map.begin(); i != rhs_map.end(); ++i) {
00244 Type ft = predicate(lhs_type, i->first->get_return_type());
00245 if (ft.is_valid())
00246 add_signature(Function_signature::make_builtin(ft));
00247 }
00248
00249 Type rhs_type = args[1].get_type();
00250 if (args[1].is_lvalue())
00251 rhs_type = rhs_type.make_reference_type();
00252 for (Conversion_op_map::iterator i = lhs_map.begin(); i != lhs_map.end(); ++i) {
00253 Type ft = predicate(i->first->get_return_type(), rhs_type);
00254 if (ft.is_valid())
00255 add_signature(Function_signature::make_builtin(ft));
00256 }
00257
00258 }
00259
00260 #line 287 "overload_resolver.cpp"
00261
00268 void
00269 Overload_resolver::add_function(Function_symbol* fsym, bool allow_dups)
00270 {
00271 unsigned limit = candidates.size();
00272 for (Function_symbol::Sig_it i = fsym->sig_begin(); i != fsym->sig_end(); ++i)
00273 if (allow_dups || !have_signature(*i, limit))
00274 add_signature(*i);
00275 }
00276
00277 #line 302 "overload_resolver.cpp"
00278
00279 bool
00280 Overload_resolver::have_signature(Function_signature* fsig, unsigned limit)
00281 {
00282 for (unsigned i = 0; i < limit; ++i)
00283 if (candidates[i]->fsig == fsig)
00284 return true;
00285 return false;
00286 }
00287
00288 #line 311 "overload_resolver.cpp"
00289
00290 Overload_candidate*
00291 Overload_resolver::get_best(bool* is_ambig)
00292 {
00293 if (is_ambig)
00294 *is_ambig = false;
00295
00296 if (candidates.empty())
00297 return 0;
00298
00299 Candidate* best = candidates.front();
00300 for (unsigned i = 1; i < candidates.size(); ++i)
00301 if (candidates[i]->is_better_than(best))
00302 best = candidates[i];
00303 for (unsigned i = 0; i < candidates.size(); ++i) {
00304 if (best != candidates[i] && !best->is_better_than(candidates[i])) {
00305
00306 if (is_ambig)
00307 *is_ambig = true;
00308 return 0;
00309 }
00310 }
00311
00312
00313 best->fill_in_tree(this);
00314 return best;
00315 }
00316
00317 #line 344 "overload_resolver.cpp"
00318
00319 void
00320 Overload_resolver::dump(std::ostream& os)
00321 {
00322 os << "The candidate set contains " << candidates.size() << " signatures.\n";
00323 for (unsigned i = 0; i < candidates.size(); ++i) {
00324 Candidate* c = candidates[i];
00325 os << "- Candidate #" << (i+1) << ": " << c->fsig->get_proto_type().get_encoded_type() << ":\n";
00326 for (unsigned j = 0; j < c->args.size(); ++j) {
00327 os << " + conversion for parameter " << (j+1) << ":\n";
00328 c->args[j]->dump(os);
00329 }
00330 }
00331 }
00332
00333 #line 364 "overload_resolver.cpp"
00334
00335
00336
00337
00338 Overload_candidate::Overload_candidate(Function_signature* sig)
00339 : fsig(sig), args()
00340 { }
00341
00342 #line 371 "overload_resolver.cpp"
00343
00344
00345 Overload_candidate::~Overload_candidate()
00346 { }
00347
00348 #line 375 "overload_resolver.cpp"
00349
00351 bool
00352 Overload_candidate::is_better_than(Overload_candidate* other)
00353 {
00354 assert(other->args.size() == args.size());
00355
00356
00357
00358
00359
00360 bool was_better = false;
00361 for (unsigned i = 0; i < args.size(); ++i) {
00362 if (!args[i] || !other->args[i]) {
00363 assert(i==0);
00364 continue;
00365 }
00366 if (other->args[i]->is_better_than(args[i], ICS_Types::c_CompareAll))
00367 return false;
00368 if (args[i]->is_better_than(other->args[i], ICS_Types::c_CompareAll))
00369 was_better = true;
00370 }
00371
00372
00373
00374
00375 if (was_better)
00376 return true;
00377
00378
00379
00380
00381
00382 return false;
00383 }
00384
00385 #line 410 "overload_resolver.cpp"
00386
00387 void
00388 Overload_candidate::fill_in_tree(Overload_resolver* resolver)
00389 {
00390
00391
00392
00393 if (!resolver->have_object && !resolver->is_operator && fsig->get_storage_specifier() == s_Member)
00394 if (fsig->get_function()->get_function_kind() != Symbol_name::k_Constructor)
00395 compile_error("attempt to call member function without an object");
00396
00397 for (unsigned i = 0; i < args.size(); ++i)
00398 if (args[i])
00399 resolver->args[i] = args[i]->make_tree(resolver->args[i]);
00400 else
00401 assert(i == 0 && resolver->have_object);
00402 }