//! init virtual fucntion inheritance void Classhierarchy::inheritVirtualFunctions() { // prepare LUT for multiple declarations //map<SgNode *, set<SgNode *> > multDec; property_map< dbgType, boost::vertex_classhierarchy_t>::type chMap = boost::get( boost::vertex_classhierarchy, *this ); graph_traits< dbgType >::vertex_iterator vi,vend; tie(vi,vend) = vertices( *this ); //graph_traits< dbgType >::vertex_descriptor par=*vi, succ=*vi; // output info for(; vi!=vend; vi++) { //cerr << " BCH v i"<< get(vertex_index,*this,*vi)<< " i1" << get(vertex_index1, *this, *vi)<<","<< get(vertex_name, *this, *vi) << endl; for( set<SgNode*>::iterator chd= chMap[*vi].defined.begin(); chd!= chMap[*vi].defined.end(); chd++) { SgFunctionDeclaration *funcDec = isSgFunctionDeclaration( *chd ); //cerr << " BCH chd " << funcDec->get_mangled_name().str()<< endl; // debug //cerr << " BCH chd " << funcDec->get_mangled_name().str()<< " "<< (int)funcDec->get_type() << endl; // debug } } // search for multiple declarations tie(vi,vend) = vertices( *this ); for(; vi!=vend; vi++) { for(set<SgNode*>::iterator chd= chMap[*vi].defined.begin(); chd!= chMap[*vi].defined.end(); chd++) { SgFunctionDeclaration *funcDec = isSgFunctionDeclaration( *chd ); bool found = true; while(found) { found = false; for(set<SgNode*>::iterator chdComp = chMap[*vi].defined.begin(); (chdComp!= chMap[*vi].defined.end())&&(!found); ) { SgFunctionDeclaration *compDec = isSgFunctionDeclaration( *chdComp ); if(chdComp != chd) { //if( compDec->get_type() == funcDec->get_type() ) { // ??? TODO fix type comparison? if(compareFunctionDeclarations(compDec, funcDec)) { //cerr << " BCH REM " << funcDec->get_mangled_name().str()<< " " << compDec->get_mangled_name().str() << endl; // debug chMap[*vi].multDeclarations[ funcDec ].insert( compDec ); found = true; chMap[*vi].defined.erase( chdComp ); // should return new iterator in newer STL standard?? //chVertexData::iterator chdComp2 = (chMap[*vi]).erase( chdComp ); //chdComp = chdComp2; //cerr << " BCH removing i"<< get(vertex_index,*this,*vi)<< " i1" << get(vertex_index1, *this, *vi)<<","<< get(vertex_name, *this, *vi) << endl; } } if(!found) chdComp++; } } // found } //if( get( vertex_dbg_data, *this , *vi).get_id() == edges[i].get_sourceId() ) { //par = *vi; //parFound = true; //} } //typedef std::deque< boostVert > container; //cerr << " TOPO START " << endl; std::deque< dbgVertex > torder; try { boost::topological_sort(*this, std::back_inserter(torder)); } catch(boost::not_a_dag) { cerr << "CH - BOOST ERROR: NOT A DAG!!!!!??? " << endl; assert( false ); return; } //cerr << " TOPO END " << endl; //cerr << " -- " << endl; // debug for( std::deque< dbgVertex >::iterator vi=torder.begin(); vi!=torder.end(); vi++) { dbgVertex srcVert = *vi; // current vertex in the topo order //cerr << "XTOPO v i"<< get(vertex_index,*this,*vi)<< " i1" << get(vertex_index1, *this, *vi)<<","<< get(vertex_name, *this, *vi) << endl; for(set<SgNode*>::iterator chd= chMap[srcVert].defined.begin(); chd!= chMap[srcVert].defined.end(); chd++) { SgFunctionDeclaration *defMF = isSgFunctionDeclaration( *chd ); bool erased = true; while(erased) { erased = false; for(set<SgNode*>::iterator inhd= chMap[srcVert].inherited.begin(); inhd!= chMap[srcVert].inherited.end() && (!erased); ) { SgFunctionDeclaration *inhMF = isSgFunctionDeclaration( *inhd ); if(compareFunctionDeclarations(defMF, inhMF)) { // own function overrides, so delete old one chMap[srcVert].inherited.erase( *inhd ); erased = true; //cerr << " TOPO MF:"<< defMF->get_mangled_name().str()<< " overrides MF:"<< inhMF->get_mangled_name().str() << endl; // debug } if(!erased) inhd++; } } } // add to inherited functions for(set<SgNode*>::iterator chd= chMap[srcVert].defined.begin(); chd!= chMap[srcVert].defined.end(); chd++) { chMap[srcVert].inherited.insert( *chd ); } // inherit own methods to child classes graph_traits<dbgType>::in_edge_iterator ii,iend; tie(ii,iend) = in_edges(*vi, *this); for(; ii!=iend; ii++) { //dbgVertex srcVert = source(*ii,*this); // methods inherited from this class to the other one dbgVertex child = source(*ii, *this); //cerr << " T inherits to "<< get(vertex_index,*this,child)<< " i1" << get(vertex_index1, *this, child)<<","<< get(vertex_name, *this, child) << endl; //for(set<SgNode*>::iterator chd= chMap[srcVert].defined.begin(); chd!= chMap[srcVert].defined.end(); chd++) { for(set<SgNode*>::iterator chd= chMap[srcVert].inherited.begin(); chd!= chMap[srcVert].inherited.end(); chd++) { SgFunctionDeclaration *inhFunc = isSgFunctionDeclaration( *chd ); bool virt = false; //cerr << " TOPO v srch1" << endl; if(inhFunc->isVirtual()) virt = true; // also check multiple declarations //cerr << " TOPO v srch2" << endl; if(!virt) { for(set<SgNode *>::iterator si=chMap[srcVert].multDeclarations[inhFunc].begin(); si != chMap[srcVert].multDeclarations[inhFunc].end(); si++) { SgFunctionDeclaration *inhDup = isSgFunctionDeclaration( *si ); if(inhDup->isVirtual()) virt = true; //cerr << " TOPO v srch "<< inhDup->get_mangled_name().str() << endl; // debug } } // TODO check virtual inheritance? other declarations? if(virt) { //cerr << " VIRT " << inhFunc->get_mangled_name().str() << endl; // debug // and now... ?? } chMap[child].inherited.insert( inhFunc ); } //cerr << " BOOST v <<< " << get(vertex_index1, *this, boost::target(*ii,*this) )<<","<< get(vertex_name, *this, boost::target(*ii,*this) ) << endl; // debug } } // add own methods to all inherited ones for( std::deque< dbgVertex >::iterator vi=torder.begin(); vi!=torder.end(); vi++) { } }
//! search for all possible (virtual) function calls vector<SgMemberFunctionDeclaration*> Classhierarchy::searchMemberFunctionCalls(SgMemberFunctionDeclaration* mfCall) { vector<SgMemberFunctionDeclaration*> retvec; property_map< dbgType, boost::vertex_classhierarchy_t>::type chMap = boost::get( boost::vertex_classhierarchy, *this ); SgClassDefinition *classDef = mfCall->get_scope(); SgName classname = classDef->get_qualified_name(); // MANGLE string cnamestr = classname.str(); graph_traits< dbgType >::vertex_iterator vi,vend; dbgVertex vdesc = *vi; bool foundVertex = false; tie(vi,vend) = vertices( *this ); for(; vi!=vend; vi++) { //cerr << " BCH v i"<< get(vertex_index,*this,*vi)<< " i1" << get(vertex_index1, *this, *vi)<<","<< get(vertex_name, *this, *vi) << endl; if( get(vertex_dbg_data, *this, *vi).get_typeName() == cnamestr ) { //cerr << " SMF srch "<< cnamestr <<" vi "<< get(vertex_index,*this,*vi)<< " i1" << get(vertex_index1, *this, *vi)<<","<< get(vertex_name, *this, *vi) << endl; vdesc = *vi; foundVertex = true; break; } } if(!foundVertex) { cerr << " SMF srch "<< cnamestr <<" vi "<< get(vertex_index,*this,*vi)<< " i1" << get(vertex_index1, *this, *vi)<<","<< get(vertex_name, *this, *vi) << endl; } assert( foundVertex ); set<dbgVertex> treeset; treeset.insert( vdesc ); // first find "highest" class in CH that still provides this MF dbgVertex vhighest = vdesc; // first assume its the current one graph_traits<dbgType>::out_edge_iterator oi,oend; tie(oi,oend) = out_edges( vdesc, *this); for(; oi!=oend; oi++) { //cerr << " SMF inherits from "<< get(vertex_index,*this,target(*oi,*this))<< " i1" << get(vertex_index1, *this, target(*oi,*this))<<","<< get(vertex_name, *this, target(*oi,*this)) << endl; // does any of the base classes implement the member function? bool noParentImpl = true; // check if this base class also implements MF for(set<SgNode*>::iterator chd= chMap[target(*oi,*this)].inherited.begin(); chd!= chMap[target(*oi,*this)].inherited.end(); chd++) { SgFunctionDeclaration *inhFunc = isSgFunctionDeclaration( *chd ); bool virt = false; //cerr << " TOPO v srch1" << endl; if(inhFunc->isVirtual()) virt = true; if( (virt) && (compareFunctionDeclarations(inhFunc,mfCall)) ) { // remeber for traversal treeset.insert( target(*oi, *this) ); noParentImpl = false; } } if(noParentImpl) { // we found it vhighest = target(*oi, *this); break; } } //cerr << " SMF high "<< cnamestr <<" vi "<< get(vertex_index,*this,vhighest)<< " i1" << get(vertex_index1, *this, vhighest)<<","<< get(vertex_name, *this, vhighest) << endl; // now traverse class hierachy downwards, for all children that implement this function, add to set set<dbgVertex> tovisit; set<dbgVertex> visited; tovisit.insert( vhighest ); //hier weiter while( tovisit.size() > 0 ) { dbgVertex currVert = *(tovisit.begin()); tovisit.erase( currVert ); visited.insert( currVert ); //cerr << " SMF visi "<< get(vertex_index,*this,currVert)<< " i1" << get(vertex_index1, *this, currVert)<<","<< get(vertex_name, *this, currVert) << endl; for(set<SgNode*>::iterator chd= chMap[currVert].defined.begin(); chd!= chMap[currVert].defined.end(); chd++) { SgMemberFunctionDeclaration*inhFunc = isSgMemberFunctionDeclaration( *chd ); if(compareFunctionDeclarations(inhFunc,mfCall)) { retvec.push_back( inhFunc ); } } graph_traits<dbgType>::in_edge_iterator ii,iend; tie(ii,iend) = in_edges( currVert, *this); for(; ii!=iend; ii++) { dbgVertex child = source(*ii, *this); // only insert of not already visited set<dbgVertex>::iterator found = visited.find( child ); if(found == visited.end()) tovisit.insert( child ); } } //retvec.push_back( mfCall ); return retvec; }