diff options
Diffstat (limited to 'source/slang/slang-emit-cpp.cpp')
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 76 |
1 files changed, 70 insertions, 6 deletions
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index 1ff5af4fb..54c2257f2 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -394,6 +394,8 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S { switch (type->op) { + case kIROp_OutType: + case kIROp_InOutType: case kIROp_PtrType: { auto ptrType = static_cast<IRPtrType*>(type); @@ -496,6 +498,7 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S return SLANG_OK; } case kIROp_RawPointerType: + case kIROp_RTTIPointerType: { out << "void*"; return SLANG_OK; @@ -510,6 +513,11 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S out << "*"; return SLANG_OK; } + case kIROp_RTTIType: + { + out << "TypeInfo"; + return SLANG_OK; + } default: { if (isNominalOp(type->op)) @@ -1692,14 +1700,35 @@ void CPPSourceEmitter::_emitWitnessTableWrappers() else m_writer->emit(", "); + // If the implementation expects a concrete type + // (either in the form of a pointer for `out`/`inout` parameters, + // or in the form a a value for `in` parameters, while + // the interface exposes a raw pointer type (void*), + // we need to cast the raw pointer type to the appropriate + // concerete type. (void*->Concrete* / void*->Concrete&). if (reqParamType->op == kIROp_RawPointerType && - param->getFullType()->op != kIROp_RawPointerType) + param->getDataType()->op != kIROp_RawPointerType) { - m_writer->emit("*static_cast<"); - emitType(param->getFullType()); - m_writer->emit("*>("); - m_writer->emit(getName(param)); - m_writer->emit(")"); + if (as<IRPtrTypeBase>(param->getFullType())) + { + // The implementation function expects a pointer to the + // concrete type. This is the case for inout/out parameters. + m_writer->emit("static_cast<"); + emitType(param->getFullType()); + m_writer->emit(">("); + m_writer->emit(getName(param)); + m_writer->emit(")"); + } + else + { + // The implementation function expects just a value of the + // concrete type. We need to insert a dereference in this case. + m_writer->emit("*static_cast<"); + emitType(param->getFullType()); + m_writer->emit("*>("); + m_writer->emit(getName(param)); + m_writer->emit(")"); + } } else { @@ -1773,6 +1802,18 @@ void CPPSourceEmitter::emitInterface(IRInterfaceType* interfaceType) m_writer->emit(";\n"); } +void CPPSourceEmitter::emitRTTIObject(IRRTTIObject* rttiObject) +{ + m_writer->emit("static TypeInfo "); + m_writer->emit(getName(rttiObject)); + m_writer->emit(" = {"); + auto typeSizeDecoration = rttiObject->findDecoration<IRRTTITypeSizeDecoration>(); + SLANG_ASSERT(typeSizeDecoration); + m_writer->emit(typeSizeDecoration->getTypeSize()); + m_writer->emit("};\n"); +} + + /// Emits witness table type definition given a sorted list of witness tables /// acoording to the order defined by `interfaceType`. /// @@ -2273,6 +2314,29 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut m_writer->emit("))"); return true; } + case kIROp_RTTIObject: + { + m_writer->emit(getName(inst)); + return true; + } + case kIROp_Alloca: + { + m_writer->emit("alloca("); + emitOperand(inst->getOperand(0), EmitOpInfo::get(EmitOp::Postfix)); + m_writer->emit("->typeSize)"); + return true; + } + case kIROp_Copy: + { + m_writer->emit("memcpy("); + emitOperand(inst->getOperand(0), EmitOpInfo::get(EmitOp::General)); + m_writer->emit(", "); + emitOperand(inst->getOperand(1), EmitOpInfo::get(EmitOp::General)); + m_writer->emit(", "); + emitOperand(inst->getOperand(2), EmitOpInfo::get(EmitOp::Postfix)); + m_writer->emit("->typeSize)"); + return true; + } } } |
