summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-check-decl.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-05-08 20:52:36 -0700
committerGitHub <noreply@github.com>2024-05-08 20:52:36 -0700
commit8e86121b6ce0f2995050ebe112306ded6bc87ca2 (patch)
tree5c7f03ec9a144fa4d38eba67d563aefaaa1f4f9a /source/slang/slang-check-decl.cpp
parent448e21adac9ec260d7854076a686bd506bb371ec (diff)
Support `[__ref]` attribute to make `this` pass by reference. (#4139)
Fixes #4110.
Diffstat (limited to 'source/slang/slang-check-decl.cpp')
-rw-r--r--source/slang/slang-check-decl.cpp33
1 files changed, 32 insertions, 1 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 0d089874e..875fddf2f 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -2753,6 +2753,15 @@ namespace Slang
return false;
}
+ if (satisfyingMemberDeclRef.getDecl()->hasModifier<RefAttribute>()
+ != requiredMemberDeclRef.getDecl()->hasModifier<RefAttribute>())
+ {
+ // A `[ref]` method can't satisfy a non-`[ref]` requirement.
+ // The opposite direction is okay, but we will need to synthesize a wrapper
+ // to ensure type matches, so we will return false here either way.
+ return false;
+ }
+
if(satisfyingMemberDeclRef.getDecl()->hasModifier<HLSLStaticModifier>()
!= requiredMemberDeclRef.getDecl()->hasModifier<HLSLStaticModifier>())
{
@@ -3647,6 +3656,16 @@ namespace Slang
auto synConstRefAttr = m_astBuilder->create<ConstRefAttribute>();
addModifier(synthesized, synConstRefAttr);
}
+ if (requiredMemberDeclRef.getDecl()->hasModifier<RefAttribute>())
+ {
+ // If the interface requirement is `[ref]` then our
+ // synthesized method should be too.
+ //
+ synThis->type.isLeftValue = true;
+
+ auto synConstRefAttr = m_astBuilder->create<RefAttribute>();
+ addModifier(synthesized, synConstRefAttr);
+ }
if (requiredMemberDeclRef.getDecl()->hasModifier<NoDiffThisAttribute>())
{
auto noDiffThisAttr = m_astBuilder->create<NoDiffThisAttribute>();
@@ -4311,7 +4330,18 @@ namespace Slang
auto synAttr = m_astBuilder->create<MutatingAttribute>();
synAccessorDecl->modifiers.first = synAttr;
}
+ else if (requiredAccessorDeclRef.getDecl()->hasModifier<RefAttribute>())
+ {
+ synThis->type.isLeftValue = true;
+ auto synAttr = m_astBuilder->create<RefAttribute>();
+ synAccessorDecl->modifiers.first = synAttr;
+ }
+ else if (requiredAccessorDeclRef.getDecl()->hasModifier<ConstRefAttribute>())
+ {
+ auto synAttr = m_astBuilder->create<ConstRefAttribute>();
+ synAccessorDecl->modifiers.first = synAttr;
+ }
// We are going to synthesize an expression and then perform
// semantic checking on it, but if there are semantic errors
// we do *not* want to report them to the user as such, and
@@ -7733,7 +7763,8 @@ namespace Slang
if (!isEffectivelyStatic(decl))
{
auto constrefAttr = decl->findModifier<ConstRefAttribute>();
- if (constrefAttr)
+ auto refAttr = decl->findModifier<RefAttribute>();
+ if (constrefAttr || refAttr)
{
if (isTypeDifferentiable(calcThisType(getParentDecl(decl))))
{