summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-11-07 09:55:53 -0800
committerTim Foley <tfoley@nvidia.com>2017-11-07 10:54:47 -0800
commit97a1a95b6192599e038a26704756a914368f3d3a (patch)
treec0d4d158cc248e04f38e68211638e08014d53112
parent722105feb1f11ea727af52bc5a484ddf4320e74d (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.
-rw-r--r--source/slang/emit.cpp49
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