| 730 | //----------------------------------------------------------------------------- |
| 731 | |
| 732 | void CfrontCodeGenerator::FormatCast(const std::string_view, |
| 733 | const QualType& castDestType, |
| 734 | const Expr* subExpr, |
| 735 | const CastKind& kind) |
| 736 | { |
| 737 | // C does not have a rvalue notation and we already transformed the temporary into an object. Skip the cast to &&. |
| 738 | // Ignore CK_UncheckedDerivedToBase which would lead to (A)c where neither A nor c is a pointer. |
| 739 | if(not castDestType->isRValueReferenceType() and not(CastKind::CK_UncheckedDerivedToBase == kind)) { |
| 740 | mOutputFormatHelper.Append("(", GetName(castDestType), ")"); |
| 741 | |
| 742 | // ARM p 221: |
| 743 | // C* pc = new C; |
| 744 | // B* pb = pc -> pc = (B*) ((char*)pc+delta(B)) |
| 745 | if(is{kind}.any_of(CastKind::CK_DerivedToBase, CastKind::CK_BaseToDerived)) { |
| 746 | // We have to switch in case of a base to derived cast |
| 747 | auto [key, |
| 748 | sign] = [&]() -> std::pair<std::pair<const CXXRecordDecl*, const CXXRecordDecl*>, std::string_view> { |
| 749 | auto plainType = [](QualType t) { |
| 750 | if(const auto* pt = dyn_cast_or_null<PointerType>(t.getTypePtrOrNull())) { |
| 751 | return pt->getPointeeType()->getAsCXXRecordDecl(); |
| 752 | } |
| 753 | |
| 754 | return t->getAsCXXRecordDecl(); |
| 755 | }; |
| 756 | |
| 757 | auto base = plainType(castDestType); |
| 758 | auto derived = plainType(subExpr->getType()); |
| 759 | |
| 760 | if((CastKind::CK_BaseToDerived == kind)) { |
| 761 | return {{base, derived}, "-"sv}; |
| 762 | } |
| 763 | |
| 764 | return {{derived, base}, "+"sv}; |
| 765 | }(); |
| 766 | |
| 767 | if(auto off = mThisPointerOffset[key]) { |
| 768 | mOutputFormatHelper.Append("((char*)"sv); |
| 769 | InsertArg(subExpr); |
| 770 | mOutputFormatHelper.Append(sign, off, ")"sv); |
| 771 | |
| 772 | return; |
| 773 | } |
| 774 | } |
| 775 | } |
| 776 | |
| 777 | InsertArg(subExpr); |
| 778 | } |
| 779 | //----------------------------------------------------------------------------- |
| 780 | |
| 781 | void CfrontCodeGenerator::InsertArg(const CXXNullPtrLiteralExpr*) |