diff options
| author | Yong He <yonghe@outlook.com> | 2025-05-15 12:51:29 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-15 12:51:29 -0700 |
| commit | 0d6312f3be66f4bff9eec9606228db3edc309e2c (patch) | |
| tree | a868e452e2d25a88f8a6cdee109a280edd11c0fb /source/slang/slang-check-decl.cpp | |
| parent | d961f4438ef865028d289148d22e0fb5c0d8319a (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.cpp | 91 |
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) |
