From 9ec6b91686b651d959fd9ffbec283845bd725dd6 Mon Sep 17 00:00:00 2001 From: kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> Date: Wed, 5 Feb 2025 12:37:03 -0600 Subject: Feature/initialize list side branch (#6058) * SP004: implement initialize list translation to ctor - We synthesize a member-wise constructor for each struct follow the rules described in SP004. - Add logic to translate the initialize list to constructor invoke - Add cuda-host decoration for the synthesized constructor - Remove the default constructor when we have a valid member init constructor - Disable -zero-initialize option, will re-implement it in followup (#6109). - Fix the overload lookup issue When creating invoke expression for ctor, we need to call ResolveInvoke() to find us the best candidates, however the existing lookup logic could find us the base constructor for child struct, we should eliminate this case by providing the LookupOptions::IgnoreInheritance to lookup, this requires us to create a subcontext on SemanticsVisitor to indicate that we only want to use this option on looking the constructor. - Do not implicit initialize a struct that doesn't have explicit default constructor. Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> --- source/slang/slang-check-overload.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'source/slang/slang-check-overload.cpp') diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp index bca2f7587..b944d2bf4 100644 --- a/source/slang/slang-check-overload.cpp +++ b/source/slang/slang-check-overload.cpp @@ -1313,6 +1313,21 @@ int SemanticsVisitor::CompareLookupResultItems( bool rightIsExtension = as(rightDeclRefParent.getDecl()) != nullptr; if (leftIsExtension != rightIsExtension) { + // Add a special case for constructors, where we prefer the one that is not synthesized, + if (auto leftCtor = as(left.declRef.getDecl())) + { + auto rightCtor = as(right.declRef.getDecl()); + bool leftIsSynthesized = + leftCtor->containsFlavor(ConstructorDecl::ConstructorFlavor::SynthesizedDefault); + bool rightIsSynthesized = + rightCtor->containsFlavor(ConstructorDecl::ConstructorFlavor::SynthesizedDefault); + + if (leftIsSynthesized != rightIsSynthesized) + { + return int(leftIsSynthesized) - int(rightIsSynthesized); + } + } + return int(leftIsExtension) - int(rightIsExtension); } else if (leftIsExtension) @@ -2177,7 +2192,6 @@ void SemanticsVisitor::AddTypeOverloadCandidates(Type* type, OverloadResolveCont context.sourceScope, LookupMask::Default, options); - AddOverloadCandidates(initializers, context); } @@ -2546,7 +2560,6 @@ Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr) context.loc = expr->loc; context.sourceScope = m_outerScope; context.baseExpr = GetBaseExpr(funcExpr); - // We run a special case here where an `InvokeExpr` // with a single argument where the base/func expression names // a type should always be treated as an explicit type coercion @@ -2565,7 +2578,7 @@ Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr) // type coercion. bool typeOverloadChecked = false; - if (expr->arguments.getCount() == 1) + if (expr->arguments.getCount() == 1 && !as(expr)) { if (const auto typeType = as(funcExpr->type)) { -- cgit v1.2.3