diff options
| author | Julius Ikkala <julius.ikkala@gmail.com> | 2025-05-22 22:10:42 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-22 22:10:42 +0300 |
| commit | ce238dd878038bf857968931773cc9b10f3b225d (patch) | |
| tree | 2e29a5191fff5eb85a5a7895fd68b7b285bcb198 /source/slang/slang-ast-val.cpp | |
| parent | 27c6e9b01f7386263bde90e16812be46327015c2 (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.cpp | 101 |
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) |
