summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-02-05 22:35:36 -0800
committerGitHub <noreply@github.com>2025-02-05 22:35:36 -0800
commit6b63ff0265ee9bdb8229bb12c71c223c00de0ffa (patch)
tree8010accc99d1f5f20465e8eeb2012f37a6f5534f /source
parent78f26f076d406a3818800b57afe4d0c2eb166269 (diff)
Allow tuples to work with initializer list. (#6301)
* Allow tuples to work with initiailizer list. * Update definition of C-Style types.
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-check-conversion.cpp38
-rw-r--r--source/slang/slang-lower-to-ir.cpp23
2 files changed, 58 insertions, 3 deletions
diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp
index 6bbdc1477..6dda9c1ea 100644
--- a/source/slang/slang-check-conversion.cpp
+++ b/source/slang/slang-check-conversion.cpp
@@ -238,6 +238,21 @@ bool SemanticsVisitor::isCStyleType(Type* type, HashSet<Type*>& isVisit)
return cacheResult(true);
+ // A tuple type is C-style if all of its members are C-style.
+ if (auto tupleType = as<TupleType>(type))
+ {
+ for (Index i = 0; i < tupleType->getMemberCount(); i++)
+ {
+ auto elementType = tupleType->getMember(i);
+ // Avoid infinite loop in case of circular reference.
+ if (isVisit.contains(elementType))
+ return cacheResult(false);
+ if (!isCStyleType(elementType, isVisit))
+ return cacheResult(false);
+ }
+ return cacheResult(true);
+ }
+
if (auto structDecl = isDeclRefTypeOf<StructDecl>(type).getDecl())
{
// 2. It cannot have inheritance, but inherit from interface is fine.
@@ -299,6 +314,7 @@ bool SemanticsVisitor::isCStyleType(Type* type, HashSet<Type*>& isVisit)
if (!isCStyleType(elementType, isVisit))
return cacheResult(false);
}
+
return cacheResult(true);
}
@@ -700,6 +716,28 @@ bool SemanticsVisitor::_readAggregateValueFromInitializerList(
}
}
}
+ else if (auto tupleType = as<TupleType>(toType))
+ {
+ for (Index ee = 0; ee < tupleType->getMemberCount(); ++ee)
+ {
+ auto elementType = tupleType->getMember(ee);
+ Expr* coercedArg = nullptr;
+ bool argResult = _readValueFromInitializerList(
+ elementType,
+ outToExpr ? &coercedArg : nullptr,
+ fromInitializerListExpr,
+ ioArgIndex);
+
+ // No point in trying further if any argument fails
+ if (!argResult)
+ return false;
+
+ if (coercedArg)
+ {
+ coercedArgs.add(coercedArg);
+ }
+ }
+ }
else if (auto toDeclRefType = as<DeclRefType>(toType))
{
auto toTypeDeclRef = toDeclRefType->getDeclRef();
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index cac157f9b..36003dcb2 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -4701,6 +4701,16 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo>
{
return LoweredValInfo::simple(getBuilder()->getNullPtrValue(irType));
}
+ else if (auto tupleType = as<TupleType>(type))
+ {
+ List<IRInst*> args;
+ for (Index i = 0; i < tupleType->getMemberCount(); i++)
+ {
+ args.add(getSimpleVal(context, getDefaultVal(tupleType->getMember(i))));
+ }
+ return LoweredValInfo::simple(
+ getBuilder()->emitMakeTuple(irType, args.getCount(), args.getBuffer()));
+ }
else if (auto declRefType = as<DeclRefType>(type))
{
DeclRef<Decl> declRef = declRefType->getDeclRef();
@@ -4925,9 +4935,16 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo>
args.add(irDefaultValue);
}
}
-
- return LoweredValInfo::simple(
- getBuilder()->emitMakeStruct(irType, args.getCount(), args.getBuffer()));
+ if (as<TupleType>(type))
+ {
+ return LoweredValInfo::simple(
+ getBuilder()->emitMakeTuple(irType, args.getCount(), args.getBuffer()));
+ }
+ else
+ {
+ return LoweredValInfo::simple(
+ getBuilder()->emitMakeStruct(irType, args.getCount(), args.getBuffer()));
+ }
}
}