| 460 | //----------------------------------------------------------------------------- |
| 461 | |
| 462 | void CfrontCodeGenerator::InsertCXXMethodDecl(const CXXMethodDecl* stmt, SkipBody) |
| 463 | { |
| 464 | // Skip if he method is unused like assignment operators by default. |
| 465 | RETURN_IF(not stmt->isUsed() and |
| 466 | (IsCopyOrMoveAssign(stmt) or (not stmt->hasBody() and not isa<CXXConstructorDecl>(stmt)))); |
| 467 | |
| 468 | OutputFormatHelper initOutputFormatHelper{}; |
| 469 | initOutputFormatHelper.SetIndent(mOutputFormatHelper, OutputFormatHelper::SkipIndenting::Yes); |
| 470 | |
| 471 | auto recordDeclType = GetRecordDeclType(stmt); |
| 472 | if(stmt->isConst()) { |
| 473 | recordDeclType.addConst(); |
| 474 | } |
| 475 | |
| 476 | auto parentType = Ptr(recordDeclType); |
| 477 | auto* body = stmt->getBody(); |
| 478 | StmtsContainer bodyStmts{}; |
| 479 | |
| 480 | auto retType = stmt->getReturnType(); |
| 481 | |
| 482 | auto processBaseClassesAndFields = [&](const CXXRecordDecl* parent) { |
| 483 | auto* thisOfParent = mkVarDeclRefExpr(kwInternalThis, parentType); |
| 484 | |
| 485 | auto insertFields = [&](const RecordDecl* rd) { |
| 486 | for(auto* fieldDecl : rd->fields()) { |
| 487 | if(const auto* cxxRecordDecl = fieldDecl->getType()->getAsCXXRecordDecl()) { |
| 488 | // We don't need any checks like isDefaultConstructible. We would not reach this |
| 489 | // point in any other case. |
| 490 | |
| 491 | auto lvalueRefType = GetGlobalAST().getLValueReferenceType(parentType); |
| 492 | auto* lhsMemberExpr = AccessMember(kwInternalThis, fieldDecl, lvalueRefType); |
| 493 | auto* rhsMemberExpr = AccessMember("__rhs"sv, fieldDecl, lvalueRefType); |
| 494 | |
| 495 | // Add call to ctor |
| 496 | bodyStmts.AddBodyStmts(Call(GetSpecialMemberName(stmt, GetRecordDeclType(cxxRecordDecl)), |
| 497 | {Ref(lhsMemberExpr), Ref(rhsMemberExpr)})); |
| 498 | |
| 499 | } else { |
| 500 | auto* rhsMemberExpr = AccessMember("__rhs"sv, fieldDecl, parentType); |
| 501 | |
| 502 | bodyStmts.AddBodyStmts(Assign(thisOfParent, fieldDecl, rhsMemberExpr)); |
| 503 | } |
| 504 | } |
| 505 | }; |
| 506 | |
| 507 | for(const auto& base : parent->bases()) { |
| 508 | const auto rd = base.getType()->getAsRecordDecl(); |
| 509 | |
| 510 | auto* lhsCast = StaticCast(GetRecordDeclType(rd), thisOfParent, true); |
| 511 | auto* rhsDeclRef = mkVarDeclRefExpr("__rhs"sv, parentType); |
| 512 | auto* rhsCast = StaticCast(GetRecordDeclType(rd), rhsDeclRef, true); |
| 513 | |
| 514 | auto* callAssignBase = Call(GetSpecialMemberName(stmt, GetRecordDeclType(rd)), {lhsCast, rhsCast}); |
| 515 | |
| 516 | bodyStmts.AddBodyStmts(callAssignBase); |
| 517 | } |
| 518 | |
| 519 | // insert own fields |
nothing calls this directly
no test coverage detected