diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-06-03 17:22:48 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-03 17:22:48 -0400 |
| commit | 1b8731c809761c4e2dbec81dcee207f8a4621903 (patch) | |
| tree | b8c67d97a71df2a8ba776b6d1a39bc13138aeaf0 /source/slang/slang-ast-substitutions.cpp | |
| parent | 4e3e7f2a8f032c3f8fc4c530023aa80973598502 (diff) | |
Devirtualize AST types (#1368)
* Make getSup work with more general non-virtual 'virtual' mechanism.
* WIP: Non virtual AST types.
* Project change.
* Type doesn't implement equalsImpl
* Fix macro invocation
Make Overridden functions public to make simply accessible by base types.
* Use SLANG_UNEXPECTED.
* GetScalarType -> getScalarType
Use SLANG_UNEXPECTED instead on ASSERT in NamedExpressionType and TypeType
Diffstat (limited to 'source/slang/slang-ast-substitutions.cpp')
| -rw-r--r-- | source/slang/slang-ast-substitutions.cpp | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/source/slang/slang-ast-substitutions.cpp b/source/slang/slang-ast-substitutions.cpp new file mode 100644 index 000000000..05865fe8f --- /dev/null +++ b/source/slang/slang-ast-substitutions.cpp @@ -0,0 +1,237 @@ +// slang-ast-substitutions.cpp +#include "slang-ast-builder.h" +#include <assert.h> + +#include "slang-ast-generated-macro.h" + +namespace Slang { + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Substitutions !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +RefPtr<Substitutions> Substitutions::applySubstitutionsShallow(ASTBuilder* astBuilder, SubstitutionSet substSet, RefPtr<Substitutions> substOuter, int* ioDiff) +{ + SLANG_AST_NODE_VIRTUAL_CALL(Substitutions, applySubstitutionsShallow, (astBuilder, substSet, substOuter, ioDiff)) +} + +bool Substitutions::equals(Substitutions* subst) +{ + SLANG_AST_NODE_VIRTUAL_CALL(Substitutions, equals, (subst)) +} + +HashCode Substitutions::getHashCode() const +{ + SLANG_AST_NODE_CONST_VIRTUAL_CALL(Substitutions, getHashCode, ()) +} + +RefPtr<Substitutions> Substitutions::_applySubstitutionsShallowOverride(ASTBuilder* astBuilder, SubstitutionSet substSet, RefPtr<Substitutions> substOuter, int* ioDiff) +{ + SLANG_UNUSED(astBuilder); + SLANG_UNUSED(substSet); + SLANG_UNUSED(substOuter); + SLANG_UNUSED(ioDiff); + SLANG_UNEXPECTED("Substitutions::_applySubstitutionsShallowOverride not overridden"); + //return RefPtr<Substitutions>(); +} + +bool Substitutions::_equalsOverride(Substitutions* subst) +{ + SLANG_UNUSED(subst); + SLANG_UNEXPECTED("Substitutions::_equalsOverride not overridden"); + //return false; +} + +HashCode Substitutions::_getHashCodeOverride() const +{ + SLANG_UNEXPECTED("Substitutions::_getHashCodeOverride not overridden"); + //return HashCode(0); +} + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! GenericSubstitution !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +RefPtr<Substitutions> GenericSubstitution::_applySubstitutionsShallowOverride(ASTBuilder* astBuilder, SubstitutionSet substSet, RefPtr<Substitutions> substOuter, int* ioDiff) +{ + int diff = 0; + + if (substOuter != outer) diff++; + + List<RefPtr<Val>> substArgs; + for (auto a : args) + { + substArgs.add(a->substituteImpl(astBuilder, substSet, &diff)); + } + + if (!diff) return this; + + (*ioDiff)++; + auto substSubst = astBuilder->create<GenericSubstitution>(); + substSubst->genericDecl = genericDecl; + substSubst->args = substArgs; + substSubst->outer = substOuter; + return substSubst; +} + +bool GenericSubstitution::_equalsOverride(Substitutions* subst) +{ + // both must be NULL, or non-NULL + if (subst == nullptr) + return false; + if (this == subst) + return true; + + auto genericSubst = as<GenericSubstitution>(subst); + if (!genericSubst) + return false; + if (genericDecl != genericSubst->genericDecl) + return false; + + Index argCount = args.getCount(); + SLANG_RELEASE_ASSERT(args.getCount() == genericSubst->args.getCount()); + for (Index aa = 0; aa < argCount; ++aa) + { + if (!args[aa]->equalsVal(genericSubst->args[aa].Ptr())) + return false; + } + + if (!outer) + return !genericSubst->outer; + + if (!outer->equals(genericSubst->outer.Ptr())) + return false; + + return true; +} + +HashCode GenericSubstitution::_getHashCodeOverride() const +{ + HashCode rs = 0; + for (auto && v : args) + { + rs ^= v->getHashCode(); + rs *= 16777619; + } + return rs; +} + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ThisTypeSubstitution !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +RefPtr<Substitutions> ThisTypeSubstitution::_applySubstitutionsShallowOverride(ASTBuilder* astBuilder, SubstitutionSet substSet, RefPtr<Substitutions> substOuter, int* ioDiff) +{ + int diff = 0; + + if (substOuter != outer) diff++; + + // NOTE: Must use .as because we must have a smart pointer here to keep in scope. + auto substWitness = witness->substituteImpl(astBuilder, substSet, &diff).as<SubtypeWitness>(); + + if (!diff) return this; + + (*ioDiff)++; + auto substSubst = astBuilder->create<ThisTypeSubstitution>(); + substSubst->interfaceDecl = interfaceDecl; + substSubst->witness = substWitness; + substSubst->outer = substOuter; + return substSubst; +} + +bool ThisTypeSubstitution::_equalsOverride(Substitutions* subst) +{ + if (!subst) + return false; + if (subst == this) + return true; + + if (auto thisTypeSubst = as<ThisTypeSubstitution>(subst)) + { + // For our purposes, two this-type substitutions are + // equivalent if they have the same type as `This`, + // even if the specific witness values they use + // might differ. + // + if (this->interfaceDecl != thisTypeSubst->interfaceDecl) + return false; + + if (!this->witness->sub->equals(thisTypeSubst->witness->sub)) + return false; + + return true; + } + return false; +} + +HashCode ThisTypeSubstitution::_getHashCodeOverride() const +{ + return witness->getHashCode(); +} + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! GlobalGenericParamSubstitution !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +RefPtr<Substitutions> GlobalGenericParamSubstitution::_applySubstitutionsShallowOverride(ASTBuilder* astBuilder, SubstitutionSet substSet, RefPtr<Substitutions> substOuter, int* ioDiff) +{ + // if we find a GlobalGenericParamSubstitution in subst that references the same type_param decl + // return a copy of that GlobalGenericParamSubstitution + int diff = 0; + + if (substOuter != outer) diff++; + + auto substActualType = actualType->substituteImpl(astBuilder, substSet, &diff).as<Type>(); + + List<ConstraintArg> substConstraintArgs; + for (auto constraintArg : constraintArgs) + { + ConstraintArg substConstraintArg; + substConstraintArg.decl = constraintArg.decl; + substConstraintArg.val = constraintArg.val->substituteImpl(astBuilder, substSet, &diff); + + substConstraintArgs.add(substConstraintArg); + } + + if (!diff) + return this; + + (*ioDiff)++; + + RefPtr<GlobalGenericParamSubstitution> substSubst = astBuilder->create<GlobalGenericParamSubstitution>(); + substSubst->paramDecl = paramDecl; + substSubst->actualType = substActualType; + substSubst->constraintArgs = substConstraintArgs; + substSubst->outer = substOuter; + return substSubst; +} + +bool GlobalGenericParamSubstitution::_equalsOverride(Substitutions* subst) +{ + if (!subst) + return false; + if (subst == this) + return true; + + if (auto genSubst = as<GlobalGenericParamSubstitution>(subst)) + { + if (paramDecl != genSubst->paramDecl) + return false; + if (!actualType->equalsVal(genSubst->actualType)) + return false; + if (constraintArgs.getCount() != genSubst->constraintArgs.getCount()) + return false; + for (Index i = 0; i < constraintArgs.getCount(); i++) + { + if (!constraintArgs[i].val->equalsVal(genSubst->constraintArgs[i].val)) + return false; + } + return true; + } + return false; +} + +HashCode GlobalGenericParamSubstitution::_getHashCodeOverride() const +{ + HashCode rs = actualType->getHashCode(); + for (auto && a : constraintArgs) + { + rs = combineHash(rs, a.val->getHashCode()); + } + return rs; +} + + +} // namespace Slang |
