diff options
| author | Yong He <yonghe@outlook.com> | 2022-08-10 14:11:27 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-10 14:11:27 -0700 |
| commit | 88f04c29244af23c1cdd472d8d1ae3e5a650494e (patch) | |
| tree | 398e55440e8f7ad157d15b2b75d9887236eaa126 /source/slang/slang-lower-to-ir.cpp | |
| parent | fcdb4629c4c3dd2931eaa88b96b668d914c4519c (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.cpp | 62 |
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) { |
