From 04c9a9fef507df565352826aeec200247cdf8f07 Mon Sep 17 00:00:00 2001 From: kaizhangNV Date: Wed, 2 Oct 2024 14:35:43 -0700 Subject: [PATCH] simplify the logic for creating invoke for synthesized ctor Separate the logic of _invokeExprForSynthesizedCtor from _readAggregateValueFromInitializerList. Because we don't really need to read and coerce the values recursively from the initializer list when we go this path. After we form a invoke expression to synthesized ctor, the ResolveInvoke logic will help us to coerce the arguments. --- source/slang/slang-check-conversion.cpp | 146 +++++++++++------------- source/slang/slang-check-impl.h | 16 +-- 2 files changed, 67 insertions(+), 95 deletions(-) diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp index 9c3c082e89..4e7dea05c9 100644 --- a/source/slang/slang-check-conversion.cpp +++ b/source/slang/slang-check-conversion.cpp @@ -103,8 +103,7 @@ namespace Slang Type* toType, Expr** outToExpr, InitializerListExpr* fromInitializerListExpr, - UInt &ioInitArgIndex, - bool useLegacyMode) + UInt &ioInitArgIndex) { // First, we will check if we have run out of arguments // on the initializer list. @@ -161,8 +160,7 @@ namespace Slang toType, outToExpr, fromInitializerListExpr, - ioInitArgIndex, - useLegacyMode); + ioInitArgIndex); } DeclRefType* findBaseStructType(ASTBuilder* astBuilder, DeclRef structTypeDeclRef) @@ -277,36 +275,27 @@ namespace Slang bool SemanticsVisitor::_invokeExprForSynthesizedCtor( Type* toType, - StructDecl* structDecl, InitializerListExpr* fromInitializerListExpr, - UInt &ioArgIndex, Expr** outExpr) { - auto synthesizedConstructor = _getSynthesizedConstructor(structDecl); - SLANG_ASSERT(synthesizedConstructor); - - List coercedArgs; - - for(auto param : getParameters(getASTBuilder(), synthesizedConstructor)) + StructDecl* structDecl = nullptr; + if(auto toDeclRefType = as(toType)) { - Expr* coercedArg = nullptr; - bool argResult = _readValueFromInitializerList( - getType(m_astBuilder, param), - &coercedArg, - fromInitializerListExpr, - ioArgIndex); - - // No point in trying further if any argument fails - if(!argResult) - return false; - - if( coercedArg ) + auto toTypeDeclRef = toDeclRefType->getDeclRef(); + if(auto toStructDeclRef = toTypeDeclRef.as()) { - coercedArgs.add(coercedArg); + structDecl = toStructDeclRef.getDecl(); } } - auto ctorInvokeExpr = _prepareCtorInvokeExpr(toType, fromInitializerListExpr->loc, coercedArgs); + if (!structDecl || isFromStdLib(structDecl)) + return false; + + auto synthesizedConstructor = _getSynthesizedConstructor(structDecl); + SLANG_ASSERT(synthesizedConstructor); + + List coercedArgs; + auto ctorInvokeExpr = _prepareCtorInvokeExpr(toType, fromInitializerListExpr->loc, fromInitializerListExpr->args); if (ctorInvokeExpr) { // The reason we need to check the coercion again is that the ResolveInvoke() could still find us @@ -343,8 +332,7 @@ namespace Slang Type* inToType, Expr** outToExpr, InitializerListExpr* fromInitializerListExpr, - UInt &ioArgIndex, - bool useLegacyMode) + UInt &ioArgIndex) { auto toType = inToType; UInt argCount = fromInitializerListExpr->args.getCount(); @@ -565,62 +553,50 @@ namespace Slang auto toTypeDeclRef = toDeclRefType->getDeclRef(); if(auto toStructDeclRef = toTypeDeclRef.as()) { - // TODO: create a function '_createCtorInvokeExpr()' - // We must have a synthesized constructor here there are only two cases that we don't synthesized constructor: - // 1. It is a stdlib struct. - // 2. It is a struct that has user defined constructor. (In this case, we should have already handled it in _coerceInitializerList) - if (!isFromStdLib(toStructDeclRef.getDecl()) && !useLegacyMode) - { - return _invokeExprForSynthesizedCtor(inToType, toStructDeclRef.getDecl(), fromInitializerListExpr, ioArgIndex, outToExpr); - } - else + // Trying to initialize a `struct` type given an initializer list. + // + // Before we iterate over the fields, we want to check if this struct + // inherits from another `struct` type. If so, we want to read + // an initializer for that base type first. + // + if (auto baseStructType = findBaseStructType(m_astBuilder, toStructDeclRef)) { - // Trying to initialize a `struct` type given an initializer list. - // - // Before we iterate over the fields, we want to check if this struct - // inherits from another `struct` type. If so, we want to read - // an initializer for that base type first. - // - if (auto baseStructType = findBaseStructType(m_astBuilder, toStructDeclRef)) + Expr* coercedArg = nullptr; + bool argResult = _readValueFromInitializerList( + baseStructType, + outToExpr ? &coercedArg : nullptr, + fromInitializerListExpr, + ioArgIndex); + + // No point in trying further if any argument fails + if (!argResult) + return false; + + if (coercedArg) { - Expr* coercedArg = nullptr; - bool argResult = _readValueFromInitializerList( - baseStructType, - outToExpr ? &coercedArg : nullptr, - fromInitializerListExpr, - ioArgIndex); - - // No point in trying further if any argument fails - if (!argResult) - return false; - - if (coercedArg) - { - coercedArgs.add(coercedArg); - } + coercedArgs.add(coercedArg); } + } - // We will go through the fields in order and try to match them - // up with initializer arguments. - // - for(auto fieldDeclRef : getMembersOfType(m_astBuilder, toStructDeclRef, MemberFilterStyle::Instance)) + // We will go through the fields in order and try to match them + // up with initializer arguments. + // + for(auto fieldDeclRef : getMembersOfType(m_astBuilder, toStructDeclRef, MemberFilterStyle::Instance)) + { + Expr* coercedArg = nullptr; + bool argResult = _readValueFromInitializerList( + getType(m_astBuilder, fieldDeclRef), + outToExpr ? &coercedArg : nullptr, + fromInitializerListExpr, + ioArgIndex); + + // No point in trying further if any argument fails + if(!argResult) + return false; + + if( coercedArg ) { - Expr* coercedArg = nullptr; - bool argResult = _readValueFromInitializerList( - getType(m_astBuilder, fieldDeclRef), - outToExpr ? &coercedArg : nullptr, - fromInitializerListExpr, - ioArgIndex, - true); - - // No point in trying further if any argument fails - if(!argResult) - return false; - - if( coercedArg ) - { - coercedArgs.add(coercedArg); - } + coercedArgs.add(coercedArg); } } } @@ -704,12 +680,18 @@ namespace Slang return true; } + // try to invoke the synthesized constructor if it exists + if (_invokeExprForSynthesizedCtor(toType, fromInitializerListExpr, outToExpr)) + { + // TODO: check if it's C-style initializer list + // if it's not, return error. + // if it is, return, fall-back to legacy logic + } + // We will fall back to the legacy logic of initialize list. if(!_readAggregateValueFromInitializerList(toType, outToExpr, fromInitializerListExpr, argIndex)) { - bool useLegacyMode = true; - if(!_readAggregateValueFromInitializerList(toType, outToExpr, fromInitializerListExpr, argIndex, useLegacyMode)) - return false; + return false; } if(argIndex != argCount) diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h index 3ecf60bf85..5b4b31d246 100644 --- a/source/slang/slang-check-impl.h +++ b/source/slang/slang-check-impl.h @@ -1499,8 +1499,7 @@ namespace Slang Type* toType, Expr** outToExpr, InitializerListExpr* fromInitializerListExpr, - UInt &ioInitArgIndex, - bool useLegacyMode = false); + UInt &ioInitArgIndex); /// Read an aggregate value from an initializer list expression. /// @@ -1525,8 +1524,7 @@ namespace Slang Type* inToType, Expr** outToExpr, InitializerListExpr* fromInitializerListExpr, - UInt &ioArgIndex, - bool useLegacyMode = false); + UInt &ioArgIndex); /// Coerce an initializer-list expression to a specific type. /// @@ -2761,18 +2759,10 @@ namespace Slang CompletionSuggestions::ScopeKind scopeKind, LookupResult const& lookupResult); bool _invokeExprForExplicitCtor(Type* toType, InitializerListExpr* fromInitializerListExpr, Expr** outExpr); - bool _invokeExprForSynthesizedCtor( - Type* toType, - StructDecl* structDecl, - InitializerListExpr* fromInitializerListExpr, - UInt &ioArgIndex, - Expr** outExpr); - + bool _invokeExprForSynthesizedCtor(Type* toType, InitializerListExpr* fromInitializerListExpr, Expr** outExpr); Expr* _prepareCtorInvokeExpr(Type* toType, const SourceLoc& loc, const List& coercedArgs); - bool _hasExplicitConstructor(StructDecl* structDecl); ConstructorDecl* _getSynthesizedConstructor(StructDecl* structDecl); - };