Changeset 9857e8d


Ignore:
Timestamp:
Sep 18, 2017, 1:25:03 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
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:
698ec72
Parents:
acdfb45
Message:

Convert CodeGenerator? to PassVisitor?

Location:
src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    racdfb45 r9857e8d  
    139139        } // CodeGenerator::genAttributes
    140140
     141        // *** BaseSyntaxNode
     142        void CodeGenerator::previsit( BaseSyntaxNode * ) {
     143                // turn off automatic recursion for all nodes, to allow each visitor to
     144                // precisely control the order in which its children are visited.
     145                visit_children = false;
     146        }
     147
     148        // *** BaseSyntaxNode
     149        void CodeGenerator::postvisit( BaseSyntaxNode * node ) {
     150                std::stringstream ss;
     151                node->print( ss );
     152                assertf( false, "Unhandled node reached in CodeGenerator: %s", ss.str().c_str() );
     153        }
    141154
    142155        // *** Declarations
    143         void CodeGenerator::visit( FunctionDecl * functionDecl ) {
     156        void CodeGenerator::postvisit( FunctionDecl * functionDecl ) {
    144157                extension( functionDecl );
    145158                genAttributes( functionDecl->get_attributes() );
     
    152165                asmName( functionDecl );
    153166
    154                 // acceptAll( functionDecl->get_oldDecls(), *this );
     167                // acceptAll( functionDecl->get_oldDecls(), *visitor );
    155168                if ( functionDecl->get_statements() ) {
    156                         functionDecl->get_statements()->accept( *this );
    157                 } // if
    158         }
    159 
    160         void CodeGenerator::visit( ObjectDecl * objectDecl ) {
     169                        functionDecl->get_statements()->accept( *visitor );
     170                } // if
     171        }
     172
     173        void CodeGenerator::postvisit( ObjectDecl * objectDecl ) {
    161174                if (objectDecl->get_name().empty() && genC ) {
    162175                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
     
    175188                if ( objectDecl->get_init() ) {
    176189                        output << " = ";
    177                         objectDecl->get_init()->accept( *this );
     190                        objectDecl->get_init()->accept( *visitor );
    178191                } // if
    179192
    180193                if ( objectDecl->get_bitfieldWidth() ) {
    181194                        output << ":";
    182                         objectDecl->get_bitfieldWidth()->accept( *this );
     195                        objectDecl->get_bitfieldWidth()->accept( *visitor );
    183196                } // if
    184197        }
     
    205218                                updateLocation( *i );
    206219                                output << indent;
    207                                 (*i)->accept( *this );
     220                                (*i)->accept( *visitor );
    208221                                output << ";" << endl;
    209222                        } // for
     
    215228        }
    216229
    217         void CodeGenerator::visit( StructDecl * structDecl ) {
     230        void CodeGenerator::postvisit( StructDecl * structDecl ) {
    218231                extension( structDecl );
    219232                handleAggregate( structDecl, "struct " );
    220233        }
    221234
    222         void CodeGenerator::visit( UnionDecl * unionDecl ) {
     235        void CodeGenerator::postvisit( UnionDecl * unionDecl ) {
    223236                extension( unionDecl );
    224237                handleAggregate( unionDecl, "union " );
    225238        }
    226239
    227         void CodeGenerator::visit( EnumDecl * enumDecl ) {
     240        void CodeGenerator::postvisit( EnumDecl * enumDecl ) {
    228241                extension( enumDecl );
    229242                updateLocation( enumDecl );
     
    246259                                if ( obj->get_init() ) {
    247260                                        output << " = ";
    248                                         obj->get_init()->accept( *this );
     261                                        obj->get_init()->accept( *visitor );
    249262                                } // if
    250263                                output << "," << endl;
     
    257270        }
    258271
    259         void CodeGenerator::visit( TraitDecl * traitDecl ) {
     272        void CodeGenerator::postvisit( TraitDecl * traitDecl ) {
    260273                assertf( ! genC, "TraitDecls should not reach code generation." );
    261274                extension( traitDecl );
     
    263276        }
    264277
    265         void CodeGenerator::visit( TypedefDecl * typeDecl ) {
     278        void CodeGenerator::postvisit( TypedefDecl * typeDecl ) {
    266279                assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
    267280                updateLocation( typeDecl );
     
    270283        }
    271284
    272         void CodeGenerator::visit( TypeDecl * typeDecl ) {
     285        void CodeGenerator::postvisit( TypeDecl * typeDecl ) {
    273286                assertf( ! genC, "TypeDecls should not reach code generation." );
    274287                output << typeDecl->genTypeString() << " " << typeDecl->get_name();
     
    283296        }
    284297
    285         void CodeGenerator::visit( Designation * designation ) {
     298        void CodeGenerator::postvisit( Designation * designation ) {
    286299                std::list< Expression * > designators = designation->get_designators();
    287300                if ( designators.size() == 0 ) return;
     
    290303                                // if expression is a NameExpr or VariableExpr, then initializing aggregate member
    291304                                output << ".";
    292                                 des->accept( *this );
     305                                des->accept( *visitor );
    293306                        } else {
    294307                                // otherwise, it has to be a ConstantExpr or CastExpr, initializing array eleemnt
    295308                                output << "[";
    296                                 des->accept( *this );
     309                                des->accept( *visitor );
    297310                                output << "]";
    298311                        } // if
     
    301314        }
    302315
    303         void CodeGenerator::visit( SingleInit * init ) {
    304                 init->get_value()->accept( *this );
    305         }
    306 
    307         void CodeGenerator::visit( ListInit * init ) {
     316        void CodeGenerator::postvisit( SingleInit * init ) {
     317                init->get_value()->accept( *visitor );
     318        }
     319
     320        void CodeGenerator::postvisit( ListInit * init ) {
    308321                auto initBegin = init->begin();
    309322                auto initEnd = init->end();
     
    313326                output << "{ ";
    314327                for ( ; initBegin != initEnd && desigBegin != desigEnd; ) {
    315                         (*desigBegin)->accept( *this );
    316                         (*initBegin)->accept( *this );
     328                        (*desigBegin)->accept( *visitor );
     329                        (*initBegin)->accept( *visitor );
    317330                        ++initBegin, ++desigBegin;
    318331                        if ( initBegin != initEnd ) {
     
    324337        }
    325338
    326         void CodeGenerator::visit( __attribute__((unused)) ConstructorInit * init ){
     339        void CodeGenerator::postvisit( __attribute__((unused)) ConstructorInit * init ){
    327340                assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
    328341                // pseudo-output for constructor/destructor pairs
    329342                output << "<ctorinit>{" << std::endl << ++indent << "ctor: ";
    330                 maybeAccept( init->get_ctor(), *this );
     343                maybeAccept( init->get_ctor(), *visitor );
    331344                output << ", " << std::endl << indent << "dtor: ";
    332                 maybeAccept( init->get_dtor(), *this );
     345                maybeAccept( init->get_dtor(), *visitor );
    333346                output << std::endl << --indent << "}";
    334347        }
    335348
    336         void CodeGenerator::visit( Constant * constant ) {
     349        void CodeGenerator::postvisit( Constant * constant ) {
    337350                output << constant->get_value() ;
    338351        }
    339352
    340353        // *** Expressions
    341         void CodeGenerator::visit( ApplicationExpr * applicationExpr ) {
     354        void CodeGenerator::postvisit( ApplicationExpr * applicationExpr ) {
    342355                extension( applicationExpr );
    343356                if ( VariableExpr * varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
     
    348361                                  case OT_INDEX:
    349362                                        assert( applicationExpr->get_args().size() == 2 );
    350                                         (*arg++)->accept( *this );
     363                                        (*arg++)->accept( *visitor );
    351364                                        output << "[";
    352                                         (*arg)->accept( *this );
     365                                        (*arg)->accept( *visitor );
    353366                                        output << "]";
    354367                                        break;
     
    365378                                                // effects, so must still output this expression
    366379                                                output << "(";
    367                                                 (*arg++)->accept( *this );
     380                                                (*arg++)->accept( *visitor );
    368381                                                output << ") /* " << opInfo.inputName << " */";
    369382                                        } else if ( applicationExpr->get_args().size() == 2 ) {
    370383                                                // intrinsic two parameter constructors are essentially bitwise assignment
    371384                                                output << "(";
    372                                                 (*arg++)->accept( *this );
     385                                                (*arg++)->accept( *visitor );
    373386                                                output << opInfo.symbol;
    374                                                 (*arg)->accept( *this );
     387                                                (*arg)->accept( *visitor );
    375388                                                output << ") /* " << opInfo.inputName << " */";
    376389                                        } else {
     
    385398                                        output << "(";
    386399                                        output << opInfo.symbol;
    387                                         (*arg)->accept( *this );
     400                                        (*arg)->accept( *visitor );
    388401                                        output << ")";
    389402                                        break;
     
    392405                                  case OT_POSTFIXASSIGN:
    393406                                        assert( applicationExpr->get_args().size() == 1 );
    394                                         (*arg)->accept( *this );
     407                                        (*arg)->accept( *visitor );
    395408                                        output << opInfo.symbol;
    396409                                        break;
     
    401414                                        assert( applicationExpr->get_args().size() == 2 );
    402415                                        output << "(";
    403                                         (*arg++)->accept( *this );
     416                                        (*arg++)->accept( *visitor );
    404417                                        output << opInfo.symbol;
    405                                         (*arg)->accept( *this );
     418                                        (*arg)->accept( *visitor );
    406419                                        output << ")";
    407420                                        break;
     
    413426                                } // switch
    414427                        } else {
    415                                 varExpr->accept( *this );
     428                                varExpr->accept( *visitor );
    416429                                output << "(";
    417430                                genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
     
    419432                        } // if
    420433                } else {
    421                         applicationExpr->get_function()->accept( *this );
     434                        applicationExpr->get_function()->accept( *visitor );
    422435                        output << "(";
    423436                        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
     
    426439        }
    427440
    428         void CodeGenerator::visit( UntypedExpr * untypedExpr ) {
     441        void CodeGenerator::postvisit( UntypedExpr * untypedExpr ) {
    429442                extension( untypedExpr );
    430443                if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     
    435448                                  case OT_INDEX:
    436449                                        assert( untypedExpr->get_args().size() == 2 );
    437                                         (*arg++)->accept( *this );
     450                                        (*arg++)->accept( *visitor );
    438451                                        output << "[";
    439                                         (*arg)->accept( *this );
     452                                        (*arg)->accept( *visitor );
    440453                                        output << "]";
    441454                                        break;
     
    450463                                                // effects, so must still output this expression
    451464                                                output << "(";
    452                                                 (*arg++)->accept( *this );
     465                                                (*arg++)->accept( *visitor );
    453466                                                output << ") /* " << opInfo.inputName << " */";
    454467                                        } else if ( untypedExpr->get_args().size() == 2 ) {
    455468                                                // intrinsic two parameter constructors are essentially bitwise assignment
    456469                                                output << "(";
    457                                                 (*arg++)->accept( *this );
     470                                                (*arg++)->accept( *visitor );
    458471                                                output << opInfo.symbol;
    459                                                 (*arg)->accept( *this );
     472                                                (*arg)->accept( *visitor );
    460473                                                output << ") /* " << opInfo.inputName << " */";
    461474                                        } else {
     
    471484                                        output << "(";
    472485                                        output << opInfo.symbol;
    473                                         (*arg)->accept( *this );
     486                                        (*arg)->accept( *visitor );
    474487                                        output << ")";
    475488                                        break;
     
    478491                                  case OT_POSTFIXASSIGN:
    479492                                        assert( untypedExpr->get_args().size() == 1 );
    480                                         (*arg)->accept( *this );
     493                                        (*arg)->accept( *visitor );
    481494                                        output << opInfo.symbol;
    482495                                        break;
     
    486499                                        assert( untypedExpr->get_args().size() == 2 );
    487500                                        output << "(";
    488                                         (*arg++)->accept( *this );
     501                                        (*arg++)->accept( *visitor );
    489502                                        output << opInfo.symbol;
    490                                         (*arg)->accept( *this );
     503                                        (*arg)->accept( *visitor );
    491504                                        output << ")";
    492505                                        break;
     
    499512                                if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2
    500513                                        assert( untypedExpr->get_args().size() == 2 );
    501                                         (*untypedExpr->get_args().begin())->accept( *this );
     514                                        (*untypedExpr->get_args().begin())->accept( *visitor );
    502515                                        output << " ... ";
    503                                         (*--untypedExpr->get_args().end())->accept( *this );
     516                                        (*--untypedExpr->get_args().end())->accept( *visitor );
    504517                                } else {                                                                // builtin routines
    505                                         nameExpr->accept( *this );
     518                                        nameExpr->accept( *visitor );
    506519                                        output << "(";
    507520                                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
     
    510523                        } // if
    511524                } else {
    512                         untypedExpr->get_function()->accept( *this );
     525                        untypedExpr->get_function()->accept( *visitor );
    513526                        output << "(";
    514527                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
     
    517530        }
    518531
    519         void CodeGenerator::visit( RangeExpr * rangeExpr ) {
    520                 rangeExpr->get_low()->accept( *this );
     532        void CodeGenerator::postvisit( RangeExpr * rangeExpr ) {
     533                rangeExpr->get_low()->accept( *visitor );
    521534                output << " ... ";
    522                 rangeExpr->get_high()->accept( *this );
    523         }
    524 
    525         void CodeGenerator::visit( NameExpr * nameExpr ) {
     535                rangeExpr->get_high()->accept( *visitor );
     536        }
     537
     538        void CodeGenerator::postvisit( NameExpr * nameExpr ) {
    526539                extension( nameExpr );
    527540                OperatorInfo opInfo;
     
    534547        }
    535548
    536         void CodeGenerator::visit( AddressExpr * addressExpr ) {
     549        void CodeGenerator::postvisit( AddressExpr * addressExpr ) {
    537550                extension( addressExpr );
    538551                output << "(&";
    539                 addressExpr->arg->accept( *this );
     552                addressExpr->arg->accept( *visitor );
    540553                output << ")";
    541554        }
    542555
    543         void CodeGenerator::visit( LabelAddressExpr *addressExpr ) {
     556        void CodeGenerator::postvisit( LabelAddressExpr *addressExpr ) {
    544557                extension( addressExpr );
    545558                output << "(&&" << addressExpr->arg << ")";
    546559        }
    547560
    548         void CodeGenerator::visit( CastExpr * castExpr ) {
     561        void CodeGenerator::postvisit( CastExpr * castExpr ) {
    549562                extension( castExpr );
    550563                output << "(";
     
    559572                        output << ")";
    560573                } // if
    561                 castExpr->get_arg()->accept( *this );
     574                castExpr->get_arg()->accept( *visitor );
    562575                output << ")";
    563576        }
    564577
    565         void CodeGenerator::visit( VirtualCastExpr * castExpr ) {
     578        void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) {
    566579                assertf( ! genC, "VirtualCastExpr should not reach code generation." );
    567580                extension( castExpr );
    568581                output << "(virtual ";
    569                 castExpr->get_arg()->accept( *this );
     582                castExpr->get_arg()->accept( *visitor );
    570583                output << ")";
    571584        }
    572585
    573         void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) {
     586        void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) {
    574587                assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
    575588                extension( memberExpr );
    576                 memberExpr->get_aggregate()->accept( *this );
     589                memberExpr->get_aggregate()->accept( *visitor );
    577590                output << ".";
    578                 memberExpr->get_member()->accept( *this );
    579         }
    580 
    581         void CodeGenerator::visit( MemberExpr * memberExpr ) {
     591                memberExpr->get_member()->accept( *visitor );
     592        }
     593
     594        void CodeGenerator::postvisit( MemberExpr * memberExpr ) {
    582595                extension( memberExpr );
    583                 memberExpr->get_aggregate()->accept( *this );
     596                memberExpr->get_aggregate()->accept( *visitor );
    584597                output << "." << mangleName( memberExpr->get_member() );
    585598        }
    586599
    587         void CodeGenerator::visit( VariableExpr * variableExpr ) {
     600        void CodeGenerator::postvisit( VariableExpr * variableExpr ) {
    588601                extension( variableExpr );
    589602                OperatorInfo opInfo;
     
    595608        }
    596609
    597         void CodeGenerator::visit( ConstantExpr * constantExpr ) {
     610        void CodeGenerator::postvisit( ConstantExpr * constantExpr ) {
    598611                assert( constantExpr->get_constant() );
    599612                extension( constantExpr );
    600                 constantExpr->get_constant()->accept( *this );
    601         }
    602 
    603         void CodeGenerator::visit( SizeofExpr * sizeofExpr ) {
     613                constantExpr->get_constant()->accept( *visitor );
     614        }
     615
     616        void CodeGenerator::postvisit( SizeofExpr * sizeofExpr ) {
    604617                extension( sizeofExpr );
    605618                output << "sizeof(";
     
    607620                        output << genType( sizeofExpr->get_type(), "", pretty, genC );
    608621                } else {
    609                         sizeofExpr->get_expr()->accept( *this );
     622                        sizeofExpr->get_expr()->accept( *visitor );
    610623                } // if
    611624                output << ")";
    612625        }
    613626
    614         void CodeGenerator::visit( AlignofExpr * alignofExpr ) {
     627        void CodeGenerator::postvisit( AlignofExpr * alignofExpr ) {
    615628                // use GCC extension to avoid bumping std to C11
    616629                extension( alignofExpr );
     
    619632                        output << genType( alignofExpr->get_type(), "", pretty, genC );
    620633                } else {
    621                         alignofExpr->get_expr()->accept( *this );
     634                        alignofExpr->get_expr()->accept( *visitor );
    622635                } // if
    623636                output << ")";
    624637        }
    625638
    626         void CodeGenerator::visit( UntypedOffsetofExpr * offsetofExpr ) {
     639        void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) {
    627640                assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );
    628641                output << "offsetof(";
     
    632645        }
    633646
    634         void CodeGenerator::visit( OffsetofExpr * offsetofExpr ) {
     647        void CodeGenerator::postvisit( OffsetofExpr * offsetofExpr ) {
    635648                // use GCC builtin
    636649                output << "__builtin_offsetof(";
     
    640653        }
    641654
    642         void CodeGenerator::visit( OffsetPackExpr * offsetPackExpr ) {
     655        void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) {
    643656                assertf( ! genC, "OffsetPackExpr should not reach code generation." );
    644657                output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")";
    645658        }
    646659
    647         void CodeGenerator::visit( LogicalExpr * logicalExpr ) {
     660        void CodeGenerator::postvisit( LogicalExpr * logicalExpr ) {
    648661                extension( logicalExpr );
    649662                output << "(";
    650                 logicalExpr->get_arg1()->accept( *this );
     663                logicalExpr->get_arg1()->accept( *visitor );
    651664                if ( logicalExpr->get_isAnd() ) {
    652665                        output << " && ";
     
    654667                        output << " || ";
    655668                } // if
    656                 logicalExpr->get_arg2()->accept( *this );
     669                logicalExpr->get_arg2()->accept( *visitor );
    657670                output << ")";
    658671        }
    659672
    660         void CodeGenerator::visit( ConditionalExpr * conditionalExpr ) {
     673        void CodeGenerator::postvisit( ConditionalExpr * conditionalExpr ) {
    661674                extension( conditionalExpr );
    662675                output << "(";
    663                 conditionalExpr->get_arg1()->accept( *this );
     676                conditionalExpr->get_arg1()->accept( *visitor );
    664677                output << " ? ";
    665                 conditionalExpr->get_arg2()->accept( *this );
     678                conditionalExpr->get_arg2()->accept( *visitor );
    666679                output << " : ";
    667                 conditionalExpr->get_arg3()->accept( *this );
     680                conditionalExpr->get_arg3()->accept( *visitor );
    668681                output << ")";
    669682        }
    670683
    671         void CodeGenerator::visit( CommaExpr * commaExpr ) {
     684        void CodeGenerator::postvisit( CommaExpr * commaExpr ) {
    672685                extension( commaExpr );
    673686                output << "(";
     
    676689                        commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );
    677690                }
    678                 commaExpr->get_arg1()->accept( *this );
     691                commaExpr->get_arg1()->accept( *visitor );
    679692                output << " , ";
    680                 commaExpr->get_arg2()->accept( *this );
     693                commaExpr->get_arg2()->accept( *visitor );
    681694                output << ")";
    682695        }
    683696
    684         void CodeGenerator::visit( TupleAssignExpr * tupleExpr ) {
     697        void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) {
    685698                assertf( ! genC, "TupleAssignExpr should not reach code generation." );
    686                 tupleExpr->stmtExpr->accept( *this );
    687         }
    688 
    689         void CodeGenerator::visit( UntypedTupleExpr * tupleExpr ) {
     699                tupleExpr->stmtExpr->accept( *visitor );
     700        }
     701
     702        void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) {
    690703                assertf( ! genC, "UntypedTupleExpr should not reach code generation." );
    691704                extension( tupleExpr );
     
    695708        }
    696709
    697         void CodeGenerator::visit( TupleExpr * tupleExpr ) {
     710        void CodeGenerator::postvisit( TupleExpr * tupleExpr ) {
    698711                assertf( ! genC, "TupleExpr should not reach code generation." );
    699712                extension( tupleExpr );
     
    703716        }
    704717
    705         void CodeGenerator::visit( TupleIndexExpr * tupleExpr ) {
     718        void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) {
    706719                assertf( ! genC, "TupleIndexExpr should not reach code generation." );
    707720                extension( tupleExpr );
    708                 tupleExpr->get_tuple()->accept( *this );
     721                tupleExpr->get_tuple()->accept( *visitor );
    709722                output << "." << tupleExpr->get_index();
    710723        }
    711724
    712         void CodeGenerator::visit( TypeExpr * typeExpr ) {
     725        void CodeGenerator::postvisit( TypeExpr * typeExpr ) {
    713726                // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
    714727                // assertf( ! genC, "TypeExpr should not reach code generation." );
     
    718731        }
    719732
    720         void CodeGenerator::visit( AsmExpr * asmExpr ) {
     733        void CodeGenerator::postvisit( AsmExpr * asmExpr ) {
    721734                if ( asmExpr->get_inout() ) {
    722735                        output << "[ ";
    723                         asmExpr->get_inout()->accept( *this );
     736                        asmExpr->get_inout()->accept( *visitor );
    724737                        output << " ] ";
    725738                } // if
    726                 asmExpr->get_constraint()->accept( *this );
     739                asmExpr->get_constraint()->accept( *visitor );
    727740                output << " ( ";
    728                 asmExpr->get_operand()->accept( *this );
     741                asmExpr->get_operand()->accept( *visitor );
    729742                output << " )";
    730743        }
    731744
    732         void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) {
     745        void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) {
    733746                assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    734747                output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")";
    735                 compLitExpr->get_initializer()->accept( *this );
    736         }
    737 
    738         void CodeGenerator::visit( UniqueExpr * unqExpr ) {
     748                compLitExpr->get_initializer()->accept( *visitor );
     749        }
     750
     751        void CodeGenerator::postvisit( UniqueExpr * unqExpr ) {
    739752                assertf( ! genC, "Unique expressions should not reach code generation." );
    740753                output << "unq<" << unqExpr->get_id() << ">{ ";
    741                 unqExpr->get_expr()->accept( *this );
     754                unqExpr->get_expr()->accept( *visitor );
    742755                output << " }";
    743756        }
    744757
    745         void CodeGenerator::visit( StmtExpr * stmtExpr ) {
     758        void CodeGenerator::postvisit( StmtExpr * stmtExpr ) {
    746759                std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    747760                updateLocation( stmtExpr );
     
    757770                                // cannot cast to void, otherwise the expression statement has no value
    758771                                if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
    759                                         exprStmt->get_expr()->accept( *this );
     772                                        exprStmt->get_expr()->accept( *visitor );
    760773                                        output << ";" << endl;
    761774                                        ++i;
     
    763776                                }
    764777                        }
    765                         stmt->accept( *this );
     778                        stmt->accept( *visitor );
    766779                        output << endl;
    767780                        if ( wantSpacing( stmt ) ) {
     
    775788
    776789        // *** Statements
    777         void CodeGenerator::visit( CompoundStmt * compoundStmt ) {
     790        void CodeGenerator::postvisit( CompoundStmt * compoundStmt ) {
    778791                std::list<Statement*> ks = compoundStmt->get_kids();
    779792                output << "{" << endl;
     
    783796                for ( std::list<Statement *>::iterator i = ks.begin(); i != ks.end();  i++ ) {
    784797                        output << indent << printLabels( (*i)->get_labels() );
    785                         (*i)->accept( *this );
     798                        (*i)->accept( *visitor );
    786799
    787800                        output << endl;
     
    795808        }
    796809
    797         void CodeGenerator::visit( ExprStmt * exprStmt ) {
     810        void CodeGenerator::postvisit( ExprStmt * exprStmt ) {
    798811                assert( exprStmt );
    799812                if ( genC ) {
     
    801814                        exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) );
    802815                }
    803                 exprStmt->get_expr()->accept( *this );
     816                exprStmt->get_expr()->accept( *visitor );
    804817                output << ";";
    805818        }
    806819
    807         void CodeGenerator::visit( AsmStmt * asmStmt ) {
     820        void CodeGenerator::postvisit( AsmStmt * asmStmt ) {
    808821                output << "asm ";
    809822                if ( asmStmt->get_voltile() ) output << "volatile ";
    810823                if ( ! asmStmt->get_gotolabels().empty()  ) output << "goto ";
    811824                output << "( ";
    812                 if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *this );
     825                if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *visitor );
    813826                output << " : ";
    814827                genCommaList( asmStmt->get_output().begin(), asmStmt->get_output().end() );
     
    828841        }
    829842
    830         void CodeGenerator::visit( AsmDecl * asmDecl ) {
     843        void CodeGenerator::postvisit( AsmDecl * asmDecl ) {
    831844                output << "asm ";
    832845                AsmStmt * asmStmt = asmDecl->get_stmt();
    833846                output << "( ";
    834                 if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *this );
     847                if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *visitor );
    835848                output << " )" ;
    836849        }
    837850
    838         void CodeGenerator::visit( IfStmt * ifStmt ) {
     851        void CodeGenerator::postvisit( IfStmt * ifStmt ) {
    839852                updateLocation( ifStmt );
    840853                output << "if ( ";
    841                 ifStmt->get_condition()->accept( *this );
     854                ifStmt->get_condition()->accept( *visitor );
    842855                output << " ) ";
    843856
    844                 ifStmt->get_thenPart()->accept( *this );
     857                ifStmt->get_thenPart()->accept( *visitor );
    845858
    846859                if ( ifStmt->get_elsePart() != 0) {
    847860                        output << " else ";
    848                         ifStmt->get_elsePart()->accept( *this );
    849                 } // if
    850         }
    851 
    852         void CodeGenerator::visit( SwitchStmt * switchStmt ) {
     861                        ifStmt->get_elsePart()->accept( *visitor );
     862                } // if
     863        }
     864
     865        void CodeGenerator::postvisit( SwitchStmt * switchStmt ) {
    853866                updateLocation( switchStmt );
    854867                output << "switch ( " ;
    855                 switchStmt->get_condition()->accept( *this );
     868                switchStmt->get_condition()->accept( *visitor );
    856869                output << " ) ";
    857870
    858871                output << "{" << std::endl;
    859872                ++indent;
    860                 acceptAll( switchStmt->get_statements(), *this );
     873                acceptAll( switchStmt->get_statements(), *visitor );
    861874                --indent;
    862875                output << indent << "}";
    863876        }
    864877
    865         void CodeGenerator::visit( CaseStmt * caseStmt ) {
     878        void CodeGenerator::postvisit( CaseStmt * caseStmt ) {
    866879                updateLocation( caseStmt );
    867880                if ( caseStmt->isDefault()) {
     
    869882                } else {
    870883                        output << "case ";
    871                         caseStmt->get_condition()->accept( *this );
     884                        caseStmt->get_condition()->accept( *visitor );
    872885                } // if
    873886                output << ":\n";
     
    878891                for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++) {
    879892                        output << indent << printLabels( (*i)->get_labels() )  ;
    880                         (*i)->accept( *this );
     893                        (*i)->accept( *visitor );
    881894                        output << endl;
    882895                } // for
     
    884897        }
    885898
    886         void CodeGenerator::visit( BranchStmt * branchStmt ) {
     899        void CodeGenerator::postvisit( BranchStmt * branchStmt ) {
    887900                switch ( branchStmt->get_type()) {
    888901                  case BranchStmt::Goto:
     
    892905                                if ( branchStmt->get_computedTarget() != 0 ) {
    893906                                        output << "goto *";
    894                                         branchStmt->get_computedTarget()->accept( *this );
     907                                        branchStmt->get_computedTarget()->accept( *visitor );
    895908                                } // if
    896909                        } // if
     
    906919        }
    907920
    908         void CodeGenerator::visit( ReturnStmt * returnStmt ) {
     921        void CodeGenerator::postvisit( ReturnStmt * returnStmt ) {
    909922                output << "return ";
    910                 maybeAccept( returnStmt->get_expr(), *this );
     923                maybeAccept( returnStmt->get_expr(), *visitor );
    911924                output << ";";
    912925        }
    913926
    914         void CodeGenerator::visit( ThrowStmt * throwStmt ) {
     927        void CodeGenerator::postvisit( ThrowStmt * throwStmt ) {
    915928                assertf( ! genC, "Throw statements should not reach code generation." );
    916929
     
    919932                if (throwStmt->get_expr()) {
    920933                        output << " ";
    921                         throwStmt->get_expr()->accept( *this );
     934                        throwStmt->get_expr()->accept( *visitor );
    922935                }
    923936                if (throwStmt->get_target()) {
    924937                        output << " _At ";
    925                         throwStmt->get_target()->accept( *this );
     938                        throwStmt->get_target()->accept( *visitor );
    926939                }
    927940                output << ";";
    928941        }
    929942
    930         void CodeGenerator::visit( WhileStmt * whileStmt ) {
     943        void CodeGenerator::postvisit( WhileStmt * whileStmt ) {
    931944                if ( whileStmt->get_isDoWhile() ) {
    932945                        output << "do" ;
    933946                } else {
    934947                        output << "while (" ;
    935                         whileStmt->get_condition()->accept( *this );
     948                        whileStmt->get_condition()->accept( *visitor );
    936949                        output << ")";
    937950                } // if
     
    939952
    940953                output << CodeGenerator::printLabels( whileStmt->get_body()->get_labels() );
    941                 whileStmt->get_body()->accept( *this );
     954                whileStmt->get_body()->accept( *visitor );
    942955
    943956                output << indent;
     
    945958                if ( whileStmt->get_isDoWhile() ) {
    946959                        output << " while (" ;
    947                         whileStmt->get_condition()->accept( *this );
     960                        whileStmt->get_condition()->accept( *visitor );
    948961                        output << ");";
    949962                } // if
    950963        }
    951964
    952         void CodeGenerator::visit( ForStmt * forStmt ) {
     965        void CodeGenerator::postvisit( ForStmt * forStmt ) {
    953966                // initialization is always hoisted, so don't bother doing anything with that
    954967                output << "for (;";
    955968
    956969                if ( forStmt->get_condition() != 0 ) {
    957                         forStmt->get_condition()->accept( *this );
     970                        forStmt->get_condition()->accept( *visitor );
    958971                } // if
    959972                output << ";";
     
    962975                        // cast the top-level expression to void to reduce gcc warnings.
    963976                        Expression * expr = new CastExpr( forStmt->get_increment() );
    964                         expr->accept( *this );
     977                        expr->accept( *visitor );
    965978                } // if
    966979                output << ") ";
     
    968981                if ( forStmt->get_body() != 0 ) {
    969982                        output << CodeGenerator::printLabels( forStmt->get_body()->get_labels() );
    970                         forStmt->get_body()->accept( *this );
    971                 } // if
    972         }
    973 
    974         void CodeGenerator::visit( __attribute__((unused)) NullStmt * nullStmt ) {
     983                        forStmt->get_body()->accept( *visitor );
     984                } // if
     985        }
     986
     987        void CodeGenerator::postvisit( __attribute__((unused)) NullStmt * nullStmt ) {
    975988                //output << indent << CodeGenerator::printLabels( nullStmt->get_labels() );
    976989                output << "/* null statement */ ;";
    977990        }
    978991
    979         void CodeGenerator::visit( DeclStmt * declStmt ) {
    980                 declStmt->get_decl()->accept( *this );
     992        void CodeGenerator::postvisit( DeclStmt * declStmt ) {
     993                declStmt->get_decl()->accept( *visitor );
    981994
    982995                if ( doSemicolon( declStmt->get_decl() ) ) {
    983996                        output << ";";
    984997                } // if
     998        }
     999
     1000        void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) {
     1001                assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." );
     1002                stmt->callStmt->accept( *visitor );
    9851003        }
    9861004
  • src/CodeGen/CodeGenerator.h

    racdfb45 r9857e8d  
    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 );
     
    3434                CodeGenerator( std::ostream &os, char *, int indent = 0, bool infun = false );
    3535
     36                //*** Turn off visit_children for all nodes
     37                void previsit( BaseSyntaxNode * );
     38
     39                //*** Error for unhandled node types
     40                void postvisit( BaseSyntaxNode * );
     41
    3642                //*** 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 );
     43                void postvisit( StructDecl * );
     44                void postvisit( FunctionDecl * );
     45                void postvisit( ObjectDecl * );
     46                void postvisit( UnionDecl *aggregateDecl );
     47                void postvisit( EnumDecl *aggregateDecl );
     48                void postvisit( TraitDecl *aggregateDecl );
     49                void postvisit( TypedefDecl *typeDecl );
     50                void postvisit( TypeDecl *typeDecl );
    4551
    4652                //*** Initializer
    47                 virtual void visit( Designation * );
    48                 virtual void visit( SingleInit * );
    49                 virtual void visit( ListInit * );
    50                 virtual void visit( ConstructorInit * );
     53                void postvisit( Designation * );
     54                void postvisit( SingleInit * );
     55                void postvisit( ListInit * );
     56                void postvisit( ConstructorInit * );
    5157
    5258                //*** Constant
    53                 virtual void visit( Constant * );
     59                void postvisit( Constant * );
    5460
    5561                //*** 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 * );
     62                void postvisit( ApplicationExpr *applicationExpr );
     63                void postvisit( UntypedExpr *untypedExpr );
     64                void postvisit( RangeExpr * rangeExpr );
     65                void postvisit( NameExpr *nameExpr );
     66                void postvisit( AddressExpr *addressExpr );
     67                void postvisit( LabelAddressExpr *addressExpr );
     68                void postvisit( CastExpr *castExpr );
     69                void postvisit( VirtualCastExpr *castExpr );
     70                void postvisit( UntypedMemberExpr *memberExpr );
     71                void postvisit( MemberExpr *memberExpr );
     72                void postvisit( VariableExpr *variableExpr );
     73                void postvisit( ConstantExpr *constantExpr );
     74                void postvisit( SizeofExpr *sizeofExpr );
     75                void postvisit( AlignofExpr *alignofExpr );
     76                void postvisit( UntypedOffsetofExpr *offsetofExpr );
     77                void postvisit( OffsetofExpr *offsetofExpr );
     78                void postvisit( OffsetPackExpr *offsetPackExpr );
     79                void postvisit( LogicalExpr *logicalExpr );
     80                void postvisit( ConditionalExpr *conditionalExpr );
     81                void postvisit( CommaExpr *commaExpr );
     82                void postvisit( CompoundLiteralExpr *compLitExpr );
     83                void postvisit( UniqueExpr * );
     84                void postvisit( TupleAssignExpr * tupleExpr );
     85                void postvisit( UntypedTupleExpr *tupleExpr );
     86                void postvisit( TupleExpr *tupleExpr );
     87                void postvisit( TupleIndexExpr * tupleExpr );
     88                void postvisit( TypeExpr *typeExpr );
     89                void postvisit( AsmExpr * );
     90                void postvisit( StmtExpr * );
    8591
    8692                //*** 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 * );
     93                void postvisit( CompoundStmt * );
     94                void postvisit( ExprStmt * );
     95                void postvisit( AsmStmt * );
     96                void postvisit( AsmDecl * );                            // special: statement in declaration context
     97                void postvisit( IfStmt * );
     98                void postvisit( SwitchStmt * );
     99                void postvisit( CaseStmt * );
     100                void postvisit( BranchStmt * );
     101                void postvisit( ReturnStmt * );
     102                void postvisit( ThrowStmt * );
     103                void postvisit( WhileStmt * );
     104                void postvisit( ForStmt * );
     105                void postvisit( NullStmt * );
     106                void postvisit( DeclStmt * );
     107                void postvisit( ImplicitCtorDtorStmt * );
    101108
    102109                void genAttributes( std::list< Attribute * > & attributes );
     
    140147          if ( begin == end ) return;
    141148                for ( ;; ) {
    142                         (*begin++)->accept( *this );
     149                        (*begin++)->accept( *visitor );
    143150                  if ( begin == end ) break;
    144151                        output << ", ";                                                         // separator
  • src/CodeGen/GenType.cc

    racdfb45 r9857e8d  
    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

    racdfb45 r9857e8d  
    4949                cleanTree( translationUnit );
    5050
    51                 CodeGen::CodeGenerator cgv( os, pretty, generateC, lineMarks );
     51                PassVisitor<CodeGenerator> cgv( os, pretty, generateC, lineMarks );
    5252                for ( auto & dcl : translationUnit ) {
    5353                        if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) {
    54                                 cgv.updateLocation( dcl );
     54                                cgv.pass.updateLocation( dcl );
    5555                                dcl->accept(cgv);
    5656                                if ( doSemicolon( dcl ) ) {
  • src/SynTree/BaseSyntaxNode.h

    racdfb45 r9857e8d  
    2626
    2727        virtual void accept( Visitor & v ) = 0;
     28  virtual void print( std::ostream & os, int indent = 0 ) const = 0;
    2829};
    2930
Note: See TracChangeset for help on using the changeset viewer.