summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-check-expr.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-03-07 17:28:19 -0800
committerGitHub <noreply@github.com>2024-03-07 17:28:19 -0800
commita810aa31f5f366d69e67be96c169fec7d6041df7 (patch)
tree3c8697241d8f3381720661b6f5d3cdaac7789f5d /source/slang/slang-check-expr.cpp
parent6492906ebe59b573f6243e7c44476944b9dd5592 (diff)
Link-time constant and linkage API improvements. (#3708)
* Link-time constant and linkage API improvements. * Fix. * Allow module name to be empty. * Fix. * Fix. * Fix compile error.
Diffstat (limited to 'source/slang/slang-check-expr.cpp')
-rw-r--r--source/slang/slang-check-expr.cpp44
1 files changed, 28 insertions, 16 deletions
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index 33a1fa680..8b6fe76c7 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -1411,6 +1411,7 @@ namespace Slang
IntVal* SemanticsVisitor::tryConstantFoldExpr(
SubstExpr<InvokeExpr> invokeExpr,
+ ConstantFoldingKind kind,
ConstantFoldingCircularityInfo* circularityInfo)
{
// We need all the operands to the expression
@@ -1448,7 +1449,7 @@ namespace Slang
for(Index a = 0; a < argCount; ++a)
{
auto argExpr = getArg(invokeExpr, a);
- auto argVal = tryFoldIntegerConstantExpression(argExpr, circularityInfo);
+ auto argVal = tryFoldIntegerConstantExpression(argExpr, kind, circularityInfo);
if (!argVal)
return nullptr;
@@ -1647,6 +1648,7 @@ namespace Slang
IntVal* SemanticsVisitor::tryConstantFoldDeclRef(
DeclRef<VarDeclBase> const& declRef,
+ ConstantFoldingKind kind,
ConstantFoldingCircularityInfo* circularityInfo)
{
auto decl = declRef.getDecl();
@@ -1657,9 +1659,17 @@ namespace Slang
// In HLSL, `const` is used to mark compile-time constant expressions.
if(!decl->hasModifier<ConstModifier>())
return nullptr;
- // Extern const is not considered compile-time constant by the front-end.
if (decl->hasModifier<ExternModifier>())
- return nullptr;
+ {
+ // Extern const is not considered compile-time constant by the front-end.
+ if (kind == ConstantFoldingKind::CompileTime)
+ return nullptr;
+ // But if we are OK with link-time constants, we can still fold it into a val.
+ auto rs = m_astBuilder->getOrCreate<GenericParamIntVal>(
+ declRef.substitute(m_astBuilder, declRef.getDecl()->getType()),
+ declRef);
+ return rs;
+ }
if (isInterfaceRequirement(decl))
{
@@ -1678,11 +1688,12 @@ namespace Slang
ensureDecl(declRef.getDecl(), DeclCheckState::DefinitionChecked);
ConstantFoldingCircularityInfo newCircularityInfo(decl, circularityInfo);
- return tryConstantFoldExpr(getInitExpr(m_astBuilder, declRef), &newCircularityInfo);
+ return tryConstantFoldExpr(getInitExpr(m_astBuilder, declRef), kind, &newCircularityInfo);
}
IntVal* SemanticsVisitor::tryConstantFoldExpr(
SubstExpr<Expr> expr,
+ ConstantFoldingKind kind,
ConstantFoldingCircularityInfo* circularityInfo)
{
@@ -1738,7 +1749,7 @@ namespace Slang
// are defined in a way that can be used as a constant expression:
if(auto varRef = declRef.as<VarDeclBase>())
{
- return tryConstantFoldDeclRef(varRef, circularityInfo);
+ return tryConstantFoldDeclRef(varRef, kind, circularityInfo);
}
else if(auto enumRef = declRef.as<EnumCaseDecl>())
{
@@ -1750,7 +1761,7 @@ namespace Slang
return nullptr;
ConstantFoldingCircularityInfo newCircularityInfo(enumCaseDecl, circularityInfo);
- return tryConstantFoldExpr(tagExpr, &newCircularityInfo);
+ return tryConstantFoldExpr(tagExpr, kind, &newCircularityInfo);
}
}
}
@@ -1762,7 +1773,7 @@ namespace Slang
return nullptr;
if (!isScalarIntegerType(substType))
return nullptr;
- auto val = tryConstantFoldExpr(getArg(castExpr, 0), circularityInfo);
+ auto val = tryConstantFoldExpr(getArg(castExpr, 0), kind, circularityInfo);
if (val)
{
if (!castExpr.getExpr()->type)
@@ -1777,7 +1788,7 @@ namespace Slang
}
else if (auto invokeExpr = expr.as<InvokeExpr>())
{
- auto val = tryConstantFoldExpr(invokeExpr, circularityInfo);
+ auto val = tryConstantFoldExpr(invokeExpr, kind, circularityInfo);
if (val)
return val;
}
@@ -1803,6 +1814,7 @@ namespace Slang
IntVal* SemanticsVisitor::tryFoldIntegerConstantExpression(
SubstExpr<Expr> expr,
+ ConstantFoldingKind kind,
ConstantFoldingCircularityInfo* circularityInfo)
{
// Check if type is acceptable for an integer constant expression
@@ -1812,10 +1824,10 @@ namespace Slang
// Consider operations that we might be able to constant-fold...
//
- return tryConstantFoldExpr(expr, circularityInfo);
+ return tryConstantFoldExpr(expr, kind, circularityInfo);
}
- IntVal* SemanticsVisitor::CheckIntegerConstantExpression(Expr* inExpr, IntegerConstantExpressionCoercionType coercionType, Type* expectedType, DiagnosticSink* sink)
+ IntVal* SemanticsVisitor::CheckIntegerConstantExpression(Expr* inExpr, IntegerConstantExpressionCoercionType coercionType, Type* expectedType, ConstantFoldingKind kind, DiagnosticSink* sink)
{
// No need to issue further errors if the expression didn't even type-check.
if(IsErrorExpr(inExpr)) return nullptr;
@@ -1840,7 +1852,7 @@ namespace Slang
// No need to issue further errors if the type coercion failed.
if(IsErrorExpr(expr)) return nullptr;
- auto result = tryFoldIntegerConstantExpression(expr, nullptr);
+ auto result = tryFoldIntegerConstantExpression(expr, kind, nullptr);
if (!result && sink)
{
sink->diagnose(expr, Diagnostics::expectedIntegerConstantNotConstant);
@@ -1848,12 +1860,12 @@ namespace Slang
return result;
}
- IntVal* SemanticsVisitor::CheckIntegerConstantExpression(Expr* inExpr, IntegerConstantExpressionCoercionType coercionType, Type* expectedType)
+ IntVal* SemanticsVisitor::CheckIntegerConstantExpression(Expr* inExpr, IntegerConstantExpressionCoercionType coercionType, Type* expectedType, ConstantFoldingKind kind)
{
- return CheckIntegerConstantExpression(inExpr, coercionType, expectedType, getSink());
+ return CheckIntegerConstantExpression(inExpr, coercionType, expectedType, kind, getSink());
}
- IntVal* SemanticsVisitor::CheckEnumConstantExpression(Expr* expr)
+ IntVal* SemanticsVisitor::CheckEnumConstantExpression(Expr* expr, ConstantFoldingKind kind)
{
// No need to issue further errors if the expression didn't even type-check.
if(IsErrorExpr(expr)) return nullptr;
@@ -1861,7 +1873,7 @@ namespace Slang
// No need to issue further errors if the type coercion failed.
if(IsErrorExpr(expr)) return nullptr;
- auto result = tryConstantFoldExpr(expr, nullptr);
+ auto result = tryConstantFoldExpr(expr, kind, nullptr);
if (!result)
{
getSink()->diagnose(expr, Diagnostics::expectedIntegerConstantNotConstant);
@@ -1936,7 +1948,7 @@ namespace Slang
IntVal* elementCount = nullptr;
if (subscriptExpr->indexExprs.getCount() == 1)
{
- elementCount = CheckIntegerConstantExpression(subscriptExpr->indexExprs[0], IntegerConstantExpressionCoercionType::AnyInteger, nullptr);
+ elementCount = CheckIntegerConstantExpression(subscriptExpr->indexExprs[0], IntegerConstantExpressionCoercionType::AnyInteger, nullptr, ConstantFoldingKind::LinkTime);
}
else if (subscriptExpr->indexExprs.getCount() != 0)
{