From 7a8ef896196ad0d7095412d8558dd9a2542874c8 Mon Sep 17 00:00:00 2001 From: Yong He Date: Thu, 21 Mar 2024 17:19:03 -0700 Subject: Support arrow operator `->` on pointers. (#3812) --- source/slang/slang-check-expr.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'source/slang/slang-check-expr.cpp') diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index f238550fd..dc7a2d35b 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -1918,7 +1918,8 @@ namespace Slang Expr* SemanticsExprVisitor::visitIndexExpr(IndexExpr* subscriptExpr) { - auto baseExpr = checkBaseForMemberExpr(subscriptExpr->baseExpression); + bool needDeref = false; + auto baseExpr = checkBaseForMemberExpr(subscriptExpr->baseExpression, needDeref); // If the base expression is a type, it means that this is an array declaration, // then we should disable short-circuit in case there is logical expression in @@ -3833,13 +3834,18 @@ namespace Slang return expr; } - Expr* SemanticsVisitor::checkBaseForMemberExpr(Expr* inBaseExpr) + Expr* SemanticsVisitor::checkBaseForMemberExpr(Expr* inBaseExpr, bool& outNeedDeref) { auto baseExpr = inBaseExpr; baseExpr = CheckTerm(baseExpr); - baseExpr = MaybeDereference(baseExpr); + auto derefExpr = MaybeDereference(baseExpr); + + if (derefExpr != baseExpr) + outNeedDeref = true; + + baseExpr = derefExpr; // If the base of the member lookup has an interface type // *without* a suitable this-type substitution, then we are @@ -3889,7 +3895,17 @@ namespace Slang Expr* SemanticsExprVisitor::visitMemberExpr(MemberExpr * expr) { - expr->baseExpression = checkBaseForMemberExpr(expr->baseExpression); + bool needDeref = false; + expr->baseExpression = checkBaseForMemberExpr(expr->baseExpression, needDeref); + + if (!needDeref && as(expr) && !as(expr->baseExpression->type)) + { + // The user is trying to use the `->` operator on something that can't be + // dereferenced, so we should diagnose that. + if (!as(expr->baseExpression->type)) + getSink()->diagnose(expr->memberOperatorLoc, Diagnostics::cannotDereferenceType, expr->baseExpression->type); + } + auto baseType = expr->baseExpression->type; // If we are looking up through a modified type, just pass straight -- cgit v1.2.3