diff options
| author | Yong He <yonghe@outlook.com> | 2023-02-07 18:36:35 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-07 18:36:35 -0800 |
| commit | 4be623c52a6518eb86756a0369706c1d6670f6bb (patch) | |
| tree | c24f54e34db9f1f02c2d51808b15121eba9195a9 /source/slang/slang-check-conversion.cpp | |
| parent | 101f164b036d0c1c012243df69179559b6f40fb8 (diff) | |
Arithmetic simplifications and more IR clean up logic. (#2632)
Diffstat (limited to 'source/slang/slang-check-conversion.cpp')
| -rw-r--r-- | source/slang/slang-check-conversion.cpp | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp index 6decce625..71231b9e5 100644 --- a/source/slang/slang-check-conversion.cpp +++ b/source/slang/slang-check-conversion.cpp @@ -642,11 +642,6 @@ namespace Slang return true; } - if (auto refType = as<RefType>(toType)) - { - return _coerce(refType->getValueType(), outToExpr, fromType, fromExpr, outCost); - } - // If both are string types we assume they are convertable in both directions if (as<StringTypeBase>(fromType) && as<StringTypeBase>(toType)) { @@ -860,6 +855,63 @@ namespace Slang return true; } + if (auto refType = as<RefType>(toType)) + { + if (!refType->getValueType()->equals(fromType)) + return false; + if (!fromExpr->type.isLeftValue) + return false; + + ConversionCost subCost = kConversionCost_GetRef; + + MakeRefExpr* refExpr = nullptr; + if (outToExpr) + { + refExpr = m_astBuilder->create<MakeRefExpr>(); + refExpr->base = fromExpr; + refExpr->type = QualType(refType); + refExpr->type.isLeftValue = false; + *outToExpr = refExpr; + } + if (outCost) + *outCost = subCost; + return true; + } + + + // Allow implicit dereferencing a reference type. + if (auto fromRefType = as<RefType>(fromType)) + { + auto fromValueType = fromRefType->getValueType(); + + // If we convert, e.g., `ConstantBuffer<A> to `A`, we will allow + // subsequent conversion of `A` to `B` if such a conversion + // is possible. + // + ConversionCost subCost = kConversionCost_None; + + Expr* openRefExpr = nullptr; + if (outToExpr) + { + openRefExpr = maybeOpenRef(fromExpr); + } + + if (!_coerce( + toType, + outToExpr, + fromValueType, + openRefExpr, + &subCost)) + { + return false; + } + + if (outCost) + *outCost = subCost + kConversionCost_ImplicitDereference; + return true; + } + + // The main general-purpose approach for conversion is // using suitable marked initializer ("constructor") // declarations on the target type. |
