summaryrefslogtreecommitdiff
path: root/source/slang/slang-ast-val.cpp
diff options
context:
space:
mode:
authorJulius Ikkala <julius.ikkala@gmail.com>2025-05-22 22:10:42 +0300
committerGitHub <noreply@github.com>2025-05-22 22:10:42 +0300
commitce238dd878038bf857968931773cc9b10f3b225d (patch)
tree2e29a5191fff5eb85a5a7895fd68b7b285bcb198 /source/slang/slang-ast-val.cpp
parent27c6e9b01f7386263bde90e16812be46327015c2 (diff)
Make sizeof(T) & alignof(T) of generic types work as compile-time constants (#7213)
* Make sizeof(generic) work as compile-time constant * format code --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'source/slang/slang-ast-val.cpp')
-rw-r--r--source/slang/slang-ast-val.cpp101
1 files changed, 101 insertions, 0 deletions
diff --git a/source/slang/slang-ast-val.cpp b/source/slang/slang-ast-val.cpp
index 1cdca0440..92e170515 100644
--- a/source/slang/slang-ast-val.cpp
+++ b/source/slang/slang-ast-val.cpp
@@ -3,6 +3,7 @@
#include "slang-ast-builder.h"
#include "slang-ast-dispatch.h"
+#include "slang-ast-natural-layout.h"
#include "slang-check-impl.h"
#include "slang-diagnostics.h"
#include "slang-mangle.h"
@@ -1742,6 +1743,106 @@ Val* FuncCallIntVal::_substituteImplOverride(
return this;
}
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SizeOfIntVal !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+void SizeOfIntVal::_toTextOverride(StringBuilder& out)
+{
+ out << "sizeof(";
+ getTypeArg()->toText(out);
+ out << ")";
+}
+
+Val* SizeOfIntVal::tryFoldOrNull(ASTBuilder* astBuilder, Type* intType, Type* newType)
+{
+ ASTNaturalLayoutContext context(astBuilder, nullptr);
+ const auto size = context.calcSize(newType);
+
+ if (!size)
+ return nullptr;
+
+ return astBuilder->getIntVal(intType, size.size);
+}
+
+Val* SizeOfIntVal::tryFold(ASTBuilder* astBuilder, Type* intType, Type* newType)
+{
+ if (auto result = tryFoldOrNull(astBuilder, intType, newType))
+ return result;
+ auto result = astBuilder->getOrCreate<SizeOfIntVal>(intType, newType);
+ return result;
+}
+
+Val* SizeOfIntVal::_substituteImplOverride(
+ ASTBuilder* astBuilder,
+ SubstitutionSet subst,
+ int* ioDiff)
+{
+ int diff = 0;
+ auto newType = as<Type>(getTypeArg()->substituteImpl(astBuilder, subst, &diff));
+ if (!diff)
+ return this;
+
+ (*ioDiff)++;
+ return tryFold(astBuilder, getType(), newType);
+}
+
+Val* SizeOfIntVal::_resolveImplOverride()
+{
+ auto resolvedTypeArg = getTypeArg()->resolve();
+ if (resolvedTypeArg == getTypeArg())
+ return this;
+ return tryFold(getCurrentASTBuilder(), getType(), as<Type>(resolvedTypeArg));
+}
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! AlignOfIntVal !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+void AlignOfIntVal::_toTextOverride(StringBuilder& out)
+{
+ out << "alignof(";
+ getTypeArg()->toText(out);
+ out << ")";
+}
+
+Val* AlignOfIntVal::tryFoldOrNull(ASTBuilder* astBuilder, Type* intType, Type* newType)
+{
+ ASTNaturalLayoutContext context(astBuilder, nullptr);
+ const auto size = context.calcSize(newType);
+
+ if (!size)
+ return nullptr;
+
+ return astBuilder->getIntVal(intType, size.alignment);
+}
+
+Val* AlignOfIntVal::tryFold(ASTBuilder* astBuilder, Type* intType, Type* newType)
+{
+ if (auto result = tryFoldOrNull(astBuilder, intType, newType))
+ return result;
+ auto result = astBuilder->getOrCreate<AlignOfIntVal>(intType, newType);
+ return result;
+}
+
+Val* AlignOfIntVal::_substituteImplOverride(
+ ASTBuilder* astBuilder,
+ SubstitutionSet subst,
+ int* ioDiff)
+{
+ int diff = 0;
+ auto newType = as<Type>(getTypeArg()->substituteImpl(astBuilder, subst, &diff));
+ if (!diff)
+ return this;
+
+ (*ioDiff)++;
+ return tryFold(astBuilder, getType(), newType);
+}
+
+Val* AlignOfIntVal::_resolveImplOverride()
+{
+ auto resolvedTypeArg = getTypeArg()->resolve();
+ if (resolvedTypeArg == getTypeArg())
+ return this;
+ return tryFold(getCurrentASTBuilder(), getType(), as<Type>(resolvedTypeArg));
+}
+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CountOfIntVal !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
void CountOfIntVal::_toTextOverride(StringBuilder& out)