diff options
| author | Yong He <yonghe@outlook.com> | 2018-01-12 14:15:56 -0800 |
|---|---|---|
| committer | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-01-12 14:15:56 -0800 |
| commit | df6eeb93c1718334779ae328db277cdf7a9d7b04 (patch) | |
| tree | f4d53d3106cdc717727701e46411a1ebe23105fb /source | |
| parent | 8daafcc2e4bf7b2dfb66d7a3b7ac60c86b2d926c (diff) | |
Refactor substitution representation in DeclRefBase (#363)
This commit changes the type of `DeclRefBase::substitutions` from `RefPtr<Substitutions>` to `SubstitutionSet`, which is a new type defined as following:
```
struct SubstitutionSet
{
RefPtr<GenericSubstitution> genericSubstitutions;
RefPtr<ThisTypeSubstitution> thisTypeSubstitution;
RefPtr<GlobalGenericParamSubstitution> globalGenParamSubstitutions;
}
```
This change get rid of most helper functions to retreive the substitution of a certain type, as well as surgery operations to insert a `ThisTypeSubstitution` or `GlobalGenericTypeSubstittuion` at top or bottom of the substitution chain. It also simplies type comparison when certain type of substitution should not be considered as part of type definition.
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/ast-legalize.cpp | 28 | ||||
| -rw-r--r-- | source/slang/check.cpp | 75 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 2 | ||||
| -rw-r--r-- | source/slang/ir.cpp | 145 | ||||
| -rw-r--r-- | source/slang/legalize-types.cpp | 3 | ||||
| -rw-r--r-- | source/slang/lower-to-ir.cpp | 72 | ||||
| -rw-r--r-- | source/slang/mangle.cpp | 17 | ||||
| -rw-r--r-- | source/slang/mangle.h | 2 | ||||
| -rw-r--r-- | source/slang/parameter-binding.cpp | 6 | ||||
| -rw-r--r-- | source/slang/syntax-base-defs.h | 30 | ||||
| -rw-r--r-- | source/slang/syntax.cpp | 508 | ||||
| -rw-r--r-- | source/slang/syntax.h | 65 | ||||
| -rw-r--r-- | source/slang/type-defs.h | 6 | ||||
| -rw-r--r-- | source/slang/val-defs.h | 6 |
14 files changed, 458 insertions, 507 deletions
diff --git a/source/slang/ast-legalize.cpp b/source/slang/ast-legalize.cpp index c6f42d4da..996a66eac 100644 --- a/source/slang/ast-legalize.cpp +++ b/source/slang/ast-legalize.cpp @@ -2629,11 +2629,12 @@ struct LoweringVisitor SLANG_UNEXPECTED("unhandled value kind"); } - RefPtr<Substitutions> translateSubstitutions( - Substitutions* inSubstitutions) + SubstitutionSet translateSubstitutions( + SubstitutionSet inSubstitutions) { - if (!inSubstitutions) return nullptr; - if (auto genSubst = dynamic_cast<GenericSubstitution*>(inSubstitutions)) + if (!inSubstitutions) return SubstitutionSet(); + SubstitutionSet rs; + if (auto genSubst = inSubstitutions.genericSubstitutions) { RefPtr<GenericSubstitution> result = new GenericSubstitution(); result->genericDecl = translateDeclRef(genSubst->genericDecl)->As<GenericDecl>(); @@ -2641,16 +2642,16 @@ struct LoweringVisitor { result->args.Add(translateVal(arg)); } - return result; + rs.genericSubstitutions = result; } - else if (auto thisSubst = dynamic_cast<ThisTypeSubstitution*>(inSubstitutions)) + if (auto thisSubst = inSubstitutions.thisTypeSubstitution) { RefPtr<ThisTypeSubstitution> result = new ThisTypeSubstitution(); if (result->sourceType) result->sourceType = translateVal(result->sourceType); - return result; + rs.thisTypeSubstitution = result; } - return nullptr; + return rs; } static Decl* getModifiedDecl(Decl* decl) @@ -2673,7 +2674,7 @@ struct LoweringVisitor RefPtr<Decl> translateDeclRef( Decl* decl) { - return translateDeclRefImpl(DeclRef<Decl>(decl, nullptr)); + return translateDeclRefImpl(DeclRef<Decl>(decl, SubstitutionSet())); } LegalExpr translateSimpleLegalValToLegalExpr(IRValue* irVal) @@ -4943,11 +4944,16 @@ struct FindIRDeclUsedByASTVisitor // If this is a specialized declaration reference, then any // of the arguments also need to be walked. - for(auto subst = declRef.substitutions; subst; subst = subst->outer) + for(auto subst = declRef.substitutions.genericSubstitutions; subst; subst = subst->outer) { walkSubst(subst); } - + for (auto subst = declRef.substitutions.globalGenParamSubstitutions; subst; subst = subst->outer) + { + walkSubst(subst); + } + if (declRef.substitutions.thisTypeSubstitution) + walkSubst(declRef.substitutions.thisTypeSubstitution); // If any parent of the declaration was in the stdlib, or // is registered as a builtin, then skip it. for (auto pp = decl; pp; pp = pp->ParentDecl) diff --git a/source/slang/check.cpp b/source/slang/check.cpp index 77f9c8f44..e7bd6d711 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -442,7 +442,7 @@ namespace Slang { RefPtr<GenericSubstitution> subst = new GenericSubstitution(); subst->genericDecl = genericDeclRef.getDecl(); - subst->outer = genericDeclRef.substitutions; + subst->outer = genericDeclRef.substitutions.genericSubstitutions; for (auto argExpr : args) { @@ -451,7 +451,8 @@ namespace Slang DeclRef<Decl> innerDeclRef; innerDeclRef.decl = GetInner(genericDeclRef); - innerDeclRef.substitutions = subst; + innerDeclRef.substitutions = SubstitutionSet(subst, genericDeclRef.substitutions.thisTypeSubstitution, + genericDeclRef.substitutions.globalGenParamSubstitutions); return DeclRefType::Create( getSession(), @@ -1944,7 +1945,7 @@ namespace Slang AggTypeDecl* typeDecl, InheritanceDecl* inheritanceDecl) { - return checkConformance(DeclRef<AggTypeDecl>(typeDecl, nullptr), inheritanceDecl); + return checkConformance(DeclRef<AggTypeDecl>(typeDecl, SubstitutionSet()), inheritanceDecl); } void visitAggTypeDecl(AggTypeDecl* decl) @@ -2364,7 +2365,7 @@ namespace Slang // generic. // subst->genericDecl = prevGenericDecl; - prevFuncDeclRef.substitutions = subst; + prevFuncDeclRef.substitutions.genericSubstitutions = subst; // // One way to think about it is that if we have these // declarations (ignore the name differences...): @@ -4000,7 +4001,7 @@ namespace Slang // // Returns a new substitution representing the values that // we solved for along the way. - RefPtr<Substitutions> TrySolveConstraintSystem( + SubstitutionSet TrySolveConstraintSystem( ConstraintSystem* system, DeclRef<GenericDecl> genericDeclRef) { @@ -4024,9 +4025,9 @@ namespace Slang for( auto constraintDeclRef : getMembersOfType<GenericTypeConstraintDecl>(genericDeclRef) ) { if(!TryUnifyTypes(*system, GetSub(constraintDeclRef), GetSup(constraintDeclRef))) - return nullptr; + return SubstitutionSet(); } - + SubstitutionSet resultSubst = genericDeclRef.substitutions; // We will loop over the generic parameters, and for // each we will try to find a way to satisfy all // the constraints for that parameter @@ -4054,7 +4055,7 @@ namespace Slang if (!joinType) { // failure! - return nullptr; + return SubstitutionSet(); } type = joinType; } @@ -4065,7 +4066,7 @@ namespace Slang if (!type) { // failure! - return nullptr; + return SubstitutionSet(); } args.Add(type); } @@ -4092,7 +4093,7 @@ namespace Slang if(!val->EqualsVal(cVal.Ptr())) { // failure! - return nullptr; + return SubstitutionSet(); } } @@ -4102,7 +4103,7 @@ namespace Slang if (!val) { // failure! - return nullptr; + return SubstitutionSet(); } args.Add(val); } @@ -4130,8 +4131,9 @@ namespace Slang RefPtr<GenericSubstitution> solvedSubst = new GenericSubstitution(); solvedSubst->genericDecl = genericDeclRef.getDecl(); - solvedSubst->outer = genericDeclRef.substitutions; + solvedSubst->outer = genericDeclRef.substitutions.genericSubstitutions; solvedSubst->args = args; + resultSubst.genericSubstitutions = solvedSubst; for( auto constraintDecl : genericDeclRef.getDecl()->getMembersOfType<GenericTypeConstraintDecl>() ) { @@ -4156,7 +4158,7 @@ namespace Slang // // TODO: Ideally we should print an error message in // this case, to let the user know why things failed. - return nullptr; + return SubstitutionSet(); } // TODO: We may need to mark some constrains in our constraint @@ -4169,11 +4171,11 @@ namespace Slang { if (!c.satisfied) { - return nullptr; + return SubstitutionSet(); } } - return solvedSubst; + return resultSubst; } // @@ -4616,13 +4618,14 @@ namespace Slang assert(subst); subst->genericDecl = genericDeclRef.getDecl(); - subst->outer = genericDeclRef.substitutions; + subst->outer = genericDeclRef.substitutions.genericSubstitutions; for( auto constraintDecl : genericDeclRef.getDecl()->getMembersOfType<GenericTypeConstraintDecl>() ) { + auto subset = genericDeclRef.substitutions; + subset.genericSubstitutions = subst; DeclRef<GenericTypeConstraintDecl> constraintDeclRef( - constraintDecl, - subst); + constraintDecl, subset); auto sub = GetSub(constraintDeclRef); auto sup = GetSup(constraintDeclRef); @@ -4695,7 +4698,7 @@ namespace Slang } subst->genericDecl = baseGenericRef.getDecl(); - subst->outer = baseGenericRef.substitutions; + subst->outer = baseGenericRef.substitutions.genericSubstitutions; DeclRef<Decl> innerDeclRef(GetInner(baseGenericRef), subst); @@ -5085,17 +5088,17 @@ namespace Slang // default: fail return false; } - + bool TryUnifySubstitutions( ConstraintSystem& constraints, - RefPtr<Substitutions> fst, - RefPtr<Substitutions> snd) + RefPtr<GenericSubstitution> fst, + RefPtr<GenericSubstitution> snd) { // They must both be NULL or non-NULL - if (!hasGenericSubstitutions(fst) || !hasGenericSubstitutions(snd)) + if (!fst || !snd) return fst == snd; - auto fstGen = fst.As<GenericSubstitution>(); - auto sndGen = snd.As<GenericSubstitution>(); + auto fstGen = fst; + auto sndGen = snd; // They must be specializing the same generic if (fstGen->genericDecl != sndGen->genericDecl) return false; @@ -5162,7 +5165,7 @@ namespace Slang { if(auto genericValueParamRef = varRef.As<GenericValueParamDecl>()) { - return TryUnifyIntParam(constraints, genericValueParamRef.getDecl(), val); + return TryUnifyIntParam(constraints, RefPtr<GenericValueParamDecl>(genericValueParamRef.getDecl()), val); } else { @@ -5196,8 +5199,8 @@ namespace Slang // to each decalration reference. if (!TryUnifySubstitutions( constraints, - fstDeclRef.substitutions, - sndDeclRef.substitutions)) + fstDeclRef.substitutions.genericSubstitutions, + sndDeclRef.substitutions.genericSubstitutions)) { return false; } @@ -5667,7 +5670,7 @@ namespace Slang if( parentGenericDeclRef ) { SLANG_RELEASE_ASSERT(declRef.substitutions); - auto genSubst = declRef.substitutions.As<GenericSubstitution>(); + auto genSubst = declRef.substitutions.genericSubstitutions; SLANG_RELEASE_ASSERT(genSubst->genericDecl == parentGenericDeclRef.getDecl()); sb << "<"; @@ -6962,10 +6965,10 @@ namespace Slang // inside the context where it is declared (e.g., with generic parameters filled in // using their archetypes). // - RefPtr<Substitutions> createDefaultSubstitutions( + SubstitutionSet createDefaultSubstitutions( Session* session, Decl* decl, - Substitutions* parentSubst) + SubstitutionSet parentSubst) { auto dd = decl->ParentDecl; if( auto genericDecl = dynamic_cast<GenericDecl*>(dd) ) @@ -6975,9 +6978,11 @@ namespace Slang if(decl != genericDecl->inner) return parentSubst; + SubstitutionSet resultSubst = parentSubst; RefPtr<GenericSubstitution> subst = new GenericSubstitution(); subst->genericDecl = genericDecl; - subst->outer = parentSubst; + subst->outer = parentSubst.genericSubstitutions; + resultSubst.genericSubstitutions = subst; for( auto mm : genericDecl->Members ) { @@ -7003,16 +7008,16 @@ namespace Slang subst->args.Add(witness); } } - return subst; + return resultSubst; } return parentSubst; } - RefPtr<Substitutions> createDefaultSubstitutions( + SubstitutionSet createDefaultSubstitutions( Session* session, Decl* decl) { - RefPtr<Substitutions> subst; + SubstitutionSet subst; if( auto parentDecl = decl->ParentDecl ) { subst = createDefaultSubstitutions(session, parentDecl); diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index e60941e50..41ae819d9 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -3054,7 +3054,7 @@ struct EmitVisitor return; } - GenericSubstitution* subst = declRef.substitutions.As<GenericSubstitution>().Ptr(); + GenericSubstitution* subst = declRef.substitutions.genericSubstitutions; if (!subst) return; diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp index 1c06f5be9..626de3d7a 100644 --- a/source/slang/ir.cpp +++ b/source/slang/ir.cpp @@ -679,7 +679,7 @@ namespace Slang { auto witnessTableVal = getDeclRefVal(witnessTableDeclRef); DeclRef<Decl> removeSubstDeclRef = interfaceMethodDeclRef; - removeSubstDeclRef.substitutions = nullptr; + removeSubstDeclRef.substitutions = SubstitutionSet(); auto interfaceMethodVal = getDeclRefVal(removeSubstDeclRef); return emitLookupInterfaceMethodInst(type, witnessTableVal, interfaceMethodVal); } @@ -690,7 +690,7 @@ namespace Slang DeclRef<Decl> interfaceMethodDeclRef) { DeclRef<Decl> removeSubstDeclRef = interfaceMethodDeclRef; - removeSubstDeclRef.substitutions = nullptr; + removeSubstDeclRef.substitutions = SubstitutionSet(); auto interfaceMethodVal = getDeclRefVal(removeSubstDeclRef); return emitLookupInterfaceMethodInst(type, witnessTableVal, interfaceMethodVal); } @@ -1689,7 +1689,7 @@ namespace Slang if(genericParentDeclRef) { - auto subst = declRef.substitutions.As<GenericSubstitution>(); + auto subst = declRef.substitutions.genericSubstitutions; if( !subst || subst->genericDecl != genericParentDeclRef.getDecl() ) { // No actual substitutions in place here @@ -3103,6 +3103,8 @@ namespace Slang // The IR builder to use for creating nodes IRBuilder* builder; + SubstitutionSet subst; + // A callback to be used when a value that is not registerd in `clonedValues` // is needed during cloning. This gives the subtype a chance to intercept // the operation and clone (or not) as needed. @@ -3226,7 +3228,6 @@ namespace Slang // to the layout to use for it. Dictionary<String, VarLayout*> globalVarLayouts; - RefPtr<GlobalGenericParamSubstitution> subst; // Override the "maybe clone" logic so that we always clone virtual IRValue* maybeCloneValue(IRValue* originalVal) override; @@ -3292,21 +3293,21 @@ namespace Slang // if the declRef is one of the __generic_param decl being substituted by subst // return the substituted decl - if (subst) + if (subst.globalGenParamSubstitutions) { int diff = 0; newDeclRef = od->declRef.SubstituteImpl(subst, &diff); - if (newDeclRef.getDecl() == subst->paramDecl) - return builder->getTypeVal(subst->actualType.As<Type>()); + if (newDeclRef.getDecl() == subst.globalGenParamSubstitutions->paramDecl) + return builder->getTypeVal(subst.globalGenParamSubstitutions->actualType.As<Type>()); else if (auto genConstraint = newDeclRef.As<GenericTypeConstraintDecl>()) { // a decl-ref to GenericTypeConstraintDecl as a result of // referencing a generic parameter type should be replaced with // the actual witness table - if (genConstraint.getDecl()->ParentDecl == subst->paramDecl) + if (genConstraint.getDecl()->ParentDecl == subst.globalGenParamSubstitutions->paramDecl) { // find the witness table from subst - for (auto witness : subst->witnessTables) + for (auto witness : subst.globalGenParamSubstitutions->witnessTables) { if (witness.Key->EqualsVal(GetSup(genConstraint))) { @@ -3362,44 +3363,51 @@ namespace Slang } } - RefPtr<Substitutions> cloneSubstitutions( - IRSpecContext* context, - Substitutions* subst) + RefPtr<GenericSubstitution> cloneGenericSubst(IRSpecContext* context, GenericSubstitution* genSubst) { - if (!subst) + if (!genSubst) return nullptr; - if (auto genSubst = dynamic_cast<GenericSubstitution*>(subst)) - { - RefPtr<GenericSubstitution> newSubst = new GenericSubstitution(); - newSubst->outer = cloneSubstitutions(context, subst->outer); - newSubst->genericDecl = genSubst->genericDecl; - for (auto arg : genSubst->args) - { - auto newArg = cloneSubstitutionArg(context, arg); - newSubst->args.Add(newArg); - } - return newSubst; + RefPtr<GenericSubstitution> newSubst = new GenericSubstitution(); + newSubst->outer = cloneGenericSubst(context, genSubst->outer); + newSubst->genericDecl = genSubst->genericDecl; + + for (auto arg : genSubst->args) + { + auto newArg = cloneSubstitutionArg(context, arg); + newSubst->args.Add(newArg); } - else if (auto thisSubst = dynamic_cast<ThisTypeSubstitution*>(subst)) + return newSubst; + } + + RefPtr<GlobalGenericParamSubstitution> cloneGlobalGenericSubst(IRSpecContext* context, GlobalGenericParamSubstitution* subst) + { + if (!subst) + return nullptr; + auto newSubst = new GlobalGenericParamSubstitution(); + newSubst->actualType = subst->actualType; + newSubst->paramDecl = subst->paramDecl; + newSubst->witnessTables = subst->witnessTables; + newSubst->outer = cloneGlobalGenericSubst(context, subst->outer); + return newSubst; + } + + SubstitutionSet cloneSubstitutions( + IRSpecContext* context, + SubstitutionSet subst) + { + SubstitutionSet rs; + if (!subst) + return rs; + rs.genericSubstitutions = cloneGenericSubst(context, subst.genericSubstitutions); + rs.globalGenParamSubstitutions = cloneGlobalGenericSubst(context, subst.globalGenParamSubstitutions); + if (auto thisSubst = subst.thisTypeSubstitution) { RefPtr<ThisTypeSubstitution> newSubst = new ThisTypeSubstitution(); newSubst->sourceType = thisSubst->sourceType; - newSubst->outer = cloneSubstitutions(context, subst->outer); - return newSubst; + rs.thisTypeSubstitution = newSubst; } - else if (auto genTypeSubst = dynamic_cast<GlobalGenericParamSubstitution*>(subst)) - { - RefPtr<GlobalGenericParamSubstitution> newSubst = new GlobalGenericParamSubstitution(); - newSubst->actualType = genTypeSubst->actualType; - newSubst->paramDecl = genTypeSubst->paramDecl; - newSubst->witnessTables = genTypeSubst->witnessTables; - newSubst->outer = cloneSubstitutions(context, subst->outer); - return newSubst; - } - else - SLANG_UNREACHABLE("unimplemented cloneSubstitution"); - UNREACHABLE_RETURN(nullptr); + return rs; } DeclRef<Decl> IRSpecContext::maybeCloneDeclRef(DeclRef<Decl> const& declRef) @@ -3416,7 +3424,6 @@ namespace Slang newDeclRef.substitutions = cloneSubstitutions(this, declRef.substitutions); return newDeclRef; - } @@ -4045,7 +4052,7 @@ namespace Slang RefPtr<ProgramLayout> specializeProgramLayout( TargetRequest * targetReq, ProgramLayout* programLayout, - Substitutions * typeSubst); + SubstitutionSet typeSubst); RefPtr<GlobalGenericParamSubstitution> createGlobalGenericParamSubstitution( EntryPointRequest * entryPointRequest, @@ -4054,7 +4061,7 @@ namespace Slang IRModule* originalIRModule) { RefPtr<GlobalGenericParamSubstitution> globalParamSubst; - Substitutions * curTailSubst = nullptr; + GlobalGenericParamSubstitution * curTailSubst = nullptr; for (auto param : programLayout->globalGenericParams) { auto paramSubst = new GlobalGenericParamSubstitution(); @@ -4154,10 +4161,10 @@ namespace Slang // into user-provided type arguments auto globalParamSubst = createGlobalGenericParamSubstitution(entryPointRequest, programLayout, context, originalIRModule); - context->subst = globalParamSubst; + context->subst.globalGenParamSubstitutions = globalParamSubst; // now specailize the program layout using the substitution - RefPtr<ProgramLayout> newProgramLayout = specializeProgramLayout(targetReq, programLayout, globalParamSubst); + RefPtr<ProgramLayout> newProgramLayout = specializeProgramLayout(targetReq, programLayout, context->subst); state->newProgramLayout = newProgramLayout; @@ -4271,10 +4278,7 @@ namespace Slang struct IRGenericSpecContext : IRSpecContextBase { IRSharedGenericSpecContext* getShared() { return (IRSharedGenericSpecContext*) shared; } - - // The substutions to apply - RefPtr<Substitutions> subst; - + // Override the "maybe clone" logic so that we always clone virtual IRValue* maybeCloneValue(IRValue* originalVal) override; @@ -4322,7 +4326,7 @@ namespace Slang IRGenericSpecContext* context, DeclRef<Decl> declRef) { - auto subst = context->subst.As<GenericSubstitution>(); + auto subst = context->subst.genericSubstitutions; SLANG_ASSERT(subst); auto genericDecl = subst->genericDecl; @@ -4373,7 +4377,7 @@ namespace Slang { auto declRefVal = (IRDeclRef*) originalVal; auto declRef = declRefVal->declRef; - auto genSubst = subst.As<GenericSubstitution>(); + auto genSubst = subst.genericSubstitutions; SLANG_ASSERT(genSubst); // We may have a direct reference to one of the parameters // of the generic we are specializing, and in that case @@ -4412,18 +4416,9 @@ namespace Slang // generic substitution in the list, or NULL if there // are no generic substitutions. RefPtr<GenericSubstitution> getInnermostGenericSubst( - Substitutions* inSubst) + SubstitutionSet inSubst) { - auto subst = inSubst; - while( subst ) - { - GenericSubstitution* genericSubst = dynamic_cast<GenericSubstitution*>(subst); - if(genericSubst) - return genericSubst; - - subst = subst->outer; - } - return nullptr; + return inSubst.genericSubstitutions; } RefPtr<GenericDecl> getInnermostGenericDecl( @@ -4442,20 +4437,18 @@ namespace Slang } // This function takes a list of substitutions that we'd - // like to apply, but which (1) might apply to a different + // like to apply, but which might apply to a different // declaration in cases where we have got target-specific - // overloads in the mix, and (2) might include some `ThisType` - // substitutions, which we don't care about in this context, - // and produces a new set of substitutiosn without these - // two issues. - RefPtr<Substitutions> cloneSubstitutionsForSpecialization( + // overloads in the mix, and produces a new set of + // substitutiosn without this issue. + RefPtr<GenericSubstitution> cloneSubstitutionsForSpecialization( IRSharedGenericSpecContext* sharedContext, - Substitutions* oldSubst, + RefPtr<GenericSubstitution> oldSubst, Decl* newDecl) { // We will "peel back" layers of substitutions until // we find our first generic subsitution. - auto oldGenericSubst = getInnermostGenericSubst(oldSubst); + auto oldGenericSubst = oldSubst; if(!oldGenericSubst) return nullptr; @@ -4506,15 +4499,16 @@ namespace Slang return (IRWitnessTable*)gv; } - RefPtr<Substitutions> newSubst = cloneSubstitutionsForSpecialization( + RefPtr<GenericSubstitution> newSubst = cloneSubstitutionsForSpecialization( sharedContext, - specDeclRef.substitutions, + specDeclRef.substitutions.genericSubstitutions, originalTable->genericDecl); IRGenericSpecContext context; context.shared = sharedContext; context.builder = &sharedContext->builderStorage; - context.subst = newSubst; + context.subst = specDeclRef.substitutions; + context.subst.genericSubstitutions = newSubst; // TODO: other initialization is needed here... @@ -4577,15 +4571,16 @@ namespace Slang // using a different overload of a target-specific function, // so we need to create a dummy substitution here, to make // sure it used the correct generic. - RefPtr<Substitutions> newSubst = cloneSubstitutionsForSpecialization( + RefPtr<GenericSubstitution> newSubst = cloneSubstitutionsForSpecialization( sharedContext, - specDeclRef.substitutions, + specDeclRef.substitutions.genericSubstitutions, genericFunc->genericDecl); IRGenericSpecContext context; context.shared = sharedContext; context.builder = &sharedContext->builderStorage; - context.subst = newSubst; + context.subst = specDeclRef.substitutions; + context.subst.genericSubstitutions = newSubst; // TODO: other initialization is needed here... diff --git a/source/slang/legalize-types.cpp b/source/slang/legalize-types.cpp index 1264201a2..211685aa2 100644 --- a/source/slang/legalize-types.cpp +++ b/source/slang/legalize-types.cpp @@ -450,8 +450,7 @@ static RefPtr<Type> createBuiltinGenericType( // TODO: we should have library code to make // manipulations like this way easier. - RefPtr<GenericSubstitution> oldGenericSubst = getGenericSubstitution( - typeDeclRef.substitutions); + RefPtr<GenericSubstitution> oldGenericSubst = typeDeclRef.substitutions.genericSubstitutions; SLANG_ASSERT(oldGenericSubst); RefPtr<GenericSubstitution> newGenericSubst = new GenericSubstitution(); diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp index e08498fc0..4af36f718 100644 --- a/source/slang/lower-to-ir.cpp +++ b/source/slang/lower-to-ir.cpp @@ -497,7 +497,7 @@ LoweredValInfo emitWitnessTableRef( { // if we are referring to an actual type, don't include substitution // and generate specialize instruction - srcDeclRef.substitutions = nullptr; + srcDeclRef.substitutions = SubstitutionSet(); } witnessTableVal = context->irBuilder->emitFindWitnessTable(srcDeclRef, inheritanceDeclRef.getDecl()->base.type); return maybeEmitSpecializeInst(context, LoweredValInfo::simple(witnessTableVal), declRefType->declRef); @@ -1058,15 +1058,12 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower void addGenericArgs(List<IRValue*>* ioArgs, DeclRefBase declRef) { - auto subs = declRef.substitutions; + auto subs = declRef.substitutions.genericSubstitutions; while(subs) { - if (auto genSubst = subs.As<GenericSubstitution>()) + for (auto aa : subs->args) { - for (auto aa : genSubst->args) - { - (*ioArgs).Add(getSimpleVal(context, lowerVal(context, aa))); - } + (*ioArgs).Add(getSimpleVal(context, lowerVal(context, aa))); } subs = subs->outer; } @@ -3837,41 +3834,52 @@ RefPtr<Val> lowerSubstitutionArg( // Given a set of substitutions, make sure that we have // lowered the arguments being used into a form that // is suitable for use in the IR. -RefPtr<Substitutions> lowerSubstitutions( +RefPtr<GenericSubstitution> lowerGenericSubstitutions( IRGenContext* context, - Substitutions* subst) + GenericSubstitution* genSubst) { - if(!subst) + if(!genSubst) return nullptr; - RefPtr<Substitutions> result; - if (auto genSubst = dynamic_cast<GenericSubstitution*>(subst)) - { - RefPtr<GenericSubstitution> newSubst = new GenericSubstitution(); - newSubst->genericDecl = genSubst->genericDecl; - - for (auto arg : genSubst->args) - { - auto newArg = lowerSubstitutionArg(context, arg); - newSubst->args.Add(newArg); - } + RefPtr<GenericSubstitution> result; + RefPtr<GenericSubstitution> newSubst = new GenericSubstitution(); + newSubst->genericDecl = genSubst->genericDecl; - result = newSubst; - } - else if (auto thisSubst = dynamic_cast<ThisTypeSubstitution*>(subst)) + for (auto arg : genSubst->args) { - RefPtr<ThisTypeSubstitution> newSubst = new ThisTypeSubstitution(); - newSubst->sourceType = lowerSubstitutionArg(context, thisSubst->sourceType); - result = newSubst; + auto newArg = lowerSubstitutionArg(context, arg); + newSubst->args.Add(newArg); } - if (subst->outer) + + result = newSubst; + if (genSubst->outer) { - result->outer = lowerSubstitutions( + result->outer = lowerGenericSubstitutions( context, - subst->outer); + genSubst->outer); } return result; } +RefPtr<ThisTypeSubstitution> lowerThisTypeSubstitution( + IRGenContext* context, + ThisTypeSubstitution* thisSubst) +{ + if (!thisSubst) + return nullptr; + RefPtr<ThisTypeSubstitution> newSubst = new ThisTypeSubstitution(); + newSubst->sourceType = lowerSubstitutionArg(context, thisSubst->sourceType); + return newSubst; +} + +SubstitutionSet lowerSubstitutions(IRGenContext* context, SubstitutionSet subst) +{ + SubstitutionSet rs; + rs.genericSubstitutions = lowerGenericSubstitutions(context, subst.genericSubstitutions); + rs.thisTypeSubstitution = lowerThisTypeSubstitution(context, subst.thisTypeSubstitution); + rs.globalGenParamSubstitutions = subst.globalGenParamSubstitutions; + return rs; +} + LoweredValInfo emitDeclRef( IRGenContext* context, DeclRef<Decl> declRef) @@ -3889,7 +3897,7 @@ LoweredValInfo maybeEmitSpecializeInst(IRGenContext* context, { // If this declaration reference doesn't involve any specializations, // then we are done at this point. - if (!hasGenericSubstitutions(declRef.substitutions)) + if (!declRef.substitutions.genericSubstitutions) return loweredDecl; // There's no reason to specialize something that maps to a NULL pointer. @@ -3902,7 +3910,7 @@ LoweredValInfo maybeEmitSpecializeInst(IRGenContext* context, // need to walk through those and replace things in // cases where the `Val`s used for substitution should // lower to something other than their original form. - RefPtr<Substitutions> newSubst = lowerSubstitutions(context, declRef.substitutions); + auto newSubst = lowerSubstitutions(context, declRef.substitutions); declRef.substitutions = newSubst; diff --git a/source/slang/mangle.cpp b/source/slang/mangle.cpp index 5b8e519b9..070c2b172 100644 --- a/source/slang/mangle.cpp +++ b/source/slang/mangle.cpp @@ -186,7 +186,7 @@ namespace Slang // TODO: this needs to be centralized RefPtr<GenericSubstitution> getOutermostGenericSubst( - RefPtr<Substitutions> inSubst) + RefPtr<GenericSubstitution> inSubst) { for (auto subst = inSubst; subst; subst = subst->outer) { @@ -233,7 +233,7 @@ namespace Slang // There are two cases here: either we have specializations // in place for the parent generic declaration, or we don't. - auto subst = getOutermostGenericSubst(declRef.substitutions); + auto subst = getOutermostGenericSubst(declRef.substitutions.genericSubstitutions); if( subst && subst->genericDecl == parentGenericDeclRef.getDecl() ) { // This is the case where we *do* have substitutions. @@ -378,20 +378,15 @@ namespace Slang DeclRef<Decl>(declRef.decl, declRef.substitutions)); } - String mangleSpecializedFuncName(String baseName, RefPtr<Substitutions> subst) + String mangleSpecializedFuncName(String baseName, SubstitutionSet subst) { ManglingContext context; emitRaw(&context, baseName.Buffer()); emitRaw(&context, "_G"); - while (subst) + if (auto genSubst = subst.genericSubstitutions) { - if (auto genSubst = subst.As<GenericSubstitution>()) - { - for (auto a : genSubst->args) - emitVal(&context, a); - break; - } - subst = subst->outer; + for (auto a : genSubst->args) + emitVal(&context, a); } return context.sb.ProduceString(); } diff --git a/source/slang/mangle.h b/source/slang/mangle.h index 406796951..45b1d4bd1 100644 --- a/source/slang/mangle.h +++ b/source/slang/mangle.h @@ -12,7 +12,7 @@ namespace Slang String getMangledName(DeclRef<Decl> const & declRef); String getMangledName(DeclRefBase const & declRef); - String mangleSpecializedFuncName(String baseName, RefPtr<Substitutions> subst); + String mangleSpecializedFuncName(String baseName, SubstitutionSet subst); String getMangledNameForConformanceWitness( Type* sub, Type* sup); diff --git a/source/slang/parameter-binding.cpp b/source/slang/parameter-binding.cpp index fcd3fa525..e5ea1d531 100644 --- a/source/slang/parameter-binding.cpp +++ b/source/slang/parameter-binding.cpp @@ -1529,7 +1529,7 @@ static RefPtr<TypeLayout> processEntryPointParameter( static void collectEntryPointParameters( ParameterBindingContext* context, EntryPointRequest* entryPoint, - Substitutions* typeSubst) + SubstitutionSet typeSubst) { FuncDecl* entryPointFuncDecl = entryPoint->decl; if (!entryPointFuncDecl) @@ -1722,7 +1722,7 @@ static void collectParameters( for( auto& entryPoint : translationUnit->entryPoints ) { context->stage = entryPoint->profile.GetStage(); - collectEntryPointParameters(context, entryPoint.Ptr(), nullptr); + collectEntryPointParameters(context, entryPoint.Ptr(), SubstitutionSet()); } context->entryPointLayout = nullptr; } @@ -2059,7 +2059,7 @@ StructTypeLayout* getGlobalStructLayout( RefPtr<ProgramLayout> specializeProgramLayout( TargetRequest * targetReq, ProgramLayout* programLayout, - Substitutions * typeSubst) + SubstitutionSet typeSubst) { RefPtr<ProgramLayout> newProgramLayout; newProgramLayout = new ProgramLayout(); diff --git a/source/slang/syntax-base-defs.h b/source/slang/syntax-base-defs.h index de8b294d8..2eb130863 100644 --- a/source/slang/syntax-base-defs.h +++ b/source/slang/syntax-base-defs.h @@ -40,14 +40,14 @@ ABSTRACT_SYNTAX_CLASS(Val, NodeBase) RAW( // construct a new value by applying a set of parameter // substitutions to this one - RefPtr<Val> Substitute(Substitutions* subst); + RefPtr<Val> Substitute(SubstitutionSet subst); // Lower-level interface for substition. Like the basic // `Substitute` above, but also takes a by-reference // integer parameter that should be incremented when // returning a modified value (this can help the caller // decide whether they need to do anything). - virtual RefPtr<Val> SubstituteImpl(Substitutions* subst, int* ioDiff); + virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff); virtual bool EqualsVal(Val* val) = 0; virtual String ToString() = 0; @@ -113,7 +113,7 @@ public: bool IsClass(); Type* GetCanonicalType(); - virtual RefPtr<Val> SubstituteImpl(Substitutions* subst, int* ioDiff) override; + virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; virtual bool EqualsVal(Val* val) override; protected: @@ -132,12 +132,9 @@ END_SYNTAX_CLASS() // type-level variables to concrete argument values ABSTRACT_SYNTAX_CLASS(Substitutions, RefObject) - // Any further substitutions, relating to outer generic declarations - SYNTAX_FIELD(RefPtr<Substitutions>, outer) - RAW( // Apply a set of substitutions to the bindings in this substitution - virtual RefPtr<Substitutions> SubstituteImpl(Substitutions* subst, int* ioDiff) = 0; + virtual RefPtr<Substitutions> SubstituteImpl(SubstitutionSet subst, int* ioDiff) = 0; // Check if these are equivalent substitutiosn to another set virtual bool Equals(Substitutions* subst) = 0; @@ -153,10 +150,13 @@ SYNTAX_CLASS(GenericSubstitution, Substitutions) // The actual values of the arguments SYNTAX_FIELD(List<RefPtr<Val>>, args) - + + // Any further substitutions, relating to outer generic declarations + SYNTAX_FIELD(RefPtr<GenericSubstitution>, outer) + RAW( // Apply a set of substitutions to the bindings in this substitution - virtual RefPtr<Substitutions> SubstituteImpl(Substitutions* subst, int* ioDiff) override; + virtual RefPtr<Substitutions> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; // Check if these are equivalent substitutiosn to another set virtual bool Equals(Substitutions* subst) override; @@ -182,7 +182,7 @@ SYNTAX_CLASS(ThisTypeSubstitution, Substitutions) SYNTAX_FIELD(RefPtr<Val>, sourceType) RAW( // Apply a set of substitutions to the bindings in this substitution - virtual RefPtr<Substitutions> SubstituteImpl(Substitutions* subst, int* ioDiff) override; + virtual RefPtr<Substitutions> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; // Check if these are equivalent substitutiosn to another set virtual bool Equals(Substitutions* subst) override; @@ -192,8 +192,9 @@ SYNTAX_CLASS(ThisTypeSubstitution, Substitutions) } virtual int GetHashCode() const override { - SLANG_ASSERT(sourceType); - return sourceType->GetHashCode(); + if (sourceType) + return sourceType->GetHashCode(); + return 0; } ) END_SYNTAX_CLASS() @@ -203,10 +204,11 @@ SYNTAX_CLASS(GlobalGenericParamSubstitution, Substitutions) DECL_FIELD(GlobalGenericParamDecl*, paramDecl) // the actual type to substitute in SYNTAX_FIELD(RefPtr<Val>, actualType) - + // Any further global type parameter substitutions + SYNTAX_FIELD(RefPtr<GlobalGenericParamSubstitution>, outer) RAW( // Apply a set of substitutions to the bindings in this substitution - virtual RefPtr<Substitutions> SubstituteImpl(Substitutions* subst, int* ioDiff) override; + virtual RefPtr<Substitutions> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; // Check if these are equivalent substitutiosn to another set virtual bool Equals(Substitutions* subst) override; diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index 4f043e0a1..c63dfc781 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -165,7 +165,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return dynamic_cast<NamedExpressionType*>(this); } - RefPtr<Val> Type::SubstituteImpl(Substitutions* subst, int* ioDiff) + RefPtr<Val> Type::SubstituteImpl(SubstitutionSet subst, int* ioDiff) { int diff = 0; auto canSubst = GetCanonicalType()->SubstituteImpl(subst, &diff); @@ -358,7 +358,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return (ArrayLength == arrType->ArrayLength && baseType->Equals(arrType->baseType.Ptr())); } - RefPtr<Val> ArrayExpressionType::SubstituteImpl(Substitutions* subst, int* ioDiff) + RefPtr<Val> ArrayExpressionType::SubstituteImpl(SubstitutionSet subst, int* ioDiff) { int diff = 0; auto elementType = baseType->SubstituteImpl(subst, &diff).As<Type>(); @@ -454,7 +454,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return this; } - RefPtr<Val> DeclRefType::SubstituteImpl(Substitutions* subst, int* ioDiff) + RefPtr<Val> DeclRefType::SubstituteImpl(SubstitutionSet subst, int* ioDiff) { if (!subst) return this; @@ -463,39 +463,36 @@ void Type::accept(IValVisitor* visitor, void* extra) if (auto genericTypeParamDecl = dynamic_cast<GenericTypeParamDecl*>(declRef.getDecl())) { // search for a substitution that might apply to us - for (auto s = subst; s; s = s->outer.Ptr()) + for (auto s = subst.genericSubstitutions; s; s = s->outer.Ptr()) { - if (auto genericSubst = dynamic_cast<GenericSubstitution*>(s)) + auto genericSubst = s; + // the generic decl associated with the substitution list must be + // the generic decl that declared this parameter + auto genericDecl = genericSubst->genericDecl; + if (genericDecl != genericTypeParamDecl->ParentDecl) + continue; + + int index = 0; + for (auto m : genericDecl->Members) { - // the generic decl associated with the substitution list must be - // the generic decl that declared this parameter - auto genericDecl = genericSubst->genericDecl; - if (genericDecl != genericTypeParamDecl->ParentDecl) - continue; - - int index = 0; - for (auto m : genericDecl->Members) + if (m.Ptr() == genericTypeParamDecl) + { + // We've found it, so return the corresponding specialization argument + (*ioDiff)++; + return genericSubst->args[index]; + } + else if (auto typeParam = m.As<GenericTypeParamDecl>()) + { + index++; + } + else if (auto valParam = m.As<GenericValueParamDecl>()) + { + index++; + } + else { - if (m.Ptr() == genericTypeParamDecl) - { - // We've found it, so return the corresponding specialization argument - (*ioDiff)++; - return genericSubst->args[index]; - } - else if (auto typeParam = m.As<GenericTypeParamDecl>()) - { - index++; - } - else if (auto valParam = m.As<GenericValueParamDecl>()) - { - index++; - } - else - { - } } } - } } // the second case we care about is when this decl type refers to an associatedtype decl @@ -510,7 +507,7 @@ void Type::accept(IValVisitor* visitor, void* extra) auto newSubst = substituteSubstitutions(declRef.substitutions, subst, ioDiff); if (restore) thisSubst->sourceType = oldSubstSrc; - if (auto thisTypeSubst = newSubst.As<ThisTypeSubstitution>()) + if (auto thisTypeSubst = newSubst.thisTypeSubstitution) { if (thisTypeSubst->sourceType) { @@ -540,15 +537,12 @@ 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()) + for (auto genericSubst = subst.globalGenParamSubstitutions; genericSubst; genericSubst = genericSubst->outer.Ptr()) { - if (auto genericSubst = dynamic_cast<GlobalGenericParamSubstitution*>(s)) + if (genericSubst->paramDecl == globalGenParam) { - if (genericSubst->paramDecl == globalGenParam) - { - (*ioDiff)++; - return genericSubst->actualType; - } + (*ioDiff)++; + return genericSubst->actualType; } } } @@ -597,17 +591,13 @@ void Type::accept(IValVisitor* visitor, void* extra) auto subst = declRef.substitutions; // try find a substitution targeting this generic decl bool substFound = false; - while (subst) + for (auto genSubst = subst.genericSubstitutions; genSubst; genSubst = genSubst->outer) { - if (auto genSubst = dynamic_cast<GenericSubstitution*>(subst.Ptr())) + if (genSubst->genericDecl == genericParent.decl) { - if (genSubst->genericDecl == genericParent.decl) - { - substFound = true; - break; - } + substFound = true; + break; } - subst = subst->outer; } // we did not find an existing substituion, create a default one if (!substFound) @@ -628,7 +618,7 @@ void Type::accept(IValVisitor* visitor, void* extra) } else if (auto magicMod = declRef.getDecl()->FindModifier<MagicTypeModifier>()) { - GenericSubstitution* subst = declRef.substitutions.As<GenericSubstitution>().Ptr(); + GenericSubstitution* subst = declRef.substitutions.genericSubstitutions.Ptr(); if (magicMod->name == "SamplerState") { @@ -952,7 +942,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return false; } - RefPtr<Val> FuncType::SubstituteImpl(Substitutions* subst, int* ioDiff) + RefPtr<Val> FuncType::SubstituteImpl(SubstitutionSet subst, int* ioDiff) { int diff = 0; @@ -1104,24 +1094,24 @@ void Type::accept(IValVisitor* visitor, void* extra) Type* MatrixExpressionType::getElementType() { - return this->declRef.substitutions.As<GenericSubstitution>()->args[0].As<Type>().Ptr(); + return this->declRef.substitutions.genericSubstitutions->args[0].As<Type>().Ptr(); } IntVal* MatrixExpressionType::getRowCount() { - return this->declRef.substitutions.As<GenericSubstitution>()->args[1].As<IntVal>().Ptr(); + return this->declRef.substitutions.genericSubstitutions->args[1].As<IntVal>().Ptr(); } IntVal* MatrixExpressionType::getColumnCount() { - return this->declRef.substitutions.As<GenericSubstitution>()->args[2].As<IntVal>().Ptr(); + return this->declRef.substitutions.genericSubstitutions->args[2].As<IntVal>().Ptr(); } // PtrTypeBase Type* PtrTypeBase::getValueType() { - return this->declRef.substitutions.As<GenericSubstitution>()->args[0].As<Type>().Ptr(); + return this->declRef.substitutions.genericSubstitutions->args[0].As<Type>().Ptr(); } // GenericParamIntVal @@ -1145,39 +1135,36 @@ void Type::accept(IValVisitor* visitor, void* extra) return declRef.GetHashCode() ^ 0xFFFF; } - RefPtr<Val> GenericParamIntVal::SubstituteImpl(Substitutions* subst, int* ioDiff) + RefPtr<Val> GenericParamIntVal::SubstituteImpl(SubstitutionSet subst, int* ioDiff) { // search for a substitution that might apply to us - for (auto s = subst; s; s = s->outer.Ptr()) + for (auto genSubst = subst.genericSubstitutions; genSubst; genSubst = genSubst->outer.Ptr()) { - if (auto genSubst = dynamic_cast<GenericSubstitution*>(s)) + // the generic decl associated with the substitution list must be + // the generic decl that declared this parameter + auto genericDecl = genSubst->genericDecl; + if (genericDecl != declRef.getDecl()->ParentDecl) + continue; + + int index = 0; + for (auto m : genericDecl->Members) { - // the generic decl associated with the substitution list must be - // the generic decl that declared this parameter - auto genericDecl = genSubst->genericDecl; - if (genericDecl != declRef.getDecl()->ParentDecl) - continue; - - int index = 0; - for (auto m : genericDecl->Members) + if (m.Ptr() == declRef.getDecl()) + { + // We've found it, so return the corresponding specialization argument + (*ioDiff)++; + return genSubst->args[index]; + } + else if (auto typeParam = m.As<GenericTypeParamDecl>()) + { + index++; + } + else if (auto valParam = m.As<GenericValueParamDecl>()) + { + index++; + } + else { - if (m.Ptr() == declRef.getDecl()) - { - // We've found it, so return the corresponding specialization argument - (*ioDiff)++; - return genSubst->args[index]; - } - else if (auto typeParam = m.As<GenericTypeParamDecl>()) - { - index++; - } - else if (auto valParam = m.As<GenericValueParamDecl>()) - { - index++; - } - else - { - } } } } @@ -1188,7 +1175,7 @@ void Type::accept(IValVisitor* visitor, void* extra) // Substitutions - RefPtr<Substitutions> GenericSubstitution::SubstituteImpl(Substitutions* subst, int* ioDiff) + RefPtr<Substitutions> GenericSubstitution::SubstituteImpl(SubstitutionSet subst, int* ioDiff) { if (!this) return nullptr; @@ -1230,36 +1217,32 @@ void Type::accept(IValVisitor* visitor, void* extra) } if (!outer) - return !subst->outer || subst->outer.As<ThisTypeSubstitution>(); + return !genericSubst->outer; - if (!outer->Equals(subst->outer.Ptr())) + if (!outer->Equals(genericSubst->outer.Ptr())) return false; return true; } - RefPtr<Substitutions> ThisTypeSubstitution::SubstituteImpl(Substitutions* subst, int* ioDiff) + RefPtr<Substitutions> ThisTypeSubstitution::SubstituteImpl(SubstitutionSet subst, int* ioDiff) { if (!this) return nullptr; int diff = 0; - RefPtr<Substitutions> outerSubst = outer ? outer->SubstituteImpl(subst, &diff) : nullptr; RefPtr<Val> 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 (subst.thisTypeSubstitution) { - if (auto pthisSubst = dynamic_cast<ThisTypeSubstitution*>(subst)) + if (subst.thisTypeSubstitution->sourceType != sourceType) { - diff++; - newSourceType = pthisSubst->sourceType; - break; + newSourceType = subst.thisTypeSubstitution->sourceType; + diff = 1; } - psubst = psubst->outer; } } if (!diff) return this; @@ -1267,7 +1250,6 @@ void Type::accept(IValVisitor* visitor, void* extra) (*ioDiff)++; auto substSubst = new ThisTypeSubstitution(); substSubst->sourceType = newSourceType; - substSubst->outer = outerSubst; return substSubst; } @@ -1284,34 +1266,31 @@ void Type::accept(IValVisitor* visitor, void* extra) return false; } - RefPtr<Substitutions> GlobalGenericParamSubstitution::SubstituteImpl(Substitutions* subst, int* ioDiff) + RefPtr<Substitutions> GlobalGenericParamSubstitution::SubstituteImpl(SubstitutionSet subst, int* ioDiff) { // if we find a GlobalGenericParamSubstitution in subst that references the same __generic_param decl // return a copy of that GlobalGenericParamSubstitution int diff = 0; RefPtr<Substitutions> outerSubst = outer ? outer->SubstituteImpl(subst, &diff) : nullptr; - while (subst) + + for (auto gSubst = subst.globalGenParamSubstitutions; gSubst; gSubst = gSubst->outer) { - if (auto gSubst = dynamic_cast<GlobalGenericParamSubstitution*>(subst)) + if (gSubst->paramDecl == paramDecl) { - if (gSubst->paramDecl == paramDecl) + // substitute only if we are really different + if (!gSubst->actualType->EqualsVal(actualType)) { - // substitute only if we are really different - if (!gSubst->actualType->EqualsVal(actualType)) - { - RefPtr<GlobalGenericParamSubstitution> rs = new GlobalGenericParamSubstitution(*gSubst); - rs->outer = outerSubst; - return rs; - } + RefPtr<GlobalGenericParamSubstitution> rs = new GlobalGenericParamSubstitution(*gSubst); + rs->outer = outerSubst.As<GlobalGenericParamSubstitution>(); + return rs; } } - subst = subst->outer; } if (diff) { *ioDiff++; RefPtr<GlobalGenericParamSubstitution> rs = new GlobalGenericParamSubstitution(*this); - rs->outer = outerSubst; + rs->outer = outerSubst.As<GlobalGenericParamSubstitution>(); return rs; } return this; @@ -1353,7 +1332,7 @@ void Type::accept(IValVisitor* visitor, void* extra) // Otherwise we need to recurse on the type structure // and apply substitutions where it makes sense - return type->Substitute(substitutions.Ptr()).As<Type>(); + return type->Substitute(substitutions).As<Type>(); } DeclRefBase DeclRefBase::Substitute(DeclRefBase declRef) const @@ -1362,7 +1341,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return declRef; int diff = 0; - return declRef.SubstituteImpl(substitutions.Ptr(), &diff); + return declRef.SubstituteImpl(substitutions, &diff); } RefPtr<Expr> DeclRefBase::Substitute(RefPtr<Expr> expr) const @@ -1376,45 +1355,38 @@ void Type::accept(IValVisitor* visitor, void* extra) UNREACHABLE_RETURN(expr); } - bool hasGlobalGenericSubst(Substitutions * destSubst, GlobalGenericParamSubstitution * genSubst) + bool hasGlobalGenericSubst(SubstitutionSet destSubst, GlobalGenericParamSubstitution * genSubst) { - while (destSubst) + for (auto subst = destSubst.globalGenParamSubstitutions; subst; subst = subst->outer) { - if (auto globalParamSubst = dynamic_cast<GlobalGenericParamSubstitution*>(destSubst)) - { - if (globalParamSubst->paramDecl == genSubst->paramDecl) - return true; - } - destSubst = destSubst->outer; + if (subst->paramDecl == genSubst->paramDecl) + return true; } return false; } - void insertGlobalGenericSubstitutions(RefPtr<Substitutions> & destSubst, Substitutions * srcSubst, int * ioDiff) + void insertGlobalGenericSubstitutions(SubstitutionSet & destSubst, SubstitutionSet srcSubst, int * ioDiff) { int diff = 0; - while (srcSubst) + + if (auto globalGenSubst = srcSubst.globalGenParamSubstitutions) { - if (auto globalGenSubst = dynamic_cast<GlobalGenericParamSubstitution*>(srcSubst)) + if (!hasGlobalGenericSubst(destSubst, globalGenSubst)) { - if (!hasGlobalGenericSubst(destSubst, globalGenSubst)) - { - RefPtr<GlobalGenericParamSubstitution> cpyGlobalGenSubst = new GlobalGenericParamSubstitution(*globalGenSubst); - cpyGlobalGenSubst->outer = nullptr; - insertSubstAtBottom(destSubst, cpyGlobalGenSubst); - diff = 1; - } + RefPtr<GlobalGenericParamSubstitution> cpyGlobalGenSubst = new GlobalGenericParamSubstitution(*globalGenSubst); + cpyGlobalGenSubst->outer = destSubst.globalGenParamSubstitutions; + destSubst.globalGenParamSubstitutions = cpyGlobalGenSubst; + diff = 1; } - srcSubst = srcSubst->outer; } *ioDiff += diff; } void buildMemberDictionary(ContainerDecl* decl); - DeclRefBase DeclRefBase::SubstituteImpl(Substitutions* subst, int* ioDiff) + DeclRefBase DeclRefBase::SubstituteImpl(SubstitutionSet subst, int* ioDiff) { int diff = 0; - RefPtr<Substitutions> substSubst = substituteSubstitutions(substitutions, subst, &diff); + auto substSubst = substituteSubstitutions(substitutions, subst, &diff); if (!diff) return *this; @@ -1460,9 +1432,7 @@ void Type::accept(IValVisitor* visitor, void* extra) { if (decl != declRef.decl) return false; - if (!substitutions) - return !hasGenericSubstitutions(declRef.substitutions); - if (!substitutions->Equals(declRef.substitutions.Ptr())) + if (!substitutions.Equals(declRef.substitutions)) return false; return true; @@ -1482,12 +1452,13 @@ void Type::accept(IValVisitor* visitor, void* extra) if (auto parentGeneric = dynamic_cast<GenericDecl*>(parentDecl)) { - auto genSubst = substitutions.As<GenericSubstitution>(); + auto genSubst = substitutions.genericSubstitutions; if (genSubst && genSubst->genericDecl == parentDecl) { // We strip away the specializations that were applied to // the parent, since we were asked for a reference *to* the parent. - return DeclRefBase(parentGeneric, substitutions->outer); + return DeclRefBase(parentGeneric, SubstitutionSet(genSubst->outer, substitutions.thisTypeSubstitution, + substitutions.globalGenParamSubstitutions)); } else { @@ -1509,18 +1480,12 @@ void Type::accept(IValVisitor* visitor, void* extra) int DeclRefBase::GetHashCode() const { - auto rs = PointerHash<1>::GetHashCode(decl); - if (substitutions) - { - rs *= 16777619; - rs ^= substitutions->GetHashCode(); - } - return rs; + return combineHash(PointerHash<1>::GetHashCode(decl), substitutions.GetHashCode()); } // Val - RefPtr<Val> Val::Substitute(Substitutions* subst) + RefPtr<Val> Val::Substitute(SubstitutionSet subst) { if (!this) return nullptr; if (!subst) return this; @@ -1528,7 +1493,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return SubstituteImpl(subst, &diff); } - RefPtr<Val> Val::SubstituteImpl(Substitutions* /*subst*/, int* /*ioDiff*/) + RefPtr<Val> Val::SubstituteImpl(SubstitutionSet /*subst*/, int* /*ioDiff*/) { // Default behavior is to not substitute at all return this; @@ -1622,12 +1587,12 @@ void Type::accept(IValVisitor* visitor, void* extra) Type* HLSLPatchType::getElementType() { - return this->declRef.substitutions.As<GenericSubstitution>()->args[0].As<Type>().Ptr(); + return this->declRef.substitutions.genericSubstitutions->args[0].As<Type>().Ptr(); } IntVal* HLSLPatchType::getElementCount() { - return this->declRef.substitutions.As<GenericSubstitution>()->args[1].As<IntVal>().Ptr(); + return this->declRef.substitutions.genericSubstitutions->args[1].As<IntVal>().Ptr(); } // Constructors for types @@ -1718,61 +1683,58 @@ void Type::accept(IValVisitor* visitor, void* extra) && declRef.Equals(otherWitness->declRef); } - RefPtr<Val> DeclaredSubtypeWitness::SubstituteImpl(Substitutions* subst, int * ioDiff) + RefPtr<Val> DeclaredSubtypeWitness::SubstituteImpl(SubstitutionSet subst, int * ioDiff) { if (auto genConstraintDecl = declRef.As<GenericTypeConstraintDecl>()) { // search for a substitution that might apply to us - for (auto s = subst; s; s = s->outer.Ptr()) + for (auto genericSubst = subst.genericSubstitutions; genericSubst; genericSubst = genericSubst->outer.Ptr()) { - if (auto genericSubst = dynamic_cast<GenericSubstitution*>(s)) + // the generic decl associated with the substitution list must be + // the generic decl that declared this parameter + auto genericDecl = genericSubst->genericDecl; + if (genericDecl != genConstraintDecl.getDecl()->ParentDecl) + continue; + bool found = false; + UInt index = 0; + for (auto m : genericDecl->Members) { - // the generic decl associated with the substitution list must be - // the generic decl that declared this parameter - auto genericDecl = genericSubst->genericDecl; - if (genericDecl != genConstraintDecl.getDecl()->ParentDecl) - continue; - bool found = false; - UInt index = 0; - for (auto m : genericDecl->Members) + if (auto constraintParam = m.As<GenericTypeConstraintDecl>()) { - if (auto constraintParam = m.As<GenericTypeConstraintDecl>()) + if (constraintParam.Ptr() == declRef.getDecl()) { - if (constraintParam.Ptr() == declRef.getDecl()) - { - found = true; - break; - } - index++; + found = true; + break; } - } - if (found) - { - (*ioDiff)++; - auto ordinaryParamCount = genericDecl->getMembersOfType<GenericTypeParamDecl>().Count() + - genericDecl->getMembersOfType<GenericValueParamDecl>().Count(); - SLANG_ASSERT(index + ordinaryParamCount < genericSubst->args.Count()); - return genericSubst->args[index + ordinaryParamCount]; + index++; } } - else if (auto globalGenParamSubst = dynamic_cast<GlobalGenericParamSubstitution*>(s)) + if (found) { - // we have a GlobalGenericParamSubstitution, this substitution will provide - // a concrete IRWitnessTable for a generic global variable - auto supType = GetSup(genConstraintDecl); + (*ioDiff)++; + auto ordinaryParamCount = genericDecl->getMembersOfType<GenericTypeParamDecl>().Count() + + genericDecl->getMembersOfType<GenericValueParamDecl>().Count(); + SLANG_ASSERT(index + ordinaryParamCount < genericSubst->args.Count()); + return genericSubst->args[index + ordinaryParamCount]; + } + } + for (auto globalGenParamSubst = subst.globalGenParamSubstitutions; globalGenParamSubst; globalGenParamSubst = globalGenParamSubst->outer.Ptr()) + { + // 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; + // 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; - } - } + // 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(); @@ -1817,7 +1779,7 @@ void Type::accept(IValVisitor* visitor, void* extra) && midToSup->EqualsVal(otherWitness->midToSup); } - RefPtr<Val> TransitiveSubtypeWitness::SubstituteImpl(Substitutions* subst, int * ioDiff) + RefPtr<Val> TransitiveSubtypeWitness::SubstituteImpl(SubstitutionSet subst, int * ioDiff) { int diff = 0; @@ -1912,60 +1874,16 @@ void Type::accept(IValVisitor* visitor, void* extra) // TODO: need to print out substitutions too! return sb.ProduceString(); } - - void insertSubstAtBottom(RefPtr<Substitutions> & substHead, RefPtr<Substitutions> substToInsert) - { - if (!substHead) - { - substHead = substToInsert; - return; - } - auto subst = substHead; - RefPtr<Substitutions> lastSubst = subst; - while (subst->outer) - { - lastSubst = subst; - subst = subst->outer; - } - lastSubst->outer = substToInsert; - } - - void insertSubstAtTop(DeclRefBase & declRef, RefPtr<Substitutions> substToInsert) - { - substToInsert->outer = declRef.substitutions; - declRef.substitutions = substToInsert; - } - - ThisTypeSubstitution* findThisTypeSubst(Substitutions* subst) - { - while (subst) - { - if (auto thisSubst = dynamic_cast<ThisTypeSubstitution*>(subst)) - return thisSubst; - subst = subst->outer.Ptr(); - } - return nullptr; - } - + 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; - } + RefPtr<ThisTypeSubstitution> thisSubst = declRef.substitutions.thisTypeSubstitution; if (!thisSubst) { thisSubst = new ThisTypeSubstitution(); if (insertSubstEntry) { - insertSubstAtTop(declRef, thisSubst); + declRef.substitutions.thisTypeSubstitution = thisSubst; } } return thisSubst; @@ -1973,80 +1891,19 @@ void Type::accept(IValVisitor* visitor, void* extra) RefPtr<ThisTypeSubstitution> getNewThisTypeSubst(DeclRefBase & declRef) { - auto oldSubst = getThisTypeSubst(declRef, false); - if (oldSubst) - removeSubstitution(declRef, oldSubst); - return getThisTypeSubst(declRef, true); + declRef.substitutions.thisTypeSubstitution = new ThisTypeSubstitution(); + return declRef.substitutions.thisTypeSubstitution; } - 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 hasThisTypeSubstitutions(RefPtr<Substitutions> subst) - { - auto p = subst.Ptr(); - while (p) - { - if (dynamic_cast<ThisTypeSubstitution*>(p)) - return true; - p = p->outer.Ptr(); - } - return false; - } - - bool hasGenericSubstitutions(RefPtr<Substitutions> subst) - { - auto p = subst.Ptr(); - while (p) - { - if (dynamic_cast<GenericSubstitution*>(p)) - return true; - p = p->outer.Ptr(); - } - return false; - } - - RefPtr<GenericSubstitution> getGenericSubstitution(RefPtr<Substitutions> subst) - { - auto p = subst.Ptr(); - while (p) - { - if (auto genSubst = dynamic_cast<GenericSubstitution*>(p)) - return genSubst; - p = p->outer.Ptr(); - } - return nullptr; - } - - RefPtr<Substitutions> substituteSubstitutions(RefPtr<Substitutions> oldSubst, Substitutions * subst, int * ioDiff) + SubstitutionSet substituteSubstitutions(SubstitutionSet oldSubst, SubstitutionSet subst, int * ioDiff) { if (oldSubst) - oldSubst = oldSubst->SubstituteImpl(subst, ioDiff); + oldSubst = oldSubst.substituteImpl(subst, ioDiff); // if oldSubst does not have ThisTypeSubst (which means `this_type` is free variable) // and subst has a ThisTypeSubst (which means `this_type` is bound to a type), // then copy that ThisTypeSubst over (to bind the this_type to the specified type) - RefPtr<Substitutions> newSubst = oldSubst; + SubstitutionSet newSubst = oldSubst; insertGlobalGenericSubstitutions(newSubst, subst, ioDiff); /*if (!hasThisTypeSubstitutions(oldSubst)) { @@ -2061,4 +1918,53 @@ void Type::accept(IValVisitor* visitor, void* extra) }*/ return newSubst; } + bool SubstitutionSet::Equals(SubstitutionSet substSet) const + { + if (genericSubstitutions) + { + if (!genericSubstitutions->Equals(substSet.genericSubstitutions)) + return false; + } + else + { + if (substSet.genericSubstitutions) + return false; + } + if (thisTypeSubstitution) + { + if (!thisTypeSubstitution->Equals(substSet.thisTypeSubstitution)) + return false; + } + else + { + if (substSet.thisTypeSubstitution && substSet.thisTypeSubstitution->sourceType != nullptr) + return false; + } + return true; + } + SubstitutionSet SubstitutionSet::substituteImpl(SubstitutionSet subst, int * ioDiff) + { + SubstitutionSet rs; + if (genericSubstitutions) + rs.genericSubstitutions = genericSubstitutions->SubstituteImpl(subst, ioDiff).As<GenericSubstitution>(); + if (globalGenParamSubstitutions) + rs.globalGenParamSubstitutions = globalGenParamSubstitutions->SubstituteImpl(subst, ioDiff).As<GlobalGenericParamSubstitution>(); + if (thisTypeSubstitution) + rs.thisTypeSubstitution = thisTypeSubstitution->SubstituteImpl(subst, ioDiff).As<ThisTypeSubstitution>(); + else + rs.thisTypeSubstitution = subst.thisTypeSubstitution; + return rs; + } + int SubstitutionSet::GetHashCode() const + { + int rs = 0; + if (genericSubstitutions) + rs = combineHash(rs, genericSubstitutions->GetHashCode()); + if (thisTypeSubstitution) + rs = combineHash(rs, thisTypeSubstitution->GetHashCode()); + if (globalGenParamSubstitutions) + rs = combineHash(rs, globalGenParamSubstitutions->GetHashCode()); + return rs; + } } + diff --git a/source/slang/syntax.h b/source/slang/syntax.h index a1f4ba801..375eb5f1c 100644 --- a/source/slang/syntax.h +++ b/source/slang/syntax.h @@ -412,7 +412,27 @@ namespace Slang return SyntaxClass<T>::getClass(); } - + struct SubstitutionSet + { + RefPtr<GenericSubstitution> genericSubstitutions; + RefPtr<ThisTypeSubstitution> thisTypeSubstitution; + RefPtr<GlobalGenericParamSubstitution> globalGenParamSubstitutions; + operator bool() const + { + return genericSubstitutions || thisTypeSubstitution || globalGenParamSubstitutions; + } + SubstitutionSet() {} + SubstitutionSet(RefPtr<GenericSubstitution> genSubst, RefPtr<ThisTypeSubstitution> inThisTypeSubst, + RefPtr<GlobalGenericParamSubstitution> globalSubst) + { + genericSubstitutions = genSubst; + thisTypeSubstitution = inThisTypeSubst; + globalGenParamSubstitutions = globalSubst; + } + bool Equals(SubstitutionSet substSet) const; + SubstitutionSet substituteImpl(SubstitutionSet subst, int * ioDiff); + int GetHashCode() const; + }; // A reference to a declaration, which may include // substitutions for generic parameters. struct DeclRefBase @@ -424,14 +444,25 @@ namespace Slang Decl* getDecl() const { return decl; } // Optionally, a chain of substititions to perform - RefPtr<Substitutions> substitutions; + SubstitutionSet substitutions; DeclRefBase() {} + + DeclRefBase(Decl* decl) + :decl(decl) + {} - DeclRefBase(Decl* decl, RefPtr<Substitutions> substitutions) - : decl(decl) - , substitutions(substitutions) + DeclRefBase(Decl* decl, SubstitutionSet subst) + :decl(decl), + substitutions(subst) + {} + + DeclRefBase(Decl* decl, RefPtr<GenericSubstitution> genSubstitutions, + RefPtr<ThisTypeSubstitution> thisTypeSubst = nullptr, + RefPtr<GlobalGenericParamSubstitution> globalSubst = nullptr) + : decl(decl), + substitutions(genSubstitutions, thisTypeSubst, globalSubst) {} // Apply substitutions to a type or ddeclaration @@ -443,7 +474,7 @@ namespace Slang RefPtr<Expr> Substitute(RefPtr<Expr> expr) const; // Apply substitutions to this declaration reference - DeclRefBase SubstituteImpl(Substitutions* subst, int* ioDiff); + DeclRefBase SubstituteImpl(SubstitutionSet subst, int* ioDiff); // Check if this is an equivalent declaration reference to another @@ -470,9 +501,13 @@ namespace Slang DeclRef() {} + + DeclRef(T* decl, SubstitutionSet subst) + : DeclRefBase(decl, subst) + {} - DeclRef(T* decl, RefPtr<Substitutions> substitutions) - : DeclRefBase(decl, substitutions) + DeclRef(T* decl, RefPtr<GenericSubstitution> genSubst) + : DeclRefBase(decl, SubstitutionSet(genSubst, nullptr, nullptr)) {} template <typename U> @@ -525,7 +560,7 @@ namespace Slang } // Apply substitutions to this declaration reference - DeclRef<T> SubstituteImpl(Substitutions* subst, int* ioDiff) + DeclRef<T> SubstituteImpl(SubstitutionSet subst, int* ioDiff) { return DeclRef<T>::unsafeInit(DeclRefBase::SubstituteImpl(subst, ioDiff)); } @@ -641,11 +676,11 @@ namespace Slang struct FilteredMemberRefList { List<RefPtr<Decl>> const& decls; - RefPtr<Substitutions> substitutions; + SubstitutionSet substitutions; FilteredMemberRefList( List<RefPtr<Decl>> const& decls, - RefPtr<Substitutions> substitutions) + SubstitutionSet substitutions) : decls(decls) , substitutions(substitutions) {} @@ -1153,12 +1188,12 @@ namespace Slang } // TODO: where should this live? - RefPtr<Substitutions> createDefaultSubstitutions( + SubstitutionSet createDefaultSubstitutions( Session* session, Decl* decl, - Substitutions* parentSubst); + SubstitutionSet parentSubst); - RefPtr<Substitutions> createDefaultSubstitutions( + SubstitutionSet createDefaultSubstitutions( Session* session, Decl* decl); @@ -1184,7 +1219,7 @@ namespace Slang // substitution lists of `DeclRef` etc. to replace the call of // `declRef.substitutions->SubstituteImpl()`, because the head to the linked list is known as a // member of that class there. - RefPtr<Substitutions> substituteSubstitutions(RefPtr<Substitutions> oldSubst, Substitutions * subst, int * ioDiff); + SubstitutionSet substituteSubstitutions(SubstitutionSet oldSubst, SubstitutionSet subst, int * ioDiff); } // namespace Slang #endif
\ No newline at end of file diff --git a/source/slang/type-defs.h b/source/slang/type-defs.h index 4efbc7ec1..c4ec09f1d 100644 --- a/source/slang/type-defs.h +++ b/source/slang/type-defs.h @@ -61,7 +61,7 @@ SYNTAX_CLASS(DeclRefType, Type) RAW( virtual String ToString() override; - virtual RefPtr<Val> SubstituteImpl(Substitutions* subst, int* ioDiff) override; + virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; static DeclRefType* Create( Session* session, @@ -310,7 +310,7 @@ RAW( protected: virtual bool EqualsImpl(Type * type) override; virtual Type* CreateCanonicalType() override; - virtual RefPtr<Val> SubstituteImpl(Substitutions* subst, int* ioDiff) override; + virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; virtual int GetHashCode() override; ) END_SYNTAX_CLASS() @@ -464,7 +464,7 @@ RAW( virtual String ToString() override; protected: - virtual RefPtr<Val> SubstituteImpl(Substitutions* subst, int* ioDiff) override; + virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; virtual bool EqualsImpl(Type * type) override; virtual Type* CreateCanonicalType() override; virtual int GetHashCode() override; diff --git a/source/slang/val-defs.h b/source/slang/val-defs.h index f0f830cd2..1fe3bfe44 100644 --- a/source/slang/val-defs.h +++ b/source/slang/val-defs.h @@ -37,7 +37,7 @@ SYNTAX_CLASS(GenericParamIntVal, IntVal) virtual bool EqualsVal(Val* val) override; virtual String ToString() override; virtual int GetHashCode() override; - virtual RefPtr<Val> SubstituteImpl(Substitutions* subst, int* ioDiff) override; + virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; ) END_SYNTAX_CLASS() @@ -98,7 +98,7 @@ RAW( virtual bool EqualsVal(Val* val) override; virtual String ToString() override; virtual int GetHashCode() override; - virtual RefPtr<Val> SubstituteImpl(Substitutions * subst, int * ioDiff) override; + virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int * ioDiff) override; virtual DeclRef<Decl> getLastStepDeclRef() override { return declRef; @@ -117,7 +117,7 @@ RAW( virtual bool EqualsVal(Val* val) override; virtual String ToString() override; virtual int GetHashCode() override; - virtual RefPtr<Val> SubstituteImpl(Substitutions * subst, int * ioDiff) override; + virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int * ioDiff) override; virtual DeclRef<Decl> getLastStepDeclRef() override { return midToSup->getLastStepDeclRef(); |
