summaryrefslogtreecommitdiff
path: root/source/slang/lower-to-ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/lower-to-ir.cpp')
-rw-r--r--source/slang/lower-to-ir.cpp75
1 files changed, 68 insertions, 7 deletions
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp
index 12ba94146..761fe9c91 100644
--- a/source/slang/lower-to-ir.cpp
+++ b/source/slang/lower-to-ir.cpp
@@ -2668,6 +2668,9 @@ struct StmtLoweringVisitor : StmtVisitor<StmtLoweringVisitor>
// so we need to track a bit of extra data:
struct SwitchStmtInfo
{
+ // The block that will be made to contain the `switch` statement
+ IRBlock* initialBlock = nullptr;
+
// The label for the `default` case, if any.
IRBlock* defaultLabel = nullptr;
@@ -2757,12 +2760,21 @@ struct StmtLoweringVisitor : StmtVisitor<StmtLoweringVisitor>
// for the best.
//
// TODO: figure out something cleaner.
- auto caseVal = getSimpleVal(context, lowerRValueExpr(context, caseStmt->expr));
+
+ // Actually, one gotcha is that if we ever allow non-constant
+ // expressions here (or anything that requires instructions
+ // to be emitted to yield its value), then those instructions
+ // need to go into an appropriate block.
+
+ IRGenContext subContext = *context;
+ IRBuilder subBuilder = *getBuilder();
+ subBuilder.setInsertInto(info->initialBlock);
+ subContext.irBuilder = &subBuilder;
+ auto caseVal = getSimpleVal(context, lowerRValueExpr(&subContext, caseStmt->expr));
// Figure out where we are branching to.
auto label = getLabelForCase(info);
-
// Add this `case` to the list for the enclosing `switch`.
info->cases.Add(caseVal);
info->cases.Add(label);
@@ -2863,6 +2875,7 @@ struct StmtLoweringVisitor : StmtVisitor<StmtLoweringVisitor>
// Iterate over the body of the statement, looking
// for `case` or `default` statements:
SwitchStmtInfo info;
+ info.initialBlock = initialBlock;
info.defaultLabel = nullptr;
lowerSwitchCases(stmt->body, &info);
@@ -3760,6 +3773,59 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
setMangledName(inst, context->getSession()->getNameObj(name));
}
+ LoweredValInfo visitEnumCaseDecl(EnumCaseDecl* decl)
+ {
+ // A case within an `enum` decl will lower to a value
+ // of the `enum`'s "tag" type.
+ //
+ // TODO: a bit more work will be needed if we allow for
+ // enum cases that have payloads, because then we need
+ // a function that constructs the value given arguments.
+
+ IRBuilder subBuilderStorage = *getBuilder();
+ IRBuilder* subBuilder = &subBuilderStorage;
+
+ // Emit any generics that should wrap the actual type.
+ emitOuterGenerics(subBuilder, decl, decl);
+
+ IRGenContext subContextStorage = *context;
+ IRGenContext* subContext = &subContextStorage;
+ subContext->irBuilder = subBuilder;
+
+ return lowerRValueExpr(subContext, decl->initExpr);
+ }
+
+ LoweredValInfo visitEnumDecl(EnumDecl* decl)
+ {
+ // Given a declaration of a type, we need to make sure
+ // to output "witness tables" for any interfaces this
+ // type has declared conformance to.
+ for( auto inheritanceDecl : decl->getMembersOfType<InheritanceDecl>() )
+ {
+ ensureDecl(context, inheritanceDecl);
+ }
+
+ IRBuilder subBuilderStorage = *getBuilder();
+ IRBuilder* subBuilder = &subBuilderStorage;
+ emitOuterGenerics(subBuilder, decl, decl);
+
+ IRGenContext subContextStorage = *context;
+ IRGenContext* subContext = &subContextStorage;
+ subContext->irBuilder = subBuilder;
+
+ // An `enum` declaration will currently lower directly to its "tag"
+ // type, so that any references to the `enum` become referenes to
+ // the tag type instead.
+ //
+ // TODO: if we ever support `enum` types with payloads, we would
+ // need to make the `enum` lower to some kind of custom "tagged union"
+ // type.
+
+ IRType* loweredTagType = lowerType(subContext, decl->tagType);
+
+ return LoweredValInfo::simple(finishOuterGenerics(subBuilder, loweredTagType));
+ }
+
LoweredValInfo visitAggTypeDecl(AggTypeDecl* decl)
{
// Don't generate an IR `struct` for intrinsic types
@@ -3768,11 +3834,6 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
return LoweredValInfo();
}
- if(getMangledName(decl) == "_ST03int")
- {
- decl = decl;
- }
-
// Given a declaration of a type, we need to make sure
// to output "witness tables" for any interfaces this
// type has declared conformance to.