diff --git a/c-opopt.cc b/c-opopt.cc index 21248a4..c85a226 100644 --- a/c-opopt.cc +++ b/c-opopt.cc @@ -366,15 +366,15 @@ namespace { void BUDCAddUseRecord_( A_Node& n , + T_String const& id , T_OptData& od , T_RootNode& root ) noexcept { // Find instruction and function index - auto& nId{ dynamic_cast< T_IdentifierExprNode& >( n ) }; A_FuncNode* func{ nullptr }; T_Optional< uint32_t > instrId; - A_Node* pn{ &nId }; + A_Node* pn{ &n }; while ( pn ) { auto* const asInstr{ dynamic_cast< A_InstructionNode* >( pn ) }; func = dynamic_cast< A_FuncNode* >( pn ); @@ -389,10 +389,10 @@ void BUDCAddUseRecord_( // Generate the identifier const T_OptData::T_VarId varId{ [&]() { - auto const& n{ nId.id( ) }; - if ( func->hasLocal( nId.id( ) ) ) { + auto const& n{ id }; + if ( func->hasLocal( id ) ) { return T_OptData::T_VarId{ n , func->name( ) , - func->isArgument( nId.id( ) ) }; + func->isArgument( id ) }; } return T_OptData::T_VarId{ n }; } () }; @@ -415,7 +415,7 @@ void BUDCAddUseRecord_( od.logger( [&](){ T_StringBuilder sb; - sb << "use " << varId.name << " at " << nId.location( ) << " ("; + sb << "use " << varId.name << " at " << n.location( ) << " ("; if ( varId.type == T_OptData::E_UDVarType::GLOBAL ) { sb << "global"; } else { @@ -459,8 +459,57 @@ void T_OptData::buildUseDefineChains( * looking at the call sites. */ visitor.visit( program.root , [&]( auto& n , const bool exit ) { - if ( n.type( ) == A_Node::EXPR_ID && !exit ) { - BUDCAddUseRecord_( n , *this , program.root ); + if ( exit ) { + return true; + } + + switch ( n.type( ) ) { + + default: break; + + case A_Node::EXPR_ID: + BUDCAddUseRecord_( n , + dynamic_cast< T_IdentifierExprNode& >( n ).id( ) , + *this , program.root ); + break; + + case A_Node::OP_UNIFORMS: + BUDCAddUseRecord_( n , + dynamic_cast< T_UniformsInstrNode& >( n ).progId( ) , + *this , program.root ); + break; + + case A_Node::OP_USE_TEXTURE: + BUDCAddUseRecord_( n , + dynamic_cast< T_UseTextureInstrNode& >( n ).samplerId( ) , + *this , program.root ); + // fallthrough + case A_Node::OP_USE_PROGRAM: + case A_Node::OP_USE_PIPELINE: + case A_Node::OP_USE_FRAMEBUFFER: + BUDCAddUseRecord_( n , + dynamic_cast< T_UseInstrNode& >( n ).id( ) , + *this , program.root ); + break; + + case A_Node::OP_PIPELINE: { + auto& pln{ dynamic_cast< T_PipelineInstrNode& >( n ) }; + // XXX decl + const auto np{ pln.size( ) }; + for ( auto i = 0u ; i < np ; i ++ ) { + BUDCAddUseRecord_( n , pln.program( i ) , + *this , program.root ); + } + break; + } + + case A_Node::TN_FBATT: { + auto& fbn{ dynamic_cast< T_FramebufferInstrNode::T_Attachment& >( n ) }; + BUDCAddUseRecord_( n , fbn.id( ) , + *this , program.root ); + break; + } + } return true;