Changeset d9a0e76


Ignore:
Timestamp:
Dec 16, 2014, 9:41:50 PM (10 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
17cd4eb
Parents:
3848e0e
Message:

remove Parser.old, add -XCFA to driver, copy ptrdiff_t from stddef.h in preclude, remove casts from initialization constants, adjust formatting

Files:
21 deleted
43 edited

Legend:

Unmodified
Added
Removed
  • driver/cc1.cc

    r3848e0e rd9a0e76  
    88// Created On       : Fri Aug 26 14:23:51 2005
    99// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Wed Nov 12 22:58:59 2014
    11 // Update Count     : 5
     10// Last Modified On : Sun Dec  7 22:21:33 2014
     11// Update Count     : 14
    1212//
    1313// This  library is free  software; you  can redistribute  it and/or  modify it
     
    4545
    4646string D__GCC_BPREFIX__( "-D__GCC_BPREFIX__=" );
     47string D__CFA_FLAGPREFIX__( "-D__CFA_FLAG__=" );
    4748
    4849
     
    140141                i += 1;                                 // and the argument
    141142                cpp_flag = true;
     143            } else if ( prefix( arg, D__CFA_FLAGPREFIX__ ) ) {
     144                uargs[nuargs] = ( *new string( arg.substr( D__CFA_FLAGPREFIX__.size() ) ) ).c_str();
     145                nuargs += 1;
     146            } else if ( arg == "-D" && prefix( argv[i + 1], D__CFA_FLAGPREFIX__.substr(2) ) ) {
     147                uargs[nuargs] = ( *new string( string( argv[i + 1] ).substr( D__CFA_FLAGPREFIX__.size() - 2 ) ) ).c_str();
     148                nuargs += 1;
     149                i += 1;                                 // and the argument
    142150            } else if ( prefix( arg, D__GCC_BPREFIX__ ) ) {
    143151                bprefix = arg.substr( D__GCC_BPREFIX__.size() );
    144             } else if ( arg == "-D" && prefix( argv[i + 1], "__GCC_BPREFIX__=" ) ) {
     152            } else if ( arg == "-D" && prefix( argv[i + 1], D__GCC_BPREFIX__.substr(2) ) ) {
    145153                bprefix = string( argv[i + 1] ).substr( D__GCC_BPREFIX__.size() - 2 );
    146154                i += 1;                                 // and the argument
  • driver/cpp.cc

    r3848e0e rd9a0e76  
    88// Created On       : Thu Aug 29 12:24:06 2002
    99// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Fri Sep 20 07:33:49 2002
    11 // Update Count     : 50
     10// Last Modified On : Sat Dec  6 08:31:49 2014
     11// Update Count     : 51
    1212//
    1313
  • libcfa/prelude.cf

    r3848e0e rd9a0e76  
    88// Created On       : Sat Nov 29 07:23:41 2014
    99// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Tue Dec  2 09:25:31 2014
    11 // Update Count     : 20
     10// Last Modified On : Mon Dec 15 16:20:30 2014
     11// Update Count     : 27
    1212//
    1313
  • translator/ControlStruct/CaseRangeMutator.cc

    r3848e0e rd9a0e76  
    1313
    1414namespace ControlStruct {
    15 
    16   Statement* CaseRangeMutator::mutate(ChooseStmt   *chooseStmt)
    17   {
    18     /* There shouldn't be any `choose' statements by now, throw an exception or something. */
    19     throw( 0 ) ; /* FIXME */
    20   }
    21 
    22   Statement* CaseRangeMutator::mutate(SwitchStmt   *switchStmt)
    23   {
    24     std::list< Statement * > &cases = switchStmt->get_branches();
    25 
    26     // a `for' would be more natural... all this contortions are because `replace' invalidates the iterator
    27     std::list< Statement * >::iterator i = cases.begin();
    28     while (  i != cases.end() ) {
    29       (*i)->acceptMutator( *this );
    30 
    31       if ( ! newCaseLabels.empty() ) {
    32         std::list< Statement * > newCases;
    33 
    34         // transform( newCaseLabels.begin(), newCaseLabels.end(), bnd1st( ptr_fun( ctor< CaseStmt, Label, Expression * > ) ) );
    35 
    36         for ( std::list< Expression * >::iterator j = newCaseLabels.begin();
    37               j != newCaseLabels.end(); j++ ) {
    38           std::list<Label> emptyLabels;
    39           std::list< Statement *> emptyStmts;
    40           newCases.push_back( new CaseStmt( emptyLabels, *j, emptyStmts ) );
    41         }
    42 
    43         if( CaseStmt *currentCase = dynamic_cast< CaseStmt * > ( *i ) )
    44           if ( !currentCase->get_statements().empty() ) {
    45             CaseStmt *lastCase = dynamic_cast< CaseStmt * > ( newCases.back() );
    46             if ( lastCase == 0 ) { throw ( 0 ); /* FIXME */ } // something is very wrong, as I just made these, and they were all cases
    47             // transfer the statement block (if any) to the new list:
    48             lastCase->set_statements( currentCase->get_statements() );
    49           }
    50         std::list< Statement * >::iterator j = i; advance( j, 1 );
    51         replace ( cases, i, newCases );
    52         i = j;
    53         newCaseLabels.clear();
    54       } else
    55         i++;
     15    Statement *CaseRangeMutator::mutate(ChooseStmt *chooseStmt) {
     16        /* There shouldn't be any `choose' statements by now, throw an exception or something. */
     17        throw( 0 ) ; /* FIXME */
    5618    }
    5719
    58     return switchStmt;
    59   }
     20    Statement *CaseRangeMutator::mutate(SwitchStmt *switchStmt) {
     21        std::list< Statement * > &cases = switchStmt->get_branches();
    6022
    61   Statement* CaseRangeMutator::mutate(FallthruStmt *fallthruStmt)
    62   {
    63     //delete fallthruStmt;
    64     return new NullStmt();
    65   }
     23        // a `for' would be more natural... all this contortions are because `replace' invalidates the iterator
     24        std::list< Statement * >::iterator i = cases.begin();
     25        while (  i != cases.end() ) {
     26            (*i)->acceptMutator( *this );
    6627
    67   Statement* CaseRangeMutator::mutate(CaseStmt *caseStmt)
    68   {
    69     UntypedExpr *cond;
    70     if ( (cond = dynamic_cast< UntypedExpr * >( caseStmt->get_condition() )) != 0 ) {
    71       NameExpr *nmfunc;
    72       if ( (nmfunc = dynamic_cast< NameExpr *>( cond->get_function() )) != 0 ) {
    73         if ( nmfunc->get_name() == std::string("Range") ) {
    74           assert( cond->get_args().size() == 2 );
    75           std::list<Expression *>::iterator i = cond->get_args().begin();
    76           Expression *lo = *i, *hi = *(++i); // "unnecessary" temporaries
    77           fillRange( lo, hi);
    78         }
    79       }
    80     } else if ( TupleExpr *tcond = dynamic_cast< TupleExpr * >( caseStmt->get_condition() ) ) {
    81       // case list
    82       assert( ! tcond->get_exprs().empty() );
    83       for ( std::list< Expression * >::iterator i = tcond->get_exprs().begin(); i != tcond->get_exprs().end(); i++ )
    84         newCaseLabels.push_back( *i ); // do I need to clone them?
     28            if ( ! newCaseLabels.empty() ) {
     29                std::list< Statement * > newCases;
     30
     31                // transform( newCaseLabels.begin(), newCaseLabels.end(), bnd1st( ptr_fun( ctor< CaseStmt, Label, Expression * > ) ) );
     32
     33                for ( std::list< Expression * >::iterator j = newCaseLabels.begin();
     34                      j != newCaseLabels.end(); j++ ) {
     35                    std::list<Label> emptyLabels;
     36                    std::list< Statement *> emptyStmts;
     37                    newCases.push_back( new CaseStmt( emptyLabels, *j, emptyStmts ) );
     38                }
     39
     40                if ( CaseStmt *currentCase = dynamic_cast< CaseStmt * > ( *i ) )
     41                    if ( ! currentCase->get_statements().empty() ) {
     42                        CaseStmt *lastCase = dynamic_cast< CaseStmt * > ( newCases.back() );
     43                        if ( lastCase == 0 ) { throw ( 0 ); /* FIXME */ } // something is very wrong, as I just made these, and they were all cases
     44                        // transfer the statement block (if any) to the new list:
     45                        lastCase->set_statements( currentCase->get_statements() );
     46                    }
     47                std::list< Statement * >::iterator j = i; advance( j, 1 );
     48                replace ( cases, i, newCases );
     49                i = j;
     50                newCaseLabels.clear();
     51            } else
     52                i++;
     53        } // while
     54
     55        return switchStmt;
    8556    }
    8657
    87     std::list< Statement * > &stmts = caseStmt->get_statements();
    88     mutateAll ( stmts, *this );
    89 
    90     return caseStmt;
    91   }
    92 
    93   void CaseRangeMutator::fillRange(Expression *lo, Expression *hi) {
    94     // generate the actual range (and check for consistency)
    95     Constant *c_lo, *c_hi;
    96     ConstantExpr *ce_lo, *ce_hi;
    97     ce_lo = dynamic_cast< ConstantExpr * >( lo );
    98     ce_hi = dynamic_cast< ConstantExpr * >( hi );
    99 
    100     if ( ce_lo && ce_hi ) {
    101       c_lo = ce_lo->get_constant(); c_hi = ce_hi->get_constant();
    102     } /* else {
    103       if ( !ce_lo ) ;
    104       if ( !ce_hi ) ;
    105       } */
    106     BasicType *ty_lo = dynamic_cast< BasicType * >( c_lo->get_type() ),
    107                        *ty_hi = dynamic_cast< BasicType * >( c_hi->get_type() );
    108    
    109     if( !ty_lo || !ty_hi )
    110       return; // one of them is not a constant
    111 
    112 
    113     switch( ty_lo->get_kind() ) {
    114     case BasicType::Char:
    115     case BasicType::UnsignedChar:
    116       switch( ty_hi->get_kind() )
    117         {
    118         case BasicType::Char:
    119         case BasicType::UnsignedChar:
    120           // first case, they are both printable ASCII characters represented as 'x'
    121           if ( c_lo->get_value().size() == 3 && c_hi->get_value().size() == 3 ) {
    122             char ch_lo = (c_lo->get_value())[1], ch_hi = (c_hi->get_value())[1];
    123 
    124             if ( ch_lo > ch_hi ) { char t=ch_lo; ch_lo=ch_hi; ch_hi=t; }
    125 
    126             for( char c = ch_lo; c <=  ch_hi; c++ ){
    127               Type::Qualifiers q;
    128               Constant cnst( new BasicType(q, BasicType::Char),
    129                                       std::string("'") + c + std::string("'") );
    130               newCaseLabels.push_back( new ConstantExpr( cnst ) );
    131             }
    132 
    133             return;
    134           }
    135           break;
    136         default:
    137           // error: incompatible constants
    138           break;
    139         }
    140       break;
    141     case BasicType::ShortSignedInt:
    142     case BasicType::ShortUnsignedInt:
    143     case BasicType::SignedInt:
    144     case BasicType::UnsignedInt:
    145     case BasicType::LongSignedInt:
    146     case BasicType::LongUnsignedInt:
    147     case BasicType::LongLongSignedInt:
    148     case BasicType::LongLongUnsignedInt:
    149       switch( ty_hi->get_kind() )
    150         {
    151         case BasicType::ShortSignedInt:
    152         case BasicType::ShortUnsignedInt:
    153         case BasicType::SignedInt:
    154         case BasicType::UnsignedInt:
    155         case BasicType::LongSignedInt:
    156         case BasicType::LongUnsignedInt:
    157         case BasicType::LongLongSignedInt:
    158         case BasicType::LongLongUnsignedInt: {
    159           int i_lo = atoi(c_lo->get_value().c_str()),
    160               i_hi = atoi(c_hi->get_value().c_str());
    161 
    162           if ( i_lo > i_hi ) { int t=i_lo; i_lo=i_hi; i_hi=t; }
    163 
    164           for( int c = i_lo; c <=  i_hi; c++ ){
    165             Type::Qualifiers q;
    166             Constant cnst( new BasicType(q, ty_hi->get_kind()), // figure can't hurt (used to think in positives)
    167                                     toString< int >( c ) );
    168             newCaseLabels.push_back( new ConstantExpr( cnst ) );
    169           }
    170 
    171           return;
    172         }
    173         default:
    174           // error: incompatible constants
    175           break;
    176         }
    177       break;
    178     default:
    179       break;
     58    Statement *CaseRangeMutator::mutate(FallthruStmt *fallthruStmt) {
     59        //delete fallthruStmt;
     60        return new NullStmt();
    18061    }
    18162
    182 /* End: */{
    183       // invalid range, signal a warning (it still generates the two case labels)
    184       newCaseLabels.push_back( lo );
    185       newCaseLabels.push_back( hi );
    186       return;
     63    Statement *CaseRangeMutator::mutate(CaseStmt *caseStmt) {
     64        UntypedExpr *cond;
     65        if ( (cond = dynamic_cast< UntypedExpr * >( caseStmt->get_condition() )) != 0 ) {
     66            NameExpr *nmfunc;
     67            if ( (nmfunc = dynamic_cast< NameExpr *>( cond->get_function() )) != 0 ) {
     68                if ( nmfunc->get_name() == std::string("Range") ) {
     69                    assert( cond->get_args().size() == 2 );
     70                    std::list<Expression *>::iterator i = cond->get_args().begin();
     71                    Expression *lo = *i, *hi = *(++i); // "unnecessary" temporaries
     72                    fillRange( lo, hi);
     73                }
     74            }
     75        } else if ( TupleExpr *tcond = dynamic_cast< TupleExpr * >( caseStmt->get_condition() ) ) {
     76            // case list
     77            assert( ! tcond->get_exprs().empty() );
     78            for ( std::list< Expression * >::iterator i = tcond->get_exprs().begin(); i != tcond->get_exprs().end(); i++ )
     79                newCaseLabels.push_back( *i ); // do I need to clone them?
     80        } // if
     81
     82        std::list< Statement * > &stmts = caseStmt->get_statements();
     83        mutateAll ( stmts, *this );
     84
     85        return caseStmt;
    18786    }
    188   }
    18987
     88    void CaseRangeMutator::fillRange(Expression *lo, Expression *hi) {
     89        // generate the actual range (and check for consistency)
     90        Constant *c_lo, *c_hi;
     91        ConstantExpr *ce_lo, *ce_hi;
     92        ce_lo = dynamic_cast< ConstantExpr * >( lo );
     93        ce_hi = dynamic_cast< ConstantExpr * >( hi );
     94
     95        if ( ce_lo && ce_hi ) {
     96            c_lo = ce_lo->get_constant(); c_hi = ce_hi->get_constant();
     97        } /* else {
     98             if ( ! ce_lo ) ;
     99             if ( ! ce_hi ) ;
     100             } */
     101        BasicType *ty_lo = dynamic_cast< BasicType * >( c_lo->get_type() ),
     102            *ty_hi = dynamic_cast< BasicType * >( c_hi->get_type() );
     103   
     104        if ( ! ty_lo || ! ty_hi )
     105            return; // one of them is not a constant
     106
     107        switch ( ty_lo->get_kind() ) {
     108          case BasicType::Char:
     109          case BasicType::UnsignedChar:
     110            switch ( ty_hi->get_kind() ){
     111                  case BasicType::Char:
     112                  case BasicType::UnsignedChar:
     113                    // first case, they are both printable ASCII characters represented as 'x'
     114                    if ( c_lo->get_value().size() == 3 && c_hi->get_value().size() == 3 ) {
     115                        char ch_lo = (c_lo->get_value())[1], ch_hi = (c_hi->get_value())[1];
     116
     117                        if ( ch_lo > ch_hi ) { char t=ch_lo; ch_lo=ch_hi; ch_hi=t; }
     118
     119                        for( char c = ch_lo; c <=  ch_hi; c++ ){
     120                            Type::Qualifiers q;
     121                            Constant cnst( new BasicType(q, BasicType::Char),
     122                                           std::string("'") + c + std::string("'") );
     123                            newCaseLabels.push_back( new ConstantExpr( cnst ) );
     124                        }
     125
     126                        return;
     127                    }
     128                    break;
     129                  default:
     130                    // error: incompatible constants
     131                    break;
     132                }
     133            break;
     134          case BasicType::ShortSignedInt:
     135          case BasicType::ShortUnsignedInt:
     136          case BasicType::SignedInt:
     137          case BasicType::UnsignedInt:
     138          case BasicType::LongSignedInt:
     139          case BasicType::LongUnsignedInt:
     140          case BasicType::LongLongSignedInt:
     141          case BasicType::LongLongUnsignedInt:
     142            switch ( ty_hi->get_kind() ) {
     143              case BasicType::ShortSignedInt:
     144              case BasicType::ShortUnsignedInt:
     145              case BasicType::SignedInt:
     146              case BasicType::UnsignedInt:
     147              case BasicType::LongSignedInt:
     148              case BasicType::LongUnsignedInt:
     149              case BasicType::LongLongSignedInt:
     150              case BasicType::LongLongUnsignedInt: {
     151                  int i_lo = atoi(c_lo->get_value().c_str()),
     152                      i_hi = atoi(c_hi->get_value().c_str());
     153
     154                  if ( i_lo > i_hi ) { int t=i_lo; i_lo=i_hi; i_hi=t; }
     155
     156                  for( int c = i_lo; c <=  i_hi; c++ ){
     157                      Type::Qualifiers q;
     158                      Constant cnst( new BasicType(q, ty_hi->get_kind()), // figure can't hurt (used to think in positives)
     159                                     toString< int >( c ) );
     160                      newCaseLabels.push_back( new ConstantExpr( cnst ) );
     161                  }
     162
     163                  return;
     164              }
     165              default:
     166                // error: incompatible constants
     167                break;
     168            }
     169            break;
     170          default:
     171            break;
     172        } // switch
     173
     174        /* End: */{
     175            // invalid range, signal a warning (it still generates the two case labels)
     176            newCaseLabels.push_back( lo );
     177            newCaseLabels.push_back( hi );
     178            return;
     179        }
     180    }
    190181} // namespace ControlStruct
  • translator/ControlStruct/CaseRangeMutator.h

    r3848e0e rd9a0e76  
    77
    88namespace ControlStruct {
     9    class CaseRangeMutator : public Mutator {
     10      public:
     11        CaseRangeMutator() {}
    912
    10   class CaseRangeMutator : public Mutator
    11   {
    12   public:
    13     CaseRangeMutator() {}
     13        virtual Statement *mutate( ChooseStmt * );
     14        virtual Statement *mutate( SwitchStmt * );
     15        virtual Statement *mutate( FallthruStmt * );
     16        virtual Statement *mutate( CaseStmt * );
     17      private:
     18        void fillRange( Expression *lo, Expression *hi );
    1419
    15     virtual Statement* mutate(ChooseStmt   *);
    16     virtual Statement* mutate(SwitchStmt   *);
    17     virtual Statement* mutate(FallthruStmt *);
    18     virtual Statement* mutate(CaseStmt     *);
    19 
    20   private:
    21     void fillRange(Expression *lo, Expression *hi);
    22 
    23     Expression *currentCondition;
    24     std::list< Expression * > newCaseLabels;
    25   };
     20        Expression *currentCondition;
     21        std::list< Expression * > newCaseLabels;
     22    };
    2623
    2724} // namespace ControlStruct
    2825
    29 #endif // #ifndef CASERNG_MUTATOR_H
     26#endif // CASERNG_MUTATOR_H
    3027
    3128/*
  • translator/ControlStruct/ChooseMutator.cc

    r3848e0e rd9a0e76  
    55
    66namespace ControlStruct {
    7 
    8   Statement* ChooseMutator::mutate(ChooseStmt   *chooseStmt)
    9   {
    10     bool enclosingChoose = insideChoose;
    11     insideChoose = true;
    12     mutateAll( chooseStmt->get_branches(), *this );
    13     insideChoose = enclosingChoose;
    14 
    15     return new SwitchStmt( chooseStmt->get_labels(),  chooseStmt->get_condition(), chooseStmt->get_branches() );
    16   }
    17 
    18   Statement* ChooseMutator::mutate(SwitchStmt   *switchStmt)
    19   {
    20     bool enclosingChoose = insideChoose;
    21     insideChoose = false;
    22     mutateAll( switchStmt->get_branches(), *this );
    23     insideChoose = enclosingChoose;
    24 
    25     return switchStmt;
    26   }
    27 
    28   Statement* ChooseMutator::mutate(FallthruStmt *fallthruStmt)
    29   {
    30     delete fallthruStmt;
    31     return new NullStmt();
    32   }
    33 
    34   Statement* ChooseMutator::mutate(CaseStmt *caseStmt)
    35   {
    36 
    37     std::list< Statement * > &stmts = caseStmt->get_statements();
    38 
    39     if ( insideChoose ) {
    40       BranchStmt *posBrk;
    41       if ( (( posBrk = dynamic_cast< BranchStmt * > ( stmts.back() ) ) &&
    42             ( posBrk->get_type() == BranchStmt::Break ))  // last statement in the list is a (superfluous) 'break'
    43            || dynamic_cast< FallthruStmt * > ( stmts.back() ) )
    44         ;
    45       else {
    46         stmts.push_back( new BranchStmt( std::list< Label >(), "", BranchStmt::Break ) );
    47       }
     7    Statement *ChooseMutator::mutate( ChooseStmt *chooseStmt) {
     8        bool enclosingChoose = insideChoose;
     9        insideChoose = true;
     10        mutateAll( chooseStmt->get_branches(), *this );
     11        insideChoose = enclosingChoose;
     12        return new SwitchStmt( chooseStmt->get_labels(),  chooseStmt->get_condition(), chooseStmt->get_branches() );
    4813    }
    4914
    50     mutateAll ( stmts, *this );
     15    Statement *ChooseMutator::mutate( SwitchStmt *switchStmt ) {
     16        bool enclosingChoose = insideChoose;
     17        insideChoose = false;
     18        mutateAll( switchStmt->get_branches(), *this );
     19        insideChoose = enclosingChoose;
     20        return switchStmt;
     21    }
    5122
    52     return caseStmt;
    53   }
     23    Statement *ChooseMutator::mutate( FallthruStmt *fallthruStmt ) {
     24        delete fallthruStmt;
     25        return new NullStmt();
     26    }
    5427
     28    Statement* ChooseMutator::mutate(CaseStmt *caseStmt) {
     29        std::list< Statement * > &stmts = caseStmt->get_statements();
     30
     31        if ( insideChoose ) {
     32            BranchStmt *posBrk;
     33            if ( (( posBrk = dynamic_cast< BranchStmt * > ( stmts.back() ) ) &&
     34                  ( posBrk->get_type() == BranchStmt::Break ))  // last statement in the list is a (superfluous) 'break'
     35                 || dynamic_cast< FallthruStmt * > ( stmts.back() ) )
     36                ;
     37            else {
     38                stmts.push_back( new BranchStmt( std::list< Label >(), "", BranchStmt::Break ) );
     39            } // if
     40        } // if
     41
     42        mutateAll ( stmts, *this );
     43        return caseStmt;
     44    }
    5545} // namespace ControlStruct
  • translator/ControlStruct/ChooseMutator.h

    r3848e0e rd9a0e76  
    88namespace ControlStruct {
    99
    10   class ChooseMutator : public Mutator
    11   {
    12   public:
    13     ChooseMutator() : insideChoose( false ) {}
     10    class ChooseMutator : public Mutator {
     11      public:
     12        ChooseMutator() : insideChoose( false ) {}
    1413
    15     virtual Statement* mutate(ChooseStmt   *);
    16     virtual Statement* mutate(SwitchStmt   *);
    17     virtual Statement* mutate(FallthruStmt *);
    18     virtual Statement* mutate(CaseStmt     *);
    19   private:
    20     bool insideChoose;
    21   };
    22 
     14        virtual Statement *mutate( ChooseStmt * );
     15        virtual Statement *mutate( SwitchStmt * );
     16        virtual Statement *mutate( FallthruStmt * );
     17        virtual Statement *mutate( CaseStmt * );
     18      private:
     19        bool insideChoose;
     20    };
    2321} // namespace ControlStruct
    2422
    25 #endif // #ifndef CHOOSE_MUTATOR_H
     23#endif // CHOOSE_MUTATOR_H
    2624
    2725/*
  • translator/ControlStruct/ForExprMutator.cc

    r3848e0e rd9a0e76  
    44
    55namespace ControlStruct {
    6   Statement* ForExprMutator::mutate(ForStmt *forStmt)
    7   {
    8     DeclStmt *decl;
    9     if (( decl = dynamic_cast< DeclStmt * > ( forStmt->get_initialization() )) != 0 )
    10       {
    11         // create compound statement, move declaration outside, leave _for_ as-is
    12         CompoundStmt *block = new CompoundStmt( std::list< Label >() );
    13         std::list<Statement *> &stmts = block->get_kids();
     6    Statement *ForExprMutator::mutate( ForStmt *forStmt ) {
     7        DeclStmt *decl;
     8        if (( decl = dynamic_cast< DeclStmt * > ( forStmt->get_initialization() )) != 0 ) {
     9            // create compound statement, move declaration outside, leave _for_ as-is
     10            CompoundStmt *block = new CompoundStmt( std::list< Label >() );
     11            std::list<Statement *> &stmts = block->get_kids();
    1412
    15         stmts.push_back( decl );
    16         forStmt->set_initialization( 0 );
    17         stmts.push_back( forStmt );
     13            stmts.push_back( decl );
     14            forStmt->set_initialization( 0 );
     15            stmts.push_back( forStmt );
    1816
    19         return block;
    20       }
    21     // ForStmt still needs to be fixed
    22     else
    23       return forStmt;
    24   }
    25 
     17            return block;
     18        } // if
     19        // ForStmt still needs to be fixed
     20        else
     21            return forStmt;
     22    }
    2623} // namespace ControlStruct
  • translator/ControlStruct/ForExprMutator.h

    r3848e0e rd9a0e76  
    77
    88namespace ControlStruct {
    9 
    10   class ForExprMutator : public Mutator
    11   {
    12   public:
    13     virtual Statement* mutate(ForStmt   *);
    14   };
    15 
     9    class ForExprMutator : public Mutator {
     10      public:
     11        virtual Statement *mutate( ForStmt * );
     12    };
    1613} // namespace ControlStruct
    1714
    18 #endif // #ifndef CHOOSE_MUTATOR_H
     15#endif // CHOOSE_MUTATOR_H
    1916
    2017/*
  • translator/ControlStruct/LabelFixer.cc

    r3848e0e rd9a0e76  
    99
    1010namespace ControlStruct {
    11   LabelFixer::Entry::Entry( Statement *to, Statement *from ) :
    12     definition ( to )
    13   {
    14     if ( from != 0 )
    15     usage.push_back( from );
    16   }
     11    LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) {
     12        if ( from != 0 )
     13            usage.push_back( from );
     14    }
    1715
    18   bool LabelFixer::Entry::insideLoop()
    19   {
    20     return ( dynamic_cast< ForStmt * > ( definition ) ||
    21              dynamic_cast< WhileStmt * > ( definition )  );
    22   }
     16    bool LabelFixer::Entry::insideLoop() {
     17        return ( dynamic_cast< ForStmt * > ( definition ) ||
     18                 dynamic_cast< WhileStmt * > ( definition )  );
     19    }
    2320
    24   LabelFixer::LabelFixer( LabelGenerator *gen ) : generator ( gen )
    25   {
    26     if ( generator == 0 )
    27       generator = LabelGenerator::getGenerator();
    28   }
     21    LabelFixer::LabelFixer( LabelGenerator *gen ) : generator ( gen ) {
     22        if ( generator == 0 )
     23            generator = LabelGenerator::getGenerator();
     24    }
    2925
    30   void LabelFixer::visit(FunctionDecl *functionDecl)
    31   {
    32     if ( functionDecl->get_statements() != 0 )
    33       functionDecl->get_statements()->accept( *this );
     26    void LabelFixer::visit(FunctionDecl *functionDecl) {
     27        if ( functionDecl->get_statements() != 0 )
     28            functionDecl->get_statements()->accept( *this );
    3429
    35     MLEMutator mlemut( resolveJumps(), generator );
    36     functionDecl->acceptMutator( mlemut );
    37   }
     30        MLEMutator mlemut( resolveJumps(), generator );
     31        functionDecl->acceptMutator( mlemut );
     32    }
    3833
    39   void LabelFixer::visit(Statement *stmt )
    40   {
    41     std::list< Label > &labels = stmt->get_labels();
     34    void LabelFixer::visit(Statement *stmt ) {
     35        std::list< Label > &labels = stmt->get_labels();
    4236
    43     if ( ! labels.empty() ) {
    44       Label current = setLabelsDef( labels, stmt );
    45       labels.clear();
    46       labels.push_front( current );
     37        if ( ! labels.empty() ) {
     38            Label current = setLabelsDef( labels, stmt );
     39            labels.clear();
     40            labels.push_front( current );
     41        } // if
    4742    }
    48   }
    4943
    50   void LabelFixer::visit(BranchStmt *branchStmt)
    51   {
    52     visit ( ( Statement * )branchStmt );  // the labels this statement might have
     44    void LabelFixer::visit(BranchStmt *branchStmt) {
     45        visit ( ( Statement * )branchStmt );  // the labels this statement might have
    5346
    54     Label target;
    55     if ( (target = branchStmt->get_target()) != "" ) {
    56       setLabelsUsg( target, branchStmt );
    57     } //else       /* computed goto or normal exit-loop statements */
    58   }
     47        Label target;
     48        if ( (target = branchStmt->get_target()) != "" ) {
     49            setLabelsUsg( target, branchStmt );
     50        } //else       /* computed goto or normal exit-loop statements */
     51    }
    5952
    6053
    61   Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition )
    62   {
    63     assert( definition != 0 );
    64     Entry *entry = new Entry( definition );
    65     bool used = false;
     54    Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
     55        assert( definition != 0 );
     56        Entry *entry = new Entry( definition );
     57        bool used = false;
    6658
    67     for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ )
    68       if ( labelTable.find( *i ) == labelTable.end() )
    69         { used = true; labelTable[ *i ] = entry; } // undefined and unused
    70       else
    71         if( labelTable[ *i ]->defined() )
    72           throw SemanticError("Duplicate definition of label: " + *i );
    73         else
    74           labelTable[ *i ]->set_definition( definition );
     59        for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ )
     60            if ( labelTable.find( *i ) == labelTable.end() )
     61                { used = true; labelTable[ *i ] = entry; } // undefined and unused
     62            else
     63                if( labelTable[ *i ]->defined() )
     64                    throw SemanticError("Duplicate definition of label: " + *i );
     65                else
     66                    labelTable[ *i ]->set_definition( definition );
    7567
    76     if (! used ) delete entry;
     68        if (! used ) delete entry;
    7769
    78     return labelTable[ llabel.front() ]->get_label();  // this *must* exist
    79   }
    80 
    81   Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use )
    82   {
    83     assert( use != 0 );
    84 
    85     if ( labelTable.find( orgValue ) != labelTable.end() )
    86       labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
    87     else
    88       labelTable[ orgValue ] = new Entry( 0, use );
    89 
    90     return labelTable[ orgValue ]->get_label();
    91   }
    92 
    93   std::map < Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError )
    94   {
    95     std::map < Statement *, Entry * > def_us;
    96 
    97     for( std::map < Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
    98       Entry *e = i->second;
    99 
    100       if ( def_us.find ( e->get_definition() ) == def_us.end() )
    101           def_us[ e->get_definition() ] = e;
    102       else
    103         if(e->used())
    104           def_us[ e->get_definition() ]->add_uses( e->get_uses() );
     70        return labelTable[ llabel.front() ]->get_label();  // this *must* exist
    10571    }
    10672
    107     // get rid of labelTable
    108     for( std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
    109       Statement *to = (*i).first;
    110       std::list < Statement *> &from = (*i).second->get_uses();
    111       Label finalLabel = generator->newLabel();
    112       (*i).second->set_label( finalLabel );
     73    Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
     74        assert( use != 0 );
    11375
    114       if ( to == 0 ) {
    115         BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back());
    116         Label undef("");
    117         if ( first_use != 0 )
    118           undef = first_use->get_target();
    119         throw SemanticError ( "'" + undef + "' label not defined");
    120       }
     76        if ( labelTable.find( orgValue ) != labelTable.end() )
     77            labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
     78        else
     79            labelTable[ orgValue ] = new Entry( 0, use );
    12180
    122       to->get_labels().clear();
    123       to->get_labels().push_back( finalLabel );
    124 
    125       for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) {
    126         BranchStmt *jumpTo = dynamic_cast < BranchStmt * > ( *j );
    127         assert( jumpTo != 0 );
    128         jumpTo->set_target( finalLabel );
    129       }
     81        return labelTable[ orgValue ]->get_label();
    13082    }
    13183
    132     // reverse table
    133     std::map < Label, Statement * > *ret = new std::map < Label, Statement * >();
    134     for(std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ )
    135       (*ret)[ (*i).second->get_label() ] = (*i).first;
     84    std::map < Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
     85        std::map < Statement *, Entry * > def_us;
    13686
    137     return ret;
    138   }
     87        for ( std::map < Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
     88            Entry *e = i->second;
    13989
     90            if ( def_us.find ( e->get_definition() ) == def_us.end() )
     91                def_us[ e->get_definition() ] = e;
     92            else
     93                if(e->used())
     94                    def_us[ e->get_definition() ]->add_uses( e->get_uses() );
     95        }
     96
     97        // get rid of labelTable
     98        for ( std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
     99            Statement *to = (*i).first;
     100            std::list < Statement *> &from = (*i).second->get_uses();
     101            Label finalLabel = generator->newLabel();
     102            (*i).second->set_label( finalLabel );
     103
     104            if ( to == 0 ) {
     105                BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back());
     106                Label undef("");
     107                if ( first_use != 0 )
     108                    undef = first_use->get_target();
     109                throw SemanticError ( "'" + undef + "' label not defined");
     110            }
     111
     112            to->get_labels().clear();
     113            to->get_labels().push_back( finalLabel );
     114
     115            for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) {
     116                BranchStmt *jumpTo = dynamic_cast < BranchStmt * > ( *j );
     117                assert( jumpTo != 0 );
     118                jumpTo->set_target( finalLabel );
     119            } // for
     120        } // for
     121
     122        // reverse table
     123        std::map < Label, Statement * > *ret = new std::map < Label, Statement * >();
     124        for (std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ )
     125            (*ret)[ (*i).second->get_label() ] = (*i).first;
     126
     127        return ret;
     128    }
    140129}  // namespace ControlStruct
  • translator/ControlStruct/LabelFixer.h

    r3848e0e rd9a0e76  
    1212
    1313namespace ControlStruct {
     14    class LabelFixer : public Visitor {
     15        typedef Visitor Parent;
     16      public:
     17        LabelFixer( LabelGenerator *gen = 0 );
    1418
    15   class LabelFixer : public Visitor
    16     {
    17       typedef Visitor Parent;
     19        std::map < Label, Statement * > *resolveJumps() throw ( SemanticError );
    1820
    19     public:
    20       LabelFixer( LabelGenerator *gen = 0 );
     21        // Declarations
     22        virtual void visit( FunctionDecl *functionDecl );
    2123
    22       std::map < Label, Statement * > *resolveJumps() throw ( SemanticError );
     24        // Statements
     25        void visit( Statement *stmt );
    2326
    24       // Declarations
    25       virtual void visit(FunctionDecl *functionDecl);
     27        virtual void visit( CompoundStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     28        virtual void visit( NullStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     29        virtual void visit( ExprStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     30        virtual void visit( IfStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     31        virtual void visit( WhileStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     32        virtual void visit( ForStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     33        virtual void visit( SwitchStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     34        virtual void visit( ChooseStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     35        virtual void visit( FallthruStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     36        virtual void visit( CaseStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     37        virtual void visit( ReturnStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     38        virtual void visit( TryStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     39        virtual void visit( CatchStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     40        virtual void visit( DeclStmt *stmt ) { visit( (Statement *)stmt ); return Parent::visit( stmt ); }
     41        virtual void visit( BranchStmt *branchStmt );
    2642
    27       // Statements
    28       void visit(Statement *stmt);
     43        Label setLabelsDef( std::list< Label > &, Statement *definition );
     44        Label setLabelsUsg( Label, Statement *usage = 0 );
    2945
    30       virtual void visit(CompoundStmt *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    31       virtual void visit(NullStmt     *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    32       virtual void visit(ExprStmt     *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    33       virtual void visit(IfStmt       *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    34       virtual void visit(WhileStmt    *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    35       virtual void visit(ForStmt      *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    36       virtual void visit(SwitchStmt   *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    37       virtual void visit(ChooseStmt   *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    38       virtual void visit(FallthruStmt *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    39       virtual void visit(CaseStmt     *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    40       virtual void visit(ReturnStmt   *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    41       virtual void visit(TryStmt      *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    42       virtual void visit(CatchStmt    *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    43       virtual void visit(DeclStmt     *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
    44       virtual void visit(BranchStmt   *branchStmt);
     46      private:
     47        class Entry {
     48          public:
     49            Entry( Statement *to = 0, Statement *from = 0 );
     50            bool used() { return ( usage.empty() ); }
     51            bool defined() { return ( definition != 0 ); }
     52            bool insideLoop();
    4553
    46       Label setLabelsDef( std::list< Label > &, Statement *definition );
    47       Label setLabelsUsg( Label, Statement *usage = 0 );
     54            Label get_label() const { return label; }
     55            Statement *get_definition() const { return definition; }
     56            std::list< Statement *> &get_uses() { return usage; }
    4857
    49     private:
    50       class Entry
    51       {
    52       public:
    53         Entry( Statement *to = 0, Statement *from = 0 );
    54         bool used() { return ( usage.empty() ); }
    55         bool defined() { return ( definition != 0 ); }
    56         bool insideLoop();
     58            void add_use ( Statement *use ) { usage.push_back( use ); }
     59            void add_uses ( std::list<Statement *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }
     60            void set_definition( Statement *def ) { definition = def; }
    5761
    58         Label get_label() const { return label; }
    59         Statement *get_definition() const { return definition; }
    60         std::list< Statement *> &get_uses() { return usage; }
    61 
    62         void add_use ( Statement *use ) { usage.push_back(use); }
    63         void add_uses ( std::list<Statement *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }
    64         void set_definition( Statement *def ) { definition = def; }
    65 
    66         void set_label( Label lab ) { label = lab; }
    67         Label gset_label() const { return label; }
    68       private:
    69         Label label; 
    70         Statement *definition;
    71         std::list<Statement *> usage;
    72       };
     62            void set_label( Label lab ) { label = lab; }
     63            Label gset_label() const { return label; }
     64          private:
     65            Label label; 
     66            Statement *definition;
     67            std::list<Statement *> usage;
     68        };
    7369             
    74       std::map < Label, Entry *> labelTable;
    75       LabelGenerator *generator;
     70        std::map < Label, Entry *> labelTable;
     71        LabelGenerator *generator;
    7672    };
    7773} // namespace ControlStruct
    7874
    79 #endif // #ifndef LABEL_FIXER_H
     75#endif // LABEL_FIXER_H
    8076
    8177/*
  • translator/ControlStruct/LabelGenerator.cc

    r3848e0e rd9a0e76  
    55
    66namespace ControlStruct {
     7    LabelGenerator *LabelGenerator::labelGenerator = 0;
    78
    8   LabelGenerator *LabelGenerator::labelGenerator = 0;
     9    LabelGenerator *LabelGenerator::getGenerator() {
     10        if ( LabelGenerator::labelGenerator == 0 )
     11            LabelGenerator::labelGenerator = new LabelGenerator();
    912
    10   LabelGenerator *LabelGenerator::getGenerator() {
    11     if ( LabelGenerator::labelGenerator == 0 )
    12       LabelGenerator::labelGenerator = new LabelGenerator();
     13        return labelGenerator;
     14    }
    1315
    14     return labelGenerator;
    15   }
    16 
    17   Label LabelGenerator::newLabel() {
    18     std::ostrstream os;
    19     os << "__L" << current++ << "__";// << std::ends;
    20     os.freeze( false );
    21     std::string ret = std::string (os.str(), os.pcount());
    22     return Label( ret );
    23   }
    24 
     16    Label LabelGenerator::newLabel() {
     17        std::ostrstream os;
     18        os << "__L" << current++ << "__";// << std::ends;
     19        os.freeze( false );
     20        std::string ret = std::string (os.str(), os.pcount());
     21        return Label( ret );
     22    }
    2523} // namespace ControlStruct
  • translator/ControlStruct/LabelGenerator.h

    r3848e0e rd9a0e76  
    55
    66namespace ControlStruct {
    7 
    8   class LabelGenerator
    9   {
    10   public:
    11     static LabelGenerator *getGenerator();
    12     Label newLabel();
    13     void reset() { current = 0; }
    14     void rewind() { current--; }
    15 
    16   protected:
    17     LabelGenerator(): current(0) {}
    18 
    19   private:
    20     int current;
    21     static LabelGenerator *labelGenerator;
    22   };
    23 
     7    class LabelGenerator {
     8      public:
     9        static LabelGenerator *getGenerator();
     10        Label newLabel();
     11        void reset() { current = 0; }
     12        void rewind() { current--; }
     13      protected:
     14        LabelGenerator(): current(0) {}
     15      private:
     16        int current;
     17        static LabelGenerator *labelGenerator;
     18    };
    2419} // namespace ControlStruct
    2520
    26 #endif // #ifndef LABEL_GENERATOR_H
     21#endif // LABEL_GENERATOR_H
    2722
    2823/*
  • translator/ControlStruct/LabelTypeChecker.cc

    r3848e0e rd9a0e76  
    1111
    1212namespace ControlStruct {
     13    void LabelTypeChecker::visit(UntypedExpr *untypedExpr){
     14        assert( untypedExpr != 0 );
     15        NameExpr *fname;
     16        if ( ((fname = dynamic_cast<NameExpr *>(untypedExpr->get_function())) != 0)
     17            && fname->get_name() == std::string("LabAddress") )
     18            std::cerr << "Taking the label of an address." << std::endl;
     19        else {
     20            acceptAll( untypedExpr->get_results(), *this );
     21            acceptAll( untypedExpr->get_args(), *this );
     22        } // if
     23        return;
     24    }
    1325
    14   void LabelTypeChecker::visit(UntypedExpr *untypedExpr){
    15     assert( untypedExpr != 0 );
    16     NameExpr *fname;
    17     if( ((fname = dynamic_cast<NameExpr *>(untypedExpr->get_function())) != 0)
    18         && fname->get_name() == std::string("LabAddress") )
    19       std::cerr << "Taking the label of an address." << std::endl;
    20     else {
    21       acceptAll( untypedExpr->get_results(), *this );
    22       acceptAll( untypedExpr->get_args(), *this );
     26    void LabelTypeChecker::visit(CompoundStmt *compoundStmt) {
     27        index.enterScope();
     28        acceptAll( compoundStmt->get_kids(), *this );
     29        index.leaveScope();
    2330    }
    24     return;
    25   }
    2631
    27   void LabelTypeChecker::visit(CompoundStmt *compoundStmt) {
    28     index.enterScope();
    29     acceptAll( compoundStmt->get_kids(), *this );
    30     index.leaveScope();
    31   }
     32    void LabelTypeChecker::visit(DeclStmt *declStmt){
     33        declStmt->accept( index );
    3234
    33   void LabelTypeChecker::visit(DeclStmt *declStmt){
    34     declStmt->accept( index );
     35        //ObjectDecl *odecl = 0;
     36        // if ( ( odecl = dynamic_cast<ObjectDecl *>(declStmt->get_decl()) ) != 0 ){
     37        return;
     38    }
    3539
    36     //ObjectDecl *odecl = 0;
    37     // if( ( odecl = dynamic_cast<ObjectDecl *>(declStmt->get_decl()) ) != 0 ){
    38     return;
    39   }
     40    void LabelTypeChecker::visit(BranchStmt *branchStmt) {
     41        if ( branchStmt->get_type() != BranchStmt::Goto ) return;
     42        Expression *target;
     43        if ( (target = branchStmt->get_computedTarget()) == 0 ) return;
    4044
    41   void LabelTypeChecker::visit(BranchStmt *branchStmt) {
    42     if( branchStmt->get_type() != BranchStmt::Goto ) return;
    43     Expression *target;
    44     if( (target = branchStmt->get_computedTarget()) == 0 ) return;
     45        NameExpr *name;
     46        if ( ((name = dynamic_cast<NameExpr *>(target)) == 0) )
     47            return; // Not a name expression
     48   
     49        std::list< DeclarationWithType * > interps;
     50        index.lookupId(name->get_name(), interps);
     51        if ( interps.size() != 1)
     52            // in case of multiple declarations
     53            throw SemanticError("Illegal label expression: " + name->get_name() );
    4554
    46     NameExpr *name;
    47     if( ((name = dynamic_cast<NameExpr *>(target)) == 0) )
    48       return; // Not a name expression
    49    
    50     std::list< DeclarationWithType * > interps;
    51     index.lookupId(name->get_name(), interps);
    52     if ( interps.size() != 1)
    53       // in case of multiple declarations
    54       throw SemanticError("Illegal label expression: " + name->get_name() );
     55        PointerType *ptr;
     56        if ( (ptr = dynamic_cast<PointerType *>(interps.front()->get_type())) != 0 )
     57            if ( dynamic_cast<VoidType *>(ptr->get_base()) != 0 )
     58                return;
     59            else
     60                throw SemanticError("Wrong type of parameter for computed goto");
     61        else
     62            throw SemanticError("Wrong type of parameter for computed goto");
    5563
    56     PointerType *ptr;
    57     if ( (ptr = dynamic_cast<PointerType *>(interps.front()->get_type())) != 0 )
    58       if ( dynamic_cast<VoidType *>(ptr->get_base()) != 0 )
    5964        return;
    60       else
    61         throw SemanticError("Wrong type of parameter for computed goto");
    62     else
    63         throw SemanticError("Wrong type of parameter for computed goto");
    64 
    65     return;
    66   }
     65    }
    6766} // namespace ControlStruct
    68 
    69 
    70 
    71 
    72 
  • translator/ControlStruct/LabelTypeChecker.h

    r3848e0e rd9a0e76  
    99
    1010namespace ControlStruct {
     11    class LabelTypeChecker : public Visitor {
     12      public:
     13        //LabelTypeChecker() {
    1114
    12   class LabelTypeChecker : public Visitor
    13   {
    14   public:
    15     //LabelTypeChecker() {
    16 
    17     virtual void visit(CompoundStmt *compoundStmt);
    18     virtual void visit(DeclStmt *declStmt);
    19     virtual void visit(BranchStmt *branchStmt);
    20     virtual void visit(UntypedExpr *untypedExpr);
    21   private:
    22     SymTab::Indexer index;
    23   };
    24 
     15        virtual void visit( CompoundStmt *compoundStmt );
     16        virtual void visit( DeclStmt *declStmt );
     17        virtual void visit( BranchStmt *branchStmt );
     18        virtual void visit( UntypedExpr *untypedExpr );
     19      private:
     20        SymTab::Indexer index;
     21    };
    2522} // namespace ControlStruct
    2623
    27 #endif // #ifndef LABEL_TYPE_H
     24#endif // LABEL_TYPE_H
    2825
    2926/*
  • translator/ControlStruct/MLEMutator.cc

    r3848e0e rd9a0e76  
    77
    88namespace ControlStruct {
    9   MLEMutator::~MLEMutator()
    10   {
    11     delete targetTable;
    12     targetTable = 0;
    13   }
    14 
    15   CompoundStmt* MLEMutator::mutate(CompoundStmt *cmpndStmt)
    16   {
    17     bool labeledBlock = false;
    18     if (!((cmpndStmt->get_labels()).empty())) {
    19       labeledBlock = true;
    20       enclosingBlocks.push_back( Entry( cmpndStmt ) );
     9    MLEMutator::~MLEMutator() {
     10        delete targetTable;
     11        targetTable = 0;
    2112    }
    2213
    23     std::list< Statement * > &kids = cmpndStmt->get_kids();
    24     for( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) {
    25       *k = (*k)->acceptMutator(*this);
     14    CompoundStmt* MLEMutator::mutate(CompoundStmt *cmpndStmt) {
     15        bool labeledBlock = false;
     16        if ( !((cmpndStmt->get_labels()).empty()) ) {
     17            labeledBlock = true;
     18            enclosingBlocks.push_back( Entry( cmpndStmt ) );
     19        }
    2620
    27       if (!get_breakLabel().empty()) {
    28         std::list< Statement * >::iterator next = k; next++;
    29         if( next == kids.end() ) {
    30           std::list<Label> ls; ls.push_back( get_breakLabel() );
    31           kids.push_back( new NullStmt(ls) );
    32         } else
    33           (*next)->get_labels().push_back( get_breakLabel() );
     21        std::list< Statement * > &kids = cmpndStmt->get_kids();
     22        for ( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) {
     23            *k = (*k)->acceptMutator(*this);
    3424
    35         set_breakLabel("");
    36       }
     25            if ( !get_breakLabel().empty() ) {
     26                std::list< Statement * >::iterator next = k; next++;
     27                if ( next == kids.end() ) {
     28                    std::list<Label> ls; ls.push_back( get_breakLabel() );
     29                    kids.push_back( new NullStmt(ls) );
     30                } else
     31                    (*next)->get_labels().push_back( get_breakLabel() );
     32
     33                set_breakLabel("");
     34            } // if
     35        } // for
     36
     37        if ( labeledBlock ) {
     38            assert( ! enclosingBlocks.empty() );
     39            if ( ! enclosingBlocks.back().get_breakExit().empty() )
     40                set_breakLabel( enclosingBlocks.back().get_breakExit() );
     41            enclosingBlocks.pop_back();
     42        } // if
     43
     44        //mutateAll( cmpndStmt->get_kids(), *this );
     45        return cmpndStmt;
    3746    }
    3847
    39     if ( labeledBlock ) {
    40       assert( ! enclosingBlocks.empty() );
    41       if( ! enclosingBlocks.back().get_breakExit().empty() )
    42         set_breakLabel( enclosingBlocks.back().get_breakExit() );
    43       enclosingBlocks.pop_back();
     48    Statement *MLEMutator::mutate( WhileStmt *whileStmt ) {
     49        enclosingLoops.push_back( Entry( whileStmt ) );
     50        whileStmt->set_body ( whileStmt->get_body()->acceptMutator( *this ) );
     51
     52        Entry &e = enclosingLoops.back();
     53        assert ( e == whileStmt );
     54        whileStmt->set_body( mutateLoop( whileStmt->get_body(), e ) );
     55        enclosingLoops.pop_back();
     56
     57        return whileStmt;
    4458    }
    4559
    46     //mutateAll( cmpndStmt->get_kids(), *this );
    47     return cmpndStmt;
    48   }
     60    Statement *MLEMutator::mutate( ForStmt *forStmt ) {
     61        enclosingLoops.push_back( Entry( forStmt ) );
     62        maybeMutate( forStmt->get_body(), *this );
    4963
    50   Statement *MLEMutator::mutate( WhileStmt *whileStmt )
    51   {
    52     enclosingLoops.push_back( Entry( whileStmt ) );
    53     whileStmt->set_body ( whileStmt->get_body()->acceptMutator( *this ) );
     64        Entry &e = enclosingLoops.back();
     65        assert ( e == forStmt );
     66        forStmt->set_body( mutateLoop( forStmt->get_body(), e ) );
     67        enclosingLoops.pop_back();
    5468
    55     Entry &e = enclosingLoops.back();
    56     assert ( e == whileStmt );
    57     whileStmt->set_body( mutateLoop( whileStmt->get_body(), e ) );
    58     enclosingLoops.pop_back();
    59 
    60     return whileStmt;
    61   }
    62 
    63   Statement *MLEMutator::mutate( ForStmt *forStmt )
    64   {
    65     enclosingLoops.push_back( Entry( forStmt ) );
    66     maybeMutate( forStmt->get_body(), *this );
    67 
    68     Entry &e = enclosingLoops.back();
    69     assert ( e == forStmt );
    70     forStmt->set_body( mutateLoop( forStmt->get_body(), e ) );
    71     enclosingLoops.pop_back();
    72 
    73     return forStmt;
    74   }
    75 
    76   Statement *MLEMutator::mutate( BranchStmt *branchStmt )
    77     throw ( SemanticError )
    78   {
    79     if ( branchStmt->get_type() == BranchStmt::Goto )
    80       return branchStmt;
    81 
    82     // test if continue target is a loop
    83     if ( branchStmt->get_type() == BranchStmt::Continue && enclosingLoops.empty() )
    84       throw SemanticError( "'continue' outside a loop" );
    85 
    86   if ( branchStmt->get_type() == BranchStmt::Break && (enclosingLoops.empty() && enclosingSwitches.empty() && enclosingBlocks.empty() ) )
    87       throw SemanticError( "'break' outside a loop or switch" );
    88 
    89     if ( branchStmt->get_target() == "" ) return branchStmt;
    90 
    91     if ( targetTable->find( branchStmt->get_target() ) == targetTable->end() )
    92       throw SemanticError("The label defined in the exit loop statement does not exist." );  // shouldn't happen (since that's already checked)
    93 
    94     std::list< Entry >::iterator check;
    95     if ( ( check = std::find( enclosingLoops.begin(), enclosingLoops.end(), (*targetTable)[branchStmt->get_target()] ) ) == enclosingLoops.end() )
    96       // not in loop, checking if in switch/choose
    97       if ( (check = std::find( enclosingBlocks.begin(), enclosingBlocks.end(), (*targetTable)[branchStmt->get_target()] )) == enclosingBlocks.end() )
    98         // neither in loop nor in block, checking if in switch/choose
    99         if ( (check = std::find( enclosingSwitches.begin(), enclosingSwitches.end(), (*targetTable)[branchStmt->get_target()] )) == enclosingSwitches.end() )
    100           throw SemanticError("The target specified in the exit loop statement does not correspond to an enclosing loop.");
    101 
    102     if ( enclosingLoops.back() == (*check) )
    103       return branchStmt;                      // exit the innermost loop (labels not necessary)
    104 
    105     Label newLabel;
    106     switch( branchStmt->get_type() ) {
    107     case BranchStmt::Break:
    108       if ( check->get_breakExit() != "" )
    109         newLabel = check->get_breakExit();
    110       else
    111         { newLabel = generator->newLabel(); check->set_breakExit( newLabel ); }
    112       break;
    113     case BranchStmt::Continue:
    114       if ( check->get_contExit() != "" )
    115         newLabel = check->get_contExit();
    116       else
    117         { newLabel = generator->newLabel(); check->set_contExit( newLabel ); }
    118       break;
    119 
    120     default:
    121       // shouldn't be here
    122       return 0;
     69        return forStmt;
    12370    }
    12471
    125     return new BranchStmt(std::list<Label>(), newLabel, BranchStmt::Goto );
    126   }
     72    Statement *MLEMutator::mutate( BranchStmt *branchStmt ) throw ( SemanticError ) {
     73        if ( branchStmt->get_type() == BranchStmt::Goto )
     74            return branchStmt;
     75
     76        // test if continue target is a loop
     77        if ( branchStmt->get_type() == BranchStmt::Continue && enclosingLoops.empty() )
     78            throw SemanticError( "'continue' outside a loop" );
     79
     80        if ( branchStmt->get_type() == BranchStmt::Break && (enclosingLoops.empty() && enclosingSwitches.empty() && enclosingBlocks.empty() ) )
     81            throw SemanticError( "'break' outside a loop or switch" );
     82
     83        if ( branchStmt->get_target() == "" ) return branchStmt;
     84
     85        if ( targetTable->find( branchStmt->get_target() ) == targetTable->end() )
     86            throw SemanticError("The label defined in the exit loop statement does not exist." );  // shouldn't happen (since that's already checked)
     87
     88        std::list< Entry >::iterator check;
     89        if ( ( check = std::find( enclosingLoops.begin(), enclosingLoops.end(), (*targetTable)[branchStmt->get_target()] ) ) == enclosingLoops.end() )
     90            // not in loop, checking if in switch/choose
     91            if ( (check = std::find( enclosingBlocks.begin(), enclosingBlocks.end(), (*targetTable)[branchStmt->get_target()] )) == enclosingBlocks.end() )
     92                // neither in loop nor in block, checking if in switch/choose
     93                if ( (check = std::find( enclosingSwitches.begin(), enclosingSwitches.end(), (*targetTable)[branchStmt->get_target()] )) == enclosingSwitches.end() )
     94                    throw SemanticError("The target specified in the exit loop statement does not correspond to an enclosing loop.");
     95
     96        if ( enclosingLoops.back() == (*check) )
     97            return branchStmt;                      // exit the innermost loop (labels not necessary)
     98
     99        Label newLabel;
     100        switch( branchStmt->get_type() ) {
     101          case BranchStmt::Break:
     102            if ( check->get_breakExit() != "" )
     103                newLabel = check->get_breakExit();
     104            else { newLabel = generator->newLabel(); check->set_breakExit( newLabel ); }
     105            break;
     106          case BranchStmt::Continue:
     107            if ( check->get_contExit() != "" )
     108                newLabel = check->get_contExit();
     109            else { newLabel = generator->newLabel(); check->set_contExit( newLabel ); }
     110            break;
     111          default:
     112            // shouldn't be here
     113            return 0;
     114        } // switch
     115
     116        return new BranchStmt(std::list<Label>(), newLabel, BranchStmt::Goto );
     117    }
    127118
    128119
    129   Statement *MLEMutator::mutate(SwitchStmt *switchStmt)
    130   {
    131     Label brkLabel = generator->newLabel();
    132     enclosingSwitches.push_back( Entry(switchStmt, "", brkLabel) );
    133     mutateAll( switchStmt->get_branches(), *this );
    134     {
    135       // check if this is necessary (if there is a break to this point, otherwise do not generate
    136       std::list<Label> temp; temp.push_back( brkLabel );
    137       switchStmt->get_branches().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
    138     }
    139     assert ( enclosingSwitches.back() == switchStmt );
    140     enclosingSwitches.pop_back();
    141     return switchStmt;
    142   }
    143 
    144   Statement *MLEMutator::mutate(ChooseStmt *switchStmt)
    145   {
    146     Label brkLabel = generator->newLabel();
    147     enclosingSwitches.push_back( Entry(switchStmt,"", brkLabel) );
    148     mutateAll( switchStmt->get_branches(), *this );
    149     {
    150       // check if this is necessary (if there is a break to this point, otherwise do not generate
    151       std::list<Label> temp; temp.push_back( brkLabel );
    152       switchStmt->get_branches().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
    153     }
    154     assert ( enclosingSwitches.back() == switchStmt );
    155     enclosingSwitches.pop_back();
    156     return switchStmt;
    157   }
    158 
    159   Statement *MLEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) {
    160     CompoundStmt *newBody;
    161     if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) {
    162       newBody = new CompoundStmt( std::list< Label >() );
    163       newBody->get_kids().push_back( bodyLoop );
     120    Statement *MLEMutator::mutate(SwitchStmt *switchStmt) {
     121        Label brkLabel = generator->newLabel();
     122        enclosingSwitches.push_back( Entry(switchStmt, "", brkLabel) );
     123        mutateAll( switchStmt->get_branches(), *this ); {
     124            // check if this is necessary (if there is a break to this point, otherwise do not generate
     125            std::list<Label> temp; temp.push_back( brkLabel );
     126            switchStmt->get_branches().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
     127        }
     128        assert ( enclosingSwitches.back() == switchStmt );
     129        enclosingSwitches.pop_back();
     130        return switchStmt;
    164131    }
    165132
    166     Label endLabel = e.get_contExit();
    167 
    168     if ( e.get_breakExit() != "" ) {
    169       if ( endLabel == "" ) endLabel = generator->newLabel();
    170       // check for whether this label is used or not, so as to not generate extraneous gotos
    171       if (e.breakExitUsed)
    172         newBody->get_kids().push_back( new BranchStmt( std::list< Label >(), endLabel, BranchStmt::Goto ) );
    173       // xxx
    174       //std::list< Label > ls; ls.push_back( e.get_breakExit() );
    175       set_breakLabel( e.get_breakExit() );
    176       //newBody->get_kids().push_back( new BranchStmt( ls, "", BranchStmt::Break ) );
     133    Statement *MLEMutator::mutate(ChooseStmt *switchStmt) {
     134        Label brkLabel = generator->newLabel();
     135        enclosingSwitches.push_back( Entry(switchStmt,"", brkLabel) );
     136        mutateAll( switchStmt->get_branches(), *this ); {
     137            // check if this is necessary (if there is a break to this point, otherwise do not generate
     138            std::list<Label> temp; temp.push_back( brkLabel );
     139            switchStmt->get_branches().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
     140        }
     141        assert ( enclosingSwitches.back() == switchStmt );
     142        enclosingSwitches.pop_back();
     143        return switchStmt;
    177144    }
    178145
    179     if ( e.get_breakExit() != "" || e.get_contExit() != "" ){
    180       if(dynamic_cast< NullStmt *>( newBody->get_kids().back() ))
    181         newBody->get_kids().back()->get_labels().push_back( endLabel );
    182       else {
    183         std::list < Label > ls; ls.push_back( endLabel );
    184         newBody->get_kids().push_back( new NullStmt( ls ) );
    185       }
     146    Statement *MLEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) {
     147        CompoundStmt *newBody;
     148        if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) {
     149            newBody = new CompoundStmt( std::list< Label >() );
     150            newBody->get_kids().push_back( bodyLoop );
     151        } // if
     152
     153        Label endLabel = e.get_contExit();
     154
     155        if ( e.get_breakExit() != "" ) {
     156            if ( endLabel == "" ) endLabel = generator->newLabel();
     157            // check for whether this label is used or not, so as to not generate extraneous gotos
     158            if (e.breakExitUsed)
     159                newBody->get_kids().push_back( new BranchStmt( std::list< Label >(), endLabel, BranchStmt::Goto ) );
     160            // xxx
     161            //std::list< Label > ls; ls.push_back( e.get_breakExit() );
     162            set_breakLabel( e.get_breakExit() );
     163            //newBody->get_kids().push_back( new BranchStmt( ls, "", BranchStmt::Break ) );
     164        } // if
     165
     166        if ( e.get_breakExit() != "" || e.get_contExit() != "" ){
     167            if (dynamic_cast< NullStmt *>( newBody->get_kids().back() ))
     168                newBody->get_kids().back()->get_labels().push_back( endLabel );
     169            else {
     170                std::list < Label > ls; ls.push_back( endLabel );
     171                newBody->get_kids().push_back( new NullStmt( ls ) );
     172            } // if
     173        } // if
     174
     175        return newBody;
    186176    }
    187177
    188     return newBody;
    189   }
     178    //*** Entry's methods
     179    void MLEMutator::Entry::set_contExit( Label l ) {
     180        assert ( contExit == "" || contExit == l );
     181        contExit = l;
     182    }
    190183
    191   //*** Entry's methods
    192   void MLEMutator::Entry::set_contExit( Label l )
    193   {
    194     assert ( contExit == "" || contExit == l );
    195     contExit = l;
    196   }
    197 
    198   void MLEMutator::Entry::set_breakExit( Label l )
    199   {
    200     assert ( breakExit == "" || breakExit == l );
    201     breakExit = l;
    202   }
    203 
     184    void MLEMutator::Entry::set_breakExit( Label l ) {
     185        assert ( breakExit == "" || breakExit == l );
     186        breakExit = l;
     187    }
    204188} // namespace ControlStruct
  • translator/ControlStruct/MLEMutator.h

    r3848e0e rd9a0e76  
    1212
    1313namespace ControlStruct {
     14    class MLEMutator : public Mutator {
     15        class Entry;
     16      public:
     17        MLEMutator( std::map <Label, Statement *> *t, LabelGenerator *gen = 0 ) : targetTable( t ), breakLabel(std::string("")), generator( gen ) {}
     18        ~MLEMutator();
    1419
    15   class MLEMutator : public Mutator {
    16     class Entry;
     20        CompoundStmt *mutate( CompoundStmt *cmpndStmt );
     21        Statement *mutate( WhileStmt *whileStmt );
     22        Statement *mutate( ForStmt *forStmt );
     23        Statement *mutate( BranchStmt *branchStmt ) throw ( SemanticError );
    1724
    18   public:
    19     MLEMutator( std::map <Label, Statement *> *t, LabelGenerator *gen = 0 ) : targetTable( t ), breakLabel(std::string("")), generator( gen ) {}
    20     ~MLEMutator();
     25        Statement *mutate( SwitchStmt *switchStmt );
     26        Statement *mutate( ChooseStmt *switchStmt );
    2127
    22     CompoundStmt *mutate( CompoundStmt *cmpndStmt );
    23     Statement *mutate( WhileStmt *whileStmt );
    24     Statement *mutate( ForStmt *forStmt );
    25     Statement *mutate( BranchStmt *branchStmt ) throw ( SemanticError );
     28        Statement *mutateLoop( Statement *bodyLoop, Entry &e );
    2629
    27     Statement *mutate( SwitchStmt *switchStmt );
    28     Statement *mutate( ChooseStmt *switchStmt );
     30        Label &get_breakLabel() { return breakLabel; }
     31        void set_breakLabel( Label newValue ) { breakLabel = newValue; }
     32      private:
     33        class Entry {
     34          public:
     35            explicit Entry( Statement *_loop = 0, Label _contExit = Label(""), Label _breakExit = Label("") ) :
     36                loop( _loop ), contExit( _contExit ), breakExit( _breakExit ), contExitUsed( false ), breakExitUsed( false ) {}
    2937
    30     Statement *mutateLoop( Statement *bodyLoop, Entry &e );
     38            bool operator==( const Statement *stmt ) { return ( loop == stmt ); }
     39            bool operator!=( const Statement *stmt ) { return ( loop != stmt ); }
    3140
    32     Label &get_breakLabel() { return breakLabel; }
    33     void set_breakLabel( Label newValue ) { breakLabel = newValue; }
     41            bool operator==( const Entry &other ) { return ( loop == other.get_loop() ); }
    3442
    35   private:
    36     class Entry {
    37     public:
    38       explicit Entry( Statement *_loop = 0, Label _contExit = Label(""), Label _breakExit = Label("") ) :
    39         loop( _loop ), contExit( _contExit ), breakExit( _breakExit ), contExitUsed( false ), breakExitUsed( false ) {}
     43            Statement *get_loop() const { return loop; }
    4044
    41       bool operator==( const Statement *stmt ) { return ( loop == stmt ) ; }
    42       bool operator!=( const Statement *stmt ) { return ( loop != stmt ) ; }
     45            Label get_contExit() const { return contExit; }
     46            void set_contExit( Label );
    4347
    44       bool operator==( const Entry &other ) { return ( loop == other.get_loop() ) ; }
     48            Label get_breakExit() const { return breakExit; }
     49            void set_breakExit( Label );
    4550
    46       Statement *get_loop() const { return loop; }
     51          private:
     52            Statement *loop;
     53            Label contExit, breakExit;
     54          public: // hack, provide proper [sg]etters
     55            bool contExitUsed, breakExitUsed;
     56        };
    4757
    48       Label get_contExit() const { return contExit; }
    49       void set_contExit( Label );
    50 
    51       Label get_breakExit() const { return breakExit; }
    52       void set_breakExit( Label );
    53 
    54     private:
    55       Statement *loop;
    56       Label contExit, breakExit;
    57     public: // hack, provide proper [sg]etters
    58       bool contExitUsed, breakExitUsed;
     58        std::map <Label, Statement *> *targetTable;
     59        std::list < Entry > enclosingBlocks,enclosingLoops,enclosingSwitches;
     60        Label breakLabel;
     61        LabelGenerator *generator;
    5962    };
    60 
    61     std::map <Label, Statement *> *targetTable;
    62     std::list < Entry > enclosingBlocks,enclosingLoops,enclosingSwitches;
    63     Label breakLabel;
    64     LabelGenerator *generator;
    65   };
    6663
    6764} // namespace ControlStruct
  • translator/ControlStruct/Mutate.cc

    r3848e0e rd9a0e76  
    2020
    2121namespace ControlStruct {
     22    void mutate( std::list< Declaration * > translationUnit ) {
     23        ChooseMutator chmut;
     24        ForExprMutator formut;
     25        CaseRangeMutator ranges;  // has to run after ChooseMutator
     26        LabelFixer lfix;
     27        //ExceptMutator exc;
     28        LabelTypeChecker lbl;
    2229
    23   void mutate( std::list< Declaration * > translationUnit )
    24   {
    25     ChooseMutator chmut;
    26     ForExprMutator formut;
    27     CaseRangeMutator ranges;  // has to run after ChooseMutator
    28     LabelFixer lfix;
    29     //ExceptMutator exc;
    30     LabelTypeChecker lbl;
    31 
    32     mutateAll( translationUnit , formut );
    33     acceptAll( translationUnit , lfix );
    34     mutateAll( translationUnit , chmut );
    35     mutateAll( translationUnit , ranges );
    36     //mutateAll( translationUnit , exc );
    37     //acceptAll( translationUnit , lbl );
    38   }
    39 
     30        mutateAll( translationUnit, formut );
     31        acceptAll( translationUnit, lfix );
     32        mutateAll( translationUnit, chmut );
     33        mutateAll( translationUnit, ranges );
     34        //mutateAll( translationUnit, exc );
     35        //acceptAll( translationUnit, lbl );
     36    }
    4037} // namespace CodeGen
    41 
    42 
  • translator/ControlStruct/Mutate.h

    r3848e0e rd9a0e76  
    88
    99namespace ControlStruct {
    10 
    11   void mutate( std::list< Declaration* > translationUnit );
    12 
     10    void mutate( std::list< Declaration* > translationUnit );
    1311} // namespace ControlStruct
    1412
    15 #endif // #ifndef CTRLS_MUTATE_H
     13#endif // CTRLS_MUTATE_H
    1614
    1715/*
  • translator/Designators/Processor.cc

    r3848e0e rd9a0e76  
    66
    77namespace Designators {
     8    Matcher::Matcher( const std::list< DeclarationWithType * > &decls ) {
     9        int cnt = 0;
     10        for ( std::list< DeclarationWithType * >::const_iterator i = decls.begin();
     11             i != decls.end(); i++, cnt++ ) {
     12            std::string newName = (*i)->get_name();
     13            if ( table.find( newName ) == table.end() ) {
     14                table.insert( std::pair<std::string, int>(newName, cnt) );
     15                order.push_back( newName );
     16                declarations.push_back( *i );
     17                alternatives.push_back( 0 );
     18            }
     19        }
     20    }
    821
    9   Matcher::Matcher( const std::list< DeclarationWithType * > &decls ) {
    10     int cnt = 0;
    11     for( std::list< DeclarationWithType * >::const_iterator i = decls.begin();
    12          i != decls.end(); i++, cnt++ ) {
    13       std::string newName = (*i)->get_name();
    14       if( table.find( newName ) == table.end() ) {
    15         table.insert( std::pair<std::string, int>(newName, cnt) );
    16         order.push_back( newName );
    17         declarations.push_back( *i );
    18         alternatives.push_back( 0 );
    19       }
     22    template< class InputIterator >
     23    bool Matcher::add(InputIterator begin, InputIterator end, ResolvExpr::Alternative &alt ) {
     24        while ( begin != end ) {
     25            if ( table.find( *begin ) != table.end() )
     26                alternatives[ table[ *begin ] ] = new ResolvExpr::Alternative(alt);
     27            else
     28                return false;
     29            begin++;
     30        }
     31        return true;
    2032    }
    21   }
    2233
    23   template< class InputIterator >
    24   bool Matcher::add(InputIterator begin, InputIterator end, ResolvExpr::Alternative &alt ) {
    25     while( begin != end ) {
    26       if ( table.find( *begin ) != table.end() )
    27         alternatives[ table[ *begin ] ] = new ResolvExpr::Alternative(alt);
    28       else
    29         return false;
    30       begin++;
     34    template< class InputIterator, class OutputIterator >
     35    bool Matcher::slice(InputIterator begin, InputIterator end, OutputIterator out ) {
     36        while ( begin != end )
     37            if ( table.find( *begin ) != table.end() )
     38                *out++ = declarations [ table[ *begin++ ] ];
     39            else
     40                return false; // throw 0;
     41        return true;
    3142    }
    32     return true;
    33   }
    3443
    35   template< class InputIterator, class OutputIterator >
    36   bool Matcher::slice(InputIterator begin, InputIterator end, OutputIterator out ) {
    37     while( begin != end )
    38       if ( table.find( *begin ) != table.end() )
    39         *out++ = declarations [ table[ *begin++ ] ];
    40       else
    41         return false; // throw 0;
    42     return true;
    43   }
     44    template< class OutputIterator >
     45    bool Matcher::get_reorderedCall( OutputIterator out ) {
     46        // fill call with defaults, if need be
     47        for (Matcher::iterator o = begin(); o != end(); o++ )
     48            if ( alternatives[ table[ *o ] ] == 0 )
     49                return false;
     50            else
     51                out++ = *alternatives[table[ *o ]];
     52        return true;
     53    }
    4454
    45   template< class OutputIterator >
    46   bool Matcher::get_reorderedCall( OutputIterator out ) {
    47     // fill call with defaults, if need be
    48     for (Matcher::iterator o = begin(); o != end(); o++ )
    49       if ( alternatives[ table[ *o ] ] == 0 )
    50         return false;
    51       else
    52         out++ = *alternatives[table[ *o ]];
    53     return true;
    54   }
     55    bool fixDesignations( ResolvExpr::AlternativeFinder &finder, Expression *designation ) {
     56        // Distribute `designation' over alternatives contained in `finder'
     57        if ( ! designation) return false;
     58        else
     59            for ( ResolvExpr::AlternativeFinder::iterator alt = finder.begin(); alt != finder.end(); alt++ )
     60                alt->expr->set_argName( designation );
     61        return true;
     62    }
    5563
    56   bool fixDesignations( ResolvExpr::AlternativeFinder &finder, Expression *designation ) {
    57     /* Distribute `designation' over alternatives contained in `finder' */
    58     if (!designation) return false;
    59     else
    60       for( ResolvExpr::AlternativeFinder::iterator alt = finder.begin(); alt != finder.end(); alt++ )
    61         alt->expr->set_argName( designation );
    62     return true;
    63   }
     64    template < class OutputIterator >
     65    bool extractNames( Expression *expr, OutputIterator out, Matcher matcher ) {
     66        Expression *designator = expr->get_argName();
     67        if ( designator == 0 ) return false;
    6468
    65   template < class OutputIterator >
    66   bool extractNames( Expression *expr, OutputIterator out, Matcher matcher ) {
    67     Expression *designator = expr->get_argName();
    68     if ( designator == 0 ) return false;
     69        if ( NameExpr *ndes = dynamic_cast<NameExpr *>(designator) )
     70            out++ = ndes->get_name();
     71        else if ( TupleExpr *tdes = dynamic_cast<TupleExpr *>(designator) ) {
     72            std::cerr << "Tuple designation" << std::endl;
     73//      ObjectDecl *decl = extractTupleV(matcher, tdes); // xxx
     74            // transform?
     75            for ( std::list< Expression * >::iterator n = tdes->get_exprs().begin();
     76                 n != tdes->get_exprs().end(); n++ ) {
    6977
    70     if( NameExpr *ndes = dynamic_cast<NameExpr *>(designator) )
    71         out++ = ndes->get_name();
    72     else if ( TupleExpr *tdes = dynamic_cast<TupleExpr *>(designator) ) {
    73       std::cerr << "Tuple designation" << std::endl;
    74 //      ObjectDecl *decl = extractTupleV(matcher, tdes); // xxx
    75       // transform?
    76       for( std::list< Expression * >::iterator n = tdes->get_exprs().begin();
    77            n != tdes->get_exprs().end(); n++ ) {
     78                if ( NameExpr *name = dynamic_cast<NameExpr *>(*n) )
     79                    out++ = name->get_name();
     80                else
     81                    // flatten nested Tuples
     82                    throw SemanticError( "Invalid tuple designation." );
     83            }
     84        }
     85        return true;
     86    }
    7887
    79         if ( NameExpr *name = dynamic_cast<NameExpr *>(*n) )
    80           out++ = name->get_name();
    81         else
    82           // flatten nested Tuples
    83           throw SemanticError( "Invalid tuple designation." );
    84       }
     88    std::string extractName( Expression *expr ) /* throw NoNameExtraction */ {
     89        if ( NameExpr *name = dynamic_cast< NameExpr *>(expr) )
     90            return name->get_name();
     91        else /* if () */
     92            throw 0;
    8593    }
    86     return true;
    87   }
    8894
    89   std::string extractName( Expression *expr ) /* throw NoNameExtraction */ {
    90     if( NameExpr *name = dynamic_cast< NameExpr *>(expr) )
    91       return name->get_name();
    92     else /* if() */
    93       throw 0;
    94   }
     95    DeclarationWithType *gensym( DeclarationWithType *, std::string prefix ) {
     96        return 0;
     97    }
    9598
    96   DeclarationWithType *gensym( DeclarationWithType *, std::string prefix ) {
    97     return 0;
    98   }
     99    ObjectDecl *extractTupleV( Matcher matcher, TupleExpr *nmTuple ) {
     100        // extract a subtuple of the function `fun' argument list, corresponding to the tuple of names requested by
     101        // `nmTuple'.
     102        std::list< Expression * > &exprs = nmTuple->get_exprs();
     103        std::cerr << "In extractTupleV, the tuple has " << exprs.size() << " components." << std::endl;
     104        std::list< std::string > names;
     105        std::transform( exprs.begin(), exprs.end(), back_inserter(names), extractName );
     106        std::list< DeclarationWithType * > decls;
     107        matcher.slice( names.begin(), names.end(), back_inserter(decls) );
     108        //std::for_each( decls.begin(), decls.end(), gensym );
     109        std::cerr << "Returning declaration with " << decls.size() << " components." << std::endl;
    99110
    100   ObjectDecl *extractTupleV( Matcher matcher, TupleExpr *nmTuple ) {
    101     /* extract a subtuple of the function `fun' argument list, corresponding to the tuple
    102        of names requested by `nmTuple'.
    103      */
    104     std::list< Expression * > &exprs = nmTuple->get_exprs();
    105     std::cerr << "In extractTupleV, the tuple has " << exprs.size() << " components." << std::endl;
    106     std::list< std::string > names;
    107     std::transform( exprs.begin(), exprs.end(), back_inserter(names), extractName );
    108     std::list< DeclarationWithType * > decls;
    109     matcher.slice( names.begin(), names.end(), back_inserter(decls) );
    110     //std::for_each( decls.begin(), decls.end(), gensym );
    111     std::cerr << "Returning declaration with " << decls.size() << " components." << std::endl;
     111        return 0;//new ObjectDecl()
     112    }
    112113
    113     return 0;//new ObjectDecl()
    114   }
     114    void check_alternative( FunctionType *fun, ResolvExpr::AltList &args ) {
     115        using namespace ResolvExpr;
    115116
    116   void check_alternative( FunctionType *fun, ResolvExpr::AltList &args ) {
    117     using namespace ResolvExpr;
     117        Matcher matcher( fun->get_parameters() );
     118        for ( AltList::iterator a = args.begin(); a != args.end(); a++ ) {
     119            std::list< std::string > actNames;
     120            if ( ! extractNames( a->expr, back_inserter(actNames), matcher ) ) {
     121                return; // not a designated call, leave alternative alone
     122            } else {
     123                // see if there's a match
     124                matcher.add( actNames.begin(), actNames.end(), *a );
     125            }
     126        }
     127        //AltList newArgs;
     128        args.clear();
     129        matcher.get_reorderedCall( back_inserter(args) );
    118130
    119     Matcher matcher( fun->get_parameters() );
    120     for ( AltList::iterator a = args.begin(); a != args.end(); a++ ) {
    121       std::list< std::string > actNames;
    122       if ( !extractNames( a->expr, back_inserter(actNames), matcher ) ) {
    123         return; // not a designated call, leave alternative alone
    124       } else {
    125         // see if there's a match
    126         matcher.add( actNames.begin(), actNames.end(), *a );
    127       }
     131        return;
    128132    }
    129     //AltList newArgs;
    130     args.clear();
    131     matcher.get_reorderedCall( back_inserter(args) );
    132 
    133     return;
    134   }
    135 
    136   /*
    137   void pruneAlternatives( Expression *expr, ResolvExpr::AlternativeFinder &finder ) {
    138     if ( expr->get_argName() != 0 ) {
    139       // Looking at designated expression
    140         using namespace ResolvExpr;
    141         AltList &alternatives = finder.get_alternatives();
    142         std::cerr << "Now printing alternatives: " << std::endl;
    143         for( AltList::iterator a = alternatives.begin(); a != alternatives.end(); a++ )
    144           a->expr->print( std::cerr );
    145         //std::cerr << "Looking for constructions of length no more than: " << tdes->get_exprs().size() << "." << std::endl;
    146       }
     133#if 0
     134    void pruneAlternatives( Expression *expr, ResolvExpr::AlternativeFinder &finder ) {
     135        if ( expr->get_argName() != 0 ) {
     136            // Looking at designated expression
     137            using namespace ResolvExpr;
     138            AltList &alternatives = finder.get_alternatives();
     139            std::cerr << "Now printing alternatives: " << std::endl;
     140            for ( AltList::iterator a = alternatives.begin(); a != alternatives.end(); a++ )
     141                a->expr->print( std::cerr );
     142            //std::cerr << "Looking for constructions of length no more than: " << tdes->get_exprs().size() << "." << std::endl;
     143        }
     144        return;
    147145    }
    148     return;
    149   }
    150   */
     146#endif // 0
    151147} // namespaces Designators
  • translator/Parser/DeclarationNode.cc

    r3848e0e rd9a0e76  
    103103}
    104104
    105 DeclarationNode *DeclarationNode::newFunction( std::string* name, DeclarationNode *ret, DeclarationNode *param, StatementNode *body, bool newStyle ) {
     105DeclarationNode *DeclarationNode::newFunction( std::string *name, DeclarationNode *ret, DeclarationNode *param, StatementNode *body, bool newStyle ) {
    106106    DeclarationNode *newnode = new DeclarationNode;
    107107    newnode->name = assign_strptr( name );
  • translator/Parser/InitializerNode.cc

    r3848e0e rd9a0e76  
    77#include <cassert>
    88
     9#include <iostream>
     10using namespace std;
    911
    1012InitializerNode::InitializerNode( ExpressionNode *_expr, bool aggrp, ExpressionNode *des )
     
    7274
    7375        std::list< Expression *> designlist;
    74         if ( designator != 0 )
     76
     77        if ( designator != 0 ) {
    7578            buildList<Expression, ExpressionNode>( designator, designlist );
     79        } // if
    7680
    7781        return new ListInit( initlist, designlist );
  • translator/ResolvExpr/AdjustExprType.cc

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: AdjustExprType.cc,v 1.3 2005/08/29 20:14:15 rcbilson Exp $
    5  *
    6  */
    7 
    81#include "typeops.h"
    92#include "SynTree/Type.h"
     
    125
    136namespace ResolvExpr {
     7    class AdjustExprType : public Mutator {
     8        typedef Mutator Parent;
     9      public:
     10        AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer );
     11      private:
     12        virtual Type* mutate(VoidType *voidType);
     13        virtual Type* mutate(BasicType *basicType);
     14        virtual Type* mutate(PointerType *pointerType);
     15        virtual Type* mutate(ArrayType *arrayType);
     16        virtual Type* mutate(FunctionType *functionType);
     17        virtual Type* mutate(StructInstType *aggregateUseType);
     18        virtual Type* mutate(UnionInstType *aggregateUseType);
     19        virtual Type* mutate(EnumInstType *aggregateUseType);
     20        virtual Type* mutate(ContextInstType *aggregateUseType);
     21        virtual Type* mutate(TypeInstType *aggregateUseType);
     22        virtual Type* mutate(TupleType *tupleType);
     23 
     24        const TypeEnvironment &env;
     25        const SymTab::Indexer &indexer;
     26    };
    1427
    15 class AdjustExprType : public Mutator
    16 {
    17   typedef Mutator Parent;
     28    void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     29        AdjustExprType adjuster( env, indexer );
     30        Type *newType = type->acceptMutator( adjuster );
     31        type = newType;
     32    }
    1833
    19 public:
    20   AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer );
     34    AdjustExprType::AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer )
     35        : env( env ), indexer( indexer ) {
     36    }
    2137
    22 private:
    23   virtual Type* mutate(VoidType *voidType);
    24   virtual Type* mutate(BasicType *basicType);
    25   virtual Type* mutate(PointerType *pointerType);
    26   virtual Type* mutate(ArrayType *arrayType);
    27   virtual Type* mutate(FunctionType *functionType);
    28   virtual Type* mutate(StructInstType *aggregateUseType);
    29   virtual Type* mutate(UnionInstType *aggregateUseType);
    30   virtual Type* mutate(EnumInstType *aggregateUseType);
    31   virtual Type* mutate(ContextInstType *aggregateUseType);
    32   virtual Type* mutate(TypeInstType *aggregateUseType);
    33   virtual Type* mutate(TupleType *tupleType);
    34  
    35   const TypeEnvironment &env;
    36   const SymTab::Indexer &indexer;
    37 };
     38    Type *AdjustExprType::mutate(VoidType *voidType) {
     39        return voidType;
     40    }
    3841
    39 void
    40 adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer )
    41 {
    42   AdjustExprType adjuster( env, indexer );
    43   Type *newType = type->acceptMutator( adjuster );
    44   type = newType;
    45 }
     42    Type *AdjustExprType::mutate(BasicType *basicType) {
     43        return basicType;
     44    }
    4645
    47 AdjustExprType::AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer )
    48   : env( env ), indexer( indexer )
    49 {
    50 }
     46    Type *AdjustExprType::mutate(PointerType *pointerType) {
     47        return pointerType;
     48    }
    5149
    52 Type*
    53 AdjustExprType::mutate(VoidType *voidType)
    54 {
    55   return voidType;
    56 }
     50    Type *AdjustExprType::mutate(ArrayType *arrayType) {
     51        PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone() );
     52        delete arrayType;
     53        return pointerType;
     54    }
    5755
    58 Type*
    59 AdjustExprType::mutate(BasicType *basicType)
    60 {
    61   return basicType;
    62 }
     56    Type *AdjustExprType::mutate(FunctionType *functionType) {
     57        PointerType *pointerType = new PointerType( Type::Qualifiers(), functionType );
     58        return pointerType;
     59    }
    6360
    64 Type*
    65 AdjustExprType::mutate(PointerType *pointerType)
    66 {
    67   return pointerType;
    68 }
     61    Type *AdjustExprType::mutate(StructInstType *aggregateUseType) {
     62        return aggregateUseType;
     63    }
    6964
    70 Type*
    71 AdjustExprType::mutate(ArrayType *arrayType)
    72 {
    73   PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone() );
    74   delete arrayType;
    75   return pointerType;
    76 }
     65    Type *AdjustExprType::mutate(UnionInstType *aggregateUseType) {
     66        return aggregateUseType;
     67    }
    7768
    78 Type*
    79 AdjustExprType::mutate(FunctionType *functionType)
    80 {
    81   PointerType *pointerType = new PointerType( Type::Qualifiers(), functionType );
    82   return pointerType;
    83 }
     69    Type *AdjustExprType::mutate(EnumInstType *aggregateUseType) {
     70        return aggregateUseType;
     71    }
    8472
    85 Type*
    86 AdjustExprType::mutate(StructInstType *aggregateUseType)
    87 {
    88   return aggregateUseType;
    89 }
     73    Type *AdjustExprType::mutate(ContextInstType *aggregateUseType) {
     74        return aggregateUseType;
     75    }
    9076
    91 Type*
    92 AdjustExprType::mutate(UnionInstType *aggregateUseType)
    93 {
    94   return aggregateUseType;
    95 }
     77    Type *AdjustExprType::mutate(TypeInstType *typeInst) {
     78        EqvClass eqvClass;
     79        if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     80            if ( eqvClass.kind == TypeDecl::Ftype ) {
     81                PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
     82                return pointerType;
     83            }
     84        } else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
     85            if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
     86                if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
     87                    PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
     88                    return pointerType;
     89                }
     90            }
     91        }
     92        return typeInst;
     93    }
    9694
    97 Type*
    98 AdjustExprType::mutate(EnumInstType *aggregateUseType)
    99 {
    100   return aggregateUseType;
    101 }
    102 
    103 Type*
    104 AdjustExprType::mutate(ContextInstType *aggregateUseType)
    105 {
    106   return aggregateUseType;
    107 }
    108 
    109 Type*
    110 AdjustExprType::mutate(TypeInstType *typeInst)
    111 {
    112   EqvClass eqvClass;
    113   if( env.lookup( typeInst->get_name(), eqvClass ) ) {
    114     if( eqvClass.kind == TypeDecl::Ftype ) {
    115       PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
    116       return pointerType;
     95    Type *AdjustExprType::mutate(TupleType *tupleType) {
     96        return tupleType;
    11797    }
    118   } else if( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
    119     if( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
    120       if( tyDecl->get_kind() == TypeDecl::Ftype ) {
    121         PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
    122         return pointerType;
    123       }
    124     }
    125   }
    126   return typeInst;
    127 }
    128 
    129 Type*
    130 AdjustExprType::mutate(TupleType *tupleType)
    131 {
    132   return tupleType;
    133 }
    134 
    135 
    13698} // namespace ResolvExpr
  • translator/ResolvExpr/Alternative.cc

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Alternative.cc,v 1.6 2005/08/29 20:14:15 rcbilson Exp $
    5  *
    6  */
    7 
    81#include "Alternative.h"
    92#include "SynTree/Type.h"
     
    125
    136namespace ResolvExpr {
     7    Alternative::Alternative() : expr( 0 ) {}
    148
    15 Alternative::Alternative()
    16   : expr( 0 )
    17 {
    18 }
     9    Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost )
     10        : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ) {}
    1911
    20 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost )
    21   : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env )
    22 {
    23 }
     12    Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost )
     13        : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ) {}
    2414
    25 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost )
    26   : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env )
    27 {
    28 }
     15    Alternative::Alternative( const Alternative &other ) {
     16        initialize( other, *this );
     17    }
    2918
    30 Alternative::Alternative( const Alternative &other )
    31 {
    32   initialize( other, *this );
    33 }
     19    Alternative &Alternative::operator=( const Alternative &other ) {
     20        if ( &other == this ) return *this;
     21        initialize( other, *this );
     22        return *this;
     23    }
    3424
    35 Alternative &
    36 Alternative::operator=( const Alternative &other )
    37 {
    38   if( &other == this ) return *this;
    39   initialize( other, *this );
    40   return *this;
    41 }
     25    void Alternative::initialize( const Alternative &src, Alternative &dest ) {
     26        dest.cost = src.cost;
     27        dest.cvtCost = src.cvtCost;
     28        dest.expr = maybeClone( src.expr );
     29        dest.env = src.env;
     30    }
    4231
    43 void
    44 Alternative::initialize( const Alternative &src, Alternative &dest )
    45 {
    46   dest.cost = src.cost;
    47   dest.cvtCost = src.cvtCost;
    48   dest.expr = maybeClone( src.expr );
    49   dest.env = src.env;
    50 }
     32    Alternative::~Alternative() {
     33        delete expr;
     34    }
    5135
    52 Alternative::~Alternative()
    53 {
    54   delete expr;
    55 }
    56 
    57 void
    58 Alternative::print( std::ostream &os, int indent ) const
    59 {
    60   os << std::string( indent, ' ' ) << "Cost " << cost << ": ";
    61   if( expr ) {
    62     expr->print( os, indent );
    63     os << "(types:" << std::endl;
    64     printAll( expr->get_results(), os, indent + 4 );
    65     os << ")" << std::endl;
    66   } else {
    67     os << "Null expression!" << std::endl;
    68   }
    69   os << std::string( indent, ' ' ) << "Environment: ";
    70   env.print( os, indent+2 );
    71   os << std::endl;
    72 }
    73 
    74 
     36    void Alternative::print( std::ostream &os, int indent ) const {
     37        os << std::string( indent, ' ' ) << "Cost " << cost << ": ";
     38        if ( expr ) {
     39            expr->print( os, indent );
     40            os << "(types:" << std::endl;
     41            printAll( expr->get_results(), os, indent + 4 );
     42            os << ")" << std::endl;
     43        } else {
     44            os << "Null expression!" << std::endl;
     45        }
     46        os << std::string( indent, ' ' ) << "Environment: ";
     47        env.print( os, indent+2 );
     48        os << std::endl;
     49    }
    7550} // namespace ResolvExpr
  • translator/ResolvExpr/Alternative.h

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Alternative.h,v 1.9 2005/08/29 20:14:15 rcbilson Exp $
    5  *
    6  */
    7 
    81#ifndef RESOLVEXPR_ALTERNATIVE_H
    92#define RESOLVEXPR_ALTERNATIVE_H
     
    158
    169namespace ResolvExpr {
     10    struct Alternative;
     11    typedef std::list< Alternative > AltList;
    1712
    18 struct Alternative;
    19 typedef std::list< Alternative > AltList;
    20 
    21 struct Alternative
    22 {
    23   Alternative();
    24   Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost );
    25   Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost );
    26   Alternative( const Alternative &other );
    27   Alternative &operator=( const Alternative &other );
    28   ~Alternative();
     13    struct Alternative {
     14        Alternative();
     15        Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost );
     16        Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost );
     17        Alternative( const Alternative &other );
     18        Alternative &operator=( const Alternative &other );
     19        ~Alternative();
    2920 
    30   void initialize( const Alternative &src, Alternative &dest );
     21        void initialize( const Alternative &src, Alternative &dest );
    3122 
    32   void print( std::ostream &os, int indent = 0 ) const;
     23        void print( std::ostream &os, int indent = 0 ) const;
    3324 
    34   Cost cost;
    35   Cost cvtCost;
    36   Expression *expr;
    37   TypeEnvironment env;
    38 };
    39 
    40 
     25        Cost cost;
     26        Cost cvtCost;
     27        Expression *expr;
     28        TypeEnvironment env;
     29    };
    4130} // namespace ResolvExpr
    4231
    43 #endif /* #ifndef RESOLVEXPR_ALTERNATIVE_H */
     32#endif // RESOLVEXPR_ALTERNATIVE_H
  • translator/ResolvExpr/AlternativeFinder.cc

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: AlternativeFinder.cc,v 1.36 2005/08/29 20:14:15 rcbilson Exp $
    5  *
    6  */
    7 
    81#include <list>
    92#include <iterator>
     
    3225#include "utility.h"
    3326
    34 
     27extern bool resolveVerbose;
     28#define PRINT( text ) if ( resolveVerbose ) { text }
    3529//#define DEBUG_COST
    3630
    3731namespace ResolvExpr {
    38 
    39 Expression *
    40 resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env )
    41 {
    42   CastExpr *castToVoid = new CastExpr( expr );
    43 
    44   AlternativeFinder finder( indexer, env );
    45   finder.findWithAdjustment( castToVoid );
    46 
    47   // it's a property of the language that a cast expression has either 1 or 0 interpretations;
    48   // if it has 0 interpretations, an exception has already been thrown.
    49   assert( finder.get_alternatives().size() == 1 );
    50   CastExpr *newExpr = dynamic_cast< CastExpr* >( finder.get_alternatives().front().expr );
    51   assert( newExpr );
    52   env = finder.get_alternatives().front().env;
    53   return newExpr->get_arg()->clone();
    54 }
    55 
    56 namespace {
    57 
    58   void
    59   printAlts( const AltList &list, std::ostream &os, int indent = 0 )
    60   {
    61     for( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
    62       i->print( os, indent );
    63       os << std::endl;
    64     }
    65   }
    66 
    67   void
    68   makeExprList( const AltList &in, std::list< Expression* > &out )
    69   {
    70     for( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
    71       out.push_back( i->expr->clone() );
    72     }
    73   }
    74 
    75   Cost
    76   sumCost( const AltList &in )
    77   {
    78     Cost total;
    79     for( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
    80       total += i->cost;
    81     }
    82     return total;
    83   }
    84 
    85   struct PruneStruct
    86   {
    87     bool isAmbiguous;
    88     AltList::iterator candidate;
    89     PruneStruct() {}
    90     PruneStruct( AltList::iterator candidate ): isAmbiguous( false ), candidate( candidate ) {}
    91   };
    92 
    93   template< typename InputIterator, typename OutputIterator >
    94   void
    95   pruneAlternatives( InputIterator begin, InputIterator end, OutputIterator out, const SymTab::Indexer &indexer )
    96   {
    97     // select the alternatives that have the minimum conversion cost for a particular set of result types
    98     std::map< std::string, PruneStruct > selected;
    99     for( AltList::iterator candidate = begin; candidate != end; ++candidate ) {
    100       PruneStruct current( candidate );
    101       std::string mangleName;
    102       for( std::list< Type* >::const_iterator retType = candidate->expr->get_results().begin(); retType != candidate->expr->get_results().end(); ++retType ) {
    103         Type *newType = (*retType)->clone();
    104         candidate->env.apply( newType );
    105         mangleName += SymTab::Mangler::mangle( newType );
    106         delete newType;
    107       }
    108       std::map< std::string, PruneStruct >::iterator mapPlace = selected.find( mangleName );
    109       if( mapPlace != selected.end() ) {
    110         if( candidate->cost < mapPlace->second.candidate->cost ) {
    111 ///           std::cout << "cost " << candidate->cost << " beats " << target->second.cost << std::endl;
    112           selected[ mangleName ] = current;
    113         } else if( candidate->cost == mapPlace->second.candidate->cost ) {
    114 ///           std::cout << "marking ambiguous" << std::endl;
    115           mapPlace->second.isAmbiguous = true;
    116         }
    117       } else {
    118         selected[ mangleName ] = current;
    119       }
    120     }
    121 
    122 ///     std::cout << "there are " << selected.size() << " alternatives before elimination" << std::endl;
    123 
    124     // accept the alternatives that were unambiguous
    125     for( std::map< std::string, PruneStruct >::iterator target = selected.begin(); target != selected.end(); ++target) {
    126       if( !target->second.isAmbiguous ) {
    127         Alternative &alt = *target->second.candidate;
    128         for( std::list< Type* >::iterator result = alt.expr->get_results().begin(); result != alt.expr->get_results().end(); ++result ) {
    129           alt.env.applyFree( *result );
    130         }
    131         *out++ = alt;
    132       }
    133     }
    134 
    135   }
    136 
    137   template< typename InputIterator, typename OutputIterator >
    138   void
    139   findMinCost( InputIterator begin, InputIterator end, OutputIterator out )
    140   {
    141     AltList alternatives;
    142 
    143     // select the alternatives that have the minimum parameter cost
    144     Cost minCost = Cost::infinity;
    145     for( AltList::iterator i = begin; i != end; ++i ) {
    146       if( i->cost < minCost ) {
    147         minCost = i->cost;
    148         i->cost = i->cvtCost;
    149         alternatives.clear();
    150         alternatives.push_back( *i );
    151       } else if( i->cost == minCost ) {
    152         i->cost = i->cvtCost;
    153         alternatives.push_back( *i );
    154       }
    155     }
    156     std::copy( alternatives.begin(), alternatives.end(), out );
    157   }
    158 
    159   template< typename InputIterator >
    160   void
    161   simpleCombineEnvironments( InputIterator begin, InputIterator end, TypeEnvironment &result )
    162   {
    163     while( begin != end ) {
    164       result.simpleCombine( (*begin++).env );
    165     }
    166   }
    167 
    168   void
    169   renameTypes( Expression *expr )
    170   {
    171     for( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
    172       (*i)->accept( global_renamer );
    173     }
    174   }
    175 }
    176 
    177 template< typename InputIterator, typename OutputIterator >
    178 void
    179 AlternativeFinder::findSubExprs( InputIterator begin, InputIterator end, OutputIterator out )
    180 {
    181   while( begin != end ) {
    182     AlternativeFinder finder( indexer, env );
    183     finder.findWithAdjustment( *begin );
    184     // XXX  either this
    185     //Designators::fixDesignations( finder, (*begin++)->get_argName() );
    186     // or XXX this
    187     begin++;
    188 ///     std::cout << "findSubExprs" << std::endl;
    189 ///     printAlts( finder.alternatives, std::cout );
    190     *out++ = finder;
    191   }
    192 }
    193 
    194 AlternativeFinder::AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env )
    195   : indexer( indexer ), env( env )
    196 {
    197 }
    198 
    199 void
    200 AlternativeFinder::find( Expression *expr, bool adjust )
    201 {
    202   expr->accept( *this );
    203   if( alternatives.empty() ) {
    204     throw SemanticError( "No reasonable alternatives for expression ", expr );
    205   }
    206   for( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
    207     if( adjust ) {
    208       adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
    209     }
    210   }
    211 ///   std::cout << "alternatives before prune:" << std::endl;
    212 ///   printAlts( alternatives, std::cout );
    213   AltList::iterator oldBegin = alternatives.begin();
    214   pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ), indexer );
    215   if( alternatives.begin() == oldBegin ) {
    216     std::ostrstream stream;
    217     stream << "Can't choose between alternatives for expression ";
    218     expr->print( stream );
    219     stream << "Alternatives are:";
    220     AltList winners;
    221     findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
    222     printAlts( winners, stream, 8 );
    223     throw SemanticError( std::string( stream.str(), stream.pcount() ) );
    224   }
    225   alternatives.erase( oldBegin, alternatives.end() );
    226 ///   std::cout << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
    227 }
    228 
    229 void
    230 AlternativeFinder::findWithAdjustment( Expression *expr )
    231 {
    232   find( expr, true );
    233 }
    234 
    235 template< typename StructOrUnionType >
    236 void
    237 AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name )
    238 {
    239   std::list< Declaration* > members;
    240   aggInst->lookup( name, members );
    241   for( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    242     if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    243       alternatives.push_back( Alternative( new MemberExpr( dwt->clone(), expr->clone() ), env, newCost ) );
    244       renameTypes( alternatives.back().expr );
    245     } else {
    246       assert( false );
    247     }
    248   }
    249 }
    250 
    251 void
    252 AlternativeFinder::visit(ApplicationExpr *applicationExpr)
    253 {
    254   alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
    255 }
    256 
    257 Cost
    258 computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer )
    259 {
    260   ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( alt.expr );
    261   assert( appExpr );
    262   PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
    263   assert( pointer );
    264   FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
    265   assert( function );
    266 
    267   Cost convCost( 0, 0, 0 );
    268   std::list< DeclarationWithType* >& formals = function->get_parameters();
    269   std::list< DeclarationWithType* >::iterator formal = formals.begin();
    270   std::list< Expression* >& actuals = appExpr->get_args();
    271   for( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    272 ///     std::cout << "actual expression:" << std::endl;
    273 ///     (*actualExpr)->print( std::cout, 8 );
    274 ///     std::cout << "--- results are" << std::endl;
    275 ///     printAll( (*actualExpr)->get_results(), std::cout, 8 );
    276     std::list< DeclarationWithType* >::iterator startFormal = formal;
    277     Cost actualCost;
    278     for( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) {
    279       if( formal == formals.end() ) {
    280         if( function->get_isVarArgs() ) {
    281           convCost += Cost( 1, 0, 0 );
    282           break;
    283         } else {
    284           return Cost::infinity;
    285         }
    286       }
    287 ///       std::cout << std::endl << "converting ";
    288 ///       (*actual)->print( std::cout, 8 );
    289 ///       std::cout << std::endl << " to ";
    290 ///       (*formal)->get_type()->print( std::cout, 8 );
    291       Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
    292 ///       std::cout << std::endl << "cost is" << newCost << std::endl;
    293 
    294       if( newCost == Cost::infinity ) {
    295         return newCost;
    296       }
    297       convCost += newCost;
    298       actualCost += newCost;
    299 
    300       convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer), 0 );
    301 
    302       formal++;
    303     }
    304     if( actualCost != Cost( 0, 0, 0 ) ) {
    305       std::list< DeclarationWithType* >::iterator startFormalPlusOne = startFormal;
    306       startFormalPlusOne++;
    307       if( formal == startFormalPlusOne ) {
    308         // not a tuple type
    309         Type *newType = (*startFormal)->get_type()->clone();
    310         alt.env.apply( newType );
    311         *actualExpr = new CastExpr( *actualExpr, newType );
    312       } else {
    313         TupleType *newType = new TupleType( Type::Qualifiers() );
    314         for( std::list< DeclarationWithType* >::iterator i = startFormal; i != formal; ++i ) {
    315           newType->get_types().push_back( (*i)->get_type()->clone() );
    316         }
    317         alt.env.apply( newType );
    318         *actualExpr = new CastExpr( *actualExpr, newType );
    319       }
    320     }
    321 
    322   }
    323   if( formal != formals.end() ) {
    324     return Cost::infinity;
    325   }
    326 
    327   for( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
    328 ///     std::cout << std::endl << "converting ";
    329 ///     assert->second.actualType->print( std::cout, 8 );
    330 ///     std::cout << std::endl << " to ";
    331 ///     assert->second.formalType->print( std::cout, 8 );
    332     Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
    333 ///     std::cout << std::endl << "cost of conversion is " << newCost << std::endl;
    334     if( newCost == Cost::infinity ) {
    335       return newCost;
    336     }
    337     convCost += newCost;
    338 
    339     convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer), 0 );
    340   }
    341 
    342   return convCost;
    343 }
    344 
    345 void
    346 makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions )
    347 {
    348   for( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    349     unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind();
    350     for( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
    351       needAssertions[ *assert ] = true;
    352     }
     32    Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ) {
     33        CastExpr *castToVoid = new CastExpr( expr );
     34
     35        AlternativeFinder finder( indexer, env );
     36        finder.findWithAdjustment( castToVoid );
     37
     38        // it's a property of the language that a cast expression has either 1 or 0 interpretations; if it has 0
     39        // interpretations, an exception has already been thrown.
     40        assert( finder.get_alternatives().size() == 1 );
     41        CastExpr *newExpr = dynamic_cast< CastExpr* >( finder.get_alternatives().front().expr );
     42        assert( newExpr );
     43        env = finder.get_alternatives().front().env;
     44        return newExpr->get_arg()->clone();
     45    }
     46
     47    namespace {
     48        void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
     49            for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
     50                i->print( os, indent );
     51                os << std::endl;
     52            }
     53        }
     54
     55        void makeExprList( const AltList &in, std::list< Expression* > &out ) {
     56            for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
     57                out.push_back( i->expr->clone() );
     58            }
     59        }
     60
     61        Cost sumCost( const AltList &in ) {
     62            Cost total;
     63            for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
     64                total += i->cost;
     65            }
     66            return total;
     67        }
     68
     69        struct PruneStruct {
     70            bool isAmbiguous;
     71            AltList::iterator candidate;
     72            PruneStruct() {}
     73            PruneStruct( AltList::iterator candidate ): isAmbiguous( false ), candidate( candidate ) {}
     74        };
     75
     76        template< typename InputIterator, typename OutputIterator >
     77        void pruneAlternatives( InputIterator begin, InputIterator end, OutputIterator out, const SymTab::Indexer &indexer ) {
     78            // select the alternatives that have the minimum conversion cost for a particular set of result types
     79            std::map< std::string, PruneStruct > selected;
     80            for ( AltList::iterator candidate = begin; candidate != end; ++candidate ) {
     81                PruneStruct current( candidate );
     82                std::string mangleName;
     83                for ( std::list< Type* >::const_iterator retType = candidate->expr->get_results().begin(); retType != candidate->expr->get_results().end(); ++retType ) {
     84                    Type *newType = (*retType)->clone();
     85                    candidate->env.apply( newType );
     86                    mangleName += SymTab::Mangler::mangle( newType );
     87                    delete newType;
     88                }
     89                std::map< std::string, PruneStruct >::iterator mapPlace = selected.find( mangleName );
     90                if ( mapPlace != selected.end() ) {
     91                    if ( candidate->cost < mapPlace->second.candidate->cost ) {
     92                        PRINT(
     93                            std::cout << "cost " << candidate->cost << " beats " << mapPlace->second.candidate->cost << std::endl;
     94                            )
     95                        selected[ mangleName ] = current;
     96                    } else if ( candidate->cost == mapPlace->second.candidate->cost ) {
     97                        PRINT(
     98                            std::cout << "marking ambiguous" << std::endl;
     99                            )
     100                        mapPlace->second.isAmbiguous = true;
     101                    }
     102                } else {
     103                    selected[ mangleName ] = current;
     104                }
     105            }
     106
     107            PRINT(
     108                std::cout << "there are " << selected.size() << " alternatives before elimination" << std::endl;
     109                )
     110
     111            // accept the alternatives that were unambiguous
     112            for ( std::map< std::string, PruneStruct >::iterator target = selected.begin(); target != selected.end(); ++target ) {
     113                if ( !target->second.isAmbiguous ) {
     114                    Alternative &alt = *target->second.candidate;
     115                    for ( std::list< Type* >::iterator result = alt.expr->get_results().begin(); result != alt.expr->get_results().end(); ++result ) {
     116                        alt.env.applyFree( *result );
     117                    }
     118                    *out++ = alt;
     119                }
     120            }
     121
     122        }
     123
     124        template< typename InputIterator, typename OutputIterator >
     125        void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
     126            AltList alternatives;
     127
     128            // select the alternatives that have the minimum parameter cost
     129            Cost minCost = Cost::infinity;
     130            for ( AltList::iterator i = begin; i != end; ++i ) {
     131                if ( i->cost < minCost ) {
     132                    minCost = i->cost;
     133                    i->cost = i->cvtCost;
     134                    alternatives.clear();
     135                    alternatives.push_back( *i );
     136                } else if ( i->cost == minCost ) {
     137                    i->cost = i->cvtCost;
     138                    alternatives.push_back( *i );
     139                }
     140            }
     141            std::copy( alternatives.begin(), alternatives.end(), out );
     142        }
     143
     144        template< typename InputIterator >
     145        void simpleCombineEnvironments( InputIterator begin, InputIterator end, TypeEnvironment &result ) {
     146            while ( begin != end ) {
     147                result.simpleCombine( (*begin++).env );
     148            }
     149        }
     150
     151        void renameTypes( Expression *expr ) {
     152            for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
     153                (*i)->accept( global_renamer );
     154            }
     155        }
     156    }
     157
     158    template< typename InputIterator, typename OutputIterator >
     159    void AlternativeFinder::findSubExprs( InputIterator begin, InputIterator end, OutputIterator out ) {
     160        while ( begin != end ) {
     161            AlternativeFinder finder( indexer, env );
     162            finder.findWithAdjustment( *begin );
     163            // XXX  either this
     164            //Designators::fixDesignations( finder, (*begin++)->get_argName() );
     165            // or XXX this
     166            begin++;
     167            PRINT(
     168                std::cout << "findSubExprs" << std::endl;
     169                printAlts( finder.alternatives, std::cout );
     170                )
     171            *out++ = finder;
     172        }
     173    }
     174
     175    AlternativeFinder::AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env )
     176        : indexer( indexer ), env( env ) {
     177    }
     178
     179    void AlternativeFinder::find( Expression *expr, bool adjust ) {
     180        expr->accept( *this );
     181        if ( alternatives.empty() ) {
     182            throw SemanticError( "No reasonable alternatives for expression ", expr );
     183        }
     184        for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
     185            if ( adjust ) {
     186                adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
     187            }
     188        }
     189        PRINT(
     190            std::cout << "alternatives before prune:" << std::endl;
     191            printAlts( alternatives, std::cout );
     192            )
     193        AltList::iterator oldBegin = alternatives.begin();
     194        pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ), indexer );
     195        if ( alternatives.begin() == oldBegin ) {
     196            std::ostrstream stream;
     197            stream << "Can't choose between alternatives for expression ";
     198            expr->print( stream );
     199            stream << "Alternatives are:";
     200            AltList winners;
     201            findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
     202            printAlts( winners, stream, 8 );
     203            throw SemanticError( std::string( stream.str(), stream.pcount() ) );
     204        }
     205        alternatives.erase( oldBegin, alternatives.end() );
     206        PRINT(
     207            std::cout << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
     208            )
     209    }
     210
     211    void AlternativeFinder::findWithAdjustment( Expression *expr ) {
     212        find( expr, true );
     213    }
     214
     215    template< typename StructOrUnionType >
     216    void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name ) {
     217        std::list< Declaration* > members;
     218        aggInst->lookup( name, members );
     219        for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
     220            if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
     221                alternatives.push_back( Alternative( new MemberExpr( dwt->clone(), expr->clone() ), env, newCost ) );
     222                renameTypes( alternatives.back().expr );
     223            } else {
     224                assert( false );
     225            }
     226        }
     227    }
     228
     229    void AlternativeFinder::visit( ApplicationExpr *applicationExpr ) {
     230        alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
     231    }
     232
     233    Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
     234        ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( alt.expr );
     235        assert( appExpr );
     236        PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
     237        assert( pointer );
     238        FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
     239        assert( function );
     240
     241        Cost convCost( 0, 0, 0 );
     242        std::list< DeclarationWithType* >& formals = function->get_parameters();
     243        std::list< DeclarationWithType* >::iterator formal = formals.begin();
     244        std::list< Expression* >& actuals = appExpr->get_args();
     245        for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
     246            PRINT(
     247                std::cout << "actual expression:" << std::endl;
     248                (*actualExpr)->print( std::cout, 8 );
     249                std::cout << "--- results are" << std::endl;
     250                printAll( (*actualExpr)->get_results(), std::cout, 8 );
     251                )
     252            std::list< DeclarationWithType* >::iterator startFormal = formal;
     253            Cost actualCost;
     254            for ( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) {
     255                if ( formal == formals.end() ) {
     256                    if ( function->get_isVarArgs() ) {
     257                        convCost += Cost( 1, 0, 0 );
     258                        break;
     259                    } else {
     260                        return Cost::infinity;
     261                    }
     262                }
     263                PRINT(
     264                    std::cout << std::endl << "converting ";
     265                    (*actual)->print( std::cout, 8 );
     266                    std::cout << std::endl << " to ";
     267                    (*formal)->get_type()->print( std::cout, 8 );
     268                    )
     269                Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
     270                PRINT(
     271                    std::cout << std::endl << "cost is" << newCost << std::endl;
     272                    )
     273
     274                if ( newCost == Cost::infinity ) {
     275                    return newCost;
     276                }
     277                convCost += newCost;
     278                actualCost += newCost;
     279
     280                convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
     281
     282                formal++;
     283            }
     284            if ( actualCost != Cost( 0, 0, 0 ) ) {
     285                std::list< DeclarationWithType* >::iterator startFormalPlusOne = startFormal;
     286                startFormalPlusOne++;
     287                if ( formal == startFormalPlusOne ) {
     288                    // not a tuple type
     289                    Type *newType = (*startFormal)->get_type()->clone();
     290                    alt.env.apply( newType );
     291                    *actualExpr = new CastExpr( *actualExpr, newType );
     292                } else {
     293                    TupleType *newType = new TupleType( Type::Qualifiers() );
     294                    for ( std::list< DeclarationWithType* >::iterator i = startFormal; i != formal; ++i ) {
     295                        newType->get_types().push_back( (*i)->get_type()->clone() );
     296                    }
     297                    alt.env.apply( newType );
     298                    *actualExpr = new CastExpr( *actualExpr, newType );
     299                }
     300            }
     301
     302        }
     303        if ( formal != formals.end() ) {
     304            return Cost::infinity;
     305        }
     306
     307        for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
     308            PRINT(
     309                std::cout << std::endl << "converting ";
     310                assert->second.actualType->print( std::cout, 8 );
     311                std::cout << std::endl << " to ";
     312                assert->second.formalType->print( std::cout, 8 );
     313                )
     314            Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
     315            PRINT(
     316                std::cout << std::endl << "cost of conversion is " << newCost << std::endl;
     317                )
     318            if ( newCost == Cost::infinity ) {
     319                return newCost;
     320            }
     321            convCost += newCost;
     322
     323            convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 );
     324        }
     325
     326        return convCost;
     327    }
     328
     329    void makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions ) {
     330        for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
     331            unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind();
     332            for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
     333                needAssertions[ *assert ] = true;
     334            }
    353335///     needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() );
    354   }
    355 }
    356 
    357 bool
    358 AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave )
    359 {
    360   std::list< TypeEnvironment > toBeDone;
    361   simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
    362   // make sure we don't widen any existing bindings
    363   for( TypeEnvironment::iterator i = resultEnv.begin(); i != resultEnv.end(); ++i ) {
    364     i->allowWidening  = false;
    365   }
    366   resultEnv.extractOpenVars( openVars );
    367 
    368   /*
    369   Tuples::NameMatcher matcher( formals );
    370   try {
    371     matcher.match( actuals );
    372   } catch ( Tuples::NoMatch &e ) {
    373     std::cerr << "Alternative doesn't match: " << e.message << std::endl;
    374   }
    375   */
    376   std::list< DeclarationWithType* >::iterator formal = formals.begin();
    377   for( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    378     for( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) {
    379       if( formal == formals.end() ) {
    380         return isVarArgs;
    381       }
    382 ///       std::cerr << "formal type is ";
    383 ///       (*formal)->get_type()->print( std::cerr );
    384 ///       std::cerr << std::endl << "actual type is ";
    385 ///       (*actual)->print( std::cerr );
    386 ///       std::cerr << std::endl;
    387       if( !unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    388         return false;
    389       }
    390       formal++;
    391     }
    392   }
    393   // Handling of default values
    394   while( formal != formals.end() ) {
    395     if( ObjectDecl *od = dynamic_cast<ObjectDecl *>( *formal ) )
    396       if( SingleInit *si = dynamic_cast<SingleInit *>( od->get_init() ))
    397         // so far, only constant expressions are accepted as default values
    398         if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>(si->get_value()) )
    399           if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) )
    400             if( unify( (*formal)->get_type(), cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    401               // XXX Don't know if this is right
    402               actuals.push_back( Alternative( cnstexpr->clone(), env, Cost::zero ) );
    403               formal++;
    404               if (formal == formals.end()) break;
    405             }
    406     return false;
    407   }
    408   return true;
    409 }
    410 
    411 static const int recursionLimit = 10;
    412 
    413 void
    414 addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer )
    415 {
    416   for( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
    417     if( i->second == true ) {
    418       i->first->accept( indexer );
    419     }
    420   }
    421 }
    422 
    423 template< typename ForwardIterator, typename OutputIterator >
    424 void
    425 inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out )
    426 {
    427   if( begin == end ) {
    428     if( newNeed.empty() ) {
    429       *out++ = newAlt;
    430       return;
    431     } else if( level >= recursionLimit ) {
    432       throw SemanticError( "Too many recursive assertions" );
    433     } else {
    434       AssertionSet newerNeed;
    435 ///       std::cerr << "recursing with new set:" << std::endl;
    436 ///       printAssertionSet( newNeed, std::cerr, 8 );
    437       inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
    438       return;
    439     }
    440   }
    441 
    442   ForwardIterator cur = begin++;
    443   if( !cur->second ) {
    444     inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
    445   }
    446   DeclarationWithType *curDecl = cur->first;
    447 ///   std::cerr << "inferRecursive: assertion is ";
    448 ///   curDecl->print( std::cerr );
    449 ///   std::cerr << std::endl;
    450   std::list< DeclarationWithType* > candidates;
    451   decls.lookupId( curDecl->get_name(), candidates );
    452 ///   if( candidates.empty() ) { std::cout << "no candidates!" << std::endl; }
    453   for( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) {
    454 ///     std::cout << "inferRecursive: candidate is ";
    455 ///     (*candidate)->print( std::cout );
    456 ///     std::cout << std::endl;
    457     AssertionSet newHave, newerNeed( newNeed );
    458     TypeEnvironment newEnv( newAlt.env );
    459     OpenVarSet newOpenVars( openVars );
    460     Type *adjType = (*candidate)->get_type()->clone();
    461     adjustExprType( adjType, newEnv, indexer );
    462     adjType->accept( global_renamer );
    463 ///     std::cerr << "unifying ";
    464 ///     curDecl->get_type()->print( std::cerr );
    465 ///     std::cerr << " with ";
    466 ///     adjType->print( std::cerr );
    467 ///     std::cerr << std::endl;
    468     if( unify( curDecl->get_type(), adjType, newEnv, newerNeed, newHave, newOpenVars, indexer ) ) {
    469 ///       std::cerr << "success!" << std::endl;
    470       SymTab::Indexer newDecls( decls );
    471       addToIndexer( newHave, newDecls );
    472       Alternative newerAlt( newAlt );
    473       newerAlt.env = newEnv;
    474       assert( (*candidate)->get_uniqueId() );
    475       Expression *varExpr = new VariableExpr( static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ) );
    476       deleteAll( varExpr->get_results() );
    477       varExpr->get_results().clear();
    478       varExpr->get_results().push_front( adjType->clone() );
    479 ///       std::cout << "satisfying assertion " << curDecl->get_uniqueId() << " ";
    480 ///       curDecl->print( std::cout );
    481 ///       std::cout << " with declaration " << (*candidate)->get_uniqueId() << " ";
    482 ///       (*candidate)->print( std::cout );
    483 ///       std::cout << std::endl;
    484       ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr );
    485       // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    486       appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    487       inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
    488     } else {
    489       delete adjType;
    490     }
    491   }
    492 }
    493 
    494 template< typename OutputIterator >
    495 void
    496 AlternativeFinder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out )
    497 {
    498 ///   std::cout << "inferParameters: assertions needed are" << std::endl;
    499 ///   printAll( need, std::cout, 8 );
    500   SymTab::Indexer decls( indexer );
    501 ///   std::cout << "============= original indexer" << std::endl;
    502 ///   indexer.print( std::cout );
    503 ///   std::cout << "============= new indexer" << std::endl;
    504 ///   decls.print( std::cout );
    505   addToIndexer( have, decls );
    506   AssertionSet newNeed;
    507   inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
    508 ///   std::cout << "declaration 14 is ";
    509 ///   Declaration::declFromId
    510 ///    *out++ = newAlt;
    511 }
    512 
    513 template< typename OutputIterator >
    514 void
    515 AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out )
    516 {
    517   OpenVarSet openVars;
    518   AssertionSet resultNeed, resultHave;
    519   TypeEnvironment resultEnv;
    520   makeUnifiableVars( funcType, openVars, resultNeed );
    521   if( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) {
    522     ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
    523     Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) );
    524     makeExprList( actualAlt, appExpr->get_args() );
    525 ///     std::cout << "need assertions:" << std::endl;
    526 ///     printAssertionSet( resultNeed, std::cout, 8 );
    527     inferParameters( resultNeed, resultHave, newAlt, openVars, out );
    528   }
    529 }
    530 
    531 void
    532 AlternativeFinder::visit(UntypedExpr *untypedExpr)
    533 {
    534   bool doneInit = false;
    535   AlternativeFinder funcOpFinder( indexer, env );
    536 
    537   AlternativeFinder funcFinder( indexer, env );
    538   {
    539     NameExpr *fname;
    540     if ( (fname = dynamic_cast<NameExpr *>(untypedExpr->get_function()))
    541          && ( fname->get_name() == std::string("LabAddress")) ) {
    542         alternatives.push_back( Alternative(untypedExpr, env, Cost()) );
    543         return;
    544       }
    545   }
    546 
    547   funcFinder.findWithAdjustment( untypedExpr->get_function() );
    548   std::list< AlternativeFinder > argAlternatives;
    549   findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), back_inserter( argAlternatives ) );
    550 
    551   std::list< AltList > possibilities;
    552   combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
    553 
    554   Tuples::TupleAssignSpotter tassign(this);
    555   if ( tassign.isTupleAssignment(untypedExpr, possibilities) ) {
    556     // take care of possible tuple assignments, or discard expression
    557     return;
    558   } // else ...
    559 
    560   AltList candidates;
    561 
    562   for( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
    563 ///     std::cout << "working on alternative: " << std::endl;
    564 ///     func->print( std::cout, 8 );
    565     // check if the type is pointer to function
    566     PointerType *pointer;
    567     if( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
    568       if( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    569         for( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    570           // XXX
    571           //Designators::check_alternative( function, *actualAlt );
    572           makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    573         }
    574       } else if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
    575         EqvClass eqvClass;
    576         if( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
    577           if( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
    578             for( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    579               makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    580             }
    581           }
    582         }
    583       }
    584     } else {
    585       // seek a function operator that's compatible
    586       if( !doneInit ) {
    587         doneInit = true;
    588         NameExpr *opExpr = new NameExpr( "?()" );
    589         try {
    590           funcOpFinder.findWithAdjustment( opExpr );
    591         } catch( SemanticError &e ) {
    592           // it's ok if there aren't any defined function ops
    593         }
    594 ///         std::cout << "known function ops:" << std::endl;
    595 ///         printAlts( funcOpFinder.alternatives, std::cout, 8 );
    596       }
    597 
    598       for( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
    599         // check if the type is pointer to function
    600         PointerType *pointer;
    601         if( funcOp->expr->get_results().size() == 1
    602                 && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
    603           if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    604             for( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    605               AltList currentAlt;
    606               currentAlt.push_back( *func );
    607               currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
    608               makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
    609             }
    610           }
    611         }
    612       }
    613     }
    614   }
    615 
    616   for( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
    617     Cost cvtCost = computeConversionCost( *withFunc, indexer );
    618 
    619 #ifdef DEBUG_COST
    620     ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr );
    621     assert( appExpr );
    622     PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
    623     assert( pointer );
    624     FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
    625     assert( function );
    626     std::cout << "Case +++++++++++++" << std::endl;
    627     std::cout << "formals are:" << std::endl;
    628     printAll( function->get_parameters(), std::cout, 8 );
    629     std::cout << "actuals are:" << std::endl;
    630     printAll( appExpr->get_args(), std::cout, 8 );
    631     std::cout << "bindings are:" << std::endl;
    632     withFunc->env.print( std::cout, 8 );
    633     std::cout << "cost of conversion is:" << cvtCost << std::endl;
    634 #endif
    635 
    636     if( cvtCost != Cost::infinity ) {
    637       withFunc->cvtCost = cvtCost;
    638       alternatives.push_back( *withFunc );
    639     }
    640   }
    641   candidates.clear();
    642   candidates.splice( candidates.end(), alternatives );
    643 
    644   findMinCost( candidates.begin(), candidates.end(), std::back_inserter( alternatives ) );
    645 }
    646 
    647 bool
    648 isLvalue( Expression *expr ) {
    649   for( std::list< Type* >::const_iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
    650     if( !(*i)->get_isLvalue() ) return false;
    651   }
    652   return true;
    653 }
    654 
    655 void
    656 AlternativeFinder::visit(AddressExpr *addressExpr)
    657 {
    658   AlternativeFinder finder( indexer, env );
    659   finder.find( addressExpr->get_arg() );
    660   for( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) {
    661     if( isLvalue( i->expr ) ) {
    662       alternatives.push_back( Alternative( new AddressExpr( i->expr->clone() ), i->env, i->cost ) );
    663     }
    664   }
    665 }
    666 
    667 void
    668 AlternativeFinder::visit(CastExpr *castExpr)
    669 {
    670   for( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) {
    671     SymTab::validateType( *i, &indexer );
    672     adjustExprType( *i, env, indexer );
    673   }
    674 
    675   AlternativeFinder finder( indexer, env );
    676   finder.findWithAdjustment( castExpr->get_arg() );
    677 
    678   AltList candidates;
    679   for( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) {
    680     AssertionSet needAssertions, haveAssertions;
    681     OpenVarSet openVars;
    682 
    683     // It's possible that a cast can throw away some values in a multiply-valued expression.
    684     // (An example is a cast-to-void, which casts from one value to zero.)
    685     // Figure out the prefix of the subexpression results that are cast directly.
    686     // The candidate is invalid if it has fewer results than there are types to cast to.
    687     int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
    688     if( discardedValues < 0 ) continue;
    689     std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin();
    690     std::advance( candidate_end, castExpr->get_results().size() );
    691     if( !unifyList( (*i).expr->get_results().begin(), candidate_end,
    692         castExpr->get_results().begin(), castExpr->get_results().end(), i->env, needAssertions, haveAssertions, openVars, indexer ) ) continue;
    693     Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end,
    694         castExpr->get_results().begin(), castExpr->get_results().end(), indexer, i->env );
    695     if( thisCost != Cost::infinity ) {
    696       // count one safe conversion for each value that is thrown away
    697       thisCost += Cost( 0, 0, discardedValues );
    698       CastExpr *newExpr = castExpr->clone();
    699       newExpr->set_arg( i->expr->clone() );
    700       candidates.push_back( Alternative( newExpr, i->env, i->cost, thisCost ) );
    701     }
    702   }
    703 
    704   // findMinCost selects the alternatives with the lowest "cost" members, but has the side effect
    705   // of copying the cvtCost member to the cost member (since the old cost is now irrelevant).
    706   // Thus, calling findMinCost twice selects first based on argument cost, then on conversion cost.
    707   AltList minArgCost;
    708   findMinCost( candidates.begin(), candidates.end(), std::back_inserter( minArgCost ) );
    709   findMinCost( minArgCost.begin(), minArgCost.end(), std::back_inserter( alternatives ) );
    710 }
    711 
    712 void
    713 AlternativeFinder::visit(UntypedMemberExpr *memberExpr)
    714 {
    715   AlternativeFinder funcFinder( indexer, env );
    716   funcFinder.findWithAdjustment( memberExpr->get_aggregate() );
    717 
    718   for( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
    719     if( agg->expr->get_results().size() == 1 ) {
    720       if( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) {
    721         addAggMembers( structInst, agg->expr, agg->cost, memberExpr->get_member() );
    722       } else if( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) {
    723         addAggMembers( unionInst, agg->expr, agg->cost, memberExpr->get_member() );
    724       }
    725     }
    726   }
    727 }
    728 
    729 void
    730 AlternativeFinder::visit(MemberExpr *memberExpr)
    731 {
    732   alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) );
    733 }
    734 
    735 void
    736 AlternativeFinder::visit(NameExpr *nameExpr)
    737 {
    738   std::list< DeclarationWithType* > declList;
    739   indexer.lookupId( nameExpr->get_name(), declList );
    740 ///     std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl;
    741   for( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
    742     VariableExpr newExpr( *i, nameExpr->get_argName() );
    743     alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
    744 ///     std::cerr << "decl is ";
    745 ///     (*i)->print( std::cerr );
    746 ///     std::cerr << std::endl;
    747 ///     std::cerr << "newExpr is ";
    748 ///     newExpr.print( std::cerr );
    749 ///     std::cerr << std::endl;
    750     renameTypes( alternatives.back().expr );
    751     if( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
    752       addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), "" );
    753     } else if( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
    754       addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), "" );
    755     }
    756   }
    757 }
    758 
    759 void
    760 AlternativeFinder::visit(VariableExpr *variableExpr)
    761 {
    762   alternatives.push_back( Alternative( variableExpr->clone(), env, Cost::zero ) );
    763 }
    764 
    765 void
    766 AlternativeFinder::visit(ConstantExpr *constantExpr)
    767 {
    768   alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) );
    769 }
    770 
    771 void
    772 AlternativeFinder::visit(SizeofExpr *sizeofExpr)
    773 {
    774   if( sizeofExpr->get_isType() ) {
    775     alternatives.push_back( Alternative( sizeofExpr->clone(), env, Cost::zero ) );
    776   } else {
    777     AlternativeFinder finder( indexer, env );
    778     finder.find( sizeofExpr->get_expr() );
    779     if( finder.alternatives.size() != 1 ) {
    780       throw SemanticError( "Ambiguous expression in sizeof operand: ", sizeofExpr->get_expr() );
    781     }
    782     Alternative &choice = finder.alternatives.front();
    783     alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
    784   }
    785 }
    786 
    787 void
    788 AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env )
    789 {
    790   // assume no polymorphism
    791   // assume no implicit conversions
    792   assert( function->get_parameters().size() == 1 );
    793 ///   std::cout << "resolvAttr: funcDecl is ";
    794 ///   funcDecl->print( std::cout );
    795 ///   std::cout << " argType is ";
    796 ///   argType->print( std::cout );
    797 ///   std::cout << std::endl;
    798   if( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
    799     alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
    800     for( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
    801       alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() );
    802     }
    803   }
    804 }
    805 
    806 void
    807 AlternativeFinder::visit(AttrExpr *attrExpr)
    808 {
    809   // assume no 'pointer-to-attribute'
    810   NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
    811   assert( nameExpr );
    812   std::list< DeclarationWithType* > attrList;
    813   indexer.lookupId( nameExpr->get_name(), attrList );
    814   if( attrExpr->get_isType() || attrExpr->get_expr() ) {
    815     for( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
    816       // check if the type is function
    817       if( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) {
    818         // assume exactly one parameter
    819         if( function->get_parameters().size() == 1 ) {
    820           if( attrExpr->get_isType() ) {
    821             resolveAttr( *i, function, attrExpr->get_type(), env );
    822           } else {
    823             AlternativeFinder finder( indexer, env );
    824             finder.find( attrExpr->get_expr() );
    825             for( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    826               if( choice->expr->get_results().size() == 1 ) {
    827                 resolveAttr(*i, function, choice->expr->get_results().front(), choice->env );
    828               }
    829             }
    830           }
    831         }
    832       }
    833     }
    834   } else {
    835     for( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
    836       VariableExpr newExpr( *i );
    837       alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
    838       renameTypes( alternatives.back().expr );
    839     }
    840   }
    841 }
    842 
    843 void
    844 AlternativeFinder::visit(LogicalExpr *logicalExpr)
    845 {
    846   AlternativeFinder firstFinder( indexer, env );
    847   firstFinder.findWithAdjustment( logicalExpr->get_arg1() );
    848   for( AltList::const_iterator first = firstFinder.alternatives.begin(); first != firstFinder.alternatives.end(); ++first ) {
    849     AlternativeFinder secondFinder( indexer, first->env );
    850     secondFinder.findWithAdjustment( logicalExpr->get_arg2() );
    851     for( AltList::const_iterator second = secondFinder.alternatives.begin(); second != secondFinder.alternatives.end(); ++second ) {
    852       LogicalExpr *newExpr = new LogicalExpr( first->expr->clone(), second->expr->clone(), logicalExpr->get_isAnd() );
    853       alternatives.push_back( Alternative( newExpr, second->env, first->cost + second->cost ) );
    854     }
    855   }
    856 }
    857 
    858 void
    859 AlternativeFinder::visit(ConditionalExpr *conditionalExpr)
    860 {
    861   AlternativeFinder firstFinder( indexer, env );
    862   firstFinder.findWithAdjustment( conditionalExpr->get_arg1() );
    863   for( AltList::const_iterator first = firstFinder.alternatives.begin(); first != firstFinder.alternatives.end(); ++first ) {
    864     AlternativeFinder secondFinder( indexer, first->env );
    865     secondFinder.findWithAdjustment( conditionalExpr->get_arg2() );
    866     for( AltList::const_iterator second = secondFinder.alternatives.begin(); second != secondFinder.alternatives.end(); ++second ) {
    867       AlternativeFinder thirdFinder( indexer, second->env );
    868       thirdFinder.findWithAdjustment( conditionalExpr->get_arg3() );
    869       for( AltList::const_iterator third = thirdFinder.alternatives.begin(); third != thirdFinder.alternatives.end(); ++third ) {
    870         OpenVarSet openVars;
    871         AssertionSet needAssertions, haveAssertions;
    872         Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost );
    873         std::list< Type* > commonTypes;
    874         if( unifyList( second->expr->get_results().begin(), second->expr->get_results().end(), third->expr->get_results().begin(), third->expr->get_results().end(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
    875           ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
    876           std::list< Type* >::const_iterator original = second->expr->get_results().begin();
    877           std::list< Type* >::const_iterator commonType = commonTypes.begin();
    878           for( ; original != second->expr->get_results().end() && commonType != commonTypes.end(); ++original, ++commonType ) {
    879             if( *commonType ) {
    880               newExpr->get_results().push_back( *commonType );
    881             } else {
    882               newExpr->get_results().push_back( (*original)->clone() );
    883             }
    884           }
    885           newAlt.expr = newExpr;
    886           inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
    887         }
    888       }
    889     }
    890   }
    891 }
    892 
    893 void
    894 AlternativeFinder::visit(CommaExpr *commaExpr)
    895 {
    896   TypeEnvironment newEnv( env );
    897   Expression *newFirstArg = resolveInVoidContext( commaExpr->get_arg1(), indexer, newEnv );
    898   AlternativeFinder secondFinder( indexer, newEnv );
    899   secondFinder.findWithAdjustment( commaExpr->get_arg2() );
    900   for( AltList::const_iterator alt = secondFinder.alternatives.begin(); alt != secondFinder.alternatives.end(); ++alt ) {
    901     alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt->expr->clone() ), alt->env, alt->cost ) );
    902   }
    903   delete newFirstArg;
    904 }
    905 
    906 void
    907 AlternativeFinder::visit(TupleExpr *tupleExpr)
    908 {
    909   std::list< AlternativeFinder > subExprAlternatives;
    910   findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) );
    911   std::list< AltList > possibilities;
    912   combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) );
    913   for( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) {
    914     TupleExpr *newExpr = new TupleExpr;
    915     makeExprList( *i, newExpr->get_exprs() );
    916     for( std::list< Expression* >::const_iterator resultExpr = newExpr->get_exprs().begin(); resultExpr != newExpr->get_exprs().end(); ++resultExpr ) {
    917       for( std::list< Type* >::const_iterator resultType = (*resultExpr)->get_results().begin(); resultType != (*resultExpr)->get_results().end(); ++resultType ) {
    918         newExpr->get_results().push_back( (*resultType)->clone() );
    919       }
    920     }
    921 
    922     TypeEnvironment compositeEnv;
    923     simpleCombineEnvironments( i->begin(), i->end(), compositeEnv );
    924     alternatives.push_back( Alternative( newExpr, compositeEnv, sumCost( *i ) ) );
    925   }
    926 }
    927 
     336        }
     337    }
     338
     339    bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) {
     340        std::list< TypeEnvironment > toBeDone;
     341        simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
     342        // make sure we don't widen any existing bindings
     343        for ( TypeEnvironment::iterator i = resultEnv.begin(); i != resultEnv.end(); ++i ) {
     344            i->allowWidening  = false;
     345        }
     346        resultEnv.extractOpenVars( openVars );
     347
     348        /*
     349          Tuples::NameMatcher matcher( formals );
     350          try {
     351          matcher.match( actuals );
     352          } catch ( Tuples::NoMatch &e ) {
     353          std::cerr << "Alternative doesn't match: " << e.message << std::endl;
     354          }
     355        */
     356        std::list< DeclarationWithType* >::iterator formal = formals.begin();
     357        for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
     358            for ( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) {
     359                if ( formal == formals.end() ) {
     360                    return isVarArgs;
     361                }
     362                PRINT(
     363                    std::cerr << "formal type is ";
     364                    (*formal)->get_type()->print( std::cerr );
     365                    std::cerr << std::endl << "actual type is ";
     366                    (*actual)->print( std::cerr );
     367                    std::cerr << std::endl;
     368                    )
     369                if ( !unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
     370                    return false;
     371                }
     372                formal++;
     373            }
     374        }
     375        // Handling of default values
     376        while ( formal != formals.end() ) {
     377            if ( ObjectDecl *od = dynamic_cast<ObjectDecl *>( *formal ) )
     378                if ( SingleInit *si = dynamic_cast<SingleInit *>( od->get_init() ))
     379                    // so far, only constant expressions are accepted as default values
     380                    if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) )
     381                        if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) )
     382                            if ( unify( (*formal)->get_type(), cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
     383                                // XXX Don't know if this is right
     384                                actuals.push_back( Alternative( cnstexpr->clone(), env, Cost::zero ) );
     385                                formal++;
     386                                if ( formal == formals.end()) break;
     387                            }
     388            return false;
     389        }
     390        return true;
     391    }
     392
     393    static const int recursionLimit = 10;
     394
     395    void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
     396        for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
     397            if ( i->second == true ) {
     398                i->first->accept( indexer );
     399            }
     400        }
     401    }
     402
     403    template< typename ForwardIterator, typename OutputIterator >
     404    void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) {
     405        if ( begin == end ) {
     406            if ( newNeed.empty() ) {
     407                *out++ = newAlt;
     408                return;
     409            } else if ( level >= recursionLimit ) {
     410                throw SemanticError( "Too many recursive assertions" );
     411            } else {
     412                AssertionSet newerNeed;
     413                PRINT(
     414                    std::cerr << "recursing with new set:" << std::endl;
     415                    printAssertionSet( newNeed, std::cerr, 8 );
     416                    )
     417                inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
     418                return;
     419            }
     420        }
     421
     422        ForwardIterator cur = begin++;
     423        if ( !cur->second ) {
     424            inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
     425        }
     426        DeclarationWithType *curDecl = cur->first;
     427        PRINT(
     428            std::cerr << "inferRecursive: assertion is ";
     429            curDecl->print( std::cerr );
     430            std::cerr << std::endl;
     431            )
     432        std::list< DeclarationWithType* > candidates;
     433        decls.lookupId( curDecl->get_name(), candidates );
     434///   if ( candidates.empty() ) { std::cout << "no candidates!" << std::endl; }
     435        for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) {
     436            PRINT(
     437                std::cout << "inferRecursive: candidate is ";
     438                (*candidate)->print( std::cout );
     439                std::cout << std::endl;
     440                )
     441            AssertionSet newHave, newerNeed( newNeed );
     442            TypeEnvironment newEnv( newAlt.env );
     443            OpenVarSet newOpenVars( openVars );
     444            Type *adjType = (*candidate)->get_type()->clone();
     445            adjustExprType( adjType, newEnv, indexer );
     446            adjType->accept( global_renamer );
     447            PRINT(
     448                std::cerr << "unifying ";
     449                curDecl->get_type()->print( std::cerr );
     450                std::cerr << " with ";
     451                adjType->print( std::cerr );
     452                std::cerr << std::endl;
     453                )
     454            if ( unify( curDecl->get_type(), adjType, newEnv, newerNeed, newHave, newOpenVars, indexer ) ) {
     455                PRINT(
     456                    std::cerr << "success!" << std::endl;
     457                    )
     458                SymTab::Indexer newDecls( decls );
     459                addToIndexer( newHave, newDecls );
     460                Alternative newerAlt( newAlt );
     461                newerAlt.env = newEnv;
     462                assert( (*candidate)->get_uniqueId() );
     463                Expression *varExpr = new VariableExpr( static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ) );
     464                deleteAll( varExpr->get_results() );
     465                varExpr->get_results().clear();
     466                varExpr->get_results().push_front( adjType->clone() );
     467                PRINT(
     468                    std::cout << "satisfying assertion " << curDecl->get_uniqueId() << " ";
     469                    curDecl->print( std::cout );
     470                    std::cout << " with declaration " << (*candidate)->get_uniqueId() << " ";
     471                    (*candidate)->print( std::cout );
     472                    std::cout << std::endl;
     473                    )
     474                ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr );
     475                // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
     476                appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
     477                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
     478            } else {
     479                delete adjType;
     480            }
     481        }
     482    }
     483
     484    template< typename OutputIterator >
     485    void AlternativeFinder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) {
     486//      PRINT(
     487//          std::cout << "inferParameters: assertions needed are" << std::endl;
     488//          printAll( need, std::cout, 8 );
     489//          )
     490        SymTab::Indexer decls( indexer );
     491        PRINT(
     492            std::cout << "============= original indexer" << std::endl;
     493            indexer.print( std::cout );
     494            std::cout << "============= new indexer" << std::endl;
     495            decls.print( std::cout );
     496            )
     497        addToIndexer( have, decls );
     498        AssertionSet newNeed;
     499        inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
     500//      PRINT(
     501//          std::cout << "declaration 14 is ";
     502//          Declaration::declFromId
     503//          *out++ = newAlt;
     504//          )
     505    }
     506
     507    template< typename OutputIterator >
     508    void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) {
     509        OpenVarSet openVars;
     510        AssertionSet resultNeed, resultHave;
     511        TypeEnvironment resultEnv;
     512        makeUnifiableVars( funcType, openVars, resultNeed );
     513        if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) {
     514            ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
     515            Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) );
     516            makeExprList( actualAlt, appExpr->get_args() );
     517            PRINT(
     518                std::cout << "need assertions:" << std::endl;
     519                printAssertionSet( resultNeed, std::cout, 8 );
     520                )
     521            inferParameters( resultNeed, resultHave, newAlt, openVars, out );
     522        }
     523    }
     524
     525    void AlternativeFinder::visit( UntypedExpr *untypedExpr ) {
     526        bool doneInit = false;
     527        AlternativeFinder funcOpFinder( indexer, env );
     528
     529        AlternativeFinder funcFinder( indexer, env ); {
     530            NameExpr *fname;
     531            if ( ( fname = dynamic_cast<NameExpr *>( untypedExpr->get_function()))
     532                 && ( fname->get_name() == std::string("LabAddress")) ) {
     533                alternatives.push_back( Alternative( untypedExpr, env, Cost()) );
     534                return;
     535            }
     536        }
     537
     538        funcFinder.findWithAdjustment( untypedExpr->get_function() );
     539        std::list< AlternativeFinder > argAlternatives;
     540        findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), back_inserter( argAlternatives ) );
     541
     542        std::list< AltList > possibilities;
     543        combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
     544
     545        Tuples::TupleAssignSpotter tassign( this );
     546        if ( tassign.isTupleAssignment( untypedExpr, possibilities ) ) {
     547            // take care of possible tuple assignments, or discard expression
     548            return;
     549        } // else ...
     550
     551        AltList candidates;
     552
     553        for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
     554            PRINT(
     555                std::cout << "working on alternative: " << std::endl;
     556                func->print( std::cout, 8 );
     557                )
     558            // check if the type is pointer to function
     559            PointerType *pointer;
     560            if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
     561                if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     562                    for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     563                        // XXX
     564                        //Designators::check_alternative( function, *actualAlt );
     565                        makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
     566                    }
     567                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
     568                    EqvClass eqvClass;
     569                    if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
     570                        if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
     571                            for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     572                                makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
     573                            }
     574                        }
     575                    }
     576                }
     577            } else {
     578                // seek a function operator that's compatible
     579                if ( !doneInit ) {
     580                    doneInit = true;
     581                    NameExpr *opExpr = new NameExpr( "?()" );
     582                    try {
     583                        funcOpFinder.findWithAdjustment( opExpr );
     584                    } catch( SemanticError &e ) {
     585                        // it's ok if there aren't any defined function ops
     586                    }
     587                    PRINT(
     588                        std::cout << "known function ops:" << std::endl;
     589                        printAlts( funcOpFinder.alternatives, std::cout, 8 );
     590                        )
     591                }
     592
     593                for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
     594                    // check if the type is pointer to function
     595                    PointerType *pointer;
     596                    if ( funcOp->expr->get_results().size() == 1
     597                        && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
     598                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     599                            for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     600                                AltList currentAlt;
     601                                currentAlt.push_back( *func );
     602                                currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
     603                                makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
     604                            }
     605                        }
     606                    }
     607                }
     608            }
     609        }
     610
     611        for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
     612            Cost cvtCost = computeConversionCost( *withFunc, indexer );
     613
     614            PRINT(
     615                ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr );
     616                assert( appExpr );
     617                PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
     618                assert( pointer );
     619                FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
     620                assert( function );
     621                std::cout << "Case +++++++++++++" << std::endl;
     622                std::cout << "formals are:" << std::endl;
     623                printAll( function->get_parameters(), std::cout, 8 );
     624                std::cout << "actuals are:" << std::endl;
     625                printAll( appExpr->get_args(), std::cout, 8 );
     626                std::cout << "bindings are:" << std::endl;
     627                withFunc->env.print( std::cout, 8 );
     628                std::cout << "cost of conversion is:" << cvtCost << std::endl;
     629                )
     630            if ( cvtCost != Cost::infinity ) {
     631                withFunc->cvtCost = cvtCost;
     632                alternatives.push_back( *withFunc );
     633            }
     634        }
     635        candidates.clear();
     636        candidates.splice( candidates.end(), alternatives );
     637
     638        findMinCost( candidates.begin(), candidates.end(), std::back_inserter( alternatives ) );
     639    }
     640
     641    bool isLvalue( Expression *expr ) {
     642        for ( std::list< Type* >::const_iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
     643            if ( !(*i)->get_isLvalue() ) return false;
     644        }
     645        return true;
     646    }
     647
     648    void AlternativeFinder::visit( AddressExpr *addressExpr ) {
     649        AlternativeFinder finder( indexer, env );
     650        finder.find( addressExpr->get_arg() );
     651        for ( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) {
     652            if ( isLvalue( i->expr ) ) {
     653                alternatives.push_back( Alternative( new AddressExpr( i->expr->clone() ), i->env, i->cost ) );
     654            }
     655        }
     656    }
     657
     658    void AlternativeFinder::visit( CastExpr *castExpr ) {
     659        for ( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) {
     660            SymTab::validateType( *i, &indexer );
     661            adjustExprType( *i, env, indexer );
     662        }
     663
     664        AlternativeFinder finder( indexer, env );
     665        finder.findWithAdjustment( castExpr->get_arg() );
     666
     667        AltList candidates;
     668        for ( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) {
     669            AssertionSet needAssertions, haveAssertions;
     670            OpenVarSet openVars;
     671
     672            // It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
     673            // cast-to-void, which casts from one value to zero.)  Figure out the prefix of the subexpression results
     674            // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
     675            // to.
     676            int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
     677            if ( discardedValues < 0 ) continue;
     678            std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin();
     679            std::advance( candidate_end, castExpr->get_results().size() );
     680            if ( !unifyList( (*i).expr->get_results().begin(), candidate_end,
     681                            castExpr->get_results().begin(), castExpr->get_results().end(), i->env, needAssertions, haveAssertions, openVars, indexer ) ) continue;
     682            Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end,
     683                                          castExpr->get_results().begin(), castExpr->get_results().end(), indexer, i->env );
     684            if ( thisCost != Cost::infinity ) {
     685                // count one safe conversion for each value that is thrown away
     686                thisCost += Cost( 0, 0, discardedValues );
     687                CastExpr *newExpr = castExpr->clone();
     688                newExpr->set_arg( i->expr->clone() );
     689                candidates.push_back( Alternative( newExpr, i->env, i->cost, thisCost ) );
     690            }
     691        }
     692
     693        // findMinCost selects the alternatives with the lowest "cost" members, but has the side effect of copying the
     694        // cvtCost member to the cost member (since the old cost is now irrelevant).  Thus, calling findMinCost twice
     695        // selects first based on argument cost, then on conversion cost.
     696        AltList minArgCost;
     697        findMinCost( candidates.begin(), candidates.end(), std::back_inserter( minArgCost ) );
     698        findMinCost( minArgCost.begin(), minArgCost.end(), std::back_inserter( alternatives ) );
     699    }
     700
     701    void AlternativeFinder::visit( UntypedMemberExpr *memberExpr ) {
     702        AlternativeFinder funcFinder( indexer, env );
     703        funcFinder.findWithAdjustment( memberExpr->get_aggregate() );
     704
     705        for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
     706            if ( agg->expr->get_results().size() == 1 ) {
     707                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) {
     708                    addAggMembers( structInst, agg->expr, agg->cost, memberExpr->get_member() );
     709                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) {
     710                    addAggMembers( unionInst, agg->expr, agg->cost, memberExpr->get_member() );
     711                }
     712            }
     713        }
     714    }
     715
     716    void AlternativeFinder::visit( MemberExpr *memberExpr ) {
     717        alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) );
     718    }
     719
     720    void AlternativeFinder::visit( NameExpr *nameExpr ) {
     721        std::list< DeclarationWithType* > declList;
     722        indexer.lookupId( nameExpr->get_name(), declList );
     723        PRINT(
     724            std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl;
     725            )
     726        for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
     727            VariableExpr newExpr( *i, nameExpr->get_argName() );
     728            alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
     729            PRINT(
     730                std::cerr << "decl is ";
     731                (*i)->print( std::cerr );
     732                std::cerr << std::endl;
     733                std::cerr << "newExpr is ";
     734                newExpr.print( std::cerr );
     735                std::cerr << std::endl;
     736                )
     737            renameTypes( alternatives.back().expr );
     738            if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
     739                addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), "" );
     740            } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
     741                addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), "" );
     742            }
     743        }
     744    }
     745
     746    void AlternativeFinder::visit( VariableExpr *variableExpr ) {
     747        alternatives.push_back( Alternative( variableExpr->clone(), env, Cost::zero ) );
     748    }
     749
     750    void AlternativeFinder::visit( ConstantExpr *constantExpr ) {
     751        alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) );
     752    }
     753
     754    void AlternativeFinder::visit( SizeofExpr *sizeofExpr ) {
     755        if ( sizeofExpr->get_isType() ) {
     756            alternatives.push_back( Alternative( sizeofExpr->clone(), env, Cost::zero ) );
     757        } else {
     758            AlternativeFinder finder( indexer, env );
     759            finder.find( sizeofExpr->get_expr() );
     760            if ( finder.alternatives.size() != 1 ) {
     761                throw SemanticError( "Ambiguous expression in sizeof operand: ", sizeofExpr->get_expr() );
     762            }
     763            Alternative &choice = finder.alternatives.front();
     764            alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
     765        }
     766    }
     767
     768    void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
     769        // assume no polymorphism
     770        // assume no implicit conversions
     771        assert( function->get_parameters().size() == 1 );
     772        PRINT(
     773            std::cout << "resolvAttr: funcDecl is ";
     774            funcDecl->print( std::cout );
     775            std::cout << " argType is ";
     776            argType->print( std::cout );
     777            std::cout << std::endl;
     778            )
     779        if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
     780            alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
     781            for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
     782                alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() );
     783            }
     784        }
     785    }
     786
     787    void AlternativeFinder::visit( AttrExpr *attrExpr ) {
     788        // assume no 'pointer-to-attribute'
     789        NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
     790        assert( nameExpr );
     791        std::list< DeclarationWithType* > attrList;
     792        indexer.lookupId( nameExpr->get_name(), attrList );
     793        if ( attrExpr->get_isType() || attrExpr->get_expr() ) {
     794            for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
     795                // check if the type is function
     796                if ( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) {
     797                    // assume exactly one parameter
     798                    if ( function->get_parameters().size() == 1 ) {
     799                        if ( attrExpr->get_isType() ) {
     800                            resolveAttr( *i, function, attrExpr->get_type(), env );
     801                        } else {
     802                            AlternativeFinder finder( indexer, env );
     803                            finder.find( attrExpr->get_expr() );
     804                            for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
     805                                if ( choice->expr->get_results().size() == 1 ) {
     806                                    resolveAttr(*i, function, choice->expr->get_results().front(), choice->env );
     807                                }
     808                            }
     809                        }
     810                    }
     811                }
     812            }
     813        } else {
     814            for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
     815                VariableExpr newExpr( *i );
     816                alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
     817                renameTypes( alternatives.back().expr );
     818            }
     819        }
     820    }
     821
     822    void AlternativeFinder::visit( LogicalExpr *logicalExpr ) {
     823        AlternativeFinder firstFinder( indexer, env );
     824        firstFinder.findWithAdjustment( logicalExpr->get_arg1() );
     825        for ( AltList::const_iterator first = firstFinder.alternatives.begin(); first != firstFinder.alternatives.end(); ++first ) {
     826            AlternativeFinder secondFinder( indexer, first->env );
     827            secondFinder.findWithAdjustment( logicalExpr->get_arg2() );
     828            for ( AltList::const_iterator second = secondFinder.alternatives.begin(); second != secondFinder.alternatives.end(); ++second ) {
     829                LogicalExpr *newExpr = new LogicalExpr( first->expr->clone(), second->expr->clone(), logicalExpr->get_isAnd() );
     830                alternatives.push_back( Alternative( newExpr, second->env, first->cost + second->cost ) );
     831            }
     832        }
     833    }
     834
     835    void AlternativeFinder::visit( ConditionalExpr *conditionalExpr ) {
     836        AlternativeFinder firstFinder( indexer, env );
     837        firstFinder.findWithAdjustment( conditionalExpr->get_arg1() );
     838        for ( AltList::const_iterator first = firstFinder.alternatives.begin(); first != firstFinder.alternatives.end(); ++first ) {
     839            AlternativeFinder secondFinder( indexer, first->env );
     840            secondFinder.findWithAdjustment( conditionalExpr->get_arg2() );
     841            for ( AltList::const_iterator second = secondFinder.alternatives.begin(); second != secondFinder.alternatives.end(); ++second ) {
     842                AlternativeFinder thirdFinder( indexer, second->env );
     843                thirdFinder.findWithAdjustment( conditionalExpr->get_arg3() );
     844                for ( AltList::const_iterator third = thirdFinder.alternatives.begin(); third != thirdFinder.alternatives.end(); ++third ) {
     845                    OpenVarSet openVars;
     846                    AssertionSet needAssertions, haveAssertions;
     847                    Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost );
     848                    std::list< Type* > commonTypes;
     849                    if ( unifyList( second->expr->get_results().begin(), second->expr->get_results().end(), third->expr->get_results().begin(), third->expr->get_results().end(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
     850                        ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
     851                        std::list< Type* >::const_iterator original = second->expr->get_results().begin();
     852                        std::list< Type* >::const_iterator commonType = commonTypes.begin();
     853                        for ( ; original != second->expr->get_results().end() && commonType != commonTypes.end(); ++original, ++commonType ) {
     854                            if ( *commonType ) {
     855                                newExpr->get_results().push_back( *commonType );
     856                            } else {
     857                                newExpr->get_results().push_back( (*original)->clone() );
     858                            }
     859                        }
     860                        newAlt.expr = newExpr;
     861                        inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     862                    }
     863                }
     864            }
     865        }
     866    }
     867
     868    void AlternativeFinder::visit( CommaExpr *commaExpr ) {
     869        TypeEnvironment newEnv( env );
     870        Expression *newFirstArg = resolveInVoidContext( commaExpr->get_arg1(), indexer, newEnv );
     871        AlternativeFinder secondFinder( indexer, newEnv );
     872        secondFinder.findWithAdjustment( commaExpr->get_arg2() );
     873        for ( AltList::const_iterator alt = secondFinder.alternatives.begin(); alt != secondFinder.alternatives.end(); ++alt ) {
     874            alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt->expr->clone() ), alt->env, alt->cost ) );
     875        }
     876        delete newFirstArg;
     877    }
     878
     879    void AlternativeFinder::visit( TupleExpr *tupleExpr ) {
     880        std::list< AlternativeFinder > subExprAlternatives;
     881        findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) );
     882        std::list< AltList > possibilities;
     883        combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) );
     884        for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) {
     885            TupleExpr *newExpr = new TupleExpr;
     886            makeExprList( *i, newExpr->get_exprs() );
     887            for ( std::list< Expression* >::const_iterator resultExpr = newExpr->get_exprs().begin(); resultExpr != newExpr->get_exprs().end(); ++resultExpr ) {
     888                for ( std::list< Type* >::const_iterator resultType = (*resultExpr)->get_results().begin(); resultType != (*resultExpr)->get_results().end(); ++resultType ) {
     889                    newExpr->get_results().push_back( (*resultType)->clone() );
     890                }
     891            }
     892
     893            TypeEnvironment compositeEnv;
     894            simpleCombineEnvironments( i->begin(), i->end(), compositeEnv );
     895            alternatives.push_back( Alternative( newExpr, compositeEnv, sumCost( *i ) ) );
     896        }
     897    }
    928898} // namespace ResolvExpr
  • translator/ResolvExpr/AlternativeFinder.h

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: AlternativeFinder.h,v 1.19 2005/08/29 20:14:15 rcbilson Exp $
    5  *
    6  */
    7 
    8 #ifndef RESOLVEXPR_ALTERNATIVEFINDER_H
    9 #define RESOLVEXPR_ALTERNATIVEFINDER_H
     1#ifndef ALTERNATIVEFINDER_H
     2#define ALTERNATIVEFINDER_H
    103
    114#include <set>
     
    1811
    1912namespace ResolvExpr {
     13    class AlternativeFinder : public Visitor {
     14      public:
     15        AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env );
     16        void find( Expression *expr, bool adjust = false );
     17        void findWithAdjustment( Expression *expr );
     18        AltList &get_alternatives() { return alternatives; }
     19 
     20        // make this look like an STL container so that we can apply generic algorithms
     21        typedef Alternative value_type;
     22        typedef AltList::iterator iterator;
     23        typedef AltList::const_iterator const_iterator;
     24        AltList::iterator begin() { return alternatives.begin(); }
     25        AltList::iterator end() { return alternatives.end(); }
     26        AltList::const_iterator begin() const { return alternatives.begin(); }
     27        AltList::const_iterator end() const { return alternatives.end(); }
     28 
     29        const SymTab::Indexer &get_indexer() const { return indexer; }
     30        const TypeEnvironment &get_environ() const { return env; }
     31      private:
     32        virtual void visit( ApplicationExpr *applicationExpr );
     33        virtual void visit( UntypedExpr *untypedExpr );
     34        virtual void visit( AddressExpr *addressExpr );
     35        virtual void visit( CastExpr *castExpr );
     36        virtual void visit( UntypedMemberExpr *memberExpr );
     37        virtual void visit( MemberExpr *memberExpr );
     38        virtual void visit( NameExpr *variableExpr );
     39        virtual void visit( VariableExpr *variableExpr );
     40        virtual void visit( ConstantExpr *constantExpr );
     41        virtual void visit( SizeofExpr *sizeofExpr );
     42        virtual void visit( AttrExpr *attrExpr );
     43        virtual void visit( LogicalExpr *logicalExpr );
     44        virtual void visit( ConditionalExpr *conditionalExpr );
     45        virtual void visit( CommaExpr *commaExpr );
     46        virtual void visit( TupleExpr *tupleExpr );
     47      public:  // xxx - temporary hack - should make Tuples::TupleAssignment a friend
     48        template< typename InputIterator, typename OutputIterator >
     49            void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
    2050
    21 class AlternativeFinder : public Visitor
    22 {
    23 public:
    24   AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env );
    25   void find( Expression *expr, bool adjust = false );
    26   void findWithAdjustment( Expression *expr );
    27   AltList &get_alternatives() { return alternatives; }
    28  
    29   // make this look like an STL container so that we can apply generic algorithms
    30   typedef Alternative value_type;
    31   typedef AltList::iterator iterator;
    32   typedef AltList::const_iterator const_iterator;
    33   AltList::iterator begin() { return alternatives.begin(); }
    34   AltList::iterator end() { return alternatives.end(); }
    35   AltList::const_iterator begin() const { return alternatives.begin(); }
    36   AltList::const_iterator end() const { return alternatives.end(); }
    37  
    38   const SymTab::Indexer &get_indexer() const { return indexer; }
    39   const TypeEnvironment &get_environ() const { return env; }
    40 private:
    41   virtual void visit(ApplicationExpr *applicationExpr);
    42   virtual void visit(UntypedExpr *untypedExpr);
    43   virtual void visit(AddressExpr *addressExpr);
    44   virtual void visit(CastExpr *castExpr);
    45   virtual void visit(UntypedMemberExpr *memberExpr);
    46   virtual void visit(MemberExpr *memberExpr);
    47   virtual void visit(NameExpr *variableExpr);
    48   virtual void visit(VariableExpr *variableExpr);
    49   virtual void visit(ConstantExpr *constantExpr);
    50   virtual void visit(SizeofExpr *sizeofExpr);
    51   virtual void visit(AttrExpr *attrExpr);
    52   virtual void visit(LogicalExpr *logicalExpr);
    53   virtual void visit(ConditionalExpr *conditionalExpr);
    54   virtual void visit(CommaExpr *commaExpr);
    55   virtual void visit(TupleExpr *tupleExpr);
    56  public:  // xxx - temporary hack - should make Tuples::TupleAssignment a friend
    57   template< typename InputIterator, typename OutputIterator >
    58   void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
     51      private:
     52        template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name );
     53        bool instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave );
     54        template< typename OutputIterator >
     55            void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out );
     56        template< typename OutputIterator >
     57            void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
     58        void resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env );
    5959
    60  private:
    61   template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name );
    62   bool instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave );
    63   template< typename OutputIterator >
    64   void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out );
    65   template< typename OutputIterator >
    66   void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
    67   void resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env );
     60        const SymTab::Indexer &indexer;
     61        AltList alternatives;
     62        const TypeEnvironment &env;
     63    }; // AlternativeFinder
    6864
    69   const SymTab::Indexer &indexer;
    70   AltList alternatives;
    71   const TypeEnvironment &env;
    72 };
    73 
    74 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env )
    75 ;
    76 
     65    Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
    7766} // namespace ResolvExpr
    7867
    79 #endif /* #ifndef RESOLVEXPR_ALTERNATIVEFINDER_H */
     68#endif // ALTERNATIVEFINDER_H
  • translator/ResolvExpr/AlternativePrinter.cc

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: AlternativePrinter.cc,v 1.5 2005/08/29 20:14:15 rcbilson Exp $
    5  *
    6  */
    7 
    81#include "AlternativePrinter.h"
    92#include "AlternativeFinder.h"
     
    158
    169namespace ResolvExpr {
     10    AlternativePrinter::AlternativePrinter( std::ostream &os ) : SymTab::Indexer( false ), os( os ) {}
    1711
    18 AlternativePrinter::AlternativePrinter( std::ostream &os )
    19   : SymTab::Indexer( false ), os( os )
    20 {
    21 }
    22 
    23 void
    24 AlternativePrinter::visit(ExprStmt *exprStmt)
    25 {
    26   TypeEnvironment env;
    27   AlternativeFinder finder( *this, env );
    28   finder.findWithAdjustment( exprStmt->get_expr() );
    29   int count = 1;
    30   os << "There are " << finder.get_alternatives().size() << " alternatives" << std::endl;
    31   for( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    32     os << "Alternative " << count++ << " ==============" << std::endl;
    33     printAll( i->expr->get_results(), os );
    34 //    i->print( os );
    35     os << std::endl;
    36   }
    37 }
    38 
     12    void AlternativePrinter::visit( ExprStmt *exprStmt ) {
     13        TypeEnvironment env;
     14        AlternativeFinder finder( *this, env );
     15        finder.findWithAdjustment( exprStmt->get_expr() );
     16        int count = 1;
     17        os << "There are " << finder.get_alternatives().size() << " alternatives" << std::endl;
     18        for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
     19            os << "Alternative " << count++ << " ==============" << std::endl;
     20            printAll( i->expr->get_results(), os );
     21            //    i->print( os );
     22            os << std::endl;
     23        } // for
     24    } // AlternativePrinter::visit
    3925} // namespace ResolvExpr
  • translator/ResolvExpr/AlternativePrinter.h

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: AlternativePrinter.h,v 1.2 2005/08/29 20:14:15 rcbilson Exp $
    5  *
    6  */
    7 
    8 #ifndef RESOLVEXPR_ALTERNATIVEPRINTER_H
    9 #define RESOLVEXPR_ALTERNATIVEPRINTER_H
     1#ifndef ALTERNATIVEPRINTER_H
     2#define ALTERNATIVEPRINTER_H
    103
    114#include <iostream>
     
    158
    169namespace ResolvExpr {
    17 
    18 class AlternativePrinter : public SymTab::Indexer
    19 {
    20 public:
    21   AlternativePrinter( std::ostream &os );
    22   virtual void visit(ExprStmt *exprStmt);
    23 
    24 private:
    25   std::ostream &os;
    26 };
    27 
     10    class AlternativePrinter : public SymTab::Indexer {
     11      public:
     12        AlternativePrinter( std::ostream &os );
     13        virtual void visit(ExprStmt *exprStmt);
     14      private:
     15        std::ostream &os;
     16    };
    2817} // namespace ResolvExpr
    2918
    30 #endif /* #ifndef RESOLVEXPR_ALTERNATIVEPRINTER_H */
     19#endif // ALTERNATIVEPRINTER_H
  • translator/ResolvExpr/Cost.h

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Cost.h,v 1.2 2003/01/27 14:46:59 rcbilson Exp $
    5  *
    6  */
    7 
    81#ifndef RESOLVEXPR_COST_H
    92#define RESOLVEXPR_COST_H
     
    125
    136namespace ResolvExpr {
     7    class Cost {
     8      public:
     9        Cost();
     10        Cost( int unsafe, int poly, int safe );
     11 
     12        void incUnsafe( int inc = 1 );
     13        void incPoly( int inc = 1 );
     14        void incSafe( int inc = 1 );
     15 
     16        Cost operator+( const Cost &other ) const;
     17        Cost operator-( const Cost &other ) const;
     18        Cost &operator+=( const Cost &other );
     19        bool operator<( const Cost &other ) const;
     20        bool operator==( const Cost &other ) const;
     21        bool operator!=( const Cost &other ) const;
     22        friend std::ostream &operator<<( std::ostream &os, const Cost &cost );
     23 
     24        static const Cost zero;
     25        static const Cost infinity;
     26      private:
     27        int compare( const Cost &other ) const;
    1428
    15 class Cost
    16 {
    17 public:
    18   Cost();
    19   Cost( int unsafe, int poly, int safe );
    20  
    21   void incUnsafe( int inc = 1 );
    22   void incPoly( int inc = 1 );
    23   void incSafe( int inc = 1 );
    24  
    25   Cost operator+( const Cost &other ) const;
    26   Cost operator-( const Cost &other ) const;
    27   Cost &operator+=( const Cost &other );
    28   bool operator<( const Cost &other ) const;
    29   bool operator==( const Cost &other ) const;
    30   bool operator!=( const Cost &other ) const;
    31   friend std::ostream &operator<<( std::ostream &os, const Cost &cost );
    32  
    33   static const Cost zero;
    34   static const Cost infinity;
    35  
    36 private:
    37   int compare( const Cost &other ) const;
     29        int unsafe;
     30        int poly;
     31        int safe;
     32    };
    3833
    39   int unsafe;
    40   int poly;
    41   int safe;
    42 };
     34    inline Cost::Cost() : unsafe( 0 ), poly( 0 ), safe( 0 ) {}
    4335
    44 inline
    45 Cost::Cost()
    46   : unsafe( 0 ), poly( 0 ), safe( 0 )
    47 {
    48 }
     36    inline Cost::Cost( int unsafe, int poly, int safe ) : unsafe( unsafe ), poly( poly ), safe( safe ) {}
    4937
    50 inline
    51 Cost::Cost( int unsafe, int poly, int safe )
    52   : unsafe( unsafe ), poly( poly ), safe( safe )
    53 {
    54 }
     38    inline void
     39        Cost::incUnsafe( int inc ) {
     40        unsafe += inc;
     41    }
    5542
    56 inline void
    57 Cost::incUnsafe( int inc )
    58 {
    59   unsafe += inc;
    60 }
     43    inline void
     44        Cost::incPoly( int inc ) {
     45        unsafe += inc;
     46    }
    6147
    62 inline void
    63 Cost::incPoly( int inc )
    64 {
    65   unsafe += inc;
    66 }
     48    inline void
     49        Cost::incSafe( int inc ) {
     50        unsafe += inc;
     51    }
    6752
    68 inline void
    69 Cost::incSafe( int inc )
    70 {
    71   unsafe += inc;
    72 }
     53    inline Cost Cost::operator+( const Cost &other ) const {
     54        return Cost( unsafe + other.unsafe, poly + other.poly, safe + other.safe );
     55    }
    7356
    74 inline Cost
    75 Cost::operator+( const Cost &other ) const
    76 {
    77   return Cost( unsafe + other.unsafe, poly + other.poly, safe + other.safe );
    78 }
     57    inline Cost Cost::operator-( const Cost &other ) const {
     58        return Cost( unsafe - other.unsafe, poly - other.poly, safe - other.safe );
     59    }
    7960
    80 inline Cost
    81 Cost::operator-( const Cost &other ) const
    82 {
    83   return Cost( unsafe - other.unsafe, poly - other.poly, safe - other.safe );
    84 }
     61    inline Cost &Cost::operator+=( const Cost &other ) {
     62        unsafe += other.unsafe;
     63        poly += other.poly;
     64        safe += other.safe;
     65        return *this;
     66    }
    8567
    86 inline Cost &
    87 Cost::operator+=( const Cost &other )
    88 {
    89    unsafe += other.unsafe;
    90    poly += other.poly;
    91    safe += other.safe;
    92    return *this;
    93 }
     68    inline bool Cost::operator<( const Cost &other ) const {
     69            if ( *this == infinity ) return false;
     70            if ( other == infinity ) return true;
     71            if ( unsafe > other.unsafe ) {
     72                return false;
     73            } else if ( unsafe < other.unsafe ) {
     74                return true;
     75            } else if ( poly > other.poly ) {
     76                return false;
     77            } else if ( poly < other.poly ) {
     78                return true;
     79            } else if ( safe > other.safe ) {
     80                return false;
     81            } else if ( safe < other.safe ) {
     82                return true;
     83            } else {
     84                return false;
     85            }
     86        }
    9487
    95 inline bool
    96 Cost::operator<( const Cost &other ) const
    97 {
    98   if( *this == infinity ) return false;
    99   if( other == infinity ) return true;
    100   if( unsafe > other.unsafe ) {
    101     return false;
    102   } else if( unsafe < other.unsafe ) {
    103     return true;
    104   } else if( poly > other.poly ) {
    105     return false;
    106   } else if( poly < other.poly ) {
    107     return true;
    108   } else if( safe > other.safe ) {
    109     return false;
    110   } else if( safe < other.safe ) {
    111     return true;
    112   } else {
    113     return false;
    114   }
    115 }
     88    inline bool Cost::operator==( const Cost &other ) const {
     89        return unsafe == other.unsafe
     90        && poly == other.poly
     91        && safe == other.safe;
     92    }
    11693
    117 inline bool
    118 Cost::operator==( const Cost &other ) const
    119 {
    120   return unsafe == other.unsafe
    121          && poly == other.poly
    122          && safe == other.safe;
    123 }
     94    inline bool Cost::operator!=( const Cost &other ) const {
     95        return !( *this == other );
     96    }
    12497
    125 inline bool
    126 Cost::operator!=( const Cost &other ) const
    127 {
    128   return !( *this == other );
    129 }
    130 
    131 inline std::ostream &
    132 operator<<( std::ostream &os, const Cost &cost )
    133 {
    134   os << "( " << cost.unsafe << ", " << cost.poly << ", " << cost.safe << " )";
    135   return os;
    136 }
    137 
     98    inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) {
     99        os << "( " << cost.unsafe << ", " << cost.poly << ", " << cost.safe << " )";
     100        return os;
     101    }
    138102} // namespace ResolvExpr
    139103
    140 #endif /* #ifndef RESOLVEXPR_COST_H */
     104#endif // RESOLVEXPR_COST_H
  • translator/ResolvExpr/ResolveTypeof.cc

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: ResolveTypeof.cc,v 1.2 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
    7 
    81#include "ResolveTypeof.h"
    92#include "Alternative.h"
     
    158
    169namespace ResolvExpr {
     10    namespace {
     11#if 0
     12        void
     13        printAlts( const AltList &list, std::ostream &os, int indent = 0 )
     14        {
     15            for( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
     16                i->print( os, indent );
     17                os << std::endl;
     18            }
     19        }
     20#endif
     21    }
    1722
    18 namespace {
     23    class ResolveTypeof : public Mutator {
     24      public:
     25        ResolveTypeof( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
     26        Type *mutate( TypeofType *typeofType );
     27
     28      private:
     29        const SymTab::Indexer &indexer;
     30    };
     31
     32    Type *resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {
     33        ResolveTypeof mutator( indexer );
     34        return type->acceptMutator( mutator );
     35    }
     36
     37    Type *ResolveTypeof::mutate( TypeofType *typeofType ) {
    1938#if 0
    20   void
    21   printAlts( const AltList &list, std::ostream &os, int indent = 0 )
    22   {
    23     for( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
    24       i->print( os, indent );
    25       os << std::endl;
     39        std::cout << "resolving typeof: ";
     40        typeofType->print( std::cout );
     41        std::cout << std::endl;
     42#endif
     43        if ( typeofType->get_expr() ) {
     44            Expression *newExpr = resolveInVoidContext( typeofType->get_expr(), indexer );
     45            assert( newExpr->get_results().size() > 0 );
     46            Type *newType;
     47            if ( newExpr->get_results().size() > 1 ) {
     48                TupleType *tupleType = new TupleType( Type::Qualifiers() );
     49                cloneAll( newExpr->get_results(), tupleType->get_types() );
     50                newType = tupleType;
     51            } else {
     52                newType = newExpr->get_results().front()->clone();
     53            }
     54            delete typeofType;
     55            return newType;
     56        }
     57        return typeofType;
    2658    }
    27   }
    28 #endif
    29 }
    30 
    31 class ResolveTypeof : public Mutator
    32 {
    33 public:
    34   ResolveTypeof( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
    35   Type *mutate( TypeofType *typeofType );
    36 
    37 private:
    38   const SymTab::Indexer &indexer;
    39 };
    40 
    41 Type *
    42 resolveTypeof( Type *type, const SymTab::Indexer &indexer )
    43 {
    44   ResolveTypeof mutator( indexer );
    45   return type->acceptMutator( mutator );
    46 }
    47 
    48 Type *
    49 ResolveTypeof::mutate( TypeofType *typeofType )
    50 {
    51 ///   std::cout << "resolving typeof: ";
    52 ///   typeofType->print( std::cout );
    53 ///   std::cout << std::endl;
    54   if( typeofType->get_expr() ) {
    55     Expression *newExpr = resolveInVoidContext( typeofType->get_expr(), indexer );
    56     assert( newExpr->get_results().size() > 0 );
    57     Type *newType;
    58     if( newExpr->get_results().size() > 1 ) {
    59       TupleType *tupleType = new TupleType( Type::Qualifiers() );
    60       cloneAll( newExpr->get_results(), tupleType->get_types() );
    61       newType = tupleType;
    62     } else {
    63       newType = newExpr->get_results().front()->clone();
    64     }
    65     delete typeofType;
    66     return newType;
    67   }
    68   return typeofType;
    69 }
    7059
    7160} // namespace ResolvExpr
  • translator/ResolvExpr/ResolveTypeof.h

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: ResolveTypeof.h,v 1.2 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
    7 
    8 #ifndef RESOLVEXPR_RESOLVETYPEOF_H
    9 #define RESOLVEXPR_RESOLVETYPEOF_H
     1#ifndef RESOLVETYPEOF_H
     2#define RESOLVETYPEOF_H
    103
    114#include "SynTree/SynTree.h"
     
    136
    147namespace ResolvExpr {
    15 
    16 Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
    17 
     8    Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
    189} // namespace ResolvExpr
    1910
    20 #endif /* #ifndef RESOLVEXPR_RESOLVETYPEOF_H */
     11#endif // RESOLVETYPEOF_H
  • translator/ResolvExpr/Resolver.cc

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Resolver.cc,v 1.19 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
    7 
    81#include "Resolver.h"
    92#include "AlternativeFinder.h"
     
    1811#include "utility.h"
    1912
     13#include <iostream>
     14using namespace std;
     15
    2016namespace ResolvExpr {
    21 
    22 class Resolver : public SymTab::Indexer
    23 {
    24 public:
    25   Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
    26  
    27   virtual void visit( FunctionDecl *functionDecl );
    28   virtual void visit( ObjectDecl *functionDecl );
    29   virtual void visit( TypeDecl *typeDecl );
    30 
    31   virtual void visit( ExprStmt *exprStmt );
    32   virtual void visit( IfStmt *ifStmt );
    33   virtual void visit( WhileStmt *whileStmt );
    34   virtual void visit( ForStmt *forStmt );
    35   virtual void visit( SwitchStmt *switchStmt );
    36   virtual void visit( ChooseStmt *switchStmt );
    37   virtual void visit( CaseStmt *caseStmt );
    38   virtual void visit( ReturnStmt *returnStmt );
    39 
    40   virtual void visit( SingleInit *singleInit );
    41 
    42 private:
    43   std::list< Type* > functionReturn;
    44   Type* initContext;
    45   Type *switchType;
    46 };
    47 
    48 void
    49 resolve( std::list< Declaration* > translationUnit )
    50 {
    51   Resolver resolver;
    52   acceptAll( translationUnit, resolver );
    53 ///   for( std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
    54 ///     (*i)->print( std::cerr );
    55 ///     (*i)->accept( resolver );
    56 ///   }
    57 }
    58 
    59 Expression *
    60 resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer )
    61 {
    62   TypeEnvironment env;
    63   return resolveInVoidContext( expr, indexer, env );
    64 }
    65 
    66 namespace {
    67 
    68   void
    69   finishExpr( Expression *expr, const TypeEnvironment &env )
    70   {
    71     expr->set_env( new TypeSubstitution );
    72     env.makeSubstitution( *expr->get_env() );
    73   }
    74 
    75   Expression*
    76   findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer )
    77   {
    78     global_renamer.reset();
    79     TypeEnvironment env;
    80     Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
    81     finishExpr( newExpr, env );
    82     return newExpr;
    83   }
    84  
    85   Expression*
    86   findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer )
    87   {
    88     TypeEnvironment env;
    89     AlternativeFinder finder( indexer, env );
    90     finder.find( untyped );
    91 ///     if( finder.get_alternatives().size() != 1 ) {
    92 ///       std::cout << "untyped expr is ";
    93 ///       untyped->print( std::cout );
    94 ///       std::cout << std::endl << "alternatives are:";
    95 ///       for( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    96 ///         i->print( std::cout );
    97 ///       }
    98 ///     }
    99     assert( finder.get_alternatives().size() == 1 );
    100     Alternative &choice = finder.get_alternatives().front();
    101     Expression *newExpr = choice.expr->clone();
    102     finishExpr( newExpr, choice.env );
    103     return newExpr;
    104   }
    105 
    106   bool
    107   isIntegralType( Type *type )
    108   {
    109     if( dynamic_cast< EnumInstType* >( type ) ) {
    110       return true;
    111     } else if( BasicType *bt = dynamic_cast< BasicType* >( type ) ) {
    112       return bt->isInteger();
    113     } else {
    114       return true;
    115     }
    116   }
    117  
    118   Expression*
    119   findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer )
    120   {
    121     TypeEnvironment env;
    122     AlternativeFinder finder( indexer, env );
    123     finder.find( untyped );
    124 ///     if( finder.get_alternatives().size() != 1 ) {
    125 ///       std::cout << "untyped expr is ";
    126 ///       untyped->print( std::cout );
    127 ///       std::cout << std::endl << "alternatives are:";
    128 ///       for( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    129 ///         i->print( std::cout );
    130 ///       }
    131 ///     }
    132     Expression *newExpr = 0;
    133     const TypeEnvironment *newEnv = 0;
    134     for( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    135       if( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) {
    136         if( newExpr ) {
    137           throw SemanticError( "Too many interpretations for switch control expression", untyped );
    138         } else {
    139           newExpr = i->expr->clone();
    140           newEnv = &i->env;
    141         }
    142       }
    143     }
    144     if( !newExpr ) {
    145       throw SemanticError( "Too many interpretations for switch control expression", untyped );
    146     }
    147     finishExpr( newExpr, *newEnv );
    148     return newExpr;
    149   }
    150  
    151 }
    152  
    153 void
    154 Resolver::visit( ObjectDecl *objectDecl )
    155 {
    156   Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
    157   objectDecl->set_type( new_type );
    158   initContext = new_type;
    159   SymTab::Indexer::visit( objectDecl );
    160 }
    161  
    162 void
    163 Resolver::visit( TypeDecl *typeDecl )
    164 {
    165   if( typeDecl->get_base() ) {
    166     Type *new_type = resolveTypeof( typeDecl->get_base(), *this );
    167     typeDecl->set_base( new_type );
    168   }
    169   SymTab::Indexer::visit( typeDecl );
    170 }
    171  
    172 void
    173 Resolver::visit( FunctionDecl *functionDecl )
    174 {
    175 ///   std::cout << "resolver visiting functiondecl ";
    176 ///   functionDecl->print( std::cout );
    177 ///   std::cout << std::endl;
    178   Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
    179   functionDecl->set_type( new_type );
    180   std::list< Type* > oldFunctionReturn = functionReturn;
    181   functionReturn.clear();
    182   for( std::list< DeclarationWithType* >::const_iterator i = functionDecl->get_functionType()->get_returnVals().begin(); i != functionDecl->get_functionType()->get_returnVals().end(); ++i ) {
    183     functionReturn.push_back( (*i)->get_type() );
    184   }
    185   SymTab::Indexer::visit( functionDecl );
    186   functionReturn = oldFunctionReturn;
    187 }
    188 
    189 void
    190 Resolver::visit( ExprStmt *exprStmt )
    191 {
    192   if( exprStmt->get_expr() ) {
    193     Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this );
    194     delete exprStmt->get_expr();
    195     exprStmt->set_expr( newExpr );
    196   }
    197 }
    198 
    199 void
    200 Resolver::visit( IfStmt *ifStmt )
    201 {
    202   Expression *newExpr = findSingleExpression( ifStmt->get_condition(), *this );
    203   delete ifStmt->get_condition();
    204   ifStmt->set_condition( newExpr );
    205   Visitor::visit( ifStmt );
    206 }
    207 
    208 void
    209 Resolver::visit( WhileStmt *whileStmt )
    210 {
    211   Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this );
    212   delete whileStmt->get_condition();
    213   whileStmt->set_condition( newExpr );
    214   Visitor::visit( whileStmt );
    215 }
    216 
    217 void
    218 Resolver::visit( ForStmt *forStmt )
    219 {
    220   Expression *newExpr;
    221   if( forStmt->get_condition() ) {
    222     newExpr = findSingleExpression( forStmt->get_condition(), *this );
    223     delete forStmt->get_condition();
    224     forStmt->set_condition( newExpr );
    225   }
    226  
    227   if( forStmt->get_increment() ) {
    228     newExpr = findVoidExpression( forStmt->get_increment(), *this );
    229     delete forStmt->get_increment();
    230     forStmt->set_increment( newExpr );
    231   }
    232  
    233   Visitor::visit( forStmt );
    234 }
    235 
    236 template< typename SwitchClass >
    237 void
    238 handleSwitchStmt( SwitchClass *switchStmt, SymTab::Indexer &visitor )
    239 {
    240   Expression *newExpr;
    241   newExpr = findIntegralExpression( switchStmt->get_condition(), visitor );
    242   delete switchStmt->get_condition();
    243   switchStmt->set_condition( newExpr );
    244  
    245   visitor.Visitor::visit( switchStmt );
    246 }
    247 
    248 void
    249 Resolver::visit( SwitchStmt *switchStmt )
    250 {
    251   handleSwitchStmt( switchStmt, *this );
    252 }
    253 
    254 void
    255 Resolver::visit( ChooseStmt *switchStmt )
    256 {
    257   handleSwitchStmt( switchStmt, *this );
    258 }
    259 
    260 void
    261 Resolver::visit( CaseStmt *caseStmt )
    262 {
    263   Visitor::visit( caseStmt );
    264 }
    265 
    266 void
    267 Resolver::visit( ReturnStmt *returnStmt )
    268 {
    269   if( returnStmt->get_expr() ) {
    270     CastExpr *castExpr = new CastExpr( returnStmt->get_expr() );
    271     cloneAll( functionReturn, castExpr->get_results() );
    272     Expression *newExpr = findSingleExpression( castExpr, *this );
    273     delete castExpr;
    274     returnStmt->set_expr( newExpr );
    275   }
    276 }
    277 
    278 void
    279 Resolver::visit( SingleInit *singleInit )
    280 {
    281   if( singleInit->get_value() ) {
    282     CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() );
    283     Expression *newExpr = findSingleExpression( castExpr, *this );
    284     delete castExpr;
    285     singleInit->set_value( newExpr );
    286   }
    287   singleInit->get_value()->accept( *this );
    288 }
    289 
     17    class Resolver : public SymTab::Indexer {
     18      public:
     19        Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
     20 
     21        virtual void visit( FunctionDecl *functionDecl );
     22        virtual void visit( ObjectDecl *functionDecl );
     23        virtual void visit( TypeDecl *typeDecl );
     24
     25        virtual void visit( ExprStmt *exprStmt );
     26        virtual void visit( IfStmt *ifStmt );
     27        virtual void visit( WhileStmt *whileStmt );
     28        virtual void visit( ForStmt *forStmt );
     29        virtual void visit( SwitchStmt *switchStmt );
     30        virtual void visit( ChooseStmt *switchStmt );
     31        virtual void visit( CaseStmt *caseStmt );
     32        virtual void visit( ReturnStmt *returnStmt );
     33
     34        virtual void visit( SingleInit *singleInit );
     35        virtual void visit( ListInit *listInit );
     36      private:
     37        std::list< Type * > functionReturn;
     38        Type *initContext;
     39        Type *switchType;
     40    };
     41
     42    void resolve( std::list< Declaration * > translationUnit ) {
     43        Resolver resolver;
     44        acceptAll( translationUnit, resolver );
     45#if 0
     46        for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
     47            (*i)->print( std::cerr );
     48            (*i)->accept( resolver );
     49        }
     50#endif
     51    }
     52
     53    Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) {
     54        TypeEnvironment env;
     55        return resolveInVoidContext( expr, indexer, env );
     56    }
     57
     58    namespace {
     59        void finishExpr( Expression *expr, const TypeEnvironment &env ) {
     60            expr->set_env( new TypeSubstitution );
     61            env.makeSubstitution( *expr->get_env() );
     62        }
     63
     64        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     65            global_renamer.reset();
     66            TypeEnvironment env;
     67            Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
     68            finishExpr( newExpr, env );
     69            return newExpr;
     70        }
     71 
     72        Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     73            TypeEnvironment env;
     74            AlternativeFinder finder( indexer, env );
     75            finder.find( untyped );
     76#if 0
     77            if ( finder.get_alternatives().size() != 1 ) {
     78                std::cout << "untyped expr is ";
     79                untyped->print( std::cout );
     80                std::cout << std::endl << "alternatives are:";
     81                for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
     82                    i->print( std::cout );
     83                }
     84            }
     85#endif
     86            assert( finder.get_alternatives().size() == 1 );
     87            Alternative &choice = finder.get_alternatives().front();
     88            Expression *newExpr = choice.expr->clone();
     89            finishExpr( newExpr, choice.env );
     90            return newExpr;
     91        }
     92
     93        bool isIntegralType( Type *type ) {
     94            if ( dynamic_cast< EnumInstType * >( type ) ) {
     95                return true;
     96            } else if ( BasicType *bt = dynamic_cast< BasicType * >( type ) ) {
     97                return bt->isInteger();
     98            } else {
     99                return true;
     100            }
     101        }
     102 
     103        Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     104            TypeEnvironment env;
     105            AlternativeFinder finder( indexer, env );
     106            finder.find( untyped );
     107#if 0
     108            if ( finder.get_alternatives().size() != 1 ) {
     109                std::cout << "untyped expr is ";
     110                untyped->print( std::cout );
     111                std::cout << std::endl << "alternatives are:";
     112                for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
     113                    i->print( std::cout );
     114                }
     115            }
     116#endif
     117            Expression *newExpr = 0;
     118            const TypeEnvironment *newEnv = 0;
     119            for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
     120                if ( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) {
     121                    if ( newExpr ) {
     122                        throw SemanticError( "Too many interpretations for switch control expression", untyped );
     123                    } else {
     124                        newExpr = i->expr->clone();
     125                        newEnv = &i->env;
     126                    }
     127                }
     128            }
     129            if ( !newExpr ) {
     130                throw SemanticError( "Too many interpretations for switch control expression", untyped );
     131            }
     132            finishExpr( newExpr, *newEnv );
     133            return newExpr;
     134        }
     135 
     136    }
     137 
     138    void Resolver::visit( ObjectDecl *objectDecl ) {
     139        Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
     140        objectDecl->set_type( new_type );
     141        initContext = new_type;
     142        SymTab::Indexer::visit( objectDecl );
     143    }
     144 
     145    void Resolver::visit( TypeDecl *typeDecl ) {
     146        if ( typeDecl->get_base() ) {
     147            Type *new_type = resolveTypeof( typeDecl->get_base(), *this );
     148            typeDecl->set_base( new_type );
     149        }
     150        SymTab::Indexer::visit( typeDecl );
     151    }
     152 
     153    void Resolver::visit( FunctionDecl *functionDecl ) {
     154#if 0
     155        std::cout << "resolver visiting functiondecl ";
     156        functionDecl->print( std::cout );
     157        std::cout << std::endl;
     158#endif
     159        Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
     160        functionDecl->set_type( new_type );
     161        std::list< Type * > oldFunctionReturn = functionReturn;
     162        functionReturn.clear();
     163        for ( std::list< DeclarationWithType * >::const_iterator i = functionDecl->get_functionType()->get_returnVals().begin(); i != functionDecl->get_functionType()->get_returnVals().end(); ++i ) {
     164            functionReturn.push_back( (*i)->get_type() );
     165        }
     166        SymTab::Indexer::visit( functionDecl );
     167        functionReturn = oldFunctionReturn;
     168    }
     169
     170    void Resolver::visit( ExprStmt *exprStmt ) {
     171        if ( exprStmt->get_expr() ) {
     172            Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this );
     173            delete exprStmt->get_expr();
     174            exprStmt->set_expr( newExpr );
     175        }
     176    }
     177
     178    void Resolver::visit( IfStmt *ifStmt ) {
     179        Expression *newExpr = findSingleExpression( ifStmt->get_condition(), *this );
     180        delete ifStmt->get_condition();
     181        ifStmt->set_condition( newExpr );
     182        Visitor::visit( ifStmt );
     183    }
     184
     185    void Resolver::visit( WhileStmt *whileStmt ) {
     186        Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this );
     187        delete whileStmt->get_condition();
     188        whileStmt->set_condition( newExpr );
     189        Visitor::visit( whileStmt );
     190    }
     191
     192    void Resolver::visit( ForStmt *forStmt ) {
     193        Expression *newExpr;
     194        if ( forStmt->get_condition() ) {
     195            newExpr = findSingleExpression( forStmt->get_condition(), *this );
     196            delete forStmt->get_condition();
     197            forStmt->set_condition( newExpr );
     198        }
     199 
     200        if ( forStmt->get_increment() ) {
     201            newExpr = findVoidExpression( forStmt->get_increment(), *this );
     202            delete forStmt->get_increment();
     203            forStmt->set_increment( newExpr );
     204        }
     205 
     206        Visitor::visit( forStmt );
     207    }
     208
     209    template< typename SwitchClass >
     210    void handleSwitchStmt( SwitchClass *switchStmt, SymTab::Indexer &visitor ) {
     211        Expression *newExpr;
     212        newExpr = findIntegralExpression( switchStmt->get_condition(), visitor );
     213        delete switchStmt->get_condition();
     214        switchStmt->set_condition( newExpr );
     215 
     216        visitor.Visitor::visit( switchStmt );
     217    }
     218
     219    void Resolver::visit( SwitchStmt *switchStmt ) {
     220        handleSwitchStmt( switchStmt, *this );
     221    }
     222
     223    void Resolver::visit( ChooseStmt *switchStmt ) {
     224        handleSwitchStmt( switchStmt, *this );
     225    }
     226
     227    void Resolver::visit( CaseStmt *caseStmt ) {
     228        Visitor::visit( caseStmt );
     229    }
     230
     231    void Resolver::visit( ReturnStmt *returnStmt ) {
     232        if ( returnStmt->get_expr() ) {
     233            CastExpr *castExpr = new CastExpr( returnStmt->get_expr() );
     234            cloneAll( functionReturn, castExpr->get_results() );
     235            Expression *newExpr = findSingleExpression( castExpr, *this );
     236            delete castExpr;
     237            returnStmt->set_expr( newExpr );
     238        }
     239    }
     240
     241    void Resolver::visit( SingleInit *singleInit ) {
     242        // if ( singleInit->get_value() ) {
     243        //     CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() );
     244        //     Expression *newExpr = findSingleExpression( castExpr, *this );
     245        //     delete castExpr;
     246        //     singleInit->set_value( newExpr );
     247        // }
     248        // singleInit->get_value()->accept( *this );
     249    }
     250
     251    void Resolver::visit( ListInit *listInit ) {
     252        // no cast necessary
     253    }
    290254} // namespace ResolvExpr
  • translator/ResolvExpr/Resolver.h

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Resolver.h,v 1.3 2005/08/29 20:14:16 rcbilson Exp $
    5  *
    6  */
    7 
    8 #ifndef RESOLVEXPR_RESOLVER_H
    9 #define RESOLVEXPR_RESOLVER_H
     1#ifndef RESOLVER_H
     2#define RESOLVER_H
    103
    114#include "SynTree/SynTree.h"
     
    136
    147namespace ResolvExpr {
    15 
    16 void resolve( std::list< Declaration* > translationUnit );
    17 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
    18 
     8    void resolve( std::list< Declaration * > translationUnit );
     9    Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
    1910} // namespace ResolvExpr
    2011
    21 #endif /* #ifndef RESOLVEXPR_RESOLVER_H */
     12#endif // RESOLVER_H
  • translator/SynTree/Initializer.cc

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Initializer.cc,v 1.10 2005/08/29 20:59:25 rcbilson Exp $
    5  *
    6  */
    7 
    81#include "Initializer.h"
    92#include "Expression.h"
     
    114
    125
    13 Initializer::Initializer( )
    14 {
    15 }
     6Initializer::Initializer() {}
    167
    17 Initializer::~Initializer( )
    18 {
    19 }
     8Initializer::~Initializer() {}
    209
    2110std::string Initializer::designator_name( Expression *des ) {
    22     if( NameExpr *n = dynamic_cast<NameExpr *>(des) )
     11    if ( NameExpr *n = dynamic_cast<NameExpr *>(des) )
    2312        return n->get_name();
    2413    else
     
    2615}
    2716
    28 void
    29 Initializer::print( std::ostream &os, int indent )
    30 {
     17void Initializer::print( std::ostream &os, int indent ) {}
     18
     19SingleInit::SingleInit( Expression *v, std::list< Expression *> &_designators ) : value ( v ), designators( _designators ) {
    3120}
    3221
    33 SingleInit::SingleInit( Expression *v, std::list< Expression *> &_designators )
    34     : value ( v ), designators( _designators )
    35 {
    36 }
    37 
    38 SingleInit::SingleInit ( const SingleInit &other )
    39     : value ( other.value )
    40 {
     22SingleInit::SingleInit( const SingleInit &other ) : value ( other.value ) {
    4123    cloneAll(other.designators, designators );
    4224}
    4325
    44 SingleInit::~SingleInit()
    45 {
    46 }
     26SingleInit::~SingleInit() {}
    4727
    4828SingleInit *SingleInit::clone() const { return new SingleInit( *this); }
    4929
    50 void SingleInit::print( std::ostream &os, int indent )
    51 {
     30void SingleInit::print( std::ostream &os, int indent ) {
    5231    os << std::endl << std::string(indent, ' ' ) << "Simple Initializer: ";
    5332    value->print( os, indent+2 );
    5433
    55     if ( ! designators.empty() )
    56         {
    57             os << std::endl << std::string(indent + 2, ' ' ) << "designated by: "  ;
    58             for ( std::list < Expression * >::iterator i = designators.begin(); i != designators.end(); i++ )
    59                 ( *i )->print(os, indent + 4 );
    60         }
     34    if ( ! designators.empty() ) {
     35        os << std::endl << std::string(indent + 2, ' ' ) << "designated by: "  ;
     36        for ( std::list < Expression * >::iterator i = designators.begin(); i != designators.end(); i++ )
     37            ( *i )->print(os, indent + 4 );
     38    }
    6139}
    6240
    63 MemberInit::MemberInit( Expression *_value, std::string _member )
    64     : member ( _member ), value ( _value )
    65 {
    66 }
     41MemberInit::MemberInit( Expression *_value, std::string _member ) : member ( _member ), value ( _value ) {}
    6742
    68 MemberInit::~MemberInit()
    69 {
    70 }
     43MemberInit::~MemberInit() {}
    7144
    72 MemberInit * MemberInit::clone() const
    73 {
     45MemberInit * MemberInit::clone() const {
    7446    return new MemberInit( *this );
    7547}
    7648
    77 void MemberInit::print( std::ostream &os, int indent )
    78 {
     49void MemberInit::print( std::ostream &os, int indent ) {
    7950    os << "Member Initializer";
    8051    value->print( os, indent+2 );
     
    8253
    8354ListInit::ListInit( std::list<Initializer*> &_initializers, std::list<Expression *> &_designators )
    84     : initializers( _initializers ), designators( _designators )
    85 {
     55    : initializers( _initializers ), designators( _designators ) {
    8656}
    8757
    88 ListInit::~ListInit()
    89 {
    90 }
     58ListInit::~ListInit() {}
    9159
    92 ListInit *ListInit::clone() const
    93 {
     60ListInit *ListInit::clone() const {
    9461    return new ListInit( *this );
    9562}
    9663
    97 void ListInit::print( std::ostream &os, int indent )
    98 {
     64void ListInit::print( std::ostream &os, int indent ) {
    9965    os << std::endl << std::string(indent, ' ') << "Compound initializer:  ";
    100     if( ! designators.empty() ) {
     66    if ( ! designators.empty() ) {
    10167        os << std::string(indent + 2, ' ' ) << "designated by: [";
    10268        for ( std::list < Expression * >::iterator i = designators.begin();
  • translator/SynTree/Initializer.h

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Initializer.h,v 1.14 2005/08/29 20:59:25 rcbilson Exp $
    5  *
    6  */
    7 
    81#ifndef INITIALIZER_H
    92#define INITIALIZER_H
     
    1710
    1811// Initializer: base class for object initializers (provide default values)
    19 class Initializer
    20 {
    21 public:
     12class Initializer {
     13  public:
    2214    //  Initializer( std::string _name = std::string(""), int _pos = 0 );
    2315    Initializer( );
     
    4133    virtual Initializer *acceptMutator( Mutator &m ) = 0;
    4234    virtual void print( std::ostream &os, int indent = 0 );
    43    
    44 private:
     35  private:
    4536    //  std::string name;
    4637    //  int pos;
     
    4839
    4940// SingleInit represents an initializer for a common object (e.g., int x = 4)
    50 class SingleInit : public Initializer
    51 {
    52 public:
     41class SingleInit : public Initializer {
     42  public:
    5343    SingleInit( Expression *value, std::list< Expression *> &designators );
    5444    SingleInit( const SingleInit &other );
     
    6555    virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    6656    virtual void print( std::ostream &os, int indent = 0 );
    67    
    68 private:
     57  private:
    6958    //Constant *value;
    7059    Expression *value;  // has to be a compile-time constant
     
    7261};
    7362
    74 // MemberInit represents an initializer for a member of an aggregate object
    75 // (e.g., struct q { int a } x = { a: 4 } )
    76 class MemberInit : public Initializer
    77 {
    78 public:
     63// MemberInit represents an initializer for a member of an aggregate object (e.g., struct q { int a; } x = { a : 4 } )
     64class MemberInit : public Initializer {
     65  public:
    7966    MemberInit( Expression *value, std::string member = std::string("") );
    8067    virtual ~MemberInit();
     
    8976    virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    9077    virtual void print( std::ostream &os, int indent = 0 );
    91    
    92 private:
     78  private:
    9379    std::string member;
    9480    Expression *value;
    9581};
    9682
    97 // ElementInit represents an initializer of an element of an array
    98 // (e.g., [10] int x = { [7]: 4 }
    99 class ElementInit : public Initializer
    100 {
    101 public:
     83// ElementInit represents an initializer of an element of an array (e.g., [10] int x = { [7] : 4 }
     84class ElementInit : public Initializer {
     85  public:
    10286    ElementInit( Expression *value );
    10387    virtual ~ElementInit();
     
    11296    virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    11397    virtual void print( std::ostream &os, int indent = 0 );
    114    
    115 private:
     98  private:
    11699    int index;
    117100    Expression *value;
    118101};
    119102
    120 // ListInit represents an initializer that is composed recursively of a list of initializers; this
    121 // is used to initialize an array or aggregate
    122 class ListInit : public Initializer
    123 {
    124 public:
     103// ListInit represents an initializer that is composed recursively of a list of initializers; this is used to initialize
     104// an array or aggregate
     105class ListInit : public Initializer {
     106  public:
    125107    ListInit( std::list<Initializer*> &,
    126             std::list<Expression *> &designators = *(new std::list<Expression *>()) );
     108              std::list<Expression *> &designators = *(new std::list<Expression *>()) );
    127109    virtual ~ListInit();
    128110
     
    139121    virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    140122    virtual void print( std::ostream &os, int indent = 0 );
    141    
    142 private:
     123  private:
    143124    std::list<Initializer*> initializers;  // order *is* important
    144125    std::list<Expression *> designators;
    145126};
    146127
    147 
    148 #endif /* #ifndef INITIALIZER_H */
    149 
    150 /*
    151     Local Variables:
    152     mode: c++
    153     End:
    154 */
     128#endif // INITIALIZER_H
  • translator/SynTree/Mutator.cc

    r3848e0e rd9a0e76  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Mutator.cc,v 1.30 2005/08/29 20:59:25 rcbilson Exp $
    5  *
    6  */
    7 
    81#include <cassert>
    92#include "Mutator.h"
     
    169#include "utility.h"
    1710
    18 Mutator::Mutator()
    19 {
    20 }
    21 
    22 Mutator::~Mutator()
    23 {
    24 }
    25 
    26 ObjectDecl*
    27 Mutator::mutate(ObjectDecl *objectDecl)
    28 {
     11Mutator::Mutator() {}
     12
     13Mutator::~Mutator() {}
     14
     15ObjectDecl *Mutator::mutate( ObjectDecl *objectDecl ) {
    2916    objectDecl->set_type( maybeMutate( objectDecl->get_type(), *this ) );
    3017    objectDecl->set_init( maybeMutate( objectDecl->get_init(), *this ) );
     
    3320}
    3421
    35 DeclarationWithType*
    36 Mutator::mutate(FunctionDecl *functionDecl)
    37 {
     22DeclarationWithType *Mutator::mutate( FunctionDecl *functionDecl ) {
    3823    functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
    3924    mutateAll( functionDecl->get_oldDecls(), *this );
     
    4227}
    4328
    44 Declaration*
    45 Mutator::handleAggregateDecl(AggregateDecl *aggregateDecl)
    46 {
     29