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

implicit_conversion.cc

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
00002 
00003 #include "implicit_conversion.h"
00004 #include "implicit_conversion_i.h"
00005 
00006 
00007 #line 267 "implicit_conversion.cpp"
00008 
00009 static bool
00010 is_ptr_to_bool(Implicit_conversion::Step_vec::const_iterator p);
00011 
00012 #line 276 "implicit_conversion.cpp"
00013 static Class_symbol*
00014 class_or_null(const Type& t);
00015 
00016 #line 712 "implicit_conversion.cpp"
00017 /******************************* Functions *******************************/
00018 
00022 static Implicit_conversion::Action
00023 fundamental_conversion_type(Type src, Type dest);
00024 
00025 #line 766 "implicit_conversion.cpp"
00026 
00028 static bool
00029 gen_builtin_conversions(Implicit_conversion* ics,
00030                         Type                 arg_type);
00031 
00032 #line 940 "implicit_conversion.cpp"
00033 
00034 static void
00035 gen_constructors(const Expr_result&          expr,
00036                  Type                        arg_type,
00037                  Function_signature*         symbol_hint,
00038                  std::vector<Implicit_conversion*>* icv);
00039 
00040 #line 1057 "implicit_conversion.cpp"
00041 
00043 static bool
00044 gen_conv_ops(const Expr_result&          expr,
00045              Type                        arg_type,
00046              Function_signature*         symbol_hint,
00047              std::vector<Implicit_conversion*>* icv);
00048 
00049 #line 266 "implicit_conversion.cpp"
00050 
00052 static inline bool
00053 is_ptr_to_bool(Implicit_conversion::Step_vec::const_iterator p)
00054 {
00055     return p->action == Implicit_conversion::a_BoolConversion
00056         && (p[-1].type.get_kind() == Type::k_Pointer
00057             || p[-1].type.get_kind() == Type::k_Member);
00058 }
00059 
00060 #line 131 "implicit_conversion.cpp"
00061 
00062 /************************** Implicit_conversion **************************/
00063 
00078 Implicit_conversion::Implicit_conversion(const Expr_result& result, Function_signature* symbol_hint)
00079     : form(f_Standard), rank(r_Exact), ambiguous(false)
00080 {
00081     steps.push_back(Step(result.get_type(), result.get_kind(), symbol_hint, a_NullStep));
00082     maybe_npc = result.is_npc();
00083 
00084     assert(result.is_value());
00085 }
00086 
00087 #line 156 "implicit_conversion.cpp"
00088 
00089 
00090 Implicit_conversion::~Implicit_conversion()
00091 { }
00092 
00093 #line 174 "implicit_conversion.cpp"
00094 
00096 void
00097 Implicit_conversion::warn_if_used(std::string s)
00098 {
00099     if (warnings.length())
00100         warnings += "\nwarning: ";
00101     warnings += s;
00102 }
00103 
00104 #line 183 "implicit_conversion.cpp"
00105 
00107 void
00108 Implicit_conversion::add_step(Step s)
00109 {
00110     // maybe validate the step here
00111     Form f = s.get_form();
00112     if (f > form)
00113         form = f;
00114     Rank r = s.get_rank();
00115     if (r > rank)
00116         rank = r;
00117 
00118     steps.push_back(s);
00119 }
00120 
00121 #line 198 "implicit_conversion.cpp"
00122 
00124 void
00125 Implicit_conversion::add_conversion(Action a, Type t)
00126 {
00127     assert(get_current().type != t);
00128     add_step(Step(t, get_current().kind, a));
00129 }
00130 
00131 #line 206 "implicit_conversion.cpp"
00132 
00135 bool
00136 Implicit_conversion::convert_to_rvalue(Type target)
00137 {
00138     Type t = get_current().type;
00139     if (t.get_kind() == Type::k_Array)
00140         add_step(Step(t.get_basis_type().make_pointer_type(),
00141                       Expr_result::k_RValue,
00142                       a_ArrayToPointer));
00143     else if (t.get_kind() == Type::k_Function)
00144         add_step(Step(t.make_pointer_type(),
00145                       Expr_result::k_RValue,
00146                       a_FunctionToPointer));
00147     else if (get_current().kind != Expr_result::k_RValue) {
00148         if (!t.is_class_type())
00149             t = t.get_unqualified_type();
00150         add_step(Step(t, Expr_result::k_RValue, a_LValueToRValue));
00151     } else if (!t.is_class_type()) {
00152         Type t2 = t.get_unqualified_type().with_qualifiers(target);
00153         if (t2 != t)
00154             add_step(Step(t2, Expr_result::k_RValue, a_QualificationAdjustment));
00155     }
00156 
00157     t = get_current().type;
00158     if (t.is_class_type()) {
00159         if (target.is_more_qualified_than(t)) {
00160             t.copy_qualifiers(target);
00161             add_step(Step(t, Expr_result::k_RValue, a_QualificationAdjustment));
00162             return true;
00163         } else if (t.is_more_qualified_than(target)) {
00164             /* no way */
00165             return false;
00166         } else {
00167             return true;
00168         }
00169     } else
00170         return true;
00171 }
00172 
00173 #line 246 "implicit_conversion.cpp"
00174 
00176 void
00177 Implicit_conversion::dump(std::ostream& os)
00178 {
00179     for (Step_vec::iterator i = steps.begin(); i != steps.end(); ++i) {
00180         os << ". ";
00181         i->dump(os);
00182         os << '\n';
00183     }
00184 }
00185 
00186 #line 257 "implicit_conversion.cpp"
00187 
00188 bool
00189 Implicit_conversion::uses_temporary() const
00190 {
00191     for (Step_vec::const_iterator i = steps.begin(); i != steps.end(); ++i)
00192         if (i->action == a_BindReferenceToTemporary)
00193             return true;
00194     return false;
00195 }    
00196 
00197 #line 275 "implicit_conversion.cpp"
00198 
00199 static Class_symbol*
00200 class_or_null(const Type& t)
00201 {
00202     if (t.get_kind() == Type::k_Userdef)
00203         return dynamic_cast<Class_symbol*>(t.get_type_symbol());
00204     else
00205         return 0;
00206 }
00207 
00208 #line 284 "implicit_conversion.cpp"
00209 
00212 bool
00213 Implicit_conversion::scs_is_better_than(Step_vec::const_iterator a1,
00214                                         Step_vec::const_iterator e1,
00215                                         Step_vec::const_iterator a2,
00216                                         Step_vec::const_iterator e2)
00217 {
00218     /* skip LValue transformations */
00219     if (a1 != e1 && (a1->action == a_NullStep || a1->is_lvalue_transformation()))
00220         ++a1;
00221     if (a2 != e2 && (a2->action == a_NullStep || a2->is_lvalue_transformation()))
00222         ++a2;
00223 
00224     /* sub-sequence rule. Looking at gcc, there's quite a lot of
00225        optimisation potential for this step. */
00226     if (e1 - a1 < e2 - a2 && std::search(a2, e2, a1, e1) != e2)
00227         return true;
00228 
00229     /* rank rule */
00230     Rank r1 = r_Exact, r2 = r_Exact;
00231     for (Step_vec::const_iterator i = a1; i != e1; ++i)
00232         if (i->get_rank() > r1)
00233             r1 = i->get_rank();
00234     for (Step_vec::const_iterator i = a2; i != e2; ++i)
00235         if (i->get_rank() > r2)
00236             r2 = i->get_rank();
00237     if (r1 < r2)
00238         return true;
00239 
00240     if (r1 == r2 && r1 != r_Exact) {
00241         /* point p1 and p2 to the interesting step. The relevant ranks
00242            are worse than r_Exact */
00243         Step_vec::const_iterator p1 = a1, p2 = a2;
00244         while (p1->get_rank() == r_Exact)
00245             ++p1;
00246         while (p2->get_rank() == r_Exact)
00247             ++p2;
00248 
00249         /* ptr->bool or PM->bool is worse than others */
00250         // 0 if neither or both are ptr->bool
00251         // 1 if p2 is ptr->bool and p1 is not, i.e. p1 is better
00252         // -1 if p1 is ptr->bool and p1 is not
00253         int result = is_ptr_to_bool(p2) - is_ptr_to_bool(p1);
00254         if (result)
00255             return result > 0;
00256 
00257         if (p1->action == p2->action) {
00258             if (p1->action == a_PointerConversion) {
00259                 // Pointer conversion. Source type might be NPC or pointer.
00260                 Type src1 = p1[-1].type, src2 = p2[-1].type,
00261                     dest1 = p1[0].type.get_basis_type(), dest2 = p2[0].type.get_basis_type();
00262 
00263                 if (src1.get_kind() == Type::k_Pointer && src2.get_kind() == Type::k_Pointer) {
00264                     src1 = src1.get_basis_type();
00265                     src2 = src2.get_basis_type();
00266 
00267                     Class_symbol *sclass1 = class_or_null(src1),
00268                         *sclass2 = class_or_null(src2),
00269                         *dclass1 = class_or_null(dest1),
00270                         *dclass2 = class_or_null(dest2);
00271 
00272                     if (dest1.is_void() && dest2.is_void()) {
00273                         // Base*->void* better than Der*->void*
00274                         if (sclass1 && sclass2 && sclass1->is_base_class_of(sclass2))
00275                             return true;
00276                     } else if (dest2.is_void()) {
00277                         // Der*->Base*  better than Der*->void*
00278                         assert(dclass1->is_base_class_of(sclass1));
00279                         if (sclass1 && dclass1 && sclass1==sclass2)
00280                             return true;
00281                     } else if (sclass1 && dclass1 && sclass2 && dclass2) {
00282                         // C*->B* better than C*->A*
00283                         if (sclass1 == sclass2 && dclass2->is_base_class_of(dclass1))
00284                             return true;
00285                         // B*->A* better than C*->A*
00286                         if (dclass1 == dclass2 && sclass1->is_base_class_of(sclass2))
00287                             return true;
00288                     }
00289                 }
00290             } else if (p1->action == a_PtrMemConversion) {
00291                 Type src1 = p1[-1].type, src2 = p2[-1].type;
00292                 if (src1.get_kind() == Type::k_Member && src2.get_kind() == Type::k_Member) {
00293                     Class_symbol
00294                         *sclass1 = class_or_null(src1),
00295                         *sclass2 = class_or_null(src2),
00296                         *dclass1 = class_or_null(p1[0].type.get_class_type()),
00297                         *dclass2 = class_or_null(p2[0].type.get_class_type());
00298                     assert(sclass1); assert(sclass2);
00299                     assert(dclass1); assert(dclass2);
00300                     if (sclass1 == sclass2 && dclass1->is_base_class_of(dclass2))
00301                         // A::*->B::* better than A::*->C::*
00302                         return true;
00303                     if (dclass1 == dclass2 && sclass2->is_base_class_of(sclass1))
00304                         // B::*->C::* better than A::*->C::*
00305                         return true;
00306                 }
00307             } else if (p1->action == a_DerivedToBaseConversion) {
00308                 // C&->B& better than C&->A&
00309                 // B&->A& better than C&->A&
00310                 // B->A better than C->A
00311                 Class_symbol
00312                     *sclass1 = class_or_null(p1[-1].type),
00313                     *sclass2 = class_or_null(p2[-1].type),
00314                     *dclass1 = class_or_null(p1[0].type),
00315                     *dclass2 = class_or_null(p2[0].type);
00316                 assert(sclass1); assert(sclass2);
00317                 assert(dclass1); assert(dclass2);
00318                 if (sclass1 == sclass2 && dclass2->is_base_class_of(dclass1))
00319                     return true;
00320                 if (dclass1 == dclass2 && sclass1->is_base_class_of(sclass2))
00321                     return true;
00322             }
00323         }
00324     }
00325 
00326     /* qualification conversion rule */
00327     // FIXME
00328 
00329     /* reference binding rule */
00330     // FIXME
00331 
00332     return false;
00333 }
00334 
00335 #line 409 "implicit_conversion.cpp"
00336 
00343 bool
00344 Implicit_conversion::is_better_than(Implicit_conversion* other,
00345                                     Compare comparison_type)
00346 {
00347     /* Compare basic forms, 13.3.3.2p2 */
00348     if (get_form() < other->get_form())
00349         return true;
00350     if (get_form() > other->get_form())
00351         return false;
00352 
00353     /* Two standard conversion sequences */
00354     if (get_form() == f_Standard) {
00355         return scs_is_better_than(steps.begin(), steps.end(),
00356                                   other->steps.begin(), other->steps.end());
00357     } else if (get_form() == f_Userdef) {
00358         Step_vec::const_iterator hit = steps.end();
00359         while (hit != steps.begin() && (--hit)->get_form() != f_Userdef)
00360             ;
00361         Step_vec::const_iterator oit = other->steps.end();
00362         while (oit != other->steps.begin() && (--oit)->get_form() != f_Userdef)
00363             ;
00364         /* hit, oit now point at the user-defined step */
00365         assert(hit != steps.end());
00366         assert(oit != other->steps.end());
00367 
00368         /* 13.3.1.4: we're comparing the sequence *before* the user
00369            converter */
00370         if (comparison_type == c_CompareBeforeUserConversion) {
00371             return scs_is_better_than(steps.begin(), hit,
00372                                       other->steps.begin(), oit);
00373         }
00374 
00375         /* 13.3.3.2p3, 13.3.1.5 */
00376         if (comparison_type == c_CompareWithInitRules
00377             && hit->action == Implicit_conversion::a_ConversionOp
00378             && oit->action == Implicit_conversion::a_ConversionOp)
00379         {
00380             /* it is an initialisation by user-defined conversion
00381                operator. This makes sure that for
00382                      struct a {
00383                         operator int();
00384                         operator void*();
00385                      } the_a;
00386                      bool b = the_a;
00387                the "int" operator is chosen. */
00388         } else {
00389             /* normal overload resolution. 13.3.3.2p3 says that two
00390                UCS's using different functions are indistinguishable.
00391                This makes
00392                    void foo(int);
00393                    void foo(void*);
00394                    // ...
00395                    foo(the_a);
00396                ambiguous but
00397                    void qoo(int);
00398                    void qoo(short);
00399                    qoo(the_a)
00400                work. */
00401             if (hit->function != oit->function)
00402                 return false;
00403         }
00404         return scs_is_better_than(++hit, steps.end(),
00405                                   ++oit, other->steps.end());
00406     }
00407 
00408     return false;
00409 }
00410 
00411 #line 483 "implicit_conversion.cpp"
00412 
00415 Expr_result
00416 Implicit_conversion::make_tree(Expr_result expr)
00417 {
00418     if (is_ambiguous())
00419         compile_error("conversion from `" + steps.front().type.get_human_readable_type()
00420                       + "' to `" + steps.back().type.get_human_readable_type() + "' is ambiguous");
00421     if (warnings.length())
00422         compile_warning(warnings, expr.get_tree());
00423 
00424     /* first, annotate the expr tree */
00425     if (expr.is_function()) {
00426         assert(steps.front().function);
00427         fill_in_overload_annotation(expr.get_tree(), steps.front().function, steps.front().type);
00428         expr.set_value(expr.get_tree(), steps.front().type);
00429     }
00430 
00431     /* process the expression */
00432     for (Step_vec::iterator i = steps.begin()+1; i != steps.end(); ++i) {
00433         switch (i->action) {
00434          case a_NullStep:
00435             assert(0);
00436          case a_QualificationAdjustment:
00437             break;              // this one's purely conceptual with no effect on the semantics.
00438          case a_LValueToRValue:
00439          case a_ArrayToPointer:
00440          case a_FunctionToPointer:
00441          case a_IntegralPromotion:
00442          case a_FloatingPromotion:
00443          case a_IntegralConversion:
00444          case a_FloatingConversion:
00445          case a_FloatingIntegralConversion:
00446          case a_PointerConversion:
00447          case a_PtrMemConversion:
00448          case a_BoolConversion:
00449          case a_DerivedToBaseConversion:
00450             /* I guess not all these actually need a cast, but why not. */
00451             expr.set_value(make_cast_expr_unchecked(expr.get_tree(), i->type), i->type);
00452             expr.set_kind(i->kind);
00453             break;
00454          case a_CtorCall:
00455             /* constructor call. Note that the type differs from the
00456                type encoded into the actual constructor symbol:
00457                constructors have type "function taking <args>
00458                returning nothing", but when called, they have type
00459                "function taking <args> returning <class>" */
00460             assert(i->function);
00461             expr.set_value(make_unary_funcall(make_name(i->function), i->type, expr.get_tree()),
00462                            i->type);
00463             expr.set_kind(i->kind);
00464             break;
00465          case a_ConversionOp:
00466             /* conversion operator. These have type "function taking
00467                <class> returning <target>" whereas they appear in
00468                symbol tables as "member function taking <dummy arg>
00469                returning <target>" */
00470             assert(i->function);
00471             expr.set_value(make_unary_funcall(make_name(i->function),
00472                                               i->type,
00473                                               expr.get_tree()),
00474                            i->type);
00475             expr.set_kind(i->kind);
00476             break;
00477          case a_Ellipsis:
00478             /* this one's purely conceptual. */
00479             break;
00480          case a_BindReferenceToTemporary:
00481             /* FIXME: what to do with this one? */
00482             break;
00483         }
00484     }
00485     return expr;
00486 }
00487 
00488 #line 558 "implicit_conversion.cpp"
00489 
00492 bool
00493 Implicit_conversion::convert_reference(Type target)
00494 {
00495     Type ics_type = get_current().type;
00496     if (!ics_type.is_same_unqualified_type(target)) {
00497         /* not same type -- must be derived class */
00498         if (ics_type.get_kind() != Type::k_Userdef || target.get_kind() != Type::k_Userdef)
00499             return false;
00500         Class_symbol* sclass = dynamic_cast<Class_symbol*>(ics_type.get_type_symbol());
00501         Class_symbol* tclass = dynamic_cast<Class_symbol*>(target.get_type_symbol());
00502         if (!sclass || !tclass || !tclass->is_base_class_of(sclass))
00503             return false;
00504 
00505         /* derived-to-base conversion */
00506         ics_type = target.get_unqualified_type().with_qualifiers(ics_type);
00507         add_conversion(a_DerivedToBaseConversion, ics_type);
00508     }
00509     if (ics_type.is_more_qualified_than(target))
00510         return false;
00511     if (target.is_more_qualified_than(ics_type))
00512         add_conversion(a_QualificationAdjustment, target);
00513     return true;
00514 }
00515 
00516 #line 584 "implicit_conversion.cpp"
00517 
00518 void
00519 Implicit_conversion::append_from(Implicit_conversion* other)
00520 {
00521     assert(steps.back().type == other->steps.front().type);
00522     assert(steps.back().kind == other->steps.front().kind);
00523     assert(other->steps.front().action == a_NullStep);
00524 
00525     for (Step_vec::const_iterator i = other->steps.begin()+1; i != other->steps.end(); ++i)
00526         add_step(*i);
00527 
00528     if (other->is_ambiguous())
00529         set_ambiguous();
00530 }
00531 #line 598 "implicit_conversion.cpp"
00532 
00533 /*********************** Implicit_conversion::Step ***********************/
00534 
00535 bool
00536 operator==(const ICS_Step& lhs, const ICS_Step& rhs)
00537 {
00538     return lhs.type == rhs.type
00539         && lhs.kind == rhs.kind
00540         && lhs.function == rhs.function
00541         && lhs.action == rhs.action;
00542 }
00543 
00544 #line 609 "implicit_conversion.cpp"
00545 
00548 ICS_Step::Rank
00549 ICS_Step::get_rank() const
00550 {
00551     switch (action) {
00552      default:
00553         return r_NoRank;
00554      case a_LValueToRValue:
00555      case a_ArrayToPointer:
00556      case a_FunctionToPointer:
00557      case a_QualificationAdjustment:
00558         return r_Exact;
00559      case a_IntegralPromotion:
00560      case a_FloatingPromotion:
00561         return r_Promotion;
00562      case a_IntegralConversion:
00563      case a_FloatingConversion:
00564      case a_FloatingIntegralConversion:
00565      case a_PointerConversion:
00566      case a_PtrMemConversion:
00567      case a_BoolConversion:
00568      case a_DerivedToBaseConversion:
00569         return r_Conversion;
00570     }
00571 }
00572 
00573 #line 636 "implicit_conversion.cpp"
00574 
00577 ICS_Step::Form
00578 ICS_Step::get_form() const
00579 {
00580     switch (action) {
00581      case a_NullStep:
00582         return f_NoForm;
00583 
00584      default:
00585         return f_Standard;
00586 
00587      case a_CtorCall:
00588      case a_ConversionOp:
00589         return f_Userdef;
00590 
00591      case a_Ellipsis:
00592         return f_Ellipsis;
00593 
00594      case a_BindReferenceToTemporary:
00595 //     case a_OverloadResolution:
00596         return f_NoForm;
00597     }
00598 }
00599 
00600 #line 661 "implicit_conversion.cpp"
00601 
00602 /*inline*/ bool
00603 ICS_Step::is_lvalue_transformation() const
00604 {
00605     return (action == a_LValueToRValue || action == a_ArrayToPointer
00606             || action == a_FunctionToPointer);
00607 }
00608 
00609 #line 668 "implicit_conversion.cpp"
00610 
00612 const char*
00613 ICS_Step::get_action_name() const
00614 {
00615     static const char*const names[] = {
00616         "null",
00617         "lvalue->rvalue",
00618         "array->pointer",
00619         "function->pointer",
00620         "qualification adjustment",
00621         "integral promotion",
00622         "fp promotion",
00623         "integral conversion",
00624         "fp conversion",
00625         "fp/integral conversion",
00626         "pointer conversion",
00627         "member pointer conversion",
00628         "anything->bool conversion",
00629         "derived->base conversion",
00630         "constructor call",
00631         "conversion operator",
00632         "ellipsis conversion",
00633         "bind reference to temporary",
00634 //        "overload resolution"
00635     };
00636     return names[action];
00637 }
00638 
00639 #line 696 "implicit_conversion.cpp"
00640 
00641 void
00642 ICS_Step::dump(std::ostream& os) const
00643 {
00644     const char* aname = get_action_name();
00645     const char* kname = (kind == Expr_result::k_LValue
00646                          ? "lvalue"
00647                          : kind == Expr_result::k_RValue
00648                          ? "rvalue"
00649                          : "You are in trouble");
00650     os << type.get_human_readable_type() << " [" << kname << "; " << aname;
00651     if (function)
00652         os << ", call to signature `" << function->get_proto_type().get_encoded_type() << "'";
00653     os << "]";
00654 }
00655 
00656 #line 711 "implicit_conversion.cpp"
00657 
00658 /******************************* Functions *******************************/
00659 
00663 static Implicit_conversion::Action
00664 fundamental_conversion_type(Type src, Type dest)
00665 {
00666     assert(src.get_kind() == Type::k_Fundamental);
00667     assert(dest.get_kind() == Type::k_Fundamental);
00668     assert(src.is_valid() && !src.is_void());
00669     assert(dest.is_valid() && !dest.is_void());
00670 
00671     src = src.get_unqualified_type();
00672     dest = dest.get_unqualified_type();
00673 
00674     if (src == bool_type) {
00675         /* bool -> int/double */
00676         if (dest.is_float())
00677             return Implicit_conversion::a_FloatingIntegralConversion;
00678         else if (dest.is_same_unqualified_type(int_type))
00679             return Implicit_conversion::a_IntegralPromotion;
00680         else
00681             return Implicit_conversion::a_IntegralConversion;
00682     } else if (src.is_float()) {
00683         if (dest == bool_type) {
00684             /* fp->bool, 4.12 */
00685             return Implicit_conversion::a_BoolConversion;
00686         } else if (dest.is_float()) {
00687             /* float->double is a promotion, everything else is a
00688                conversion (4.6, 4.8) */
00689             if (src == float_type && dest == double_type)
00690                 return Implicit_conversion::a_FloatingPromotion;
00691             else
00692                 return Implicit_conversion::a_FloatingConversion;
00693         } else {
00694             /* must be float->integral */
00695             assert(dest.is_int());
00696             return Implicit_conversion::a_FloatingIntegralConversion;
00697         }
00698     } else if (src.is_int()) {
00699         /* anything smaller than int can be converted to int resp.
00700            unsigned int. Hence, formally, short->long is a conversion. */
00701         if (dest == bool_type)
00702             return Implicit_conversion::a_BoolConversion;
00703         else if (src.get_promoted_integer() == dest)
00704             return Implicit_conversion::a_IntegralPromotion;
00705         else
00706             return Implicit_conversion::a_IntegralConversion;
00707     } else {
00708         assert(0);
00709     }
00710 }
00711 
00712 #line 765 "implicit_conversion.cpp"
00713 
00716 static bool
00717 gen_builtin_conversions(Implicit_conversion* ics,
00718                         Type                 arg_type)
00719 {
00720     Type ics_type = ics->get_current().type;
00721 
00722     assert(!arg_type.is_void());
00723     assert(!ics_type.is_void());
00724     assert(arg_type.is_valid());
00725     assert(ics_type.is_valid());
00726     assert(arg_type.get_kind() != Type::k_Function && arg_type.get_kind() != Type::k_Array);
00727 
00728     /* 4.1 cv-lvalue -> rvalue (nonclass)
00729            cv-lvalue -> rvalue (class) */
00730     /* There can be no arg_type which is a function, nor can there be
00731        an arg_type which is an array and not an exact match */
00732 //    if (ics_type.is_same_unqualified_type(arg_type))
00733         if (!ics->convert_to_rvalue(arg_type)) {
00734             return false;
00735         }
00736 
00737     ics_type = ics->get_current().type;
00738     if (ics_type == arg_type)
00739         return true;
00740 
00741     switch (ics_type.get_kind()) {
00742      case Type::k_Fundamental:
00743         /* fundamental types can only be converted into fundamental
00744            types or null pointers */
00745         if (arg_type.get_kind() == Type::k_Pointer || arg_type.get_kind() == Type::k_Member) {
00746             /* 4.10: npc -> *T */
00747             /* 4.11: npc -> PM */
00748             if (!ics->is_npc())
00749                 // FIXME: this is problematic; it might be a null-
00750                 // pointer constant which we don't recognize. However,
00751                 // making this just a warning prevents correct
00752                 // resolution when someone has a ctor which takes
00753                 // both int or T* args.
00754                 // ics->warn_if_used("possibly invalid conversion of integer to pointer used");
00755                 return false;
00756             if (arg_type.get_kind() == Type::k_Pointer)
00757                 ics->add_conversion(Implicit_conversion::a_PointerConversion, arg_type);
00758             else
00759                 ics->add_conversion(Implicit_conversion::a_PtrMemConversion, arg_type);
00760             return true;
00761         } else if (arg_type.get_kind() == Type::k_Fundamental) {
00762             /* 4.5: integral promotions (FOO int -> int, bool -> int) */
00763             /* 4.6: fp promotions (float -> double) */
00764             /* 4.7: integral conversions (int/bool -> any int) */
00765             /* 4.8: fp conversions (fp -> fp) */
00766             /* 4.9: fpint conversions (fp -> int, int/enum -> fp */
00767             /* 4.12: bool conv (int/fp/enum -> bool) */
00768             /* essentially, we can convert anything to anything else,
00769                we just have to figure out how */
00770             ics->add_conversion(fundamental_conversion_type(ics_type, arg_type), arg_type);
00771             return true;
00772         } else {
00773             return false;
00774         }
00775      case Type::k_Pointer:
00776         if (arg_type.get_kind() == Type::k_Pointer) {
00777             /* pointer-to-pointer conversions */
00778             Type sp = ics_type.get_basis_type();
00779             Type tp = arg_type.get_basis_type();
00780 
00781             if (tp.is_void() && !sp.is_void()) {
00782                 /* 4.10: cv-T* can be converted to cv-void* */
00783                 ics_type = void_type.with_qualifiers(sp).make_pointer_type();
00784                 ics->add_conversion(Implicit_conversion::a_PointerConversion,
00785                                     ics_type);
00786             } else if (tp.get_kind() == Type::k_Userdef && sp.get_kind() == Type::k_Userdef
00787                        && !sp.is_same_unqualified_type(tp))
00788             {
00789                 /* 4.10: cv-Derived can be converted to cv-Base */
00790                 // FIXME: I think when it is ambiguous it still takes
00791                 // part in overload resolution; 4.10 isn't entirely clear
00792                 // about that
00793                 Class_symbol* sclass = dynamic_cast<Class_symbol*>(sp.get_type_symbol());
00794                 Class_symbol* tclass = dynamic_cast<Class_symbol*>(tp.get_type_symbol());
00795                 if (!sclass || !tclass || !tclass->is_unique_base_class_of(sclass))
00796                     return false;
00797                 ics_type = tclass->get_type().with_qualifiers(sp).make_pointer_type();
00798                 ics->add_conversion(Implicit_conversion::a_PointerConversion,
00799                                     ics_type);
00800             }
00801 
00802             /* 4.3: we can add qualifiers */
00803             if (ics_type != arg_type) {
00804                 if (!ics_type.is_qualification_convertible_to(arg_type))
00805                     return false;
00806                 ics->add_conversion(Implicit_conversion::a_QualificationAdjustment,
00807                                     arg_type);
00808             }
00809             return true;
00810         } else if (arg_type.get_unqualified_type() == bool_type) {
00811             /* 4.12: bool conv (ptr -> bool) */
00812             ics->add_conversion(Implicit_conversion::a_BoolConversion, arg_type);
00813             return true;
00814         } else {
00815             return false;
00816         }
00817      case Type::k_Reference:
00818         assert(0);
00819         return false;
00820      case Type::k_Function:
00821         /* 4.3: function -> pointer. When we end up here, we attempt
00822            an incompatible conversion. */
00823         return false;
00824      case Type::k_Array:
00825         /* 4.2: array -> pointer. When we end up here, we attempt
00826            an incompatible conversion. */
00827         return false;
00828      case Type::k_Member:
00829         /* 4.3: cv-PM -> more-cv-PM
00830                 add cv qualifiers */
00831         /* 4.11: cv-PM-base -> cv-PM-derived */
00832         /* 4.12: bool conv (PM -> bool) */
00833         if (arg_type.get_kind() == Type::k_Member) {
00834             Type sct = ics_type.get_class_type();
00835             Type tct = arg_type.get_class_type();
00836 
00837             if (!sct.is_same_unqualified_type(tct)) {
00838                 /* 4.11: cv-PM-of-Base -> cv-PM-of-Derived */
00839                 Class_symbol* sclass = dynamic_cast<Class_symbol*>(sct.get_type_symbol());
00840                 Class_symbol* tclass = dynamic_cast<Class_symbol*>(tct.get_type_symbol());
00841                 // FIXME: the same ambiguity problem as above strikes here, too
00842                 if (!sclass || !tclass || !sclass->is_unique_base_class_of(tclass))
00843                     return false;
00844                 // FIXME: classes don't have cv-qualifiers in member pointers,
00845                 // so there's no need to do with_qualifiers here. Check that.
00846                 ics_type = tclass->get_type().make_member_type(ics_type.get_member_type());
00847                 ics->add_conversion(Implicit_conversion::a_PtrMemConversion, ics_type);
00848             }
00849 
00850             if (ics_type != arg_type) {
00851                 /* qualification conversion */
00852                 if (!ics_type.is_qualification_convertible_to(arg_type))
00853                     return false;
00854                 ics->add_conversion(Implicit_conversion::a_QualificationAdjustment, arg_type);
00855             }
00856             return true;
00857         } else if (arg_type.get_unqualified_type() == bool_type) {
00858             ics->add_conversion(Implicit_conversion::a_BoolConversion, arg_type);
00859             return true;
00860         } else {
00861             return false;
00862         }
00863      case Type::k_Userdef:
00864         {
00865             Type_symbol* sym = ics_type.get_type_symbol();
00866             if (sym->get_kind() != Symbol::k_Enum)
00867                 return false;
00868             if (arg_type.get_unqualified_type() == bool_type) {
00869                 /* 4.12: enum -> bool */
00870                 ics->add_conversion(Implicit_conversion::a_BoolConversion, arg_type);
00871                 return true;
00872             } else if (arg_type.is_int()) {
00873                 /* 4.7: enum -> int */
00874                 ics->add_conversion(Implicit_conversion::a_IntegralConversion, arg_type);
00875                 return true;
00876             } else {
00877                 return false;
00878             }
00879         }
00880      case Type::k_Template:
00881         assert(0);
00882      case Type::k_Ellipsis:
00883      case Type::k_Nothing:
00884         return false;
00885     }
00886 }
00887 
00888 #line 939 "implicit_conversion.cpp"
00889 
00891 static void
00892 gen_constructors(const Expr_result&          expr,
00893                  Type                        arg_type,
00894                  Function_signature*         symbol_hint,
00895                  std::vector<Implicit_conversion*>* icv)
00896 {
00897     if (arg_type.get_kind() != Type::k_Userdef)
00898         return;
00899 
00900     Class_symbol* sym = dynamic_cast<Class_symbol*>(arg_type.get_type_symbol());
00901     if (!sym || !sym->is_defined())
00902         return;
00903 
00904     /* it is a class. Iterate through all its one-arg constructors */
00905     Function_symbol* fsym = dynamic_cast<Function_symbol*>(sym->get_scope()->lookup_here(Symbol_name::CONSTRUCTOR_NAME, true).untag);
00906     if (!fsym)
00907         /* no constructors defined */
00908         return;
00909 
00910     for (Function_symbol::Sig_it i = fsym->sig_begin(); i != fsym->sig_end(); ++i) {
00911         Function_signature* sig = *i;
00912         if (!sig->is_declared() || sig->get_proto_type().get_num_function_args() != 1)
00913             continue;
00914         if (sig->get_function_specifiers() & f_Explicit)
00915             continue;
00916 
00917         /* okay, it's a possible constructor. Figure out how to call it. */
00918         Implicit_conversion* ic =
00919             generate_implicit_conversion(expr,
00920                                          sig->get_proto_type().get_function_arg(0),
00921                                          symbol_hint,
00922                                          false /* no user-defined */,
00923                                          true /* is copy-initialisation */,
00924                                          false /* not implicit object arg */);
00925         if (ic) {
00926             ic->add_step(Implicit_conversion::Step(arg_type.get_unqualified_type(),
00927                                                    Expr_result::k_RValue,
00928                                                    sig,
00929                                                    Implicit_conversion::a_CtorCall));
00930             /* do const adjustments etc. */
00931             if (ic->convert_to_rvalue(arg_type))
00932                 icv->push_back(ic);
00933         }
00934     }
00935 }
00936 
00937 #line 990 "implicit_conversion.cpp"
00938 
00939 
00940 Class_op_lookup_helper::Class_op_lookup_helper(Type t)
00941     : t(t)
00942 { }
00943 
00944 #line 995 "implicit_conversion.cpp"
00945 
00946 bool
00947 Class_op_lookup_helper::predicate(Class_symbol* sym)
00948 {
00949     Function_symbol* fsym = dynamic_cast<Function_symbol*>(sym->lookup_helper(Symbol_name::CONVERSION_OPERATOR_NAME).untag);
00950     if (!fsym)
00951         return false;
00952 
00953     Function_signature* fsig = fsym->get_function_signature(t, 0);
00954     return fsig != 0;
00955 }
00956 
00957 #line 1006 "implicit_conversion.cpp"
00958 
00960 bool
00961 Class_op_lookup_helper::is_visible_in(Class_symbol* what, Class_symbol* sym)
00962 {
00963     add_class(sym);
00964     finish(sym);
00965     for (classes_t::const_iterator i = result_set.begin(); i != result_set.end(); ++i) {
00966         if (what == *i)
00967             return true;
00968     }
00969     return false;
00970 }
00971 
00972 #line 1019 "implicit_conversion.cpp"
00973 
00974 /******************************* Functions *******************************/
00975 
00976 void
00977 enumerate_conversion_ops(const Expr_result& expr,
00978                          Conversion_op_map* output)
00979 {
00980     if (expr.get_type().get_kind() != Type::k_Userdef)
00981         return;
00982 
00983     Class_symbol* sym = dynamic_cast<Class_symbol*>(expr.get_type().get_type_symbol());
00984     if (!sym)
00985         return;
00986     if (!sym->is_defined())
00987         compile_error("attempting to use undefined type `" + sym->get_name() + "'");
00988 
00989     /* It's a class. Enumerate all operators defined in the derivation
00990        tree. Then look which of them are visible. */
00991     Class_symbol::bases_t list;
00992     list.push_back(sym);
00993     sym->enumerate_base_classes(true, &list);
00994 
00995     for (Class_symbol::bases_t::iterator i = list.begin(); i != list.end(); ++i) {
00996         Function_symbol* fsym = dynamic_cast<Function_symbol*>((*i)->lookup_helper(Symbol_name::CONVERSION_OPERATOR_NAME).untag);
00997         if (!fsym)
00998             continue;
00999         for (Function_symbol::Sig_it j = fsym->sig_begin(); j != fsym->sig_end(); ++j) {
01000             /* class members are always known */
01001             assert((*j)->is_declared());
01002             /* /j/ now is an operator function signature from class /i/.
01003                We have to check whether this signature is visible from /sym/. */
01004             Class_op_lookup_helper lh(expr.get_type().make_member_type((*j)->get_proto_type()));
01005             if (lh.is_visible_in(*i, sym))
01006                 (*output)[*j]++;
01007         }
01008     }
01009 }
01010 
01011 #line 1056 "implicit_conversion.cpp"
01012 
01015 static bool
01016 gen_conv_ops(const Expr_result&          expr,
01017              Type                        arg_type,
01018              Function_signature*         symbol_hint,
01019              std::vector<Implicit_conversion*>* icv)
01020 {
01021     Conversion_op_map sigs;
01022     enumerate_conversion_ops(expr, &sigs);
01023 
01024     /* Now, /sigs/ contains all operators, with visibility count.
01025        Generate the appropriate number of conversion sequences. */
01026     bool rv = false;
01027     for (std::map<Function_signature*, int>::iterator i = sigs.begin(); i != sigs.end(); ++i) {
01028         Implicit_conversion* ics = new Implicit_conversion(expr, symbol_hint);
01029 
01030         /* convert the source to the implicit object argument */
01031         if (!ics->convert_reference(i->first->get_this_type()))
01032             continue;
01033 
01034         /* call the function */
01035         Type type = i->first->get_return_type();
01036         Expr_result interm_expr;
01037         interm_expr.set_value(0, type);
01038         ics->add_step(Implicit_conversion::Step(interm_expr.get_type(), interm_expr.get_kind(), i->first,
01039                                                 Implicit_conversion::a_ConversionOp));
01040         if (i->second != 1)
01041             ics->set_ambiguous();
01042 
01043         /* convert result to target */
01044         // FIXME: we should use actual overload resolution here. This
01045         // makes a difference when template constructors / converters
01046         // enter the game. Probably it's even better to do that
01047         // directly in generate_implicit_conversion.
01048         Implicit_conversion* final =
01049             generate_implicit_conversion(interm_expr,
01050                                          arg_type,
01051                                          symbol_hint,
01052                                          false /* no user-defined */,
01053                                          true /* is copy-initialisation; this
01054                                                  is completely egal since
01055                                                  we don't use user convs. */,
01056                                          false /* not implicit object arg */);
01057         if (final) {
01058             ics->append_from(final);
01059             icv->push_back(ics);
01060             rv = true;
01061         }
01062     }
01063     return rv;
01064 }
01065 
01066 #line 1109 "implicit_conversion.cpp"
01067 
01078 void
01079 gen_candidates(Expr_result         expr,
01080                Type                arg_type,
01081                Function_signature* symbol_hint,
01082                bool                with_userdef,
01083                bool                is_object,
01084                std::vector<Implicit_conversion*>* candidates)
01085 {
01086     if (expr.is_bound_member()) {
01087         /* I'm not 100% sure what to do here. Probably it's
01088            simplest to simply generate no candidates; callers
01089            will notice and say so. The alternative would be
01090            to compile_error(). */
01091         return;
01092     }
01093 
01094     if (expr.is_function()) {
01095         /* expr is a function name. Generate all conversions which
01096            convert any of these functions into a target. */
01097         for (Function_symbol::Sig_it i = expr.get_function()->sig_begin(); i != expr.get_function()->sig_end(); ++i) {
01098             Expr_result nexpr;
01099             nexpr.set_value(expr.get_tree(), (*i)->get_pointer_type());
01100             gen_candidates(nexpr, arg_type, *i, with_userdef, is_object, candidates);
01101         }
01102         return;
01103     }
01104 
01105     /* Normal ICS generation follows: */
01106     assert(expr.get_type().get_kind() != Type::k_Reference);
01107 
01108     if (arg_type.get_kind() == Type::k_Reference) {
01109         Type ref_type = arg_type.get_basis_type();
01110         /* references, 8.5.3.
01111            p5: if the initializer is a reference-compatible lvalue,
01112                or can be converted to a reference-compatible "T3&" 
01113            The implicit object arg can also be bound to an rvalue. */
01114         if (is_object || expr.is_lvalue()) {
01115             /* try to bind directly */
01116             Implicit_conversion* idirect = new Implicit_conversion(expr, symbol_hint);
01117             if (idirect->convert_reference(ref_type)) {
01118                 candidates->push_back(idirect);
01119                 /* No matter what happens, this conversion can't be beaten,
01120                    so no need to try the others */
01121                 return;
01122             }
01123         }
01124         if (with_userdef && expr.get_type().get_kind() == Type::k_Userdef) {
01125             /* try to bind with conversion operator. If there was
01126                such a conversion, don't try the others. The others
01127                would involve a temporary. */
01128             if (gen_conv_ops(expr, arg_type, symbol_hint, candidates))
01129                 return;
01130         }
01131 
01132         /* otherwise, reference shall not be volatile but const */
01133         if (ref_type.is_qualified(Type::q_Const) && !ref_type.is_qualified(Type::q_Volatile)) {
01134             // FIXME: I'm not 100% sure about this one
01135             if (Implicit_conversion* ics =
01136                     generate_implicit_conversion(expr, ref_type, symbol_hint,
01137                                                  with_userdef /* with user-defined */,
01138                                                  true /* is copy-init */,
01139                                                  false /* not implicit object arg. We don't get 
01140                                                           here when it is the i.o.a. */))
01141             {
01142                 ics->add_step(ICS_Step(ref_type, Expr_result::k_LValue,
01143                                        Implicit_conversion::a_BindReferenceToTemporary));
01144 //                 ics->bind_to_temporary(ref_type);
01145                 candidates->push_back(ics);
01146             }
01147         }
01148     } else {
01149         /* target is by-value thing */
01150         assert(expr.get_type().is_valid());
01151 
01152         arg_type = arg_type.get_unqualified_type();
01153 
01154         Implicit_conversion* im = new Implicit_conversion(expr, symbol_hint);
01155         if (gen_builtin_conversions(im, arg_type))
01156             candidates->push_back(im);
01157         if (with_userdef) {
01158             if (arg_type.get_kind() == Type::k_Userdef)
01159                 gen_constructors(expr, arg_type, symbol_hint, candidates);
01160             if (expr.get_type().get_kind() == Type::k_Userdef)
01161                 gen_conv_ops(expr, arg_type, symbol_hint, candidates);
01162         }
01163     }
01164 }
01165 
01166 #line 1207 "implicit_conversion.cpp"
01167 
01170 Implicit_conversion*
01171 generate_implicit_conversion(Expr_result   expr,
01172                              Type          arg_type,
01173                              Function_signature* symbol_hint,
01174                              bool          with_userdef,
01175                              bool          is_copy_initialisation,
01176                              bool          is_implicit_object_arg)
01177 {
01178     /* shortcut: there are no conversions from void */
01179     if (expr.get_type().is_void())
01180         return 0;
01181 
01182     std::vector<Implicit_conversion*> candidates;
01183     gen_candidates(expr, arg_type, symbol_hint, with_userdef, is_implicit_object_arg, &candidates);
01184 
01185     if (candidates.empty())
01186         return 0;
01187 
01188     ICS_Types::Compare compare = ICS_Types::c_CompareWithInitRules;
01189 
01190     if (is_copy_initialisation && arg_type.is_class_type()
01191         && !expr.get_type().is_same_unqualified_type(arg_type)) {
01192         /* special case, 13.3.1.4: in an expression of the form
01193                 Arg_type x = expr
01194            where Arg_type is a class type and expr has not the same type
01195            as Arg_type, we have to do overload resolution with
01196               Argument list = expr
01197               Function list = all constructors of Arg_type
01198                               all conversion functions of expr
01199            without user-defined conversions. We'd end up with a number
01200            of SCSs, pick the best, tack our function at the end, and
01201            add more SCSs to convert the function result into the
01202            target type.
01203 
01204            When we're here, we already have the complete ICS including
01205            the two SCSs and the user-defined converter, so all we have
01206            to do is to compare the ICSs *before* the user-defined
01207            function. */
01208         compare = ICS_Types::c_CompareBeforeUserConversion;
01209     }
01210 
01211     /* figure out best one.
01212        step 1) find one which is not worse than all others
01213        step 2) ensure that this one is actually better */
01214     Implicit_conversion* best = candidates.front();
01215     for (std::vector<Implicit_conversion*>::size_type i = 1; i < candidates.size(); ++i)
01216         if (candidates[i]->is_better_than(best, compare))
01217             best = candidates[i];
01218     for (std::vector<Implicit_conversion*>::size_type i = 0; i < candidates.size(); ++i) {
01219         if (best != candidates[i] && !best->is_better_than(candidates[i], compare)) {
01220             /* best is not uniquely better than this one. Ambiguous. */
01221             best->set_ambiguous();
01222             return best;
01223         }
01224     }
01225     return best;
01226 }

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