summaryrefslogtreecommitdiff
path: root/source/slang/slang-check-decl.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-08-24 12:05:19 -0700
committerGitHub <noreply@github.com>2022-08-24 12:05:19 -0700
commitba6f55ed9481960b4f6c7f0a6b8f1cf7d450c752 (patch)
treebd92bf3cca5614585f8be6ad6f57510b18565b47 /source/slang/slang-check-decl.cpp
parent3746a47ce407b14c4afbfc5b625513cf81b5e890 (diff)
Allow `static const` interface requirements. (#2378)
Diffstat (limited to 'source/slang/slang-check-decl.cpp')
-rw-r--r--source/slang/slang-check-decl.cpp76
1 files changed, 76 insertions, 0 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index abe7642fb..9e3fbaa8d 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -1053,6 +1053,33 @@ namespace Slang
addModifier(varDecl, m_astBuilder->create<NVAPIMagicModifier>());
}
}
+
+ if (auto interfaceDecl = as<InterfaceDecl>(varDecl->parentDecl))
+ {
+ if (auto basicType = as<BasicExpressionType>(varDecl->getType()))
+ {
+ switch (basicType->baseType)
+ {
+ case BaseType::Bool:
+ case BaseType::Int8:
+ case BaseType::Int16:
+ case BaseType::Int:
+ case BaseType::Int64:
+ case BaseType::UInt8:
+ case BaseType::UInt16:
+ case BaseType::UInt:
+ case BaseType::UInt64:
+ break;
+ default:
+ getSink()->diagnose(varDecl, Diagnostics::staticConstRequirementMustBeIntOrBool);
+ break;
+ }
+ }
+ if (!varDecl->findModifier<HLSLStaticModifier>() || !varDecl->findModifier<ConstModifier>())
+ {
+ getSink()->diagnose(varDecl, Diagnostics::valueRequirementMustBeCompileTimeConst);
+ }
+ }
}
void SemanticsDeclHeaderVisitor::visitStructDecl(StructDecl* structDecl)
@@ -1588,6 +1615,47 @@ namespace Slang
return true;
}
+ bool SemanticsVisitor::doesVarMatchRequirement(
+ DeclRef<VarDeclBase> satisfyingMemberDeclRef,
+ DeclRef<VarDeclBase> requiredMemberDeclRef,
+ RefPtr<WitnessTable> witnessTable)
+ {
+ // The type of the satisfying member must match the type of the required member.
+ auto satisfyingType = getType(getASTBuilder(), satisfyingMemberDeclRef);
+ auto requiredType = getType(getASTBuilder(), requiredMemberDeclRef);
+ if (!satisfyingType->equals(requiredType))
+ return false;
+
+ for (auto modifier : requiredMemberDeclRef.getDecl()->modifiers)
+ {
+ bool found = false;
+ for (auto satisfyingModifier : satisfyingMemberDeclRef.getDecl()->modifiers)
+ {
+ if (satisfyingModifier->astNodeType == modifier->astNodeType)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return false;
+ }
+
+ auto satisfyingVal = tryConstantFoldDeclRef(satisfyingMemberDeclRef, nullptr);
+ if (satisfyingVal)
+ {
+ witnessTable->add(
+ requiredMemberDeclRef,
+ RequirementWitness(satisfyingVal));
+ }
+ else
+ {
+ witnessTable->add(
+ requiredMemberDeclRef.getDecl(),
+ RequirementWitness(satisfyingMemberDeclRef));
+ }
+ return true;
+ }
bool SemanticsVisitor::doesGenericSignatureMatchRequirement(
DeclRef<GenericDecl> satisfyingGenericDeclRef,
@@ -1975,6 +2043,14 @@ namespace Slang
return doesPropertyMatchRequirement(propertyDeclRef, requiredPropertyDeclRef, witnessTable);
}
}
+ else if (auto varDeclRef = memberDeclRef.as<VarDeclBase>())
+ {
+ if (auto requiredVarDeclRef = requiredMemberDeclRef.as<VarDeclBase>())
+ {
+ ensureDecl(varDeclRef, DeclCheckState::SignatureChecked);
+ return doesVarMatchRequirement(varDeclRef, requiredVarDeclRef, witnessTable);
+ }
+ }
// Default: just assume that thing aren't being satisfied.
return false;
}