Exemplo n.º 1
0
    /**
     * Q: how can this be optimized?
     * @brief test if there exists a return transition with the given from state, 
     *        predecessor state, and symbol in this collection of transitions 
     *
     * @param - from: the desired from state for the return transition
     * @param - pred: the desired predecessor state for the return transition
     * @param - sym: the desired symbol for the return transition
     * @return true if there exists a return transition with the given from state and
     *          symbol in this collection of transitions
     *
     */
    bool TransitionStorage::returnExists( State from, State pred, Symbol sym ) const
    {
      Returns const & outgoing = T_info.exitTrans(from);

      for( ReturnIterator rit = outgoing.begin(); rit != outgoing.end(); rit++ )
      {
        if( (getCallSite(*rit) == pred) && (getReturnSym(*rit) == sym) )
          return true;      
      }     
      return false;
    }   
Exemplo n.º 2
0
    /**
     * Q: how can this be optimized?
     * @brief provides access to all return transitions with the given from
     *        state and symbol in this collection of transitions
     *
     * @param - from: the desired from state for the return transitions
     * @param - sym: the desired symbol for the return transitions
     * @return the set of return transitions with the given from state and symbol
     *
     */
    const TransitionStorage::Returns TransitionStorage::getReturns( State from, Symbol sym ) const
    {
      Returns result;
      Returns const & outgoing = T_info.exitTrans(from);

      for( ReturnIterator rit = outgoing.begin(); rit != outgoing.end(); rit++ )
      {
        if( (getExit(*rit) == from) && (getReturnSym(*rit) == sym) )
          result.insert(*rit);
      } 
      return result;
    }
Exemplo n.º 3
0
    /**
     *   
     * @brief creates transitions for 'dup' mirroring 'orig' outgoing transitions
     *
     * @param - orig: the state that is being duplicated
     * @param - dup: the state that is duplicating 'orig'
     *  
     */
    void TransitionStorage::dupTransOutgoing( State orig, State dup )
    { 
      // Duplicate outgoing internal transitions.
      const Info::Internals & from = T_info.fromTrans(orig);
      for( Info::InternalIterator it = from.begin(); it != from.end(); it++ )
      {
        Internal iTrans(dup,getInternalSym(*it),getTarget(*it));
        addInternal(iTrans);
      }

      // Duplicate call site call transitions.
      const Info::Calls & call = T_info.callTrans(orig);
      for( Info::CallIterator it = call.begin(); it != call.end(); it++ )
      {
        Call cTrans(dup,getCallSym(*it),getEntry(*it));
        addCall(cTrans);

      }

      // Duplicate exit point return transitions.
      const Info::Returns & exit = T_info.exitTrans(orig);
      for( Info::ReturnIterator it = exit.begin(); it != exit.end(); it++ )
      {
        Return rTrans(dup,getCallSite(*it),getReturnSym(*it),getReturnSite(*it));
        addReturn(rTrans);
      }

      // Q: Do we want to do these? Seems inconsistent. -Evan
      // A: Aditya says 'yes', and thinks we need it. So we definitely don't
      //    want to change it without looking at uses and compensating.
      // Duplicate call predecessor return transitions.
      const Info::Returns & pred = T_info.predTrans(orig);
      for( Info::ReturnIterator it = pred.begin(); it != pred.end(); it++ )
      {
        Return rTrans(getExit(*it),dup,getReturnSym(*it),getReturnSite(*it));
        addReturn(rTrans);
      }
    }
Exemplo n.º 4
0
 /**
  *  
  * @brief finds the symbol on any transition whose source is 'from' and
  *        whose target is 'to'
  *
  * @param - from: the source of the transition
  * @param - to: the target of the transition
  * @return true if there exists some transition with the given source and 
  *         target, false otherwise
  *
  */
 bool TransitionStorage::getSymbol( State fromSt, State toSt, Symbol & sym ) const
 {
   //Check internal transitions.
   const Info::Internals & from = T_info.fromTrans(fromSt);
   for(Info::InternalIterator it = from.begin(); it != from.end(); it++ )
   {
     if( toSt == getTarget(*it) )
     {
       sym = getInternalSym(*it);
       return true;
     }
   }
   //Check call transitions.
   const Info::Calls & call = T_info.callTrans(fromSt);
   for(Info::CallIterator it = call.begin(); it != call.end(); it++ )
   {
     if( toSt == getEntry(*it) )
     {
       sym = getCallSym(*it);
       return true;
     }
   }
   //Check return transitions.      
   const Info::Returns & exit = T_info.exitTrans(fromSt);
   for(Info::ReturnIterator it = exit.begin(); it != exit.end(); it++ )
   {
     if( toSt == getReturnSite(*it) )
     {
       sym = getReturnSym(*it);
       return true;
     }
   }
   //Q: does this count as a symbol we would like to have?
   /*const Info::Returns pred = T_info.predTrans(fromSt);
     for( Info::ReturnIterator it = pred.begin(); it != pred.end(); it++ )
     {
     if( toSt == getReturnSite(*it) )
     {
     sym = getReturnSym(*it);
     return true;
     }
     }*/
   
   return false;
 }
Exemplo n.º 5
0
    /** 
     *
     * @brief removes all return transitions with the given symbol 
     *
     * @param - sym: the symbol whose transitions to remove
     * @return false if no transitions were removed, true otherwise
     *
     */
    bool TransitionStorage::removeReturnTransSym( Symbol sym )
    {
      Returns removeTrans;

      //Find transitions to remove.
      for( ReturnIterator rit = returnTrans.begin(); rit != returnTrans.end(); rit++ )
      {
        if( getReturnSym(*rit) == sym )
          removeTrans.insert(*rit);
      }

      //Remove transitions.
      for( ReturnIterator rit = removeTrans.begin(); rit != removeTrans.end(); rit++ )
      {
        removeReturn(*rit);
      }
      
      return removeTrans.size() > 0; 
    }
Exemplo n.º 6
0
PTREE AnalyseReturnClassVal     // RETURN CLASS VALUE
    ( PTREE expr )              // - expression for return
{
    TYPE retn_type;             // - return type
    TYPE retn_class;            // - class for return
    PTREE tgt;                  // - target expression
    CNV_DIAG* diag;             // - diagnosis

    retn_type = expr->u.subtree[0]->type;
    retn_class = StructType( retn_type );
    DbgVerify( retn_class != NULL, "AnalyseReturnClassVal -- not class" );
    if( ClassCorrupted( retn_class ) ) {
        PTreeErrorNode( expr );
    } else if( TypeAbstract( retn_class ) ) {
        PTreeErrorExprType( expr, ERR_CONVERT_TO_ABSTRACT_TYPE, retn_class );
        ScopeNotePureFunctions( retn_class );
    } else {
        diag = DefargBeingCompiled() ? &diagDefarg : &diagReturn;
        tgt = NodeFetchReference( getReturnSym() );
        expr = removeReturnNode( expr );
        expr = CopyClassRetnVal( expr, tgt, retn_type, diag );
        if( expr->op != PT_ERROR ) {
            if( NodeIsBinaryOp( expr, CO_DTOR ) ) {
                PTREE node = expr->u.subtree[0];
                if( SymFunctionReturn() == node->u.symcg.symbol ) {
                    PTreeFree( node );
                    node = expr;
                    expr = expr->u.subtree[1];
                    PTreeFree( node );
                }
            }
        }
#if 0
            // this is just so we can do some checking
            expr = CastImplicit( expr
                               , retn_type
                               , CNV_EXPR
                               , DefargBeingCompiled()
                                    ? &diagDefarg : &diagReturn );
        }
#endif
    }
Exemplo n.º 7
0
    /**
     *
     * @brief print the collection of transitions
     *
     * @param - o: the output stream to print to
     * @return the output stream that was printed to
     *
     */
    std::ostream & TransitionStorage::print( std::ostream & o ) const
    {    
      //Print call transitions.
      o << "Delta_c: {\n  ";
      bool first = true;
      for( CallIterator cit = callTrans.begin(); cit != callTrans.end(); cit++, first=false )
      {
        if( !first )
          o << ", \n  ";
        o << "(";
        printKey(o,getCallSite(*cit));
        o << " (=" << getCallSite(*cit) << ") ";
        o << ", ";
        printKey(o,getCallSym(*cit));
        o << ", "; 
        printKey(o,getEntry(*cit));
        o << " (=" << getEntry(*cit) << ") ";
        o << ")";
      }
      o << "\n}\n";

      //Print internal transitions.
      o << "Delta_i:  {\n  ";
      first = true;
      for(InternalIterator iit = internalTrans.begin();
          iit != internalTrans.end(); iit++, first=false )
      {
        if( !first )
          o << ",\n  ";
        o << "(";
        printKey(o,getSource(*iit));
        o << " (=" << getSource(*iit) << ") ";
        o << ", ";
        printKey(o,getInternalSym(*iit));
        o << ", ";
        printKey(o,getTarget(*iit));
        o << " (=" << getTarget(*iit) << ") ";
        o << ")";
      }
      o << "\n}\n";

      //Print return transitions.
      o << "Delta_r: {\n  ";
      first = true;
      for(ReturnIterator rit = returnTrans.begin();
          rit != returnTrans.end(); rit++, first = false )
      {
        if( !first )
          o << ",\n  ";
        o << "(";
        printKey(o,getExit(*rit));
        o << " (=" << getExit(*rit) << ") ";
        o << ", ";
        printKey(o,getCallSite(*rit));
        o << " (=" << getCallSite(*rit) << ") ";
        o << ", "; 
        printKey(o,getReturnSym(*rit));
        o << ", ";
        printKey(o,getReturnSite(*rit));
        o << " (=" << getReturnSite(*rit) << ") ";
        o << ")";
      }
      o << "\n}\n";
      
      return o;
    }
Exemplo n.º 8
0
    /**
     *  
     * @brief creates transitions for 'dup' mirroring 'orig' transitions
     *
     * @param - orig: the state that is being duplicated
     * @param - dup: the state that is duplicating 'orig'
     *  
     */
    void TransitionStorage::dupTrans( State orig, State dup )
    { 
      //Duplicate outgoing internal transitions.
      const Info::Internals & from = T_info.fromTrans(orig);
      for( Info::InternalIterator it = from.begin(); it != from.end(); it++ )
      {
        Internal iTrans(dup,getInternalSym(*it),getTarget(*it));
        addInternal(iTrans);

        // Q: This is also inconsistent with dupTransOutgoing, which didn't do
        //    anything special with self loops. -Evan
        // A: Aditya says yes, but this is again what McVeto(?) needs.
        //    dupTrans is used in 'duplicateState', but dupTransOutgoing is
        //    different.
        if( orig == getTarget(*it) )   //Handle self-loops.
        {
          Internal loop(dup,getInternalSym(*it),dup);
          addInternal(loop);
        }
      }

      //Duplicate incoming internal transitions.
      const Info::Internals & to = T_info.toTrans(orig);
      for( Info::InternalIterator it = to.begin(); it != to.end(); it++ )
      {
        Internal iTrans(getSource(*it),getInternalSym(*it),dup);
        addInternal(iTrans);
      }

      //Duplicate call site call transitions.
      const Info::Calls & call = T_info.callTrans(orig);
      for( Info::CallIterator it = call.begin(); it != call.end(); it++ )
      {
        Call cTrans(dup,getCallSym(*it),getEntry(*it));
        addCall(cTrans);
        if( orig == getEntry(*it) )   //Handle self-loops.
        {
          Call loop(dup,getCallSym(*it),dup);
          addCall(loop);
        }
      }

      //Duplicate entry point call transitions.
      const Info::Calls & entry = T_info.entryTrans(orig);
      for( Info::CallIterator it = entry.begin(); it != entry.end(); it++ )
      {
        Call cTrans(getCallSite(*it),getCallSym(*it),dup);
        addCall(cTrans);
      }

      //Duplicate exit point return transitions.
      const Info::Returns & exit = T_info.exitTrans(orig);
      for( Info::ReturnIterator it = exit.begin(); it != exit.end(); it++ )
      {
        Return rTrans(dup,getCallSite(*it),getReturnSym(*it),getReturnSite(*it));
        addReturn(rTrans);
        if( orig == getCallSite(*it) )   //Handle self-loops.
        {
          Return loop(dup,dup,getReturnSym(*it),getReturnSite(*it));
          addReturn(loop);
        }
        if( orig == getReturnSite(*it) )   //Handle self-loops.
        {
          Return loop(dup,getCallSite(*it),getReturnSym(*it),dup);
          addReturn(loop);
        }
        if( orig == getCallSite(*it) && orig == getReturnSite(*it) )   //Handle self-loops.
        {
          Return loop(dup,dup,getReturnSym(*it),dup);
          addReturn(loop);
        }
      }

      //Duplicate call predecessor return transitions.
      const Info::Returns & pred = T_info.predTrans(orig);
      for( Info::ReturnIterator it = pred.begin(); it != pred.end(); it++ )
      {
        Return rTrans(getExit(*it),dup,getReturnSym(*it),getReturnSite(*it));
        addReturn(rTrans);
        if( orig == getReturnSite(*it) )   //Handle self-loops.
        {
          Return loop(getExit(*it),dup,getReturnSym(*it),dup);
          addReturn(loop);
        }
      }

      //Duplicate return site return transitions.
      const Info::Returns & ret = T_info.retTrans(orig);
      for( Info::ReturnIterator it = ret.begin(); it != ret.end(); it++ )
      {
        Return rTrans(getExit(*it),getCallSite(*it),getReturnSym(*it),dup);
        addReturn(rTrans);
      }
    }