diff options
Diffstat (limited to 'source/slang/slang-emit-cpp.cpp')
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 100 |
1 files changed, 82 insertions, 18 deletions
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index 96b42af43..5df13cbde 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -1677,7 +1677,11 @@ void CPPSourceEmitter::emitWitnessTable(IRWitnessTable* witnessTable) if (isBuiltin(interfaceType)) return; - auto witnessTableItems = witnessTable->getChildren(); + if (interfaceType->findDecoration<IRComInterfaceDecoration>()) + { + pendingWitnessTableDefinitions.add(witnessTable); + return; + } // Declare a global variable for the witness table. m_writer->emit("extern \"C\" { "); @@ -1701,6 +1705,11 @@ void CPPSourceEmitter::_emitWitnessTableDefinitions() for (auto witnessTable : pendingWitnessTableDefinitions) { auto interfaceType = cast<IRInterfaceType>(witnessTable->getConformanceType()); + if (interfaceType->findDecoration<IRComInterfaceDecoration>()) + { + emitComWitnessTable(witnessTable); + continue; + } List<IRWitnessTableEntry*> sortedWitnessTableEntries = getSortedWitnessTableEntries(witnessTable); m_writer->emit("extern \"C\"\n{\n"); m_writer->indent(); @@ -1750,6 +1759,12 @@ void CPPSourceEmitter::_emitWitnessTableDefinitions() void CPPSourceEmitter::emitComInterface(IRInterfaceType* interfaceType) { + auto comDecoration = interfaceType->findDecoration<IRComInterfaceDecoration>(); + auto guidInst = as<IRStringLit>(comDecoration->getOperand(0)); + SLANG_RELEASE_ASSERT(guidInst); + auto guid = guidInst->getStringSlice(); + SLANG_RELEASE_ASSERT(guid.getLength() == 32); + m_writer->emit("struct "); emitSimpleType(interfaceType); m_writer->emit(" : "); @@ -1779,6 +1794,23 @@ void CPPSourceEmitter::emitComInterface(IRInterfaceType* interfaceType) // Emit methods. m_writer->emit("\n{\n"); m_writer->indent(); + // Emit GUID. + m_writer->emit("SLANG_COM_INTERFACE(0x"); + m_writer->emit(guid.subString(0, 8)); + m_writer->emit(", 0x"); + m_writer->emit(guid.subString(8, 4)); + m_writer->emit(", 0x"); + m_writer->emit(guid.subString(12, 4)); + m_writer->emit(", { "); + for (UInt i = 0; i < 8; i++) + { + if (i > 0) + m_writer->emit(", "); + m_writer->emit("0x"); + m_writer->emit(guid.subString(16 + i * 2, 2)); + } + m_writer->emit(" })\n"); + for (UInt i = 0; i < interfaceType->getOperandCount(); i++) { auto entry = as<IRInterfaceRequirementEntry>(interfaceType->getOperand(i)); @@ -2476,6 +2508,33 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut } return true; } + case kIROp_MakeExistential: + case kIROp_MakeExistentialWithRTTI: + { + auto rsType = cast<IRComPtrType>(inst->getDataType()); + m_writer->emit("ComPtr<"); + m_writer->emit(getName(rsType->getOperand(0))); + m_writer->emit(">("); + m_writer->emit("static_cast<"); + m_writer->emit(getName(rsType->getOperand(0))); + m_writer->emit("*>("); + auto prec = getInfo(EmitOp::Postfix); + emitOperand(inst->getOperand(0), leftSide(getInfo(EmitOp::General), prec)); + m_writer->emit(".Ptr()"); + m_writer->emit("))"); + return true; + } + case kIROp_GetValueFromBoundInterface: + { + m_writer->emit("static_cast<"); + m_writer->emit(getName(inst->getFullType())); + m_writer->emit("*>("); + auto prec = getInfo(EmitOp::Postfix); + emitOperand(inst->getOperand(0), leftSide(getInfo(EmitOp::General), prec)); + m_writer->emit(".get()"); + m_writer->emit(")"); + return true; + } } } @@ -2604,9 +2663,10 @@ void CPPSourceEmitter::emitVarDecorationsImpl(IRInst* inst) Super::emitVarDecorationsImpl(inst); } - -void CPPSourceEmitter::_maybeEmitExportLike(IRInst* inst) +void CPPSourceEmitter::_getExportStyle(IRInst* inst, bool& outIsExport, bool& outIsExternC) { + outIsExport = false; + outIsExternC = false; // Specially handle export, as we don't want to emit it multiple times if (getTargetReq()->isWholeProgramRequest()) { @@ -2619,34 +2679,38 @@ void CPPSourceEmitter::_maybeEmitExportLike(IRInst* inst) } } - bool isExternC = false; - bool isExported = false; - // If public/export made it externally visible for (auto decoration : inst->getDecorations()) { const auto op = decoration->getOp(); if (op == kIROp_ExternCppDecoration) { - isExternC = true; + outIsExternC = true; } else if (op == kIROp_PublicDecoration || op == kIROp_HLSLExportDecoration) { - isExported = true; + outIsExport = true; } } + } +} - // TODO(JS): Currently export *also* implies it's extern "C" and we can't list twice - if (isExported) - { - m_writer->emit("SLANG_PRELUDE_EXPORT\n"); - } - else if (isExternC) - { - // It's name is not manged. - m_writer->emit("extern \"C\"\n"); - } +void CPPSourceEmitter::_maybeEmitExportLike(IRInst* inst) +{ + bool isExternC = false; + bool isExported = false; + _getExportStyle(inst, isExternC, isExported); + + // TODO(JS): Currently export *also* implies it's extern "C" and we can't list twice + if (isExported) + { + m_writer->emit("SLANG_PRELUDE_EXPORT\n"); + } + else if (isExternC) + { + // It's name is not manged. + m_writer->emit("extern \"C\"\n"); } } |
