00001
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
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
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
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
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
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
00225
00226 if (e1 - a1 < e2 - a2 && std::search(a2, e2, a1, e1) != e2)
00227 return true;
00228
00229
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
00242
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
00250
00251
00252
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
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
00274 if (sclass1 && sclass2 && sclass1->is_base_class_of(sclass2))
00275 return true;
00276 } else if (dest2.is_void()) {
00277
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
00283 if (sclass1 == sclass2 && dclass2->is_base_class_of(dclass1))
00284 return true;
00285
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
00302 return true;
00303 if (dclass1 == dclass2 && sclass2->is_base_class_of(sclass1))
00304
00305 return true;
00306 }
00307 } else if (p1->action == a_DerivedToBaseConversion) {
00308
00309
00310
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
00327
00328
00329
00330
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
00348 if (get_form() < other->get_form())
00349 return true;
00350 if (get_form() > other->get_form())
00351 return false;
00352
00353
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
00365 assert(hit != steps.end());
00366 assert(oit != other->steps.end());
00367
00368
00369
00370 if (comparison_type == c_CompareBeforeUserConversion) {
00371 return scs_is_better_than(steps.begin(), hit,
00372 other->steps.begin(), oit);
00373 }
00374
00375
00376 if (comparison_type == c_CompareWithInitRules
00377 && hit->action == Implicit_conversion::a_ConversionOp
00378 && oit->action == Implicit_conversion::a_ConversionOp)
00379 {
00380
00381
00382
00383
00384
00385
00386
00387
00388 } else {
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
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
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
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;
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
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
00456
00457
00458
00459
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
00467
00468
00469
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
00479 break;
00480 case a_BindReferenceToTemporary:
00481
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
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
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
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
00596 return f_NoForm;
00597 }
00598 }
00599
00600 #line 661 "implicit_conversion.cpp"
00601
00602 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
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
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
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
00685 return Implicit_conversion::a_BoolConversion;
00686 } else if (dest.is_float()) {
00687
00688
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
00695 assert(dest.is_int());
00696 return Implicit_conversion::a_FloatingIntegralConversion;
00697 }
00698 } else if (src.is_int()) {
00699
00700
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
00729
00730
00731
00732
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
00744
00745 if (arg_type.get_kind() == Type::k_Pointer || arg_type.get_kind() == Type::k_Member) {
00746
00747
00748 if (!ics->is_npc())
00749
00750
00751
00752
00753
00754
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
00763
00764
00765
00766
00767
00768
00769
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
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
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
00790
00791
00792
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
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
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
00822
00823 return false;
00824 case Type::k_Array:
00825
00826
00827 return false;
00828 case Type::k_Member:
00829
00830
00831
00832
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
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
00842 if (!sclass || !tclass || !sclass->is_unique_base_class_of(tclass))
00843 return false;
00844
00845
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
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
00870 ics->add_conversion(Implicit_conversion::a_BoolConversion, arg_type);
00871 return true;
00872 } else if (arg_type.is_int()) {
00873
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
00905 Function_symbol* fsym = dynamic_cast<Function_symbol*>(sym->get_scope()->lookup_here(Symbol_name::CONSTRUCTOR_NAME, true).untag);
00906 if (!fsym)
00907
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
00918 Implicit_conversion* ic =
00919 generate_implicit_conversion(expr,
00920 sig->get_proto_type().get_function_arg(0),
00921 symbol_hint,
00922 false ,
00923 true ,
00924 false );
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
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
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
00990
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
01001 assert((*j)->is_declared());
01002
01003
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
01025
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
01031 if (!ics->convert_reference(i->first->get_this_type()))
01032 continue;
01033
01034
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
01044
01045
01046
01047
01048 Implicit_conversion* final =
01049 generate_implicit_conversion(interm_expr,
01050 arg_type,
01051 symbol_hint,
01052 false ,
01053 true
01054
01055 ,
01056 false );
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
01088
01089
01090
01091 return;
01092 }
01093
01094 if (expr.is_function()) {
01095
01096
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
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
01111
01112
01113
01114 if (is_object || expr.is_lvalue()) {
01115
01116 Implicit_conversion* idirect = new Implicit_conversion(expr, symbol_hint);
01117 if (idirect->convert_reference(ref_type)) {
01118 candidates->push_back(idirect);
01119
01120
01121 return;
01122 }
01123 }
01124 if (with_userdef && expr.get_type().get_kind() == Type::k_Userdef) {
01125
01126
01127
01128 if (gen_conv_ops(expr, arg_type, symbol_hint, candidates))
01129 return;
01130 }
01131
01132
01133 if (ref_type.is_qualified(Type::q_Const) && !ref_type.is_qualified(Type::q_Volatile)) {
01134
01135 if (Implicit_conversion* ics =
01136 generate_implicit_conversion(expr, ref_type, symbol_hint,
01137 with_userdef ,
01138 true ,
01139 false
01140 ))
01141 {
01142 ics->add_step(ICS_Step(ref_type, Expr_result::k_LValue,
01143 Implicit_conversion::a_BindReferenceToTemporary));
01144
01145 candidates->push_back(ics);
01146 }
01147 }
01148 } else {
01149
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
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
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 compare = ICS_Types::c_CompareBeforeUserConversion;
01209 }
01210
01211
01212
01213
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
01221 best->set_ambiguous();
01222 return best;
01223 }
01224 }
01225 return best;
01226 }