diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-09-11 09:33:46 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-09-11 14:06:02 -0700 |
| commit | 2055d540c5dd420448a6924d784d5aed0efcd93d (patch) | |
| tree | 29167b8abb5001cd3c2803807ec5c8eb3bc2329f /source/slang/emit.cpp | |
| parent | 80fb7b05b851e645d821331fdbbcea1add686c9a (diff) | |
Support IR-based codegen for a few more examples.
The main interesting change here is around support for lowering of calls to "subscript" operations (what a C++ programmer would think of as `operator[]`).
An important infrastructure change here was to add an explicit AST-node representation for a "static member expression" which we use whenever a member is looked up in a type as opposed to a value. The implementation of this probably isn't robust yet, but it turns out to be important to be able to tell such cases apart.
Diffstat (limited to 'source/slang/emit.cpp')
| -rw-r--r-- | source/slang/emit.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index a0cf8eb19..f6c63dff6 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -2274,6 +2274,44 @@ struct EmitVisitor if(needClose) Emit(")"); } + void visitStaticMemberExpr(StaticMemberExpr* memberExpr, ExprEmitArg const& arg) + { + auto prec = kEOp_Postfix; + auto outerPrec = arg.outerPrec; + bool needClose = MaybeEmitParens(outerPrec, prec); + + // TODO(tfoley): figure out a good way to reference + // declarations that might be generic and/or might + // not be generated as lexically nested declarations... + + // TODO(tfoley): also, probably need to special case + // this for places where we are using a built-in... + + auto base = memberExpr->BaseExpression; + if (IsBaseExpressionImplicit(base)) + { + // don't emit the base expression + } + else + { + EmitExprWithPrecedence(memberExpr->BaseExpression, leftSide(outerPrec, prec)); + Emit("."); + } + + if (!memberExpr->declRef) + { + // This case arises when checking didn't find anything, but we were + // in "rewrite" mode so we blazed ahead anyway. + emitName(memberExpr->name); + } + else + { + emit(memberExpr->declRef.GetName()); + } + + if(needClose) Emit(")"); + } + void visitMemberExpr(MemberExpr* memberExpr, ExprEmitArg const& arg) { auto prec = kEOp_Postfix; @@ -4033,6 +4071,15 @@ emitDeclImpl(decl, nullptr); } break; + case kIROp_readWriteStructuredBufferType: + { + auto tt = (IRBufferType*) type; + emit("RWStructuredBuffer<"); + emitIRType(context, tt->getElementType(), nullptr); + emit(">"); + } + break; + case kIROp_SamplerType: { // TODO: actually look at the flavor and emit the right name @@ -4308,6 +4355,13 @@ emitDeclImpl(decl, nullptr); emitIROperand(context, inst->getArg(1)); break; + case kIROp_Store: + // TODO: this logic will really only work for a simple variable reference... + emitIROperand(context, inst->getArg(1)); + emit(" = "); + emitIROperand(context, inst->getArg(2)); + break; + case kIROp_Call: { emitIROperand(context, inst->getArg(1)); @@ -4322,6 +4376,13 @@ emitDeclImpl(decl, nullptr); } break; + case kIROp_BufferLoad: + emitIROperand(context, inst->getArg(1)); + emit("["); + emitIROperand(context, inst->getArg(2)); + emit("]"); + break; + default: emit("/* uhandled */"); break; @@ -4345,6 +4406,17 @@ emitDeclImpl(decl, nullptr); emit(";\n"); break; + case kIROp_Var: + { + auto ptrType = inst->getType(); + auto valType = ((IRPtrType*)ptrType)->getValueType(); + + auto name = getName(inst); + emitIRType(context, valType, name); + emit(";\n"); + } + break; + case kIROp_Param: // Don't emit parameters, since they are declared as part of the function. break; |
