Changes in / [9a8930f:a61fea9a]


Ignore:
Location:
src
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r9a8930f ra61fea9a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CodeGenerator.cc --
     7// CodeGenerator2.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  4 14:05:45 2015
    13 // Update Count     : 120
     12// Last Modified On : Wed Jun  3 11:53:32 2015
     13// Update Count     : 13
    1414//
    1515
     
    3535
    3636namespace CodeGen {
    37         int CodeGenerator::tabsize = 4;
    38 
    39         // the kinds of statements that would ideally be separated by more whitespace
    40         bool wantSpacing( Statement * stmt) {
    41                 return dynamic_cast< IfStmt * >( stmt ) || dynamic_cast< CompoundStmt * >( stmt ) ||
    42                         dynamic_cast< WhileStmt * >( stmt ) || dynamic_cast< ForStmt * > ( stmt ) || dynamic_cast< SwitchStmt *>( stmt );
    43         }
    44 
    45         CodeGenerator::CodeGenerator( std::ostream &os ) : cur_indent( 0 ), insideFunction( false ), output( os ) { }
    46 
    47         CodeGenerator::CodeGenerator( std::ostream &os, std::string init, int indent, bool infunp )
    48                         : cur_indent( indent ), insideFunction( infunp ), output( os ) {
    49                 //output << std::string( init );
    50         }
    51 
    52         CodeGenerator::CodeGenerator( std::ostream &os, char *init, int indent, bool infunp )
    53                         : cur_indent( indent ), insideFunction( infunp ), output( os ) {
    54                 //output << std::string( init );
     37        int CodeGenerator2::tabsize = 4;
     38
     39        CodeGenerator2::CodeGenerator2( std::ostream &os ) : cur_indent( 0 ), insideFunction( false ), before( os ), after() { }
     40
     41        CodeGenerator2::CodeGenerator2( std::ostream &os, std::string init, int indent, bool infunp )
     42                        : cur_indent( indent ), insideFunction( infunp ), before( os ) {
     43                //before << std::string( init );
     44        }
     45
     46        CodeGenerator2::CodeGenerator2( std::ostream &os, char *init, int indent, bool infunp )
     47                        : cur_indent( indent ), insideFunction( infunp ), before( os ) {
     48                //before << std::string( init );
    5549        }
    5650
     
    6458 
    6559        //*** Declarations
    66         void CodeGenerator::visit( FunctionDecl *functionDecl ) {
     60        void CodeGenerator2::visit( FunctionDecl *functionDecl ) {
    6761                handleStorageClass( functionDecl );
    6862                if ( functionDecl->get_isInline() ) {
    69                         output << "inline ";
    70                 } // if
    71                 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );
     63                        before << "inline ";
     64                } // if
     65                before << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );
    7266
    7367                // how to get this to the Functype?
    7468                std::list< Declaration * > olds = functionDecl->get_oldDecls();
    7569                if ( ! olds.empty() ) {
    76                         output << " /* function has old declaration */";
     70                        before << " /* function has old declaration */";
    7771                } // if
    7872
     
    8377        }
    8478
    85         void CodeGenerator::visit( ObjectDecl *objectDecl ) {
     79        void CodeGenerator2::visit( ObjectDecl *objectDecl ) {
    8680                handleStorageClass( objectDecl );
    87                 output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
     81                before << genType( objectDecl->get_type(), mangleName( objectDecl ) );
    8882       
    8983                if ( objectDecl->get_init() ) {
    90                         output << " = ";
     84                        before << " = ";
    9185                        objectDecl->get_init()->accept( *this );
    9286                } // if
    9387                if ( objectDecl->get_bitfieldWidth() ) {
    94                         output << ":";
     88                        before << ":";
    9589                        objectDecl->get_bitfieldWidth()->accept( *this );
    9690                } // if
    9791        }
    9892
    99         void CodeGenerator::handleAggregate( AggregateDecl *aggDecl ) {
     93        void CodeGenerator2::handleAggregate( AggregateDecl *aggDecl ) {
    10094                if ( aggDecl->get_name() != "" )
    101                         output << aggDecl->get_name();
     95                        before << aggDecl->get_name();
    10296       
    10397                std::list< Declaration * > &memb = aggDecl->get_members();
    10498
    10599                if ( ! memb.empty() ) {
    106                         output << endl << string( cur_indent, ' ' ) << "{" << endl;
    107 
    108                         cur_indent += CodeGenerator::tabsize;
     100                        before << endl << string( cur_indent, ' ' ) << "{" << endl;
     101
     102                        cur_indent += CodeGenerator2::tabsize;
    109103                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    110                                 output << string( cur_indent, ' ' );
     104                                before << string( cur_indent, ' ' );
    111105                                (*i)->accept(*this );
    112                                 output << ";" << endl;
     106                                before << ";" << endl;
    113107                        }
    114108
    115                         cur_indent -= CodeGenerator::tabsize;
    116 
    117                         output << string( cur_indent, ' ' ) << "}";
    118                 } // if
    119         }
    120 
    121         void CodeGenerator::visit( StructDecl *structDecl ) {
    122                 output << "struct ";
     109                        cur_indent -= CodeGenerator2::tabsize;
     110
     111                        before << string( cur_indent, ' ' ) << "}";
     112                } // if
     113        }
     114
     115        void CodeGenerator2::visit( StructDecl *structDecl ) {
     116                before << "struct ";
    123117                handleAggregate( structDecl );
    124118        }
    125119
    126         void CodeGenerator::visit( UnionDecl *aggregateDecl ) {
    127                 output << "union ";
     120        void CodeGenerator2::visit( UnionDecl *aggregateDecl ) {
     121                before << "union ";
    128122                handleAggregate( aggregateDecl );
    129123        }
    130124 
    131         void CodeGenerator::visit( EnumDecl *aggDecl ) {
    132                 output << "enum ";
     125        void CodeGenerator2::visit( EnumDecl *aggDecl ) {
     126                before << "enum ";
    133127
    134128                if ( aggDecl->get_name() != "" )
    135                         output << aggDecl->get_name();
     129                        before << aggDecl->get_name();
    136130       
    137131                std::list< Declaration* > &memb = aggDecl->get_members();
    138132
    139133                if ( ! memb.empty() ) {
    140                         output << endl << "{" << endl;
    141 
    142                         cur_indent += CodeGenerator::tabsize;
     134                        before << endl << "{" << endl;
     135
     136                        cur_indent += CodeGenerator2::tabsize;
    143137                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    144138                                ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
    145139                                assert( obj );
    146                                 output << string( cur_indent, ' ' ) << mangleName( obj );
     140                                before << string( cur_indent, ' ' ) << mangleName( obj );
    147141                                if ( obj->get_init() ) {
    148                                         output << " = ";
     142                                        before << " = ";
    149143                                        obj->get_init()->accept(*this );
    150144                                } // if
    151                                 output << "," << endl;
     145                                before << "," << endl;
    152146                        } // for
    153147
    154                         cur_indent -= CodeGenerator::tabsize;
    155 
    156                         output << "}" << endl;
    157                 } // if
    158         }
    159  
    160         void CodeGenerator::visit( ContextDecl *aggregateDecl ) {}
    161  
    162         void CodeGenerator::visit( TypedefDecl *typeDecl ) {
    163                 output << "typedef ";
    164                 output << genType( typeDecl->get_base(), typeDecl->get_name() );
    165         }
    166  
    167         void CodeGenerator::visit( TypeDecl *typeDecl ) {
     148                        cur_indent -= CodeGenerator2::tabsize;
     149
     150                        before << "}" << endl;
     151                } // if
     152        }
     153 
     154        void CodeGenerator2::visit( ContextDecl *aggregateDecl ) {}
     155 
     156        void CodeGenerator2::visit( TypedefDecl *typeDecl ) {
     157                before << "typedef ";
     158                before << genType( typeDecl->get_base(), typeDecl->get_name() );
     159        }
     160 
     161        void CodeGenerator2::visit( TypeDecl *typeDecl ) {
    168162                // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
    169163                // still to be done
    170                 output << "extern unsigned long " << typeDecl->get_name();
     164                before << "extern unsigned long " << typeDecl->get_name();
    171165                if ( typeDecl->get_base() ) {
    172                         output << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";
    173                 } // if
    174         }
    175 
    176         void CodeGenerator::visit( SingleInit *init ) {
     166                        before << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";
     167                } // if
     168        }
     169
     170        void CodeGenerator2::visit( SingleInit *init ) {
    177171                init->get_value()->accept( *this );
    178172        }
    179173
    180         void CodeGenerator::visit( ListInit *init ) {
    181                 output << "{ ";
     174        void CodeGenerator2::visit( ListInit *init ) {
     175                before << "{ ";
    182176                genCommaList( init->begin_initializers(), init->end_initializers() );
    183                 output << " }";
    184         }
    185 
    186         void CodeGenerator::visit( Constant *constant ) {
    187                 output << constant->get_value() ;
     177                before << " }";
     178        }
     179
     180        void CodeGenerator2::visit( Constant *constant ) {
     181                before << constant->get_value() ;
    188182        }
    189183
    190184        //*** Expressions
    191         void CodeGenerator::visit( ApplicationExpr *applicationExpr ) {
     185        void CodeGenerator2::visit( ApplicationExpr *applicationExpr ) {
    192186                if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
    193187                        OperatorInfo opInfo;
     
    220214                                        assert( applicationExpr->get_args().size() == 2 );
    221215                                        (*arg++)->accept( *this );
    222                                         output << "[";
    223                                         (*arg)->accept( *this );
    224                                         output << "]";
     216                                        before << "[";
     217                                        (*arg)->accept( *this );
     218                                        before << "]";
    225219                                        break;
    226220             
     
    233227                                  case OT_PREFIXASSIGN:
    234228                                        assert( applicationExpr->get_args().size() == 1 );
    235                                         output << "(";
    236                                         output << opInfo.symbol;
    237                                         (*arg)->accept( *this );
    238                                         output << ")";
     229                                        before << "(";
     230                                        before << opInfo.symbol;
     231                                        (*arg)->accept( *this );
     232                                        before << ")";
    239233                                        break;
    240234             
     
    243237                                        assert( applicationExpr->get_args().size() == 1 );
    244238                                        (*arg)->accept( *this );
    245                                         output << opInfo.symbol;
     239                                        before << opInfo.symbol;
    246240                                        break;
    247241
     
    249243                                  case OT_INFIXASSIGN:
    250244                                        assert( applicationExpr->get_args().size() == 2 );
    251                                         output << "(";
     245                                        before << "(";
    252246                                        (*arg++)->accept( *this );
    253                                         output << opInfo.symbol;
    254                                         (*arg)->accept( *this );
    255                                         output << ")";
     247                                        before << opInfo.symbol;
     248                                        (*arg)->accept( *this );
     249                                        before << ")";
    256250                                        break;
    257251             
     
    262256                        } else {
    263257                                varExpr->accept( *this );
    264                                 output << "(";
     258                                before << "(";
    265259                                genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
    266                                 output << ")";
     260                                before << ")";
    267261                        } // if
    268262                } else {
    269263                        applicationExpr->get_function()->accept( *this );
    270                         output << "(";
     264                        before << "(";
    271265                        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
    272                         output << ")";
    273                 } // if
    274         }
    275  
    276         void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
     266                        before << ")";
     267                } // if
     268        }
     269 
     270        void CodeGenerator2::visit( UntypedExpr *untypedExpr ) {
    277271                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
    278272                        OperatorInfo opInfo;
     
    283277                                        assert( untypedExpr->get_args().size() == 2 );
    284278                                        (*arg++)->accept( *this );
    285                                         output << "[";
    286                                         (*arg)->accept( *this );
    287                                         output << "]";
     279                                        before << "[";
     280                                        (*arg)->accept( *this );
     281                                        before << "]";
    288282                                        break;
    289283             
     
    295289                                  case OT_PREFIXASSIGN:
    296290                                        assert( untypedExpr->get_args().size() == 1 );
    297                                         output << "(";
    298                                         output << opInfo.symbol;
    299                                         (*arg)->accept( *this );
    300                                         output << ")";
     291                                        before << "(";
     292                                        before << opInfo.symbol;
     293                                        (*arg)->accept( *this );
     294                                        before << ")";
    301295                                        break;
    302296             
     
    305299                                        assert( untypedExpr->get_args().size() == 1 );
    306300                                        (*arg)->accept( *this );
    307                                         output << opInfo.symbol;
     301                                        before << opInfo.symbol;
    308302                                        break;
    309303 
     
    311305                                  case OT_INFIXASSIGN:
    312306                                        assert( untypedExpr->get_args().size() == 2 );
    313                                         output << "(";
     307                                        before << "(";
    314308                                        (*arg++)->accept( *this );
    315                                         output << opInfo.symbol;
    316                                         (*arg)->accept( *this );
    317                                         output << ")";
     309                                        before << opInfo.symbol;
     310                                        (*arg)->accept( *this );
     311                                        before << ")";
    318312                                        break;
    319313             
     
    324318                        } else {
    325319                                nameExpr->accept( *this );
    326                                 output << "(";
     320                                before << "(";
    327321                                genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
    328                                 output << ")";
     322                                before << ")";
    329323                        } // if
    330324                } else {
    331325                        untypedExpr->get_function()->accept( *this );
    332                         output << "(";
     326                        before << "(";
    333327                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
    334                         output << ")";
    335                 } // if
    336         }
    337  
    338         void CodeGenerator::visit( NameExpr *nameExpr ) {
     328                        before << ")";
     329                } // if
     330        }
     331 
     332        void CodeGenerator2::visit( NameExpr *nameExpr ) {
    339333                OperatorInfo opInfo;
    340334                if ( operatorLookup( nameExpr->get_name(), opInfo ) ) {
    341335                        assert( opInfo.type == OT_CONSTANT );
    342                         output << opInfo.symbol;
    343                 } else {
    344                         output << nameExpr->get_name();
    345                 } // if
    346         }
    347  
    348         void CodeGenerator::visit( AddressExpr *addressExpr ) {
    349                 output << "(&";
     336                        before << opInfo.symbol;
     337                } else {
     338                        before << nameExpr->get_name();
     339                } // if
     340        }
     341 
     342        void CodeGenerator2::visit( AddressExpr *addressExpr ) {
     343                before << "(&";
    350344                // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
    351345                if ( VariableExpr *variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {
    352                         output << mangleName( variableExpr->get_var() );
     346                        before << mangleName( variableExpr->get_var() );
    353347                } else {
    354348                        addressExpr->get_arg()->accept( *this );
    355349                } // if
    356                 output << ")";
    357         }
    358 
    359         void CodeGenerator::visit( CastExpr *castExpr ) {
    360                 output << "((";
     350                before << ")";
     351        }
     352
     353        void CodeGenerator2::visit( CastExpr *castExpr ) {
     354                before << "((";
    361355                if ( castExpr->get_results().empty() ) {
    362                         output << "void" ;
    363                 } else {
    364                         output << genType( castExpr->get_results().front(), "" );
    365                 } // if
    366                 output << ")";
     356                        before << "void" ;
     357                } else {
     358                        before << genType( castExpr->get_results().front(), "" );
     359                } // if
     360                before << ")";
    367361                castExpr->get_arg()->accept( *this );
    368                 output << ")";
    369         }
    370  
    371         void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
     362                before << ")";
     363        }
     364 
     365        void CodeGenerator2::visit( UntypedMemberExpr *memberExpr ) {
    372366                assert( false );
    373367        }
    374368 
    375         void CodeGenerator::visit( MemberExpr *memberExpr ) {
     369        void CodeGenerator2::visit( MemberExpr *memberExpr ) {
    376370                memberExpr->get_aggregate()->accept( *this );
    377                 output << "." << mangleName( memberExpr->get_member() );
    378         }
    379  
    380         void CodeGenerator::visit( VariableExpr *variableExpr ) {
     371                before << "." << mangleName( memberExpr->get_member() );
     372        }
     373 
     374        void CodeGenerator2::visit( VariableExpr *variableExpr ) {
    381375                OperatorInfo opInfo;
    382376                if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) {
    383                         output << opInfo.symbol;
    384                 } else {
    385                         output << mangleName( variableExpr->get_var() );
    386                 } // if
    387         }
    388  
    389         void CodeGenerator::visit( ConstantExpr *constantExpr ) {
     377                        before << opInfo.symbol;
     378                } else {
     379                        before << mangleName( variableExpr->get_var() );
     380                } // if
     381        }
     382 
     383        void CodeGenerator2::visit( ConstantExpr *constantExpr ) {
    390384                assert( constantExpr->get_constant() );
    391385                constantExpr->get_constant()->accept( *this );
    392386        }
    393387 
    394         void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
    395                 output << "sizeof(";
     388        void CodeGenerator2::visit( SizeofExpr *sizeofExpr ) {
     389                before << "sizeof(";
    396390                if ( sizeofExpr->get_isType() ) {
    397                         output << genType( sizeofExpr->get_type(), "" );
     391                        before << genType( sizeofExpr->get_type(), "" );
    398392                } else {
    399393                        sizeofExpr->get_expr()->accept( *this );
    400394                } // if
    401                 output << ")";
    402         }
    403  
    404         void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
    405                 output << "(";
     395                before << ")";
     396        }
     397 
     398        void CodeGenerator2::visit( LogicalExpr *logicalExpr ) {
     399                before << "(";
    406400                logicalExpr->get_arg1()->accept( *this );
    407401                if ( logicalExpr->get_isAnd() ) {
    408                         output << " && ";
    409                 } else {
    410                         output << " || ";
     402                        before << " && ";
     403                } else {
     404                        before << " || ";
    411405                } // if
    412406                logicalExpr->get_arg2()->accept( *this );
    413                 output << ")";
    414         }
    415  
    416         void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
    417                 output << "(";
     407                before << ")";
     408        }
     409 
     410        void CodeGenerator2::visit( ConditionalExpr *conditionalExpr ) {
     411                before << "(";
    418412                conditionalExpr->get_arg1()->accept( *this );
    419                 output << " ? ";
     413                before << " ? ";
    420414                conditionalExpr->get_arg2()->accept( *this );
    421                 output << " : ";
     415                before << " : ";
    422416                conditionalExpr->get_arg3()->accept( *this );
    423                 output << ")";
    424         }
    425  
    426         void CodeGenerator::visit( CommaExpr *commaExpr ) {
    427                 output << "(";
     417                before << ")";
     418        }
     419 
     420        void CodeGenerator2::visit( CommaExpr *commaExpr ) {
     421                before << "(";
    428422                commaExpr->get_arg1()->accept( *this );
    429                 output << " , ";
     423                before << " , ";
    430424                commaExpr->get_arg2()->accept( *this );
    431                 output << ")";
    432         }
    433  
    434         void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
    435  
    436         void CodeGenerator::visit( TypeExpr *typeExpr ) {}
    437 
     425                before << ")";
     426        }
     427 
     428        void CodeGenerator2::visit( TupleExpr *tupleExpr ) {}
     429 
     430        void CodeGenerator2::visit( TypeExpr *typeExpr ) {}
     431 
     432 
    438433        //*** Statements
    439         void CodeGenerator::visit( CompoundStmt *compoundStmt ) {
     434        void CodeGenerator2::visit( CompoundStmt *compoundStmt ) {
    440435                std::list<Statement*> ks = compoundStmt->get_kids();
    441                 output << "{" << endl;
    442 
    443                 cur_indent += CodeGenerator::tabsize;
     436
     437                before << endl << string( cur_indent, ' ' ) << "{" << endl;
     438
     439                cur_indent += CodeGenerator2::tabsize;
    444440
    445441                for ( std::list<Statement *>::iterator i = ks.begin(); i != ks.end();  i++) {
    446                         output << string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() );
     442                        before << string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() )  ;
    447443                        (*i)->accept(*this );
    448 
    449                         output << endl;
    450                         if ( wantSpacing( *i ) ) {
    451                                 output << endl;
    452                         }
     444                        shift_left();
     445                        before << endl;
    453446                }
    454                 cur_indent -= CodeGenerator::tabsize;
    455 
    456                 output << string( cur_indent, ' ' ) << "}";
    457         }
    458 
    459         void CodeGenerator::visit( ExprStmt *exprStmt ) {
    460                 // I don't see why this check is necessary.
    461                 // If this starts to cause problems then put it back in,
    462                 // with an explanation
    463                 assert( exprStmt );
    464 
    465                 // if ( exprStmt != 0 ) {
    466                 exprStmt->get_expr()->accept( *this );
    467                 output << ";" ;
    468                 // } // if
    469         }
    470 
    471         void CodeGenerator::visit( IfStmt *ifStmt ) {
    472                 output << "if (";
     447                cur_indent -= CodeGenerator2::tabsize;
     448
     449                before << string( cur_indent, ' ' ) << "}" << endl;
     450        }
     451
     452        void CodeGenerator2::visit( ExprStmt *exprStmt ) {
     453                if ( exprStmt != 0 ) {
     454                        exprStmt->get_expr()->accept( *this );
     455                        shift_left();
     456                        before << ";" ;
     457                } // if
     458        }
     459
     460        void CodeGenerator2::visit( IfStmt *ifStmt ) {
     461                before << "if (";
    473462                ifStmt->get_condition()->accept(*this );
    474                 output << ") ";
    475 
     463                after += ")\n";
     464                shift_left();
     465
     466                cur_indent += CodeGenerator2::tabsize;
     467                before << string( cur_indent, ' ' );
    476468                ifStmt->get_thenPart()->accept(*this );
     469                cur_indent -= CodeGenerator2::tabsize;
     470                shift_left(); before << endl;
    477471
    478472                if ( ifStmt->get_elsePart() != 0) {
    479                         output << " else ";
     473                        before << string( cur_indent, ' ' ) << " else " << endl ;
     474
     475                        cur_indent += CodeGenerator2::tabsize;
    480476                        ifStmt->get_elsePart()->accept(*this );
    481                 } // if
    482         }
    483 
    484         void CodeGenerator::visit( SwitchStmt *switchStmt ) {
    485                 //output << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator::printLabels( switchStmt->get_labels() )
    486                 output << "switch (" ;
     477                        cur_indent -= CodeGenerator2::tabsize;
     478                } // if
     479        }
     480
     481        void CodeGenerator2::visit( SwitchStmt *switchStmt ) {
     482                //before << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator2::printLabels( switchStmt->get_labels() )
     483                before << "switch (" ;
    487484                switchStmt->get_condition()->accept(*this );
    488                 output << ") ";
    489                
    490                 output << "{" << std::endl;
    491                 cur_indent += CodeGenerator::tabsize;
    492 
    493                 acceptAll( switchStmt->get_branches(), *this );
    494 
    495                 cur_indent -= CodeGenerator::tabsize;
    496 
    497                 output << string( cur_indent, ' ' ) << "}";
    498         }
    499 
    500         void CodeGenerator::visit( CaseStmt *caseStmt ) {
    501                 output << string( cur_indent, ' ' );
     485                after += ")\n";
     486                shift_left();
     487
     488                before << string( cur_indent, ' ' ) << "{" << std::endl;
     489                cur_indent += CodeGenerator2::tabsize;
     490
     491                std::list< Statement * > stmts = switchStmt->get_branches();
     492                bool lastBreak = false;
     493
     494                // horrible, horrible hack
     495                if ( dynamic_cast<BranchStmt *>( stmts.back() ) != 0 ) {
     496                        lastBreak = true;
     497                        stmts.pop_back();
     498                } // if
     499                acceptAll( stmts, *this );
     500                if ( lastBreak ) {
     501                        Statement *st = switchStmt->get_branches().back();
     502                        before << CodeGenerator2::printLabels( st->get_labels());
     503                        st->accept( *this );
     504                } // if
     505         
     506                cur_indent -= CodeGenerator2::tabsize;
     507
     508                before << /* "\r" << */ string( cur_indent, ' ' ) << "}" << endl ;
     509        }
     510
     511        void CodeGenerator2::visit( CaseStmt *caseStmt ) {
     512                before << string( cur_indent, ' ' );
    502513                if ( caseStmt->isDefault())
    503                         output << "default";
     514                        before << "default "  ;
    504515                else {
    505                         output << "case ";
     516                        before << "case "  ;
    506517                        caseStmt->get_condition()->accept(*this );
    507518                } // if
    508                 output << ":\n";
    509                
     519                after += ":\n";
     520                shift_left();
     521
    510522                std::list<Statement *> sts = caseStmt->get_statements();
    511523
    512                 cur_indent += CodeGenerator::tabsize;
     524                cur_indent += CodeGenerator2::tabsize;
    513525                for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++) {
    514                         output << /* "\r" << */ string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() )  ;
     526                        before << /* "\r" << */ string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() )  ;
    515527                        (*i)->accept(*this );
    516                         output << endl;
     528                        shift_left();
     529                        before << ";" << endl;
    517530                }
    518                 cur_indent -= CodeGenerator::tabsize;
    519         }
    520 
    521         void CodeGenerator::visit( BranchStmt *branchStmt ) {
    522                 output << "\r" << string( cur_indent, ' ' );
    523                 output << CodeGenerator::printLabels( branchStmt->get_labels());
    524 
     531                cur_indent -= CodeGenerator2::tabsize;
     532        }
     533
     534        void CodeGenerator2::visit( BranchStmt *branchStmt ) {
    525535                switch ( branchStmt->get_type()) {
    526536                  case BranchStmt::Goto:
    527537                        if ( ! branchStmt->get_target().empty() )
    528                                 output << "goto " << branchStmt->get_target();
     538                                before << "goto " << branchStmt->get_target();
    529539                        else {
    530540                                if ( branchStmt->get_computedTarget() != 0 ) {
    531                                         output << "goto *";
     541                                        before << "goto *";
    532542                                        branchStmt->get_computedTarget()->accept( *this );
    533543                                } // if
     
    535545                        break;
    536546                  case BranchStmt::Break:
    537                         output << "break";
     547                        before << "break";
    538548                        break;
    539549                  case BranchStmt::Continue:
    540                         output << "continue";
     550                        before << "continue";
    541551                        break;
    542552                }
    543                 output << ";";
    544         }
    545 
    546 
    547         void CodeGenerator::visit( ReturnStmt *returnStmt ) {
    548                 output << "return ";
     553                before << ";";
     554        }
     555
     556
     557        void CodeGenerator2::visit( ReturnStmt *returnStmt ) {
     558                before << "return ";
    549559
    550560                // xxx -- check for null expression;
     
    552562                        returnStmt->get_expr()->accept( *this );
    553563                } // if
    554                 output << ";";
    555         }
    556 
    557         void CodeGenerator::visit( WhileStmt *whileStmt ) {
     564                after += ";";
     565        }
     566
     567        void CodeGenerator2::visit( WhileStmt *whileStmt ) {
    558568                if ( whileStmt->get_isDoWhile() )
    559                         output << "do" ;
     569                        before << "do" ;
    560570                else {
    561                         output << "while (" ;
     571                        before << "while (" ;
    562572                        whileStmt->get_condition()->accept(*this );
    563                         output << ")";
    564                 } // if
    565                 output << " ";
    566 
    567                 output << CodeGenerator::printLabels( whileStmt->get_body()->get_labels() );
     573                        after += ")";
     574                } // if
     575                after += "{\n";
     576                shift_left();
     577
    568578                whileStmt->get_body()->accept( *this );
    569579
    570                 output << /* "\r" << */ string( cur_indent, ' ' );
     580                before << /* "\r" << */ string( cur_indent, ' ' ) << "}" ;
    571581
    572582                if ( whileStmt->get_isDoWhile() ) {
    573                         output << " while (" ;
     583                        before << " while (" ;
    574584                        whileStmt->get_condition()->accept(*this );
    575                         output << ");";
    576                 } // if
    577         }
    578 
    579         void CodeGenerator::visit( ForStmt *forStmt ) {
    580                 output << "for (";
     585                        after += ");";
     586                } // if
     587
     588                after += "\n";
     589        }
     590
     591        void CodeGenerator2::visit( ForStmt *forStmt ) {
     592                before << "for (";
    581593
    582594                if ( forStmt->get_initialization() != 0 )
    583595                        forStmt->get_initialization()->accept( *this );
    584596                else
    585                         output << ";";
    586                
     597                        before << ";";
     598                shift_left();
     599
    587600                if ( forStmt->get_condition() != 0 )
    588601                        forStmt->get_condition()->accept( *this );
    589                 output << ";";
     602                shift_left(); before << ";";
    590603
    591604                if ( forStmt->get_increment() != 0 )
    592605                        forStmt->get_increment()->accept( *this );
    593                 output << ") ";
     606                shift_left(); before << ")" << endl;
    594607
    595608                if ( forStmt->get_body() != 0 ) {
    596                         output << CodeGenerator::printLabels( forStmt->get_body()->get_labels() );
     609                        cur_indent += CodeGenerator2::tabsize;
     610                        before << string( cur_indent, ' ' ) << CodeGenerator2::printLabels( forStmt->get_body()->get_labels() );
    597611                        forStmt->get_body()->accept( *this );
    598                 } // if
    599         }
    600 
    601         void CodeGenerator::visit( NullStmt *nullStmt ) {
    602                 //output << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator::printLabels( nullStmt->get_labels() );
    603                 output << "/* null statement */ ;";
    604         }
    605 
    606         void CodeGenerator::visit( DeclStmt *declStmt ) {
     612                        cur_indent -= CodeGenerator2::tabsize;
     613                } // if
     614        }
     615
     616        void CodeGenerator2::visit( NullStmt *nullStmt ) {
     617                //before << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator2::printLabels( nullStmt->get_labels() );
     618                before << "/* null statement */ ;";
     619        }
     620
     621        void CodeGenerator2::visit( DeclStmt *declStmt ) {
    607622                declStmt->get_decl()->accept( *this );
    608623       
    609624                if ( doSemicolon( declStmt->get_decl() ) ) {
    610                         output << ";";
    611                 } // if
    612         }
    613 
    614         std::string CodeGenerator::printLabels( std::list< Label > &l ) {
     625                        after += ";";
     626                } // if
     627                shift_left();
     628        }
     629
     630        std::string CodeGenerator2::printLabels( std::list< Label > &l ) {
    615631                std::string str( "" );
    616                 l.unique(); // assumes a sorted list. Why not use set?
     632                l.unique();
    617633
    618634                for ( std::list< Label >::iterator i = l.begin(); i != l.end(); i++ )
     
    622638        }
    623639
    624         void CodeGenerator::handleStorageClass( Declaration *decl ) {
     640        void CodeGenerator2::shift_left() {
     641                before << after;
     642                after = "";
     643        }
     644
     645        void CodeGenerator2::handleStorageClass( Declaration *decl ) {
    625646                switch ( decl->get_storageClass() ) {
    626647                  case Declaration::NoStorageClass:
    627648                        break;
    628649                  case Declaration::Extern:
    629                         output << "extern ";
     650                        before << "extern ";
    630651                        break;
    631652                  case Declaration::Static:
    632                         output << "static ";
     653                        before << "static ";
    633654                        break;
    634655                  case Declaration::Auto:
     
    636657                        break;
    637658                  case Declaration::Register:
    638                         output << "register ";
     659                        before << "register ";
    639660                        break;
    640661                  case Declaration::Inline:
  • src/CodeGen/CodeGenerator.h

    r9a8930f ra61fea9a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CodeGenerator.h --
     7// CodeGenerator2.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Jun 02 13:43:29 2015
    13 // Update Count     : 14
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon May 18 23:35:37 2015
     13// Update Count     : 2
    1414//
    1515
     
    2525
    2626namespace CodeGen {
    27         class CodeGenerator : public Visitor {
     27        class CodeGenerator2 : public Visitor {
    2828          public:
    2929                static int tabsize;
    3030
    31                 CodeGenerator( std::ostream &os );
    32                 CodeGenerator( std::ostream &os, std::string, int indent = 0, bool infun = false );
    33                 CodeGenerator( std::ostream &os, char *, int indent = 0, bool infun = false );
     31                CodeGenerator2( std::ostream &os );
     32                CodeGenerator2( std::ostream &os, std::string, int indent = 0, bool infun = false );
     33                CodeGenerator2( std::ostream &os, char *, int indent = 0, bool infun = false );
     34
     35                CodeGenerator2( CodeGenerator2 & );
    3436
    3537                //*** Declaration
     
    8082                virtual void visit( DeclStmt * );
    8183
     84                std::string get_string( void );
     85                void add_string_left( std::string s ) { before << s; }
     86                void shift_left();
    8287                template< class Iterator > void genCommaList( Iterator begin, Iterator end );
    8388          private:
    8489                int cur_indent;
    8590                bool insideFunction;
    86                 std::ostream &output;
     91                std::ostream &before;
     92                std::string after;
    8793
    8894                static std::string printLabels ( std::list < Label > & );
     
    94100       
    95101        template< class Iterator >
    96         void CodeGenerator::genCommaList( Iterator begin, Iterator end ) {
     102        void CodeGenerator2::genCommaList( Iterator begin, Iterator end ) {
    97103                if ( begin == end ) return;
    98104
     
    100106                        (*begin++)->accept( *this );
    101107                        if ( begin == end ) return;
    102                         output << ", ";
     108                        before << ", ";
    103109                } // for
    104110        }
  • src/CodeGen/GenType.cc

    r9a8930f ra61fea9a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  4 14:04:58 2015
    13 // Update Count     : 4
     12// Last Modified On : Tue Jun  2 11:21:32 2015
     13// Update Count     : 3
    1414//
    1515
     
    9797                } // if
    9898                if ( dimension != 0 ) {
    99                         CodeGenerator cg( os );
     99                        CodeGenerator2 cg( os );
    100100                        dimension->accept( cg );
    101101                } // if
     
    148148                        } // if
    149149                } else {
    150                         CodeGenerator cg( os );
     150                        CodeGenerator2 cg( os );
    151151                        os << "(" ;
    152152
  • src/CodeGen/Generate.cc

    r9a8930f ra61fea9a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  4 14:04:25 2015
    13 // Update Count     : 5
     12// Last Modified On : Tue Jun  2 11:21:06 2015
     13// Update Count     : 2
    1414//
    1515
     
    2727namespace CodeGen {
    2828        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics ) {
    29                 CodeGen::CodeGenerator cgv( os );
     29                CodeGen::CodeGenerator2 cgv( os );
    3030
    3131                for ( std::list<Declaration *>::iterator i = translationUnit.begin(); i != translationUnit.end();  i++ ) {
    3232                        if ( LinkageSpec::isGeneratable( (*i)->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) ) {
    3333                                (*i)->accept(cgv);
     34                                cgv.shift_left();
    3435                                if ( doSemicolon( *i ) ) {
    3536                                        os << ";";
  • src/Common/utility.h

    r9a8930f ra61fea9a  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri May 29 16:17:02 2015
    13 // Update Count     : 7
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 15:34:57 2015
     13// Update Count     : 3
    1414//
    1515
     
    198198}
    199199
    200 // it's nice to actually be able to increment iterators by an arbitrary amount
    201 template< typename Iterator >
    202 Iterator operator+(Iterator i, int inc) {
    203         while ( inc > 0 ) {
    204                 ++i;
    205                 --inc;
    206         }
    207         return i;
    208 }
    209 
    210200#endif // _UTILITY_H
    211201
  • src/ControlStruct/ChooseMutator.cc

    r9a8930f ra61fea9a  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Jun 03 15:30:20 2015
    13 // Update Count     : 5
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 15:31:39 2015
     13// Update Count     : 2
    1414//
    1515
     
    4444                std::list< Statement * > &stmts = caseStmt->get_statements();
    4545
    46                 // the difference between switch and choose is that switch has an implicit fallthrough
    47                 // to the next case, whereas choose has an implicit break at the end of the current case.
    48                 // thus to transform a choose statement into a switch, we only need to insert breaks at the
    49                 // end of any case that doesn't already end in a break and that doesn't end in a fallthru
    50 
    5146                if ( insideChoose ) {
    5247                        BranchStmt *posBrk;
  • src/ControlStruct/LabelFixer.cc

    r9a8930f ra61fea9a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Jun 02 15:30:32 2015
    13 // Update Count     : 93
     12// Last Modified On : Wed May 27 16:16:14 2015
     13// Update Count     : 4
    1414//
    1515
     
    2323#include "utility.h"
    2424
    25 #include <iostream>
    26 
    2725namespace ControlStruct {
    28         LabelFixer::Entry::Entry( Statement *to, BranchStmt *from ) : definition ( to ) {
     26        LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) {
    2927                if ( from != 0 )
    3028                        usage.push_back( from );
     
    3331        bool LabelFixer::Entry::insideLoop() {
    3432                return ( dynamic_cast< ForStmt * > ( definition ) ||
    35                         dynamic_cast< WhileStmt * > ( definition )  );
     33                                 dynamic_cast< WhileStmt * > ( definition )  );
    3634        }
    3735
     
    4846        }
    4947
    50         // prune to at most one label definition for each statement
    5148        void LabelFixer::visit( Statement *stmt ) {
    5249                std::list< Label > &labels = stmt->get_labels();
    5350
    5451                if ( ! labels.empty() ) {
    55                         // only remember one label for each statement
    5652                        Label current = setLabelsDef( labels, stmt );
    5753                        labels.clear();
     
    6157
    6258        void LabelFixer::visit( BranchStmt *branchStmt ) {
    63                 visit ( ( Statement * )branchStmt );
     59                visit ( ( Statement * )branchStmt );  // the labels this statement might have
    6460
    65                 // for labeled branches, add an entry to the label table
    66                 Label target = branchStmt->get_target();
    67                 if ( target != "" ) {
     61                Label target;
     62                if ( (target = branchStmt->get_target()) != "" ) {
    6863                        setLabelsUsg( target, branchStmt );
    69                 }
     64                } //else       /* computed goto or normal exit-loop statements */
    7065        }
    7166
    72         // sets the definition of the labelTable entry to be the provided
    73         // statement for every label in the list parameter. Happens for every kind of statement
    7467        Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
    7568                assert( definition != 0 );
    76                 assert( llabel.size() > 0 );
     69                Entry *entry = new Entry( definition );
     70                bool used = false;
    7771
    78                 Entry * e = new Entry( definition );
     72                for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ )
     73                        if ( labelTable.find( *i ) == labelTable.end() )
     74                                { used = true; labelTable[ *i ] = entry; } // undefined and unused
     75                        else
     76                                if ( labelTable[ *i ]->defined() )
     77                                        throw SemanticError( "Duplicate definition of label: " + *i );
     78                                else
     79                                        labelTable[ *i ]->set_definition( definition );
    7980
    80                 for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) {
    81                         if ( labelTable.find( *i ) == labelTable.end() ) {
    82                                 // all labels on this statement need to use the same entry, so this should only be created once
    83                                 // undefined and unused until now, add an entry
    84                                 labelTable[ *i ] =  e;
    85                         } else if ( labelTable[ *i ]->defined() ) {
    86                                 // defined twice, error
    87                                 throw SemanticError( "Duplicate definition of label: " + *i );
    88                         }       else {
    89                                 // used previously, but undefined until now -> link with this entry
    90                                 Entry * oldEntry = labelTable[ *i ];
    91                                 e->add_uses( oldEntry->get_uses() );
    92                                 labelTable[ *i ] = e;
    93                         } // if
    94                 } // for
     81                if ( ! used ) delete entry;
    9582
    96                 // produce one of the labels attached to this statement to be
    97                 // temporarily used as the canonical label
    98                 return labelTable[ llabel.front() ]->get_label();
     83                return labelTable[ llabel.front() ]->get_label();  // this *must* exist
    9984        }
    10085
    101         // Remember all uses of a label.
    102         void LabelFixer::setLabelsUsg( Label orgValue, BranchStmt *use ) {
     86        Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
    10387                assert( use != 0 );
    10488
    105                 if ( labelTable.find( orgValue ) != labelTable.end() ) {
    106                         // the label has been defined or used before
    107                         labelTable[ orgValue ]->add_use( use );
    108                 } else {
     89                if ( labelTable.find( orgValue ) != labelTable.end() )
     90                        labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
     91                else
    10992                        labelTable[ orgValue ] = new Entry( 0, use );
    110                 }
     93
     94                return labelTable[ orgValue ]->get_label();
    11195        }
    11296
    113         // Ultimately builds a table that maps a label to its defining statement.
    114         // In the process,
    11597        std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
    11698                std::map< Statement *, Entry * > def_us;
    11799
    118                 // combine the entries for all labels that target the same location
    119                 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
     100                for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
    120101                        Entry *e = i->second;
    121102
    122103                        if ( def_us.find ( e->get_definition() ) == def_us.end() ) {
    123104                                def_us[ e->get_definition() ] = e;                             
    124                         } else if ( e->used() ) {
    125                                 def_us[ e->get_definition() ]->add_uses( e->get_uses() );
     105                        } else {
     106                                if ( e->used() )
     107                                        def_us[ e->get_definition() ]->add_uses( e->get_uses() );
    126108                        }
    127109                }
    128110
    129                 // create a unique label for each target location.
    130                 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
     111                // get rid of labelTable
     112                for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
    131113                        Statement *to = (*i).first;
    132                         Entry * entry = (*i).second;
    133                         std::list< BranchStmt *> &from = entry->get_uses();
     114                        std::list< Statement *> &from = (*i).second->get_uses();
     115                        Label finalLabel = generator->newLabel();
     116                        (*i).second->set_label( finalLabel );
    134117
    135                         // no label definition found
    136118                        if ( to == 0 ) {
    137                                 Label undef = from.back()->get_target();
     119                                BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back());
     120                                Label undef("");
     121                                if ( first_use != 0 )
     122                                        undef = first_use->get_target();
    138123                                throw SemanticError ( "'" + undef + "' label not defined");
    139124                        }
    140 
    141                         // generate a new label, and attach it to its defining statement
    142                         // as the only label on that statement
    143                         Label finalLabel = generator->newLabel();
    144                         entry->set_label( finalLabel );
    145125
    146126                        to->get_labels().clear();
    147127                        to->get_labels().push_back( finalLabel );
    148128
    149                         // redirect each of the source branch statements to the new target label
    150                         for ( std::list< BranchStmt *>::iterator j = from.begin(); j != from.end(); ++j ) {
    151                                 BranchStmt *jump = *j;
    152                                 assert( jump != 0 );
    153                                 jump->set_target( finalLabel );
     129                        for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) {
     130                                BranchStmt *jumpTo = dynamic_cast< BranchStmt * > ( *j );
     131                                assert( jumpTo != 0 );
     132                                jumpTo->set_target( finalLabel );
    154133                        } // for
    155134                } // for
    156135
    157                 // create a table where each label maps to its defining statement
     136                // reverse table
    158137                std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
    159                 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
     138                for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ )
    160139                        (*ret)[ (*i).second->get_label() ] = (*i).first;
    161                 }
    162140
    163141                return ret;
  • src/ControlStruct/LabelFixer.h

    r9a8930f ra61fea9a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri May 29 15:25:55 2015
    13 // Update Count     : 11
     12// Last Modified On : Tue May 26 12:55:10 2015
     13// Update Count     : 4
    1414//
    1515
     
    5555
    5656                Label setLabelsDef( std::list< Label > &, Statement *definition );
    57                 void setLabelsUsg( Label, BranchStmt *usage = 0 );
     57                Label setLabelsUsg( Label, Statement *usage = 0 );
    5858
    5959          private:
    6060                class Entry {
    6161                  public:
    62                         Entry( Statement *to = 0, BranchStmt *from = 0 );
     62                        Entry( Statement *to = 0, Statement *from = 0 );
    6363                        bool used() { return ( usage.empty() ); }
    6464                        bool defined() { return ( definition != 0 ); }
     
    7171                        void set_definition( Statement *def ) { definition = def; }
    7272
    73                         std::list< BranchStmt *> &get_uses() { return usage; }
    74                         void add_use ( BranchStmt *use ) { usage.push_back( use ); }
    75                         void add_uses ( std::list<BranchStmt *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }
     73                        std::list< Statement *> &get_uses() { return usage; }
     74                        void add_use ( Statement *use ) { usage.push_back( use ); }
     75                        void add_uses ( std::list<Statement *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }
    7676                  private:
    7777                        Label label; 
    7878                        Statement *definition;
    79                         std::list<BranchStmt *> usage;
     79                        std::list<Statement *> usage;
    8080                };
    8181                 
  • src/ControlStruct/LabelGenerator.cc

    r9a8930f ra61fea9a  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Jun 03 14:23:26 2015
    13 // Update Count     : 9
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 15:32:04 2015
     13// Update Count     : 2
    1414//
    1515
     
    2929        }
    3030
    31         Label LabelGenerator::newLabel(std::string suffix) {
     31        Label LabelGenerator::newLabel() {
    3232                std::ostrstream os;
    33                 os << "__L" << current++ << "__" << suffix;
     33                os << "__L" << current++ << "__";// << std::ends;
    3434                os.freeze( false );
    3535                std::string ret = std::string (os.str(), os.pcount());
  • src/ControlStruct/LabelGenerator.h

    r9a8930f ra61fea9a  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Jun 03 14:16:26 2015
    13 // Update Count     : 5
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 15:33:20 2015
     13// Update Count     : 3
    1414//
    1515
     
    1818
    1919#include "SynTree/SynTree.h"
    20 #include <string>
    2120
    2221namespace ControlStruct {
     
    2423          public:
    2524                static LabelGenerator *getGenerator();
    26                 Label newLabel(std::string suffix = "");
     25                Label newLabel();
    2726                void reset() { current = 0; }
    2827                void rewind() { current--; }
  • src/ControlStruct/MLEMutator.cc

    r9a8930f ra61fea9a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Jun 03 15:09:27 2015
    13 // Update Count     : 170
     12// Last Modified On : Wed May 27 16:19:32 2015
     13// Update Count     : 44
    1414//
    1515
     
    1919#include "MLEMutator.h"
    2020#include "SynTree/Statement.h"
    21 #include "SynTree/Expression.h"
    2221
    2322namespace ControlStruct {
     
    2726        }
    2827
    29         // break labels have to come after the statement they break out of,
    30         // so mutate a statement, then if they inform us through the breakLabel field
    31         // tha they need a place to jump to on a break statement, add the break label
    32         // to the body of statements
    33         void MLEMutator::fixBlock( std::list< Statement * > &kids ) {
     28        CompoundStmt* MLEMutator::mutate( CompoundStmt *cmpndStmt ) {
     29                bool labeledBlock = false;
     30                if ( !(cmpndStmt->get_labels().empty()) ) {
     31                        labeledBlock = true;
     32                        enclosingBlocks.push_back( Entry( cmpndStmt ) );
     33                } // if
     34
     35                std::list< Statement * > &kids = cmpndStmt->get_kids();
    3436                for ( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) {
    3537                        *k = (*k)->acceptMutator(*this);
    3638
    3739                        if ( ! get_breakLabel().empty() ) {
    38                                 std::list< Statement * >::iterator next = k+1;
     40                                std::list< Statement * >::iterator next = k; next++;
    3941                                if ( next == kids.end() ) {
    4042                                        std::list<Label> ls; ls.push_back( get_breakLabel() );
     
    4749                        } // if
    4850                } // for
    49         }
    50 
    51         CompoundStmt* MLEMutator::mutate( CompoundStmt *cmpndStmt ) {
    52                 bool labeledBlock = !(cmpndStmt->get_labels().empty());
    53                 if ( labeledBlock ) {
    54                         Label brkLabel = generator->newLabel();
    55                         enclosingBlocks.push_back( Entry( cmpndStmt, brkLabel ) );
    56                 } // if
    57 
    58                 // a child statement may set the break label
    59                 // - if they do, attach it to the next statement
    60                 std::list< Statement * > &kids = cmpndStmt->get_kids();
    61                 fixBlock( kids );
    6251
    6352                if ( labeledBlock ) {
    6453                        assert( ! enclosingBlocks.empty() );
    65                         if ( ! enclosingBlocks.back().useBreakExit().empty() ) {
    66                                 set_breakLabel( enclosingBlocks.back().useBreakExit() );
     54                        if ( ! enclosingBlocks.back().get_breakExit().empty() ) {
     55                                set_breakLabel( enclosingBlocks.back().get_breakExit() );
    6756                        }
    6857                        enclosingBlocks.pop_back();
    6958                } // if
    7059
     60                //mutateAll( cmpndStmt->get_kids(), *this );
    7161                return cmpndStmt;
    7262        }
    7363
    74         template< typename LoopClass >
    75         Statement *MLEMutator::handleLoopStmt( LoopClass *loopStmt ) {
    76                 // remember this as the most recent enclosing loop, then mutate
    77                 // the body of the loop -- this will do SOMETHING with branch statements
    78                 // and will recursively do the same to nested loops
    79                 Label brkLabel = generator->newLabel("loopBreak");
    80                 Label contLabel = generator->newLabel("loopContinue");
    81                 enclosingLoops.push_back( Entry( loopStmt, brkLabel, contLabel ) );
    82                 loopStmt->set_body ( loopStmt->get_body()->acceptMutator( *this ) );
    83 
    84                 // sanity check that the enclosing loops have been popped correctly
     64        Statement *MLEMutator::mutate( WhileStmt *whileStmt ) {
     65                enclosingLoops.push_back( Entry( whileStmt ) );
     66                whileStmt->set_body ( whileStmt->get_body()->acceptMutator( *this ) );
     67
    8568                Entry &e = enclosingLoops.back();
    86                 assert ( e == loopStmt );
    87 
    88                 // generate labels as needed
    89                 loopStmt->set_body( mutateLoop( loopStmt->get_body(), e ) );
     69                assert ( e == whileStmt );
     70                whileStmt->set_body( mutateLoop( whileStmt->get_body(), e ) );
    9071                enclosingLoops.pop_back();
    9172
    92                 return loopStmt;
    93         }
    94 
    95         Statement *MLEMutator::mutate( CaseStmt *caseStmt ) {
    96                 caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) );
    97                 fixBlock( caseStmt->get_statements() );
    98 
    99                 return caseStmt;
    100         }
    101 
    102         template< typename SwitchClass >
    103         Statement *MLEMutator::handleSwitchStmt( SwitchClass *switchStmt ) {
    104                 // generate a label for breaking out of a labeled switch
    105                 Label brkLabel = generator->newLabel("switchBreak");
    106                 enclosingSwitches.push_back( Entry(switchStmt, brkLabel) );
    107                 mutateAll( switchStmt->get_branches(), *this );
    108 
    109                 Entry &e = enclosingSwitches.back();
    110                 assert ( e == switchStmt );
    111 
    112                 // only generate break label if labeled break is used
    113                 if (e.isBreakUsed()) {
    114                         // for the purposes of keeping switch statements uniform (i.e. all statements that are
    115                         // direct children of a switch should be CastStmts), append the exit label + break to the
    116                         // last case statement; create a default case if there are no cases
    117                         std::list< Statement * > &branches = switchStmt->get_branches();
    118                         if ( branches.empty() ) {
    119                                 branches.push_back( CaseStmt::makeDefault() );
    120                         }
    121 
    122                         if ( CaseStmt * c = dynamic_cast< CaseStmt * >( branches.back() ) ) {
    123                                 std::list<Label> temp; temp.push_back( brkLabel );
    124                                 c->get_statements().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
    125                         } else assert(0); // as of this point, all branches of a switch are still CaseStmts
    126                 }
    127 
    128                 assert ( enclosingSwitches.back() == switchStmt );
    129                 enclosingSwitches.pop_back();
    130                 return switchStmt;
     73                return whileStmt;
     74        }
     75
     76        Statement *MLEMutator::mutate( ForStmt *forStmt ) {
     77                enclosingLoops.push_back( Entry( forStmt ) );
     78                maybeMutate( forStmt->get_body(), *this );
     79
     80                Entry &e = enclosingLoops.back();
     81                assert ( e == forStmt );
     82                forStmt->set_body( mutateLoop( forStmt->get_body(), e ) );
     83                enclosingLoops.pop_back();
     84
     85                return forStmt;
    13186        }
    13287
     
    162117                                        throw SemanticError("The target specified in the exit loop statement does not correspond to an enclosing control structure: " + originalTarget );
    163118
    164                 // what about exiting innermost block or switch???
    165119                if ( enclosingLoops.back() == (*check) )
    166120                        return branchStmt;                              // exit the innermost loop (labels unnecessary)
    167121
    168                 // branch error checks, get the appropriate label name and create a goto
    169                 Label exitLabel;
     122                Label newLabel;
    170123                switch ( branchStmt->get_type() ) {
    171124                  case BranchStmt::Break:
    172                                 assert( check->useBreakExit() != "");
    173                                 exitLabel = check->useBreakExit();
     125                                if ( check->get_breakExit() != "" ) {
     126                                        newLabel = check->get_breakExit();
     127                                } else {
     128                                        newLabel = generator->newLabel();
     129                                        check->set_breakExit( newLabel );
     130                                } // if
    174131                                break;
    175132                  case BranchStmt::Continue:
    176                                 assert( check->useContExit() != "");
    177                                 exitLabel = check->useContExit();
     133                                if ( check->get_contExit() != "" ) {
     134                                        newLabel = check->get_contExit();
     135                                } else {
     136                                        newLabel = generator->newLabel();
     137                                        check->set_contExit( newLabel );
     138                                } // if
    178139                                break;
    179140                  default:
    180                                 assert(0);                                      // shouldn't be here
     141                                return 0;                                       // shouldn't be here
    181142                } // switch
    182143
    183                 return new BranchStmt( std::list<Label>(), exitLabel, BranchStmt::Goto );
     144                return new BranchStmt( std::list<Label>(), newLabel, BranchStmt::Goto );
     145        }
     146
     147        template< typename SwitchClass >
     148        Statement *handleSwitchStmt( SwitchClass *switchStmt, MLEMutator &mutator ) {
     149                // set up some aliases so that the rest of the code isn't messy
     150                typedef MLEMutator::Entry Entry;
     151                LabelGenerator *generator = mutator.generator;
     152                std::list< Entry > &enclosingSwitches = mutator.enclosingSwitches;
     153
     154                Label brkLabel = generator->newLabel();
     155                enclosingSwitches.push_back( Entry(switchStmt, "", brkLabel) );
     156                mutateAll( switchStmt->get_branches(), mutator ); {
     157                        // check if this is necessary (if there is a break to this point, otherwise do not generate
     158                        std::list<Label> temp; temp.push_back( brkLabel );
     159                        switchStmt->get_branches().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
     160                }
     161                assert ( enclosingSwitches.back() == switchStmt );
     162                enclosingSwitches.pop_back();
     163                return switchStmt;
     164        }
     165
     166        Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) {
     167                return handleSwitchStmt( switchStmt, *this );
     168        }
     169
     170        Statement *MLEMutator::mutate( ChooseStmt *switchStmt ) {
     171                return handleSwitchStmt( switchStmt, *this );           
    184172        }
    185173
    186174        Statement *MLEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) {
    187                 // ensure loop body is a block
    188175                CompoundStmt *newBody;
    189176                if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) {
     
    192179                } // if
    193180
    194                 // only generate these when needed
    195 
    196                 if ( e.isContUsed() ) {
    197                         // continue label goes in the body as the last statement
    198                         std::list< Label > labels; labels.push_back( e.useContExit() );
    199                         newBody->get_kids().push_back( new NullStmt( labels ) );                       
    200                 }
    201 
    202                 if ( e.isBreakUsed() ) {
    203                         // break label goes after the loop -- it'll get set by the
    204                         // outer mutator if we do this
    205                         set_breakLabel( e.useBreakExit() );                     
    206                 }
     181                Label endLabel = e.get_contExit();
     182
     183                if ( e.get_breakExit() != "" ) {
     184                        if ( endLabel == "" ) endLabel = generator->newLabel();
     185                        // check for whether this label is used or not, so as to not generate extraneous gotos
     186                        if (e.breakExitUsed)
     187                                newBody->get_kids().push_back( new BranchStmt( std::list< Label >(), endLabel, BranchStmt::Goto ) );
     188                        // xxx
     189                        //std::list< Label > ls; ls.push_back( e.get_breakExit() );
     190                        set_breakLabel( e.get_breakExit() );
     191                        //newBody->get_kids().push_back( new BranchStmt( ls, "", BranchStmt::Break ) );
     192                } // if
     193
     194                if ( e.get_breakExit() != "" || e.get_contExit() != "" ) {
     195                        if (dynamic_cast< NullStmt *>( newBody->get_kids().back() ))
     196                                newBody->get_kids().back()->get_labels().push_back( endLabel );
     197                        else {
     198                                std::list < Label > ls; ls.push_back( endLabel );
     199                                newBody->get_kids().push_back( new NullStmt( ls ) );
     200                        } // if
     201                } // if
    207202
    208203                return newBody;
    209204        }
    210205
    211         Statement *MLEMutator::mutate( WhileStmt *whileStmt ) {
    212                 return handleLoopStmt( whileStmt );
    213         }
    214 
    215         Statement *MLEMutator::mutate( ForStmt *forStmt ) {
    216                 return handleLoopStmt( forStmt );
    217         }
    218 
    219         Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) {
    220                 return handleSwitchStmt( switchStmt );
    221         }
    222 
    223         Statement *MLEMutator::mutate( ChooseStmt *switchStmt ) {
    224                 return handleSwitchStmt( switchStmt );         
    225         }
    226 
     206        //*** Entry's methods
     207        void MLEMutator::Entry::set_contExit( Label l ) {
     208                assert ( contExit == "" || contExit == l );
     209                contExit = l;
     210        }
     211
     212        void MLEMutator::Entry::set_breakExit( Label l ) {
     213                assert ( breakExit == "" || breakExit == l );
     214                breakExit = l;
     215        }
    227216} // namespace ControlStruct
    228217
  • src/ControlStruct/MLEMutator.h

    r9a8930f ra61fea9a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Jun 03 15:06:36 2015
    13 // Update Count     : 25
     12// Last Modified On : Tue May 26 15:04:21 2015
     13// Update Count     : 7
    1414//
    1515
     
    3838                Statement *mutate( BranchStmt *branchStmt ) throw ( SemanticError );
    3939
    40                 Statement *mutate( CaseStmt *caseStmt );
    4140                Statement *mutate( SwitchStmt *switchStmt );
    4241                Statement *mutate( ChooseStmt *switchStmt );
     
    4948                class Entry {
    5049                  public:
    51                         explicit Entry( Statement *_loop, Label _breakExit, Label _contExit = Label("") ) :
    52                                 loop( _loop ), breakExit( _breakExit ), contExit( _contExit ), breakUsed(false), contUsed(false) {}
     50                        explicit Entry( Statement *_loop = 0, Label _contExit = Label(""), Label _breakExit = Label("") ) :
     51                                loop( _loop ), contExit( _contExit ), breakExit( _breakExit ), contExitUsed( false ), breakExitUsed( false ) {}
    5352
    5453                        bool operator==( const Statement *stmt ) { return ( loop == stmt ); }
     
    5958                        Statement *get_loop() const { return loop; }
    6059
    61                         Label useContExit() { contUsed = true; return contExit; }
    62                         Label useBreakExit() { breakUsed = true; return breakExit; }
     60                        Label get_contExit() const { return contExit; }
     61                        void set_contExit( Label );
    6362
    64                         bool isContUsed() const { return contUsed; }
    65                         bool isBreakUsed() const { return breakUsed; }
     63                        Label get_breakExit() const { return breakExit; }
     64                        void set_breakExit( Label );
    6665
    6766                  private:
    6867                        Statement *loop;
    69                         Label breakExit, contExit;
    70                         bool breakUsed, contUsed;
     68                        Label contExit, breakExit;
     69                  public: // hack, provide proper [sg]etters
     70                        bool contExitUsed, breakExitUsed;
    7171                };
    7272
     
    7676                LabelGenerator *generator;
    7777
    78                 template< typename LoopClass >
    79                 Statement *handleLoopStmt( LoopClass *loopStmt );
    80 
    8178                template< typename SwitchClass >
    82                 Statement *handleSwitchStmt( SwitchClass *switchStmt );
    83 
    84                 void fixBlock( std::list< Statement * > &kids );
     79                friend Statement *handleSwitchStmt( SwitchClass *switchStmt, MLEMutator &mutator );
    8580        };
    8681} // namespace ControlStruct
  • src/ControlStruct/Mutate.cc

    r9a8930f ra61fea9a  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Jun 03 23:08:43 2015
    13 // Update Count     : 5
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 15:32:52 2015
     13// Update Count     : 2
    1414//
    1515
     
    3737        void mutate( std::list< Declaration * > translationUnit ) {
    3838                // ForExprMutator formut;
    39 
    40                 // normalizes label definitions and generates multi-level
    41                 // exit labels
    4239                LabelFixer lfix;
    43 
    44                 // transform choose statements into switch statements
    4540                ChooseMutator chmut;
    46 
    47                 // expand case ranges and turn fallthru into a null statement
    4841                CaseRangeMutator ranges;  // has to run after ChooseMutator
    49 
    5042                //ExceptMutator exc;
    5143                // LabelTypeChecker lbl;
  • src/SynTree/Mutator.h

    r9a8930f ra61fea9a  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri May 29 16:34:08 2015
    13 // Update Count     : 4
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon May 18 10:12:28 2015
     13// Update Count     : 3
    1414//
    1515#include <cassert>
     
    104104                assert( newnode );
    105105                return newnode;
     106///         return tree->acceptMutator( mutator );
    106107        } else {
    107108                return 0;
  • src/SynTree/ObjectDecl.cc

    r9a8930f ra61fea9a  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Thu May 28 14:10:02 2015
    13 // Update Count     : 8
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon May 18 10:14:18 2015
     13// Update Count     : 2
    1414//
    1515
     
    6565
    6666void ObjectDecl::printShort( std::ostream &os, int indent ) const {
    67 #if 0
    68         if ( get_mangleName() != "") {
    69                 os << get_mangleName() << ": a ";
    70         } else
    71 #endif
    7267        if ( get_name() != "" ) {
    7368                os << get_name() << ": a ";
  • src/SynTree/Statement.cc

    r9a8930f ra61fea9a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Jun 02 13:07:09 2015
    13 // Update Count     : 14
     12// Last Modified On : Wed May 27 15:41:13 2015
     13// Update Count     : 8
    1414//
    1515
     
    124124CaseStmt::~CaseStmt() {
    125125        delete condition;
    126 }
    127 
    128 CaseStmt * CaseStmt::makeDefault( std::list<Label> labels, std::list<Statement *> branches ) {
    129         return new CaseStmt( labels, 0, branches, true );
    130126}
    131127
  • src/SynTree/Statement.h

    r9a8930f ra61fea9a  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  4 14:03:31 2015
    13 // Update Count     : 14
     12// Last Modified On : Wed Jun  3 11:55:15 2015
     13// Update Count     : 6
    1414//
    1515
     
    149149              std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
    150150        virtual ~CaseStmt();
    151 
    152         static CaseStmt * makeDefault( std::list<Label> labels = std::list<Label>(),
    153                 std::list<Statement *> stmts = std::list<Statement *>() );
    154151
    155152        bool isDefault() { return _isDefault; }
  • src/examples/control_structures.c

    r9a8930f ra61fea9a  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  4 14:02:50 2015
    13 // Update Count     : 24
     12// Last Modified On : Thu Jun  4 11:21:12 2015
     13// Update Count     : 23
    1414//
    1515
Note: See TracChangeset for help on using the changeset viewer.