diff options
| -rw-r--r-- | source/slang/check.cpp | 84 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 3 | ||||
| -rw-r--r-- | source/slang/lookup.cpp | 43 | ||||
| -rw-r--r-- | source/slang/lower-to-ir.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang.vcxproj | 3 | ||||
| -rw-r--r-- | source/slang/slang.vcxproj.filters | 3 | ||||
| -rw-r--r-- | source/slang/syntax.cpp | 84 | ||||
| -rw-r--r-- | source/slang/syntax.h | 7 | ||||
| -rw-r--r-- | tests/compute/assoctype-complex.slang | 9 | ||||
| -rw-r--r-- | tests/compute/assoctype-complex.slang.expected.txt | 4 | ||||
| -rw-r--r-- | tests/compute/generics-constraint1.slang | 17 | ||||
| -rw-r--r-- | tests/compute/generics-constructor.slang.expected.txt | 4 |
12 files changed, 157 insertions, 108 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp index 5b3247ea4..8e5bab4e5 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -140,46 +140,6 @@ namespace Slang return result; } - void insertSubstAtBottom(DeclRefBase & declRef, RefPtr<Substitutions> substToInsert) - { - RefPtr<Substitutions> lastSubst; - auto subst = declRef.substitutions; - while (subst) - { - if (subst) - lastSubst = subst; - subst = subst->outer; - } - if (lastSubst) - lastSubst->outer = substToInsert; - else - declRef.substitutions = substToInsert; - } - - RefPtr<ThisTypeSubstitution> getThisTypeSubst(DeclRefBase & declRef, bool insertSubstEntry) - { - RefPtr<ThisTypeSubstitution> thisSubst; - auto subst = declRef.substitutions; - while (subst) - { - if (auto s = subst.As<ThisTypeSubstitution>()) - { - thisSubst = s; - break; - } - subst = subst->outer; - } - if (!thisSubst) - { - thisSubst = new ThisTypeSubstitution(); - if (insertSubstEntry) - { - insertSubstAtBottom(declRef, thisSubst); - } - } - return thisSubst; - } - RefPtr<DeclRefType> getExprDeclRefType(Expr * expr) { if (auto typetype = expr->type->As<TypeType>()) @@ -221,19 +181,25 @@ namespace Slang RefPtr<ThisTypeSubstitution> baseThisTypeSubst; if (auto baseDeclRefExpr = baseExpr->As<DeclRefExpr>()) + { baseThisTypeSubst = getThisTypeSubst(baseDeclRefExpr->declRef, false); - + if (auto baseAssocType = baseDeclRefExpr->declRef.As<AssocTypeDecl>()) + { + baseThisTypeSubst = new ThisTypeSubstitution(); + baseThisTypeSubst->sourceType = baseDeclRefExpr->type.type; + if (auto typetype = baseThisTypeSubst->sourceType.As<TypeType>()) + baseThisTypeSubst->sourceType = typetype->type; + } + } if (auto assocTypeDecl = declRef.As<AssocTypeDecl>()) { - if (!baseThisTypeSubst) - baseThisTypeSubst = new ThisTypeSubstitution(); - expr->type = GetTypeForDeclRef(DeclRef<AssocTypeDecl>(assocTypeDecl.getDecl(), baseThisTypeSubst)); - - RefPtr<ThisTypeSubstitution> outerSubst = getThisTypeSubst(*declRefOut, true); - outerSubst->sourceType = expr->type.type; - if (auto outerTypeType = outerSubst->sourceType.As<TypeType>()) - outerSubst->sourceType = outerTypeType->type; - declRefOut->substitutions = outerSubst; + auto newThisTypeSubst = new ThisTypeSubstitution(); + if (baseThisTypeSubst) + newThisTypeSubst->sourceType = baseThisTypeSubst->sourceType; + expr->type = GetTypeForDeclRef(DeclRef<AssocTypeDecl>(assocTypeDecl.getDecl(), newThisTypeSubst)); + auto declOutThisTypeSubst = getNewThisTypeSubst(*declRefOut); + if (baseThisTypeSubst) + declOutThisTypeSubst->sourceType = baseThisTypeSubst->sourceType; return expr; } @@ -241,7 +207,9 @@ namespace Slang if (baseThisTypeSubst) { if (auto declRefExpr = expr.As<DeclRefExpr>()) - insertSubstAtBottom(declRefExpr->declRef, baseThisTypeSubst); + { + getNewThisTypeSubst(declRefExpr->declRef)->sourceType = baseThisTypeSubst->sourceType; + } } expr->type = GetTypeForDeclRef(declRef); return expr; @@ -2000,8 +1968,6 @@ namespace Slang void visitFuncDecl(FuncDecl *functionNode) { - if (functionNode->nameAndLoc.name->text == "test") - printf("break"); if (functionNode->IsChecked(DeclCheckState::Checked)) return; @@ -5861,7 +5827,6 @@ namespace Slang RefPtr<Expr> CheckInvokeExprWithCheckedOperands(InvokeExpr *expr) { - auto rs = ResolveInvoke(expr); if (auto invoke = dynamic_cast<InvokeExpr*>(rs.Ptr())) { @@ -5894,9 +5859,6 @@ namespace Slang RefPtr<Expr> visitInvokeExpr(InvokeExpr *expr) { - if (auto mbrExpr = expr->FunctionExpr->As<MemberExpr>()) - if (mbrExpr->name->text == "add") - printf("break"); // check the base expression first expr->FunctionExpr = CheckExpr(expr->FunctionExpr); @@ -6631,9 +6593,11 @@ namespace Slang } else if (auto constraintDeclRef = declRef.As<GenericTypeConstraintDecl>()) { - auto type = DeclRefType::Create(session, constraintDeclRef); - *outTypeResult = type; - return QualType(getTypeType(type)); + // When we access a constraint or an inheritance decl (as a member), + // we are conceptually performing a "cast" to the given super-type, + // with the declaration showing that such a cast is legal. + auto type = GetSup(constraintDeclRef); + return QualType(type); } if( sink ) { diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 54788e33a..ccf7f94c0 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -395,8 +395,7 @@ struct EmitVisitor void emitRawTextSpan(char const* textBegin, char const* textEnd) { // TODO(tfoley): Need to make "corelib" not use `int` for pointer-sized things... - auto len = int(textEnd - textBegin); - + auto len = textEnd - textBegin; context->shared->sb.Append(textBegin, len); } diff --git a/source/slang/lookup.cpp b/source/slang/lookup.cpp index a5425074f..b01732362 100644 --- a/source/slang/lookup.cpp +++ b/source/slang/lookup.cpp @@ -410,7 +410,27 @@ void lookUpMemberImpl( if (auto declRefType = type->As<DeclRefType>()) { auto declRef = declRefType->declRef; - if (auto aggTypeDeclRef = declRef.As<AggTypeDecl>()) + if (auto assocTypeDeclRef = declRef.As<AssocTypeDecl>()) + { + for (auto constraintDeclRef : getMembersOfType<GenericTypeConstraintDecl>(assocTypeDeclRef)) + { + // The super-type in the constraint (e.g., `Foo` in `T : Foo`) + // will tell us a type we should use for lookup. + auto bound = GetSup(constraintDeclRef); + + // Go ahead and use the target type, with an appropriate breadcrumb + // to indicate that we indirected through a type constraint. + + BreadcrumbInfo breadcrumb; + breadcrumb.prev = inBreadcrumbs; + breadcrumb.kind = LookupResultItem::Breadcrumb::Kind::Constraint; + breadcrumb.declRef = constraintDeclRef; + + // TODO: Need to consider case where this might recurse infinitely. + lookUpMemberImpl(session, semantics, name, bound, ioResult, &breadcrumb); + } + } + else if (auto aggTypeDeclRef = declRef.As<AggTypeDecl>()) { LookupRequest request; request.semantics = semantics; @@ -452,26 +472,7 @@ void lookUpMemberImpl( lookUpMemberImpl(session, semantics, name, bound, ioResult, &breadcrumb); } } - else if (auto assocTypeDeclRef = declRef.As<AssocTypeDecl>()) - { - for (auto constraintDeclRef : getMembersOfType<GenericTypeConstraintDecl>(assocTypeDeclRef)) - { - // The super-type in the constraint (e.g., `Foo` in `T : Foo`) - // will tell us a type we should use for lookup. - auto bound = GetSup(constraintDeclRef); - - // Go ahead and use the target type, with an appropriate breadcrumb - // to indicate that we indirected through a type constraint. - - BreadcrumbInfo breadcrumb; - breadcrumb.prev = inBreadcrumbs; - breadcrumb.kind = LookupResultItem::Breadcrumb::Kind::Constraint; - breadcrumb.declRef = constraintDeclRef; - - // TODO: Need to consider case where this might recurse infinitely. - lookUpMemberImpl(session, semantics, name, bound, ioResult, &breadcrumb); - } - } + } } diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp index 7a3e9356a..81fab7108 100644 --- a/source/slang/lower-to-ir.cpp +++ b/source/slang/lower-to-ir.cpp @@ -2652,8 +2652,6 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> LoweredValInfo lowerFuncDecl(FunctionDeclBase* decl) { - if (decl->getName()->text == "test") - printf("break"); // Collect the parameter lists we will use for our new function. ParameterLists parameterLists; collectParameterLists(decl, ¶meterLists, kParameterListCollectMode_Default); @@ -3086,7 +3084,7 @@ LoweredValInfo emitDeclRef( // If this declaration reference doesn't involve any specializations, // then we are done at this point. - if(!declRef.substitutions) + if(!hasGenericSubstitutions(declRef.substitutions)) return loweredDecl; auto val = getSimpleVal(context, loweredDecl); diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj index b09eae3ab..15fde5673 100644 --- a/source/slang/slang.vcxproj +++ b/source/slang/slang.vcxproj @@ -296,6 +296,9 @@ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)slang-generate.exe</AdditionalInputs> </CustomBuild> </ItemGroup> + <ItemGroup> + <None Include="slang.natstepfilter" /> + </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters index ef9b3c8e5..011199af4 100644 --- a/source/slang/slang.vcxproj.filters +++ b/source/slang/slang.vcxproj.filters @@ -77,4 +77,7 @@ <CustomBuild Include="glsl.meta.slang" /> <CustomBuild Include="hlsl.meta.slang" /> </ItemGroup> + <ItemGroup> + <None Include="slang.natstepfilter" /> + </ItemGroup> </Project>
\ No newline at end of file diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index 24d508ed5..161f9cc26 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -530,7 +530,14 @@ void Type::accept(IValVisitor* visitor, void* extra) // we want to replace it with the actual associated type else if (auto assocTypeDecl = dynamic_cast<AssocTypeDecl*>(declRef.getDecl())) { + auto thisSubst = getThisTypeSubst(declRef, false); + auto oldSubstSrc = thisSubst ? thisSubst->sourceType : nullptr; + bool restore = false; + if (thisSubst && thisSubst->sourceType.Ptr() == dynamic_cast<Val*>(this)) + thisSubst->sourceType = nullptr; auto newSubst = declRef.substitutions->SubstituteImpl(subst, ioDiff); + if (restore) + thisSubst->sourceType = oldSubstSrc; if (auto thisTypeSubst = newSubst.As<ThisTypeSubstitution>()) { if (thisTypeSubst->sourceType) @@ -1258,6 +1265,8 @@ void Type::accept(IValVisitor* visitor, void* extra) bool ThisTypeSubstitution::Equals(Substitutions* subst) { + if (!subst) + return true; if (subst && dynamic_cast<ThisTypeSubstitution*>(subst)) return true; return false; @@ -1323,7 +1332,7 @@ void Type::accept(IValVisitor* visitor, void* extra) if (decl != declRef.decl) return false; if (!substitutions) - return !declRef.substitutions; + return !declRef.substitutions || declRef.substitutions.As<ThisTypeSubstitution>(); if (!substitutions->Equals(declRef.substitutions.Ptr())) return false; @@ -1634,4 +1643,77 @@ void Type::accept(IValVisitor* visitor, void* extra) + void insertSubstAtTop(DeclRefBase & declRef, RefPtr<Substitutions> substToInsert) + { + substToInsert->outer = declRef.substitutions; + declRef.substitutions = substToInsert; + } + + RefPtr<ThisTypeSubstitution> getThisTypeSubst(DeclRefBase & declRef, bool insertSubstEntry) + { + RefPtr<ThisTypeSubstitution> thisSubst; + auto subst = declRef.substitutions; + while (subst) + { + if (auto s = subst.As<ThisTypeSubstitution>()) + { + thisSubst = s; + break; + } + subst = subst->outer; + } + if (!thisSubst) + { + thisSubst = new ThisTypeSubstitution(); + if (insertSubstEntry) + { + insertSubstAtTop(declRef, thisSubst); + } + } + return thisSubst; + } + + RefPtr<ThisTypeSubstitution> getNewThisTypeSubst(DeclRefBase & declRef) + { + auto oldSubst = getThisTypeSubst(declRef, false); + if (oldSubst) + removeSubstitution(declRef, oldSubst); + return getThisTypeSubst(declRef, true); + } + + void removeSubstitution(DeclRefBase & declRef, RefPtr<Substitutions> toRemove) + { + if (!declRef.substitutions) + return; + if (toRemove == declRef.substitutions) + { + declRef.substitutions = declRef.substitutions->outer; + return; + } + auto prev = declRef.substitutions; + auto subst = prev->outer; + while (subst) + { + if (subst == toRemove) + { + prev->outer = subst->outer; + break; + } + prev = subst; + subst = subst->outer; + } + } + + bool hasGenericSubstitutions(RefPtr<Substitutions> subst) + { + auto p = subst.Ptr(); + while (p) + { + if (dynamic_cast<GenericSubstitution*>(p)) + return true; + p = p->outer.Ptr(); + } + return false; + } + } diff --git a/source/slang/syntax.h b/source/slang/syntax.h index cf75b5624..bda43b336 100644 --- a/source/slang/syntax.h +++ b/source/slang/syntax.h @@ -1155,7 +1155,12 @@ namespace Slang RefPtr<Substitutions> createDefaultSubstitutions( Session* session, Decl* decl); - + + RefPtr<ThisTypeSubstitution> getNewThisTypeSubst(DeclRefBase & declRef); + RefPtr<ThisTypeSubstitution> getThisTypeSubst(DeclRefBase & declRef, bool insertSubstEntry); + void removeSubstitution(DeclRefBase & declRef, RefPtr<Substitutions> subst); + bool hasGenericSubstitutions(RefPtr<Substitutions> subst); + } // namespace Slang #endif
\ No newline at end of file diff --git a/tests/compute/assoctype-complex.slang b/tests/compute/assoctype-complex.slang index f29d231b6..16d6b1514 100644 --- a/tests/compute/assoctype-complex.slang +++ b/tests/compute/assoctype-complex.slang @@ -1,7 +1,7 @@ //TEST(smoke, compute):COMPARE_COMPUTE:-xslang -use-ir //TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out -RWStructuredBuffer<float> outputBuffer; +RWStructuredBuffer<int> outputBuffer; interface IBase { associatedtype V; @@ -16,9 +16,10 @@ interface ISimple struct Val : IBase { typedef int V; + int base; V sub(V a0, V a1) { - return a0-a1; + return a0 - a1 + base; } }; @@ -42,6 +43,8 @@ void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) { Simple s; Val v0, v1; - float outVal = test(s, v0, v1); // == 1.0 + v0.base = 1; + v1.base = 2; + int outVal = test<Simple>(s, v0, v1); // == 4.0 outputBuffer[dispatchThreadID.x] = outVal; }
\ No newline at end of file diff --git a/tests/compute/assoctype-complex.slang.expected.txt b/tests/compute/assoctype-complex.slang.expected.txt new file mode 100644 index 000000000..e43ad329a --- /dev/null +++ b/tests/compute/assoctype-complex.slang.expected.txt @@ -0,0 +1,4 @@ +4 +4 +4 +4
\ No newline at end of file diff --git a/tests/compute/generics-constraint1.slang b/tests/compute/generics-constraint1.slang deleted file mode 100644 index aa8d398e8..000000000 --- a/tests/compute/generics-constraint1.slang +++ /dev/null @@ -1,17 +0,0 @@ -//TEST(smoke, compute):COMPARE_COMPUTE:-xslang -use-ir -//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out - -RWStructuredBuffer<float> outputBuffer; - -__generic<T:__BuiltinFloatingPointType> -T test(T v0, T v1) -{ - return v0; -} - -[numthreads(4, 1, 1)] -void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) -{ - float outVal = test<float>(1.0, 2.0); - outputBuffer[dispatchThreadID.x] = outVal; -}
\ No newline at end of file diff --git a/tests/compute/generics-constructor.slang.expected.txt b/tests/compute/generics-constructor.slang.expected.txt new file mode 100644 index 000000000..e54af3bc8 --- /dev/null +++ b/tests/compute/generics-constructor.slang.expected.txt @@ -0,0 +1,4 @@ +40400000 +40400000 +40400000 +40400000 |
