diff options
| author | Yong He <yonghe@outlook.com> | 2024-08-20 20:51:57 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-20 20:51:57 -0700 |
| commit | f9f6a28df40f418ddd0c8ff3b9cacccdb085e202 (patch) | |
| tree | a6bafa63cee4f9bbcfe496de54af6e5727bb021e /source/slang/slang-lower-to-ir.cpp | |
| parent | 03e1e17745920c8e3a7b6f4e3b1e64062589604a (diff) | |
Support dependent generic constraints. (#4870)
* Support dependent generic constraints.
* Fix warning.
* Update comment.
* Fix.
* Add a test case to verify fix of #3804.
* Address review.
Diffstat (limited to 'source/slang/slang-lower-to-ir.cpp')
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 44c62e858..2828752a0 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -9304,15 +9304,46 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> auto typeGeneric = typeBuilder.emitGeneric(); typeGeneric->setFullType(typeBuilder.getGenericKind()); typeBuilder.setInsertInto(typeGeneric); - typeBuilder.emitBlock(); + auto block = typeBuilder.emitBlock(); + struct ParamCloneInfo + { + IRParam* originalParam; + IRParam* clonedParam; + }; + ShortList<ParamCloneInfo> paramCloneInfos; + for (auto child : parentGeneric->getFirstBlock()->getChildren()) { if (valuesToClone.contains(child)) { - cloneInst(&cloneEnv, &typeBuilder, child); + if (child->getOp() == kIROp_Param) + { + // Params may have forward references in its type and + // decorations, so we just create a placeholder for it + // in this first pass. + IRParam* clonedParam = typeBuilder.emitParam(nullptr); + cloneEnv.mapOldValToNew[child] = clonedParam; + paramCloneInfos.add({ (IRParam*)child, clonedParam }); + } + else + { + cloneInst(&cloneEnv, &typeBuilder, child); + } } } + + // In a second pass, clone the types and decorations on params which may + // contain forward references. + for (auto param : paramCloneInfos) + { + typeBuilder.setInsertInto(param.clonedParam); + param.clonedParam->setFullType((IRType*)cloneInst(&cloneEnv, &typeBuilder, param.originalParam->getFullType())); + cloneInstDecorationsAndChildren(&cloneEnv, typeBuilder.getModule(), param.originalParam, param.clonedParam); + } + + typeBuilder.setInsertInto(block); + IRInst* clonedReturnType = nullptr; cloneEnv.mapOldValToNew.tryGetValue(returnType, clonedReturnType); if (clonedReturnType) |
