summaryrefslogtreecommitdiff
path: root/source/slang/slang-check-conversion.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-02-07 18:36:35 -0800
committerGitHub <noreply@github.com>2023-02-07 18:36:35 -0800
commit4be623c52a6518eb86756a0369706c1d6670f6bb (patch)
treec24f54e34db9f1f02c2d51808b15121eba9195a9 /source/slang/slang-check-conversion.cpp
parent101f164b036d0c1c012243df69179559b6f40fb8 (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.cpp62
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.