diff options
| author | Yong He <yonghe@outlook.com> | 2017-12-27 18:47:40 -0500 |
|---|---|---|
| committer | Yong He <yonghe@outlook.com> | 2017-12-27 18:50:32 -0500 |
| commit | 87cba147d513fcbc4b69a083dc10557a6c1b42ba (patch) | |
| tree | 1eb707caede6b43ef417b952656cbdf97b9c9001 /source | |
| parent | 69242398be1ba76898c0d6541eec3b7ca0ec1ab4 (diff) | |
Support nested generic types (e.g. L<T<S>>)
fixes #325
This commit includes following changes:
1. Including a default DeclaredSubtypeWitness argument when creating a default GenericSubstitution for a DeclRefType, so that the witness argument can be successfully replaced with an actual witness table after specialization. (check,cpp)
2. Not emitting full mangled name for struct field members. Since the declref of the member access instruction do not include necessary generic substitutions for its parent generic parameters, so the mangled names of the declaration site and use site mismatches. Instead we just emit the original name for struct fields. (emit.cpp)
3. Allow IRWitnessTable to represent a generic witness table for generic structs. Adds necessary fields to IRWitnessTable for generic specialization. For now, the user field of the IRUse is not used and is nullptr. (ir-inst.h)
4. Make IRProxyVal use an IRUse instead of an IRValue*, so that an IRValue referenced by IRProxyVal (as a substitution argument) can be managed by the def-use chain for easy replacement. This is used for specializing witness tables. (ir.cpp, ir.h)
5. Add a `String dumpIRFunc(IRFunc*)` function for debugging.
6. Add name mangling for generic / specialized witness tables (mangle.cpp)
7. improved natvis file for inspecting witness tables.
8. Add specialization of witness tables:
1) `findWitnessTable` will simply return the specialize IRInst for a generic witness table.
2) make `cloneSubstitutionArg` call `cloneValue` to clone the argument instead of calling `context->maybeCloneValue`, so we can make use of the cloned value lookup machanism to directly return the specialized witness table (which is done when we process the `specialize` instruction on the generic witness table before process the decl ref).
3) bug fix: the argument in ir.cpp:3338 should be `newArg` instead of `arg`.
4) add `specializeWitnessTable` function to specailize a generic witness table. It clones the witness table, and recursively calls `getSpecailizedFunc` for the witness table entries.
5) make `specailizeGenerics` function also handle the case when an operand of the `specialize` instruction is a witness table. We will call `specializeWitnessTable` here and replace the `specialize` instruction with the specialized witness table. The replacement mechanism based on IR def-use chain works here because we have already make IRProxyVal a part of the def-use chain.
9. Add two more test cases for nested generics with constraints. (generic-list.slang and generic-struct-with-constraint.slang)
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/check.cpp | 14 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 8 | ||||
| -rw-r--r-- | source/slang/ir-insts.h | 8 | ||||
| -rw-r--r-- | source/slang/ir.cpp | 177 | ||||
| -rw-r--r-- | source/slang/ir.h | 1 | ||||
| -rw-r--r-- | source/slang/lower-to-ir.cpp | 22 | ||||
| -rw-r--r-- | source/slang/mangle.cpp | 11 | ||||
| -rw-r--r-- | source/slang/mangle.h | 4 | ||||
| -rw-r--r-- | source/slang/slang.natvis | 10 | ||||
| -rw-r--r-- | source/slang/slang.vcxproj | 1 | ||||
| -rw-r--r-- | source/slang/slang.vcxproj.filters | 1 | ||||
| -rw-r--r-- | source/slang/syntax.cpp | 4 | ||||
| -rw-r--r-- | source/slang/syntax.h | 2 | ||||
| -rw-r--r-- | source/slang/val-defs.h | 6 |
14 files changed, 210 insertions, 59 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp index 9faad1127..5141d8634 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -7003,8 +7003,18 @@ namespace Slang } } - // TODO: need to fill in constraints here... - + // create default substitution arguments for constraints + for (auto mm : genericDecl->Members) + { + if (auto genericTypeConstraintDecl = mm.As<GenericTypeConstraintDecl>()) + { + RefPtr<DeclaredSubtypeWitness> witness = new DeclaredSubtypeWitness(); + witness->declRef = makeDeclRef(genericTypeConstraintDecl.Ptr()); + witness->sub = genericTypeConstraintDecl->sub.type; + witness->sup = genericTypeConstraintDecl->sup.type; + subst->args.Add(witness); + } + } return subst; } return parentSubst; diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index e9a2588d5..080478225 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -4503,8 +4503,12 @@ emitDeclImpl(decl, nullptr); return name; } - // Special case (2): not implemented yet. - + // Special case (2) + if (declRef.GetParent().decl->As<AggTypeDecl>()) + { + name.append(declRef.decl->nameAndLoc.name->text); + return name; + } // General case: name.append(getMangledName(declRef)); return name; diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h index 769229962..a8c8383e2 100644 --- a/source/slang/ir-insts.h +++ b/source/slang/ir-insts.h @@ -304,6 +304,8 @@ struct IRWitnessTableEntry : IRUser // to the IR values that satisfy those requirements. struct IRWitnessTable : IRGlobalValue { + RefPtr<GenericDecl> genericDecl; + DeclRef<Decl> subTypeDeclRef, supTypeDeclRef; IRValueList<IRWitnessTableEntry> entries; }; @@ -341,6 +343,7 @@ struct SharedIRBuilder Dictionary<IRInstKey, IRInst*> globalValueNumberingMap; Dictionary<IRConstantKey, IRConstant*> constantMap; + Dictionary<String, IRWitnessTable*> witnessTableMap; }; struct IRBuilderSourceLocRAII; @@ -417,7 +420,7 @@ struct IRBuilder IRValue* const* args); IRModule* createModule(); - + IRFunc* createFunc(); IRGlobalVar* createGlobalVar( IRType* valueType); @@ -427,7 +430,8 @@ struct IRBuilder IRWitnessTable* witnessTable, IRValue* requirementKey, IRValue* satisfyingVal); - + IRWitnessTable* lookupWitnessTable(String mangledName); + void registerWitnessTable(IRWitnessTable* table); IRBlock* createBlock(); IRBlock* emitBlock(); diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp index cd36e8d47..e0f703cbd 100644 --- a/source/slang/ir.cpp +++ b/source/slang/ir.cpp @@ -60,7 +60,8 @@ namespace Slang // clear out the old value if (usedVal) { - *prevLink = nextUse; + if (prevLink) + *prevLink = nextUse; } init(user, usedVal); @@ -934,6 +935,19 @@ namespace Slang return entry; } + IRWitnessTable * IRBuilder::lookupWitnessTable(String mangledName) + { + IRWitnessTable * result; + if (sharedBuilder->witnessTableMap.TryGetValue(mangledName, result)) + return result; + return nullptr; + } + + + void IRBuilder::registerWitnessTable(IRWitnessTable * table) + { + sharedBuilder->witnessTableMap[table->mangledName] = table; + } IRBlock* IRBuilder::createBlock() { @@ -1396,7 +1410,7 @@ namespace Slang struct IRDumpContext { StringBuilder* builder; - int indent; + int indent = 0; UInt idCounter = 1; Dictionary<IRValue*, UInt> mapValueToID; @@ -1588,7 +1602,7 @@ namespace Slang } else if (auto proxyVal = dynamic_cast<IRProxyVal*>(val)) { - dumpOperand(context, proxyVal->inst); + dumpOperand(context, proxyVal->inst.usedValue); } else { @@ -2095,6 +2109,17 @@ namespace Slang dump(context, "}\n"); } + + String dumpIRFunc(IRFunc* func) + { + IRDumpContext dumpContext; + StringBuilder sbDump; + dumpContext.builder = &sbDump; + dumpIRFunc(&dumpContext, func); + auto strFunc = sbDump.ToString(); + return strFunc; + } + void dumpIRGlobalVar( IRDumpContext* context, IRGlobalVar* var) @@ -3199,7 +3224,6 @@ namespace Slang case kIROp_Func: case kIROp_witness_table: return cloneGlobalValue(this, (IRGlobalValue*) originalValue); - case kIROp_boolConst: { IRConstant* c = (IRConstant*)originalValue; @@ -3246,7 +3270,7 @@ namespace Slang { auto proxyVal = witness.Value.As<IRProxyVal>(); SLANG_ASSERT(proxyVal); - return proxyVal->inst; + return proxyVal->inst.usedValue; } } } @@ -3270,16 +3294,20 @@ namespace Slang } } + IRValue* cloneValue( + IRSpecContextBase* context, + IRValue* originalValue); + RefPtr<Val> cloneSubstitutionArg( IRSpecContext* context, Val* val) { if (auto proxyVal = dynamic_cast<IRProxyVal*>(val)) { - auto newIRVal = context->maybeCloneValue(proxyVal->inst); + auto newIRVal = cloneValue(context, proxyVal->inst.usedValue); RefPtr<IRProxyVal> newProxyVal = new IRProxyVal(); - newProxyVal->inst = newIRVal; + newProxyVal->inst.init(nullptr, newIRVal); return newProxyVal; } else if (auto type = dynamic_cast<Type*>(val)) @@ -3307,7 +3335,7 @@ namespace Slang for (auto arg : genSubst->args) { auto newArg = cloneSubstitutionArg(context, arg); - newSubst->args.Add(arg); + newSubst->args.Add(newArg); } return newSubst; } @@ -3436,7 +3464,7 @@ namespace Slang } IRWitnessTable* cloneWitnessTableImpl( - IRSpecContext* context, + IRSpecContextBase* context, IRWitnessTable* originalTable, IROriginalValuesForClone const& originalValues) { @@ -3445,7 +3473,9 @@ namespace Slang auto mangledName = originalTable->mangledName; clonedTable->mangledName = mangledName; - + clonedTable->genericDecl = originalTable->genericDecl; + clonedTable->subTypeDeclRef = originalTable->subTypeDeclRef; + clonedTable->supTypeDeclRef = originalTable->supTypeDeclRef; cloneDecorations(context, clonedTable, originalTable); // Clone the entries in the witness table as well @@ -3463,7 +3493,7 @@ namespace Slang } IRWitnessTable* cloneWitnessTableWithoutRegistering( - IRSpecContext* context, + IRSpecContextBase* context, IRWitnessTable* originalTable) { return cloneWitnessTableImpl(context, originalTable, IROriginalValuesForClone()); @@ -4008,7 +4038,7 @@ namespace Slang SLANG_ASSERT(table); table = cloneWitnessTableWithoutRegistering(context, (IRWitnessTable*)(table)); IRProxyVal * tableVal = new IRProxyVal(); - tableVal->inst = table; + tableVal->inst.init(nullptr, table); paramSubst->witnessTables.Add(KeyValuePair<RefPtr<Type>, RefPtr<Val>>(subtypeWitness->sup, tableVal)); } } @@ -4228,7 +4258,7 @@ namespace Slang // the pointed-to value and not the proxy type-level `Val` // instead. - return context->maybeCloneValue(proxyVal->inst); + return context->maybeCloneValue(proxyVal->inst.usedValue); } else { @@ -4394,6 +4424,69 @@ namespace Slang return newSubst; } + IRFunc* getSpecializedFunc( + IRSharedGenericSpecContext* sharedContext, + IRFunc* genericFunc, + DeclRef<Decl> specDeclRef); + + IRWitnessTable* specializeWitnessTable(IRSharedGenericSpecContext * sharedContext, IRWitnessTable* originalTable, DeclRef<Decl> specDeclRef) + { + // First, we want to see if an existing specialization + // has already been made. To do that we will need to + // compute the mangled name of the specialized function, + // so that we can look for existing declarations. + String specMangledName; + String specializedMangledName = getMangledNameForConformanceWitness(specDeclRef.Substitute(originalTable->subTypeDeclRef), + specDeclRef.Substitute(originalTable->supTypeDeclRef)); + + // TODO: This is a terrible linear search, and we should + // avoid it by building a dictionary ahead of time, + // as is being done for the `IRSpecContext` used above. + // We can probalby use the same basic context, actually. + auto module = originalTable->parentModule; + for (auto gv = module->getFirstGlobalValue(); gv; gv = gv->getNextValue()) + { + if (gv->mangledName == specMangledName) + return (IRWitnessTable*)gv; + } + + RefPtr<Substitutions> newSubst = cloneSubstitutionsForSpecialization( + sharedContext, + specDeclRef.substitutions, + originalTable->genericDecl); + + IRGenericSpecContext context; + context.shared = sharedContext; + context.builder = &sharedContext->builderStorage; + context.subst = newSubst; + + // TODO: other initialization is needed here... + + auto specTable = cloneWitnessTableWithoutRegistering(&context, originalTable); + + // Set up the clone to recognize that it is no longer generic + specTable->mangledName = specMangledName; + specTable->genericDecl = nullptr; + + // Specialization of witness tables should trigger cascading specializations + // of involved functions. + for (auto entry : specTable->entries) + { + if (entry->satisfyingVal.usedValue->op == kIROp_Func) + { + IRFunc* func = (IRFunc*)entry->satisfyingVal.usedValue; + if (func->genericDecl) + entry->satisfyingVal.set(getSpecializedFunc(sharedContext, func, specDeclRef)); + } + + } + // We also need to make sure that we register this specialized + // function under its mangled name, so that later lookup + // steps will find it. + insertGlobalValueSymbol(sharedContext, specTable); + + return specTable; + } IRFunc* getSpecializedFunc( IRSharedGenericSpecContext* sharedContext, @@ -4415,9 +4508,9 @@ namespace Slang // as is being done for the `IRSpecContext` used above. // We can probalby use the same basic context, actually. auto module = genericFunc->parentModule; - for(auto gv = module->getFirstGlobalValue(); gv; gv = gv->getNextValue()) + for (auto gv = module->getFirstGlobalValue(); gv; gv = gv->getNextValue()) { - if(gv->mangledName == specMangledName) + if (gv->mangledName == specMangledName) return (IRFunc*) gv; } @@ -4564,7 +4657,7 @@ namespace Slang // specialization to perform. auto func = workList[count-1]; workList.RemoveAt(count-1); - + // We are going to go ahead and walk through // all the instructions in this function, // and look for `specialize` operations. @@ -4596,32 +4689,40 @@ namespace Slang // specialization here and now. IRSpecialize* specInst = (IRSpecialize*) ii; - // We need to check that the value being specialized is - // a generic function. - auto genericVal = specInst->genericVal.usedValue; - if(genericVal->op != kIROp_Func) - continue; - auto genericFunc = (IRFunc*) genericVal; - if(!genericFunc->genericDecl) - continue; - // Now we extract the specialized decl-ref that will // tell us how to specialize things. - auto specDeclRefVal = (IRDeclRef*) specInst->specDeclRefVal.usedValue; + auto specDeclRefVal = (IRDeclRef*)specInst->specDeclRefVal.usedValue; auto specDeclRef = specDeclRefVal->declRef; - // Okay, we have a candidate for specialization here. - // - // We will first find or construct a specialized version - // of the callee funciton/ - auto specFunc = getSpecializedFunc(sharedContext, genericFunc, specDeclRef); - // - // Then we will replace the use sites for the `specialize` - // instruction with uses of the specialized function. - // - specInst->replaceUsesWith(specFunc); - - specInst->removeAndDeallocate(); + // We need to specialize functions and witness tables + auto genericVal = specInst->genericVal.usedValue; + if (genericVal->op == kIROp_Func) + { + auto genericFunc = (IRFunc*)genericVal; + if (!genericFunc->genericDecl) + continue; + + // Okay, we have a candidate for specialization here. + // + // We will first find or construct a specialized version + // of the callee funciton/ + auto specFunc = getSpecializedFunc(sharedContext, genericFunc, specDeclRef); + // + // Then we will replace the use sites for the `specialize` + // instruction with uses of the specialized function. + // + specInst->replaceUsesWith(specFunc); + + specInst->removeAndDeallocate(); + } + else if (genericVal->op == kIROp_witness_table) + { + // specialize a witness table + auto originalTable = (IRWitnessTable*)genericVal; + auto specWitnessTable = specializeWitnessTable(sharedContext, originalTable, specDeclRef); + specInst->replaceUsesWith(specWitnessTable); + specInst->removeAndDeallocate(); + } } break; diff --git a/source/slang/ir.h b/source/slang/ir.h index 8ca4508ff..c56f8fb62 100644 --- a/source/slang/ir.h +++ b/source/slang/ir.h @@ -471,6 +471,7 @@ void printSlangIRAssembly(StringBuilder& builder, IRModule* module); String getSlangIRAssembly(IRModule* module); void dumpIR(IRModule* module); +String dumpIRFunc(IRFunc* func); } diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp index 8fc1239cd..1d6da3a3b 100644 --- a/source/slang/lower-to-ir.cpp +++ b/source/slang/lower-to-ir.cpp @@ -2740,10 +2740,6 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> context->getSession(), makeDeclRef(parentDecl)); - - // TODO: if the parent type is generic, then I suppose these - // need to be *generic* witness tables? - // What is the super-type that we have declared we inherit from? RefPtr<Type> superType = inheritanceDecl->base.type; @@ -2758,6 +2754,11 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> auto witnessTable = context->irBuilder->createWitnessTable(); witnessTable->mangledName = mangledName; + if (parentDecl->ParentDecl) + witnessTable->genericDecl = dynamic_cast<GenericDecl*>(parentDecl->ParentDecl); + witnessTable->subTypeDeclRef = makeDeclRef(parentDecl); + witnessTable->supTypeDeclRef = inheritanceDecl->base.type->AsDeclRefType()->declRef; + // Register the value now, rather than later, to avoid // infinite recursion. context->shared->declValues[inheritanceDecl] = LoweredValInfo::simple(witnessTable); @@ -3713,7 +3714,7 @@ LoweredValInfo ensureDecl( return result; } -IRWitnessTable* findWitnessTable( +IRValue* findWitnessTable( IRGenContext* context, DeclRef<Decl> declRef) { @@ -3724,10 +3725,13 @@ IRWitnessTable* findWitnessTable( return nullptr; } + if (irVal->op == kIROp_specialize) + { + return irVal; + } + if (irVal->op != kIROp_witness_table) { - // TODO: We might eventually have cases of `specialize` called - // on a witness table... SLANG_UNEXPECTED("expected a witness table"); return nullptr; } @@ -3764,7 +3768,7 @@ RefPtr<Val> lowerSubstitutionArg( // up in a reasonably clean fashion. // RefPtr<IRProxyVal> proxyVal = new IRProxyVal(); - proxyVal->inst = irWitnessTable; + proxyVal->inst.init(nullptr, irWitnessTable); return proxyVal; } else @@ -3860,7 +3864,7 @@ LoweredValInfo maybeEmitSpecializeInst(IRGenContext* context, // Otherwise, we need to construct a specialization of the // given declaration. - return LoweredValInfo::simple(context->irBuilder->emitSpecializeInst( + return LoweredValInfo::simple((IRInst*)context->irBuilder->emitSpecializeInst( type, val, declRef)); diff --git a/source/slang/mangle.cpp b/source/slang/mangle.cpp index 0625a6f73..5b8e519b9 100644 --- a/source/slang/mangle.cpp +++ b/source/slang/mangle.cpp @@ -400,6 +400,17 @@ namespace Slang { return getMangledName(makeDeclRef(decl)); } + + String getMangledNameForConformanceWitness( + DeclRef<Decl> sub, + DeclRef<Decl> sup) + { + ManglingContext context; + emitRaw(&context, "_SW"); + emitQualifiedName(&context, sub); + emitQualifiedName(&context, sup); + return context.sb.ProduceString(); + } String getMangledNameForConformanceWitness( Type* sub, diff --git a/source/slang/mangle.h b/source/slang/mangle.h index 65afea741..406796951 100644 --- a/source/slang/mangle.h +++ b/source/slang/mangle.h @@ -16,7 +16,9 @@ namespace Slang String getMangledNameForConformanceWitness( Type* sub, Type* sup); - + String getMangledNameForConformanceWitness( + DeclRef<Decl> sub, + DeclRef<Decl> sup); String getMangledTypeName(Type* type); } diff --git a/source/slang/slang.natvis b/source/slang/slang.natvis index 91e9d0994..d58e733fa 100644 --- a/source/slang/slang.natvis +++ b/source/slang/slang.natvis @@ -35,6 +35,12 @@ <Type Name="Slang::NameLoc"> <DisplayString>{{name={(char*)((*name).text.buffer.pointer+1), s} loc={loc.raw}}}</DisplayString> </Type> + <Type Name="Slang::IRWitnessTableEntry"> + <Expand> + <Item Name="[Key]">requirementKey</Item> + <Item Name="[Val]">satisfyingVal</Item> + </Expand> + </Type> <Type Name="Slang::IRValue"> <DisplayString>{{{op}}}</DisplayString> <Expand> @@ -44,11 +50,13 @@ <ExpandedItem Condition="op==kIROp_decl_ref">(Slang::IRDeclRef*)this</ExpandedItem> <ExpandedItem Condition="op==kIROp_Func">(Slang::IRFunc*)this</ExpandedItem> <ExpandedItem Condition="op==kIROp_Block">(Slang::IRBlock*)this</ExpandedItem> + <ExpandedItem Condition="op==kIROp_witness_table">(Slang::IRWitnessTable*)this</ExpandedItem> + <ExpandedItem Condition="op==kIROp_witness_table_entry">(Slang::IRWitnessTableEntry*)this</ExpandedItem> <Item Name="====Uses====">"-------"</Item> <LinkedListItems> <HeadPointer>firstUse</HeadPointer> <NextPointer>nextUse</NextPointer> - <ValueNode>usedValue</ValueNode> + <ValueNode>user</ValueNode> </LinkedListItems> </Expand> diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj index 9835640e0..da0d9d9d4 100644 --- a/source/slang/slang.vcxproj +++ b/source/slang/slang.vcxproj @@ -237,6 +237,7 @@ <ClCompile Include="syntax.cpp" /> <ClCompile Include="token.cpp" /> <ClCompile Include="type-layout.cpp" /> + <ClCompile Include="val-defs.cpp" /> <ClCompile Include="vm.cpp" /> </ItemGroup> <ItemGroup> diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters index f207c6dcd..7bc22ae5d 100644 --- a/source/slang/slang.vcxproj.filters +++ b/source/slang/slang.vcxproj.filters @@ -74,6 +74,7 @@ <ClCompile Include="ir-legalize-types.cpp" /> <ClCompile Include="ast-legalize.cpp" /> <ClCompile Include="legalize-types.cpp" /> + <ClCompile Include="val-defs.cpp" /> </ItemGroup> <ItemGroup> <CustomBuild Include="core.meta.slang" /> diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index 070362ddf..9ca2dc827 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -1827,7 +1827,7 @@ void Type::accept(IValVisitor* visitor, void* extra) if(!otherProxy) return false; - return this->inst == otherProxy->inst; + return this->inst.usedValue == otherProxy->inst.usedValue; } String IRProxyVal::ToString() @@ -1837,7 +1837,7 @@ void Type::accept(IValVisitor* visitor, void* extra) int IRProxyVal::GetHashCode() { - auto hash = Slang::GetHashCode(inst); + auto hash = Slang::GetHashCode(inst.usedValue); return hash; } diff --git a/source/slang/syntax.h b/source/slang/syntax.h index 749c5ae32..00e6bd6d3 100644 --- a/source/slang/syntax.h +++ b/source/slang/syntax.h @@ -1167,7 +1167,7 @@ namespace Slang void removeSubstitution(DeclRefBase & declRef, RefPtr<Substitutions> subst); bool hasGenericSubstitutions(RefPtr<Substitutions> subst); RefPtr<GenericSubstitution> getGenericSubstitution(RefPtr<Substitutions> subst); - + // This function substitutes the type arguments referenced in a linked list of substitutions // which head is at `substHead` using the substitutions specified by `subst`. If the linked // list `substHead` does not contain `GlobalGenericParamSubstitution` entries, they will be diff --git a/source/slang/val-defs.h b/source/slang/val-defs.h index f3cdf52a2..4ecd5a51b 100644 --- a/source/slang/val-defs.h +++ b/source/slang/val-defs.h @@ -117,11 +117,15 @@ END_SYNTAX_CLASS() // A value that is used as a proxy when we need to // put an IR-level value into AST types SYNTAX_CLASS(IRProxyVal, Val) - FIELD(IRValue*, inst) + FIELD(IRUse, inst) RAW( virtual bool EqualsVal(Val* val) override; virtual String ToString() override; virtual int GetHashCode() override; + ~IRProxyVal() override + { + inst.clear(); + } ) END_SYNTAX_CLASS() |
