summaryrefslogtreecommitdiffstats
path: root/source/slang/emit.cpp
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 /source/slang/emit.cpp
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.
Diffstat (limited to 'source/slang/emit.cpp')
-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