summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2018-01-12 14:15:56 -0800
committerTim Foley <tfoleyNV@users.noreply.github.com>2018-01-12 14:15:56 -0800
commitdf6eeb93c1718334779ae328db277cdf7a9d7b04 (patch)
treef4d53d3106cdc717727701e46411a1ebe23105fb /source
parent8daafcc2e4bf7b2dfb66d7a3b7ac60c86b2d926c (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.cpp28
-rw-r--r--source/slang/check.cpp75
-rw-r--r--source/slang/emit.cpp2
-rw-r--r--source/slang/ir.cpp145
-rw-r--r--source/slang/legalize-types.cpp3
-rw-r--r--source/slang/lower-to-ir.cpp72
-rw-r--r--source/slang/mangle.cpp17
-rw-r--r--source/slang/mangle.h2
-rw-r--r--source/slang/parameter-binding.cpp6
-rw-r--r--source/slang/syntax-base-defs.h30
-rw-r--r--source/slang/syntax.cpp508
-rw-r--r--source/slang/syntax.h65
-rw-r--r--source/slang/type-defs.h6
-rw-r--r--source/slang/val-defs.h6
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();