diff options
| author | kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> | 2025-05-15 12:00:50 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-15 10:00:50 -0700 |
| commit | d961f4438ef865028d289148d22e0fb5c0d8319a (patch) | |
| tree | ee9adf165634f89fc2454761c706f12292e58b69 /source | |
| parent | b325474c4aba52cca7e0bcd4eae02d23ca4ab9a3 (diff) | |
Implement C++ style default member initializer (#7087)
close #7069.
We just insert the assignment expression to the beginning of the user-defined ctor, where the assignee is the member with init expression.
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 82 |
1 files changed, 70 insertions, 12 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index bdd59c2c5..e7ce8721a 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -380,8 +380,13 @@ private: bool isMemberInitCtor, Index& paramIndex); - MemberExpr* createMemberExpr(ThisExpr* thisExpr, Scope* scope, Decl* member); + AssignExpr* createMemberAssignmentExpr( + ThisExpr* thisExpr, + Scope* scope, + Decl* member, + Expr* rightHandSideExpr); Expr* createCtorParamExpr(ConstructorDecl* ctor, Index paramIndex); + void maybeInsertDefaultInitExpr(StructDecl* structDecl); }; template<typename VisitorType> @@ -9194,10 +9199,11 @@ static SeqStmt* _ensureCtorBodyIsSeqStmt(ASTBuilder* m_astBuilder, ConstructorDe return as<SeqStmt>(stmt->body); } -MemberExpr* SemanticsDeclBodyVisitor::createMemberExpr( +AssignExpr* SemanticsDeclBodyVisitor::createMemberAssignmentExpr( ThisExpr* thisExpr, Scope* scope, - Decl* member) + Decl* member, + Expr* rightHandSideExpr) { MemberExpr* memberExpr = m_astBuilder->create<MemberExpr>(); memberExpr->baseExpression = thisExpr; @@ -9207,7 +9213,15 @@ MemberExpr* SemanticsDeclBodyVisitor::createMemberExpr( memberExpr->name = member->getName(); memberExpr->type = GetTypeForDeclRef(member->getDefaultDeclRef(), member->loc); - return memberExpr; + if (!memberExpr->type.isLeftValue) + return nullptr; + + auto assign = m_astBuilder->create<AssignExpr>(); + assign->left = memberExpr; + assign->right = rightHandSideExpr; + assign->loc = member->loc; + + return assign; } Expr* SemanticsDeclBodyVisitor::createCtorParamExpr(ConstructorDecl* ctor, Index paramIndex) @@ -9345,15 +9359,10 @@ void SemanticsDeclBodyVisitor::synthesizeCtorBodyForMember( } } - MemberExpr* memberExpr = createMemberExpr(thisExpr, ctor->ownedScope, member); - if (!memberExpr->type.isLeftValue) + auto assign = createMemberAssignmentExpr(thisExpr, ctor->ownedScope, member, initExpr); + if (!assign) return; - auto assign = m_astBuilder->create<AssignExpr>(); - assign->left = memberExpr; - assign->right = initExpr; - assign->loc = member->loc; - auto stmt = m_astBuilder->create<ExpressionStmt>(); stmt->expression = assign; stmt->loc = member->loc; @@ -9363,13 +9372,61 @@ void SemanticsDeclBodyVisitor::synthesizeCtorBodyForMember( checkedMemberVarExpr = cachedDeclToCheckedVar[member]; else { - checkedMemberVarExpr = CheckTerm(memberExpr); + checkedMemberVarExpr = CheckTerm(assign->left); cachedDeclToCheckedVar.add({member, checkedMemberVarExpr}); } seqStmtChild->stmts.add(stmt); } +// This function inserts the default initialization expression for every member who +// has init expression at beginning of the user-defined ctor. We don't need to do this +// for synthesized ctor, because synthesized ctor already handle this at the function +// parameters +void SemanticsDeclBodyVisitor::maybeInsertDefaultInitExpr(StructDecl* structDecl) +{ + // If there is no explicit constructor, we don't need to do anything. + if (!_hasExplicitConstructor(structDecl, false)) + return; + + // traverse all the constructors and insert the default initialization expressions. + for (auto ctor : structDecl->getMembersOfType<ConstructorDecl>()) + { + ThisExpr* thisExpr = m_astBuilder->create<ThisExpr>(); + thisExpr->scope = ctor->ownedScope; + thisExpr->type = ctor->returnType.type; + auto seqStmtChild = m_astBuilder->create<SeqStmt>(); + seqStmtChild->stmts.reserve(structDecl->members.getCount()); + + for (auto& member : structDecl->members) + { + if (auto varDeclBase = as<VarDeclBase>(member)) + { + if (varDeclBase->hasModifier<HLSLStaticModifier>() || + varDeclBase->getName() == nullptr || varDeclBase->initExpr == nullptr) + continue; + + auto assign = createMemberAssignmentExpr( + thisExpr, + ctor->ownedScope, + member, + varDeclBase->initExpr); + if (!assign) + continue; + + auto stmt = m_astBuilder->create<ExpressionStmt>(); + stmt->expression = assign; + stmt->loc = member->loc; + seqStmtChild->stmts.add(stmt); + } + } + if (seqStmtChild->stmts.getCount() != 0) + { + auto seqStmt = _ensureCtorBodyIsSeqStmt(m_astBuilder, ctor); + seqStmt->stmts.insert(0, seqStmtChild); + } + } +} void SemanticsDeclBodyVisitor::synthesizeCtorBody( DeclAndCtorInfo& structDeclInfo, @@ -9476,6 +9533,7 @@ void SemanticsDeclBodyVisitor::visitAggTypeDecl(AggTypeDecl* aggTypeDecl) } synthesizeCtorBody(structDeclInfo, inheritanceDefaultCtorList, structDecl); + maybeInsertDefaultInitExpr(structDecl); if (structDeclInfo.defaultCtor) { |
