diff options
Diffstat (limited to 'source/slang/slang-emit-cpp.cpp')
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 64 |
1 files changed, 35 insertions, 29 deletions
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index 4a59f4cf9..eeace4aa7 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -390,12 +390,27 @@ static UnownedStringSlice _getResourceTypePrefix(IROp op) } } +static bool isVoidPtrType(IRType* type) +{ + auto ptrType = as<IRPtrType>(type); + if (!ptrType) return false; + return ptrType->getValueType()->op == kIROp_VoidType; +} + SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, StringBuilder& out) { switch (type->op) { case kIROp_PtrType: { + if (isVoidPtrType(type)) + { + // A `void*` type will always emit as `void*`. + // `void*` types are generated as a result of generics lowering + // for dynamic dispatch. + out << "void*"; + return SLANG_OK; + } auto ptrType = static_cast<IRPtrType*>(type); SLANG_RETURN_ON_FAIL(calcTypeName(ptrType->getValueType(), target, out)); // TODO(JS): It seems although it says it is a pointer, it can actually be output as a reference @@ -494,7 +509,7 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S // struct of function pointers corresponding to the interface type. auto witnessTableType = static_cast<IRWitnessTableType*>(type); auto baseType = cast<IRType>(witnessTableType->getOperand(0)); - emitType(baseType); + SLANG_RETURN_ON_FAIL(calcTypeName(baseType, target, out)); out << "*"; return SLANG_OK; } @@ -1591,8 +1606,7 @@ void CPPSourceEmitter::emitWitnessTable(IRWitnessTable* witnessTable) { auto interfaceType = cast<IRInterfaceType>(witnessTable->getOperand(0)); auto witnessTableItems = witnessTable->getChildren(); - List<IRWitnessTableEntry*> sortedWitnessTableEntries = getSortedWitnessTableEntries(witnessTable); - _maybeEmitWitnessTableTypeDefinition(interfaceType, sortedWitnessTableEntries); + _maybeEmitWitnessTableTypeDefinition(interfaceType); // Define a global variable for the witness table. m_writer->emit("extern "); @@ -1747,17 +1761,16 @@ void CPPSourceEmitter::emitInterface(IRInterfaceType* interfaceType) /// acoording to the order defined by `interfaceType`. /// void CPPSourceEmitter::_maybeEmitWitnessTableTypeDefinition( - IRInterfaceType* interfaceType, - const List<IRWitnessTableEntry*>& sortedWitnessTableEntries) + IRInterfaceType* interfaceType) { m_writer->emit("struct "); emitSimpleType(interfaceType); m_writer->emit("\n{\n"); m_writer->indent(); - for (Index i = 0; i < sortedWitnessTableEntries.getCount(); i++) + for (UInt i = 0; i < interfaceType->getOperandCount(); i++) { - auto entry = sortedWitnessTableEntries[i]; - if (auto funcVal = as<IRFunc>(entry->satisfyingVal.get())) + auto entry = as<IRInterfaceRequirementEntry>(interfaceType->getOperand(i)); + if (auto funcVal = as<IRFuncType>(entry->getRequirementVal())) { emitType(funcVal->getResultType()); m_writer->emit(" (KernelContext::*"); @@ -1765,33 +1778,35 @@ void CPPSourceEmitter::_maybeEmitWitnessTableTypeDefinition( m_writer->emit(")"); m_writer->emit("("); bool isFirstParam = true; - for (auto param : funcVal->getParams()) + for (UInt p = 0; p < funcVal->getParamCount(); p++) { + auto paramType = funcVal->getParamType(p); + // Ingore TypeType-typed parameters for now. + if (as<IRTypeType>(paramType)) + continue; + if (!isFirstParam) m_writer->emit(", "); else isFirstParam = false; - if (param->findDecoration<IRThisPointerDecoration>()) + auto thisDecor = funcVal->findDecoration<IRThisPointerDecoration>(); + if (thisDecor && cast<IRIntLit>(thisDecor->getOperand(0))->value.intVal == (IRIntegerValue)p) { - m_writer->emit("void* "); - m_writer->emit(getName(param)); + m_writer->emit("void* param"); + m_writer->emit(p); continue; } - emitSimpleFuncParamImpl(param); + emitParamType(paramType, String("param") + String(p)); } m_writer->emit(");\n"); } - else if (auto witnessTableVal = as<IRWitnessTable>(entry->getSatisfyingVal())) + else if (auto constraintInterfaceType = as<IRInterfaceType>(entry->getRequirementVal())) { - emitType(as<IRType>(witnessTableVal->getOperand(0))); + emitType(constraintInterfaceType); m_writer->emit("* "); m_writer->emit(getName(entry->requirementKey.get())); m_writer->emit(";\n"); } - else - { - // TODO: handle other witness table entry types. - } } m_writer->dedent(); m_writer->emit("};\n"); @@ -1990,13 +2005,6 @@ void CPPSourceEmitter::emitSimpleValueImpl(IRInst* inst) } } -static bool isVoidPtrType(IRType* type) -{ - auto ptrType = as<IRPtrType>(type); - if (!ptrType) return false; - return ptrType->getValueType()->op == kIROp_VoidType; -} - void CPPSourceEmitter::emitSimpleFuncParamImpl(IRParam* param) { // Polymorphic types are already translated to void* type in @@ -2004,9 +2012,7 @@ void CPPSourceEmitter::emitSimpleFuncParamImpl(IRParam* param) // emit "void&" instead of "void*" for pointer types. // In the future, we will handle pointer types more properly, // and this override logic will not be necessary. - // For now we special-case this scenario. - if (param->findDecoration<IRPolymorphicDecoration>() && - isVoidPtrType(param->getDataType())) + if (isVoidPtrType(param->getDataType())) { m_writer->emit("void* "); m_writer->emit(getName(param)); |
