@@ -390,12 +390,27 @@ static UnownedStringSlice _getResourceTypePrefix(IROp op)
390
390
}
391
391
}
392
392
393
+ static bool isVoidPtrType (IRType* type)
394
+ {
395
+ auto ptrType = as<IRPtrType>(type);
396
+ if (!ptrType) return false ;
397
+ return ptrType->getValueType ()->op == kIROp_VoidType ;
398
+ }
399
+
393
400
SlangResult CPPSourceEmitter::calcTypeName (IRType* type, CodeGenTarget target, StringBuilder& out)
394
401
{
395
402
switch (type->op )
396
403
{
397
404
case kIROp_PtrType :
398
405
{
406
+ if (isVoidPtrType (type))
407
+ {
408
+ // A `void*` type will always emit as `void*`.
409
+ // `void*` types are generated as a result of generics lowering
410
+ // for dynamic dispatch.
411
+ out << " void*" ;
412
+ return SLANG_OK;
413
+ }
399
414
auto ptrType = static_cast <IRPtrType*>(type);
400
415
SLANG_RETURN_ON_FAIL (calcTypeName (ptrType->getValueType (), target, out));
401
416
// 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
494
509
// struct of function pointers corresponding to the interface type.
495
510
auto witnessTableType = static_cast <IRWitnessTableType*>(type);
496
511
auto baseType = cast<IRType>(witnessTableType->getOperand (0 ));
497
- emitType ( baseType);
512
+ SLANG_RETURN_ON_FAIL ( calcTypeName ( baseType, target, out) );
498
513
out << " *" ;
499
514
return SLANG_OK;
500
515
}
@@ -1591,8 +1606,7 @@ void CPPSourceEmitter::emitWitnessTable(IRWitnessTable* witnessTable)
1591
1606
{
1592
1607
auto interfaceType = cast<IRInterfaceType>(witnessTable->getOperand (0 ));
1593
1608
auto witnessTableItems = witnessTable->getChildren ();
1594
- List<IRWitnessTableEntry*> sortedWitnessTableEntries = getSortedWitnessTableEntries (witnessTable);
1595
- _maybeEmitWitnessTableTypeDefinition (interfaceType, sortedWitnessTableEntries);
1609
+ _maybeEmitWitnessTableTypeDefinition (interfaceType);
1596
1610
1597
1611
// Define a global variable for the witness table.
1598
1612
m_writer->emit (" extern " );
@@ -1747,51 +1761,52 @@ void CPPSourceEmitter::emitInterface(IRInterfaceType* interfaceType)
1747
1761
// / acoording to the order defined by `interfaceType`.
1748
1762
// /
1749
1763
void CPPSourceEmitter::_maybeEmitWitnessTableTypeDefinition (
1750
- IRInterfaceType* interfaceType,
1751
- const List<IRWitnessTableEntry*>& sortedWitnessTableEntries)
1764
+ IRInterfaceType* interfaceType)
1752
1765
{
1753
1766
m_writer->emit (" struct " );
1754
1767
emitSimpleType (interfaceType);
1755
1768
m_writer->emit (" \n {\n " );
1756
1769
m_writer->indent ();
1757
- for (Index i = 0 ; i < sortedWitnessTableEntries. getCount (); i++)
1770
+ for (UInt i = 0 ; i < interfaceType-> getOperandCount (); i++)
1758
1771
{
1759
- auto entry = sortedWitnessTableEntries[i] ;
1760
- if (auto funcVal = as<IRFunc >(entry->satisfyingVal . get ()))
1772
+ auto entry = as<IRInterfaceRequirementEntry>(interfaceType-> getOperand (i)) ;
1773
+ if (auto funcVal = as<IRFuncType >(entry->getRequirementVal ()))
1761
1774
{
1762
1775
emitType (funcVal->getResultType ());
1763
1776
m_writer->emit (" (KernelContext::*" );
1764
1777
m_writer->emit (getName (entry->requirementKey .get ()));
1765
1778
m_writer->emit (" )" );
1766
1779
m_writer->emit (" (" );
1767
1780
bool isFirstParam = true ;
1768
- for (auto param : funcVal->getParams () )
1781
+ for (UInt p = 0 ; p < funcVal->getParamCount (); p++ )
1769
1782
{
1783
+ auto paramType = funcVal->getParamType (p);
1784
+ // Ingore TypeType-typed parameters for now.
1785
+ if (as<IRTypeType>(paramType))
1786
+ continue ;
1787
+
1770
1788
if (!isFirstParam)
1771
1789
m_writer->emit (" , " );
1772
1790
else
1773
1791
isFirstParam = false ;
1774
- if (param->findDecoration <IRThisPointerDecoration>())
1792
+ auto thisDecor = funcVal->findDecoration <IRThisPointerDecoration>();
1793
+ if (thisDecor && cast<IRIntLit>(thisDecor->getOperand (0 ))->value .intVal == (IRIntegerValue)p)
1775
1794
{
1776
- m_writer->emit (" void* " );
1777
- m_writer->emit (getName (param) );
1795
+ m_writer->emit (" void* param " );
1796
+ m_writer->emit (p );
1778
1797
continue ;
1779
1798
}
1780
- emitSimpleFuncParamImpl ( param);
1799
+ emitParamType (paramType, String ( " param" ) + String (p) );
1781
1800
}
1782
1801
m_writer->emit (" );\n " );
1783
1802
}
1784
- else if (auto witnessTableVal = as<IRWitnessTable >(entry->getSatisfyingVal ()))
1803
+ else if (auto constraintInterfaceType = as<IRInterfaceType >(entry->getRequirementVal ()))
1785
1804
{
1786
- emitType (as<IRType>(witnessTableVal-> getOperand ( 0 )) );
1805
+ emitType (constraintInterfaceType );
1787
1806
m_writer->emit (" * " );
1788
1807
m_writer->emit (getName (entry->requirementKey .get ()));
1789
1808
m_writer->emit (" ;\n " );
1790
1809
}
1791
- else
1792
- {
1793
- // TODO: handle other witness table entry types.
1794
- }
1795
1810
}
1796
1811
m_writer->dedent ();
1797
1812
m_writer->emit (" };\n " );
@@ -1990,23 +2005,14 @@ void CPPSourceEmitter::emitSimpleValueImpl(IRInst* inst)
1990
2005
}
1991
2006
}
1992
2007
1993
- static bool isVoidPtrType (IRType* type)
1994
- {
1995
- auto ptrType = as<IRPtrType>(type);
1996
- if (!ptrType) return false ;
1997
- return ptrType->getValueType ()->op == kIROp_VoidType ;
1998
- }
1999
-
2000
2008
void CPPSourceEmitter::emitSimpleFuncParamImpl (IRParam* param)
2001
2009
{
2002
2010
// Polymorphic types are already translated to void* type in
2003
2011
// lower-generics pass. However, the current emitting logic will
2004
2012
// emit "void&" instead of "void*" for pointer types.
2005
2013
// In the future, we will handle pointer types more properly,
2006
2014
// and this override logic will not be necessary.
2007
- // For now we special-case this scenario.
2008
- if (param->findDecoration <IRPolymorphicDecoration>() &&
2009
- isVoidPtrType (param->getDataType ()))
2015
+ if (isVoidPtrType (param->getDataType ()))
2010
2016
{
2011
2017
m_writer->emit (" void* " );
2012
2018
m_writer->emit (getName (param));
0 commit comments