summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-check-expr.cpp
diff options
context:
space:
mode:
authorSai Praveen Bangaru <31557731+saipraveenb25@users.noreply.github.com>2024-07-10 13:53:35 -0400
committerGitHub <noreply@github.com>2024-07-10 10:53:35 -0700
commit4a247244715e35872ab2359e9bc7cd55b5ea27d4 (patch)
treead5402cf83cd17cd923ad410a734d968c60def1b /source/slang/slang-check-expr.cpp
parent8ed0f49d337338426c05aa643106098e755b8d9d (diff)
Various fixes around differentiable member associations `[DerivativeMember(<diff-member>)]` (#4525)
* Add diagnostic for missing diff-member associations + Automatically create diff member associations if differential type is the same as the primal type. + Move diff-member attribute checking to conformance-checking phase to avoid circularity issues. Fixes #4103 * Update slang-check-decl.cpp --------- Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'source/slang/slang-check-expr.cpp')
-rw-r--r--source/slang/slang-check-expr.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index f79e23b42..ee36a21fb 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -1213,6 +1213,57 @@ namespace Slang
}
}
+ void SemanticsVisitor::checkDerivativeMemberAttributeReferences(
+ VarDeclBase* varDecl, DerivativeMemberAttribute* derivativeMemberAttr)
+ {
+ if (derivativeMemberAttr->memberDeclRef)
+ {
+ // Already checked! This usually happens if this attribute is synthesized by the compiler.
+ return;
+ }
+
+ SLANG_ASSERT(derivativeMemberAttr->args.getCount() == 1);
+ auto checkedExpr = dispatchExpr(derivativeMemberAttr->args[0], allowStaticReferenceToNonStaticMember());
+
+ auto memberType = varDecl->type.type; // All types must be fully checked by now.
+ auto diffType = getDifferentialType(m_astBuilder, memberType, varDecl->loc);
+ auto thisType = calcThisType(makeDeclRef(varDecl->parentDecl));
+ if (!thisType) return; // Diagnostic should have been emitted previously.
+
+ auto diffThisType = getDifferentialType(m_astBuilder, thisType, derivativeMemberAttr->loc);
+ if (!diffThisType) return; // Diagnostic should have been emitted previously.
+
+ if (auto declRefExpr = as<DeclRefExpr>(checkedExpr))
+ {
+ derivativeMemberAttr->memberDeclRef = declRefExpr;
+ if (!diffType->equals(declRefExpr->type))
+ {
+ getSink()->diagnose(derivativeMemberAttr, Diagnostics::typeMismatch, diffType, declRefExpr->type);
+ }
+ if (!varDecl->parentDecl)
+ {
+ getSink()->diagnose(derivativeMemberAttr, Diagnostics::attributeNotApplicable, diffType, declRefExpr->type);
+ }
+ if (auto memberExpr = as<StaticMemberExpr>(declRefExpr))
+ {
+ auto baseExprType = memberExpr->baseExpression->type.type;
+ if (auto typeType = as<TypeType>(baseExprType))
+ {
+ if (diffThisType->equals(typeType->getType()))
+ {
+ return;
+ }
+ }
+
+ }
+ }
+ getSink()->diagnose(
+ derivativeMemberAttr,
+ Diagnostics::
+ derivativeMemberAttributeMustNameAMemberInExpectedDifferentialType,
+ diffThisType);
+ }
+
Type* SemanticsVisitor::getDifferentialType(ASTBuilder* builder, Type* type, SourceLoc loc)
{
auto result = tryGetDifferentialType(builder, type);