summaryrefslogtreecommitdiffstats
path: root/source/slang/syntax.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/syntax.cpp')
-rw-r--r--source/slang/syntax.cpp62
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();