diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-11-07 10:02:10 -0800 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-11-07 10:56:45 -0800 |
| commit | f4c4f63c0cfad93b1eacf9300eb8e06d2c78ccc9 (patch) | |
| tree | 9d3458ed0ea798839867ef7070424c02fa563126 | |
| parent | 97a1a95b6192599e038a26704756a914368f3d3a (diff) | |
Fix for emitting subscript calls in HLSL/GLSL
The old approach was relying on an `__intrinsic_op` modifier to tell us we need to do something special with an `InvokeExpr`, but a previous change removed a bunch of those modifiers.
Instead, we will now check for calls to subscript declarations as part of the normal flow of emitting *any* call, similar to what is done for constructor calls already.
Eventually we should be able to eliminate the special case in the `__intrinsic_op` path, but I'm holding off on that because the AST emit logic can probably be cleaned up a *lot* once it doesn't have to be used for cross-compilation as well.
| -rw-r--r-- | source/slang/emit.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 615fb47a0..c67bb7b29 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -1614,6 +1614,32 @@ struct EmitVisitor } } + void emitSimpleSubscriptCallExpr( + RefPtr<InvokeExpr> callExpr, + EOpInfo /*outerPrec*/) + { + auto funcExpr = callExpr->FunctionExpr; + + // We expect any subscript operation to be invoked as a member, + // so the function expression had better be in the correct form. + auto memberExpr = funcExpr.As<MemberExpr>(); + if(!memberExpr) + { + SLANG_UNEXPECTED("subscript needs base expression"); + } + + Emit("("); + EmitExpr(memberExpr->BaseExpression); + Emit(")["); + UInt argCount = callExpr->Arguments.Count(); + for (UInt aa = 0; aa < argCount; ++aa) + { + if (aa != 0) Emit(", "); + EmitExpr(callExpr->Arguments[aa]); + } + Emit("]"); + } + // Emit a call expression that doesn't involve any special cases, // just an expression of the form `f(a0, a1, ...)` void emitSimpleCallExpr( @@ -1632,6 +1658,18 @@ struct EmitVisitor emitSimpleConstructorCallExpr(callExpr, outerPrec); return; } + + if(auto acessorDeclRef = declRef.As<AccessorDecl>()) + { + declRef = acessorDeclRef.GetParent(); + } + + if(auto subscriptDeclRef = declRef.As<SubscriptDecl>()) + { + emitSimpleSubscriptCallExpr(callExpr, outerPrec); + return; + } + } // Once we've ruled out constructor calls, we can move on |
