summaryrefslogtreecommitdiffstats
path: root/source/slang/ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/ir.cpp')
-rw-r--r--source/slang/ir.cpp71
1 files changed, 56 insertions, 15 deletions
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index 677429e32..3f6f8e0a3 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -236,6 +236,60 @@ namespace Slang
return nullptr;
}
+ // IRPtrTypeBase
+
+ IRType* tryGetPointedToType(
+ IRBuilder* builder,
+ IRType* type)
+ {
+ if( auto rateQualType = as<IRRateQualifiedType>(type) )
+ {
+ type = rateQualType->getDataType();
+ }
+
+ // The "true" pointers and the pointer-like stdlib types are the easy cases.
+ if( auto ptrType = as<IRPtrTypeBase>(type) )
+ {
+ return ptrType->getValueType();
+ }
+ else if( auto ptrLikeType = as<IRPointerLikeType>(type) )
+ {
+ return ptrLikeType->getElementType();
+ }
+ //
+ // A more interesting case arises when we have a `BindExistentials<P<T>, ...>`
+ // where `P<T>` is a pointer(-like) type.
+ //
+ else if( auto bindExistentials = as<IRBindExistentialsType>(type) )
+ {
+ // We know that `BindExistentials` won't introduce its own
+ // existential type parameters, nor will any of the pointer(-like)
+ // type constructors `P`.
+ //
+ // Thus we know that the type that is pointed to should be
+ // the same as `BindExistentials<T, ...>`.
+ //
+ auto baseType = bindExistentials->getBaseType();
+ if( auto baseElementType = tryGetPointedToType(builder, baseType) )
+ {
+ UInt existentialArgCount = bindExistentials->getExistentialArgCount();
+ List<IRInst*> existentialArgs;
+ for( UInt ii = 0; ii < existentialArgCount; ++ii )
+ {
+ existentialArgs.Add(bindExistentials->getExistentialArg(ii));
+ }
+ return builder->getBindExistentialsType(
+ baseElementType,
+ existentialArgCount,
+ existentialArgs.Buffer());
+ }
+ }
+
+ // TODO: We may need to handle other cases here.
+
+ return nullptr;
+ }
+
// IRBlock
@@ -2395,21 +2449,8 @@ namespace Slang
// results) at the "default" rate of the parent function,
// unless a subsequent analysis pass constraints it.
- IRType* valueType = nullptr;
- if(auto ptrType = as<IRPtrTypeBase>(ptr->getDataType()))
- {
- valueType = ptrType->getValueType();
- }
- else if(auto ptrLikeType = as<IRPointerLikeType>(ptr->getDataType()))
- {
- valueType = ptrLikeType->getElementType();
- }
- else
- {
- // Bad!
- SLANG_ASSERT(ptrType);
- return nullptr;
- }
+ IRType* valueType = tryGetPointedToType(this, ptr->getFullType());
+ SLANG_ASSERT(valueType);
// Ugly special case: if the front-end created a variable with
// type `Ptr<@R T>` instead of `@R Ptr<T>`, then the above