diff options
Diffstat (limited to 'source/slang/syntax.cpp')
| -rw-r--r-- | source/slang/syntax.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index e5fc8dfa3..fa9c88051 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -93,6 +93,7 @@ ABSTRACT_SYNTAX_CLASS(Expr, SyntaxNode); ABSTRACT_SYNTAX_CLASS(Substitutions, SyntaxNode); ABSTRACT_SYNTAX_CLASS(GenericSubstitution, Substitutions); ABSTRACT_SYNTAX_CLASS(ThisTypeSubstitution, Substitutions); +ABSTRACT_SYNTAX_CLASS(GlobalGenericParamSubstitution, Substitutions); #include "expr-defs.h" #include "decl-defs.h" @@ -488,6 +489,20 @@ void Type::accept(IValVisitor* visitor, void* extra) } } } + else if (auto globalGenParam = dynamic_cast<GlobalGenericParamDecl*>(declRef.getDecl())) + { + // search for a substitution that might apply to us + for (auto s = subst; s; s = s->outer.Ptr()) + { + if (auto genericSubst = dynamic_cast<GlobalGenericParamSubstitution*>(s)) + { + if (genericSubst->paramDecl == globalGenParam) + { + return genericSubst->actualType; + } + } + } + } int diff = 0; DeclRef<Decl> substDeclRef = declRef.SubstituteImpl(subst, &diff); @@ -1208,6 +1223,35 @@ void Type::accept(IValVisitor* visitor, void* extra) return false; } + RefPtr<Substitutions> GlobalGenericParamSubstitution::SubstituteImpl(Substitutions* /*subst*/, int* /*ioDiff*/) + { + // we will never replace values for this type of substitution + return this; + } + + bool GlobalGenericParamSubstitution::Equals(Substitutions* subst) + { + if (!subst) + return false; + if (auto genSubst = dynamic_cast<GlobalGenericParamSubstitution*>(subst)) + { + if (paramDecl != genSubst->paramDecl) + return false; + if (!actualType->EqualsVal(genSubst->actualType)) + return false; + if (witnessTables.Count() != genSubst->witnessTables.Count()) + return false; + for (UInt i = 0; i < witnessTables.Count(); i++) + { + if (!witnessTables[i].Key->Equals(genSubst->witnessTables[i].Key)) + return false; + if (!witnessTables[i].Value->EqualsVal(genSubst->witnessTables[i].Value)) + return false; + } + return true; + } + return false; + } // DeclRefBase @@ -1564,6 +1608,24 @@ void Type::accept(IValVisitor* visitor, void* extra) return genericSubst->args[index + ordinaryParamCount]; } } + else if (auto globalGenParamSubst = dynamic_cast<GlobalGenericParamSubstitution*>(s)) + { + // we have a GlobalGenericParamSubstitution, this substitution will provide + // a concrete IRWitnessTable for a generic global variable + auto supType = GetSup(genConstraintDecl); + + // check if the substitution is really about this global generic type parameter + if (globalGenParamSubst->paramDecl != genConstraintDecl.getDecl()->ParentDecl) + continue; + + // find witness table for the required interface + for (auto witness : globalGenParamSubst->witnessTables) + if (witness.Key->EqualsVal(supType)) + { + (*ioDiff)++; + return witness.Value; + } + } } } RefPtr<DeclaredSubtypeWitness> rs = new DeclaredSubtypeWitness(); |
