diff options
| author | Yong He <yonghe@outlook.com> | 2017-11-04 15:20:21 -0400 |
|---|---|---|
| committer | Yong He <yonghe@outlook.com> | 2017-11-04 15:20:21 -0400 |
| commit | 31e7f84484d227206f3bbb33a8b9be8a9acecfe5 (patch) | |
| tree | eb06912348d3fd39a671308d80db999d144ae024 /source | |
| parent | d803bf74eee7842ce8a358e145b2546c03308dfc (diff) | |
Passing both assoctype-simple and assoctype-complex test cases.
Diffstat (limited to 'source')
| -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 |
8 files changed, 143 insertions, 88 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 |
