summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-check-decl.cpp11
-rw-r--r--source/slang/slang-check-expr.cpp47
-rw-r--r--source/slang/slang-check-impl.h19
-rw-r--r--source/slang/slang-check-type.cpp5
-rw-r--r--source/slang/slang-check.h1
-rw-r--r--source/slang/slang-ir-lower-buffer-element-type.cpp22
6 files changed, 65 insertions, 40 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 4a4ade047..eeb75e3fd 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -3105,6 +3105,17 @@ Type* unwrapArrayType(Type* type)
}
}
+Type* unwrapModifiedType(Type* type)
+{
+ for (;;)
+ {
+ if (auto modType = as<ModifiedType>(type))
+ type = modType->getBase();
+ else
+ return type;
+ }
+}
+
void discoverExtensionDecls(List<ExtensionDecl*>& decls, Decl* parent)
{
if (auto extDecl = as<ExtensionDecl>(parent))
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index 2840cdd39..1f2776ba0 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -2307,7 +2307,10 @@ Expr* SemanticsVisitor::CheckSimpleSubscriptExpr(IndexExpr* subscriptExpr, Type*
Expr* SemanticsExprVisitor::visitIndexExpr(IndexExpr* subscriptExpr)
{
bool needDeref = false;
- auto baseExpr = checkBaseForMemberExpr(subscriptExpr->baseExpression, needDeref);
+ auto baseExpr = checkBaseForMemberExpr(
+ subscriptExpr->baseExpression,
+ CheckBaseContext::Subscript,
+ needDeref);
// If the base expression is a type, it means that this is an array declaration,
// then we should disable short-circuit in case there is logical expression in
@@ -2951,7 +2954,10 @@ Expr* SemanticsExprVisitor::visitInvokeExpr(InvokeExpr* expr)
auto operatorName = getName("()");
bool needDeref = false;
- expr->functionExpr = maybeInsertImplicitOpForMemberBase(expr->functionExpr, needDeref);
+ expr->functionExpr = maybeInsertImplicitOpForMemberBase(
+ expr->functionExpr,
+ CheckBaseContext::Member,
+ needDeref);
LookupResult lookupResult = lookUpMember(
m_astBuilder,
@@ -4060,19 +4066,29 @@ void SemanticsExprVisitor::maybeCheckKnownBuiltinInvocation(Expr* invokeExpr)
}
}
-Expr* SemanticsVisitor::MaybeDereference(Expr* inExpr)
+Expr* SemanticsVisitor::maybeDereference(Expr* inExpr, CheckBaseContext checkBaseContext)
{
Expr* expr = inExpr;
for (;;)
{
auto baseType = expr->type;
+ QualType elementType;
if (auto pointerLikeType = as<PointerLikeType>(baseType))
{
- auto elementType = QualType(pointerLikeType->getElementType());
+ elementType = QualType(pointerLikeType->getElementType());
elementType.isLeftValue = baseType.isLeftValue;
elementType.hasReadOnlyOnTarget = baseType.hasReadOnlyOnTarget;
elementType.isWriteOnly = baseType.isWriteOnly;
-
+ }
+ else if (auto ptrType = as<PtrType>(baseType))
+ {
+ if (checkBaseContext == CheckBaseContext::Subscript)
+ return expr;
+ elementType = QualType(ptrType->getValueType());
+ elementType.isLeftValue = true;
+ }
+ if (elementType.type)
+ {
auto derefExpr = m_astBuilder->create<DerefExpr>();
derefExpr->base = expr;
derefExpr->type = elementType;
@@ -4080,7 +4096,6 @@ Expr* SemanticsVisitor::MaybeDereference(Expr* inExpr)
expr = derefExpr;
continue;
}
-
// Default case: just use the expression as-is
return expr;
}
@@ -4751,7 +4766,7 @@ Expr* SemanticsExprVisitor::visitStaticMemberExpr(StaticMemberExpr* expr)
expr->baseExpression = CheckTerm(expr->baseExpression);
// Not sure this is needed -> but guess someone could do
- expr->baseExpression = MaybeDereference(expr->baseExpression);
+ expr->baseExpression = maybeDereference(expr->baseExpression, CheckBaseContext::Member);
// If the base of the member lookup has an interface type
// *without* a suitable this-type substitution, then we are
@@ -4779,9 +4794,12 @@ Expr* SemanticsVisitor::lookupMemberResultFailure(
return expr;
}
-Expr* SemanticsVisitor::maybeInsertImplicitOpForMemberBase(Expr* baseExpr, bool& outNeedDeref)
+Expr* SemanticsVisitor::maybeInsertImplicitOpForMemberBase(
+ Expr* baseExpr,
+ CheckBaseContext checkBaseContext,
+ bool& outNeedDeref)
{
- auto derefExpr = MaybeDereference(baseExpr);
+ auto derefExpr = maybeDereference(baseExpr, checkBaseContext);
if (derefExpr != baseExpr)
outNeedDeref = true;
@@ -4834,11 +4852,15 @@ Expr* SemanticsVisitor::maybeInsertImplicitOpForMemberBase(Expr* baseExpr, bool&
return baseExpr;
}
-Expr* SemanticsVisitor::checkBaseForMemberExpr(Expr* inBaseExpr, bool& outNeedDeref)
+Expr* SemanticsVisitor::checkBaseForMemberExpr(
+ Expr* inBaseExpr,
+ CheckBaseContext checkBaseContext,
+ bool& outNeedDeref)
{
auto baseExpr = inBaseExpr;
baseExpr = CheckTerm(baseExpr);
- return maybeInsertImplicitOpForMemberBase(baseExpr, outNeedDeref);
+
+ return maybeInsertImplicitOpForMemberBase(baseExpr, checkBaseContext, outNeedDeref);
}
Expr* SemanticsVisitor::checkGeneralMemberLookupExpr(MemberExpr* expr, Type* baseType)
@@ -4861,7 +4883,8 @@ Expr* SemanticsVisitor::checkGeneralMemberLookupExpr(MemberExpr* expr, Type* bas
Expr* SemanticsExprVisitor::visitMemberExpr(MemberExpr* expr)
{
bool needDeref = false;
- expr->baseExpression = checkBaseForMemberExpr(expr->baseExpression, needDeref);
+ expr->baseExpression =
+ checkBaseForMemberExpr(expr->baseExpression, CheckBaseContext::Member, needDeref);
if (!needDeref && as<DerefMemberExpr>(expr) && !as<PtrType>(expr->baseExpression->type))
{
diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h
index 95ec872a5..460e87cb9 100644
--- a/source/slang/slang-check-impl.h
+++ b/source/slang/slang-check-impl.h
@@ -2654,8 +2654,6 @@ public:
//
//
- Expr* MaybeDereference(Expr* inExpr);
-
Expr* CheckMatrixSwizzleExpr(
MemberExpr* memberRefExpr,
Type* baseElementType,
@@ -2696,11 +2694,24 @@ public:
/// Perform checking operations required for the "base" expression of a member-reference like
/// `base.someField`
- Expr* checkBaseForMemberExpr(Expr* baseExpr, bool& outNeedDeref);
+ enum class CheckBaseContext
+ {
+ Member,
+ Subscript,
+ };
+ Expr* checkBaseForMemberExpr(
+ Expr* baseExpr,
+ CheckBaseContext checkBaseContext,
+ bool& outNeedDeref);
+
+ Expr* maybeDereference(Expr* inExpr, CheckBaseContext checkBaseContext);
/// Prepare baseExpr for use as the base of a member expr.
/// This include inserting implicit open-existential operations as needed.
- Expr* maybeInsertImplicitOpForMemberBase(Expr* baseExpr, bool& outNeedDeref);
+ Expr* maybeInsertImplicitOpForMemberBase(
+ Expr* baseExpr,
+ CheckBaseContext checkBaseContext,
+ bool& outNeedDeref);
Expr* lookupMemberResultFailure(
DeclRefExpr* expr,
diff --git a/source/slang/slang-check-type.cpp b/source/slang/slang-check-type.cpp
index d9691a828..2c8f3d0c0 100644
--- a/source/slang/slang-check-type.cpp
+++ b/source/slang/slang-check-type.cpp
@@ -216,9 +216,10 @@ bool isManagedType(Type* type)
{
if (auto declRefValueType = as<DeclRefType>(type))
{
- if (as<ClassDecl>(declRefValueType->getDeclRef().getDecl()))
+ auto decl = declRefValueType->getDeclRef().getDecl();
+ if (as<ClassDecl>(decl))
return true;
- if (as<InterfaceDecl>(declRefValueType->getDeclRef().getDecl()))
+ if (as<InterfaceDecl>(decl) && decl->findModifier<ComInterfaceAttribute>())
return true;
}
return false;
diff --git a/source/slang/slang-check.h b/source/slang/slang-check.h
index bd2bdce41..f1392e9ce 100644
--- a/source/slang/slang-check.h
+++ b/source/slang/slang-check.h
@@ -24,6 +24,7 @@ bool isFromCoreModule(Decl* decl);
void registerBuiltinDecls(Session* session, Decl* decl);
Type* unwrapArrayType(Type* type);
+Type* unwrapModifiedType(Type* type);
OrderedDictionary<GenericTypeParamDeclBase*, List<Type*>> getCanonicalGenericConstraints(
ASTBuilder* builder,
diff --git a/source/slang/slang-ir-lower-buffer-element-type.cpp b/source/slang/slang-ir-lower-buffer-element-type.cpp
index bd3e350bc..dd62ca02c 100644
--- a/source/slang/slang-ir-lower-buffer-element-type.cpp
+++ b/source/slang/slang-ir-lower-buffer-element-type.cpp
@@ -901,28 +901,6 @@ struct LoweredElementTypeContext
{
builder.setInsertBefore(ptrVal);
auto newArrayPtrVal = fieldAddr->getBase();
- // Is base a pointer to an empty struct? If so, don't offset it.
- // For example, if the user has written:
- // ```
- // struct S {int arr[]};
- // uniform S* p;
- // void test() { p->arr[1]; }
- // ```
- // Then `S` will become an empty struct after we remove `arr[]`.
- // And `p` will be come a `void*`.
- // We don't want to offset `p` to `p+1` to get the starting address of
- // the array in this case.
- IRSizeAndAlignment parentStructSize = {};
- getNaturalSizeAndAlignment(
- target->getOptionSet(),
- tryGetPointedToType(&builder, fieldAddr->getBase()->getDataType()),
- &parentStructSize);
- if (parentStructSize.size != 0)
- {
- newArrayPtrVal = builder.emitGetOffsetPtr(
- fieldAddr->getBase(),
- builder.getIntValue(builder.getIntType(), 1));
- }
auto loweredInnerType =
getLoweredTypeInfo(unsizedArrayType->getElementType(), layoutRules);