summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-emit-cpp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-emit-cpp.cpp')
-rw-r--r--source/slang/slang-emit-cpp.cpp109
1 files changed, 53 insertions, 56 deletions
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 4a59f4cf9..7f743d9e0 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -494,10 +494,15 @@ 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;
}
+ case kIROp_RawPointerType:
+ {
+ out << "void*";
+ return SLANG_OK;
+ }
default:
{
if (isNominalOp(type->op))
@@ -1591,8 +1596,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 ");
@@ -1613,12 +1617,27 @@ void CPPSourceEmitter::_emitWitnessTableWrappers()
{
for (auto witnessTable : pendingWitnessTableDefinitions)
{
+ auto interfaceType = cast<IRInterfaceType>(witnessTable->getOperand(0));
for (auto child : witnessTable->getChildren())
{
if (auto entry = as<IRWitnessTableEntry>(child))
{
if (auto funcVal = as<IRFunc>(entry->getSatisfyingVal()))
{
+ IRInst* requirementVal = nullptr;
+ for (UInt i = 0; i < interfaceType->getOperandCount(); i++)
+ {
+ if (auto reqEntry = as<IRInterfaceRequirementEntry>(interfaceType->getOperand(i)))
+ {
+ if (reqEntry->getRequirementKey() == entry->getRequirementKey())
+ {
+ requirementVal = reqEntry->getRequirementVal();
+ break;
+ }
+ }
+ }
+ SLANG_ASSERT(requirementVal != nullptr);
+ IRFuncType* requirementFuncType = cast<IRFuncType>(requirementVal);
emitType(funcVal->getResultType());
m_writer->emit(" ");
m_writer->emit(_getWitnessTableWrapperFuncName(funcVal));
@@ -1626,23 +1645,20 @@ void CPPSourceEmitter::_emitWitnessTableWrappers()
// Emit parameter list.
{
bool isFirst = true;
- for (auto param : funcVal->getParams())
+ SLANG_ASSERT(funcVal->getParamCount() == requirementFuncType->getParamCount());
+ auto pp = funcVal->getParams().begin();
+ for (UInt i = 0; i < requirementFuncType->getParamCount(); ++i, ++pp)
{
- if (as<IRTypeType>(param->getFullType()))
+ auto paramType = requirementFuncType->getParamType(i);
+
+ if (as<IRTypeType>(paramType))
continue;
if (isFirst)
isFirst = false;
else
m_writer->emit(",");
-
- if (param->findDecoration<IRThisPointerDecoration>())
- {
- m_writer->emit("void* ");
- m_writer->emit(getName(param));
- continue;
- }
- emitSimpleFuncParamImpl(param);
+ emitParamType(paramType, getName(*pp));
}
}
m_writer->emit(")\n{\n");
@@ -1653,8 +1669,13 @@ void CPPSourceEmitter::_emitWitnessTableWrappers()
// Emit argument list.
{
bool isFirst = true;
- for (auto param : funcVal->getParams())
+ UInt paramIndex = 0;
+ for (auto defParamIter = funcVal->getParams().begin();
+ defParamIter!=funcVal->getParams().end();
+ ++defParamIter, ++paramIndex)
{
+ auto param = *defParamIter;
+ auto reqParamType = requirementFuncType->getParamType(paramIndex);
if (as<IRTypeType>(param->getFullType()))
continue;
@@ -1663,7 +1684,8 @@ void CPPSourceEmitter::_emitWitnessTableWrappers()
else
m_writer->emit(", ");
- if (param->findDecoration<IRThisPointerDecoration>())
+ if (reqParamType->op == kIROp_RawPointerType &&
+ param->getFullType()->op != kIROp_RawPointerType)
{
m_writer->emit("*static_cast<");
emitType(param->getFullType());
@@ -1747,51 +1769,46 @@ 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::*");
- m_writer->emit(getName(entry->requirementKey.get()));
+ m_writer->emit(getName(entry->getRequirementKey()));
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>())
- {
- m_writer->emit("void* ");
- m_writer->emit(getName(param));
- continue;
- }
- emitSimpleFuncParamImpl(param);
+
+ emitParamType(paramType, String("param") + String(p));
}
m_writer->emit(");\n");
}
- else if (auto witnessTableVal = as<IRWitnessTable>(entry->getSatisfyingVal()))
+ else if (auto witnessTableType = as<IRWitnessTableType>(entry->getRequirementVal()))
{
- emitType(as<IRType>(witnessTableVal->getOperand(0)));
+ emitType((IRType*)witnessTableType->getConformanceType());
m_writer->emit("* ");
- m_writer->emit(getName(entry->requirementKey.get()));
+ m_writer->emit(getName(entry->getRequirementKey()));
m_writer->emit(";\n");
}
- else
- {
- // TODO: handle other witness table entry types.
- }
}
m_writer->dedent();
m_writer->emit("};\n");
@@ -1990,28 +2007,8 @@ 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
- // lower-generics pass. However, the current emitting logic will
- // 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()))
- {
- m_writer->emit("void* ");
- m_writer->emit(getName(param));
- return;
- }
CLikeSourceEmitter::emitSimpleFuncParamImpl(param);
}