diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-11-07 09:55:53 -0800 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-11-07 10:54:47 -0800 |
| commit | 97a1a95b6192599e038a26704756a914368f3d3a (patch) | |
| tree | c0d4d158cc248e04f38e68211638e08014d53112 /source/slang/emit.cpp | |
| parent | 722105feb1f11ea727af52bc5a484ddf4320e74d (diff) | |
Try to fix up IR emit for subscript calls
This code isn't especially useful right now since most of the important subscripts are still special-cased with `__intrinsic_op`, but the idea is that if we de-mangle an intrinsic operation's name and see it is called `operator[]` then we are probably calling a subscript, and should emit an appropriate expression.
Aside: this change has pointed out to me that our current name mangling isn't properly handling non-alphanumeric characters, so we'll be in trouble as soon as we have non-intrinsic subscripts, operators, etc.
Diffstat (limited to 'source/slang/emit.cpp')
| -rw-r--r-- | source/slang/emit.cpp | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 7e4fca4e5..615fb47a0 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -4664,7 +4664,7 @@ emitDeclImpl(decl, nullptr); expect("_S"); } - int readCount() + UInt readCount() { int c = peek(); if(!isDigit((char)c)) @@ -4822,15 +4822,50 @@ emitDeclImpl(decl, nullptr); IRCall* inst, IRFunc* func) { - // TODO: we need to inspect the mangled name, - // and construct a suitable expression from it... + // For a call with N arguments, the instruction will + // have N+1 operands. We will start consuming operands + // starting at the index 1. + UInt operandCount = inst->getArgCount(); + UInt argCount = operandCount - 1; + UInt operandIndex = 1; - UnmangleContext um(func->mangledName); + // Our current strategy for dealing with intrinsic + // calls is to "un-mangle" the mangled name, in + // order to figure out what the user was originally + // calling. This is a bit messy, and there might + // be better strategies (including just stuffing + // a pointer to the original decl onto the callee). + UnmangleContext um(func->mangledName); um.startUnmangling(); + // We'll read through the qualified name of the + // symbol (e.g., `Texture2D<T>.Sample`) and then + // only keep the last segment of the name (e.g., + // the `Sample` part). auto name = um.readSimpleName(); + // We will special-case some names here, that + // represent callable declarations that aren't + // ordinary functions, and thus may use different + // syntax. + if(name == "operator[]") + { + // The user is invoking a built-in subscript operator + emit("("); + emitIROperand(ctx, inst->getArg(operandIndex++)); + emit(")["); + emitIROperand(ctx, inst->getArg(operandIndex++)); + emit("]"); + + if(operandIndex < operandCount) + { + emit(" = "); + emitIROperand(ctx, inst->getArg(operandIndex++)); + } + return; + } + // The mangled function name currently records // the number of explicit parameters, and thus // doesn't include the implicit `this` parameter. @@ -4838,12 +4873,6 @@ emitDeclImpl(decl, nullptr); // to figure out whether we have a member function call. UInt paramCount = um.readParamCount(); - // For a call with N arguments, the instruction will - // have N+1 operands. - UInt operandCount = inst->getArgCount(); - UInt argCount = operandCount - 1; - UInt operandIndex = 1; - if(argCount != paramCount) { // Looks like a member function call |
