diff options
| author | Yong He <yonghe@outlook.com> | 2024-08-14 18:41:48 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-14 18:41:48 -0700 |
| commit | 071f1b6062b459928ebfd6f2f60a8d6ad021112b (patch) | |
| tree | 2ba65eb40f39701db6fc775a9258ec8079d161a0 /source/slang/slang-check-expr.cpp | |
| parent | 35a3d32c87f079749f6b100d01b289c3da02d7d6 (diff) | |
Variadic Generics Part 1: parsing and type checking. (#4833)
Diffstat (limited to 'source/slang/slang-check-expr.cpp')
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 120 |
1 files changed, 118 insertions, 2 deletions
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>(); - 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<LocalTempVarModifier>()); 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<Type*> capturedTypePackSet; + auto subContext = this->withParentExpandExpr(expr, &capturedTypePackSet); + expr->baseExpr = dispatchExpr(expr->baseExpr, subContext); + + Type* patternType = nullptr; + bool isTypeExpr = false; + if (auto typeType = as<TypeType>(expr->baseExpr->type)) + { + patternType = typeType->getType(); + isTypeExpr = true; + } + else + { + patternType = expr->baseExpr->type; + } + if (as<ErrorType>(patternType)) + { + expr->type = m_astBuilder->getErrorType(); + return expr; + } + if (subContext.getCapturedTypePacks()->getCount() == 0) + { + getSink()->diagnose(expr, Diagnostics::expandTermCapturesNoTypePacks); + } + List<Type*> 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<TypeType>(expr->baseExpr->type)) + { + isTypeNode = true; + baseType = typeType->getType(); + } + else + { + baseType = expr->baseExpr->type; + } + if (as<ErrorType>(baseType)) + { + expr->type = m_astBuilder->getErrorType(); + return expr; + } + if (isTypeNode) + { + auto declRefType = as<DeclRefType>(baseType); + if (!declRefType) + { + goto error; + } + if (!declRefType->getDeclRef().as<GenericTypePackParamDecl>()) + { + goto error; + } + } + else + { + if (!isTypePack(baseType) && !as<TupleType>(baseType)) + goto error; + } + { + SLANG_ASSERT(m_capturedTypePacks); + if (auto baseExpandType = as<ExpandType>(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<ErrorType>(baseType)) + { + getSink()->diagnose(expr, Diagnostics::expectTypePackAfterEach); + } + return expr; + } + void SemanticsExprVisitor::maybeCheckKnownBuiltinInvocation(Expr* invokeExpr) { auto checkedInvokeExpr = as<InvokeExpr>(invokeExpr); |
