diff options
| author | Sai Praveen Bangaru <31557731+saipraveenb25@users.noreply.github.com> | 2024-07-10 13:53:35 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-10 10:53:35 -0700 |
| commit | 4a247244715e35872ab2359e9bc7cd55b5ea27d4 (patch) | |
| tree | ad5402cf83cd17cd923ad410a734d968c60def1b /source/slang/slang-check-expr.cpp | |
| parent | 8ed0f49d337338426c05aa643106098e755b8d9d (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.cpp | 51 |
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); |
