summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-check-expr.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-08-14 18:41:48 -0700
committerGitHub <noreply@github.com>2024-08-14 18:41:48 -0700
commit071f1b6062b459928ebfd6f2f60a8d6ad021112b (patch)
tree2ba65eb40f39701db6fc775a9258ec8079d161a0 /source/slang/slang-check-expr.cpp
parent35a3d32c87f079749f6b100d01b289c3da02d7d6 (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.cpp120
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);