summaryrefslogtreecommitdiffstats
path: root/source/slang/check.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/check.cpp')
-rw-r--r--source/slang/check.cpp96
1 files changed, 88 insertions, 8 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index 0c35c4bf4..fe7498d86 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -1538,7 +1538,48 @@ namespace Slang
requiredInitDecl);
}
}
+ else if (auto subStructTypeDecl = dynamic_cast<AggTypeDecl*>(memberDecl))
+ {
+ // this is a sub type (e.g. nested struct declaration) in an aggregate type
+ // check if this sub type declaration satisfies the constraints defined by the associated type
+ if (auto requiredTypeDecl = requiredMemberDeclRef.As<AssocTypeDecl>())
+ {
+ bool conformance = true;
+ for (auto & inheritanceDecl : requiredTypeDecl.getDecl()->getMembersOfType<InheritanceDecl>())
+ {
+ conformance = conformance && checkConformance(subStructTypeDecl, inheritanceDecl.Ptr());
+ }
+ return conformance;
+ }
+ }
+ else if (auto typedefDecl = dynamic_cast<TypeDefDecl*>(memberDecl))
+ {
+ // this is a type-def decl in an aggregate type
+ // check if the specified type satisfies the constraints defined by the associated type
+ if (auto requiredTypeDecl = requiredMemberDeclRef.As<AssocTypeDecl>())
+ {
+ auto constraintList = requiredTypeDecl.getDecl()->getMembersOfType<InheritanceDecl>();
+ if (constraintList.Count())
+ {
+ auto declRefType = typedefDecl->type->AsDeclRefType();
+ if (!declRefType)
+ return false;
+ auto subStructTypeDecl = declRefType->declRef.getDecl()->As<AggTypeDecl>();
+ //TODO: What do we do if type is a generic specialization?
+ // i.e. if the struct defines typedef Generic<float> T;
+ // how to check if T satisfies the associatedtype constraints?
+ // the code below will only work when T is defined to be a simple aggregated type (no generics).
+ bool conformance = true;
+ for (auto & inheritanceDecl : constraintList)
+ {
+ conformance = conformance && checkConformance(subStructTypeDecl, inheritanceDecl.Ptr());
+ }
+ return conformance;
+ }
+ return true;
+ }
+ }
// Default: just assume that thing aren't being satisfied.
return false;
}
@@ -1623,11 +1664,13 @@ namespace Slang
// declares conformance to the interface `interfaceDeclRef`,
// (via the given `inheritanceDecl`) actually provides
// members to satisfy all the requirements in the interface.
- void checkInterfaceConformance(
+ bool checkInterfaceConformance(
AggTypeDecl* typeDecl,
InheritanceDecl* inheritanceDecl,
DeclRef<InterfaceDecl> interfaceDeclRef)
{
+ bool result = true;
+
// We need to check the declaration of the interface
// before we can check that we conform to it.
EnsureDecl(interfaceDeclRef.getDecl());
@@ -1654,7 +1697,7 @@ namespace Slang
// to the inherited interface.
//
// TODO: we *really* need a linearization step here!!!!
- checkConformanceToType(
+ result = result && checkConformanceToType(
typeDecl,
inheritanceDecl,
getBaseType(requiredInheritanceDeclRef));
@@ -1670,16 +1713,20 @@ namespace Slang
requiredMemberDeclRef);
if (!conformanceWitness)
+ {
+ result = false;
continue;
+ }
// Store that witness into a table stored on the `inheritnaceDecl`
// so that it can be used for downstream code generation.
inheritanceDecl->requirementWitnesses.Add(requiredMemberDeclRef, conformanceWitness);
}
+ return result;
}
- void checkConformanceToType(
+ bool checkConformanceToType(
AggTypeDecl* typeDecl,
InheritanceDecl* inheritanceDecl,
Type* baseType)
@@ -1692,29 +1739,29 @@ namespace Slang
// The type is stating that it conforms to an interface.
// We need to check that it provides all of the members
// required by that interface.
- checkInterfaceConformance(
+ return checkInterfaceConformance(
typeDecl,
inheritanceDecl,
baseInterfaceDeclRef);
- return;
}
}
getSink()->diagnose(inheritanceDecl, Diagnostics::unimplemented, "type not supported for inheritance");
+ return false;
}
// Check that the type declaration `typeDecl`, which
// declares that it inherits from another type via
// `inheritanceDecl` actually does what it needs to
// for that inheritance to be valid.
- void checkConformance(
+ bool checkConformance(
AggTypeDecl* typeDecl,
InheritanceDecl* inheritanceDecl)
{
// Look at the type being inherited from, and validate
// appropriately.
auto baseType = inheritanceDecl->base.type;
- checkConformanceToType(typeDecl, inheritanceDecl, baseType);
+ return checkConformanceToType(typeDecl, inheritanceDecl, baseType);
}
void visitAggTypeDecl(AggTypeDecl* decl)
@@ -1758,6 +1805,11 @@ namespace Slang
// Don't check that an interface conforms to the
// things it inherits from.
}
+ else if (auto assocTypeDecl = dynamic_cast<AssocTypeDecl*>(decl))
+ {
+ // Don't check that an associated type decl conforms to the
+ // things it inherits from.
+ }
else
{
// For non-interface types we need to check conformance.
@@ -1794,6 +1846,24 @@ namespace Slang
decl->SetCheckState(DeclCheckState::Checked);
}
+ void visitAssocTypeDecl(AssocTypeDecl* decl)
+ {
+ if (decl->IsChecked(DeclCheckState::Checked)) return;
+ decl->SetCheckState(DeclCheckState::CheckedHeader);
+
+ // assoctype only allowed in an interface
+ auto interfaceDecl = decl->ParentDecl->As<InterfaceDecl>();
+ if (!interfaceDecl)
+ getSink()->diagnose(decl, Slang::Diagnostics::assocTypeInInterfaceOnly);
+
+ // Now check all of the member declarations.
+ for (auto member : decl->Members)
+ {
+ checkDecl(member);
+ }
+ decl->SetCheckState(DeclCheckState::Checked);
+ }
+
void checkStmt(Stmt* stmt)
{
if (!stmt) return;
@@ -5647,8 +5717,13 @@ namespace Slang
RefPtr<Expr> visitInvokeExpr(InvokeExpr *expr)
{
+ if (auto appExpr = expr->FunctionExpr->As<GenericAppExpr>())
+ if (auto varExpr = appExpr->FunctionExpr->As<VarExpr>())
+ if (varExpr->name->text == "test")
+ printf("break");
// check the base expression first
expr->FunctionExpr = CheckExpr(expr->FunctionExpr);
+
// Next check the argument expressions
for (auto & arg : expr->Arguments)
@@ -6386,7 +6461,12 @@ namespace Slang
auto type = getFuncType(session, funcDeclRef);
return QualType(type);
}
-
+ else if (auto assocTypeDeclRef = declRef.As<AssocTypeDecl>())
+ {
+ auto type = DeclRefType::Create(session, assocTypeDeclRef);
+ *outTypeResult = type;
+ return QualType(getTypeType(type));
+ }
if( sink )
{
sink->diagnose(declRef, Diagnostics::unimplemented, "cannot form reference to this kind of declaration");