Changeset f980549 for src/CodeGen


Ignore:
Timestamp:
Sep 20, 2017, 12:24:45 PM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
b18830e
Parents:
764e009 (diff), 47b5b63 (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:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/CodeGen
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r764e009 rf980549  
    7979        }
    8080
    81         /* Using updateLocation at the beginning of a node and nextLine
     81        /* Using updateLocation at the beginning of a node and endl
    8282         * within a node should become the method of formating.
    8383         */
    8484        void CodeGenerator::updateLocation( CodeLocation const & to ) {
    85                 if ( !lineMarks ) {
    86                         return;
    87                 } else if ( currentLocation.followedBy( to, 0 ) ) {
     85                // skip if linemarks shouldn't appear or if codelocation is unset
     86                if ( !lineMarks || to.isUnset() ) return;
     87
     88                if ( currentLocation.followedBy( to, 0 ) ) {
    8889                        return;
    8990                } else if ( currentLocation.followedBy( to, 1 ) ) {
    9091                        output << "\n" << indent;
    91                         currentLocation.linenumber += 1;
     92                        currentLocation.first_line += 1;
    9293                } else if ( currentLocation.followedBy( to, 2 ) ) {
    9394                        output << "\n\n" << indent;
    94                         currentLocation.linenumber += 2;
    95                 } else {
    96                         output << "\n# " << to.linenumber << " \"" << to.filename
     95                        currentLocation.first_line += 2;
     96                } else {
     97                        output << "\n# " << to.first_line << " \"" << to.filename
    9798                               << "\"\n" << indent;
    9899                        currentLocation = to;
     
    105106        }
    106107
    107         void CodeGenerator::nextLine() {
    108                 if ( !lineMarks ) {
    109                         output << "\n" << indent << std::flush;
    110                 }
    111         }
    112 
    113         CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( CodeGenerator::tabsize ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {}
     108        // replace endl
     109        ostream & CodeGenerator::LineEnder::operator()( ostream & os ) const {
     110                // if ( !cg.lineMarks ) {
     111                //      os << "\n" << cg.indent << std::flush;
     112                // }
     113                os << "\n" << std::flush;
     114                cg.currentLocation.first_line++;
     115                // os << "/* did endl; current loc is: " << cg.currentLocation.first_line << "*/";
     116                return os;
     117        }
     118
     119        CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ), endl( *this ) {}
    114120
    115121        string CodeGenerator::mangleName( DeclarationWithType * decl ) {
     
    139145        } // CodeGenerator::genAttributes
    140146
     147        // *** BaseSyntaxNode
     148        void CodeGenerator::previsit( BaseSyntaxNode * node ) {
     149                // turn off automatic recursion for all nodes, to allow each visitor to
     150                // precisely control the order in which its children are visited.
     151                visit_children = false;
     152                updateLocation( node );
     153        }
     154
     155        // *** BaseSyntaxNode
     156        void CodeGenerator::postvisit( BaseSyntaxNode * node ) {
     157                std::stringstream ss;
     158                node->print( ss );
     159                assertf( false, "Unhandled node reached in CodeGenerator: %s", ss.str().c_str() );
     160        }
    141161
    142162        // *** Declarations
    143         void CodeGenerator::visit( FunctionDecl * functionDecl ) {
     163        void CodeGenerator::postvisit( FunctionDecl * functionDecl ) {
    144164                extension( functionDecl );
    145165                genAttributes( functionDecl->get_attributes() );
     
    152172                asmName( functionDecl );
    153173
    154                 // acceptAll( functionDecl->get_oldDecls(), *this );
    155174                if ( functionDecl->get_statements() ) {
    156                         functionDecl->get_statements()->accept( *this );
    157                 } // if
    158         }
    159 
    160         void CodeGenerator::visit( ObjectDecl * objectDecl ) {
     175                        functionDecl->get_statements()->accept( *visitor );
     176                } // if
     177        }
     178
     179        void CodeGenerator::postvisit( ObjectDecl * objectDecl ) {
    161180                if (objectDecl->get_name().empty() && genC ) {
    162181                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
     
    175194                if ( objectDecl->get_init() ) {
    176195                        output << " = ";
    177                         objectDecl->get_init()->accept( *this );
     196                        objectDecl->get_init()->accept( *visitor );
    178197                } // if
    179198
    180199                if ( objectDecl->get_bitfieldWidth() ) {
    181200                        output << ":";
    182                         objectDecl->get_bitfieldWidth()->accept( *this );
     201                        objectDecl->get_bitfieldWidth()->accept( *visitor );
    183202                } // if
    184203        }
     
    203222                        ++indent;
    204223                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++ ) {
    205                                 updateLocation( *i );
    206224                                output << indent;
    207                                 (*i)->accept( *this );
     225                                (*i)->accept( *visitor );
    208226                                output << ";" << endl;
    209227                        } // for
     
    215233        }
    216234
    217         void CodeGenerator::visit( StructDecl * structDecl ) {
     235        void CodeGenerator::postvisit( StructDecl * structDecl ) {
    218236                extension( structDecl );
    219237                handleAggregate( structDecl, "struct " );
    220238        }
    221239
    222         void CodeGenerator::visit( UnionDecl * unionDecl ) {
     240        void CodeGenerator::postvisit( UnionDecl * unionDecl ) {
    223241                extension( unionDecl );
    224242                handleAggregate( unionDecl, "union " );
    225243        }
    226244
    227         void CodeGenerator::visit( EnumDecl * enumDecl ) {
     245        void CodeGenerator::postvisit( EnumDecl * enumDecl ) {
    228246                extension( enumDecl );
    229                 updateLocation( enumDecl );
    230247                output << "enum ";
    231248                genAttributes( enumDecl->get_attributes() );
     
    242259                                ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
    243260                                assert( obj );
    244                                 updateLocation( obj );
    245261                                output << indent << mangleName( obj );
    246262                                if ( obj->get_init() ) {
    247263                                        output << " = ";
    248                                         obj->get_init()->accept( *this );
     264                                        obj->get_init()->accept( *visitor );
    249265                                } // if
    250266                                output << "," << endl;
     
    257273        }
    258274
    259         void CodeGenerator::visit( TraitDecl * traitDecl ) {
     275        void CodeGenerator::postvisit( TraitDecl * traitDecl ) {
    260276                assertf( ! genC, "TraitDecls should not reach code generation." );
    261277                extension( traitDecl );
     
    263279        }
    264280
    265         void CodeGenerator::visit( TypedefDecl * typeDecl ) {
     281        void CodeGenerator::postvisit( TypedefDecl * typeDecl ) {
    266282                assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
    267                 updateLocation( typeDecl );
    268283                output << "typedef ";
    269284                output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;
    270285        }
    271286
    272         void CodeGenerator::visit( TypeDecl * typeDecl ) {
     287        void CodeGenerator::postvisit( TypeDecl * typeDecl ) {
    273288                assertf( ! genC, "TypeDecls should not reach code generation." );
    274289                output << typeDecl->genTypeString() << " " << typeDecl->get_name();
     
    283298        }
    284299
    285         void CodeGenerator::visit( Designation * designation ) {
     300        void CodeGenerator::postvisit( Designation * designation ) {
    286301                std::list< Expression * > designators = designation->get_designators();
    287302                if ( designators.size() == 0 ) return;
     
    290305                                // if expression is a NameExpr or VariableExpr, then initializing aggregate member
    291306                                output << ".";
    292                                 des->accept( *this );
     307                                des->accept( *visitor );
    293308                        } else {
    294309                                // otherwise, it has to be a ConstantExpr or CastExpr, initializing array eleemnt
    295310                                output << "[";
    296                                 des->accept( *this );
     311                                des->accept( *visitor );
    297312                                output << "]";
    298313                        } // if
     
    301316        }
    302317
    303         void CodeGenerator::visit( SingleInit * init ) {
    304                 init->get_value()->accept( *this );
    305         }
    306 
    307         void CodeGenerator::visit( ListInit * init ) {
     318        void CodeGenerator::postvisit( SingleInit * init ) {
     319                init->get_value()->accept( *visitor );
     320        }
     321
     322        void CodeGenerator::postvisit( ListInit * init ) {
    308323                auto initBegin = init->begin();
    309324                auto initEnd = init->end();
     
    313328                output << "{ ";
    314329                for ( ; initBegin != initEnd && desigBegin != desigEnd; ) {
    315                         (*desigBegin)->accept( *this );
    316                         (*initBegin)->accept( *this );
     330                        (*desigBegin)->accept( *visitor );
     331                        (*initBegin)->accept( *visitor );
    317332                        ++initBegin, ++desigBegin;
    318333                        if ( initBegin != initEnd ) {
     
    324339        }
    325340
    326         void CodeGenerator::visit( __attribute__((unused)) ConstructorInit * init ){
     341        void CodeGenerator::postvisit( ConstructorInit * init ){
    327342                assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
    328343                // pseudo-output for constructor/destructor pairs
    329                 output << "<ctorinit>{" << std::endl << ++indent << "ctor: ";
    330                 maybeAccept( init->get_ctor(), *this );
    331                 output << ", " << std::endl << indent << "dtor: ";
    332                 maybeAccept( init->get_dtor(), *this );
    333                 output << std::endl << --indent << "}";
    334         }
    335 
    336         void CodeGenerator::visit( Constant * constant ) {
     344                output << "<ctorinit>{" << endl << ++indent << "ctor: ";
     345                maybeAccept( init->get_ctor(), *visitor );
     346                output << ", " << endl << indent << "dtor: ";
     347                maybeAccept( init->get_dtor(), *visitor );
     348                output << endl << --indent << "}";
     349        }
     350
     351        void CodeGenerator::postvisit( Constant * constant ) {
    337352                output << constant->get_value() ;
    338353        }
    339354
    340355        // *** Expressions
    341         void CodeGenerator::visit( ApplicationExpr * applicationExpr ) {
     356        void CodeGenerator::postvisit( ApplicationExpr * applicationExpr ) {
    342357                extension( applicationExpr );
    343358                if ( VariableExpr * varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
     
    348363                                  case OT_INDEX:
    349364                                        assert( applicationExpr->get_args().size() == 2 );
    350                                         (*arg++)->accept( *this );
     365                                        (*arg++)->accept( *visitor );
    351366                                        output << "[";
    352                                         (*arg)->accept( *this );
     367                                        (*arg)->accept( *visitor );
    353368                                        output << "]";
    354369                                        break;
     
    365380                                                // effects, so must still output this expression
    366381                                                output << "(";
    367                                                 (*arg++)->accept( *this );
     382                                                (*arg++)->accept( *visitor );
    368383                                                output << ") /* " << opInfo.inputName << " */";
    369384                                        } else if ( applicationExpr->get_args().size() == 2 ) {
    370385                                                // intrinsic two parameter constructors are essentially bitwise assignment
    371386                                                output << "(";
    372                                                 (*arg++)->accept( *this );
     387                                                (*arg++)->accept( *visitor );
    373388                                                output << opInfo.symbol;
    374                                                 (*arg)->accept( *this );
     389                                                (*arg)->accept( *visitor );
    375390                                                output << ") /* " << opInfo.inputName << " */";
    376391                                        } else {
     
    385400                                        output << "(";
    386401                                        output << opInfo.symbol;
    387                                         (*arg)->accept( *this );
     402                                        (*arg)->accept( *visitor );
    388403                                        output << ")";
    389404                                        break;
     
    392407                                  case OT_POSTFIXASSIGN:
    393408                                        assert( applicationExpr->get_args().size() == 1 );
    394                                         (*arg)->accept( *this );
     409                                        (*arg)->accept( *visitor );
    395410                                        output << opInfo.symbol;
    396411                                        break;
     
    401416                                        assert( applicationExpr->get_args().size() == 2 );
    402417                                        output << "(";
    403                                         (*arg++)->accept( *this );
     418                                        (*arg++)->accept( *visitor );
    404419                                        output << opInfo.symbol;
    405                                         (*arg)->accept( *this );
     420                                        (*arg)->accept( *visitor );
    406421                                        output << ")";
    407422                                        break;
     
    413428                                } // switch
    414429                        } else {
    415                                 varExpr->accept( *this );
     430                                varExpr->accept( *visitor );
    416431                                output << "(";
    417432                                genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
     
    419434                        } // if
    420435                } else {
    421                         applicationExpr->get_function()->accept( *this );
     436                        applicationExpr->get_function()->accept( *visitor );
    422437                        output << "(";
    423438                        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
     
    426441        }
    427442
    428         void CodeGenerator::visit( UntypedExpr * untypedExpr ) {
     443        void CodeGenerator::postvisit( UntypedExpr * untypedExpr ) {
    429444                extension( untypedExpr );
    430445                if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     
    435450                                  case OT_INDEX:
    436451                                        assert( untypedExpr->get_args().size() == 2 );
    437                                         (*arg++)->accept( *this );
     452                                        (*arg++)->accept( *visitor );
    438453                                        output << "[";
    439                                         (*arg)->accept( *this );
     454                                        (*arg)->accept( *visitor );
    440455                                        output << "]";
    441456                                        break;
     
    450465                                                // effects, so must still output this expression
    451466                                                output << "(";
    452                                                 (*arg++)->accept( *this );
     467                                                (*arg++)->accept( *visitor );
    453468                                                output << ") /* " << opInfo.inputName << " */";
    454469                                        } else if ( untypedExpr->get_args().size() == 2 ) {
    455470                                                // intrinsic two parameter constructors are essentially bitwise assignment
    456471                                                output << "(";
    457                                                 (*arg++)->accept( *this );
     472                                                (*arg++)->accept( *visitor );
    458473                                                output << opInfo.symbol;
    459                                                 (*arg)->accept( *this );
     474                                                (*arg)->accept( *visitor );
    460475                                                output << ") /* " << opInfo.inputName << " */";
    461476                                        } else {
    462477                                                // no constructors with 0 or more than 2 parameters
    463                                                 assert( false );
     478                                                assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
     479                                                output << "(";
     480                                                (*arg++)->accept( *visitor );
     481                                                output << opInfo.symbol << "{ ";
     482                                                genCommaList( arg, untypedExpr->get_args().end() );
     483                                                output << "}) /* " << opInfo.inputName << " */";
    464484                                        } // if
    465485                                        break;
     
    471491                                        output << "(";
    472492                                        output << opInfo.symbol;
    473                                         (*arg)->accept( *this );
     493                                        (*arg)->accept( *visitor );
    474494                                        output << ")";
    475495                                        break;
     
    478498                                  case OT_POSTFIXASSIGN:
    479499                                        assert( untypedExpr->get_args().size() == 1 );
    480                                         (*arg)->accept( *this );
     500                                        (*arg)->accept( *visitor );
    481501                                        output << opInfo.symbol;
    482502                                        break;
     
    486506                                        assert( untypedExpr->get_args().size() == 2 );
    487507                                        output << "(";
    488                                         (*arg++)->accept( *this );
     508                                        (*arg++)->accept( *visitor );
    489509                                        output << opInfo.symbol;
    490                                         (*arg)->accept( *this );
     510                                        (*arg)->accept( *visitor );
    491511                                        output << ")";
    492512                                        break;
     
    499519                                if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2
    500520                                        assert( untypedExpr->get_args().size() == 2 );
    501                                         (*untypedExpr->get_args().begin())->accept( *this );
     521                                        (*untypedExpr->get_args().begin())->accept( *visitor );
    502522                                        output << " ... ";
    503                                         (*--untypedExpr->get_args().end())->accept( *this );
     523                                        (*--untypedExpr->get_args().end())->accept( *visitor );
    504524                                } else {                                                                // builtin routines
    505                                         nameExpr->accept( *this );
     525                                        nameExpr->accept( *visitor );
    506526                                        output << "(";
    507527                                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
     
    510530                        } // if
    511531                } else {
    512                         untypedExpr->get_function()->accept( *this );
     532                        untypedExpr->get_function()->accept( *visitor );
    513533                        output << "(";
    514534                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
     
    517537        }
    518538
    519         void CodeGenerator::visit( RangeExpr * rangeExpr ) {
    520                 rangeExpr->get_low()->accept( *this );
     539        void CodeGenerator::postvisit( RangeExpr * rangeExpr ) {
     540                rangeExpr->get_low()->accept( *visitor );
    521541                output << " ... ";
    522                 rangeExpr->get_high()->accept( *this );
    523         }
    524 
    525         void CodeGenerator::visit( NameExpr * nameExpr ) {
     542                rangeExpr->get_high()->accept( *visitor );
     543        }
     544
     545        void CodeGenerator::postvisit( NameExpr * nameExpr ) {
    526546                extension( nameExpr );
    527547                OperatorInfo opInfo;
     
    534554        }
    535555
    536         void CodeGenerator::visit( AddressExpr * addressExpr ) {
     556        void CodeGenerator::postvisit( AddressExpr * addressExpr ) {
    537557                extension( addressExpr );
    538558                output << "(&";
    539                 addressExpr->arg->accept( *this );
     559                addressExpr->arg->accept( *visitor );
    540560                output << ")";
    541561        }
    542562
    543         void CodeGenerator::visit( LabelAddressExpr *addressExpr ) {
     563        void CodeGenerator::postvisit( LabelAddressExpr *addressExpr ) {
    544564                extension( addressExpr );
    545565                output << "(&&" << addressExpr->arg << ")";
    546566        }
    547567
    548         void CodeGenerator::visit( CastExpr * castExpr ) {
     568        void CodeGenerator::postvisit( CastExpr * castExpr ) {
    549569                extension( castExpr );
    550570                output << "(";
     
    559579                        output << ")";
    560580                } // if
    561                 castExpr->get_arg()->accept( *this );
     581                castExpr->get_arg()->accept( *visitor );
    562582                output << ")";
    563583        }
    564584
    565         void CodeGenerator::visit( VirtualCastExpr * castExpr ) {
     585        void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) {
    566586                assertf( ! genC, "VirtualCastExpr should not reach code generation." );
    567587                extension( castExpr );
    568588                output << "(virtual ";
    569                 castExpr->get_arg()->accept( *this );
     589                castExpr->get_arg()->accept( *visitor );
    570590                output << ")";
    571591        }
    572592
    573         void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) {
     593        void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) {
    574594                assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
    575595                extension( memberExpr );
    576                 memberExpr->get_aggregate()->accept( *this );
     596                memberExpr->get_aggregate()->accept( *visitor );
    577597                output << ".";
    578                 memberExpr->get_member()->accept( *this );
    579         }
    580 
    581         void CodeGenerator::visit( MemberExpr * memberExpr ) {
     598                memberExpr->get_member()->accept( *visitor );
     599        }
     600
     601        void CodeGenerator::postvisit( MemberExpr * memberExpr ) {
    582602                extension( memberExpr );
    583                 memberExpr->get_aggregate()->accept( *this );
     603                memberExpr->get_aggregate()->accept( *visitor );
    584604                output << "." << mangleName( memberExpr->get_member() );
    585605        }
    586606
    587         void CodeGenerator::visit( VariableExpr * variableExpr ) {
     607        void CodeGenerator::postvisit( VariableExpr * variableExpr ) {
    588608                extension( variableExpr );
    589609                OperatorInfo opInfo;
     
    595615        }
    596616
    597         void CodeGenerator::visit( ConstantExpr * constantExpr ) {
     617        void CodeGenerator::postvisit( ConstantExpr * constantExpr ) {
    598618                assert( constantExpr->get_constant() );
    599619                extension( constantExpr );
    600                 constantExpr->get_constant()->accept( *this );
    601         }
    602 
    603         void CodeGenerator::visit( SizeofExpr * sizeofExpr ) {
     620                constantExpr->get_constant()->accept( *visitor );
     621        }
     622
     623        void CodeGenerator::postvisit( SizeofExpr * sizeofExpr ) {
    604624                extension( sizeofExpr );
    605625                output << "sizeof(";
     
    607627                        output << genType( sizeofExpr->get_type(), "", pretty, genC );
    608628                } else {
    609                         sizeofExpr->get_expr()->accept( *this );
     629                        sizeofExpr->get_expr()->accept( *visitor );
    610630                } // if
    611631                output << ")";
    612632        }
    613633
    614         void CodeGenerator::visit( AlignofExpr * alignofExpr ) {
     634        void CodeGenerator::postvisit( AlignofExpr * alignofExpr ) {
    615635                // use GCC extension to avoid bumping std to C11
    616636                extension( alignofExpr );
     
    619639                        output << genType( alignofExpr->get_type(), "", pretty, genC );
    620640                } else {
    621                         alignofExpr->get_expr()->accept( *this );
     641                        alignofExpr->get_expr()->accept( *visitor );
    622642                } // if
    623643                output << ")";
    624644        }
    625645
    626         void CodeGenerator::visit( UntypedOffsetofExpr * offsetofExpr ) {
     646        void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) {
    627647                assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );
    628648                output << "offsetof(";
     
    632652        }
    633653
    634         void CodeGenerator::visit( OffsetofExpr * offsetofExpr ) {
     654        void CodeGenerator::postvisit( OffsetofExpr * offsetofExpr ) {
    635655                // use GCC builtin
    636656                output << "__builtin_offsetof(";
     
    640660        }
    641661
    642         void CodeGenerator::visit( OffsetPackExpr * offsetPackExpr ) {
     662        void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) {
    643663                assertf( ! genC, "OffsetPackExpr should not reach code generation." );
    644664                output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")";
    645665        }
    646666
    647         void CodeGenerator::visit( LogicalExpr * logicalExpr ) {
     667        void CodeGenerator::postvisit( LogicalExpr * logicalExpr ) {
    648668                extension( logicalExpr );
    649669                output << "(";
    650                 logicalExpr->get_arg1()->accept( *this );
     670                logicalExpr->get_arg1()->accept( *visitor );
    651671                if ( logicalExpr->get_isAnd() ) {
    652672                        output << " && ";
     
    654674                        output << " || ";
    655675                } // if
    656                 logicalExpr->get_arg2()->accept( *this );
     676                logicalExpr->get_arg2()->accept( *visitor );
    657677                output << ")";
    658678        }
    659679
    660         void CodeGenerator::visit( ConditionalExpr * conditionalExpr ) {
     680        void CodeGenerator::postvisit( ConditionalExpr * conditionalExpr ) {
    661681                extension( conditionalExpr );
    662682                output << "(";
    663                 conditionalExpr->get_arg1()->accept( *this );
     683                conditionalExpr->get_arg1()->accept( *visitor );
    664684                output << " ? ";
    665                 conditionalExpr->get_arg2()->accept( *this );
     685                conditionalExpr->get_arg2()->accept( *visitor );
    666686                output << " : ";
    667                 conditionalExpr->get_arg3()->accept( *this );
     687                conditionalExpr->get_arg3()->accept( *visitor );
    668688                output << ")";
    669689        }
    670690
    671         void CodeGenerator::visit( CommaExpr * commaExpr ) {
     691        void CodeGenerator::postvisit( CommaExpr * commaExpr ) {
    672692                extension( commaExpr );
    673693                output << "(";
     
    676696                        commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );
    677697                }
    678                 commaExpr->get_arg1()->accept( *this );
     698                commaExpr->get_arg1()->accept( *visitor );
    679699                output << " , ";
    680                 commaExpr->get_arg2()->accept( *this );
     700                commaExpr->get_arg2()->accept( *visitor );
    681701                output << ")";
    682702        }
    683703
    684         void CodeGenerator::visit( TupleAssignExpr * tupleExpr ) {
     704        void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) {
    685705                assertf( ! genC, "TupleAssignExpr should not reach code generation." );
    686                 tupleExpr->stmtExpr->accept( *this );
    687         }
    688 
    689         void CodeGenerator::visit( UntypedTupleExpr * tupleExpr ) {
     706                tupleExpr->stmtExpr->accept( *visitor );
     707        }
     708
     709        void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) {
    690710                assertf( ! genC, "UntypedTupleExpr should not reach code generation." );
    691711                extension( tupleExpr );
     
    695715        }
    696716
    697         void CodeGenerator::visit( TupleExpr * tupleExpr ) {
     717        void CodeGenerator::postvisit( TupleExpr * tupleExpr ) {
    698718                assertf( ! genC, "TupleExpr should not reach code generation." );
    699719                extension( tupleExpr );
     
    703723        }
    704724
    705         void CodeGenerator::visit( TupleIndexExpr * tupleExpr ) {
     725        void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) {
    706726                assertf( ! genC, "TupleIndexExpr should not reach code generation." );
    707727                extension( tupleExpr );
    708                 tupleExpr->get_tuple()->accept( *this );
     728                tupleExpr->get_tuple()->accept( *visitor );
    709729                output << "." << tupleExpr->get_index();
    710730        }
    711731
    712         void CodeGenerator::visit( TypeExpr * typeExpr ) {
     732        void CodeGenerator::postvisit( TypeExpr * typeExpr ) {
    713733                // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
    714734                // assertf( ! genC, "TypeExpr should not reach code generation." );
     
    718738        }
    719739
    720         void CodeGenerator::visit( AsmExpr * asmExpr ) {
     740        void CodeGenerator::postvisit( AsmExpr * asmExpr ) {
    721741                if ( asmExpr->get_inout() ) {
    722742                        output << "[ ";
    723                         asmExpr->get_inout()->accept( *this );
     743                        asmExpr->get_inout()->accept( *visitor );
    724744                        output << " ] ";
    725745                } // if
    726                 asmExpr->get_constraint()->accept( *this );
     746                asmExpr->get_constraint()->accept( *visitor );
    727747                output << " ( ";
    728                 asmExpr->get_operand()->accept( *this );
     748                asmExpr->get_operand()->accept( *visitor );
    729749                output << " )";
    730750        }
    731751
    732         void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) {
     752        void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) {
    733753                assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    734754                output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")";
    735                 compLitExpr->get_initializer()->accept( *this );
    736         }
    737 
    738         void CodeGenerator::visit( UniqueExpr * unqExpr ) {
     755                compLitExpr->get_initializer()->accept( *visitor );
     756        }
     757
     758        void CodeGenerator::postvisit( UniqueExpr * unqExpr ) {
    739759                assertf( ! genC, "Unique expressions should not reach code generation." );
    740760                output << "unq<" << unqExpr->get_id() << ">{ ";
    741                 unqExpr->get_expr()->accept( *this );
     761                unqExpr->get_expr()->accept( *visitor );
    742762                output << " }";
    743763        }
    744764
    745         void CodeGenerator::visit( StmtExpr * stmtExpr ) {
     765        void CodeGenerator::postvisit( StmtExpr * stmtExpr ) {
    746766                std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    747                 updateLocation( stmtExpr );
    748                 output << "({" << std::endl;
     767                output << "({" << endl;
    749768                ++indent;
    750769                unsigned int numStmts = stmts.size();
    751770                unsigned int i = 0;
    752771                for ( Statement * stmt : stmts ) {
    753                         updateLocation( stmt );
    754772                        output << indent << printLabels( stmt->get_labels() );
    755773                        if ( i+1 == numStmts ) {
     
    757775                                // cannot cast to void, otherwise the expression statement has no value
    758776                                if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
    759                                         exprStmt->get_expr()->accept( *this );
     777                                        exprStmt->get_expr()->accept( *visitor );
    760778                                        output << ";" << endl;
    761779                                        ++i;
     
    763781                                }
    764782                        }
    765                         stmt->accept( *this );
     783                        stmt->accept( *visitor );
    766784                        output << endl;
    767785                        if ( wantSpacing( stmt ) ) {
     
    774792        }
    775793
     794        void CodeGenerator::postvisit( ConstructorExpr * expr ) {
     795                assertf( ! genC, "Unique expressions should not reach code generation." );
     796                expr->callExpr->accept( *visitor );
     797        }
     798
    776799        // *** Statements
    777         void CodeGenerator::visit( CompoundStmt * compoundStmt ) {
     800        void CodeGenerator::postvisit( CompoundStmt * compoundStmt ) {
    778801                std::list<Statement*> ks = compoundStmt->get_kids();
    779802                output << "{" << endl;
     
    783806                for ( std::list<Statement *>::iterator i = ks.begin(); i != ks.end();  i++ ) {
    784807                        output << indent << printLabels( (*i)->get_labels() );
    785                         (*i)->accept( *this );
     808                        (*i)->accept( *visitor );
    786809
    787810                        output << endl;
     
    795818        }
    796819
    797         void CodeGenerator::visit( ExprStmt * exprStmt ) {
     820        void CodeGenerator::postvisit( ExprStmt * exprStmt ) {
    798821                assert( exprStmt );
    799822                if ( genC ) {
     
    801824                        exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) );
    802825                }
    803                 exprStmt->get_expr()->accept( *this );
     826                exprStmt->get_expr()->accept( *visitor );
    804827                output << ";";
    805828        }
    806829
    807         void CodeGenerator::visit( AsmStmt * asmStmt ) {
     830        void CodeGenerator::postvisit( AsmStmt * asmStmt ) {
    808831                output << "asm ";
    809832                if ( asmStmt->get_voltile() ) output << "volatile ";
    810833                if ( ! asmStmt->get_gotolabels().empty()  ) output << "goto ";
    811834                output << "( ";
    812                 if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *this );
     835                if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *visitor );
    813836                output << " : ";
    814837                genCommaList( asmStmt->get_output().begin(), asmStmt->get_output().end() );
     
    828851        }
    829852
    830         void CodeGenerator::visit( AsmDecl * asmDecl ) {
     853        void CodeGenerator::postvisit( AsmDecl * asmDecl ) {
    831854                output << "asm ";
    832855                AsmStmt * asmStmt = asmDecl->get_stmt();
    833856                output << "( ";
    834                 if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *this );
     857                if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *visitor );
    835858                output << " )" ;
    836859        }
    837860
    838         void CodeGenerator::visit( IfStmt * ifStmt ) {
    839                 updateLocation( ifStmt );
     861        void CodeGenerator::postvisit( IfStmt * ifStmt ) {
    840862                output << "if ( ";
    841                 ifStmt->get_condition()->accept( *this );
     863                ifStmt->get_condition()->accept( *visitor );
    842864                output << " ) ";
    843865
    844                 ifStmt->get_thenPart()->accept( *this );
     866                ifStmt->get_thenPart()->accept( *visitor );
    845867
    846868                if ( ifStmt->get_elsePart() != 0) {
    847869                        output << " else ";
    848                         ifStmt->get_elsePart()->accept( *this );
    849                 } // if
    850         }
    851 
    852         void CodeGenerator::visit( SwitchStmt * switchStmt ) {
    853                 updateLocation( switchStmt );
     870                        ifStmt->get_elsePart()->accept( *visitor );
     871                } // if
     872        }
     873
     874        void CodeGenerator::postvisit( SwitchStmt * switchStmt ) {
    854875                output << "switch ( " ;
    855                 switchStmt->get_condition()->accept( *this );
     876                switchStmt->get_condition()->accept( *visitor );
    856877                output << " ) ";
    857878
    858                 output << "{" << std::endl;
     879                output << "{" << endl;
    859880                ++indent;
    860                 acceptAll( switchStmt->get_statements(), *this );
     881                acceptAll( switchStmt->get_statements(), *visitor );
    861882                --indent;
    862883                output << indent << "}";
    863884        }
    864885
    865         void CodeGenerator::visit( CaseStmt * caseStmt ) {
     886        void CodeGenerator::postvisit( CaseStmt * caseStmt ) {
    866887                updateLocation( caseStmt );
    867888                output << indent;
     
    870891                } else {
    871892                        output << "case ";
    872                         caseStmt->get_condition()->accept( *this );
    873                 } // if
    874                 output << ":\n";
     893                        caseStmt->get_condition()->accept( *visitor );
     894                } // if
     895                output << ":" << endl;
    875896
    876897                std::list<Statement *> sts = caseStmt->get_statements();
     
    879900                for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++) {
    880901                        output << indent << printLabels( (*i)->get_labels() )  ;
    881                         (*i)->accept( *this );
     902                        (*i)->accept( *visitor );
    882903                        output << endl;
    883904                } // for
     
    885906        }
    886907
    887         void CodeGenerator::visit( BranchStmt * branchStmt ) {
     908        void CodeGenerator::postvisit( BranchStmt * branchStmt ) {
    888909                switch ( branchStmt->get_type()) {
    889910                  case BranchStmt::Goto:
     
    893914                                if ( branchStmt->get_computedTarget() != 0 ) {
    894915                                        output << "goto *";
    895                                         branchStmt->get_computedTarget()->accept( *this );
     916                                        branchStmt->get_computedTarget()->accept( *visitor );
    896917                                } // if
    897918                        } // if
     
    907928        }
    908929
    909         void CodeGenerator::visit( ReturnStmt * returnStmt ) {
     930        void CodeGenerator::postvisit( ReturnStmt * returnStmt ) {
    910931                output << "return ";
    911                 maybeAccept( returnStmt->get_expr(), *this );
     932                maybeAccept( returnStmt->get_expr(), *visitor );
    912933                output << ";";
    913934        }
    914935
    915         void CodeGenerator::visit( ThrowStmt * throwStmt ) {
     936        void CodeGenerator::postvisit( ThrowStmt * throwStmt ) {
    916937                assertf( ! genC, "Throw statements should not reach code generation." );
    917938
     
    920941                if (throwStmt->get_expr()) {
    921942                        output << " ";
    922                         throwStmt->get_expr()->accept( *this );
     943                        throwStmt->get_expr()->accept( *visitor );
    923944                }
    924945                if (throwStmt->get_target()) {
    925946                        output << " _At ";
    926                         throwStmt->get_target()->accept( *this );
     947                        throwStmt->get_target()->accept( *visitor );
    927948                }
    928949                output << ";";
    929950        }
    930951
    931         void CodeGenerator::visit( WhileStmt * whileStmt ) {
     952        void CodeGenerator::postvisit( WhileStmt * whileStmt ) {
    932953                if ( whileStmt->get_isDoWhile() ) {
    933954                        output << "do" ;
    934955                } else {
    935956                        output << "while (" ;
    936                         whileStmt->get_condition()->accept( *this );
     957                        whileStmt->get_condition()->accept( *visitor );
    937958                        output << ")";
    938959                } // if
     
    940961
    941962                output << CodeGenerator::printLabels( whileStmt->get_body()->get_labels() );
    942                 whileStmt->get_body()->accept( *this );
     963                whileStmt->get_body()->accept( *visitor );
    943964
    944965                output << indent;
     
    946967                if ( whileStmt->get_isDoWhile() ) {
    947968                        output << " while (" ;
    948                         whileStmt->get_condition()->accept( *this );
     969                        whileStmt->get_condition()->accept( *visitor );
    949970                        output << ");";
    950971                } // if
    951972        }
    952973
    953         void CodeGenerator::visit( ForStmt * forStmt ) {
     974        void CodeGenerator::postvisit( ForStmt * forStmt ) {
    954975                // initialization is always hoisted, so don't bother doing anything with that
    955976                output << "for (;";
    956977
    957978                if ( forStmt->get_condition() != 0 ) {
    958                         forStmt->get_condition()->accept( *this );
     979                        forStmt->get_condition()->accept( *visitor );
    959980                } // if
    960981                output << ";";
     
    963984                        // cast the top-level expression to void to reduce gcc warnings.
    964985                        Expression * expr = new CastExpr( forStmt->get_increment() );
    965                         expr->accept( *this );
     986                        expr->accept( *visitor );
    966987                } // if
    967988                output << ") ";
     
    969990                if ( forStmt->get_body() != 0 ) {
    970991                        output << CodeGenerator::printLabels( forStmt->get_body()->get_labels() );
    971                         forStmt->get_body()->accept( *this );
    972                 } // if
    973         }
    974 
    975         void CodeGenerator::visit( __attribute__((unused)) NullStmt * nullStmt ) {
     992                        forStmt->get_body()->accept( *visitor );
     993                } // if
     994        }
     995
     996        void CodeGenerator::postvisit( __attribute__((unused)) NullStmt * nullStmt ) {
    976997                //output << indent << CodeGenerator::printLabels( nullStmt->get_labels() );
    977998                output << "/* null statement */ ;";
    978999        }
    9791000
    980         void CodeGenerator::visit( DeclStmt * declStmt ) {
    981                 declStmt->get_decl()->accept( *this );
     1001        void CodeGenerator::postvisit( DeclStmt * declStmt ) {
     1002                declStmt->get_decl()->accept( *visitor );
    9821003
    9831004                if ( doSemicolon( declStmt->get_decl() ) ) {
    9841005                        output << ";";
    9851006                } // if
     1007        }
     1008
     1009        void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) {
     1010                assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." );
     1011                stmt->callStmt->accept( *visitor );
    9861012        }
    9871013
  • src/CodeGen/CodeGenerator.h

    r764e009 rf980549  
    2121
    2222#include "Common/Indenter.h"      // for Indenter
     23#include "Common/PassVisitor.h"   // for PassVisitor
    2324#include "SynTree/Declaration.h"  // for DeclarationWithType (ptr only), Fun...
    2425#include "SynTree/Visitor.h"      // for Visitor
     
    2627
    2728namespace CodeGen {
    28         class CodeGenerator : public Visitor {
    29           public:
    30                 static int tabsize;
     29        struct CodeGenerator : public WithShortCircuiting, public WithVisitorRef<CodeGenerator> {
     30          static int tabsize;
    3131
    3232                CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false, bool lineMarks = false );
    33                 CodeGenerator( std::ostream &os, std::string, int indent = 0, bool infun = false );
    34                 CodeGenerator( std::ostream &os, char *, int indent = 0, bool infun = false );
     33
     34                //*** Turn off visit_children for all nodes
     35                void previsit( BaseSyntaxNode * );
     36
     37                //*** Error for unhandled node types
     38                void postvisit( BaseSyntaxNode * );
    3539
    3640                //*** Declaration
    37                 virtual void visit( StructDecl * );
    38                 virtual void visit( FunctionDecl * );
    39                 virtual void visit( ObjectDecl * );
    40                 virtual void visit( UnionDecl *aggregateDecl );
    41                 virtual void visit( EnumDecl *aggregateDecl );
    42                 virtual void visit( TraitDecl *aggregateDecl );
    43                 virtual void visit( TypedefDecl *typeDecl );
    44                 virtual void visit( TypeDecl *typeDecl );
     41                void postvisit( StructDecl * );
     42                void postvisit( FunctionDecl * );
     43                void postvisit( ObjectDecl * );
     44                void postvisit( UnionDecl *aggregateDecl );
     45                void postvisit( EnumDecl *aggregateDecl );
     46                void postvisit( TraitDecl *aggregateDecl );
     47                void postvisit( TypedefDecl *typeDecl );
     48                void postvisit( TypeDecl *typeDecl );
    4549
    4650                //*** Initializer
    47                 virtual void visit( Designation * );
    48                 virtual void visit( SingleInit * );
    49                 virtual void visit( ListInit * );
    50                 virtual void visit( ConstructorInit * );
     51                void postvisit( Designation * );
     52                void postvisit( SingleInit * );
     53                void postvisit( ListInit * );
     54                void postvisit( ConstructorInit * );
    5155
    5256                //*** Constant
    53                 virtual void visit( Constant * );
     57                void postvisit( Constant * );
    5458
    5559                //*** Expression
    56                 virtual void visit( ApplicationExpr *applicationExpr );
    57                 virtual void visit( UntypedExpr *untypedExpr );
    58                 virtual void visit( RangeExpr * rangeExpr );
    59                 virtual void visit( NameExpr *nameExpr );
    60                 virtual void visit( AddressExpr *addressExpr );
    61                 virtual void visit( LabelAddressExpr *addressExpr );
    62                 virtual void visit( CastExpr *castExpr );
    63                 virtual void visit( VirtualCastExpr *castExpr );
    64                 virtual void visit( UntypedMemberExpr *memberExpr );
    65                 virtual void visit( MemberExpr *memberExpr );
    66                 virtual void visit( VariableExpr *variableExpr );
    67                 virtual void visit( ConstantExpr *constantExpr );
    68                 virtual void visit( SizeofExpr *sizeofExpr );
    69                 virtual void visit( AlignofExpr *alignofExpr );
    70                 virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    71                 virtual void visit( OffsetofExpr *offsetofExpr );
    72                 virtual void visit( OffsetPackExpr *offsetPackExpr );
    73                 virtual void visit( LogicalExpr *logicalExpr );
    74                 virtual void visit( ConditionalExpr *conditionalExpr );
    75                 virtual void visit( CommaExpr *commaExpr );
    76                 virtual void visit( CompoundLiteralExpr *compLitExpr );
    77                 virtual void visit( UniqueExpr * );
    78                 virtual void visit( TupleAssignExpr * tupleExpr );
    79                 virtual void visit( UntypedTupleExpr *tupleExpr );
    80                 virtual void visit( TupleExpr *tupleExpr );
    81                 virtual void visit( TupleIndexExpr * tupleExpr );
    82                 virtual void visit( TypeExpr *typeExpr );
    83                 virtual void visit( AsmExpr * );
    84                 virtual void visit( StmtExpr * );
     60                void postvisit( ApplicationExpr *applicationExpr );
     61                void postvisit( UntypedExpr *untypedExpr );
     62                void postvisit( RangeExpr * rangeExpr );
     63                void postvisit( NameExpr *nameExpr );
     64                void postvisit( AddressExpr *addressExpr );
     65                void postvisit( LabelAddressExpr *addressExpr );
     66                void postvisit( CastExpr *castExpr );
     67                void postvisit( VirtualCastExpr *castExpr );
     68                void postvisit( UntypedMemberExpr *memberExpr );
     69                void postvisit( MemberExpr *memberExpr );
     70                void postvisit( VariableExpr *variableExpr );
     71                void postvisit( ConstantExpr *constantExpr );
     72                void postvisit( SizeofExpr *sizeofExpr );
     73                void postvisit( AlignofExpr *alignofExpr );
     74                void postvisit( UntypedOffsetofExpr *offsetofExpr );
     75                void postvisit( OffsetofExpr *offsetofExpr );
     76                void postvisit( OffsetPackExpr *offsetPackExpr );
     77                void postvisit( LogicalExpr *logicalExpr );
     78                void postvisit( ConditionalExpr *conditionalExpr );
     79                void postvisit( CommaExpr *commaExpr );
     80                void postvisit( CompoundLiteralExpr *compLitExpr );
     81                void postvisit( UniqueExpr * );
     82                void postvisit( TupleAssignExpr * tupleExpr );
     83                void postvisit( UntypedTupleExpr *tupleExpr );
     84                void postvisit( TupleExpr *tupleExpr );
     85                void postvisit( TupleIndexExpr * tupleExpr );
     86                void postvisit( TypeExpr *typeExpr );
     87                void postvisit( AsmExpr * );
     88                void postvisit( StmtExpr * );
     89                void postvisit( ConstructorExpr * );
    8590
    8691                //*** Statements
    87                 virtual void visit( CompoundStmt * );
    88                 virtual void visit( ExprStmt * );
    89                 virtual void visit( AsmStmt * );
    90                 virtual void visit( AsmDecl * );                                // special: statement in declaration context
    91                 virtual void visit( IfStmt * );
    92                 virtual void visit( SwitchStmt * );
    93                 virtual void visit( CaseStmt * );
    94                 virtual void visit( BranchStmt * );
    95                 virtual void visit( ReturnStmt * );
    96                 virtual void visit( ThrowStmt * );
    97                 virtual void visit( WhileStmt * );
    98                 virtual void visit( ForStmt * );
    99                 virtual void visit( NullStmt * );
    100                 virtual void visit( DeclStmt * );
     92                void postvisit( CompoundStmt * );
     93                void postvisit( ExprStmt * );
     94                void postvisit( AsmStmt * );
     95                void postvisit( AsmDecl * );                            // special: statement in declaration context
     96                void postvisit( IfStmt * );
     97                void postvisit( SwitchStmt * );
     98                void postvisit( CaseStmt * );
     99                void postvisit( BranchStmt * );
     100                void postvisit( ReturnStmt * );
     101                void postvisit( ThrowStmt * );
     102                void postvisit( WhileStmt * );
     103                void postvisit( ForStmt * );
     104                void postvisit( NullStmt * );
     105                void postvisit( DeclStmt * );
     106                void postvisit( ImplicitCtorDtorStmt * );
    101107
    102108                void genAttributes( std::list< Attribute * > & attributes );
     
    117123
    118124                void updateLocation( BaseSyntaxNode const * to );
     125                struct LineEnder {
     126                        CodeGenerator & cg;
     127                        LineEnder( CodeGenerator & cg ) : cg( cg ) {}
     128                        std::ostream & operator()(std::ostream &) const;
     129                };
    119130          private:
    120131                Indenter indent;
    121                 bool insideFunction;
    122                 std::ostream &output;
     132                std::ostream & output;
    123133                LabelPrinter printLabels;
    124134                bool pretty = false;  // pretty print
    125135                bool genC = false;    // true if output has to be C code
    126136                bool lineMarks = false;
     137        public:
     138                LineEnder endl;
     139        private:
    127140
    128141                CodeLocation currentLocation;
    129142                void updateLocation( CodeLocation const & to );
    130                 void nextLine();
    131143
    132144                void handleStorageClass( DeclarationWithType *decl );
     
    140152          if ( begin == end ) return;
    141153                for ( ;; ) {
    142                         (*begin++)->accept( *this );
     154                        (*begin++)->accept( *visitor );
    143155                  if ( begin == end ) break;
    144156                        output << ", ";                                                         // separator
     
    155167        /// returns C-compatible name of declaration
    156168        std::string genName( DeclarationWithType * decl );
     169
     170        inline std::ostream & operator<<( std::ostream & os, const CodeGenerator::LineEnder & endl ) {
     171                return endl( os );
     172        }
    157173} // namespace CodeGen
    158174
  • src/CodeGen/GenType.cc

    r764e009 rf980549  
    6363
    6464                if ( ! type->get_attributes().empty() ) {
    65                         CodeGenerator cg( os, pretty, genC, lineMarks );
    66                         cg.genAttributes( type->get_attributes() );
     65                        PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     66                        cg.pass.genAttributes( type->get_attributes() );
    6767                } // if
    6868
     
    116116                } // if
    117117                if ( dimension != 0 ) {
    118                         CodeGenerator cg( os, pretty, genC, lineMarks );
     118                        PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
    119119                        dimension->accept( cg );
    120120                } else if ( isVarLen ) {
     
    178178                        } // if
    179179                } else {
    180                         CodeGenerator cg( os, pretty, genC, lineMarks );
     180                        PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
    181181                        os << "(" ;
    182182
    183                         cg.genCommaList( pars.begin(), pars.end() );
     183                        cg.pass.genCommaList( pars.begin(), pars.end() );
    184184
    185185                        if ( funcType->get_isVarArgs() ) {
     
    201201                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    202202                        std::ostringstream os;
    203                         CodeGenerator cg( os, pretty, genC, lineMarks );
     203                        PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
    204204                        os << "forall(";
    205                         cg.genCommaList( funcType->get_forall().begin(), funcType->get_forall().end() );
     205                        cg.pass.genCommaList( funcType->get_forall().begin(), funcType->get_forall().end() );
    206206                        os << ")" << std::endl;
    207207                        typeString = os.str() + typeString;
     
    212212                if ( ! refType->get_parameters().empty() ) {
    213213                        std::ostringstream os;
    214                         CodeGenerator cg( os, pretty, genC, lineMarks );
     214                        PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
    215215                        os << "(";
    216                         cg.genCommaList( refType->get_parameters().begin(), refType->get_parameters().end() );
     216                        cg.pass.genCommaList( refType->get_parameters().begin(), refType->get_parameters().end() );
    217217                        os << ") ";
    218218                        return os.str();
  • src/CodeGen/Generate.cc

    r764e009 rf980549  
    3333                /// Removes misc. nodes that should not exist in CodeGen
    3434                struct TreeCleaner {
    35                         void previsit( CompoundStmt * stmt );
     35                        void premutate( CompoundStmt * stmt );
     36                        Statement * postmutate( ImplicitCtorDtorStmt * stmt );
    3637
    3738                        static bool shouldClean( Declaration * );
     
    4142                        PassVisitor<TreeCleaner> cleaner;
    4243                        filter( translationUnit, [](Declaration * decl) { return TreeCleaner::shouldClean(decl); }, false );
    43                         acceptAll( translationUnit, cleaner );
     44                        mutateAll( translationUnit, cleaner );
    4445                } // cleanTree
    4546        } // namespace
     
    4849                cleanTree( translationUnit );
    4950
    50                 CodeGen::CodeGenerator cgv( os, pretty, generateC, lineMarks );
     51                PassVisitor<CodeGenerator> cgv( os, pretty, generateC, lineMarks );
    5152                for ( auto & dcl : translationUnit ) {
    5253                        if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) {
    53                                 cgv.updateLocation( dcl );
     54                                cgv.pass.updateLocation( dcl );
    5455                                dcl->accept(cgv);
    5556                                if ( doSemicolon( dcl ) ) {
    5657                                        os << ";";
    5758                                } // if
    58                                 os << std::endl;
     59                                os << cgv.pass.endl;
    5960                        } // if
    6061                } // for
     
    6566                        os << CodeGen::genPrettyType( type, "" );
    6667                } else {
    67                         CodeGen::CodeGenerator cgv( os, true, false, false );
     68                        PassVisitor<CodeGenerator> cgv( os, true, false, false );
    6869                        node->accept( cgv );
    6970                }
     
    7273
    7374        namespace {
    74                 void TreeCleaner::previsit( CompoundStmt * cstmt ) {
     75                void TreeCleaner::premutate( CompoundStmt * cstmt ) {
    7576                        filter( cstmt->kids, [](Statement * stmt) {
    7677                                if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
     
    7980                                return false;
    8081                        }, false );
     82                }
     83
     84                Statement * TreeCleaner::postmutate( ImplicitCtorDtorStmt * stmt ) {
     85                        Statement * callStmt = nullptr;
     86                        std::swap( stmt->callStmt, callStmt );
     87                        delete stmt;
     88                        return callStmt;
    8189                }
    8290
Note: See TracChangeset for help on using the changeset viewer.