Changeset 9a8930f


Ignore:
Timestamp:
Jun 4, 2015, 2:07:40 PM (9 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:
0423f25, eb3261f
Parents:
a61fea9a (diff), 1136d96 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

enable AM_MAINTAINER_MODE, add operator ?{}, formatting

Location:
src
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    ra61fea9a r9a8930f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CodeGenerator2.cc --
     7// CodeGenerator.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 : Wed Jun  3 11:53:32 2015
    13 // Update Count     : 13
     12// Last Modified On : Thu Jun  4 14:05:45 2015
     13// Update Count     : 120
    1414//
    1515
     
    3535
    3636namespace CodeGen {
    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 );
     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 );
    4955        }
    5056
     
    5864 
    5965        //*** Declarations
    60         void CodeGenerator2::visit( FunctionDecl *functionDecl ) {
     66        void CodeGenerator::visit( FunctionDecl *functionDecl ) {
    6167                handleStorageClass( functionDecl );
    6268                if ( functionDecl->get_isInline() ) {
    63                         before << "inline ";
    64                 } // if
    65                 before << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );
     69                        output << "inline ";
     70                } // if
     71                output << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );
    6672
    6773                // how to get this to the Functype?
    6874                std::list< Declaration * > olds = functionDecl->get_oldDecls();
    6975                if ( ! olds.empty() ) {
    70                         before << " /* function has old declaration */";
     76                        output << " /* function has old declaration */";
    7177                } // if
    7278
     
    7783        }
    7884
    79         void CodeGenerator2::visit( ObjectDecl *objectDecl ) {
     85        void CodeGenerator::visit( ObjectDecl *objectDecl ) {
    8086                handleStorageClass( objectDecl );
    81                 before << genType( objectDecl->get_type(), mangleName( objectDecl ) );
     87                output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
    8288       
    8389                if ( objectDecl->get_init() ) {
    84                         before << " = ";
     90                        output << " = ";
    8591                        objectDecl->get_init()->accept( *this );
    8692                } // if
    8793                if ( objectDecl->get_bitfieldWidth() ) {
    88                         before << ":";
     94                        output << ":";
    8995                        objectDecl->get_bitfieldWidth()->accept( *this );
    9096                } // if
    9197        }
    9298
    93         void CodeGenerator2::handleAggregate( AggregateDecl *aggDecl ) {
     99        void CodeGenerator::handleAggregate( AggregateDecl *aggDecl ) {
    94100                if ( aggDecl->get_name() != "" )
    95                         before << aggDecl->get_name();
     101                        output << aggDecl->get_name();
    96102       
    97103                std::list< Declaration * > &memb = aggDecl->get_members();
    98104
    99105                if ( ! memb.empty() ) {
    100                         before << endl << string( cur_indent, ' ' ) << "{" << endl;
    101 
    102                         cur_indent += CodeGenerator2::tabsize;
     106                        output << endl << string( cur_indent, ' ' ) << "{" << endl;
     107
     108                        cur_indent += CodeGenerator::tabsize;
    103109                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    104                                 before << string( cur_indent, ' ' );
     110                                output << string( cur_indent, ' ' );
    105111                                (*i)->accept(*this );
    106                                 before << ";" << endl;
     112                                output << ";" << endl;
    107113                        }
    108114
    109                         cur_indent -= CodeGenerator2::tabsize;
    110 
    111                         before << string( cur_indent, ' ' ) << "}";
    112                 } // if
    113         }
    114 
    115         void CodeGenerator2::visit( StructDecl *structDecl ) {
    116                 before << "struct ";
     115                        cur_indent -= CodeGenerator::tabsize;
     116
     117                        output << string( cur_indent, ' ' ) << "}";
     118                } // if
     119        }
     120
     121        void CodeGenerator::visit( StructDecl *structDecl ) {
     122                output << "struct ";
    117123                handleAggregate( structDecl );
    118124        }
    119125
    120         void CodeGenerator2::visit( UnionDecl *aggregateDecl ) {
    121                 before << "union ";
     126        void CodeGenerator::visit( UnionDecl *aggregateDecl ) {
     127                output << "union ";
    122128                handleAggregate( aggregateDecl );
    123129        }
    124130 
    125         void CodeGenerator2::visit( EnumDecl *aggDecl ) {
    126                 before << "enum ";
     131        void CodeGenerator::visit( EnumDecl *aggDecl ) {
     132                output << "enum ";
    127133
    128134                if ( aggDecl->get_name() != "" )
    129                         before << aggDecl->get_name();
     135                        output << aggDecl->get_name();
    130136       
    131137                std::list< Declaration* > &memb = aggDecl->get_members();
    132138
    133139                if ( ! memb.empty() ) {
    134                         before << endl << "{" << endl;
    135 
    136                         cur_indent += CodeGenerator2::tabsize;
     140                        output << endl << "{" << endl;
     141
     142                        cur_indent += CodeGenerator::tabsize;
    137143                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    138144                                ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
    139145                                assert( obj );
    140                                 before << string( cur_indent, ' ' ) << mangleName( obj );
     146                                output << string( cur_indent, ' ' ) << mangleName( obj );
    141147                                if ( obj->get_init() ) {
    142                                         before << " = ";
     148                                        output << " = ";
    143149                                        obj->get_init()->accept(*this );
    144150                                } // if
    145                                 before << "," << endl;
     151                                output << "," << endl;
    146152                        } // for
    147153
    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 ) {
     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 ) {
    162168                // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
    163169                // still to be done
    164                 before << "extern unsigned long " << typeDecl->get_name();
     170                output << "extern unsigned long " << typeDecl->get_name();
    165171                if ( typeDecl->get_base() ) {
    166                         before << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";
    167                 } // if
    168         }
    169 
    170         void CodeGenerator2::visit( SingleInit *init ) {
     172                        output << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";
     173                } // if
     174        }
     175
     176        void CodeGenerator::visit( SingleInit *init ) {
    171177                init->get_value()->accept( *this );
    172178        }
    173179
    174         void CodeGenerator2::visit( ListInit *init ) {
    175                 before << "{ ";
     180        void CodeGenerator::visit( ListInit *init ) {
     181                output << "{ ";
    176182                genCommaList( init->begin_initializers(), init->end_initializers() );
    177                 before << " }";
    178         }
    179 
    180         void CodeGenerator2::visit( Constant *constant ) {
    181                 before << constant->get_value() ;
     183                output << " }";
     184        }
     185
     186        void CodeGenerator::visit( Constant *constant ) {
     187                output << constant->get_value() ;
    182188        }
    183189
    184190        //*** Expressions
    185         void CodeGenerator2::visit( ApplicationExpr *applicationExpr ) {
     191        void CodeGenerator::visit( ApplicationExpr *applicationExpr ) {
    186192                if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
    187193                        OperatorInfo opInfo;
     
    214220                                        assert( applicationExpr->get_args().size() == 2 );
    215221                                        (*arg++)->accept( *this );
    216                                         before << "[";
    217                                         (*arg)->accept( *this );
    218                                         before << "]";
     222                                        output << "[";
     223                                        (*arg)->accept( *this );
     224                                        output << "]";
    219225                                        break;
    220226             
     
    227233                                  case OT_PREFIXASSIGN:
    228234                                        assert( applicationExpr->get_args().size() == 1 );
    229                                         before << "(";
    230                                         before << opInfo.symbol;
    231                                         (*arg)->accept( *this );
    232                                         before << ")";
     235                                        output << "(";
     236                                        output << opInfo.symbol;
     237                                        (*arg)->accept( *this );
     238                                        output << ")";
    233239                                        break;
    234240             
     
    237243                                        assert( applicationExpr->get_args().size() == 1 );
    238244                                        (*arg)->accept( *this );
    239                                         before << opInfo.symbol;
     245                                        output << opInfo.symbol;
    240246                                        break;
    241247
     
    243249                                  case OT_INFIXASSIGN:
    244250                                        assert( applicationExpr->get_args().size() == 2 );
    245                                         before << "(";
     251                                        output << "(";
    246252                                        (*arg++)->accept( *this );
    247                                         before << opInfo.symbol;
    248                                         (*arg)->accept( *this );
    249                                         before << ")";
     253                                        output << opInfo.symbol;
     254                                        (*arg)->accept( *this );
     255                                        output << ")";
    250256                                        break;
    251257             
     
    256262                        } else {
    257263                                varExpr->accept( *this );
    258                                 before << "(";
     264                                output << "(";
    259265                                genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
    260                                 before << ")";
     266                                output << ")";
    261267                        } // if
    262268                } else {
    263269                        applicationExpr->get_function()->accept( *this );
    264                         before << "(";
     270                        output << "(";
    265271                        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
    266                         before << ")";
    267                 } // if
    268         }
    269  
    270         void CodeGenerator2::visit( UntypedExpr *untypedExpr ) {
     272                        output << ")";
     273                } // if
     274        }
     275 
     276        void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
    271277                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
    272278                        OperatorInfo opInfo;
     
    277283                                        assert( untypedExpr->get_args().size() == 2 );
    278284                                        (*arg++)->accept( *this );
    279                                         before << "[";
    280                                         (*arg)->accept( *this );
    281                                         before << "]";
     285                                        output << "[";
     286                                        (*arg)->accept( *this );
     287                                        output << "]";
    282288                                        break;
    283289             
     
    289295                                  case OT_PREFIXASSIGN:
    290296                                        assert( untypedExpr->get_args().size() == 1 );
    291                                         before << "(";
    292                                         before << opInfo.symbol;
    293                                         (*arg)->accept( *this );
    294                                         before << ")";
     297                                        output << "(";
     298                                        output << opInfo.symbol;
     299                                        (*arg)->accept( *this );
     300                                        output << ")";
    295301                                        break;
    296302             
     
    299305                                        assert( untypedExpr->get_args().size() == 1 );
    300306                                        (*arg)->accept( *this );
    301                                         before << opInfo.symbol;
     307                                        output << opInfo.symbol;
    302308                                        break;
    303309 
     
    305311                                  case OT_INFIXASSIGN:
    306312                                        assert( untypedExpr->get_args().size() == 2 );
    307                                         before << "(";
     313                                        output << "(";
    308314                                        (*arg++)->accept( *this );
    309                                         before << opInfo.symbol;
    310                                         (*arg)->accept( *this );
    311                                         before << ")";
     315                                        output << opInfo.symbol;
     316                                        (*arg)->accept( *this );
     317                                        output << ")";
    312318                                        break;
    313319             
     
    318324                        } else {
    319325                                nameExpr->accept( *this );
    320                                 before << "(";
     326                                output << "(";
    321327                                genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
    322                                 before << ")";
     328                                output << ")";
    323329                        } // if
    324330                } else {
    325331                        untypedExpr->get_function()->accept( *this );
    326                         before << "(";
     332                        output << "(";
    327333                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
    328                         before << ")";
    329                 } // if
    330         }
    331  
    332         void CodeGenerator2::visit( NameExpr *nameExpr ) {
     334                        output << ")";
     335                } // if
     336        }
     337 
     338        void CodeGenerator::visit( NameExpr *nameExpr ) {
    333339                OperatorInfo opInfo;
    334340                if ( operatorLookup( nameExpr->get_name(), opInfo ) ) {
    335341                        assert( opInfo.type == OT_CONSTANT );
    336                         before << opInfo.symbol;
    337                 } else {
    338                         before << nameExpr->get_name();
    339                 } // if
    340         }
    341  
    342         void CodeGenerator2::visit( AddressExpr *addressExpr ) {
    343                 before << "(&";
     342                        output << opInfo.symbol;
     343                } else {
     344                        output << nameExpr->get_name();
     345                } // if
     346        }
     347 
     348        void CodeGenerator::visit( AddressExpr *addressExpr ) {
     349                output << "(&";
    344350                // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
    345351                if ( VariableExpr *variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {
    346                         before << mangleName( variableExpr->get_var() );
     352                        output << mangleName( variableExpr->get_var() );
    347353                } else {
    348354                        addressExpr->get_arg()->accept( *this );
    349355                } // if
    350                 before << ")";
    351         }
    352 
    353         void CodeGenerator2::visit( CastExpr *castExpr ) {
    354                 before << "((";
     356                output << ")";
     357        }
     358
     359        void CodeGenerator::visit( CastExpr *castExpr ) {
     360                output << "((";
    355361                if ( castExpr->get_results().empty() ) {
    356                         before << "void" ;
    357                 } else {
    358                         before << genType( castExpr->get_results().front(), "" );
    359                 } // if
    360                 before << ")";
     362                        output << "void" ;
     363                } else {
     364                        output << genType( castExpr->get_results().front(), "" );
     365                } // if
     366                output << ")";
    361367                castExpr->get_arg()->accept( *this );
    362                 before << ")";
    363         }
    364  
    365         void CodeGenerator2::visit( UntypedMemberExpr *memberExpr ) {
     368                output << ")";
     369        }
     370 
     371        void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
    366372                assert( false );
    367373        }
    368374 
    369         void CodeGenerator2::visit( MemberExpr *memberExpr ) {
     375        void CodeGenerator::visit( MemberExpr *memberExpr ) {
    370376                memberExpr->get_aggregate()->accept( *this );
    371                 before << "." << mangleName( memberExpr->get_member() );
    372         }
    373  
    374         void CodeGenerator2::visit( VariableExpr *variableExpr ) {
     377                output << "." << mangleName( memberExpr->get_member() );
     378        }
     379 
     380        void CodeGenerator::visit( VariableExpr *variableExpr ) {
    375381                OperatorInfo opInfo;
    376382                if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) {
    377                         before << opInfo.symbol;
    378                 } else {
    379                         before << mangleName( variableExpr->get_var() );
    380                 } // if
    381         }
    382  
    383         void CodeGenerator2::visit( ConstantExpr *constantExpr ) {
     383                        output << opInfo.symbol;
     384                } else {
     385                        output << mangleName( variableExpr->get_var() );
     386                } // if
     387        }
     388 
     389        void CodeGenerator::visit( ConstantExpr *constantExpr ) {
    384390                assert( constantExpr->get_constant() );
    385391                constantExpr->get_constant()->accept( *this );
    386392        }
    387393 
    388         void CodeGenerator2::visit( SizeofExpr *sizeofExpr ) {
    389                 before << "sizeof(";
     394        void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
     395                output << "sizeof(";
    390396                if ( sizeofExpr->get_isType() ) {
    391                         before << genType( sizeofExpr->get_type(), "" );
     397                        output << genType( sizeofExpr->get_type(), "" );
    392398                } else {
    393399                        sizeofExpr->get_expr()->accept( *this );
    394400                } // if
    395                 before << ")";
    396         }
    397  
    398         void CodeGenerator2::visit( LogicalExpr *logicalExpr ) {
    399                 before << "(";
     401                output << ")";
     402        }
     403 
     404        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
     405                output << "(";
    400406                logicalExpr->get_arg1()->accept( *this );
    401407                if ( logicalExpr->get_isAnd() ) {
    402                         before << " && ";
    403                 } else {
    404                         before << " || ";
     408                        output << " && ";
     409                } else {
     410                        output << " || ";
    405411                } // if
    406412                logicalExpr->get_arg2()->accept( *this );
    407                 before << ")";
    408         }
    409  
    410         void CodeGenerator2::visit( ConditionalExpr *conditionalExpr ) {
    411                 before << "(";
     413                output << ")";
     414        }
     415 
     416        void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
     417                output << "(";
    412418                conditionalExpr->get_arg1()->accept( *this );
    413                 before << " ? ";
     419                output << " ? ";
    414420                conditionalExpr->get_arg2()->accept( *this );
    415                 before << " : ";
     421                output << " : ";
    416422                conditionalExpr->get_arg3()->accept( *this );
    417                 before << ")";
    418         }
    419  
    420         void CodeGenerator2::visit( CommaExpr *commaExpr ) {
    421                 before << "(";
     423                output << ")";
     424        }
     425 
     426        void CodeGenerator::visit( CommaExpr *commaExpr ) {
     427                output << "(";
    422428                commaExpr->get_arg1()->accept( *this );
    423                 before << " , ";
     429                output << " , ";
    424430                commaExpr->get_arg2()->accept( *this );
    425                 before << ")";
    426         }
    427  
    428         void CodeGenerator2::visit( TupleExpr *tupleExpr ) {}
    429  
    430         void CodeGenerator2::visit( TypeExpr *typeExpr ) {}
    431  
    432  
     431                output << ")";
     432        }
     433 
     434        void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
     435 
     436        void CodeGenerator::visit( TypeExpr *typeExpr ) {}
     437
    433438        //*** Statements
    434         void CodeGenerator2::visit( CompoundStmt *compoundStmt ) {
     439        void CodeGenerator::visit( CompoundStmt *compoundStmt ) {
    435440                std::list<Statement*> ks = compoundStmt->get_kids();
    436 
    437                 before << endl << string( cur_indent, ' ' ) << "{" << endl;
    438 
    439                 cur_indent += CodeGenerator2::tabsize;
     441                output << "{" << endl;
     442
     443                cur_indent += CodeGenerator::tabsize;
    440444
    441445                for ( std::list<Statement *>::iterator i = ks.begin(); i != ks.end();  i++) {
    442                         before << string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() )  ;
     446                        output << string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() );
    443447                        (*i)->accept(*this );
    444                         shift_left();
    445                         before << endl;
     448
     449                        output << endl;
     450                        if ( wantSpacing( *i ) ) {
     451                                output << endl;
     452                        }
    446453                }
    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 (";
     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 (";
    462473                ifStmt->get_condition()->accept(*this );
    463                 after += ")\n";
    464                 shift_left();
    465 
    466                 cur_indent += CodeGenerator2::tabsize;
    467                 before << string( cur_indent, ' ' );
     474                output << ") ";
     475
    468476                ifStmt->get_thenPart()->accept(*this );
    469                 cur_indent -= CodeGenerator2::tabsize;
    470                 shift_left(); before << endl;
    471477
    472478                if ( ifStmt->get_elsePart() != 0) {
    473                         before << string( cur_indent, ' ' ) << " else " << endl ;
    474 
    475                         cur_indent += CodeGenerator2::tabsize;
     479                        output << " else ";
    476480                        ifStmt->get_elsePart()->accept(*this );
    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 (" ;
     481                } // if
     482        }
     483
     484        void CodeGenerator::visit( SwitchStmt *switchStmt ) {
     485                //output << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator::printLabels( switchStmt->get_labels() )
     486                output << "switch (" ;
    484487                switchStmt->get_condition()->accept(*this );
    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, ' ' );
     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, ' ' );
    513502                if ( caseStmt->isDefault())
    514                         before << "default "  ;
     503                        output << "default";
    515504                else {
    516                         before << "case "  ;
     505                        output << "case ";
    517506                        caseStmt->get_condition()->accept(*this );
    518507                } // if
    519                 after += ":\n";
    520                 shift_left();
    521 
     508                output << ":\n";
     509               
    522510                std::list<Statement *> sts = caseStmt->get_statements();
    523511
    524                 cur_indent += CodeGenerator2::tabsize;
     512                cur_indent += CodeGenerator::tabsize;
    525513                for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++) {
    526                         before << /* "\r" << */ string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() )  ;
     514                        output << /* "\r" << */ string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() )  ;
    527515                        (*i)->accept(*this );
    528                         shift_left();
    529                         before << ";" << endl;
     516                        output << endl;
    530517                }
    531                 cur_indent -= CodeGenerator2::tabsize;
    532         }
    533 
    534         void CodeGenerator2::visit( BranchStmt *branchStmt ) {
     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
    535525                switch ( branchStmt->get_type()) {
    536526                  case BranchStmt::Goto:
    537527                        if ( ! branchStmt->get_target().empty() )
    538                                 before << "goto " << branchStmt->get_target();
     528                                output << "goto " << branchStmt->get_target();
    539529                        else {
    540530                                if ( branchStmt->get_computedTarget() != 0 ) {
    541                                         before << "goto *";
     531                                        output << "goto *";
    542532                                        branchStmt->get_computedTarget()->accept( *this );
    543533                                } // if
     
    545535                        break;
    546536                  case BranchStmt::Break:
    547                         before << "break";
     537                        output << "break";
    548538                        break;
    549539                  case BranchStmt::Continue:
    550                         before << "continue";
     540                        output << "continue";
    551541                        break;
    552542                }
    553                 before << ";";
    554         }
    555 
    556 
    557         void CodeGenerator2::visit( ReturnStmt *returnStmt ) {
    558                 before << "return ";
     543                output << ";";
     544        }
     545
     546
     547        void CodeGenerator::visit( ReturnStmt *returnStmt ) {
     548                output << "return ";
    559549
    560550                // xxx -- check for null expression;
     
    562552                        returnStmt->get_expr()->accept( *this );
    563553                } // if
    564                 after += ";";
    565         }
    566 
    567         void CodeGenerator2::visit( WhileStmt *whileStmt ) {
     554                output << ";";
     555        }
     556
     557        void CodeGenerator::visit( WhileStmt *whileStmt ) {
    568558                if ( whileStmt->get_isDoWhile() )
    569                         before << "do" ;
     559                        output << "do" ;
    570560                else {
    571                         before << "while (" ;
     561                        output << "while (" ;
    572562                        whileStmt->get_condition()->accept(*this );
    573                         after += ")";
    574                 } // if
    575                 after += "{\n";
    576                 shift_left();
    577 
     563                        output << ")";
     564                } // if
     565                output << " ";
     566
     567                output << CodeGenerator::printLabels( whileStmt->get_body()->get_labels() );
    578568                whileStmt->get_body()->accept( *this );
    579569
    580                 before << /* "\r" << */ string( cur_indent, ' ' ) << "}" ;
     570                output << /* "\r" << */ string( cur_indent, ' ' );
    581571
    582572                if ( whileStmt->get_isDoWhile() ) {
    583                         before << " while (" ;
     573                        output << " while (" ;
    584574                        whileStmt->get_condition()->accept(*this );
    585                         after += ");";
    586                 } // if
    587 
    588                 after += "\n";
    589         }
    590 
    591         void CodeGenerator2::visit( ForStmt *forStmt ) {
    592                 before << "for (";
     575                        output << ");";
     576                } // if
     577        }
     578
     579        void CodeGenerator::visit( ForStmt *forStmt ) {
     580                output << "for (";
    593581
    594582                if ( forStmt->get_initialization() != 0 )
    595583                        forStmt->get_initialization()->accept( *this );
    596584                else
    597                         before << ";";
    598                 shift_left();
    599 
     585                        output << ";";
     586               
    600587                if ( forStmt->get_condition() != 0 )
    601588                        forStmt->get_condition()->accept( *this );
    602                 shift_left(); before << ";";
     589                output << ";";
    603590
    604591                if ( forStmt->get_increment() != 0 )
    605592                        forStmt->get_increment()->accept( *this );
    606                 shift_left(); before << ")" << endl;
     593                output << ") ";
    607594
    608595                if ( forStmt->get_body() != 0 ) {
    609                         cur_indent += CodeGenerator2::tabsize;
    610                         before << string( cur_indent, ' ' ) << CodeGenerator2::printLabels( forStmt->get_body()->get_labels() );
     596                        output << CodeGenerator::printLabels( forStmt->get_body()->get_labels() );
    611597                        forStmt->get_body()->accept( *this );
    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 ) {
     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 ) {
    622607                declStmt->get_decl()->accept( *this );
    623608       
    624609                if ( doSemicolon( declStmt->get_decl() ) ) {
    625                         after += ";";
    626                 } // if
    627                 shift_left();
    628         }
    629 
    630         std::string CodeGenerator2::printLabels( std::list< Label > &l ) {
     610                        output << ";";
     611                } // if
     612        }
     613
     614        std::string CodeGenerator::printLabels( std::list< Label > &l ) {
    631615                std::string str( "" );
    632                 l.unique();
     616                l.unique(); // assumes a sorted list. Why not use set?
    633617
    634618                for ( std::list< Label >::iterator i = l.begin(); i != l.end(); i++ )
     
    638622        }
    639623
    640         void CodeGenerator2::shift_left() {
    641                 before << after;
    642                 after = "";
    643         }
    644 
    645         void CodeGenerator2::handleStorageClass( Declaration *decl ) {
     624        void CodeGenerator::handleStorageClass( Declaration *decl ) {
    646625                switch ( decl->get_storageClass() ) {
    647626                  case Declaration::NoStorageClass:
    648627                        break;
    649628                  case Declaration::Extern:
    650                         before << "extern ";
     629                        output << "extern ";
    651630                        break;
    652631                  case Declaration::Static:
    653                         before << "static ";
     632                        output << "static ";
    654633                        break;
    655634                  case Declaration::Auto:
     
    657636                        break;
    658637                  case Declaration::Register:
    659                         before << "register ";
     638                        output << "register ";
    660639                        break;
    661640                  case Declaration::Inline:
  • src/CodeGen/CodeGenerator.h

    ra61fea9a r9a8930f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CodeGenerator2.h --
     7// CodeGenerator.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 23:35:37 2015
    13 // Update Count     : 2
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Jun 02 13:43:29 2015
     13// Update Count     : 14
    1414//
    1515
     
    2525
    2626namespace CodeGen {
    27         class CodeGenerator2 : public Visitor {
     27        class CodeGenerator : public Visitor {
    2828          public:
    2929                static int tabsize;
    3030
    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 & );
     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 );
    3634
    3735                //*** Declaration
     
    8280                virtual void visit( DeclStmt * );
    8381
    84                 std::string get_string( void );
    85                 void add_string_left( std::string s ) { before << s; }
    86                 void shift_left();
    8782                template< class Iterator > void genCommaList( Iterator begin, Iterator end );
    8883          private:
    8984                int cur_indent;
    9085                bool insideFunction;
    91                 std::ostream &before;
    92                 std::string after;
     86                std::ostream &output;
    9387
    9488                static std::string printLabels ( std::list < Label > & );
     
    10094       
    10195        template< class Iterator >
    102         void CodeGenerator2::genCommaList( Iterator begin, Iterator end ) {
     96        void CodeGenerator::genCommaList( Iterator begin, Iterator end ) {
    10397                if ( begin == end ) return;
    10498
     
    106100                        (*begin++)->accept( *this );
    107101                        if ( begin == end ) return;
    108                         before << ", ";
     102                        output << ", ";
    109103                } // for
    110104        }
  • src/CodeGen/GenType.cc

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

    ra61fea9a r9a8930f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jun  2 11:21:06 2015
    13 // Update Count     : 2
     12// Last Modified On : Thu Jun  4 14:04:25 2015
     13// Update Count     : 5
    1414//
    1515
     
    2727namespace CodeGen {
    2828        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics ) {
    29                 CodeGen::CodeGenerator2 cgv( os );
     29                CodeGen::CodeGenerator 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();
    3534                                if ( doSemicolon( *i ) ) {
    3635                                        os << ";";
  • src/Common/utility.h

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

    ra61fea9a r9a8930f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 15:31:39 2015
    13 // Update Count     : 2
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Jun 03 15:30:20 2015
     13// Update Count     : 5
    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
    4651                if ( insideChoose ) {
    4752                        BranchStmt *posBrk;
  • src/ControlStruct/LabelFixer.cc

    ra61fea9a r9a8930f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed May 27 16:16:14 2015
    13 // Update Count     : 4
     12// Last Modified On : Tue Jun 02 15:30:32 2015
     13// Update Count     : 93
    1414//
    1515
     
    2323#include "utility.h"
    2424
     25#include <iostream>
     26
    2527namespace ControlStruct {
    26         LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) {
     28        LabelFixer::Entry::Entry( Statement *to, BranchStmt *from ) : definition ( to ) {
    2729                if ( from != 0 )
    2830                        usage.push_back( from );
     
    3133        bool LabelFixer::Entry::insideLoop() {
    3234                return ( dynamic_cast< ForStmt * > ( definition ) ||
    33                                  dynamic_cast< WhileStmt * > ( definition )  );
     35                        dynamic_cast< WhileStmt * > ( definition )  );
    3436        }
    3537
     
    4648        }
    4749
     50        // prune to at most one label definition for each statement
    4851        void LabelFixer::visit( Statement *stmt ) {
    4952                std::list< Label > &labels = stmt->get_labels();
    5053
    5154                if ( ! labels.empty() ) {
     55                        // only remember one label for each statement
    5256                        Label current = setLabelsDef( labels, stmt );
    5357                        labels.clear();
     
    5761
    5862        void LabelFixer::visit( BranchStmt *branchStmt ) {
    59                 visit ( ( Statement * )branchStmt );  // the labels this statement might have
     63                visit ( ( Statement * )branchStmt );
    6064
    61                 Label target;
    62                 if ( (target = branchStmt->get_target()) != "" ) {
     65                // for labeled branches, add an entry to the label table
     66                Label target = branchStmt->get_target();
     67                if ( target != "" ) {
    6368                        setLabelsUsg( target, branchStmt );
    64                 } //else       /* computed goto or normal exit-loop statements */
     69                }
    6570        }
    6671
     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
    6774        Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
    6875                assert( definition != 0 );
    69                 Entry *entry = new Entry( definition );
    70                 bool used = false;
     76                assert( llabel.size() > 0 );
    7177
    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 );
     78                Entry * e = new Entry( definition );
    8079
    81                 if ( ! used ) delete entry;
     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
    8295
    83                 return labelTable[ llabel.front() ]->get_label();  // this *must* exist
     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();
    8499        }
    85100
    86         Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
     101        // Remember all uses of a label.
     102        void LabelFixer::setLabelsUsg( Label orgValue, BranchStmt *use ) {
    87103                assert( use != 0 );
    88104
    89                 if ( labelTable.find( orgValue ) != labelTable.end() )
    90                         labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
    91                 else
     105                if ( labelTable.find( orgValue ) != labelTable.end() ) {
     106                        // the label has been defined or used before
     107                        labelTable[ orgValue ]->add_use( use );
     108                } else {
    92109                        labelTable[ orgValue ] = new Entry( 0, use );
    93 
    94                 return labelTable[ orgValue ]->get_label();
     110                }
    95111        }
    96112
     113        // Ultimately builds a table that maps a label to its defining statement.
     114        // In the process,
    97115        std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
    98116                std::map< Statement *, Entry * > def_us;
    99117
    100                 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
     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 ) {
    101120                        Entry *e = i->second;
    102121
    103122                        if ( def_us.find ( e->get_definition() ) == def_us.end() ) {
    104123                                def_us[ e->get_definition() ] = e;                             
    105                         } else {
    106                                 if ( e->used() )
    107                                         def_us[ e->get_definition() ]->add_uses( e->get_uses() );
     124                        } else if ( e->used() ) {
     125                                def_us[ e->get_definition() ]->add_uses( e->get_uses() );
    108126                        }
    109127                }
    110128
    111                 // get rid of labelTable
    112                 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
     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 ) {
    113131                        Statement *to = (*i).first;
    114                         std::list< Statement *> &from = (*i).second->get_uses();
    115                         Label finalLabel = generator->newLabel();
    116                         (*i).second->set_label( finalLabel );
     132                        Entry * entry = (*i).second;
     133                        std::list< BranchStmt *> &from = entry->get_uses();
    117134
     135                        // no label definition found
    118136                        if ( to == 0 ) {
    119                                 BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back());
    120                                 Label undef("");
    121                                 if ( first_use != 0 )
    122                                         undef = first_use->get_target();
     137                                Label undef = from.back()->get_target();
    123138                                throw SemanticError ( "'" + undef + "' label not defined");
    124139                        }
     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 );
    125145
    126146                        to->get_labels().clear();
    127147                        to->get_labels().push_back( finalLabel );
    128148
    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 );
     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 );
    133154                        } // for
    134155                } // for
    135156
    136                 // reverse table
     157                // create a table where each label maps to its defining statement
    137158                std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
    138                 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ )
     159                for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
    139160                        (*ret)[ (*i).second->get_label() ] = (*i).first;
     161                }
    140162
    141163                return ret;
  • src/ControlStruct/LabelFixer.h

    ra61fea9a r9a8930f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue May 26 12:55:10 2015
    13 // Update Count     : 4
     12// Last Modified On : Fri May 29 15:25:55 2015
     13// Update Count     : 11
    1414//
    1515
     
    5555
    5656                Label setLabelsDef( std::list< Label > &, Statement *definition );
    57                 Label setLabelsUsg( Label, Statement *usage = 0 );
     57                void setLabelsUsg( Label, BranchStmt *usage = 0 );
    5858
    5959          private:
    6060                class Entry {
    6161                  public:
    62                         Entry( Statement *to = 0, Statement *from = 0 );
     62                        Entry( Statement *to = 0, BranchStmt *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< 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() ); }
     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() ); }
    7676                  private:
    7777                        Label label; 
    7878                        Statement *definition;
    79                         std::list<Statement *> usage;
     79                        std::list<BranchStmt *> usage;
    8080                };
    8181                 
  • src/ControlStruct/LabelGenerator.cc

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

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

    ra61fea9a r9a8930f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed May 27 16:19:32 2015
    13 // Update Count     : 44
     12// Last Modified On : Wed Jun 03 15:09:27 2015
     13// Update Count     : 170
    1414//
    1515
     
    1919#include "MLEMutator.h"
    2020#include "SynTree/Statement.h"
     21#include "SynTree/Expression.h"
    2122
    2223namespace ControlStruct {
     
    2627        }
    2728
    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();
     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 ) {
    3634                for ( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) {
    3735                        *k = (*k)->acceptMutator(*this);
    3836
    3937                        if ( ! get_breakLabel().empty() ) {
    40                                 std::list< Statement * >::iterator next = k; next++;
     38                                std::list< Statement * >::iterator next = k+1;
    4139                                if ( next == kids.end() ) {
    4240                                        std::list<Label> ls; ls.push_back( get_breakLabel() );
     
    4947                        } // if
    5048                } // 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 );
    5162
    5263                if ( labeledBlock ) {
    5364                        assert( ! enclosingBlocks.empty() );
    54                         if ( ! enclosingBlocks.back().get_breakExit().empty() ) {
    55                                 set_breakLabel( enclosingBlocks.back().get_breakExit() );
     65                        if ( ! enclosingBlocks.back().useBreakExit().empty() ) {
     66                                set_breakLabel( enclosingBlocks.back().useBreakExit() );
    5667                        }
    5768                        enclosingBlocks.pop_back();
    5869                } // if
    5970
    60                 //mutateAll( cmpndStmt->get_kids(), *this );
    6171                return cmpndStmt;
    6272        }
    6373
    64         Statement *MLEMutator::mutate( WhileStmt *whileStmt ) {
    65                 enclosingLoops.push_back( Entry( whileStmt ) );
    66                 whileStmt->set_body ( whileStmt->get_body()->acceptMutator( *this ) );
    67 
     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
    6885                Entry &e = enclosingLoops.back();
    69                 assert ( e == whileStmt );
    70                 whileStmt->set_body( mutateLoop( whileStmt->get_body(), e ) );
     86                assert ( e == loopStmt );
     87
     88                // generate labels as needed
     89                loopStmt->set_body( mutateLoop( loopStmt->get_body(), e ) );
    7190                enclosingLoops.pop_back();
    7291
    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;
     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;
    86131        }
    87132
     
    117162                                        throw SemanticError("The target specified in the exit loop statement does not correspond to an enclosing control structure: " + originalTarget );
    118163
     164                // what about exiting innermost block or switch???
    119165                if ( enclosingLoops.back() == (*check) )
    120166                        return branchStmt;                              // exit the innermost loop (labels unnecessary)
    121167
    122                 Label newLabel;
     168                // branch error checks, get the appropriate label name and create a goto
     169                Label exitLabel;
    123170                switch ( branchStmt->get_type() ) {
    124171                  case BranchStmt::Break:
    125                                 if ( check->get_breakExit() != "" ) {
    126                                         newLabel = check->get_breakExit();
    127                                 } else {
    128                                         newLabel = generator->newLabel();
    129                                         check->set_breakExit( newLabel );
    130                                 } // if
     172                                assert( check->useBreakExit() != "");
     173                                exitLabel = check->useBreakExit();
    131174                                break;
    132175                  case BranchStmt::Continue:
    133                                 if ( check->get_contExit() != "" ) {
    134                                         newLabel = check->get_contExit();
    135                                 } else {
    136                                         newLabel = generator->newLabel();
    137                                         check->set_contExit( newLabel );
    138                                 } // if
     176                                assert( check->useContExit() != "");
     177                                exitLabel = check->useContExit();
    139178                                break;
    140179                  default:
    141                                 return 0;                                       // shouldn't be here
     180                                assert(0);                                      // shouldn't be here
    142181                } // switch
    143182
    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 );           
     183                return new BranchStmt( std::list<Label>(), exitLabel, BranchStmt::Goto );
    172184        }
    173185
    174186        Statement *MLEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) {
     187                // ensure loop body is a block
    175188                CompoundStmt *newBody;
    176189                if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) {
     
    179192                } // if
    180193
    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
     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                }
    202207
    203208                return newBody;
    204209        }
    205210
    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         }
     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
    216227} // namespace ControlStruct
    217228
  • src/ControlStruct/MLEMutator.h

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

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

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

    ra61fea9a r9a8930f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 10:14:18 2015
    13 // Update Count     : 2
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu May 28 14:10:02 2015
     13// Update Count     : 8
    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
    6772        if ( get_name() != "" ) {
    6873                os << get_name() << ": a ";
  • src/SynTree/Statement.cc

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

    ra61fea9a r9a8930f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun  3 11:55:15 2015
    13 // Update Count     : 6
     12// Last Modified On : Thu Jun  4 14:03:31 2015
     13// Update Count     : 14
    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 *>() );
    151154
    152155        bool isDefault() { return _isDefault; }
  • src/examples/control_structures.c

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