Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

overload_resolver.cc

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
00002 
00003 #include "overload_resolver.h"
00004 #include "overload_resolver_i.h"
00005 
00006 
00007 #line 44 "overload_resolver.cpp"
00008 
00009 /*************************** Overload_resolver ***************************/
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     /* first, analyze the function parameter count. */
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         /* FIXME? reject operators with ellipsis args. They are not
00061            allowed; g++ doesn't even allow to define them (13.5). */
00062         if (is_ellipsis)
00063             return;
00064 
00065         /* A::operator@(B) => [A, B]
00066            operator@(A, B) => [A, B] */
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, /* no user-defined */
00074                                                                         true, /* is copy initialisation */
00075                                                                         true /* impl. obj. arg */))
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 /* not impl. obj. arg */);
00090             if (ics)
00091                 cand->args.push_back(ics);
00092             else
00093                 return;
00094         }
00095     } else {
00096         /* Not an operator. 
00097            Member function:  A::foo(X,Y,Z) => [A, X, Y, Z]
00098                         or                       [X, Y, Z]
00099            Non-member function: foo(X,Y,Z) => [0, X, Y, Z]
00100                         or                       [X, Y, Z] */
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                 /* ellipsis */
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                 /* normal argument */
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     /* add the candidate */
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         /* operator-- doesn't apply to bool */
00174         if (t.is_same_unqualified_type(bool_type) && !is_increment)
00175             continue;
00176 
00177         /* can't be const */
00178         if (t.is_qualified(Type::q_Const))
00179             continue;
00180 
00181         /* arithmetic or pointer type */
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             /* ambiguous */
00306             if (is_ambig)
00307                 *is_ambig = true;
00308             return 0;
00309         }
00310     }
00311 
00312     /* okay, it's not ambiguous. Check all ICSs. */
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 /********************** Overload_resolver::Candidate *********************/
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     /* a viable function F1 is better than another viable function
00357        F2 if for all arguments, ICSi(F1) is not a worse conversion
00358        sequence than ICSi(F2) ... */
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     /*  ... and then
00373         - for some argument j, ICSj(F1) is a better conversion
00374         sequence than ICSj(F2) ... */
00375     if (was_better)
00376         return true;
00377 
00378     /* FIXME: ... or, if not that
00379        - non-template is better than template
00380        - specialized template is better than general template
00381        - initialisation-by-user-defined-conversion rules here */
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     /* We need an object if
00391        - we're doing a member call
00392        - the member is not a constructor */
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 }

Generated on Mon Feb 10 17:32:52 2003 for VFiasco Semantics Compiler by doxygen1.2.15