diff options
| author | Yong He <yonghe@outlook.com> | 2020-06-18 15:06:14 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-18 15:06:14 -0700 |
| commit | 515d8eb0cd719ae31db2f6e03751011a123bc0ba (patch) | |
| tree | 3e78893a74af856fb29158078bed7099a567f5dd /source/slang/slang-ir-lower-generics.cpp | |
| parent | e2d21026d115dc61296b47dcc990534f1844bc7f (diff) | |
| parent | aa6aca498cd1f7fbbdb143e72dd48b1d714c8fbb (diff) | |
Merge branch 'master' into feature/prelude-fix
Diffstat (limited to 'source/slang/slang-ir-lower-generics.cpp')
| -rw-r--r-- | source/slang/slang-ir-lower-generics.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp index 4378d396f..f6340a633 100644 --- a/source/slang/slang-ir-lower-generics.cpp +++ b/source/slang/slang-ir-lower-generics.cpp @@ -79,6 +79,14 @@ namespace Slang block->addParam(as<IRParam>(param)); } loweredGenericFunctions[genericValue] = loweredFunc; + // Turn generic parameters into void pointers. + for (auto param : cast<IRFunc>(loweredFunc)->getParams()) + { + if (param->findDecoration<IRPolymorphicDecoration>()) + { + param->setFullType(builder.getPtrType(builder.getVoidType())); + } + } addToWorkList(loweredFunc); return loweredFunc; } @@ -103,8 +111,29 @@ namespace Slang builder->sharedBuilder = &sharedBuilderStorage; builder->setInsertBefore(inst); List<IRInst*> args; + auto pp = as<IRFunc>(loweredFunc)->getParams().begin(); + auto voidPtrType = builder->getPtrType(builder->getVoidType()); for (UInt i = 0; i < callInst->getArgCount(); i++) - args.add(callInst->getArg(i)); + { + auto arg = callInst->getArg(i); + if ((*pp)->getDataType() == voidPtrType && + arg->getDataType() != voidPtrType) + { + // We are calling a generic function that with an argument of + // concrete type. We need to convert this argument o void*. + + // Ideally this should just be a GetElementAddress inst. + // However the current code emitting logic for this instruction + // doesn't truly respect the pointerness and does not produce + // what we needed. For now we use another instruction here + // to keep changes minimal. + arg = builder->emitGetAddress( + voidPtrType, + arg); + } + args.add(arg); + ++pp; + } for (UInt i = 0; i < specializeInst->getArgCount(); i++) args.add(specializeInst->getArg(i)); auto newCall = builder->emitCallInst(callInst->getFullType(), loweredFunc, args); |
