From c94ca1692e101df87215232e87fa7edadc1a7b05 Mon Sep 17 00:00:00 2001 From: Ellie Hermaszewska Date: Tue, 1 Jul 2025 23:36:02 +0800 Subject: Allow Link time constant array length sizing, warn on unsupported functionality (#7067) * Add link time array layout test * Add link time constant array size compilation test * Link time constant array size test * Allow getting link time array size Closes https://github.com/shader-slang/slang/issues/6753 * format * Switch to SIMPLE test and check output * Implement without binary api changes * diagnose on link time constant sized array * fix test --------- Co-authored-by: Yong He --- source/slang/slang-check-decl.cpp | 5 +++++ source/slang/slang-diagnostic-defs.h | 8 ++++++++ source/slang/slang-reflection-api.cpp | 36 +++++++++++++++++++++++++++++++---- 3 files changed, 45 insertions(+), 4 deletions(-) (limited to 'source') diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 0dd859bb2..9e4d5a6d3 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -10468,6 +10468,11 @@ void SemanticsVisitor::validateArraySizeForVariable(VarDeclBase* varDecl) getSink()->diagnose(varDecl, Diagnostics::invalidArraySize); return; } + + if (elementCount->isLinkTimeVal()) + { + getSink()->diagnose(varDecl, Diagnostics::linkTimeConstantArraySize); + } } bool getExtensionTargetDeclList( diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index 384a81f9b..8efdf1d91 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -1587,6 +1587,14 @@ DIAGNOSTIC( switchDuplicateCases, "duplicate cases not allowed within a 'switch' statement") +// 310xx: link time specializaion +DIAGNOSTIC( + 31000, + Warning, + linkTimeConstantArraySize, + "Link-time constant sized arrays are a work in progress feature, some aspects of the " + "reflection API may not work") + // TODO: need to assign numbers to all these extra diagnostics... DIAGNOSTIC(39999, Fatal, cyclicReference, "cyclic reference '$0'.") DIAGNOSTIC( diff --git a/source/slang/slang-reflection-api.cpp b/source/slang/slang-reflection-api.cpp index b0d88e954..56a82e17e 100644 --- a/source/slang/slang-reflection-api.cpp +++ b/source/slang/slang-reflection-api.cpp @@ -4,6 +4,7 @@ #include "slang-check-impl.h" #include "slang-check.h" #include "slang-compiler.h" +#include "slang-deprecated.h" #include "slang-syntax.h" #include "slang-type-layout.h" #include "slang.h" @@ -567,21 +568,46 @@ SLANG_API SlangReflectionVariable* spReflectionType_GetFieldByIndex( } SLANG_API size_t spReflectionType_GetElementCount(SlangReflectionType* inType) +{ + return spReflectionType_GetSpecializedElementCount(inType, nullptr); +} + +SLANG_API size_t spReflectionType_GetSpecializedElementCount( + SlangReflectionType* inType, + SlangReflection* reflection) { auto type = convert(inType); if (!type) return 0; + IntVal* elementCount; + bool isUnsized; if (auto arrayType = as(type)) { - return !arrayType->isUnsized() ? (size_t)getIntVal(arrayType->getElementCount()) : 0; + elementCount = arrayType->getElementCount(); + isUnsized = arrayType->isUnsized(); } else if (auto vectorType = as(type)) { - return (size_t)getIntVal(vectorType->getElementCount()); + elementCount = vectorType->getElementCount(); + isUnsized = false; + } + else + { + return 0; } - return 0; + if (const auto program = convert(reflection)) + { + if (const auto componentType = program->getProgram()) + { + if (const auto c = componentType->tryFoldIntVal(elementCount)) + return c->getValue(); + } + } + + const auto isWithoutSize = isUnsized || elementCount->isLinkTimeVal(); + return isWithoutSize ? 0 : (size_t)getIntVal(elementCount); } SLANG_API SlangReflectionType* spReflectionType_GetElementType(SlangReflectionType* inType) @@ -1945,7 +1971,9 @@ struct ExtendedTypeLayoutContext LayoutSize elementCount = LayoutSize::infinite(); if (auto arrayType = as(arrayTypeLayout->type)) { - if (!arrayType->isUnsized()) + const auto isWithoutSize = + arrayType->isUnsized() || arrayType->getElementCount()->isLinkTimeVal(); + if (!isWithoutSize) { elementCount = LayoutSize::RawValue(getIntVal(arrayType->getElementCount())); } -- cgit v1.2.3