From 071f1b6062b459928ebfd6f2f60a8d6ad021112b Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 14 Aug 2024 18:41:48 -0700 Subject: Variadic Generics Part 1: parsing and type checking. (#4833) --- source/slang/slang-check-expr.cpp | 120 +++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 2 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 96e0a95d0..561d17c00 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -61,7 +61,10 @@ namespace Slang Expr* SemanticsVisitor::moveTemp(Expr* const& expr, F const& func) { VarDecl* varDecl = m_astBuilder->create(); - varDecl->parentDecl = nullptr; // TODO: need to fill this in somehow! + varDecl->parentDecl = nullptr; + if (m_outerScope && m_outerScope->containerDecl) + m_outerScope->containerDecl->addMember(varDecl); + addModifier(varDecl, m_astBuilder->create()); varDecl->checkState = DeclCheckState::DefinitionChecked; varDecl->nameAndLoc.loc = expr->loc; varDecl->initExpr = expr; @@ -2091,7 +2094,7 @@ namespace Slang getSink()->diagnose(subscriptExpr, Diagnostics::multiDimensionalArrayNotSupported); } - auto elementType = CoerceToUsableType(TypeExp(baseExpr, baseTypeType->getType())); + auto elementType = CoerceToUsableType(TypeExp(baseExpr, baseTypeType->getType()), nullptr); auto arrayType = getArrayType( m_astBuilder, elementType, @@ -3466,6 +3469,119 @@ namespace Slang return expr; } + + Expr* SemanticsExprVisitor::visitExpandExpr(ExpandExpr* expr) + { + OrderedHashSet capturedTypePackSet; + auto subContext = this->withParentExpandExpr(expr, &capturedTypePackSet); + expr->baseExpr = dispatchExpr(expr->baseExpr, subContext); + + Type* patternType = nullptr; + bool isTypeExpr = false; + if (auto typeType = as(expr->baseExpr->type)) + { + patternType = typeType->getType(); + isTypeExpr = true; + } + else + { + patternType = expr->baseExpr->type; + } + if (as(patternType)) + { + expr->type = m_astBuilder->getErrorType(); + return expr; + } + if (subContext.getCapturedTypePacks()->getCount() == 0) + { + getSink()->diagnose(expr, Diagnostics::expandTermCapturesNoTypePacks); + } + List capturedTypePacks; + for (auto capturedType : capturedTypePackSet) + { + capturedTypePacks.add(capturedType); + } + auto expandType = m_astBuilder->getExpandType(patternType, capturedTypePacks.getArrayView()); + if (isTypeExpr) + expr->type = m_astBuilder->getTypeType(expandType); + else + expr->type = QualType(expandType); + return expr; + } + + Expr* SemanticsExprVisitor::visitEachExpr(EachExpr* expr) + { + if (!m_parentExpandExpr) + { + getSink()->diagnose(expr, Diagnostics::eachExprMustBeInsideExpandExpr); + expr->type = m_astBuilder->getErrorType(); + return expr; + } + + expr->baseExpr = CheckTerm(expr->baseExpr); + bool isTypeNode = false; + Type* baseType = nullptr; + if (auto typeType = as(expr->baseExpr->type)) + { + isTypeNode = true; + baseType = typeType->getType(); + } + else + { + baseType = expr->baseExpr->type; + } + if (as(baseType)) + { + expr->type = m_astBuilder->getErrorType(); + return expr; + } + if (isTypeNode) + { + auto declRefType = as(baseType); + if (!declRefType) + { + goto error; + } + if (!declRefType->getDeclRef().as()) + { + goto error; + } + } + else + { + if (!isTypePack(baseType) && !as(baseType)) + goto error; + } + { + SLANG_ASSERT(m_capturedTypePacks); + if (auto baseExpandType = as(baseType)) + { + for (Index i = 0; i < baseExpandType->getCapturedTypePackCount(); i++) + { + auto capturedType = baseExpandType->getCapturedTypePack(i); + m_capturedTypePacks->add(capturedType); + } + } + else + { + m_capturedTypePacks->add(baseType); + } + auto eachType = m_astBuilder->getEachType(baseType); + if (isTypeNode) + expr->type = m_astBuilder->getTypeType(eachType); + else + expr->type = QualType(eachType); + return expr; + } + error:; + expr->type = m_astBuilder->getErrorType(); + if (!as(baseType)) + { + getSink()->diagnose(expr, Diagnostics::expectTypePackAfterEach); + } + return expr; + } + void SemanticsExprVisitor::maybeCheckKnownBuiltinInvocation(Expr* invokeExpr) { auto checkedInvokeExpr = as(invokeExpr); -- cgit v1.2.3