summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-check-decl.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-05-15 12:51:29 -0700
committerGitHub <noreply@github.com>2025-05-15 12:51:29 -0700
commit0d6312f3be66f4bff9eec9606228db3edc309e2c (patch)
treea868e452e2d25a88f8a6cdee109a280edd11c0fb /source/slang/slang-check-decl.cpp
parentd961f4438ef865028d289148d22e0fb5c0d8319a (diff)
Add checking for hlsl register semantic. (#7118)
* Add checking for hlsl register semantic. * Fix. * Fix test. * Fix switch error. * Fix tests.
Diffstat (limited to 'source/slang/slang-check-decl.cpp')
-rw-r--r--source/slang/slang-check-decl.cpp91
1 files changed, 91 insertions, 0 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index e7ce8721a..f340bd6fd 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -95,6 +95,8 @@ struct SemanticsDeclAttributesVisitor : public SemanticsDeclVisitorBase,
void checkVarDeclCommon(VarDeclBase* varDecl);
+ void checkHLSLRegisterSemantic(VarDeclBase* varDecl, HLSLRegisterSemantic* registerSematnic);
+
void visitVarDecl(VarDecl* varDecl) { checkVarDeclCommon(varDecl); }
// Synthesize the constructor declaration for a struct during header visit, as we
@@ -12606,6 +12608,10 @@ void SemanticsDeclAttributesVisitor::checkVarDeclCommon(VarDeclBase* varDecl)
{
hasPushConstAttr = true;
}
+ else if (auto registerSemantic = as<HLSLRegisterSemantic>(modifier))
+ {
+ checkHLSLRegisterSemantic(varDecl, registerSemantic);
+ }
}
if (hasSpecConstAttr && hasPushConstAttr)
{
@@ -12623,6 +12629,91 @@ void SemanticsDeclAttributesVisitor::checkVarDeclCommon(VarDeclBase* varDecl)
}
}
+void SemanticsDeclAttributesVisitor::checkHLSLRegisterSemantic(
+ VarDeclBase* varDecl,
+ HLSLRegisterSemantic* registerSemantic)
+{
+ auto registerName = registerSemantic->registerName.getContent();
+ if (registerName.getLength() < 1)
+ {
+ getSink()->diagnose(
+ registerSemantic->registerName.getLoc(),
+ Diagnostics::invalidHLSLRegisterName,
+ registerSemantic->registerName);
+ return;
+ }
+
+ // Check to make sure the HLSL semantic register name is consistent with the resource type.
+
+ auto varType = getType(m_astBuilder, DeclRef<VarDeclBase>(varDecl));
+ varType = unwrapModifiedType(unwrapArrayType(varType));
+ bool isValid = true;
+ if (auto resType = as<ResourceType>(varType))
+ {
+ switch (registerName[0])
+ {
+ case 't':
+ if (resType->getAccess() != SLANG_RESOURCE_ACCESS_READ)
+ isValid = false;
+ break;
+ case 'u':
+ if (resType->getAccess() == SLANG_RESOURCE_ACCESS_READ)
+ isValid = false;
+ break;
+ case 's':
+ if (!resType->isCombined())
+ isValid = false;
+ break;
+ default:
+ isValid = false;
+ break;
+ }
+ }
+ else if (
+ as<HLSLByteAddressBufferType>(varType) || as<HLSLStructuredBufferType>(varType) ||
+ as<RaytracingAccelerationStructureType>(varType))
+ {
+ if (registerName[0] != 't')
+ {
+ isValid = false;
+ }
+ }
+ else if (
+ as<HLSLRWByteAddressBufferType>(varType) ||
+ as<HLSLRasterizerOrderedByteAddressBufferType>(varType) ||
+ as<HLSLRWStructuredBufferType>(varType) || as<HLSLConsumeStructuredBufferType>(varType) ||
+ as<HLSLAppendStructuredBufferType>(varType) ||
+ as<HLSLRasterizerOrderedStructuredBufferType>(varType))
+ {
+ if (registerName[0] != 'u')
+ {
+ isValid = false;
+ }
+ }
+ else if (as<SamplerStateType>(varType))
+ {
+ if (registerName[0] != 's')
+ {
+ isValid = false;
+ }
+ }
+ else if (as<ConstantBufferType>(varType))
+ {
+ if (registerName[0] != 'b')
+ {
+ isValid = false;
+ }
+ }
+ if (!isValid)
+ {
+ getSink()->diagnose(
+ registerSemantic->registerName.getLoc(),
+ Diagnostics::invalidHLSLRegisterNameForType,
+ registerName,
+ varType);
+ }
+}
+
void SemanticsDeclAttributesVisitor::checkForwardDerivativeOfAttribute(
FunctionDeclBase* funcDecl,
ForwardDerivativeOfAttribute* attr)