From 0a3656788473244b4760791c4129a4080a6631f6 Mon Sep 17 00:00:00 2001 From: Yong He Date: Fri, 3 Nov 2017 18:55:03 -0400 Subject: associatedtypes: generating almost correct HLSL, but is not calling correctly mangled function. --- source/slang/syntax.cpp | 120 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 8 deletions(-) (limited to 'source/slang/syntax.cpp') diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index a3a5fdcb6..2f3368f4c 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -376,6 +376,85 @@ void Type::accept(IValVisitor* visitor, void* extra) (int)(typeid(this).hash_code())); } + // ThisType + + String ThisType::ToString() + { + return ""; + } + + int ThisType::GetHashCode() + { + return 0; + } + + bool ThisType::EqualsImpl(Type * type) + { + return true; + } + + Type* ThisType::CreateCanonicalType() + { + // A declaration reference is already canonical + return this; + } + + RefPtr ThisType::SubstituteImpl(Substitutions* subst, int* ioDiff) + { + while (subst) + { + if (auto thisTypeSubst = dynamic_cast(subst)) + { + return thisTypeSubst->sourceType; + } + subst = subst->outer; + } + return this; + } + + // MemberType + /* + String MemberType::ToString() + { + return objectType->ToString() + "::" + declRef.toString(); + } + + int MemberType::GetHashCode() + { + return combineHash(objectType->GetHashCode(), declRef.GetHashCode()); + } + + bool MemberType::EqualsImpl(Type * type) + { + if (auto memberType = dynamic_cast(type)) + return objectType->Equals(memberType->objectType.Ptr()) && declRef.Equals(memberType->declRef); + return false; + } + + Type* MemberType::CreateCanonicalType() + { + if (auto declRefType = objectType->As()) + { + if (auto aggDeclRef = declRefType->declRef.As()) + { + Decl* targetDecl = nullptr; + if (aggDeclRef.getDecl()->memberDictionary.TryGetValue(declRef.getDecl()->nameAndLoc.name, targetDecl)) + { + if (auto typeDefDecl = dynamic_cast(targetDecl)) + return typeDefDecl->type.type; + else + return DeclRefType::Create(getSession(), DeclRef(targetDecl, aggDeclRef.substitutions)); + } + } + } + return this; + } + + RefPtr MemberType::SubstituteImpl(Substitutions* subst, int* ioDiff) + { + return this; + } + */ // DeclRefType String DeclRefType::ToString() @@ -451,16 +530,21 @@ void Type::accept(IValVisitor* visitor, void* extra) // we want to replace it with the actual associated type else if (auto assocTypeDecl = dynamic_cast(declRef.getDecl())) { - // search for a substitution that might apply to us - for (auto s = subst; s; s = s->outer.Ptr()) + auto newSubst = declRef.substitutions->SubstituteImpl(subst, ioDiff); + if (auto thisTypeSubst = newSubst.As()) { - if (auto thisTypeSubst = dynamic_cast(s)) + if (thisTypeSubst->sourceType) { if (auto aggTypeDeclRef = thisTypeSubst->sourceType.As()->declRef.As()) { Decl * targetType = nullptr; if (aggTypeDeclRef.getDecl()->memberDictionary.TryGetValue(assocTypeDecl->getName(), targetType)) - return DeclRefType::Create(this->getSession(), DeclRef(targetType, aggTypeDeclRef.substitutions)); + { + if (auto typeDefDecl = dynamic_cast(targetType)) + return typeDefDecl->type.type; + else + return DeclRefType::Create(getSession(), DeclRef(targetType, aggTypeDeclRef.substitutions)); + } } } } @@ -1142,9 +1226,27 @@ void Type::accept(IValVisitor* visitor, void* extra) if (!this) return nullptr; int diff = 0; - auto outerSubst = outer->SubstituteImpl(subst, &diff); - - auto newSourceType = sourceType->SubstituteImpl(subst, ioDiff); + RefPtr outerSubst; + if (outer) + outerSubst = outer->SubstituteImpl(subst, &diff); + RefPtr newSourceType; + if (sourceType) + newSourceType = sourceType->SubstituteImpl(subst, &diff); + else + { + // this_type is a free variable, use this_type from subst + auto psubst = subst; + while (psubst) + { + if (auto pthisSubst = dynamic_cast(subst)) + { + diff++; + newSourceType = pthisSubst->sourceType; + break; + } + psubst = psubst->outer; + } + } if (!diff) return this; (*ioDiff)++; @@ -1162,7 +1264,9 @@ void Type::accept(IValVisitor* visitor, void* extra) auto thisSubst = dynamic_cast(subst); if (!thisSubst) return false; - if (!thisSubst->sourceType->EqualsVal(sourceType)) + if (!sourceType && thisSubst->sourceType || sourceType && !thisSubst->sourceType) + return false; + if (thisSubst->sourceType && !thisSubst->sourceType->EqualsVal(sourceType)) return false; if (!outer->Equals(subst->outer.Ptr())) return false; -- cgit v1.2.3