summaryrefslogtreecommitdiff
path: root/source/slang/slang-lower-to-ir.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-08-10 14:11:27 -0700
committerGitHub <noreply@github.com>2022-08-10 14:11:27 -0700
commit88f04c29244af23c1cdd472d8d1ae3e5a650494e (patch)
tree398e55440e8f7ad157d15b2b75d9887236eaa126 /source/slang/slang-lower-to-ir.cpp
parentfcdb4629c4c3dd2931eaa88b96b668d914c4519c (diff)
`is` and `as` operator and `Optional<T>`. (#2355)
* `is` and `as` operator and `Optional<T>`. * Fix. Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-lower-to-ir.cpp')
-rw-r--r--source/slang/slang-lower-to-ir.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index be7373d40..aef60c9d9 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -3384,6 +3384,24 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
return LoweredValInfo::simple(irLit);
}
+ LoweredValInfo visitMakeOptionalExpr(MakeOptionalExpr* expr)
+ {
+ if (expr->value)
+ {
+ auto val = lowerRValueExpr(context, expr->value);
+ auto optType = lowerType(context, expr->type);
+ auto irVal = context->irBuilder->emitMakeOptionalValue(optType, val.val);
+ return LoweredValInfo::simple(irVal);
+ }
+ else
+ {
+ auto optType = lowerType(context, expr->type);
+ auto defaultVal = getDefaultVal(as<OptionalType>(expr->type)->getValueType());
+ auto irVal = context->irBuilder->emitMakeOptionalNone(optType, defaultVal.val);
+ return LoweredValInfo::simple(irVal);
+ }
+ }
+
LoweredValInfo visitAggTypeCtorExpr(AggTypeCtorExpr* /*expr*/)
{
SLANG_UNIMPLEMENTED_X("codegen for aggregate type constructor expression");
@@ -3911,6 +3929,50 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
UNREACHABLE_RETURN(LoweredValInfo());
}
+ LoweredValInfo visitAsTypeExpr(AsTypeExpr* expr)
+ {
+ auto value = lowerLValueExpr(context, expr->value);
+ auto existentialInfo = value.getExtractedExistentialValInfo();
+ auto optType = lowerType(context, expr->type);
+ SLANG_RELEASE_ASSERT(optType->getOp() == kIROp_OptionalType);
+ auto targetType = optType->getOperand(0);
+ auto witness = lowerSimpleVal(context, expr->witnessArg);
+ auto builder = getBuilder();
+ auto var = builder->emitVar(optType);
+ auto isType = builder->emitIsType(existentialInfo->extractedVal, existentialInfo->witnessTable, targetType, witness);
+ IRBlock* trueBlock;
+ IRBlock* falseBlock;
+ IRBlock* afterBlock;
+ builder->emitIfElseWithBlocks(isType, trueBlock, falseBlock, afterBlock);
+ builder->setInsertInto(trueBlock);
+ auto irVal = builder->emitReinterpret(targetType, existentialInfo->extractedVal);
+ auto optionalVal = builder->emitMakeOptionalValue(optType, irVal);
+ builder->emitStore(var, optionalVal);
+ builder->emitBranch(afterBlock);
+ builder->setInsertInto(falseBlock);
+ auto defaultVal = getDefaultVal(as<OptionalType>(expr->type)->getValueType());
+ auto noneVal = builder->emitMakeOptionalNone(optType, defaultVal.val);
+ builder->emitStore(var, noneVal);
+ builder->emitBranch(afterBlock);
+ builder->setInsertInto(afterBlock);
+ auto result = builder->emitLoad(var);
+ return LoweredValInfo::simple(result);
+ }
+
+ LoweredValInfo visitIsTypeExpr(IsTypeExpr* expr)
+ {
+ if (expr->isAlwaysTrue)
+ {
+ return LoweredValInfo::simple(getBuilder()->getBoolValue(true));
+ }
+ auto value = lowerLValueExpr(context, expr->value);
+ auto type = lowerType(context, expr->type);
+ auto witness = lowerSimpleVal(context, expr->witnessArg);
+ auto existentialInfo = value.getExtractedExistentialValInfo();
+ auto irVal = getBuilder()->emitIsType(existentialInfo->extractedVal, existentialInfo->witnessTable, type, witness);
+ return LoweredValInfo::simple(irVal);
+ }
+
LoweredValInfo visitModifierCastExpr(
ModifierCastExpr* expr)
{