@@ -1446,6 +1446,24 @@ UnownedStringSlice CPPSourceEmitter::_getFuncName(const HLSLIntrinsic* specOp)
1446
1446
return m_slicePool.getSlice (handle);
1447
1447
}
1448
1448
1449
+ UnownedStringSlice CPPSourceEmitter::_getWitnessTableWrapperFuncName (IRFunc* func)
1450
+ {
1451
+ StringSlicePool::Handle handle = StringSlicePool::kNullHandle ;
1452
+ if (m_witnessTableWrapperFuncNameMap.TryGetValue (func, handle))
1453
+ {
1454
+ return m_slicePool.getSlice (handle);
1455
+ }
1456
+
1457
+ StringBuilder builder;
1458
+ builder << getName (func) << " _wtwrapper" ;
1459
+
1460
+ handle = m_slicePool.add (builder);
1461
+ m_witnessTableWrapperFuncNameMap.Add (func, handle);
1462
+
1463
+ SLANG_ASSERT (handle != StringSlicePool::kNullHandle );
1464
+ return m_slicePool.getSlice (handle);
1465
+ }
1466
+
1449
1467
SlangResult CPPSourceEmitter::calcFuncName (const HLSLIntrinsic* specOp, StringBuilder& outBuilder)
1450
1468
{
1451
1469
typedef HLSLIntrinsic::Op Op;
@@ -1591,6 +1609,83 @@ void CPPSourceEmitter::emitWitnessTable(IRWitnessTable* witnessTable)
1591
1609
pendingWitnessTableDefinitions.add (witnessTable);
1592
1610
}
1593
1611
1612
+ void CPPSourceEmitter::_emitWitnessTableWrappers ()
1613
+ {
1614
+ for (auto witnessTable : pendingWitnessTableDefinitions)
1615
+ {
1616
+ for (auto child : witnessTable->getChildren ())
1617
+ {
1618
+ if (auto entry = as<IRWitnessTableEntry>(child))
1619
+ {
1620
+ if (auto funcVal = as<IRFunc>(entry->getSatisfyingVal ()))
1621
+ {
1622
+ emitType (funcVal->getResultType ());
1623
+ m_writer->emit (" " );
1624
+ m_writer->emit (_getWitnessTableWrapperFuncName (funcVal));
1625
+ m_writer->emit (" (" );
1626
+ // Emit parameter list.
1627
+ {
1628
+ bool isFirst = true ;
1629
+ for (auto param : funcVal->getParams ())
1630
+ {
1631
+ if (as<IRTypeType>(param->getFullType ()))
1632
+ continue ;
1633
+
1634
+ if (isFirst)
1635
+ isFirst = false ;
1636
+ else
1637
+ m_writer->emit (" ," );
1638
+
1639
+ if (param->findDecoration <IRThisPointerDecoration>())
1640
+ {
1641
+ m_writer->emit (" void* " );
1642
+ m_writer->emit (getName (param));
1643
+ continue ;
1644
+ }
1645
+ emitSimpleFuncParamImpl (param);
1646
+ }
1647
+ }
1648
+ m_writer->emit (" )\n {\n " );
1649
+ m_writer->indent ();
1650
+ m_writer->emit (" return " );
1651
+ m_writer->emit (getName (funcVal));
1652
+ m_writer->emit (" (" );
1653
+ // Emit argument list.
1654
+ {
1655
+ bool isFirst = true ;
1656
+ for (auto param : funcVal->getParams ())
1657
+ {
1658
+ if (as<IRTypeType>(param->getFullType ()))
1659
+ continue ;
1660
+
1661
+ if (isFirst)
1662
+ isFirst = false ;
1663
+ else
1664
+ m_writer->emit (" , " );
1665
+
1666
+ if (param->findDecoration <IRThisPointerDecoration>())
1667
+ {
1668
+ m_writer->emit (" *static_cast<" );
1669
+ emitType (param->getFullType ());
1670
+ m_writer->emit (" *>(" );
1671
+ m_writer->emit (getName (param));
1672
+ m_writer->emit (" )" );
1673
+ }
1674
+ else
1675
+ {
1676
+ m_writer->emit (getName (param));
1677
+ }
1678
+ }
1679
+ }
1680
+ m_writer->emit (" );\n " );
1681
+ m_writer->dedent ();
1682
+ m_writer->emit (" }\n " );
1683
+ }
1684
+ }
1685
+ }
1686
+ }
1687
+ }
1688
+
1594
1689
void CPPSourceEmitter::_emitWitnessTableDefinitions ()
1595
1690
{
1596
1691
for (auto witnessTable : pendingWitnessTableDefinitions)
@@ -1613,7 +1708,7 @@ void CPPSourceEmitter::_emitWitnessTableDefinitions()
1613
1708
else
1614
1709
isFirstEntry = false ;
1615
1710
m_writer->emit (" &Context::" );
1616
- m_writer->emit (getName (funcVal));
1711
+ m_writer->emit (_getWitnessTableWrapperFuncName (funcVal));
1617
1712
}
1618
1713
else
1619
1714
{
@@ -1671,7 +1766,13 @@ void CPPSourceEmitter::_maybeEmitWitnessTableTypeDefinition(
1671
1766
m_writer->emit (" , " );
1672
1767
else
1673
1768
isFirstParam = false ;
1674
- emitParamType (param->getFullType (), getName (param));
1769
+ if (param->findDecoration <IRThisPointerDecoration>())
1770
+ {
1771
+ m_writer->emit (" void* " );
1772
+ m_writer->emit (getName (param));
1773
+ continue ;
1774
+ }
1775
+ emitSimpleFuncParamImpl (param);
1675
1776
}
1676
1777
m_writer->emit (" );\n " );
1677
1778
}
@@ -1681,7 +1782,7 @@ void CPPSourceEmitter::_maybeEmitWitnessTableTypeDefinition(
1681
1782
}
1682
1783
}
1683
1784
m_writer->dedent ();
1684
- m_writer->emit (" \n };\n " );
1785
+ m_writer->emit (" };\n " );
1685
1786
}
1686
1787
1687
1788
bool CPPSourceEmitter::tryEmitGlobalParamImpl (IRGlobalParam* varDecl, IRType* varType)
@@ -1877,6 +1978,31 @@ void CPPSourceEmitter::emitSimpleValueImpl(IRInst* inst)
1877
1978
}
1878
1979
}
1879
1980
1981
+ static bool isVoidPtrType (IRType* type)
1982
+ {
1983
+ auto ptrType = as<IRPtrType>(type);
1984
+ if (!ptrType) return false ;
1985
+ return ptrType->getValueType ()->op == kIROp_VoidType ;
1986
+ }
1987
+
1988
+ void CPPSourceEmitter::emitSimpleFuncParamImpl (IRParam* param)
1989
+ {
1990
+ // Polymorphic types are already translated to void* type in
1991
+ // lower-generics pass. However, the current emitting logic will
1992
+ // emit "void&" instead of "void*" for pointer types.
1993
+ // In the future, we will handle pointer types more properly,
1994
+ // and this override logic will not be necessary.
1995
+ // For now we special-case this scenario.
1996
+ if (param->findDecoration <IRPolymorphicDecoration>() &&
1997
+ isVoidPtrType (param->getDataType ()))
1998
+ {
1999
+ m_writer->emit (" void* " );
2000
+ m_writer->emit (getName (param));
2001
+ return ;
2002
+ }
2003
+ CLikeSourceEmitter::emitSimpleFuncParamImpl (param);
2004
+ }
2005
+
1880
2006
void CPPSourceEmitter::emitVectorTypeNameImpl (IRType* elementType, IRIntegerValue elementCount)
1881
2007
{
1882
2008
emitSimpleType (m_typeSet.addVectorType (elementType, int (elementCount)));
@@ -2102,6 +2228,16 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
2102
2228
m_writer->emit (" )" );
2103
2229
return true ;
2104
2230
}
2231
+ case kIROp_getAddr :
2232
+ {
2233
+ // Once we clean up the pointer emitting logic, we can
2234
+ // just use GetElementAddress instruction in place of
2235
+ // getAddr instruction, and this case can be removed.
2236
+ m_writer->emit (" (&(" );
2237
+ emitInstExpr (inst->getOperand (0 ), EmitOpInfo::get (EmitOp::General));
2238
+ m_writer->emit (" ))" );
2239
+ return true ;
2240
+ }
2105
2241
}
2106
2242
}
2107
2243
@@ -2658,6 +2794,11 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module)
2658
2794
}
2659
2795
}
2660
2796
2797
+ // Emit wrapper functions for each witness table entry.
2798
+ // These wrapper functions takes an abstract type parameter (void*)
2799
+ // in the place of `this` parameter.
2800
+ _emitWitnessTableWrappers ();
2801
+
2661
2802
m_writer->dedent ();
2662
2803
m_writer->emit (" };\n\n " );
2663
2804
}
0 commit comments