summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2017-11-04 15:20:21 -0400
committerYong He <yonghe@outlook.com>2017-11-04 15:20:21 -0400
commit31e7f84484d227206f3bbb33a8b9be8a9acecfe5 (patch)
treeeb06912348d3fd39a671308d80db999d144ae024
parentd803bf74eee7842ce8a358e145b2546c03308dfc (diff)
Passing both assoctype-simple and assoctype-complex test cases.
-rw-r--r--source/slang/check.cpp84
-rw-r--r--source/slang/emit.cpp3
-rw-r--r--source/slang/lookup.cpp43
-rw-r--r--source/slang/lower-to-ir.cpp4
-rw-r--r--source/slang/slang.vcxproj3
-rw-r--r--source/slang/slang.vcxproj.filters3
-rw-r--r--source/slang/syntax.cpp84
-rw-r--r--source/slang/syntax.h7
-rw-r--r--tests/compute/assoctype-complex.slang9
-rw-r--r--tests/compute/assoctype-complex.slang.expected.txt4
-rw-r--r--tests/compute/generics-constraint1.slang17
-rw-r--r--tests/compute/generics-constructor.slang.expected.txt4
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, &parameterLists, 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